diff --git a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
index b083a9b..7a87776 100644
--- a/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
+++ b/src/main/java/de/ids_mannheim/korap/security/auth/KustvaktAuthenticationManager.java
@@ -1,13 +1,33 @@
 package de.ids_mannheim.korap.security.auth;
 
-import com.sun.org.apache.xpath.internal.SourceTree;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// import com.novell.ldap.*; search() funktioniert nicht korrekt, ausgewechselt gegen unboundID's Bibliothek 20.04.17/FB
+//Using JAR from unboundID:
+import com.unboundid.ldap.sdk.LDAPException;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.config.URIParam;
-import de.ids_mannheim.korap.exceptions.*;
+import de.ids_mannheim.korap.exceptions.EmptyResultException;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.NotAuthorizedException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.exceptions.WrappedException;
 import de.ids_mannheim.korap.interfaces.AuthenticationIface;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
@@ -17,1031 +37,883 @@
 import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
 import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
-import de.ids_mannheim.korap.user.*;
-import de.ids_mannheim.korap.user.User.Location;
+import de.ids_mannheim.korap.user.DemoUser;
+import de.ids_mannheim.korap.user.KorAPUser;
+import de.ids_mannheim.korap.user.ShibUser;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.User.CorpusAccess;
+import de.ids_mannheim.korap.user.User.Location;
+import de.ids_mannheim.korap.user.UserDetails;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
 import de.ids_mannheim.korap.utils.StringUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
