diff --git a/full/Changes b/full/Changes
index bcc23a1..02d7491 100644
--- a/full/Changes
+++ b/full/Changes
@@ -16,7 +16,11 @@
 16/01/2019
    - Added a PUT request for both creating and editing vc (margaretha)
    - Added aliases to some VC controllers (margaretha)
-   - Merged VC access list controllers (margaretha)  
+   - Merged VC access list controllers (margaretha)
+21/01/2019
+   - Removed codes related to user registration & password management (margaretha)  
+22/01/2019
+   - Added create, edit, retrieve user default setting controllers (margaretha)
 
 # version 0.61.4
 14/11/2018
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index fa2d380..99e707d 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -621,7 +621,7 @@
 		entHandler.updateAccount(u);
 	}
 
-		// todo:
+	@Deprecated	// todo:
 	private ShibbolethUser createShibbUserAccount(Map<String, Object> attributes) throws KustvaktException {
         if (DEBUG) {
             jlog.debug("creating shibboleth user account for user attr: "
@@ -746,6 +746,7 @@
 	}
 
 	// EM: not in the new DB
+	@Deprecated
 	@Override
 	public <T extends Userdata> T getUserData(User user, Class<T> clazz) throws WrappedException {
 		try {
@@ -765,6 +766,7 @@
 		}
 	}
 
+	@Deprecated
 	// todo: cache userdata outside of the user object!
 	@Override
 	public void updateUserData(Userdata data) throws WrappedException {
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
new file mode 100644
index 0000000..1a60efc
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
@@ -0,0 +1,81 @@
+package de.ids_mannheim.korap.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.entity.DefaultSetting;
+import de.ids_mannheim.korap.entity.DefaultSetting_;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.ParameterChecker;
+
+@Transactional
+@Repository
+public class DefaultSettingDao {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    /**
+     * Creates a new entry of default setting in the database. This
+     * method allows storing settings of an empty json object, i.e.
+     * {}.
+     * 
+     * @param username
+     *            username
+     * @param settings
+     *            default settings in json
+     * @throws KustvaktException
+     */
+    public void createDefaultSetting (String username, String settings)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(username, "username");
+        ParameterChecker.checkStringValue(settings, "settings");
+        DefaultSetting us = new DefaultSetting(username, settings);
+        entityManager.persist(us);
+    }
+
+    public void updateDefaultSetting (DefaultSetting defaultSetting)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(defaultSetting, "defaultSetting");
+        entityManager.merge(defaultSetting);
+    }
+
+    public void deleteDefaultSetting (DefaultSetting defaultSetting)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(defaultSetting, "defaultSetting");
+        if (!entityManager.contains(defaultSetting)) {
+            defaultSetting = entityManager.merge(defaultSetting);
+        }
+        entityManager.remove(defaultSetting);
+
+    }
+
+    public DefaultSetting retrieveDefautlSetting (String username)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(username, "username");
+
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<DefaultSetting> query =
+                criteriaBuilder.createQuery(DefaultSetting.class);
+        Root<DefaultSetting> defaultSetting = query.from(DefaultSetting.class);
+
+        query.select(defaultSetting);
+        query.where(criteriaBuilder
+                .equal(defaultSetting.get(DefaultSetting_.username), username));
+        Query q = entityManager.createQuery(query);
+        try {
+            return (DefaultSetting) q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            return null;
+        }
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java b/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java
new file mode 100644
index 0000000..b485ab5
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java
@@ -0,0 +1,56 @@
+package de.ids_mannheim.korap.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Describes default_setting table. Each user may define one set of
+ * default settings. The elements of default settings are
+ * not strictly defined and thus are described as JSON strings.
+ * 
+ * Some elements that are often used may be adopted as columns.
+ * 
+ * Examples of the default settings' elements are foundry, layer and
+ * number of results per page.
+ * 
+ * @author margaretha
+ *
+ */
+@Entity
+@Table(name = "default_setting")
+public class DefaultSetting {
+
+    @Id
+    private String username;
+    private String settings; // json string
+
+    public DefaultSetting () {}
+
+    public DefaultSetting (String username, String settings) {
+        this.username = username;
+        this.settings = settings;
+    }
+
+    @Override
+    public String toString () {
+        return "name= " + getUsername() + ", settings= " + getSettings();
+    }
+
+    public String getUsername () {
+        return username;
+    }
+
+    public void setUsername (String username) {
+        this.username = username;
+    }
+
+    public String getSettings () {
+        return settings;
+    }
+
+    public void setSettings (String settings) {
+        this.settings = settings;
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java b/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
new file mode 100644
index 0000000..39ee4ce
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
@@ -0,0 +1,71 @@
+package de.ids_mannheim.korap.service;
+
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.dao.DefaultSettingDao;
+import de.ids_mannheim.korap.entity.DefaultSetting;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
+
+@Service
+public class DefaultSettingService {
+
+    @Autowired
+    private DefaultSettingDao settingDao;
+
+    public void handlePutRequest (String username,
+            Map<String, Object> form, String authenticatedUser)
+            throws KustvaktException {
+        if (!username.equals(authenticatedUser)) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "Username verification failed. Path parameter username "
+                            + "must be the same as the authenticated username.");
+        }
+        else if (form == null || form.isEmpty()) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "Entity body is empty. No settings are given.");
+        }
+
+        Userdata userdata = new UserSettings(username);
+        userdata.readQuietly(form, false);
+
+        DefaultSetting defaultSetting =
+                settingDao.retrieveDefautlSetting(username);
+        if (defaultSetting == null) {
+            createDefaultSetting(username, userdata);
+        }
+        else {
+            updateDefaultSetting(defaultSetting, userdata);
+        }
+    }
+
+    public void createDefaultSetting (String username, Userdata userdata)
+            throws KustvaktException {
+        String jsonSettings = userdata.serialize();
+        settingDao.createDefaultSetting(username, jsonSettings);
+    }
+
+    public void updateDefaultSetting (DefaultSetting setting, Userdata newData)
+            throws KustvaktException {
+        Userdata existingData = new UserSettings(setting.getUsername());
+        existingData.setData(setting.getSettings());
+        existingData.update(newData);
+
+        String newSettings = existingData.serialize();
+        setting.setSettings(newSettings);
+        settingDao.updateDefaultSetting(setting);
+    }
+
+    public String retrieveDefaultSettings (String username)
+            throws KustvaktException {
+        DefaultSetting defaultSetting =
+                settingDao.retrieveDefautlSetting(username);
+        return defaultSetting.getSettings();
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java
new file mode 100644
index 0000000..bd95f13
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java
@@ -0,0 +1,340 @@
+package de.ids_mannheim.korap.web.controller;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.spi.container.ResourceFilters;
+
+import de.ids_mannheim.korap.authentication.AuthenticationManager;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.Scopes;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
+import de.ids_mannheim.korap.user.KorAPUser;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.UserDetails;
+import de.ids_mannheim.korap.user.UserQuery;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.web.KustvaktResponseHandler;
+import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.BlockingFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+/** 
+ * 
+ * @author hanl, margaretha
+ */
+@Controller
+@Path("{version}/shibboleth/user")
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+@ResourceFilters({APIVersionFilter.class, PiwikFilter.class })
+public class ShibbolethUserController {
+
+    @Autowired
+    private KustvaktResponseHandler kustvaktResponseHandler;
+
+    private static Logger jlog = LogManager.getLogger(ShibbolethUserController.class);
+    @Autowired
+    private AuthenticationManager controller;
+
+    private @Context UriInfo info;
+
+    // EM: may be used for managing shib users
+    //todo: password update in special function? --> password reset only!
+    @POST
+    @Path("update")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateAccount (@Context SecurityContext ctx, String json) {
+        TokenContext context = (TokenContext) ctx.getUserPrincipal();
+        try {
+            User user = controller.getUser(context.getUsername());
+
+            JsonNode node = JsonUtils.readTree(json);
+            KorAPUser ident = (KorAPUser) user;
+            KorAPUser values = User.UserFactory.toUser(json);
+            //            user = controller
+            //                    .checkPasswordAllowance(ident, values.getPassword(),
+            //                            node.path("new_password").asText());
+            //            controller.updateAccount(user);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+    
+    // todo: refactor and make something out of if --> needs to give some sort of feedback!
+    @GET
+    @Path("info")
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response getStatus (@Context SecurityContext context,
+            @QueryParam("scopes") String scopes) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Scopes m;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserDetails.class);
+
+            Set<String> base_scope = StringUtils.toSet(scopes, " ");
+            if (scopes != null) base_scope.retainAll(StringUtils.toSet(scopes));
+            scopes = StringUtils.toString(base_scope);
+            m = Scopes.mapScopes(scopes, data);
+            return Response.ok(m.toEntity()).build();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+
+
+    @GET
+    @Path("settings")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getUserSettings (@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String result;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserSettings.class);
+            data.setField(Attributes.USERNAME, ctx.getUsername());
+            result = data.serialize();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
+
+
+    @Deprecated
+    @POST
+    @Path("settings")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateSettings (@Context SecurityContext context,
+            @Context Locale locale, Map settings) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+
+        if (settings == null) return Response.notModified().build();
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            if (User.UserFactory.isDemo(ctx.getUsername()))
+                return Response.notModified().build();
+
+            Userdata data = controller.getUserData(user, UserSettings.class);
+            // todo: check setting only within the scope of user settings permissions; not foundry range. Latter is part of
+            // frontend which only displays available foundries and
+            //            SecurityManager.findbyId(us.getDefaultConstfoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultLemmafoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultPOSfoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultRelfoundry(), user, Foundry.class);
+            Userdata new_data = new UserSettings(user.getId());
+            new_data.readQuietly((Map<String, Object>) settings, false);
+            data.update(new_data);
+            controller.updateUserData(data);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("details")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getDetails (@Context SecurityContext context,
+            @Context Locale locale, @QueryParam("pointer") String pointer) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String result;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserDetails.class);
+            data.setField(Attributes.USERNAME, ctx.getUsername());
+            if (pointer != null)
+                result = data.get(pointer).toString();
+            else
+                result = data.serialize();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: "+ e.string());
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
+
+
+    // EM: may be used for managing shib users
+    @POST
+    @Path("details")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateDetails (@Context SecurityContext context,
+            @Context Locale locale, Map details) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+
+        if (details == null) return Response.notModified().build();
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            if (User.UserFactory.isDemo(ctx.getUsername()))
+                return Response.notModified().build();
+
+            UserDetails new_data = new UserDetails(user.getId());
+            new_data.readQuietly((Map<String, Object>) details, false);
+
+            UserDetails det = controller.getUserData(user, UserDetails.class);
+            det.update(new_data);
+            controller.updateUserData(det);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+
+    //fixme: if policy allows, foreign user might be allowed to change search!
+    @POST
+    @Path("queries")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateQueries (@Context SecurityContext context,
+            String json) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Collection<UserQuery> add = new HashSet<>();
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            List<UserQuery> userQuieres = new ArrayList<>();
+            JsonNode nodes = JsonUtils.readTree(json);
+            Iterator<JsonNode> node = nodes.elements();
+            while (node.hasNext()) {
+                JsonNode cursor = node.next();
+                UserQuery query =
+                        new UserQuery(cursor.path("id").asInt(), user.getId());
+                query.setQueryLanguage(cursor.path("queryLanguage").asText());
+                query.setQuery(cursor.path("query").asText());
+                query.setDescription(cursor.path("description").asText());
+                userQuieres.add(query);
+            }
+
+            //1: add all that are new, update all that are retained, delete the rest
+            //            Set<UserQuery> resources = ResourceFinder
+            //                    .search(user, UserQuery.class);
+            //
+            //            add.addAll(userQuieres);
+            //            add.removeAll(resources);
+            //            Collection<UserQuery> update = new HashSet<>(userQuieres);
+            //            update.retainAll(resources);
+            //            resources.removeAll(userQuieres);
+            //
+            //            if (!update.isEmpty()) {
+            //                resourceHandler.updateResources(user,
+            //                        update.toArray(new UserQuery[update.size()]));
+            //            }
+            //            if (!add.isEmpty()) {
+            //                resourceHandler.storeResources(user,
+            //                        add.toArray(new UserQuery[add.size()]));
+            //            }
+            //            if (!resources.isEmpty()) {
+            //                resourceHandler.deleteResources(user,
+            //                        resources.toArray(new UserQuery[resources.size()]));
+            //            }
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        try {
+            return Response.ok(JsonUtils.toJSON(add)).build();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+
+    // EM: may be used for managing shib users
+    @DELETE
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response deleteUser (@Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            //todo: test that demo user cannot be deleted!
+            controller.deleteAccount(user);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+
+    @GET
+    @Path("queries")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getQueries (@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String queryStr;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            //            Set<UserQuery> queries = ResourceFinder
+            //                    .search(user, UserQuery.class);
+            //            queryStr = JsonUtils.toJSON(queries);
+            //todo:
+            queryStr = "";
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(queryStr).build();
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
index 216cad5..904fab4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
@@ -1,339 +1,91 @@
 package de.ids_mannheim.korap.web.controller;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
-import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
-import javax.ws.rs.core.UriInfo;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
-import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.jersey.spi.container.ResourceFilters;
 
-import de.ids_mannheim.korap.authentication.AuthenticationManager;
-import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.Scopes;
+import de.ids_mannheim.korap.constant.OAuth2Scope;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.service.OAuth2ScopeService;
 import de.ids_mannheim.korap.security.context.TokenContext;
-import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.User;
-import de.ids_mannheim.korap.user.UserDetails;
-import de.ids_mannheim.korap.user.UserQuery;
-import de.ids_mannheim.korap.user.UserSettings;
-import de.ids_mannheim.korap.user.Userdata;
-import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.service.DefaultSettingService;
 import de.ids_mannheim.korap.web.KustvaktResponseHandler;
 import de.ids_mannheim.korap.web.filter.APIVersionFilter;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
-import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 
-/** 
- * 
- * @author hanl, margaretha
+/**
+ * @author margaretha
+ *
  */
 @Controller
 @Path("{version}/user")
-@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-@ResourceFilters({APIVersionFilter.class, PiwikFilter.class })
+@ResourceFilters({ AuthenticationFilter.class, APIVersionFilter.class,
+        PiwikFilter.class })
 public class UserController {
 
     @Autowired
-    private KustvaktResponseHandler kustvaktResponseHandler;
-
-    private static Logger jlog = LogManager.getLogger(UserController.class);
+    private DefaultSettingService settingService;
     @Autowired
-    private AuthenticationManager controller;
+    private KustvaktResponseHandler kustvaktResponseHandler;
+    @Autowired
+    private OAuth2ScopeService scopeService;
 
-    private @Context UriInfo info;
-
-    // EM: may be used for managing shib users
-    //todo: password update in special function? --> password reset only!
-    @POST
-    @Path("update")
+    @PUT
+    @Path("settings/{username}")
     @Consumes(MediaType.APPLICATION_JSON)
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
-    public Response updateAccount (@Context SecurityContext ctx, String json) {
-        TokenContext context = (TokenContext) ctx.getUserPrincipal();
-        try {
-            User user = controller.getUser(context.getUsername());
+    public Response createDefaultSetting (@Context SecurityContext context,
+            @PathParam("username") String username,
+            Map<String, Object> form) {
 
-            JsonNode node = JsonUtils.readTree(json);
-            KorAPUser ident = (KorAPUser) user;
-            KorAPUser values = User.UserFactory.toUser(json);
-            //            user = controller
-            //                    .checkPasswordAllowance(ident, values.getPassword(),
-            //                            node.path("new_password").asText());
-            //            controller.updateAccount(user);
+        TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
+        try {
+            scopeService.verifyScope(tokenContext,
+                    OAuth2Scope.CREATE_DEFAULT_SETTING);
+            settingService.handlePutRequest(username, form,
+                    tokenContext.getUsername());
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
-    
-    // todo: refactor and make something out of if --> needs to give some sort of feedback!
-    @GET
-    @Path("info")
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response getStatus (@Context SecurityContext context,
-            @QueryParam("scopes") String scopes) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        Scopes m;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserDetails.class);
-
-            Set<String> base_scope = StringUtils.toSet(scopes, " ");
-            if (scopes != null) base_scope.retainAll(StringUtils.toSet(scopes));
-            scopes = StringUtils.toString(base_scope);
-            m = Scopes.mapScopes(scopes, data);
-            return Response.ok(m.toEntity()).build();
-        }
-        catch (KustvaktException e) {
-            throw kustvaktResponseHandler.throwit(e);
-        }
-    }
-
-
-    @GET
-    @Path("settings")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getUserSettings (@Context SecurityContext context,
-            @Context Locale locale) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String result;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserSettings.class);
-            data.setField(Attributes.USERNAME, ctx.getUsername());
-            result = data.serialize();
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(result).build();
-    }
-
-
-    @POST
-    @Path("settings")
-    @Consumes({ MediaType.APPLICATION_JSON })
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response updateSettings (@Context SecurityContext context,
-            @Context Locale locale, Map settings) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-
-        if (settings == null) return Response.notModified().build();
-
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            if (User.UserFactory.isDemo(ctx.getUsername()))
-                return Response.notModified().build();
-
-            Userdata data = controller.getUserData(user, UserSettings.class);
-            // todo: check setting only within the scope of user settings permissions; not foundry range. Latter is part of
-            // frontend which only displays available foundries and
-            //            SecurityManager.findbyId(us.getDefaultConstfoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultLemmafoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultPOSfoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultRelfoundry(), user, Foundry.class);
-            Userdata new_data = new UserSettings(user.getId());
-            new_data.readQuietly((Map<String, Object>) settings, false);
-            data.update(new_data);
-            controller.updateUserData(data);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-
-        return Response.ok().build();
-    }
 
     @GET
-    @Path("details")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getDetails (@Context SecurityContext context,
-            @Context Locale locale, @QueryParam("pointer") String pointer) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String result;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserDetails.class);
-            data.setField(Attributes.USERNAME, ctx.getUsername());
-            if (pointer != null)
-                result = data.get(pointer).toString();
-            else
-                result = data.serialize();
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered: "+ e.string());
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(result).build();
-    }
-
-
-    // EM: may be used for managing shib users
-    @POST
-    @Path("details")
-    @Consumes({ MediaType.APPLICATION_JSON })
+    @Path("settings")
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
-    public Response updateDetails (@Context SecurityContext context,
-            @Context Locale locale, Map details) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-
-        if (details == null) return Response.notModified().build();
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response createDefaultSetting (@Context SecurityContext context) {
+        TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
 
         try {
-            User user = controller.getUser(ctx.getUsername());
-            if (User.UserFactory.isDemo(ctx.getUsername()))
-                return Response.notModified().build();
-
-            UserDetails new_data = new UserDetails(user.getId());
-            new_data.readQuietly((Map<String, Object>) details, false);
-
-            UserDetails det = controller.getUserData(user, UserDetails.class);
-            det.update(new_data);
-            controller.updateUserData(det);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok().build();
-    }
-
-
-    //fixme: if policy allows, foreign user might be allowed to change search!
-    @POST
-    @Path("queries")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response updateQueries (@Context SecurityContext context,
-            String json) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        Collection<UserQuery> add = new HashSet<>();
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            List<UserQuery> userQuieres = new ArrayList<>();
-            JsonNode nodes = JsonUtils.readTree(json);
-            Iterator<JsonNode> node = nodes.elements();
-            while (node.hasNext()) {
-                JsonNode cursor = node.next();
-                UserQuery query =
-                        new UserQuery(cursor.path("id").asInt(), user.getId());
-                query.setQueryLanguage(cursor.path("queryLanguage").asText());
-                query.setQuery(cursor.path("query").asText());
-                query.setDescription(cursor.path("description").asText());
-                userQuieres.add(query);
-            }
-
-            //1: add all that are new, update all that are retained, delete the rest
-            //            Set<UserQuery> resources = ResourceFinder
-            //                    .search(user, UserQuery.class);
-            //
-            //            add.addAll(userQuieres);
-            //            add.removeAll(resources);
-            //            Collection<UserQuery> update = new HashSet<>(userQuieres);
-            //            update.retainAll(resources);
-            //            resources.removeAll(userQuieres);
-            //
-            //            if (!update.isEmpty()) {
-            //                resourceHandler.updateResources(user,
-            //                        update.toArray(new UserQuery[update.size()]));
-            //            }
-            //            if (!add.isEmpty()) {
-            //                resourceHandler.storeResources(user,
-            //                        add.toArray(new UserQuery[add.size()]));
-            //            }
-            //            if (!resources.isEmpty()) {
-            //                resourceHandler.deleteResources(user,
-            //                        resources.toArray(new UserQuery[resources.size()]));
-            //            }
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        try {
-            return Response.ok(JsonUtils.toJSON(add)).build();
+            scopeService.verifyScope(tokenContext,
+                    OAuth2Scope.CREATE_DEFAULT_SETTING);
+            String settings = settingService
+                    .retrieveDefaultSettings(tokenContext.getUsername());
+            return Response.ok(settings).build();
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
         }
     }
 
-    // EM: may be used for managing shib users
-    @DELETE
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response deleteUser (@Context SecurityContext context) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            //todo: test that demo user cannot be deleted!
-            controller.deleteAccount(user);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok().build();
-    }
-
-
-    @GET
-    @Path("queries")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getQueries (@Context SecurityContext context,
-            @Context Locale locale) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String queryStr;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            //            Set<UserQuery> queries = ResourceFinder
-            //                    .search(user, UserQuery.class);
-            //            queryStr = JsonUtils.toJSON(queries);
-            //todo:
-            queryStr = "";
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(queryStr).build();
-    }
 }