-import de.ids_mannheim.korap.security.auth.LdapAuth3;
-
-import javax.ws.rs.core.HttpHeaders;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-// import com.novell.ldap.*; search() funktioniert nicht korrekt, ausgewechselt gegen unboundID's Bibliothek 20.04.17/FB
-//Using JAR from unboundID:
-import com.unboundid.ldap.sdk.LDAPException;
-
-
-
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.MultivaluedMap;
 
 /**
- * contains the logic to authentication and registration processes.
- * Uses
- * interface implementations (AuthenticationIface) for different
- * databases and handlers
+ * contains the logic to authentication and registration processes. Uses
+ * interface implementations (AuthenticationIface) for different databases and
+ * handlers
  * 
  * @author hanl
  */
 public class KustvaktAuthenticationManager extends AuthenticationManagerIface {
 
-    private static Logger jlog = LoggerFactory
-            .getLogger(KustvaktAuthenticationManager.class);
-    private EncryptionIface crypto;
-    private EntityHandlerIface entHandler;
-    private AdminHandlerIface adminHandler;
-    private AuditingIface auditing;
-    private KustvaktConfiguration config;
-    private Collection userdatadaos;
-    private LoginCounter counter;
-    private ValidatorIface validator;
+	private static Logger jlog = LoggerFactory.getLogger(KustvaktAuthenticationManager.class);
+	private EncryptionIface crypto;
+	private EntityHandlerIface entHandler;
+	private AdminHandlerIface adminHandler;
+	private AuditingIface auditing;
+	private KustvaktConfiguration config;
+	private Collection userdatadaos;
+	private LoginCounter counter;
+	private ValidatorIface validator;
 
-    public KustvaktAuthenticationManager (EntityHandlerIface userdb, 
-    									  AdminHandlerIface admindb,
-                                          EncryptionIface crypto,
-                                          KustvaktConfiguration config,
-                                          AuditingIface auditer,
-                                          Collection<UserDataDbIface> userdatadaos) {
-        this.entHandler = userdb;
-        this.adminHandler = admindb;
-        this.config = config;
-        this.crypto = crypto;
-        this.auditing = auditer;
-        this.counter = new LoginCounter(config);
-        this.userdatadaos = userdatadaos;
-        // todo: load via beancontext
-        try {
-            this.validator = new ApacheValidator();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
+	public KustvaktAuthenticationManager(EntityHandlerIface userdb, AdminHandlerIface admindb, EncryptionIface crypto,
+			KustvaktConfiguration config, AuditingIface auditer, Collection<UserDataDbIface> userdatadaos) {
+		this.entHandler = userdb;
+		this.adminHandler = admindb;
+		this.config = config;
+		this.crypto = crypto;
+		this.auditing = auditer;
+		this.counter = new LoginCounter(config);
+		this.userdatadaos = userdatadaos;
+		// todo: load via beancontext
+		try {
+			this.validator = new ApacheValidator();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
 
+	/**
+	 * get session object if token was a session token
+	 * 
+	 * @param token
+	 * @param host
+	 * @param useragent
+	 * @return
+	 * @throws KustvaktException
+	 */
+	@Override
+	public TokenContext getTokenStatus(String token, String host, String useragent) throws KustvaktException {
+		if (token == null)
+			throw new KustvaktException(StatusCodes.MISSING_ARGUMENT, "authorization header");
 
-    /**
-     * get session object if token was a session token
-     * 
-     * @param token
-     * @param host
-     * @param useragent
-     * @return
-     * @throws KustvaktException
-     */
-    @Override
-    public TokenContext getTokenStatus (String token, String host,
-            String useragent) throws KustvaktException {
-        if (token == null)
-            throw new KustvaktException(StatusCodes.MISSING_ARGUMENT, "authorization header");
+		String token_type = StringUtils.getTokenType(token);
+		token = StringUtils.stripTokenType(token);
+		jlog.info("getting session status of token type '{}'", token.split(" ")[0]);
+		AuthenticationIface provider = getProvider(token_type, null);
 
-        String token_type = StringUtils.getTokenType(token);
-        token = StringUtils.stripTokenType(token);
-        jlog.info("getting session status of token type '{}'",
-                token.split(" ")[0]);
-        AuthenticationIface provider = getProvider(
-                token_type, null);
+		if (provider == null)
+			// throw exception for missing type parameter
+			throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT, "token type not defined or found", "token_type");
 
-        if (provider == null)
-            // throw exception for missing type parameter
-            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
-                    "token type not defined or found", "token_type");
+		TokenContext context = provider.getTokenContext(token);
+		if (context != null && TimeUtils.isExpired(context.getExpirationTime()))
+			throw new KustvaktException(StatusCodes.EXPIRED);
+		else if (context == null)
+			throw new KustvaktException(StatusCodes.NO_VALUE_FOUND);
 
-        TokenContext context = provider.getTokenContext(token);
-        if (context != null && TimeUtils.isExpired(context.getExpirationTime()))
-            throw new KustvaktException(StatusCodes.EXPIRED);
-        else if (context == null)
-            throw new KustvaktException(StatusCodes.NO_VALUE_FOUND);
+		// if (!matchStatus(host, useragent, context))
+		// provider.removeUserSession(token);
+		return context;
+	}
 
-        //        if (!matchStatus(host, useragent, context))
-        //            provider.removeUserSession(token);
-        return context;
-    }
+	@Override
+	public User getUser(String username) throws KustvaktException {
+		// User user;
+		// Object value = this.getCacheValue(username);
 
+		if (User.UserFactory.isDemo(username))
+			return User.UserFactory.getDemoUser();
 
-    @Override
-    public User getUser (String username) throws KustvaktException {
-        //User user;
-        //Object value = this.getCacheValue(username);
+		// if (value != null) {
+		// Map map = (Map) value;
+		// user = User.UserFactory.toUser(map);
+		// }
+		// else {
+		// user = entHandler.getAccount(username);
+		// this.storeInCache(username, user.toCache());
+		// todo: not valid. for the duration of the session, the host should not
+		// change!
+		// }
+		// todo:
+		// user.addField(Attributes.HOST, context.getHostAddress());
+		// user.addField(Attributes.USER_AGENT, context.getUserAgent());
+		return entHandler.getAccount(username);
+	}
 
-        if (User.UserFactory.isDemo(username))
-            return User.UserFactory.getDemoUser();
+	public TokenContext refresh(TokenContext context) throws KustvaktException {
+		AuthenticationIface provider = getProvider(context.getTokenType(), null);
+		if (provider == null) {
+			// todo:
+		}
 
-        //if (value != null) {
-         //   Map map = (Map) value;
-          //  user = User.UserFactory.toUser(map);
-        //}
-       // else {
-        //    user = entHandler.getAccount(username);
-        //    this.storeInCache(username, user.toCache());
-            // todo: not valid. for the duration of the session, the host should not change!
-        //}
-        //todo:
-        //        user.addField(Attributes.HOST, context.getHostAddress());
-        //        user.addField(Attributes.USER_AGENT, context.getUserAgent());
-        return entHandler.getAccount(username);
-    }
+		try {
+			provider.removeUserSession(context.getToken());
+			User user = getUser(context.getUsername());
+			return provider.createTokenContext(user, context.params());
+		} catch (KustvaktException e) {
+			throw new WrappedException(e, StatusCodes.LOGIN_FAILED);
+		}
+	}
 
+	/**
+	 * @param type
+	 * @param attributes
+	 *            contains username and password to authenticate the user.
+	 *            Depending of the authentication schema, may contain other
+	 *            values as well
+	 * @return User
+	 * @throws KustvaktException
+	 */
+	@Override
+	public User authenticate(int type, String username, String password, Map<String, Object> attributes)
+			throws KustvaktException {
+		User user;
+		switch (type) {
+		case 1:
+			// todo:
+			user = authenticateShib(attributes);
+			break;
+		case 2:
+			// IdM/LDAP: (09.02.17/FB)
+			user = authenticateIdM(username, password, attributes);
+			break;
+		default:
+			user = authenticate(username, password, attributes);
+			break;
+		}
+		auditing.audit(AuditRecord.serviceRecord(user.getId(), StatusCodes.LOGIN_SUCCESSFUL, user.toString()));
+		return user;
+	}
 
+	// a. set location depending on X-Forwarded-For.
+	// X-Forwarded-For: clientIP, ProxyID, ProxyID...
+	// the following private address spaces may be used to define intranet
+	// spaces:
+	// 10.0.0.0 - 10.255.255.255 (10/8 prefix)
+	// 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
+	// 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
+	// b. set corpusAccess depending on location:
+	// 16.05.17/FB
 
-    public TokenContext refresh (TokenContext context) throws KustvaktException {
-        AuthenticationIface provider = getProvider(context.getTokenType(), null);
-        if (provider == null) {
-            //todo:
-        }
+	@Override
+	public void setAccessAndLocation(User user, HttpHeaders headers) {
+		Boolean DEBUG_LOG = true;
+		MultivaluedMap<String, String> headerMap = headers.getRequestHeaders();
+		Location location = Location.EXTERN;
+		CorpusAccess corpusAccess = CorpusAccess.FREE;
 
-        try {
-            provider.removeUserSession(context.getToken());
-            User user = getUser(context.getUsername());
-            return provider.createTokenContext(user, context.params());
-        }
-        catch (KustvaktException e) {
-            throw new WrappedException(e, StatusCodes.LOGIN_FAILED);
-        }
-    }
+		if (headerMap != null && headerMap.containsKey(org.eclipse.jetty.http.HttpHeaders.X_FORWARDED_FOR)) {
 
+			String[] vals = headerMap.getFirst(org.eclipse.jetty.http.HttpHeaders.X_FORWARDED_FOR).split(",");
+			String clientAddress = vals[0];
 
-    /**
-     * @param type
-     * @param attributes
-     *            contains username and password to authenticate the
-     *            user.
-     *            Depending of the authentication schema, may contain
-     *            other values as well
-     * @return User
-     * @throws KustvaktException
-     */
-    @Override
-    public User authenticate (int type, String username, String password,
-            Map<String, Object> attributes) throws KustvaktException {
-        User user;
-        switch (type) {
-            case 1:
-                // todo:
-                user = authenticateShib(attributes);
-                break;
-            case 2:
-                // IdM/LDAP: (09.02.17/FB)
-                user = authenticateIdM(username, password, attributes);
-                break;
-            default:
-                user = authenticate(username, password, attributes);
-                break;
-        }
-        auditing.audit(AuditRecord.serviceRecord(user.getId(),
-                StatusCodes.LOGIN_SUCCESSFUL, user.toString()));
-        return user;
-    }
+			try {
+				InetAddress ip = InetAddress.getByName(clientAddress);
+				if (ip.isSiteLocalAddress()){
+//				if (clientAddress.startsWith("10.0.") || clientAddress.startsWith("172.16.")
+//						|| clientAddress.startsWith("192.168."))
+					location = Location.INTERN;
+				}
+				else{
+					location = Location.EXTERN;
+				}
+				
+				if (location == Location.EXTERN) {
+					corpusAccess = CorpusAccess.PUB;
+				} 
+				else {
+					corpusAccess = CorpusAccess.ALL;
+				}
+				if (DEBUG_LOG == true) {
+					System.out.printf("Debug: X-Forwarded-For : '%s' (%d values) -> %s\n", vals, vals.length, vals[0]);
+					System.out.printf("Debug: X-Forwarded-For : location = %s corpusAccess = %s\n",
+							location == Location.INTERN ? "INTERN" : "EXTERN", corpusAccess == CorpusAccess.ALL ? "ALL"
+									: corpusAccess == CorpusAccess.PUB ? "PUB" : "FREE");
+				}
 
-    // a. set location depending on X-Forwarded-For.
-    // X-Forwarded-For: clientIP, ProxyID, ProxyID...
-    // the following private address spaces may be used to define intranet spaces:
-    // 10.0.0.0        -   10.255.255.255  (10/8 prefix)
-    // 172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
-    // 192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
-    // b. set corpusAccess depending on location:
-    // 16.05.17/FB
-    
-    @Override
-    public void setAccessAndLocation(User user, HttpHeaders headers)
-    
-    {
-    Boolean DEBUG_LOG = true;
-    MultivaluedMap<String,String> headerMap = headers.getRequestHeaders();
-    Location location = Location.INTERN;
-    CorpusAccess corpusAccess = CorpusAccess.FREE;
-    
-    if( headerMap != null && headerMap.size() > 0 )
-    	{
-    	Iterator<String> it = headerMap.keySet().iterator();
-    	while( it.hasNext() )
-    		{
-    		String key = (String)it.next();
-    		if( key.equals("X-Forwarded-For"))
-        		{
-        		List<String> vals = new ArrayList<String>(Arrays.asList(headerMap.getFirst(key).split(",")));
-        		String clientAddress = vals.get(0);
-        		
-        		if( clientAddress.startsWith("10.0.") || clientAddress.startsWith("172.16.") || clientAddress.startsWith("192.168."))
-        			location = Location.INTERN;
-        		else
-        			location = Location.EXTERN;
-        		if( location == Location.EXTERN )
-        			corpusAccess = CorpusAccess.PUB;
-        		else
-        			corpusAccess = CorpusAccess.ALL;
-        		
-        		if( DEBUG_LOG == true )
-        			{
-	        		System.out.printf("Debug: X-Forwarded-For : '%s' (%d values) -> %s\n", vals, vals.size(), vals.get(0));
-	        		System.out.printf("Debug: X-Forwarded-For : location = %s corpusAccess = %s\n", 
-	        				location == Location.INTERN ? "INTERN" : "EXTERN",
-	        				corpusAccess == CorpusAccess.ALL ? "ALL" : corpusAccess == CorpusAccess.PUB ? "PUB" : "FREE"); 
-	        		}
-        		}	
-    		}
-    	}
-    
-    user.setLocation(location);
-    user.setCorpusAccess(corpusAccess);
-        
-    } // getAccess
-    
-    @Override
-    public TokenContext createTokenContext (User user,
-            Map<String, Object> attr, String provider_key)
-            throws KustvaktException {
-        AuthenticationIface provider = getProvider(provider_key,
-                Attributes.API_AUTHENTICATION);
+			} catch (UnknownHostException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
 
-        if (attr.get(Attributes.SCOPES) != null)
-            this.getUserData(user, UserDetails.class);
+			user.setLocation(location);
+			user.setCorpusAccess(corpusAccess);
+		}
+	} // getAccess
 
-        TokenContext context = provider.createTokenContext(user, attr);
-        if (context == null)
-            throw new KustvaktException(StatusCodes.NOT_SUPPORTED);
-        context.setUserAgent((String) attr.get(Attributes.USER_AGENT));
-        context.setHostAddress(Attributes.HOST);
-        return context;
-    }
+	@Override
+	public TokenContext createTokenContext(User user, Map<String, Object> attr, String provider_key)
+			throws KustvaktException {
+		AuthenticationIface provider = getProvider(provider_key, Attributes.API_AUTHENTICATION);
 
+		if (attr.get(Attributes.SCOPES) != null)
+			this.getUserData(user, UserDetails.class);
 
-    //todo: test
-    @Deprecated
-    private boolean matchStatus (String host, String useragent,
-            TokenContext context) {
-        if (host.equals(context.getHostAddress())) {
-            if (useragent.equals(context.getUserAgent()))
-                return true;
-        }
-        return false;
-    }
+		TokenContext context = provider.createTokenContext(user, attr);
+		if (context == null)
+			throw new KustvaktException(StatusCodes.NOT_SUPPORTED);
+		context.setUserAgent((String) attr.get(Attributes.USER_AGENT));
+		context.setHostAddress(Attributes.HOST);
+		return context;
+	}
 
+	// todo: test
+	@Deprecated
+	private boolean matchStatus(String host, String useragent, TokenContext context) {
+		if (host.equals(context.getHostAddress())) {
+			if (useragent.equals(context.getUserAgent()))
+				return true;
+		}
+		return false;
+	}
 
-    private User authenticateShib (Map<String, Object> attributes)
-            throws KustvaktException {
-        // todo use persistent id, since eppn is not unique
-        String eppn = (String) attributes.get(Attributes.EPPN);
+	private User authenticateShib(Map<String, Object> attributes) throws KustvaktException {
+		// todo use persistent id, since eppn is not unique
+		String eppn = (String) attributes.get(Attributes.EPPN);
 
-        if (eppn == null || eppn.isEmpty())
-            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+		if (eppn == null || eppn.isEmpty())
+			throw new KustvaktException(StatusCodes.REQUEST_INVALID);
 
-        if (!attributes.containsKey(Attributes.EMAIL)
-                && validator.isValid(eppn, Attributes.EMAIL))
-            attributes.put(Attributes.EMAIL, eppn);
+		if (!attributes.containsKey(Attributes.EMAIL) && validator.isValid(eppn, Attributes.EMAIL))
+			attributes.put(Attributes.EMAIL, eppn);
 
-        User user = null;
-        if (isRegistered(eppn))
-            user = createShibbUserAccount(attributes);
-        return user;
-    }
+		User user = null;
+		if (isRegistered(eppn))
+			user = createShibbUserAccount(attributes);
+		return user;
+	}
 
+	// todo: what if attributes null?
+	private User authenticate(String username, String password, Map<String, Object> attr) throws KustvaktException {
 
-    //todo: what if attributes null?
-    private User authenticate (String username, String password, Map<String, Object> attr) throws KustvaktException {
-    	
-        Map<String, Object> attributes = validator.validateMap(attr);
-        User unknown;
-        // just to make sure that the plain password does not appear anywhere in the logs!
+		Map<String, Object> attributes = validator.validateMap(attr);
+		User unknown;
+		// just to make sure that the plain password does not appear anywhere in
+		// the logs!
 
-        try {
-            validator.validateEntry(username, Attributes.USERNAME);
-        } catch (KustvaktException e) {
-            throw new WrappedException(e, StatusCodes.LOGIN_FAILED, username);
-        }
+		try {
+			validator.validateEntry(username, Attributes.USERNAME);
+		} catch (KustvaktException e) {
+			throw new WrappedException(e, StatusCodes.LOGIN_FAILED, username);
+		}
 
-        if (username == null || username.isEmpty())
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED);
-        else {
-            try {
-                unknown = entHandler.getAccount(username);
-            } 
-            catch (EmptyResultException e) {
-                // mask exception to disable user guessing in possible attacks
-                throw new WrappedException(new KustvaktException(username,
-                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
-                        username);
-            }
-            catch (KustvaktException e) {
-                jlog.error("Error: {}", e);
-                throw new WrappedException(e, StatusCodes.LOGIN_FAILED,
-                        attributes.toString());
-            }
-        }
-        
-        boolean isAdmin = adminHandler.isAdmin(unknown.getId());
-        unknown.setAdmin(isAdmin);
-        jlog.trace("Authentication: found username " + unknown.getUsername());
-        
-        if (unknown instanceof KorAPUser) {
-            if (password == null || password.isEmpty())
-                throw new WrappedException(new KustvaktException(
-                        unknown.getId(), StatusCodes.BAD_CREDENTIALS),
-                        StatusCodes.LOGIN_FAILED, username);
+		if (username == null || username.isEmpty())
+			throw new WrappedException(new KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+					StatusCodes.LOGIN_FAILED);
+		else {
+			try {
+				unknown = entHandler.getAccount(username);
+			} catch (EmptyResultException e) {
+				// mask exception to disable user guessing in possible attacks
+				throw new WrappedException(new KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+						StatusCodes.LOGIN_FAILED, username);
+			} catch (KustvaktException e) {
+				jlog.error("Error: {}", e);
+				throw new WrappedException(e, StatusCodes.LOGIN_FAILED, attributes.toString());
+			}
+		}
 
-            KorAPUser user = (KorAPUser) unknown;
-            boolean check = crypto.checkHash(password, user.getPassword());
+		boolean isAdmin = adminHandler.isAdmin(unknown.getId());
+		unknown.setAdmin(isAdmin);
+		jlog.trace("Authentication: found username " + unknown.getUsername());
 
-            if (!check) {
-                // the fail counter only applies for wrong password
-                jlog.warn("Wrong Password!");
-                processLoginFail(unknown);
-                throw new WrappedException(new KustvaktException(user.getId(),
-                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
-                        username);
-            }
+		if (unknown instanceof KorAPUser) {
+			if (password == null || password.isEmpty())
+				throw new WrappedException(new KustvaktException(unknown.getId(), StatusCodes.BAD_CREDENTIALS),
+						StatusCodes.LOGIN_FAILED, username);
 
-            // bad credentials error has precedence over account locked or unconfirmed codes
-            // since latter can lead to account guessing of third parties
-            if (user.isAccountLocked()) {
-                URIParam param = (URIParam) user.getField(URIParam.class);
+			KorAPUser user = (KorAPUser) unknown;
+			boolean check = crypto.checkHash(password, user.getPassword());
 
-                if (param.hasValues()) {
-                    jlog.debug("Account is not yet activated for user '{}'",
-                            user.getUsername());
-                    if (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
-                        jlog.error(
-                                "URI token is expired. Deleting account for user {}",
-                                user.getUsername());
-                        deleteAccount(user);
-                        throw new WrappedException(new KustvaktException(
-                                unknown.getId(), StatusCodes.EXPIRED,
-                                "account confirmation uri has expired!",
-                                param.getUriFragment()),
-                                StatusCodes.LOGIN_FAILED, username);
-                    }
-                    throw new WrappedException(new KustvaktException(
-                            unknown.getId(), StatusCodes.ACCOUNT_NOT_CONFIRMED),
-                            StatusCodes.LOGIN_FAILED, username);
-                }
-                jlog.error("ACCESS DENIED: account not active for '{}'",
-                        unknown.getUsername());
-                throw new WrappedException(new KustvaktException(
-                        unknown.getId(), StatusCodes.ACCOUNT_DEACTIVATED),
-                        StatusCodes.LOGIN_FAILED, username);
-            }
+			if (!check) {
+				// the fail counter only applies for wrong password
+				jlog.warn("Wrong Password!");
+				processLoginFail(unknown);
+				throw new WrappedException(new KustvaktException(user.getId(), StatusCodes.BAD_CREDENTIALS),
+						StatusCodes.LOGIN_FAILED, username);
+			}
 
-        }
-        else if (unknown instanceof ShibUser) {
-            //todo
-        }
-        jlog.debug("Authentication done: " + username);
-        return unknown;
-    }
+			// bad credentials error has precedence over account locked or
+			// unconfirmed codes
+			// since latter can lead to account guessing of third parties
+			if (user.isAccountLocked()) {
+				URIParam param = (URIParam) user.getField(URIParam.class);
 
+				if (param.hasValues()) {
+					jlog.debug("Account is not yet activated for user '{}'", user.getUsername());
+					if (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
+						jlog.error("URI token is expired. Deleting account for user {}", user.getUsername());
+						deleteAccount(user);
+						throw new WrappedException(
+								new KustvaktException(unknown.getId(), StatusCodes.EXPIRED,
+										"account confirmation uri has expired!", param.getUriFragment()),
+								StatusCodes.LOGIN_FAILED, username);
+					}
+					throw new WrappedException(
+							new KustvaktException(unknown.getId(), StatusCodes.ACCOUNT_NOT_CONFIRMED),
+							StatusCodes.LOGIN_FAILED, username);
+				}
+				jlog.error("ACCESS DENIED: account not active for '{}'", unknown.getUsername());
+				throw new WrappedException(new KustvaktException(unknown.getId(), StatusCodes.ACCOUNT_DEACTIVATED),
+						StatusCodes.LOGIN_FAILED, username);
+			}
 
-    /**
-     * authenticate using IdM (Identitätsmanagement) accessed by LDAP.
-     * @param username
-     * @param password
-     * @param attr
-     * @return
-     * @throws KustvaktException
-     * @date 09.02.17/FB
-     */
-    //todo: what if attributes null?
-    
-    private User authenticateIdM (String username, String password, Map<String, Object> attr) throws KustvaktException {
-    	
-        Map<String, Object> attributes = validator.validateMap(attr);
-        User unknown = null;
-        // just to make sure that the plain password does not appear anywhere in the logs!
+		} else if (unknown instanceof ShibUser) {
+			// todo
+		}
+		jlog.debug("Authentication done: " + username);
+		return unknown;
+	}
+
+	/**
+	 * authenticate using IdM (Identitätsmanagement) accessed by LDAP.
+	 * 
+	 * @param username
+	 * @param password
+	 * @param attr
+	 * @return
+	 * @throws KustvaktException
+	 * @date 09.02.17/FB
+	 */
+	// todo: what if attributes null?
 
-        System.out.printf("Debug: authenticateIdM: entering for '%s'...\n", username);
-        
-        /** wozu Apache Validatoren für User/Passwort für IdM/LDAP?
-         * siehe validation.properties. Abgeschaltet 21.04.17/FB
-        try { 
-            validator.validateEntry(username, Attributes.USERNAME);
-        	} 
-        catch (KustvaktException e) {
-            throw new WrappedException(e, StatusCodes.LOGIN_FAILED, username);
-        }
-		*/
-        if (username == null || username.isEmpty() || password == null || password.isEmpty() )
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED);
+	private User authenticateIdM(String username, String password, Map<String, Object> attr) throws KustvaktException {
 
-        // LDAP Access:
-        try {
-        	// todo: unknown = ...
-        	int ret = LdapAuth3.login(username, password);
-        	System.out.printf("Debug: autenticationIdM: Ldap.login(%s) returns: %d.\n", username, ret); 
-        	if( ret != LdapAuth3.LDAP_AUTH_ROK )
-        		{
-        		jlog.error("LdapAuth3.login(username='{}') returns '{}'='{}'!", username, ret,
-        				LdapAuth3.getErrMessage(ret));
-        		
-               	// mask exception to disable user guessing in possible attacks
-        		/* by Hanl
-                throw new WrappedException(new KustvaktException(username,
-                            StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
-                            username);        		 
-        		 */
-                throw new WrappedException(
-                			new KustvaktException(
-                					username,
-                					StatusCodes.LDAP_BASE_ERRCODE+ret,
-                					LdapAuth3.getErrMessage(ret),
-                					null), 
-        					StatusCodes.LOGIN_FAILED,
-                            username);
-        		}
-            }
-        catch ( LDAPException e ) {
-        	
-        	jlog.error("Error: username='{}' -> '{}'!", username, e);
-        	// mask exception to disable user guessing in possible attacks
-        	/* by Hanl:
-            throw new WrappedException(new KustvaktException(username,
-                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
-                        username);
-            */
-            throw new WrappedException(
-            		new KustvaktException(
-            				username,
-            				StatusCodes.LDAP_BASE_ERRCODE+LdapAuth3.LDAP_AUTH_RINTERR,
-            				LdapAuth3.getErrMessage(LdapAuth3.LDAP_AUTH_RINTERR),
-            				null), 
-    				StatusCodes.LOGIN_FAILED,
-                    username);
-            }
+		Map<String, Object> attributes = validator.validateMap(attr);
+		User unknown = null;
+		// just to make sure that the plain password does not appear anywhere in
+		// the logs!
 
-        // Create a User
-        // TODO: KorAPUser für solche mit einem bestehenden Account
-        //       DefaultUser sonst.
-        User user = new KorAPUser();
-        user.setUsername(username);
-        /* folgender Code funktioniert hier noch nicht, da die Headers noch nicht ausgewertet
-         * worden sind - 23.05.17/FB
-        Object o = attr.get(Attributes.LOCATION);
-        String loc = (String)o.toString();
-        int location = Integer.parseInt(loc);
-        user.setLocation(location); 
-        user.setCorpusAccess(Integer.parseInt(attr.get(Attributes.CORPUS_ACCESS).toString()));
-         */
-        unknown = user;
-        
-        jlog.trace("Authentication: found username " + unknown.getUsername());
-        
-        if (unknown instanceof KorAPUser) {
-            /* password already checked using LDAP:
-            if (password == null || password.isEmpty())
-                throw new WrappedException(new KustvaktException(
-                        unknown.getId(), StatusCodes.BAD_CREDENTIALS),
-                        StatusCodes.LOGIN_FAILED, username);
+		System.out.printf("Debug: authenticateIdM: entering for '%s'...\n", username);
 
-            KorAPUser user = (KorAPUser) unknown;
-            boolean check = crypto.checkHash(password, user.getPassword());
+		/**
+		 * wozu Apache Validatoren für User/Passwort für IdM/LDAP? siehe
+		 * validation.properties. Abgeschaltet 21.04.17/FB try {
+		 * validator.validateEntry(username, Attributes.USERNAME); } catch
+		 * (KustvaktException e) { throw new WrappedException(e,
+		 * StatusCodes.LOGIN_FAILED, username); }
+		 */
+		if (username == null || username.isEmpty() || password == null || password.isEmpty())
+			throw new WrappedException(new KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+					StatusCodes.LOGIN_FAILED);
 
-            if (!check) {
-                // the fail counter only applies for wrong password
-                jlog.warn("Wrong Password!");
-                processLoginFail(unknown);
-                throw new WrappedException(new KustvaktException(user.getId(),
-                        StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
-                        username);
-            }
-            */
-            // bad credentials error has precedence over account locked or unconfirmed codes
-            // since latter can lead to account guessing of third parties
-            /*
-            if (user.isAccountLocked()) {
-            
-                URIParam param = (URIParam) user.getField(URIParam.class);
+		// LDAP Access:
+		try {
+			// todo: unknown = ...
+			int ret = LdapAuth3.login(username, password);
+			System.out.printf("Debug: autenticationIdM: Ldap.login(%s) returns: %d.\n", username, ret);
+			if (ret != LdapAuth3.LDAP_AUTH_ROK) {
+				jlog.error("LdapAuth3.login(username='{}') returns '{}'='{}'!", username, ret,
+						LdapAuth3.getErrMessage(ret));
 
-                if (param.hasValues()) {
-                    jlog.debug("Account is not yet activated for user '{}'",
-                            user.getUsername());
-                    if (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
-                        jlog.error(
-                                "URI token is expired. Deleting account for user {}",
-                                user.getUsername());
-                        deleteAccount(user);
-                        throw new WrappedException(new KustvaktException(
-                                unknown.getId(), StatusCodes.EXPIRED,
-                                "account confirmation uri has expired!",
-                                param.getUriFragment()),
-                                StatusCodes.LOGIN_FAILED, username);
-                    }
-                    throw new WrappedException(new KustvaktException(
-                            unknown.getId(), StatusCodes.ACCOUNT_NOT_CONFIRMED),
-                            StatusCodes.LOGIN_FAILED, username);
-                }
-                jlog.error("ACCESS DENIED: account not active for '{}'",
-                        unknown.getUsername());
-                throw new WrappedException(new KustvaktException(
-                        unknown.getId(), StatusCodes.ACCOUNT_DEACTIVATED),
-                        StatusCodes.LOGIN_FAILED, username);
-            }
-             */
+				// mask exception to disable user guessing in possible attacks
+				/*
+				 * by Hanl throw new WrappedException(new
+				 * KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+				 * StatusCodes.LOGIN_FAILED, username);
+				 */
+				throw new WrappedException(new KustvaktException(username, StatusCodes.LDAP_BASE_ERRCODE + ret,
+						LdapAuth3.getErrMessage(ret), null), StatusCodes.LOGIN_FAILED, username);
+			}
+		} catch (LDAPException e) {
 
-        }
-        else if (unknown instanceof ShibUser) {
-            //todo
-        }
-        
-        jlog.debug("Authentication done: " + username);
-        return unknown;
-        
-    } // authenticateIdM
+			jlog.error("Error: username='{}' -> '{}'!", username, e);
+			// mask exception to disable user guessing in possible attacks
+			/*
+			 * by Hanl: throw new WrappedException(new
+			 * KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+			 * StatusCodes.LOGIN_FAILED, username);
+			 */
+			throw new WrappedException(
+					new KustvaktException(username, StatusCodes.LDAP_BASE_ERRCODE + LdapAuth3.LDAP_AUTH_RINTERR,
+							LdapAuth3.getErrMessage(LdapAuth3.LDAP_AUTH_RINTERR), null),
+					StatusCodes.LOGIN_FAILED, username);
+		}
 
-    public boolean isRegistered (String username) {
-        User user;
-        if (username == null || username.isEmpty())
-            return false;
-        //    throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
-        //            "username must be set", username);
+		// Create a User
+		// TODO: KorAPUser für solche mit einem bestehenden Account
+		// DefaultUser sonst.
+		User user = new KorAPUser();
+		user.setUsername(username);
+		/*
+		 * folgender Code funktioniert hier noch nicht, da die Headers noch
+		 * nicht ausgewertet worden sind - 23.05.17/FB Object o =
+		 * attr.get(Attributes.LOCATION); String loc = (String)o.toString(); int
+		 * location = Integer.parseInt(loc); user.setLocation(location);
+		 * user.setCorpusAccess(Integer.parseInt(attr.get(Attributes.
+		 * CORPUS_ACCESS).toString()));
+		 */
+		unknown = user;
 
-        try {
-            user = entHandler.getAccount(username);
-        }
-        catch (EmptyResultException e) {
-            jlog.debug("user does not exist ({})", username);
-            return false;
+		jlog.trace("Authentication: found username " + unknown.getUsername());
 
-        }
-        catch (KustvaktException e) {
-            jlog.error("KorAPException", e.string());
-            return false;
-            //throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
-             //       "username invalid", username);
-        }
-        return user != null;
-    }
+		if (unknown instanceof KorAPUser) {
+			/*
+			 * password already checked using LDAP: if (password == null ||
+			 * password.isEmpty()) throw new WrappedException(new
+			 * KustvaktException( unknown.getId(), StatusCodes.BAD_CREDENTIALS),
+			 * StatusCodes.LOGIN_FAILED, username);
+			 * 
+			 * KorAPUser user = (KorAPUser) unknown; boolean check =
+			 * crypto.checkHash(password, user.getPassword());
+			 * 
+			 * if (!check) { // the fail counter only applies for wrong password
+			 * jlog.warn("Wrong Password!"); processLoginFail(unknown); throw
+			 * new WrappedException(new KustvaktException(user.getId(),
+			 * StatusCodes.BAD_CREDENTIALS), StatusCodes.LOGIN_FAILED,
+			 * username); }
+			 */
+			// bad credentials error has precedence over account locked or
+			// unconfirmed codes
+			// since latter can lead to account guessing of third parties
+			/*
+			 * if (user.isAccountLocked()) {
+			 * 
+			 * URIParam param = (URIParam) user.getField(URIParam.class);
+			 * 
+			 * if (param.hasValues()) {
+			 * jlog.debug("Account is not yet activated for user '{}'",
+			 * user.getUsername()); if
+			 * (TimeUtils.getNow().isAfter(param.getUriExpiration())) {
+			 * jlog.error( "URI token is expired. Deleting account for user {}",
+			 * user.getUsername()); deleteAccount(user); throw new
+			 * WrappedException(new KustvaktException( unknown.getId(),
+			 * StatusCodes.EXPIRED, "account confirmation uri has expired!",
+			 * param.getUriFragment()), StatusCodes.LOGIN_FAILED, username); }
+			 * throw new WrappedException(new KustvaktException(
+			 * unknown.getId(), StatusCodes.ACCOUNT_NOT_CONFIRMED),
+			 * StatusCodes.LOGIN_FAILED, username); }
+			 * jlog.error("ACCESS DENIED: account not active for '{}'",
+			 * unknown.getUsername()); throw new WrappedException(new
+			 * KustvaktException( unknown.getId(),
+			 * StatusCodes.ACCOUNT_DEACTIVATED), StatusCodes.LOGIN_FAILED,
+			 * username); }
+			 */
 
+		} else if (unknown instanceof ShibUser) {
+			// todo
+		}
 
-    public void logout (TokenContext context) throws KustvaktException {
-        try {
-            AuthenticationIface provider = getProvider(context.getTokenType(),
-                    null);
+		jlog.debug("Authentication done: " + username);
+		return unknown;
 
-            if (provider == null) {
-                throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
-                        "provider not supported!", context.getTokenType());
-            }
-            provider.removeUserSession(context.getToken());
-        }
-        catch (KustvaktException e) {
-            throw new WrappedException(e, StatusCodes.LOGOUT_FAILED,
-                    context.toString());
-        }
-        auditing.audit(AuditRecord.serviceRecord(context.getUsername(),
-                StatusCodes.LOGOUT_SUCCESSFUL, context.toString()));
-        this.removeCacheEntry(context.getToken());
-    }
+	} // authenticateIdM
 
+	public boolean isRegistered(String username) {
+		User user;
+		if (username == null || username.isEmpty())
+			return false;
+		// throw new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT,
+		// "username must be set", username);
 
-    private void processLoginFail (User user) throws KustvaktException {
-        counter.registerFail(user.getUsername());
-        if (!counter.validate(user.getUsername())) {
-            try {
-                this.lockAccount(user);
-            }
-            catch (KustvaktException e) {
-                jlog.error("user account could not be locked", e);
-                throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
-            }
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.ACCOUNT_DEACTIVATED), StatusCodes.LOGIN_FAILED);
-        }
-    }
+		try {
+			user = entHandler.getAccount(username);
+		} catch (EmptyResultException e) {
+			jlog.debug("user does not exist ({})", username);
+			return false;
 
+		} catch (KustvaktException e) {
+			jlog.error("KorAPException", e.string());
+			return false;
+			// throw new KustvaktException(username,
+			// StatusCodes.ILLEGAL_ARGUMENT,
+			// "username invalid", username);
+		}
+		return user != null;
+	}
 
-    public void lockAccount (User user) throws KustvaktException {
-        if (!(user instanceof KorAPUser))
-            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+	public void logout(TokenContext context) throws KustvaktException {
+		try {
+			AuthenticationIface provider = getProvider(context.getTokenType(), null);
 
-        KorAPUser u = (KorAPUser) user;
-        u.setAccountLocked(true);
-        jlog.info("locking account for user: {}", user.getUsername());
-        entHandler.updateAccount(u);
-    }
+			if (provider == null) {
+				throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT, "provider not supported!",
+						context.getTokenType());
+			}
+			provider.removeUserSession(context.getToken());
+		} catch (KustvaktException e) {
+			throw new WrappedException(e, StatusCodes.LOGOUT_FAILED, context.toString());
+		}
+		auditing.audit(
+				AuditRecord.serviceRecord(context.getUsername(), StatusCodes.LOGOUT_SUCCESSFUL, context.toString()));
+		this.removeCacheEntry(context.getToken());
+	}
 
+	private void processLoginFail(User user) throws KustvaktException {
+		counter.registerFail(user.getUsername());
+		if (!counter.validate(user.getUsername())) {
+			try {
+				this.lockAccount(user);
+			} catch (KustvaktException e) {
+				jlog.error("user account could not be locked", e);
+				throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
+			}
+			throw new WrappedException(new KustvaktException(user.getId(), StatusCodes.ACCOUNT_DEACTIVATED),
+					StatusCodes.LOGIN_FAILED);
+		}
+	}
 