diff --git a/full/src/main/resources/db/sqlite/V1.6__user_tables.sql b/full/src/main/resources/db/sqlite/V1.6__user_tables.sql
new file mode 100644
index 0000000..9df4a20
--- /dev/null
+++ b/full/src/main/resources/db/sqlite/V1.6__user_tables.sql
@@ -0,0 +1,4 @@
+CREATE TABLE IF NOT EXISTS default_setting (
+    username VARCHAR(100) PRIMARY KEY,
+    settings TEXT NOT NULL
+);
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/user/DataFactoryTest.java b/full/src/test/java/de/ids_mannheim/korap/user/DataFactoryTest.java
new file mode 100644
index 0000000..f5d2fdd
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/user/DataFactoryTest.java
@@ -0,0 +1,186 @@
+package de.ids_mannheim.korap.user;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+/** Taken from UserdataTest
+ * @author hanl
+ * @date 27/01/2016
+ */
+public class DataFactoryTest {
+
+    @Test
+    public void testDataFactoryAdd () throws KustvaktException {
+        String data = "{}";
+        Object node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+
+        data = "[]";
+        node = JsonUtils.readTree(data);
+
+        factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+    }
+
+
+    @Test
+    public void testDataFactoryGet () throws KustvaktException {
+        String data = "{}";
+        Object node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+        Object value = factory.getValue(node, "field_1");
+        assertEquals("value_1", value);
+        value = factory.getValue(node, "field_2");
+        assertEquals(20, value);
+        value = factory.getValue(node, "field_3");
+        assertEquals(true, value);
+
+        data = "[]";
+        node = JsonUtils.readTree(data);
+
+        assertTrue(factory.addValue(node, "", "value_2"));
+        assertTrue(factory.addValue(node, "", 10));
+        assertTrue(factory.addValue(node, "", false));
+
+        value = factory.getValue(node, "/0");
+        assertEquals("value_2", value);
+        value = factory.getValue(node, "/1");
+        assertEquals(10, value);
+        value = factory.getValue(node, "/2");
+        assertEquals(false, value);
+    }
+
+    @Test
+    public void testDataFactoryMerge () throws KustvaktException {
+        String data = "{}";
+        Object node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+
+        data = "{}";
+        Object node2 = JsonUtils.readTree(data);
+        assertTrue(factory.addValue(node2, "field_1", "value_new"));
+        assertTrue(factory.addValue(node2, "field_2", "value_next"));
+        assertTrue(factory.addValue(node2, "field_4", "value_2"));
+        assertTrue(factory.addValue(node2, "field_7", "value_3"));
+
+        JsonNode node_new = (JsonNode) factory.merge(node, node2);
+
+        assertEquals("value_new", node_new.path("field_1").asText());
+        assertEquals("value_next", node_new.path("field_2").asText());
+        assertEquals(true, node_new.path("field_3").asBoolean());
+        assertEquals("value_2", node_new.path("field_4").asText());
+        assertEquals("value_3", node_new.path("field_7").asText());
+
+    }
+    
+    @Test
+    public void testDataFactoryKeys () throws KustvaktException {
+        String data = "{}";
+        Object node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+        assertEquals(3, factory.size(node));
+        assertEquals(3, factory.keys(node).size());
+    }
+
+    @Test
+    @Ignore
+    public void testDataFactoryRemove () throws KustvaktException {
+        String data = "{}";
+        Object node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+        Object value = factory.getValue(node, "field_1");
+        assertEquals("value_1", value);
+        value = factory.getValue(node, "field_2");
+        assertEquals(20, value);
+        value = factory.getValue(node, "field_3");
+        assertEquals(true, value);
+
+        assertTrue(factory.removeValue(node, "field_1"));
+        assertTrue(factory.removeValue(node, "field_2"));
+        assertTrue(factory.removeValue(node, "field_3"));
+        assertNotNull(node);
+        assertEquals("{}", node.toString());
+
+        data = "[]";
+        node = JsonUtils.readTree(data);
+
+        assertTrue(factory.addValue(node, "", "value_2"));
+        assertTrue(factory.addValue(node, "", 10));
+        assertTrue(factory.addValue(node, "", false));
+
+        value = factory.getValue(node, "/0");
+        assertEquals("value_2", value);
+        value = factory.getValue(node, "/1");
+        assertEquals(10, value);
+        value = factory.getValue(node, "/2");
+        assertEquals(false, value);
+
+
+        // fixme: cannot be removed
+        assertTrue(factory.removeValue(node, "0"));
+        assertTrue(factory.removeValue(node, "1"));
+        assertTrue(factory.removeValue(node, "2"));
+        assertNotNull(node);
+        assertEquals("[]", node.toString());
+    }
+    
+    @Test
+    public void testDataFactoryEmbeddedProperty () throws KustvaktException {
+        String data = "{}";
+        JsonNode node = JsonUtils.readTree(data);
+
+        DataFactory factory = DataFactory.getFactory();
+        assertTrue(factory.addValue(node, "field_1", "value_1"));
+        assertTrue(factory.addValue(node, "field_2", 20));
+        assertTrue(factory.addValue(node, "field_3", true));
+
+        ArrayNode array = JsonUtils.createArrayNode();
+        array.add(10);
+        array.add("v1");
+        array.add("v2");
+        factory.addValue(node, "field_3", array);
+
+        assertNotNull(node);
+        assertEquals(10, node.at("/field_3/0").asInt());
+        assertEquals("v1", node.at("/field_3/1").asText());
+        assertEquals("v2", node.at("/field_3/2").asText());
+
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
index aa2c71f..04f8359 100644
--- a/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
@@ -6,16 +6,10 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeanConfigTest;
 import de.ids_mannheim.korap.config.BeansFactory;
@@ -23,12 +17,12 @@
 import de.ids_mannheim.korap.handlers.UserDetailsDao;
 import de.ids_mannheim.korap.handlers.UserSettingsDao;
 import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
-import de.ids_mannheim.korap.utils.JsonUtils;
 
-/**EM: To do: not implemented in the new DB yet
+/**
  * @author hanl
  * @date 27/01/2016
  */
+@Deprecated
 @Ignore
 public class UserdataTest extends BeanConfigTest {
 
@@ -93,7 +87,7 @@
         data.setField(Attributes.COUNTRY, "Germany");
 
         String[] req = data.requiredFields();
-        String[] r = data.missing();
+        String[] r = data.findMissingFields();
         assertNotEquals(0, r.length);
         assertEquals(req.length, r.length);
         assertFalse(data.isValid());
@@ -106,7 +100,7 @@
         data.setField(Attributes.FILE_FORMAT_FOR_EXPORT, "export");
 
         String[] req = data.requiredFields();
-        String[] r = data.missing();
+        String[] r = data.findMissingFields();
         assertEquals(0, r.length);
         assertEquals(req.length, r.length);
         assertTrue(data.isValid());
@@ -129,272 +123,7 @@
         assertTrue(dao instanceof UserSettingsDao);
     }
 
-
-    @Test
-    public void testDataFactoryAdd () throws KustvaktException {
-        String data = "{}";
-        Object node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-
-        data = "[]";
-        node = JsonUtils.readTree(data);
-
-        factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-    }
-
-
-    @Test
-    public void testDataFactoryGet () throws KustvaktException {
-        String data = "{}";
-        Object node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-        Object value = factory.getValue(node, "field_1");
-        assertEquals("value_1", value);
-        value = factory.getValue(node, "field_2");
-        assertEquals(20, value);
-        value = factory.getValue(node, "field_3");
-        assertEquals(true, value);
-
-        data = "[]";
-        node = JsonUtils.readTree(data);
-
-        assertTrue(factory.addValue(node, "", "value_2"));
-        assertTrue(factory.addValue(node, "", 10));
-        assertTrue(factory.addValue(node, "", false));
-
-        value = factory.getValue(node, "/0");
-        assertEquals("value_2", value);
-        value = factory.getValue(node, "/1");
-        assertEquals(10, value);
-        value = factory.getValue(node, "/2");
-        assertEquals(false, value);
-    }
-
-
-    @Test
-    public void testUserDataUpdate () {
-        UserDetails details = new UserDetails(-1);
-        details.setField(Attributes.FIRSTNAME, "first");
-        details.setField(Attributes.LASTNAME, "last");
-        details.setField(Attributes.ADDRESS, "address");
-        details.setField(Attributes.EMAIL, "email");
-
-        UserDetails details2 = new UserDetails(-1);
-        details2.setField(Attributes.COUNTRY, "Germany");
-        details.update(details2);
-
-        assertEquals("first", details.get(Attributes.FIRSTNAME));
-        assertEquals("Germany", details.get(Attributes.COUNTRY));
-    }
-
-
-    @Test
-    public void testDataFactoryEmbeddedProperty () throws KustvaktException {
-        String data = "{}";
-        JsonNode node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-        ArrayNode array = JsonUtils.createArrayNode();
-        array.add(10);
-        array.add("v1");
-        array.add("v2");
-        factory.addValue(node, "field_3", array);
-
-        assertNotNull(node);
-        assertEquals(10, node.at("/field_3/0").asInt());
-        assertEquals("v1", node.at("/field_3/1").asText());
-        assertEquals("v2", node.at("/field_3/2").asText());
-
-    }
-
-
-    @Test
-    public void testUserDataPointerFunction () throws KustvaktException {
-        UserDetails details = new UserDetails(-1);
-        Map<String, Object> m = new HashMap<>();
-        m.put(Attributes.FIRSTNAME, "first");
-        m.put(Attributes.LASTNAME, "last");
-        m.put(Attributes.ADDRESS, "address");
-        m.put(Attributes.EMAIL, "email");
-        details.setData(JsonUtils.toJSON(m));
-
-        ArrayNode array = JsonUtils.createArrayNode();
-        array.add(100);
-        array.add("message");
-        details.setField("errors", array);
-
-        assertEquals(100, details.get("/errors/0"));
-        assertEquals("message", details.get("/errors/1"));
-    }
-
-
-    @Test
-    public void testDataFactoryMerge () throws KustvaktException {
-        String data = "{}";
-        Object node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-
-        data = "{}";
-        Object node2 = JsonUtils.readTree(data);
-        assertTrue(factory.addValue(node2, "field_1", "value_new"));
-        assertTrue(factory.addValue(node2, "field_2", "value_next"));
-        assertTrue(factory.addValue(node2, "field_4", "value_2"));
-        assertTrue(factory.addValue(node2, "field_7", "value_3"));
-
-        JsonNode node_new = (JsonNode) factory.merge(node, node2);
-
-        assertEquals("value_new", node_new.path("field_1").asText());
-        assertEquals("value_next", node_new.path("field_2").asText());
-        assertEquals(true, node_new.path("field_3").asBoolean());
-        assertEquals("value_2", node_new.path("field_4").asText());
-        assertEquals("value_3", node_new.path("field_7").asText());
-
-    }
-
-
-    @Test
-    @Ignore
-    public void testDataFactoryRemove () throws KustvaktException {
-        String data = "{}";
-        Object node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-
-        Object value = factory.getValue(node, "field_1");
-        assertEquals("value_1", value);
-        value = factory.getValue(node, "field_2");
-        assertEquals(20, value);
-        value = factory.getValue(node, "field_3");
-        assertEquals(true, value);
-
-        assertTrue(factory.removeValue(node, "field_1"));
-        assertTrue(factory.removeValue(node, "field_2"));
-        assertTrue(factory.removeValue(node, "field_3"));
-        assertNotNull(node);
-        assertEquals("{}", node.toString());
-
-        data = "[]";
-        node = JsonUtils.readTree(data);
-
-        assertTrue(factory.addValue(node, "", "value_2"));
-        assertTrue(factory.addValue(node, "", 10));
-        assertTrue(factory.addValue(node, "", false));
-
-        value = factory.getValue(node, "/0");
-        assertEquals("value_2", value);
-        value = factory.getValue(node, "/1");
-        assertEquals(10, value);
-        value = factory.getValue(node, "/2");
-        assertEquals(false, value);
-
-
-        // fixme: cannot be removed
-        assertTrue(factory.removeValue(node, "0"));
-        assertTrue(factory.removeValue(node, "1"));
-        assertTrue(factory.removeValue(node, "2"));
-        assertNotNull(node);
-        assertEquals("[]", node.toString());
-    }
-
-
-    @Test
-    public void testUserdataRequiredFields () throws KustvaktException {
-        UserDetails details = new UserDetails(-1);
-        Map<String, Object> m = new HashMap<>();
-        m.put(Attributes.FIRSTNAME, "first");
-        m.put(Attributes.LASTNAME, "last");
-        m.put(Attributes.ADDRESS, "address");
-        m.put(Attributes.EMAIL, "email");
-        details.setData(JsonUtils.toJSON(m));
-
-        details.setData(JsonUtils.toJSON(m));
-        String[] missing = details.missing();
-        assertEquals(0, missing.length);
-    }
-
-
-    @Test
-    public void testUserdataDefaultFields () throws KustvaktException {
-        UserSettings settings = new UserSettings(-1);
-        Map<String, Object> m = new HashMap<>();
-        m.put(Attributes.DEFAULT_REL_FOUNDRY, "rel_1");
-        m.put(Attributes.DEFAULT_CONST_FOUNDRY, "const_1");
-        m.put(Attributes.DEFAULT_POS_FOUNDRY, "pos_1");
-        m.put(Attributes.DEFAULT_LEMMA_FOUNDRY, "lemma_1");
-        m.put(Attributes.PAGE_LENGTH, 10);
-        m.put(Attributes.QUERY_LANGUAGE, "poliqarp");
-        m.put(Attributes.METADATA_QUERY_EXPERT_MODUS, false);
-
-        settings.read(m, true);
-
-        assertNotEquals(m.size(), settings.size());
-        assertEquals(settings.defaultFields().length, settings.size());
-        assertEquals("rel_1", settings.get(Attributes.DEFAULT_REL_FOUNDRY));
-        assertEquals("pos_1", settings.get(Attributes.DEFAULT_POS_FOUNDRY));
-        assertEquals("lemma_1", settings.get(Attributes.DEFAULT_LEMMA_FOUNDRY));
-        assertEquals("const_1", settings.get(Attributes.DEFAULT_CONST_FOUNDRY));
-        assertEquals(10, settings.get(Attributes.PAGE_LENGTH));
-
-    }
-
-
-    @Test(expected = KustvaktException.class)
-    public void testUserDataRequiredFieldsException () throws KustvaktException {
-        UserDetails details = new UserDetails(-1);
-        Map<String, Object> m = new HashMap<>();
-        m.put(Attributes.FIRSTNAME, "first");
-        m.put(Attributes.LASTNAME, "last");
-        m.put(Attributes.ADDRESS, "address");
-
-        details.setData(JsonUtils.toJSON(m));
-        String[] missing = details.missing();
-
-        assertEquals(1, missing.length);
-        assertEquals("email", missing[0]);
-        details.checkRequired();
-    }
-
-
-    @Test
-    public void testDataFactoryKeys () throws KustvaktException {
-        String data = "{}";
-        Object node = JsonUtils.readTree(data);
-
-        DataFactory factory = DataFactory.getFactory();
-        assertTrue(factory.addValue(node, "field_1", "value_1"));
-        assertTrue(factory.addValue(node, "field_2", 20));
-        assertTrue(factory.addValue(node, "field_3", true));
-        assertEquals(3, factory.size(node));
-        assertEquals(3, factory.keys(node).size());
-    }
-
-
+    @Deprecated
     @Test(expected = RuntimeException.class)
     public void testUserdatafactoryError () throws KustvaktException {
         BeansFactory.getTypeFactory().getTypeInterfaceBean(
diff --git a/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest2.java b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest2.java
new file mode 100644
index 0000000..acdd062
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest2.java
@@ -0,0 +1,156 @@
+package de.ids_mannheim.korap.user;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.node.ArrayNode;
+
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+/**
+ * @author margaretha, hanl
+ *
+ */
+public class UserdataTest2 {
+
+    @Test
+    public void testReadEmptyMap () throws KustvaktException {
+        Userdata userData = new UserSettings();
+        userData.read(new HashMap<>(), false);
+        String jsonSettings = userData.serialize();
+        assertEquals("{}", jsonSettings);
+    }
+
+    @Test
+    public void testReadNullMap () throws KustvaktException {
+        Userdata userData = new UserSettings();
+        userData.read(null, false);
+        String jsonSettings = userData.serialize();
+        assertEquals("{}", jsonSettings);
+    }
+
+    // EM: based on MH code, supposedly to validate entries like email
+    // and date. See ApacheValidator
+    //
+    // It has inconsistent behaviors:
+    // throws exceptions when there are invalid entries in a list,
+    // otherwise skips invalid entries and returns a valid map
+    // Moreover, Userdata.validate(ValidatorIface) does not return a
+    // valid map.
+    //
+    // At the moment, validation is not needed for default settings.
+    @Test
+    public void testValidateMap () throws IOException, KustvaktException {
+
+        Map<String, Object> map = new HashMap<>();
+        map.put("k1", Arrays.asList(new String[] { "a", "b", "c" }));
+        map.put("k2", Arrays.asList(new Integer[] { 1, 2, 3 }));
+
+        Userdata data = new UserSettings();
+        data.read(map, false);
+        data.validate(new ApacheValidator());
+    }
+
+    // EM: below are tests from MH
+
+    @Test
+    public void testUserdataRequiredFields () throws KustvaktException {
+        UserDetails details = new UserDetails(-1);
+        Map<String, Object> m = new HashMap<>();
+        m.put(Attributes.FIRSTNAME, "first");
+        m.put(Attributes.LASTNAME, "last");
+        m.put(Attributes.ADDRESS, "address");
+        m.put(Attributes.EMAIL, "email");
+        details.setData(JsonUtils.toJSON(m));
+
+        details.setData(JsonUtils.toJSON(m));
+        String[] missing = details.findMissingFields();
+        assertEquals(0, missing.length);
+    }
+
+    @Test
+    public void testUserdataDefaultFields () throws KustvaktException {
+        UserSettings settings = new UserSettings(-1);
+        Map<String, Object> m = new HashMap<>();
+        m.put(Attributes.DEFAULT_REL_FOUNDRY, "rel_1");
+        m.put(Attributes.DEFAULT_CONST_FOUNDRY, "const_1");
+        m.put(Attributes.DEFAULT_POS_FOUNDRY, "pos_1");
+        m.put(Attributes.DEFAULT_LEMMA_FOUNDRY, "lemma_1");
+        m.put(Attributes.PAGE_LENGTH, 10);
+        m.put(Attributes.QUERY_LANGUAGE, "poliqarp");
+        m.put(Attributes.METADATA_QUERY_EXPERT_MODUS, false);
+
+        settings.read(m, true);
+
+        assertNotEquals(m.size(), settings.size());
+        assertEquals(settings.defaultFields().length, settings.size());
+        assertEquals("rel_1", settings.get(Attributes.DEFAULT_REL_FOUNDRY));
+        assertEquals("pos_1", settings.get(Attributes.DEFAULT_POS_FOUNDRY));
+        assertEquals("lemma_1", settings.get(Attributes.DEFAULT_LEMMA_FOUNDRY));
+        assertEquals("const_1", settings.get(Attributes.DEFAULT_CONST_FOUNDRY));
+        assertEquals(10, settings.get(Attributes.PAGE_LENGTH));
+
+    }
+
+    @Test(expected = KustvaktException.class)
+    public void testUserDataRequiredFieldsException ()
+            throws KustvaktException {
+        UserDetails details = new UserDetails(-1);
+        Map<String, Object> m = new HashMap<>();
+        m.put(Attributes.FIRSTNAME, "first");
+        m.put(Attributes.LASTNAME, "last");
+        m.put(Attributes.ADDRESS, "address");
+
+        details.setData(JsonUtils.toJSON(m));
+        String[] missing = details.findMissingFields();
+
+        assertEquals(1, missing.length);
+        assertEquals("email", missing[0]);
+        details.checkRequired();
+    }
+
+    @Test
+    public void testUserDataPointerFunction () throws KustvaktException {
+        UserDetails details = new UserDetails(-1);
+        Map<String, Object> m = new HashMap<>();
+        m.put(Attributes.FIRSTNAME, "first");
+        m.put(Attributes.LASTNAME, "last");
+        m.put(Attributes.ADDRESS, "address");
+        m.put(Attributes.EMAIL, "email");
+        details.setData(JsonUtils.toJSON(m));
+
+        ArrayNode array = JsonUtils.createArrayNode();
+        array.add(100);
+        array.add("message");
+        details.setField("errors", array);
+
+        assertEquals(100, details.get("/errors/0"));
+        assertEquals("message", details.get("/errors/1"));
+    }
+
+    @Test
+    public void testUserDataUpdate () {
+        UserDetails details = new UserDetails(-1);
+        details.setField(Attributes.FIRSTNAME, "first");
+        details.setField(Attributes.LASTNAME, "last");
+        details.setField(Attributes.ADDRESS, "address");
+        details.setField(Attributes.EMAIL, "email");
+
+        UserDetails details2 = new UserDetails(-1);
+        details2.setField(Attributes.COUNTRY, "Germany");
+        details.update(details2);
+
+        assertEquals("first", details.get(Attributes.FIRSTNAME));
+        assertEquals("Germany", details.get(Attributes.COUNTRY));
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/ShibbolethUserControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/ShibbolethUserControllerTest.java
new file mode 100644
index 0000000..fb2af03
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/ShibbolethUserControllerTest.java
@@ -0,0 +1,339 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+
+import org.apache.commons.collections.map.LinkedMap;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.nimbusds.jose.JOSEException;
+import com.nimbusds.jwt.SignedJWT;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.BeansFactory;
+import de.ids_mannheim.korap.config.FullConfiguration;
+import de.ids_mannheim.korap.config.JWTSigner;
+import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import de.ids_mannheim.korap.web.FastJerseyTest;
+
+/** EM: To do: not implemented in the new DB yet
+ * @author hanl
+ * @date 21/03/2015
+ */
+
+// todo: do benchmarks for simple request to check access_token check and user
+// retrieval!
+@Ignore
+public class ShibbolethUserControllerTest extends FastJerseyTest {
+
+    @Autowired
+    FullConfiguration config;
+	private static String[] credentials;
+
+	@Override
+	public void initMethod() throws KustvaktException {
+		helper().setupAccount();
+	}
+
+	@BeforeClass
+	public static void setup() throws Exception {
+		credentials = new String[2];
+		credentials[0] = (String) TestHelper.getUserCredentials().get(Attributes.USERNAME);
+		credentials[1] = (String) TestHelper.getUserCredentials().get(Attributes.PASSWORD);
+	}
+
+	@Test
+	public void loginHTTP() throws KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		ClientResponse response = resource().path("user").path("info")
+				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+	}
+
+	// EM: This test require VPN / IDS Intranet
+	@Test
+	@Ignore
+	public void loginJWT() throws KustvaktException{
+		String en = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		/* lauffähige Version von Hanl: */
+		ClientResponse response = resource().path("auth").path("apiToken")
+				.header(Attributes.AUTHORIZATION, en).get(ClientResponse.class);
+		/**/
+		/*
+		 * Test : ClientResponse response = null; WebResource webRes =
+		 * resource().path("auth") .path("apiToken");
+		 * webRes.header(Attributes.AUTHORIZATION, en);
+		 * 
+		 * System.out.printf("resource: " + webRes.toString());
+		 * 
+		 * response = webRes.get(ClientResponse.class);
+		 * 
+		 */
+
+//		assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+		String entity = response.getEntity(String.class);
+//		System.out.println(entity);
+		JsonNode node = JsonUtils.readTree(entity);
+		assertEquals(2022, node.at("/errors/0/0").asInt());
+	}
+
+	// EM: cannot do test with LDAP
+	@Test
+	@Ignore
+	public void loginJWTExpired() throws InterruptedException, KustvaktException, ParseException, JOSEException {
+
+		assertTrue(BeansFactory.getKustvaktContext().getConfiguration().getTokenTTL() < 10);
+
+		String en = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		ClientResponse response = resource().path("auth").path("apiToken")
+				.header(Attributes.AUTHORIZATION, en).get(ClientResponse.class);
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(node);
+		String token = node.path("token").asText();
+
+		JWTSigner sign = new JWTSigner(BeansFactory.getKustvaktContext().getConfiguration().getSharedSecret(),
+				config.getIssuer(), -1);
+		        //BeansFactory.getKustvaktContext().getConfiguration().getIssuer(), -1);
+		SignedJWT jwt = sign.verifyToken(token);
+
+		while (true) {
+			if (TimeUtils.isExpired(jwt.getJWTClaimsSet().getExpirationTime().getTime()))
+				break;
+		}
+
+		response = resource().path("user").path("info")
+				.header(Attributes.AUTHORIZATION, "api_token " + token).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+
+	}
+
+	@Test
+	public void testGetUserDetails() throws KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		ClientResponse response = resource().path("user").path("details")
+				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testGetUserDetailsEmbeddedPointer() throws KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		Map m = new LinkedMap();
+		m.put("test", "[100, \"error message\", true, \"another message\"]");
+
+		ClientResponse response = resource().path("user").path("details")
+				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
+				.post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("details").queryParam("pointer", "test")
+				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+		String ent = response.getEntity(String.class);
+		assertEquals("[100, \"error message\", true, \"another message\"]", ent);
+	}
+
+	@Test
+	public void testUpdateUserDetailsMerge() throws KustvaktException{
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		Map m = new LinkedMap();
+		m.put("test", "test value 1");
+
+		ClientResponse response = resource().path("user").path("details")
+				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
+				.post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
+				.get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+		String ent = response.getEntity(String.class);
+		JsonNode node = JsonUtils.readTree(ent);
+		assertNotNull(node);
+		assertEquals("test value 1", node.at("/test").asText());
+		assertEquals("user", node.at("/lastName").asText());
+		assertEquals("test@ids-mannheim.de", node.at("/email").asText());
+	}
+
+	@Test
+	public void testGetUserDetailsPointer() throws KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		ClientResponse response = resource().path("user").path("details")
+				.queryParam("pointer", "email").header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+		String ent = response.getEntity(String.class);
+		assertEquals("test@ids-mannheim.de", ent);
+	}
+
+	@Test
+	public void testGetUserDetailsNonExistent() throws KustvaktException {
+//		helper().setupSimpleAccount("userservicetest", "servicepass");
+
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue("userservicetest", "servicepass");
+		ClientResponse response = resource().path("user").path("details")
+				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+		String entity = response.getEntity(String.class);
+		JsonNode node = JsonUtils.readTree(entity);
+		assertNotNull(node);
+		assertEquals(StatusCodes.NO_RESULT_FOUND, node.at("/errors/0/0").asInt());
+		assertEquals("UserDetails", node.at("/errors/0/2").asText());
+		helper().dropUser("userservicetest");
+	}
+
+	@Test
+	public void testGetUserSettings() throws KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		ClientResponse response = resource().path("user").path("settings")
+				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	public void testUpdateUserDetailsJson() throws KustvaktException{
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		Map m = new LinkedMap();
+		m.put("firstName", "newName");
+		m.put("lastName", "newLastName");
+		m.put("email", "newtest@ids-mannheim.de");
+
+		ClientResponse response = resource().path("user").path("details")
+				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
+				.post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
+				.get(ClientResponse.class);
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+		JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(node);
+		assertEquals("newName", node.path("firstName").asText());
+		assertEquals("newLastName", node.path("lastName").asText());
+		assertEquals("newtest@ids-mannheim.de", node.path("email").asText());
+		assertEquals("Mannheim", node.path("address").asText());
+
+		m = new LinkedMap();
+		m.put("firstName", "test");
+		m.put("lastName", "user");
+		m.put("email", "test@ids-mannheim.de");
+
+		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
+				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+	}
+
+	@Test
+	@Ignore
+	public void testUpdateUserSettingsForm() throws IOException, KustvaktException{
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		MultivaluedMap m = new MultivaluedMapImpl();
+		m.putSingle("queryLanguage", "poliqarp_test");
+		m.putSingle("pageLength", "200");
+
+		ClientResponse response = resource().path("user").path("settings")
+				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", "application/x-www-form-urlencodeBase64d")
+				.get(ClientResponse.class);
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		JsonNode map = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(map);
+
+		assertNotEquals(m.getFirst("queryLanguage"), map.get("queryLanguage"));
+		assertNotEquals(m.get("pageLength"), Integer.valueOf((String) m.getFirst("pageLength")));
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
+				.header("Content-Type", "application/x-www-form-urlencodeBase64d").post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
+				.header("Content-Type", "application/x-www-form-urlencodeBase64d").get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		map = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(map);
+
+		assertEquals(map.get("queryLanguage"), m.getFirst("queryLanguage"));
+		int p1 = map.path("pageLength").asInt();
+		int p2 = Integer.valueOf((String) m.getFirst("pageLength"));
+		assertEquals(p1, p2);
+	}
+
+	@Test
+	public void testUpdateUserSettingsJson() throws IOException, KustvaktException {
+		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
+		Map m = new HashMap<>();
+		m.put("queryLanguage", "poliqarp_test");
+		m.put("pageLength", "200");
+		m.put("setting_1", "value_1");
+
+		ClientResponse response = resource().path("user").path("settings")
+				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
+				.get(ClientResponse.class);
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		JsonNode map = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(map);
+
+		assertNotEquals(m.get("queryLanguage"), map.get("queryLanguage"));
+		assertNotEquals(m.get("pageLength"), Integer.valueOf((String) m.get("pageLength")));
+
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
+				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, m);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
+				.get(ClientResponse.class);
+		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+
+		map = JsonUtils.readTree(response.getEntity(String.class));
+		assertNotNull(map);
+
+		assertEquals(map.path("queryLanguage").asText(), m.get("queryLanguage"));
+		int p1 = map.path("pageLength").asInt();
+		int p2 = Integer.valueOf((String) m.get("pageLength"));
+		assertEquals(p1, p2);
+	}
+
+	@Test
+	public void testLoginFailedLockAccount() {
+
+	}
+
+	@Test
+	public void delete() {
+
+	}
+
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserControllerTest.java
index 70d4eaf..da336a0 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserControllerTest.java
@@ -1,447 +1,106 @@
 package de.ids_mannheim.korap.web.controller;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
 
-import java.io.IOException;
-import java.net.URI;
-import java.text.ParseException;
 import java.util.HashMap;
 import java.util.Map;
 
 import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
 
-import org.apache.commons.collections.map.LinkedMap;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
 import org.junit.Test;
-import org.springframework.beans.factory.annotation.Autowired;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.nimbusds.jose.JOSEException;
-import com.nimbusds.jwt.SignedJWT;
+import com.google.common.net.HttpHeaders;
 import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.core.util.MultivaluedMapImpl;
+import com.sun.jersey.api.client.ClientResponse.Status;
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.BeansFactory;
-import de.ids_mannheim.korap.config.FullConfiguration;
-import de.ids_mannheim.korap.config.JWTSigner;
-import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.config.SpringJerseyTest;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.TimeUtils;
-import de.ids_mannheim.korap.web.FastJerseyTest;
 
-/** EM: To do: not implemented in the new DB yet
- * @author hanl
- * @date 21/03/2015
+/**
+ * @author margaretha
+ *
  */
+public class UserControllerTest extends SpringJerseyTest {
 
-// todo: do benchmarks for simple request to check access_token check and user
-// retrieval!
-@Ignore
-public class UserControllerTest extends FastJerseyTest {
+    private String username = "UserControllerTest";
 
-    @Autowired
-    FullConfiguration config;
-	private static String[] credentials;
+    private ClientResponse sendPutRequest (Map<String, Object> form)
+            throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("user")
+                .path("settings").path(username)
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .type(MediaType.APPLICATION_JSON).entity(form)
+                .put(ClientResponse.class);
 
-	@Override
-	public void initMethod() throws KustvaktException {
-		helper().setupAccount();
-	}
+        return response;
+    }
 
-	@BeforeClass
-	public static void setup() throws Exception {
-		credentials = new String[2];
-		credentials[0] = (String) TestHelper.getUserCredentials().get(Attributes.USERNAME);
-		credentials[1] = (String) TestHelper.getUserCredentials().get(Attributes.PASSWORD);
-	}
+    @Test
+    public void testCreateSettingWithJson () throws KustvaktException {
+        String json = "{\"foundry\":\"opennlp\",\"metadata\":\"author title "
+                + "textSigle availability\",\"resultPerPage\":25}";
 
-	@Test
-	public void testRegisterMissingFields() throws KustvaktException{
+        ClientResponse response = resource().path(API_VERSION).path("user")
+                .path("settings").path(username)
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .type(MediaType.APPLICATION_JSON).entity(json)
+                .put(ClientResponse.class);
 
-		MultivaluedMap map = new MultivaluedMapImpl();
-		map.putSingle("username", "testuser"); // bodmer funktioniert noch nicht
-		map.putSingle("email", "hanl@ids-mannheim.de");
-		map.putSingle("password", "testPassword1234");
-		map.putSingle("firstName", "test");
-		map.putSingle("lastName", "user");
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
 
-		ClientResponse response = resource().path("user").path("register")
-				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, JsonUtils.toJSON(map));
-		assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-		String ent = response.getEntity(String.class);
-		JsonNode node = JsonUtils.readTree(ent);
-		assertNotNull(node);
-		assertTrue(node.at("/errors/0/2").asText().contains("address"));
+        testRetrieveSettings("opennlp", 25,
+                "author title textSigle availability");
+    }
 
-		// map.putSingle("address", "Mannheim");
+    @Test
+    public void testCreateSettingWithForm () throws KustvaktException {
+        Map<String, Object> form = new HashMap<>();
+        form.put("foundry", "opennlp");
+        form.put("resultPerPage", 25);
+        form.put("metadata", "author title textSigle availability");
 
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue("testuser", "testPassword1234");
-		response = resource().path("user").path("info")
-				.header("Content-Type", MediaType.APPLICATION_JSON).header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
+        ClientResponse response = sendPutRequest(form);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
 
-		assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-	}
+        testRetrieveSettings("opennlp", 25,
+                "author title textSigle availability");
 
-	// test if user locked and what error message you get back
-	@Test
-	public void testregisterWithoutConfirm() throws KustvaktException {
-		MultivaluedMap map = new MultivaluedMapImpl();
-		map.putSingle("username", "testuser2");
-		map.putSingle("email", "hanl@ids-mannheim.de");
-		map.putSingle("password", "testPassword1234");
-		map.putSingle("firstName", "test");
-		map.putSingle("lastName", "user");
-		map.putSingle("address", "Mannheim");
+        testUpdateSetting();
+    }
 
-		ClientResponse response = resource().path("user").path("register")
-				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, map);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
+    private void testUpdateSetting () throws KustvaktException {
+        Map<String, Object> form = new HashMap<>();
+        form.put("foundry", "malt");
+        form.put("resultPerPage", 15);
+        form.put("metadata", "author title");
 
-		// run login/ status --> exception or information about locked account
-		// should appear
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue("testuser2", "testPassword1234");
-		response = resource().path("user").path("info").header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-		String ent = response.getEntity(String.class);
+        ClientResponse response = sendPutRequest(form);
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
 
-	}
+        testRetrieveSettings("malt", 15, "author title");
 
-	// should be run over https, since password is transmitted in plain text
-	@Test
-	public void testRegisterAndConfirm() throws KustvaktException{
-		MultivaluedMap map = new MultivaluedMapImpl();
-		map.putSingle("username", "testuser");
-		map.putSingle("email", "hanl@ids-mannheim.de");
-		map.putSingle("password", "testPassword1234");
-		map.putSingle("firstName", "test");
-		map.putSingle("lastName", "user");
-		map.putSingle("address", "Mannheim");
+    }
 
-		ClientResponse response = resource().path("user").path("register")
-				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, map);
+    private void testRetrieveSettings (String foundry, int numOfResult,
+            String metadata) throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("user")
+                .path("settings")
+                .header(Attributes.AUTHORIZATION, HttpAuthorizationHandler
+                        .createBasicAuthorizationHeaderValue(username, "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
 
-		String ent = response.getEntity(String.class);
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		JsonNode node = JsonUtils.readTree(ent);
-		assertNotNull(node);
-
-		String conf_uri = node.path("confirm_uri").asText();
-		response = resource().uri(URI.create(conf_uri)).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue("testuser", "testPassword1234");
-		response = resource().path("user").path("info").header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-	}
-
-	@Test
-	public void loginHTTP() throws KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		ClientResponse response = resource().path("user").path("info")
-				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-	}
-
-	// EM: This test require VPN / IDS Intranet
-	@Test
-	@Ignore
-	public void loginJWT() throws KustvaktException{
-		String en = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		/* lauffähige Version von Hanl: */
-		ClientResponse response = resource().path("auth").path("apiToken")
-				.header(Attributes.AUTHORIZATION, en).get(ClientResponse.class);
-		/**/
-		/*
-		 * Test : ClientResponse response = null; WebResource webRes =
-		 * resource().path("auth") .path("apiToken");
-		 * webRes.header(Attributes.AUTHORIZATION, en);
-		 * 
-		 * System.out.printf("resource: " + webRes.toString());
-		 * 
-		 * response = webRes.get(ClientResponse.class);
-		 * 
-		 */
-
-//		assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-		String entity = response.getEntity(String.class);
-//		System.out.println(entity);
-		JsonNode node = JsonUtils.readTree(entity);
-		assertEquals(2022, node.at("/errors/0/0").asInt());
-	}
-
-	// EM: cannot do test with LDAP
-	@Test
-	@Ignore
-	public void loginJWTExpired() throws InterruptedException, KustvaktException, ParseException, JOSEException {
-
-		assertTrue(BeansFactory.getKustvaktContext().getConfiguration().getTokenTTL() < 10);
-
-		String en = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		ClientResponse response = resource().path("auth").path("apiToken")
-				.header(Attributes.AUTHORIZATION, en).get(ClientResponse.class);
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(node);
-		String token = node.path("token").asText();
-
-		JWTSigner sign = new JWTSigner(BeansFactory.getKustvaktContext().getConfiguration().getSharedSecret(),
-				config.getIssuer(), -1);
-		        //BeansFactory.getKustvaktContext().getConfiguration().getIssuer(), -1);
-		SignedJWT jwt = sign.verifyToken(token);
-
-		while (true) {
-			if (TimeUtils.isExpired(jwt.getJWTClaimsSet().getExpirationTime().getTime()))
-				break;
-		}
-
-		response = resource().path("user").path("info")
-				.header(Attributes.AUTHORIZATION, "api_token " + token).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
-
-	}
-
-	@Test
-	public void testGetUserDetails() throws KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		ClientResponse response = resource().path("user").path("details")
-				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-	}
-
-	@Test
-	public void testGetUserDetailsEmbeddedPointer() throws KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		Map m = new LinkedMap();
-		m.put("test", "[100, \"error message\", true, \"another message\"]");
-
-		ClientResponse response = resource().path("user").path("details")
-				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
-				.post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("details").queryParam("pointer", "test")
-				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-		String ent = response.getEntity(String.class);
-		assertEquals("[100, \"error message\", true, \"another message\"]", ent);
-	}
-
-	@Test
-	public void testUpdateUserDetailsMerge() throws KustvaktException{
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		Map m = new LinkedMap();
-		m.put("test", "test value 1");
-
-		ClientResponse response = resource().path("user").path("details")
-				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
-				.post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-		String ent = response.getEntity(String.class);
-		JsonNode node = JsonUtils.readTree(ent);
-		assertNotNull(node);
-		assertEquals("test value 1", node.at("/test").asText());
-		assertEquals("user", node.at("/lastName").asText());
-		assertEquals("test@ids-mannheim.de", node.at("/email").asText());
-	}
-
-	@Test
-	public void testGetUserDetailsPointer() throws KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		ClientResponse response = resource().path("user").path("details")
-				.queryParam("pointer", "email").header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-		String ent = response.getEntity(String.class);
-		assertEquals("test@ids-mannheim.de", ent);
-	}
-
-	@Test
-	public void testGetUserDetailsNonExistent() throws KustvaktException {
-//		helper().setupSimpleAccount("userservicetest", "servicepass");
-
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue("userservicetest", "servicepass");
-		ClientResponse response = resource().path("user").path("details")
-				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(), response.getStatus());
-		String entity = response.getEntity(String.class);
-		JsonNode node = JsonUtils.readTree(entity);
-		assertNotNull(node);
-		assertEquals(StatusCodes.NO_RESULT_FOUND, node.at("/errors/0/0").asInt());
-		assertEquals("UserDetails", node.at("/errors/0/2").asText());
-		helper().dropUser("userservicetest");
-	}
-
-	@Test
-	public void testGetUserSettings() throws KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		ClientResponse response = resource().path("user").path("settings")
-				.header(Attributes.AUTHORIZATION, enc).get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-	}
-
-	@Test
-	public void testUpdateUserDetailsJson() throws KustvaktException{
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		Map m = new LinkedMap();
-		m.put("firstName", "newName");
-		m.put("lastName", "newLastName");
-		m.put("email", "newtest@ids-mannheim.de");
-
-		ClientResponse response = resource().path("user").path("details")
-				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
-				.post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-		JsonNode node = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(node);
-		assertEquals("newName", node.path("firstName").asText());
-		assertEquals("newLastName", node.path("lastName").asText());
-		assertEquals("newtest@ids-mannheim.de", node.path("email").asText());
-		assertEquals("Mannheim", node.path("address").asText());
-
-		m = new LinkedMap();
-		m.put("firstName", "test");
-		m.put("lastName", "user");
-		m.put("email", "test@ids-mannheim.de");
-
-		response = resource().path("user").path("details").header(Attributes.AUTHORIZATION, enc)
-				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-	}
-
-	@Test
-	@Ignore
-	public void testUpdateUserSettingsForm() throws IOException, KustvaktException{
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		MultivaluedMap m = new MultivaluedMapImpl();
-		m.putSingle("queryLanguage", "poliqarp_test");
-		m.putSingle("pageLength", "200");
-
-		ClientResponse response = resource().path("user").path("settings")
-				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", "application/x-www-form-urlencodeBase64d")
-				.get(ClientResponse.class);
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		JsonNode map = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(map);
-
-		assertNotEquals(m.getFirst("queryLanguage"), map.get("queryLanguage"));
-		assertNotEquals(m.get("pageLength"), Integer.valueOf((String) m.getFirst("pageLength")));
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
-				.header("Content-Type", "application/x-www-form-urlencodeBase64d").post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
-				.header("Content-Type", "application/x-www-form-urlencodeBase64d").get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		map = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(map);
-
-		assertEquals(map.get("queryLanguage"), m.getFirst("queryLanguage"));
-		int p1 = map.path("pageLength").asInt();
-		int p2 = Integer.valueOf((String) m.getFirst("pageLength"));
-		assertEquals(p1, p2);
-	}
-
-	@Test
-	public void testUpdateUserSettingsJson() throws IOException, KustvaktException {
-		String enc = HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(credentials[0], credentials[1]);
-		Map m = new HashMap<>();
-		m.put("queryLanguage", "poliqarp_test");
-		m.put("pageLength", "200");
-		m.put("setting_1", "value_1");
-
-		ClientResponse response = resource().path("user").path("settings")
-				.header(Attributes.AUTHORIZATION, enc).header("Content-Type", MediaType.APPLICATION_JSON)
-				.get(ClientResponse.class);
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		JsonNode map = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(map);
-
-		assertNotEquals(m.get("queryLanguage"), map.get("queryLanguage"));
-		assertNotEquals(m.get("pageLength"), Integer.valueOf((String) m.get("pageLength")));
-
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
-				.header("Content-Type", MediaType.APPLICATION_JSON).post(ClientResponse.class, m);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		response = resource().path("user").path("settings").header(Attributes.AUTHORIZATION, enc)
-				.get(ClientResponse.class);
-		assertEquals(ClientResponse.Status.OK.getStatusCode(), response.getStatus());
-
-		map = JsonUtils.readTree(response.getEntity(String.class));
-		assertNotNull(map);
-
-		assertEquals(map.path("queryLanguage").asText(), m.get("queryLanguage"));
-		int p1 = map.path("pageLength").asInt();
-		int p2 = Integer.valueOf((String) m.get("pageLength"));
-		assertEquals(p1, p2);
-	}
-
-	@Test
-	public void registerInvalidPassword() {
-		final String CREDENTIALS_INVALID = "{\"username\":\"testuser2\","
-				+ "\"email\":\"hanl@ids-mannheim.de\",\"password\":\"testpassword\"}";
-		// Response response = given()
-		// .contentType("application/x-www-form-urlencodeBase64d").when()
-		// .body(CREDENTIALS_INVALID).post("/register");
-		// String body = response.getBody().asString();
-		// Assert.assertEquals("response is in error", true,
-		// body.contains("error"));
-		// JsonNode n = JsonUtils.readTree(body);
-		// String uri = n.path("uri").asText();
-		// Response r = given().get(URI.create(uri));
-		// System.out.println("RESPONSE " + r.getStatusCode());
-		// System.out.println("RESPONSE BODY " + n);
-	}
-
-	@Test
-	public void testLoginFailedLockAccount() {
-
-	}
-
-	@Test
-	@Ignore
-	public void delete() {
-
-	}
-
-	@Test
-	@Ignore
-	public void updatePassword() {
-
-	}
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(foundry, node.at("/foundry").asText());
+        assertEquals(numOfResult, node.at("/resultPerPage").asInt());
+        assertEquals(metadata, node.at("/metadata").asText());
+    }
 
 }