-    public KorAPUser checkPasswordAllowance (KorAPUser user,
-            String oldPassword, String newPassword) throws KustvaktException {
-        String dbPassword = user.getPassword();
+	public void lockAccount(User user) throws KustvaktException {
+		if (!(user instanceof KorAPUser))
+			throw new KustvaktException(StatusCodes.REQUEST_INVALID);
 
-        if (oldPassword.trim().equals(newPassword.trim())) {
-            // TODO: special error StatusCodes for this?
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.ILLEGAL_ARGUMENT),
-                    StatusCodes.PASSWORD_RESET_FAILED, newPassword);
-        }
+		KorAPUser u = (KorAPUser) user;
+		u.setAccountLocked(true);
+		jlog.info("locking account for user: {}", user.getUsername());
+		entHandler.updateAccount(u);
+	}
 
-        boolean check = crypto.checkHash(oldPassword, dbPassword);
+	public KorAPUser checkPasswordAllowance(KorAPUser user, String oldPassword, String newPassword)
+			throws KustvaktException {
+		String dbPassword = user.getPassword();
 
-        if (!check)
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.BAD_CREDENTIALS),
-                    StatusCodes.PASSWORD_RESET_FAILED);
+		if (oldPassword.trim().equals(newPassword.trim())) {
+			// TODO: special error StatusCodes for this?
+			throw new WrappedException(new KustvaktException(user.getId(), StatusCodes.ILLEGAL_ARGUMENT),
+					StatusCodes.PASSWORD_RESET_FAILED, newPassword);
+		}
 
-        try {
-            user.setPassword(crypto.secureHash(newPassword));
-        }
-        catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
-                    newPassword), StatusCodes.PASSWORD_RESET_FAILED,
-                    user.toString(), newPassword);
-        }
-        return user;
-    }
+		boolean check = crypto.checkHash(oldPassword, dbPassword);
 
+		if (!check)
+			throw new WrappedException(new KustvaktException(user.getId(), StatusCodes.BAD_CREDENTIALS),
+					StatusCodes.PASSWORD_RESET_FAILED);
 
-    //fixme: use clientinfo for logging/auditing?! = from where did he access the reset function?
-    @Override
-    public void resetPassword (String uriFragment, String username,
-            String newPassphrase) throws KustvaktException {
-        try {
-            validator.validateEntry(username, Attributes.USERNAME);
-            validator.validateEntry(newPassphrase, Attributes.PASSWORD);
-        } catch (KustvaktException e) {
-            jlog.error("Error: {}", e.string());
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
-                    newPassphrase), StatusCodes.PASSWORD_RESET_FAILED,
-                    username, newPassphrase);
-        }
+		try {
+			user.setPassword(crypto.secureHash(newPassword));
+		} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+			throw new WrappedException(
+					new KustvaktException(user.getId(), StatusCodes.ILLEGAL_ARGUMENT, "password invalid", newPassword),
+					StatusCodes.PASSWORD_RESET_FAILED, user.toString(), newPassword);
+		}
+		return user;
+	}
 
-        try {
-            newPassphrase= crypto.secureHash(newPassphrase);
-        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
-            jlog.error("Encoding/Algorithm Error", e);
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.ILLEGAL_ARGUMENT, "password invalid",
-                    newPassphrase), StatusCodes.PASSWORD_RESET_FAILED,
-                    username, uriFragment, newPassphrase);
-        }
-        int result = entHandler
-                .resetPassphrase(username, uriFragment, newPassphrase);
+	// fixme: use clientinfo for logging/auditing?! = from where did he access
+	// the reset function?
+	@Override
+	public void resetPassword(String uriFragment, String username, String newPassphrase) throws KustvaktException {
+		try {
+			validator.validateEntry(username, Attributes.USERNAME);
+			validator.validateEntry(newPassphrase, Attributes.PASSWORD);
+		} catch (KustvaktException e) {
+			jlog.error("Error: {}", e.string());
+			throw new WrappedException(
+					new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT, "password invalid", newPassphrase),
+					StatusCodes.PASSWORD_RESET_FAILED, username, newPassphrase);
+		}
 
-        if (result == 0)
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.EXPIRED, "URI fragment expired", uriFragment),
-                    StatusCodes.PASSWORD_RESET_FAILED, username, uriFragment);
-        else if (result == 1)
-            jlog.info("successfully reset password for user {}", username);
-    }
+		try {
+			newPassphrase = crypto.secureHash(newPassphrase);
+		} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+			jlog.error("Encoding/Algorithm Error", e);
+			throw new WrappedException(
+					new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT, "password invalid", newPassphrase),
+					StatusCodes.PASSWORD_RESET_FAILED, username, uriFragment, newPassphrase);
+		}
+		int result = entHandler.resetPassphrase(username, uriFragment, newPassphrase);
 
+		if (result == 0)
+			throw new WrappedException(
+					new KustvaktException(username, StatusCodes.EXPIRED, "URI fragment expired", uriFragment),
+					StatusCodes.PASSWORD_RESET_FAILED, username, uriFragment);
+		else if (result == 1)
+			jlog.info("successfully reset password for user {}", username);
+	}
 
-    public void confirmRegistration (String uriFragment, String username)
-            throws KustvaktException {
-        try {
-            validator.validateEntry(username, Attributes.USERNAME);
-        } catch (KustvaktException e) {
-            jlog.error("Error: {}", e.string());
-            throw new WrappedException(e,
-                    StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
-                    uriFragment);
-        }
-        int r = entHandler.activateAccount(username, uriFragment);
-        if (r == 0) {
-            User user;
-            try {
-                user = entHandler.getAccount(username);
-            }
-            catch (EmptyResultException e) {
-                throw new WrappedException(new KustvaktException(username,
-                        StatusCodes.BAD_CREDENTIALS),
-                        StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
-                        uriFragment);
-            }
-            entHandler.deleteAccount(user.getId());
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.EXPIRED),
-                    StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username,
-                    uriFragment);
-        }
-        else if (r == 1)
-            jlog.info("successfully confirmed user registration for user {}",
-                    username);
-        // register successful audit!
-    }
+	public void confirmRegistration(String uriFragment, String username) throws KustvaktException {
+		try {
+			validator.validateEntry(username, Attributes.USERNAME);
+		} catch (KustvaktException e) {
+			jlog.error("Error: {}", e.string());
+			throw new WrappedException(e, StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username, uriFragment);
+		}
+		int r = entHandler.activateAccount(username, uriFragment);
+		if (r == 0) {
+			User user;
+			try {
+				user = entHandler.getAccount(username);
+			} catch (EmptyResultException e) {
+				throw new WrappedException(new KustvaktException(username, StatusCodes.BAD_CREDENTIALS),
+						StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username, uriFragment);
+			}
+			entHandler.deleteAccount(user.getId());
+			throw new WrappedException(new KustvaktException(user.getId(), StatusCodes.EXPIRED),
+					StatusCodes.ACCOUNT_CONFIRMATION_FAILED, username, uriFragment);
+		} else if (r == 1)
+			jlog.info("successfully confirmed user registration for user {}", username);
+		// register successful audit!
+	}
 
+	/**
+	 * @param attributes
+	 * @return
+	 * @throws KustvaktException
+	 */
+	// fixme: remove clientinfo object (not needed), use json representation to
+	// get stuff
+	public User createUserAccount(Map<String, Object> attributes, boolean confirmation_required)
+			throws KustvaktException {
+		Map<String, Object> safeMap = validator.validateMap(attributes);
 
-    /**
-     * @param attributes
-     * @return
-     * @throws KustvaktException
-     */
-    //fixme: remove clientinfo object (not needed), use json representation to get stuff
-    public User createUserAccount (Map<String, Object> attributes,
-            boolean confirmation_required) throws KustvaktException {
-        Map<String, Object> safeMap = validator.validateMap(attributes);
+		if (safeMap.get(Attributes.USERNAME) == null || ((String) safeMap.get(Attributes.USERNAME)).isEmpty())
+			throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT, "username must be set", "username");
+		if (safeMap.get(Attributes.PASSWORD) == null || ((String) safeMap.get(Attributes.PASSWORD)).isEmpty())
+			throw new KustvaktException(safeMap.get(Attributes.USERNAME), StatusCodes.ILLEGAL_ARGUMENT,
+					"password must be set", "password");
 
-        if (safeMap.get(Attributes.USERNAME) == null
-                || ((String) safeMap.get(Attributes.USERNAME)).isEmpty())
-            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT,
-                    "username must be set", "username");
-        if (safeMap.get(Attributes.PASSWORD) == null
-                || ((String) safeMap.get(Attributes.PASSWORD)).isEmpty())
-            throw new KustvaktException(safeMap.get(Attributes.USERNAME),
-                    StatusCodes.ILLEGAL_ARGUMENT, "password must be set",
-                    "password");
+		String username = validator.validateEntry((String) safeMap.get(Attributes.USERNAME), Attributes.USERNAME);
+		String password = validator.validateEntry((String) safeMap.get(Attributes.PASSWORD), Attributes.PASSWORD);
+		String hash;
+		try {
+			hash = crypto.secureHash(password);
+		} catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
+			jlog.error("Encryption error", e);
+			throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+		}
 
-        String username = validator.validateEntry(
-                (String) safeMap.get(Attributes.USERNAME), Attributes.USERNAME);
-        String password = validator.validateEntry(
-                (String) safeMap.get(Attributes.PASSWORD), Attributes.PASSWORD);
-        String hash;
-        try {
-            hash = crypto.secureHash(password);
-        }
-        catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
-            jlog.error("Encryption error", e);
-            throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
-        }
+		KorAPUser user = User.UserFactory.getUser(username);
+		Object id = attributes.get(Attributes.ID);
+		if (id != null && id instanceof Integer)
+			user.setId((Integer) id);
 
-        KorAPUser user = User.UserFactory.getUser(username);
-        Object id = attributes.get(Attributes.ID);
-        if (id != null && id instanceof Integer)
-            user.setId((Integer) id);
+		user.setAccountLocked(confirmation_required);
+		if (confirmation_required) {
+			URIParam param = new URIParam(crypto.createToken(),
+					TimeUtils.plusSeconds(config.getTokenTTL()).getMillis());
+			user.addField(param);
+		}
+		user.setPassword(hash);
 
-        user.setAccountLocked(confirmation_required);
-        if (confirmation_required) {
-            URIParam param = new URIParam(crypto.createToken(), TimeUtils
-                    .plusSeconds(config.getTokenTTL()).getMillis());
-            user.addField(param);
-        }
-        user.setPassword(hash);
-        
-        String o = (String) attributes.get(Attributes.IS_ADMIN);
+		String o = (String) attributes.get(Attributes.IS_ADMIN);
 		boolean b = Boolean.parseBoolean(o);
 		user.setAdmin(b);
-        
-        try {
-            UserDetails details = new UserDetails();
-            details.read(safeMap, true);
 
-            UserSettings settings = new UserSettings();
-            settings.read(safeMap, true);
+		try {
+			UserDetails details = new UserDetails();
+			details.read(safeMap, true);
 
-            jlog.info("Creating new user account for user {}",
-                    user.getUsername());
-            entHandler.createAccount(user);
-            if (user.isAdmin() && user instanceof KorAPUser){
-            	adminHandler.addAccount(user);
-            	user.setCorpusAccess(CorpusAccess.ALL);
-            }
-            details.setUserId(user.getId());
-            settings.setUserId(user.getId());
+			UserSettings settings = new UserSettings();
+			settings.read(safeMap, true);
 
-            UserDataDbIface dao = BeansFactory.getTypeFactory()
-                    .getTypeInterfaceBean(userdatadaos, UserDetails.class);
-            //todo: remove this
-            assert dao != null;
-            dao.store(details);
-            dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(
-                    userdatadaos, UserSettings.class);
-            assert dao != null;
-            dao.store(settings);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Error: {}", e.string());
-            throw new WrappedException(e, StatusCodes.CREATE_ACCOUNT_FAILED,
-                    user.toString());
-        }
+			jlog.info("Creating new user account for user {}", user.getUsername());
+			entHandler.createAccount(user);
+			if (user.isAdmin() && user instanceof KorAPUser) {
+				adminHandler.addAccount(user);
+				user.setCorpusAccess(CorpusAccess.ALL);
+			}
+			details.setUserId(user.getId());
+			settings.setUserId(user.getId());
 
-        auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
-                StatusCodes.CREATE_ACCOUNT_SUCCESSFUL));
-        return user;
-    }
+			UserDataDbIface dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos, UserDetails.class);
+			// todo: remove this
+			assert dao != null;
+			dao.store(details);
+			dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos, UserSettings.class);
+			assert dao != null;
+			dao.store(settings);
+		} catch (KustvaktException e) {
+			jlog.error("Error: {}", e.string());
+			throw new WrappedException(e, StatusCodes.CREATE_ACCOUNT_FAILED, user.toString());
+		}
 
+		auditing.audit(AuditRecord.serviceRecord(user.getUsername(), StatusCodes.CREATE_ACCOUNT_SUCCESSFUL));
+		return user;
+	}
 
-    //todo:
-    private ShibUser createShibbUserAccount (Map<String, Object> attributes)
-            throws KustvaktException {
-        jlog.debug("creating shibboleth user account for user attr: {}",
-                attributes);
-        Map<String, Object> safeMap = validator.validateMap(attributes);
+	// todo:
+	private ShibUser createShibbUserAccount(Map<String, Object> attributes) throws KustvaktException {
+		jlog.debug("creating shibboleth user account for user attr: {}", attributes);
+		Map<String, Object> safeMap = validator.validateMap(attributes);
 
-        //todo eppn non-unique.join with idp or use persistent_id as username identifier
-        ShibUser user = User.UserFactory.getShibInstance(
-                (String) safeMap.get(Attributes.EPPN),
-                (String) safeMap.get(Attributes.MAIL),
-                (String) safeMap.get(Attributes.CN));
-        user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
-        user.setAccountCreation(TimeUtils.getNow().getMillis());
+		// todo eppn non-unique.join with idp or use persistent_id as username
+		// identifier
+		ShibUser user = User.UserFactory.getShibInstance((String) safeMap.get(Attributes.EPPN),
+				(String) safeMap.get(Attributes.MAIL), (String) safeMap.get(Attributes.CN));
+		user.setAffiliation((String) safeMap.get(Attributes.EDU_AFFIL));
+		user.setAccountCreation(TimeUtils.getNow().getMillis());
 
+		UserDetails d = new UserDetails();
+		d.read(attributes, true);
 
-        UserDetails d = new UserDetails();
-        d.read(attributes, true);
+		UserSettings s = new UserSettings();
+		s.read(attributes, true);
 
-        UserSettings s = new UserSettings();
-        s.read(attributes, true);
+		entHandler.createAccount(user);
 
-        entHandler.createAccount(user);
+		s.setUserId(user.getId());
+		d.setUserId(user.getId());
 
-        s.setUserId(user.getId());
-        d.setUserId(user.getId());
+		UserDataDbIface dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos, UserDetails.class);
+		assert dao != null;
+		dao.store(d);
 
-        UserDataDbIface dao = BeansFactory.getTypeFactory()
-                .getTypeInterfaceBean(userdatadaos, UserDetails.class);
-        assert dao != null;
-        dao.store(d);
+		dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos, UserSettings.class);
+		assert dao != null;
+		dao.store(d);
 
-        dao = BeansFactory.getTypeFactory().getTypeInterfaceBean(userdatadaos,
-                UserSettings.class);
-        assert dao != null;
-        dao.store(d);
+		return user;
+	}
 
-        return user;
-    }
+	/**
+	 * link shibboleth and korap user account to one another.
+	 * 
+	 * @param current
+	 *            currently logged in user
+	 * @param for_name
+	 *            foreign user name the current account should be linked to
+	 * @param transstrat
+	 *            transfer status of user data (details, settings, user queries)
+	 *            0 = the currently logged in data should be kept 1 = the
+	 *            foreign account data should be kept
+	 * @throws NotAuthorizedException
+	 * @throws KustvaktException
+	 */
+	// todo:
+	public void accountLink(User current, String for_name, int transstrat) throws KustvaktException {
+		// User foreign = entHandler.getAccount(for_name);
 
+		// if (current.getAccountLink() == null && current.getAccountLink()
+		// .isEmpty()) {
+		// if (current instanceof KorAPUser && foreign instanceof ShibUser) {
+		// if (transstrat == 1)
+		// current.transfer(foreign);
+		//// foreign.setAccountLink(current.getUsername());
+		//// current.setAccountLink(foreign.getUsername());
+		// // entHandler.purgeDetails(foreign);
+		// // entHandler.purgeSettings(foreign);
+		// }else if (foreign instanceof KorAPUser
+		// && current instanceof ShibUser) {
+		// if (transstrat == 0)
+		// foreign.transfer(current);
+		//// current.setAccountLink(foreign.getUsername());
+		// // entHandler.purgeDetails(current);
+		// // entHandler.purgeSettings(current);
+		// // entHandler.purgeSettings(current);
+		// }
+		// entHandler.updateAccount(current);
+		// entHandler.updateAccount(foreign);
+		// }
+	}
 
-    /**
-     * link shibboleth and korap user account to one another.
-     * 
-     * @param current
-     *            currently logged in user
-     * @param for_name
-     *            foreign user name the current account should be
-     *            linked to
-     * @param transstrat
-     *            transfer status of user data (details, settings,
-     *            user queries)
-     *            0 = the currently logged in data should be kept
-     *            1 = the foreign account data should be kept
-     * @throws NotAuthorizedException
-     * @throws KustvaktException
-     */
-    // todo:
-    public void accountLink (User current, String for_name, int transstrat)
-            throws KustvaktException {
-        //        User foreign = entHandler.getAccount(for_name);
+	// todo: test and rest usage?!
+	public boolean updateAccount(User user) throws KustvaktException {
+		boolean result;
+		if (user instanceof DemoUser)
+			throw new KustvaktException(user.getId(), StatusCodes.REQUEST_INVALID,
+					"account not updateable for demo user", user.getUsername());
+		else {
+			// crypto.validate(user);
+			try {
+				result = entHandler.updateAccount(user) > 0;
+			} catch (KustvaktException e) {
+				jlog.error("Error: {}", e.string());
+				throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
+			}
+		}
+		if (result) {
+			// this.removeCacheEntry(user.getUsername());
+			auditing.audit(
+					AuditRecord.serviceRecord(user.getId(), StatusCodes.UPDATE_ACCOUNT_SUCCESSFUL, user.toString()));
+		}
+		return result;
+	}
 
-        //        if (current.getAccountLink() == null && current.getAccountLink()
-        //                .isEmpty()) {
-        //            if (current instanceof KorAPUser && foreign instanceof ShibUser) {
-        //                if (transstrat == 1)
-        //                    current.transfer(foreign);
-        ////                foreign.setAccountLink(current.getUsername());
-        ////                current.setAccountLink(foreign.getUsername());
-        //                //                entHandler.purgeDetails(foreign);
-        //                //                entHandler.purgeSettings(foreign);
-        //            }else if (foreign instanceof KorAPUser
-        //                    && current instanceof ShibUser) {
-        //                if (transstrat == 0)
-        //                    foreign.transfer(current);
-        ////                current.setAccountLink(foreign.getUsername());
-        //                //                entHandler.purgeDetails(current);
-        //                //                entHandler.purgeSettings(current);
-        //                //                entHandler.purgeSettings(current);
-        //            }
-        //        entHandler.updateAccount(current);
-        //        entHandler.updateAccount(foreign);
-        //        }
-    }
+	public boolean deleteAccount(User user) throws KustvaktException {
+		boolean result;
+		if (user instanceof DemoUser)
+			return true;
+		else {
+			try {
+				result = entHandler.deleteAccount(user.getId()) > 0;
+			} catch (KustvaktException e) {
+				jlog.error("Error: {}", e.string());
+				throw new WrappedException(e, StatusCodes.DELETE_ACCOUNT_FAILED);
+			}
+		}
+		if (result) {
+			// this.removeCacheEntry(user.getUsername());
+			auditing.audit(AuditRecord.serviceRecord(user.getUsername(), StatusCodes.DELETE_ACCOUNT_SUCCESSFUL,
+					user.toString()));
+		}
+		return result;
+	}
 
+	public Object[] validateResetPasswordRequest(String username, String email) throws KustvaktException {
+		String uritoken;
+		validator.validateEntry(email, Attributes.EMAIL);
+		User ident;
+		try {
+			ident = entHandler.getAccount(username);
+			if (ident instanceof DemoUser)
+				// throw new
+				// NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
+				// "password reset now allowed for DemoUser", "");
+				throw new WrappedException(username, StatusCodes.PASSWORD_RESET_FAILED, username);
+		} catch (EmptyResultException e) {
+			throw new WrappedException(
+					new KustvaktException(username, StatusCodes.ILLEGAL_ARGUMENT, "username not found", username),
+					StatusCodes.PASSWORD_RESET_FAILED, username);
+		}
 
-    // todo: test and rest usage?!
-    public boolean updateAccount (User user) throws KustvaktException {
-        boolean result;
-        if (user instanceof DemoUser)
-            throw new KustvaktException(user.getId(),
-                    StatusCodes.REQUEST_INVALID,
-                    "account not updateable for demo user", user.getUsername());
-        else {
-            //            crypto.validate(user);
-            try {
-                result = entHandler.updateAccount(user) > 0;
-            }
-            catch (KustvaktException e) {
-                jlog.error("Error: {}", e.string());
-                throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
-            }
-        }
-        if (result) {
-            // this.removeCacheEntry(user.getUsername());
-            auditing.audit(AuditRecord.serviceRecord(user.getId(),
-                    StatusCodes.UPDATE_ACCOUNT_SUCCESSFUL, user.toString()));
-        }
-        return result;
-    }
+		Userdata data = this.getUserData(ident, UserDetails.class);
+		KorAPUser user = (KorAPUser) ident;
 
+		if (!email.equals(data.get(Attributes.EMAIL)))
+			// throw new NotAuthorizedException(StatusCodes.ILLEGAL_ARGUMENT,
+			// "invalid parameter: email", "email");
+			throw new WrappedException(
+					new KustvaktException(user.getId(), StatusCodes.ILLEGAL_ARGUMENT, "email invalid", email),
+					StatusCodes.PASSWORD_RESET_FAILED, email);
+		uritoken = crypto.encodeBase();
+		URIParam param = new URIParam(uritoken, TimeUtils.plusHours(24).getMillis());
+		user.addField(param);
 
-    public boolean deleteAccount (User user) throws KustvaktException {
-        boolean result;
-        if (user instanceof DemoUser)
-            return true;
-        else {
-            try {
-                result = entHandler.deleteAccount(user.getId()) > 0;
-            }
-            catch (KustvaktException e) {
-                jlog.error("Error: {}", e.string());
-                throw new WrappedException(e, StatusCodes.DELETE_ACCOUNT_FAILED);
-            }
-        }
-        if (result) {
-            // this.removeCacheEntry(user.getUsername());
-            auditing.audit(AuditRecord.serviceRecord(user.getUsername(),
-                    StatusCodes.DELETE_ACCOUNT_SUCCESSFUL, user.toString()));
-        }
-        return result;
-    }
+		try {
+			entHandler.updateAccount(user);
+		} catch (KustvaktException e) {
+			jlog.error("Error ", e.string());
+			throw new WrappedException(e, StatusCodes.PASSWORD_RESET_FAILED);
+		}
+		return new Object[] { uritoken, TimeUtils.format(param.getUriExpiration()) };
+	}
 
+	@Override
+	public <T extends Userdata> T getUserData(User user, Class<T> clazz) throws WrappedException {
 
-    public Object[] validateResetPasswordRequest (String username, String email)
-            throws KustvaktException {
-        String uritoken;
-        validator.validateEntry(email, Attributes.EMAIL);
-        User ident;
-        try {
-            ident = entHandler.getAccount(username);
-            if (ident instanceof DemoUser)
-                //            throw new NotAuthorizedException(StatusCodes.PERMISSION_DENIED,
-                //                    "password reset now allowed for DemoUser", "");
-                throw new WrappedException(username,
-                        StatusCodes.PASSWORD_RESET_FAILED, username);
-        }
-        catch (EmptyResultException e) {
-            throw new WrappedException(new KustvaktException(username,
-                    StatusCodes.ILLEGAL_ARGUMENT, "username not found",
-                    username), StatusCodes.PASSWORD_RESET_FAILED, username);
-        }
+		try {
+			UserDataDbIface<T> dao = BeansFactory.getTypeFactory()
+					.getTypeInterfaceBean(BeansFactory.getKustvaktContext().getUserDataProviders(), clazz);
+			T data = null;
+			if (dao != null)
+				data = dao.get(user);
 
-        Userdata data = this.getUserData(ident, UserDetails.class);
-        KorAPUser user = (KorAPUser) ident;
+			if (data == null)
+				throw new KustvaktException(user.getId(), StatusCodes.NO_VALUE_FOUND, "No data found!",
+						clazz.getSimpleName());
+			return data;
+		} catch (KustvaktException e) {
+			jlog.error("Error during user data retrieval: {}", e.getEntity());
+			throw new WrappedException(e, StatusCodes.GET_ACCOUNT_FAILED);
+		}
+	}
 
-        if (!email.equals(data.get(Attributes.EMAIL)))
-            //            throw new NotAuthorizedException(StatusCodes.ILLEGAL_ARGUMENT,
-            //                    "invalid parameter: email", "email");
-            throw new WrappedException(new KustvaktException(user.getId(),
-                    StatusCodes.ILLEGAL_ARGUMENT, "email invalid", email),
-                    StatusCodes.PASSWORD_RESET_FAILED, email);
-        uritoken = crypto.encodeBase();
-        URIParam param = new URIParam(uritoken, TimeUtils.plusHours(24)
-                .getMillis());
-        user.addField(param);
-
-        try {
-            entHandler.updateAccount(user);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Error ", e.string());
-            throw new WrappedException(e, StatusCodes.PASSWORD_RESET_FAILED);
-        }
-        return new Object[] { uritoken, TimeUtils.format(param.getUriExpiration()) };
-    }
-
-
-    @Override
-    public <T extends Userdata> T getUserData (User user, Class<T> clazz)
-            throws WrappedException {
-
-        try {
-            UserDataDbIface<T> dao = BeansFactory.getTypeFactory()
-                    .getTypeInterfaceBean(
-                            BeansFactory.getKustvaktContext()
-                                    .getUserDataProviders(), clazz);
-            T data = null;
-            if (dao != null)
-                data = dao.get(user);
-
-            if (data == null)
-                throw new KustvaktException(user.getId(),
-                        StatusCodes.NO_VALUE_FOUND, "No data found!",
-                        clazz.getSimpleName());
-            return data;
-        }
-        catch (KustvaktException e) {
-            jlog.error("Error during user data retrieval: {}", e.getEntity());
-            throw new WrappedException(e, StatusCodes.GET_ACCOUNT_FAILED);
-        }
-    }
-
-
-    //todo: cache userdata outside of the user object!
-    @Override
-    public void updateUserData (Userdata data) throws WrappedException {
-        try {
-            data.validate(this.validator);
-            UserDataDbIface dao = BeansFactory.getTypeFactory()
-                    .getTypeInterfaceBean(
-                            BeansFactory.getKustvaktContext()
-                                    .getUserDataProviders(), data.getClass());
-            if (dao != null)
-                dao.update(data);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Error during update of user data!", e.getEntity());
-            throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
-        }
-    }
+	// todo: cache userdata outside of the user object!
+	@Override
+	public void updateUserData(Userdata data) throws WrappedException {
+		try {
+			data.validate(this.validator);
+			UserDataDbIface dao = BeansFactory.getTypeFactory()
+					.getTypeInterfaceBean(BeansFactory.getKustvaktContext().getUserDataProviders(), data.getClass());
+			if (dao != null)
+				dao.update(data);
+		} catch (KustvaktException e) {
+			jlog.error("Error during update of user data!", e.getEntity());
+			throw new WrappedException(e, StatusCodes.UPDATE_ACCOUNT_FAILED);
+		}
+	}
 }
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
index 6706967..c6c0b04 100644
--- a/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
@@ -4,6 +4,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+import org.eclipse.jetty.http.HttpHeaders;
 import org.junit.BeforeClass;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -56,6 +57,7 @@
 
     // EM: Cannot be tested yet
     @Test
+    @Ignore
     public void testGetMatchInfoWithAuthentication () {
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").path("WPD15").path("B07").path("51608")
@@ -63,6 +65,7 @@
                 .queryParam("foundry", "*")
                 .header(Attributes.AUTHORIZATION,
                         BasicHttpAuth.encode("kustvakt", "kustvakt2015"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "172.27.0.32")
                 .get(ClientResponse.class);
 
         String entity = response.getEntity(String.class);
