diff --git a/src/main/java/de/ids_mannheim/korap/config/Scopes.java b/src/main/java/de/ids_mannheim/korap/config/Scopes.java
new file mode 100644
index 0000000..9c4ef7a
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/config/Scopes.java
@@ -0,0 +1,70 @@
+package de.ids_mannheim.korap.config;
+
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.UserDetails;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author hanl
+ * @date 09/12/2014
+ */
+public class Scopes {
+
+    public enum Scope {
+        openid, profile, email, queries, account, preferences, search
+
+    }
+
+    private static final String[] profile = { Attributes.EMAIL,
+            Attributes.FIRSTNAME, Attributes.LASTNAME, Attributes.INSTITUTION,
+            Attributes.ADDRESS, Attributes.PHONE, Attributes.GENDER,
+            Attributes.COUNTRY };
+
+    private static final String[] OPENID_CONNECT = { Scope.profile.toString() };
+
+    private static final Enum[] SERVICE_DEFAULTS = { Scope.account,
+            Scope.preferences, Scope.search, Scope.queries };
+
+    public static Map<String, Object> getProfileScopes(
+            Map<String, Object> values) {
+        Map<String, Object> r = new HashMap<>();
+        for (String key : profile) {
+            Object v = values.get(key);
+            if (v != null)
+                r.put(key, v);
+        }
+        return r;
+    }
+
+    /**
+     * expects space separated values
+     *
+     * @param scopes
+     * @return
+     */
+    //todo: test
+    public static Enum[] mapScopes(String scopes) {
+        List<Enum> s = new ArrayList<>();
+        for (String value : scopes.split(" "))
+            s.add(Scope.valueOf(value.toLowerCase()));
+        return (Enum[]) s.toArray(new Enum[s.size()]);
+    }
+
+    public static Map<String, Object> mapOpenIDConnectScopes(String scopes,
+            UserDetails details) {
+        Map<String, Object> m = new HashMap<>();
+        if (scopes != null && !scopes.isEmpty()) {
+            scopes = scopes.toLowerCase();
+            if (scopes.contains(Scope.email.toString()))
+                m.put(Attributes.EMAIL, details.getEmail());
+            if (scopes.contains(Scope.profile.toString()))
+                m.putAll(Scopes.getProfileScopes(details.toMap()));
+        }
+        return m;
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java b/src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java
new file mode 100644
index 0000000..122970f
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/interfaces/PolicyHandlerIface.java
@@ -0,0 +1,175 @@
+package de.ids_mannheim.korap.interfaces;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.resources.KustvaktResource;
+import de.ids_mannheim.korap.security.Parameter;
+import de.ids_mannheim.korap.security.PolicyCondition;
+import de.ids_mannheim.korap.security.SecurityPolicy;
+import de.ids_mannheim.korap.user.User;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * User: hanl
+ * Date: 10/31/13
+ * Time: 3:01 PM
+ */
+// todo: this still applicable?
+@Transactional
+public interface PolicyHandlerIface {
+
+    /**
+     * @param policy
+     * @param user
+     * @throws KustvaktException
+     */
+    int createPolicy(SecurityPolicy policy, User user) throws KustvaktException;
+
+    /**
+     * @param target
+     * @param user
+     * @param perm
+     * @return
+     */
+    List<SecurityPolicy>[] getPolicies(Integer target, User user, Byte perm);
+
+    /**
+     * @param policy
+     * @return
+     * @throws KustvaktException
+     */
+    void mapConstraints(SecurityPolicy policy) throws KustvaktException;
+
+    /**
+     * @param target
+     * @param user
+     * @param perm
+     * @return
+     */
+    List<SecurityPolicy>[] getPolicies(String target, User user, Byte perm);
+
+    /**
+     * @param path
+     * @param user
+     * @param perm
+     * @return
+     */
+    List<SecurityPolicy>[] findPolicies(String path, User user, Byte perm);
+
+    /**
+     * @param path
+     * @param user
+     * @param b
+     * @param clazz
+     * @return
+     * @throws KustvaktException
+     */
+    List<KustvaktResource.Container> getDescending(String path, User user,
+            Byte b, Class<? extends KustvaktResource> clazz)
+            throws KustvaktException;
+
+    /**
+     * @param path
+     * @param user
+     * @param b
+     * @param clazz
+     * @return
+     * @throws KustvaktException
+     */
+    List<KustvaktResource.Container> getAscending(String path, User user,
+            Byte b, Class<? extends KustvaktResource> clazz)
+            throws KustvaktException;
+
+    /**
+     * @param id
+     * @param user
+     */
+    //todo: test
+    void deleteResourcePolicies(String id, User user) throws KustvaktException;
+
+    /**
+     * @param policy
+     * @param user
+     * @return
+     * @throws KustvaktException
+     */
+    int deletePolicy(SecurityPolicy policy, User user) throws KustvaktException;
+
+    /**
+     * @param policy
+     * @param user
+     * @return
+     * @throws KustvaktException
+     */
+    int updatePolicy(SecurityPolicy policy, User user) throws KustvaktException;
+
+    /**
+     * checks if a similar policy already exists
+     *
+     * @param policy
+     * @return
+     * @throws KustvaktException
+     */
+    int checkPolicy(SecurityPolicy policy, User user) throws KustvaktException;
+
+    /**
+     * @param user
+     * @param name
+     * @param owner
+     * @return
+     * @throws KustvaktException
+     */
+    int matchCondition(User user, String name, boolean owner)
+            throws KustvaktException;
+
+    /**
+     * @param username
+     * @param condition
+     * @param admin
+     * @return
+     * @throws KustvaktException
+     */
+    int addToCondition(String username, PolicyCondition condition,
+            boolean admin) throws KustvaktException;
+
+    /**
+     * @param usernames
+     * @param condition
+     * @param status
+     * @throws KustvaktException
+     */
+
+    //todo: add a handler user id, to skip the matching step in the corpusmanagement segment!
+    int[] addToCondition(List<String> usernames, PolicyCondition condition,
+            boolean status) throws KustvaktException;
+
+    /**
+     * @param usernames
+     * @param condition
+     * @throws KustvaktException
+     */
+    void removeFromCondition(List<String> usernames, PolicyCondition condition)
+            throws KustvaktException;
+
+    /**
+     * @param param
+     * @throws KustvaktException
+     */
+    void createParamBinding(Parameter param) throws KustvaktException;
+
+    /**
+     * @param condition
+     * @return
+     * @throws KustvaktException
+     */
+    List<String> getUsersFromCondition(PolicyCondition condition)
+            throws KustvaktException;
+
+    /**
+     * @param policy
+     * @throws KustvaktException
+     */
+    void removeParamBinding(SecurityPolicy policy) throws KustvaktException;
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java
deleted file mode 100644
index cb0a06c..0000000
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteNode.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package de.ids_mannheim.korap.resource.rewrite;
-
-/**
- * node rewrites get injected typically object nodes that are subject to altering.
- * Be aware that node rewrites are processed before query rewrites. Thus query rewrite may override previous node rewrites
- *
- * {@link de.ids_mannheim.korap.resource.rewrite.RewriteNode} rewrite support the deletion of the respective node by simply setting the node invalid in KoralNode
- *
- * @author hanl
- * @date 03/07/2015
- */
-public abstract class RewriteNode extends RewriteTask {
-
-    public RewriteNode() {
-        super();
-    }
-
-
-
-}
diff --git a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java b/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java
deleted file mode 100644
index 99bfb34..0000000
--- a/src/main/java/de/ids_mannheim/korap/resource/rewrite/RewriteQuery.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package de.ids_mannheim.korap.resource.rewrite;
-
-/**
- * query rewrites get injected the entire query from root containing all child nodes
- * <p/>
- * {@link de.ids_mannheim.korap.resource.rewrite.RewriteQuery} does not allow the deletion of the root node or subnode through KoralNode.
- * The {@link de.ids_mannheim.korap.resource.rewrite.RewriteHandler} will igonore respecitve invalid requests
- *
- * @author hanl
- * @date 03/07/2015
- */
-public abstract class RewriteQuery extends RewriteTask {
-
-    public RewriteQuery() {
-        super();
-    }
-
-}
diff --git a/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder2.java b/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder2.java
deleted file mode 100644
index 1058f5b..0000000
--- a/src/main/java/de/ids_mannheim/korap/utils/CollectionQueryBuilder2.java
+++ /dev/null
@@ -1,86 +0,0 @@
-package de.ids_mannheim.korap.utils;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-import java.io.IOException;
-import java.util.*;
-
-/**
- * @author hanl
- * @date 13/05/2014
- */
-@Deprecated
-public class CollectionQueryBuilder2 {
-
-    private List<Map> rq;
-    private Map groups;
-    private CollectionTypes types;
-    private boolean verbose;
-
-    public CollectionQueryBuilder2() {
-        this.verbose = false;
-        this.rq = new ArrayList<>();
-        this.groups = new HashMap();
-        this.types = new CollectionTypes();
-    }
-
-    public CollectionQueryBuilder2(boolean verbose) {
-        this();
-        this.verbose = verbose;
-    }
-
-
-    public CollectionQueryBuilder2 addResource(String collections) {
-        try {
-            List v = JsonUtils.read(collections, LinkedList.class);
-            this.rq.addAll(v);
-        } catch (IOException e) {
-            throw new IllegalArgumentException("Conversion went wrong!");
-        }
-        return this;
-    }
-
-    public CollectionQueryBuilder2 addResources(List<String> queries) {
-        for (String query : queries)
-            addResource(query);
-        return this;
-    }
-
-//    public CollectionQueryBuilder2 setQuery(String query) {
-//        CollectionQueryProcessor tree = new CollectionQueryProcessor();
-//        tree.process(query);
-//        this.groups = tree.getRequestMap();
-//        return this;
-//    }
-
-    public List raw() {
-        List list = new ArrayList(this.rq);
-        list.add(types.createMetaFilter(this.groups));
-        return list;
-    }
-
-    private Object raw2() {
-        return this.groups;
-    }
-
-    public String toCollections() {
-        Map value = new HashMap();
-        value.put("collections", raw2());
-        return JsonUtils.toJSON(value);
-    }
-
-    public JsonNode toNode() {
-        return JsonUtils.valueToTree(raw2());
-    }
-
-    public String toJSON() {
-        return JsonUtils.toJSON(raw2());
-    }
-
-
-    // add public filter to original query
-    private void addToGroup() {
-        Map first = this.rq.get(0);
-
-    }
-}
diff --git a/src/main/java/de/ids_mannheim/korap/utils/PropertyReader.java b/src/main/java/de/ids_mannheim/korap/utils/PropertyReader.java
new file mode 100644
index 0000000..292b019
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/utils/PropertyReader.java
@@ -0,0 +1,36 @@
+package de.ids_mannheim.korap.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author hanl
+ * @date 27/09/2014
+ */
+public abstract class PropertyReader {
+
+
+    protected Map<String, Properties> read(String path) throws IOException {
+        Map<String, Properties> res = new HashMap<>();
+        Properties s = new Properties();
+        s.load(new FileInputStream(new File(path)));
+        for (Map.Entry<Object, Object> e : s.entrySet()) {
+            String key = e.getKey().toString().split("\\.")[0];
+            Properties in = res.get(key);
+            if (in == null) {
+                in = new Properties();
+                res.put(key, in);
+            }
+            in.setProperty(e.getKey().toString(), e.getValue().toString());
+        }
+        return res;
+    }
+
+
+    public abstract void load();
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/utils/UserPropertyReader.java b/src/main/java/de/ids_mannheim/korap/utils/UserPropertyReader.java
new file mode 100644
index 0000000..b506d22
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/utils/UserPropertyReader.java
@@ -0,0 +1,111 @@
+package de.ids_mannheim.korap.utils;
+
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
+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.UserSettings;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.NoSuchAlgorithmException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author hanl
+ * @date 30/09/2014
+ */
+public class UserPropertyReader extends PropertyReader {
+
+    private Map<String, Properties> props;
+    private String path;
+    private EntityHandlerIface iface;
+    private EncryptionIface crypto;
+    private static Logger jlog = KustvaktLogger
+            .initiate(UserPropertyReader.class);
+
+    public UserPropertyReader(String path) {
+        this.path = path;
+        this.iface = BeanConfiguration.getBeans().getUserDBHandler();
+        this.crypto = BeanConfiguration.getBeans().getEncryption();
+    }
+
+    @Override
+    public void load() {
+        try {
+            props = super.read(this.path);
+            for (Map.Entry<String, Properties> e : props.entrySet()) {
+                try {
+                    createUser(e.getKey(), e.getValue());
+                }catch (KustvaktException ex) {
+                    jlog.error("KorAP-Exception: {} for user {}",
+                            ex.getStatusCode(), e.getKey());
+                }
+            }
+            iface.createAccount(User.UserFactory.getDemoUser());
+        }catch (IOException e) {
+            jlog.error("Could not read from path {}", path);
+        }catch (KustvaktException e) {
+            jlog.error("KorAP-Exception: {}", e.getStatusCode());
+        }
+    }
+
+    private User createUser(String username, Properties p)
+            throws KustvaktException {
+        KorAPUser user;
+        if (username.equals(User.ADMINISTRATOR_NAME)) {
+            user = User.UserFactory.getAdmin();
+
+            String pass = p.getProperty(username + ".password", null);
+            if (pass == null)
+                throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+
+            try {
+                pass = crypto.produceSecureHash(pass);
+            }catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+                throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+            }
+            user.setPassword(pass);
+        }else {
+            user = User.UserFactory.getUser(username);
+            Map<String, Object> vals = new HashMap<>();
+            for (Map.Entry e : p.entrySet()) {
+                String key = e.getKey().toString().split("\\.", 2)[1];
+                vals.put(key, e.getValue().toString());
+            }
+            String pass = p.getProperty(username + ".password", null);
+            if (pass == null)
+                throw new KustvaktException(StatusCodes.ILLEGAL_ARGUMENT);
+
+            try {
+                pass = crypto.produceSecureHash(pass);
+            }catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
+                throw new KustvaktException(StatusCodes.REQUEST_INVALID);
+            }
+
+            user.setPassword(pass);
+            user.setAccountLocked(Boolean.valueOf(
+                    p.getProperty(username + ".lock", "false")));
+            user.setAccountCreation(TimeUtils.getNow().getMillis());
+
+            //todo: make sure uri is set to 0, so sql queries work with the null value
+//            user.setURIExpiration(0L);
+
+            UserDetails det = UserDetails.newDetailsIterator(vals);
+
+            user.setDetails(det);
+            user.setSettings(new UserSettings());
+        }
+        iface.createAccount(user);
+        jlog.info("successfully created account for user {}",
+                user.getUsername());
+        return user;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
new file mode 100644
index 0000000..8346e1f
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
@@ -0,0 +1,63 @@
+package de.ids_mannheim.korap.web.filter;
+
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+import com.sun.jersey.spi.container.ResourceFilter;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.web.utils.KorAPContext;
+
+import javax.ws.rs.ext.Provider;
+
+/**
+ * @author hanl
+ * @date 28/01/2014
+ */
+@Provider
+public class AuthFilter implements ContainerRequestFilter, ResourceFilter {
+
+    private AuthenticationManagerIface userController;
+
+    public AuthFilter() {
+        this.userController = BeanConfiguration.getBeans()
+                .getAuthenticationManager();
+    }
+
+    @Override
+    public ContainerRequest filter(ContainerRequest request) {
+        String host = request.getHeaderValue(ContainerRequest.HOST);
+        String ua = request.getHeaderValue(ContainerRequest.USER_AGENT);
+
+        String authentication = request
+                .getHeaderValue(ContainerRequest.AUTHORIZATION);
+        if (authentication != null && !authentication.isEmpty()) {
+            TokenContext context;
+            try {
+                context = userController
+                        .getTokenStatus(authentication, host, ua);
+
+            }catch (KustvaktException e) {
+                throw BeanConfiguration.getResponseHandler().throwit(e);
+            }
+
+            if (context != null && (
+                    (context.isSecureRequired() && request.isSecure())
+                            | !context.isSecureRequired()))
+                request.setSecurityContext(new KorAPContext(context));
+        }
+        return request;
+    }
+
+    @Override
+    public ContainerRequestFilter getRequestFilter() {
+        return this;
+    }
+
+    @Override
+    public ContainerResponseFilter getResponseFilter() {
+        return null;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
new file mode 100644
index 0000000..a8ffe89
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
@@ -0,0 +1,60 @@
+package de.ids_mannheim.korap.web.filter;
+
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ContainerRequestFilter;
+import com.sun.jersey.spi.container.ContainerResponseFilter;
+import com.sun.jersey.spi.container.ResourceFilter;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import de.ids_mannheim.korap.web.utils.KorAPContext;
+
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.ext.Provider;
+
+/**
+ * Created by hanl on 7/15/14.
+ */
+@Provider
+public class DefaultFilter implements ContainerRequestFilter, ResourceFilter {
+
+    @Context
+    UriInfo info;
+
+    @Override
+    public ContainerRequest filter(ContainerRequest request) {
+        String host = request.getHeaderValue(ContainerRequest.HOST);
+        String ua = request.getHeaderValue(ContainerRequest.USER_AGENT);
+        String authentication = request
+                .getHeaderValue(ContainerRequest.AUTHORIZATION);
+
+        // means that this is the public service
+        if (authentication == null)
+            request.setSecurityContext(
+                    new KorAPContext(createShorterToken(host, ua)));
+        return request;
+    }
+
+    private TokenContext createShorterToken(String host, String agent) {
+        User demo = User.UserFactory.getDemoUser();
+        TokenContext c = new TokenContext(demo.getUsername());
+        c.setHostAddress(host);
+        c.setUserAgent(agent);
+        c.setExpirationTime(TimeUtils.plusSeconds(
+                BeanConfiguration.getBeans().getConfiguration()
+                        .getShortTokenTTL()).getMillis());
+        return c;
+    }
+
+    @Override
+    public ContainerRequestFilter getRequestFilter() {
+        return this;
+    }
+
+    @Override
+    public ContainerResponseFilter getResponseFilter() {
+        return null;
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/AuthService.java b/src/main/java/de/ids_mannheim/korap/web/service/AuthService.java
new file mode 100644
index 0000000..5e76016
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/service/AuthService.java
@@ -0,0 +1,222 @@
+package de.ids_mannheim.korap.web.service;
+
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ResourceFilters;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.ServiceVersion;
+import de.ids_mannheim.korap.web.KustvaktServer;
+import de.ids_mannheim.korap.web.filter.AuthFilter;
+import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+import org.slf4j.Logger;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+//import com.sun.xml.internal.messaging.saaj.util.Base64;
+
+/**
+ * @author hanl
+ * @date 24/01/2014
+ */
+@Path(KustvaktServer.API_VERSION + "/auth")
+@ResourceFilters({ PiwikFilter.class })
+@Produces(MediaType.TEXT_HTML + ";charset=utf-8")
+public class AuthService {
+
+    //todo: bootstrap function to transmit certain default configuration settings and examples (example user queries,
+    // default usersettings, etc.)
+    private static Logger jlog = KustvaktLogger.initiate(AuthService.class);
+
+    private AuthenticationManagerIface controller;
+    //    private SendMail mail;
+
+    public AuthService() {
+        this.controller = BeanConfiguration.getBeans()
+                .getAuthenticationManager();
+        //todo: replace with real property values
+        //        this.mail = new SendMail(ExtConfiguration.getMailProperties());
+    }
+
+    /**
+     * represents json string with data. All GUI clients can access this method to get certain default values
+     * --> security checks?
+     *
+     * @return String
+     */
+    @GET
+    @Path("bootstrap")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response bootstrap() {
+        Map m = new HashMap();
+        m.put("settings", new UserSettings().toObjectMap());
+        m.put("ql", BeanConfiguration.getBeans().getConfiguration()
+                .getQueryLanguages());
+        m.put("SortTypes", null); // types of sorting that are supported!
+        m.put("version", ServiceVersion.getAPIVersion());
+        return Response.ok(JsonUtils.toJSON(m)).build();
+    }
+
+    @GET
+    @Path("status")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class })
+    public Response getStatus(@Context SecurityContext context,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        return Response.ok(ctx.toJSON()).build();
+    }
+
+    @GET
+    @Path("apiToken")
+    public Response requestAPIToken(@Context HttpHeaders headers,
+            @Context Locale locale,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            @HeaderParam("referer-url") String referer,
+            @QueryParam("scope") String scope) {
+        List<String> auth = headers
+                .getRequestHeader(ContainerRequest.AUTHORIZATION);
+
+        if (auth == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.PERMISSION_DENIED);
+        String[] values = BasicHttpAuth.decode(auth.get(0));
+
+        // "Invalid syntax for username and password"
+        if (values == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.PERMISSION_DENIED);
+
+        if (values[0].equalsIgnoreCase("null") | values[1]
+                .equalsIgnoreCase("null"))
+            // is actual an invalid request
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.REQUEST_INVALID);
+
+        Map<String, Object> attr = new HashMap<>();
+        if (scope != null && !scope.isEmpty())
+            attr.put(Attributes.SCOPES, scope);
+        attr.put(Attributes.HOST, host);
+        attr.put(Attributes.USER_AGENT, agent);
+        TokenContext context;
+        try {
+            User user = controller.authenticate(0, values[0], values[1], attr);
+            this.controller.getUserDetails(user);
+            context = controller.createTokenContext(user, attr,
+                    Attributes.API_AUTHENTICATION);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+
+        return Response.ok(context.toResponse()).build();
+    }
+
+    // todo:
+    @Deprecated
+    @GET
+    @Path("refresh")
+    public Response refresh(@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        TokenContext newContext;
+
+        //        try {
+        //            newContext = controller.refresh(ctx);
+        //        }catch (KorAPException e) {
+        //            KorAPLogger.ERROR_LOGGER.error("Exception encountered!", e);
+        //            throw BeanConfiguration.getResponseHandler().throwit(e);
+        //        }
+        //        return Response.ok().entity(newContext.getToken()).build();
+        return null;
+    }
+
+    @GET
+    @Path("sessionToken")
+    public Response requestSession(@Context HttpHeaders headers,
+            @Context Locale locale,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host) {
+        List<String> auth = headers
+                .getRequestHeader(ContainerRequest.AUTHORIZATION);
+
+        if (auth == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.PERMISSION_DENIED);
+
+        String[] values = BasicHttpAuth.decode(auth.get(0));
+        //        authentication = StringUtils.stripTokenType(authentication);
+        //        String[] values = new String(
+        //                DatatypeConverter.parseBase64Binary(authentication)).split(":");
+        //        String[] values = Base64.base64Decode(authentication).split(":");
+
+        // "Invalid syntax for username and password"
+        if (values == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.PERMISSION_DENIED);
+
+        if (values[0].equalsIgnoreCase("null") | values[1]
+                .equalsIgnoreCase("null"))
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.REQUEST_INVALID);
+
+        Map<String, Object> attr = new HashMap<>();
+        attr.put(Attributes.HOST, host);
+        attr.put(Attributes.USER_AGENT, agent);
+        TokenContext context;
+        try {
+            User user = controller.authenticate(0, values[0], values[1], attr);
+            context = controller.createTokenContext(user, attr,
+                    Attributes.SESSION_AUTHENTICATION);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().entity(context.toJSON()).build();
+    }
+
+    // fixme: security issues: setup shibboleth compatible authentication system
+    // todo: will be purged with token authentication --> shib is client side
+    @POST
+    @Consumes("application/x-www-form-urlencoded")
+    @Produces("application/json")
+    @Path("shibboleth")
+    public Response loginshib(@Context HttpHeaders headers,
+            @Context Locale locale,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            @QueryParam("client_id") String client_id) {
+
+        // the shibfilter decrypted the values
+        // define default provider for returned access token strategy?!
+
+        Map<String, Object> attr = new HashMap<>();
+        attr.put(Attributes.HOST, host);
+        attr.put(Attributes.USER_AGENT, agent);
+
+        TokenContext context;
+
+        try {
+            // todo: distinguish type KorAP/Shibusers
+            User user = controller.authenticate(1, null, null, attr);
+            context = controller.createTokenContext(user, attr, null);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().entity(context.toJSON()).build();
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/OAuthService.java b/src/main/java/de/ids_mannheim/korap/web/service/OAuthService.java
new file mode 100644
index 0000000..525eca9
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/service/OAuthService.java
@@ -0,0 +1,551 @@
+package de.ids_mannheim.korap.web.service;
+
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ResourceFilters;
+import de.ids_mannheim.korap.config.*;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.handlers.OAuth2Handler;
+import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.user.Attributes;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.web.KustvaktServer;
+import de.ids_mannheim.korap.web.filter.AuthFilter;
+import de.ids_mannheim.korap.web.filter.BlockFilter;
+import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
+import org.apache.oltu.oauth2.as.issuer.MD5Generator;
+import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
+import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
+import org.apache.oltu.oauth2.as.request.OAuthAuthzRequest;
+import org.apache.oltu.oauth2.as.request.OAuthTokenRequest;
+import org.apache.oltu.oauth2.as.response.OAuthASResponse;
+import org.apache.oltu.oauth2.common.OAuth;
+import org.apache.oltu.oauth2.common.error.OAuthError;
+import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
+import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.apache.oltu.oauth2.common.message.OAuthResponse;
+import org.apache.oltu.oauth2.common.message.types.GrantType;
+import org.apache.oltu.oauth2.common.message.types.ResponseType;
+import org.apache.oltu.oauth2.common.message.types.TokenType;
+import org.apache.oltu.oauth2.common.utils.OAuthUtils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author hanl
+ * @date 07/06/2014
+ */
+//todo: only allow oauth2 access_token requests GET methods?
+//todo: allow refresh tokens
+@Path(KustvaktServer.API_VERSION + "/oauth2")
+//@ResourceFilters({ AccessLevelFilter.class, PiwikFilter.class })
+public class OAuthService {
+
+    private OAuth2Handler handler;
+    private AuthenticationManagerIface controller;
+    private EncryptionIface crypto;
+    private KustvaktConfiguration config;
+
+    public OAuthService() {
+        this.handler = new OAuth2Handler(
+                BeanConfiguration.getBeans().getPersistenceClient());
+        this.controller = BeanConfiguration.getBeans()
+                .getAuthenticationManager();
+        this.crypto = BeanConfiguration.getBeans().getEncryption();
+        this.config = BeanConfiguration.getBeans().getConfiguration();
+    }
+
+    @POST
+    @Path("unregister")
+    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    public Response unregisterClient(@Context SecurityContext context,
+            @HeaderParam("Host") String host,
+            @QueryParam("client_secret") String secret,
+            @QueryParam("client_id") String client_id) {
+        ClientInfo info = new ClientInfo(client_id, secret);
+        info.setUrl(host);
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            this.handler.removeClient(info,
+                    this.controller.getUser(ctx.getUsername()));
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+    @POST
+    @Path("register")
+    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    public Response registerClient(@Context SecurityContext context,
+            @HeaderParam("Host") String host,
+            @QueryParam("redirect_url") String rurl) {
+        ClientInfo info = new ClientInfo(crypto.createID(),
+                crypto.createToken());
+        info.setUrl(host);
+        if (rurl == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.ILLEGAL_ARGUMENT, "Missing parameter!",
+                            "redirect_url");
+        info.setRedirect_uri(rurl);
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            this.handler.registerClient(info,
+                    this.controller.getUser(ctx.getUsername()));
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok(info.toJSON()).build();
+    }
+
+    @GET
+    @Path("info")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response getStatus(@Context SecurityContext context,
+            @QueryParam("scope") String scopes) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        User user;
+        try {
+            user = this.controller.getUser(ctx.getUsername());
+            this.controller.getUserDetails(user);
+            Set<String> base_scope = StringUtils
+                    .toSet((String) ctx.getParameters().get(Attributes.SCOPES),
+                            " ");
+            base_scope.retainAll(StringUtils.toSet(scopes));
+            scopes = StringUtils.toString(base_scope);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        // json format with scope callback parameter
+        return Response.ok(JsonUtils.toJSON(Scopes
+                .mapOpenIDConnectScopes(scopes, user.getDetails()))).build();
+    }
+
+    @GET
+    @Path("authorizations")
+    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    public Response getAuthorizations(@Context SecurityContext context,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host) {
+        // works on all tokens, but access to native apps cannot be revoked!
+        // check secret and id and retrieve access tokens
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            User user = this.controller.getUser(ctx.getUsername());
+            Collection auths = this.handler.getAuthorizedClients(user.getId());
+            if (auths.isEmpty())
+                return Response.noContent().build();
+            return Response.ok(JsonUtils.toJSON(auths)).build();
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+    }
+
+    // todo: scopes for access_token are defined here
+    // todo: if user already has an access token registered for client and application, then redirect to token endpoint to retrive that token
+    // todo: demo account should be disabled for this function --> if authentication failed, client must redirect to login url (little login window)
+    @POST
+    @Path("authorize")
+    @Consumes("application/x-www-form-urlencoded")
+    @Produces("application/json")
+    @ResourceFilters({ BlockFilter.class })
+    public Response authorize(@Context HttpServletRequest request,
+            @Context SecurityContext context,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            MultivaluedMap<String, String> form)
+            throws OAuthSystemException, URISyntaxException {
+        // user needs to be authenticated to this service!
+        TokenContext c = (TokenContext) context.getUserPrincipal();
+
+        try {
+            OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(
+                    new FormRequestWrapper(request, form));
+            OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(
+                    new MD5Generator());
+            User user;
+
+            Map<String, Object> attr = new HashMap<>();
+            attr.put(Attributes.HOST, host);
+            attr.put(Attributes.USER_AGENT, agent);
+            attr.put(Attributes.USERNAME, c.getUsername());
+            // also extractable via authorization header
+            attr.put(Attributes.CLIENT_ID, oauthRequest.getClientId());
+            attr.put(Attributes.CLIENT_SECRET, oauthRequest.getClientSecret());
+            StringBuilder scopes = new StringBuilder();
+            for (String scope : oauthRequest.getScopes())
+                scopes.append(scope + " ");
+            attr.put(Attributes.SCOPES, scopes.toString());
+
+            try {
+                user = controller.getUser(c.getUsername());
+                controller.getUserDetails(user);
+            }catch (KustvaktException e) {
+                throw BeanConfiguration.getResponseHandler().throwit(e);
+            }
+
+            // register response according to response_type
+            String responseType = oauthRequest
+                    .getParam(OAuth.OAUTH_RESPONSE_TYPE);
+
+            OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse
+                    .authorizationResponse(request,
+                            HttpServletResponse.SC_FOUND);
+
+            final String authorizationCode = oauthIssuerImpl
+                    .authorizationCode();
+            ClientInfo info = this.handler
+                    .getClient(oauthRequest.getClientId());
+
+            if (info == null || !info.getClient_secret()
+                    .equals(oauthRequest.getClientSecret())) {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                        .setError(OAuthError.CodeResponse.UNAUTHORIZED_CLIENT)
+                        .setErrorDescription("Unauthorized client!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }
+
+            if (!info.getRedirect_uri()
+                    .contains(oauthRequest.getRedirectURI())) {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                        .setError(OAuthError.CodeResponse.INVALID_REQUEST)
+                        .setErrorDescription("Unauthorized redirect!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }
+
+            String accessToken = this.handler
+                    .getToken(oauthRequest.getClientId(), user.getId());
+            //todo: test this with parameters
+            if (accessToken != null) {
+                final OAuthResponse response = builder.location("/oauth2/token")
+                        .setParam(OAuth.OAUTH_CLIENT_ID,
+                                oauthRequest.getClientId())
+                        .setParam(OAuth.OAUTH_CLIENT_SECRET,
+                                oauthRequest.getClientSecret())
+                        .buildQueryMessage();
+                return Response.status(response.getResponseStatus())
+                        .location(new URI(response.getLocationUri())).build();
+            }
+
+            if (responseType.equals(ResponseType.CODE.toString())) {
+                try {
+                    AuthCodeInfo codeInfo = new AuthCodeInfo(
+                            info.getClient_id(), authorizationCode);
+                    codeInfo.setScopes(StringUtils
+                            .toString(oauthRequest.getScopes(), " "));
+                    this.handler.authorize(codeInfo, user);
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+                builder.setParam(OAuth.OAUTH_RESPONSE_TYPE,
+                        ResponseType.CODE.toString());
+                builder.setCode(authorizationCode);
+
+            }else if (responseType.contains(ResponseType.TOKEN.toString())) {
+                try {
+                    AuthCodeInfo codeInfo = new AuthCodeInfo(
+                            info.getClient_id(), authorizationCode);
+                    codeInfo.setScopes(StringUtils
+                            .toString(oauthRequest.getScopes(), " "));
+                    this.handler.authorize(codeInfo, user);
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+
+                builder.setParam(OAuth.OAUTH_RESPONSE_TYPE,
+                        ResponseType.TOKEN.toString());
+                builder.setCode(authorizationCode);
+
+                String token = oauthIssuerImpl.accessToken();
+                this.handler.addToken(authorizationCode, token,
+                        config.getLongTokenTTL());
+                builder.setAccessToken(token);
+                builder.setExpiresIn((long) config.getLongTokenTTL());
+
+                // skips authorization code type and returns id_token and access token directly
+                if (oauthRequest.getScopes().contains("openid")) {
+                    try {
+                        TokenContext new_context = this.controller
+                                .createTokenContext(user, attr, null);
+                        builder.setParam(new_context.getTokenType(),
+                                new_context.getToken());
+                    }catch (KustvaktException e) {
+                        throw BeanConfiguration.getResponseHandler().throwit(e);
+                    }
+                }
+            }else {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                        .setError(
+                                OAuthError.CodeResponse.UNSUPPORTED_RESPONSE_TYPE)
+                        .setErrorDescription("Unsupported Response type!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }
+
+            String redirectURI = oauthRequest.getRedirectURI();
+
+            // enables state parameter to disable cross-site scripting attacks
+            final OAuthResponse response = builder.location(redirectURI)
+                    .buildQueryMessage();
+            if (OAuthUtils.isEmpty(redirectURI)) {
+                throw new WebApplicationException(
+                        Response.status(HttpServletResponse.SC_BAD_REQUEST)
+                                .entity("OAuth callback url needs to be provided by client!!!\n")
+                                .build());
+            }
+
+            return Response.status(response.getResponseStatus())
+                    .location(new URI(response.getLocationUri())).build();
+        }catch (OAuthProblemException e) {
+            e.printStackTrace();
+            final Response.ResponseBuilder responseBuilder = Response
+                    .status(HttpServletResponse.SC_BAD_REQUEST);
+            String redirectUri = e.getRedirectUri();
+
+            if (OAuthUtils.isEmpty(redirectUri))
+                throw new WebApplicationException(responseBuilder
+                        .entity("OAuth callback url needs to be provided by client!!!\n")
+                        .build());
+
+            final OAuthResponse response = OAuthASResponse
+                    .errorResponse(HttpServletResponse.SC_BAD_REQUEST).error(e)
+                    .location(redirectUri).buildQueryMessage();
+            final URI location = new URI(response.getLocationUri());
+            return responseBuilder.location(location).build();
+        }catch (OAuthSystemException | URISyntaxException | KustvaktException e) {
+            e.printStackTrace();
+        }
+        return Response.noContent().build();
+    }
+
+    @POST
+    @Path("revoke")
+    public Response revokeToken(@Context HttpServletRequest request,
+            @Context SecurityContext context,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host)
+            throws OAuthSystemException, URISyntaxException {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+
+            if (!this.handler.revokeToken(ctx.getToken())) {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                        .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
+                        .setErrorDescription("Invalid access token!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }
+
+        }catch (KustvaktException e) {
+            e.printStackTrace();
+            // fixme: do something
+            /**
+             * final Response.ResponseBuilder responseBuilder = Response
+             .status(HttpServletResponse.SC_FOUND);
+             String redirectUri = e.getRedirectUri();
+
+             final OAuthResponse response = OAuthASResponse
+             .errorResponse(HttpServletResponse.SC_FOUND).error(e)
+             .location(redirectUri).buildQueryMessage();
+             final URI location = new URI(response.getLocationUri());
+             return responseBuilder.location(location).build();
+             */
+        }
+
+        return Response.ok().build();
+    }
+
+    @POST
+    @Consumes("application/x-www-form-urlencoded")
+    @Produces("application/json")
+    @Path("token")
+    public Response requestToken(@Context HttpServletRequest request,
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            MultivaluedMap form) throws OAuthSystemException {
+        boolean openid_valid = false;
+        User user = null;
+        OAuthTokenRequest oauthRequest;
+        OAuthASResponse.OAuthTokenResponseBuilder builder = OAuthASResponse
+                .tokenResponse(HttpServletResponse.SC_OK);
+
+        OAuthIssuer oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
+        ClientInfo info;
+        try {
+            oauthRequest = new OAuthTokenRequest(
+                    new FormRequestWrapper(request, form));
+
+            if ((info = this.handler.getClient(oauthRequest.getClientId()))
+                    == null) {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                        .setError(OAuthError.TokenResponse.INVALID_CLIENT)
+                        .setErrorDescription("Invalid client id!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }else if (!info.getClient_secret()
+                    .equals(oauthRequest.getClientSecret())) {
+                OAuthResponse res = OAuthASResponse
+                        .errorResponse(HttpServletResponse.SC_UNAUTHORIZED)
+                        .setError(OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
+                        .setErrorDescription("Invalid client secret!\n")
+                        .buildJSONMessage();
+                return Response.status(res.getResponseStatus())
+                        .entity(res.getBody()).build();
+            }
+
+            Map<String, Object> attr = new HashMap<>();
+            attr.put(Attributes.HOST, host);
+            attr.put(Attributes.USER_AGENT, agent);
+            attr.put(Attributes.SCOPES,
+                    StringUtils.toString(oauthRequest.getScopes(), " "));
+
+            // support code (for external clients only) and password grant type
+            // password grant at this point is only allowed with trusted clients (korap frontend)
+            if (oauthRequest.getGrantType().equalsIgnoreCase(
+                    GrantType.AUTHORIZATION_CODE.toString())) {
+                // validate auth code
+                AuthCodeInfo codeInfo;
+                try {
+                    //can this be joined with the simple retrieval of access tokens?
+                    // partially yes: auth code can be valid, even though no access token exists
+                    // --> zero result set
+                    codeInfo = this.handler
+                            .getAuthorization(oauthRequest.getCode());
+                    if (codeInfo == null) {
+                        OAuthResponse res = OAuthASResponse.errorResponse(
+                                HttpServletResponse.SC_UNAUTHORIZED).setError(
+                                OAuthError.TokenResponse.INVALID_REQUEST)
+                                .setErrorDescription(
+                                        "Invalid authorization code\n")
+                                .buildJSONMessage();
+                        return Response.status(res.getResponseStatus())
+                                .entity(res.getBody()).build();
+                    }else {
+                        openid_valid = codeInfo.getScopes().contains("openid");
+                        String accessToken = oauthIssuerImpl.accessToken();
+                        // auth code posesses the user reference. native apps access_tokens are directly associated with the user
+                        this.handler
+                                .addToken(oauthRequest.getCode(), accessToken,
+                                        config.getTokenTTL());
+
+                        builder.setTokenType(TokenType.BEARER.toString());
+                        builder.setExpiresIn(
+                                String.valueOf(config.getLongTokenTTL()));
+                        builder.setAccessToken(accessToken);
+                    }
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+                // todo: errors for invalid scopes or different scopes then during authorization request?
+                //todo ??
+                attr.put(Attributes.SCOPES, codeInfo.getScopes());
+
+            }else if (oauthRequest.getGrantType()
+                    .equalsIgnoreCase(GrantType.PASSWORD.toString())) {
+                //fixme: via https; as basic auth header and only if client is native!
+                if (!info.isConfidential()) {
+                    OAuthResponse res = OAuthASResponse
+                            .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
+                            .setError(
+                                    OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)
+                            .setErrorDescription(
+                                    "Grant type not supported for client!\n")
+                            .buildJSONMessage();
+                    return Response.status(res.getResponseStatus())
+                            .entity(res.getBody()).build();
+                }
+
+                openid_valid = true;
+                try {
+                    user = controller
+                            .authenticate(0, oauthRequest.getUsername(),
+                                    oauthRequest.getPassword(), attr);
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+
+                try {
+                    String accessToken = this.handler
+                            .getToken(oauthRequest.getClientId(), user.getId());
+                    if (accessToken == null) {
+                        accessToken = oauthIssuerImpl.accessToken();
+                        this.handler.addToken(accessToken, user.getId(),
+                                oauthRequest.getClientId(), StringUtils
+                                        .toString(oauthRequest.getScopes(),
+                                                " "), config.getLongTokenTTL());
+                    }
+                    builder.setTokenType(TokenType.BEARER.toString());
+                    builder.setExpiresIn(
+                            String.valueOf(config.getLongTokenTTL()));
+                    builder.setAccessToken(accessToken);
+
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+            }
+
+            if (openid_valid && oauthRequest.getScopes()
+                    .contains(Scopes.Scope.openid.toString())) {
+                try {
+                    if (user == null)
+                        user = controller
+                                .authenticate(0, oauthRequest.getUsername(),
+                                        oauthRequest.getPassword(), attr);
+                    controller.getUserDetails(user);
+                    attr.put(Attributes.CLIENT_SECRET,
+                            oauthRequest.getClientSecret());
+                    TokenContext c = controller.createTokenContext(user, attr,
+                            Attributes.OPENID_AUTHENTICATION);
+                    builder.setParam(c.getTokenType(), c.getToken());
+                }catch (KustvaktException e) {
+                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                }
+            }
+
+            OAuthResponse r = builder.buildJSONMessage();
+            return Response.status(r.getResponseStatus()).entity(r.getBody())
+                    .build();
+        }catch (OAuthProblemException ex) {
+            OAuthResponse r = OAuthResponse.errorResponse(401).error(ex)
+                    .buildJSONMessage();
+            return Response.status(r.getResponseStatus()).entity(r.getBody())
+                    .build();
+        }catch (OAuthSystemException e) {
+            e.printStackTrace();
+            // todo: throw error
+        }
+        return Response.noContent().build();
+    }
+
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/UserService.java b/src/main/java/de/ids_mannheim/korap/web/service/UserService.java
new file mode 100644
index 0000000..befa736
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/service/UserService.java
@@ -0,0 +1,456 @@
+package de.ids_mannheim.korap.web.service;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.sun.jersey.spi.container.ContainerRequest;
+import com.sun.jersey.spi.container.ResourceFilters;
+import de.ids_mannheim.korap.config.BeanConfiguration;
+import de.ids_mannheim.korap.config.Scopes;
+import de.ids_mannheim.korap.config.URIParam;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.security.ac.ResourceHandler;
+import de.ids_mannheim.korap.user.*;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.KustvaktLogger;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.utils.TimeUtils;
+import de.ids_mannheim.korap.web.KustvaktServer;
+import de.ids_mannheim.korap.web.filter.AuthFilter;
+import de.ids_mannheim.korap.web.filter.DefaultFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+import de.ids_mannheim.korap.web.utils.FormWrapper;
+import org.slf4j.Logger;
+
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author hanl
+ * @date 29/01/2014
+ */
+@Path(KustvaktServer.API_VERSION + "/user")
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+@ResourceFilters({ PiwikFilter.class })
+public class UserService {
+
+    private static Logger error = KustvaktLogger
+            .initiate(KustvaktLogger.ERROR_LOG);
+    private static Logger jlog = KustvaktLogger
+            .initiate(KustvaktLogger.SECURITY_LOG);
+    private AuthenticationManagerIface controller;
+    private ResourceHandler resourceHandler;
+
+    private
+    @Context
+    UriInfo info;
+
+    public UserService() {
+        this.controller = BeanConfiguration.getBeans()
+                .getAuthenticationManager();
+        //        this.resourceHandler = BeanConfiguration.getResourceHandler();
+    }
+
+    // fixme: json contains password in clear text. Encrypt request?
+    // fixme: should also collect service exception, not just db exception!
+    @POST
+    @Path("register")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    public Response signUp(
+            @HeaderParam(ContainerRequest.USER_AGENT) String agent,
+            @HeaderParam(ContainerRequest.HOST) String host,
+            @Context Locale locale, MultivaluedMap form_values) {
+
+        FormWrapper wrapper = new FormWrapper(form_values);
+
+        wrapper.put(Attributes.HOST, host);
+        wrapper.put(Attributes.USER_AGENT, agent);
+        UriBuilder uriBuilder;
+        User user;
+        if (wrapper.get(Attributes.EMAIL) == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
+                            "email");
+
+        try {
+            uriBuilder = info.getBaseUriBuilder();
+            uriBuilder.path(KustvaktServer.API_VERSION).path("user")
+                    .path("confirm");
+
+            user = controller.createUserAccount(wrapper);
+
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        URIParam uri = user.getField(URIParam.class);
+        if (uri.hasValues()) {
+            uriBuilder.queryParam(Attributes.QUERY_PARAM_URI,
+                    uri.getUriFragment())
+                    .queryParam(Attributes.QUERY_PARAM_USER,
+                            user.getUsername());
+            jlog.info("registration was successful for user '{}'",
+                    form_values.get(Attributes.USERNAME));
+            Map object = new HashMap();
+            object.put("confirm_uri", uriBuilder.build());
+            object.put("uri_expiration",
+                    TimeUtils.format(uri.getUriExpiration()));
+            return Response.ok(JsonUtils.toJSON(object)).build();
+        }else {
+            // todo: return error or warning
+            return null;
+        }
+
+    }
+
+    //todo: password update in special function?
+    @POST
+    @Path("update")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.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 BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("confirm")
+    @Produces(MediaType.TEXT_HTML)
+    public Response confirmRegistration(@QueryParam("uri") String uritoken,
+            @Context Locale locale, @QueryParam("user") String username) {
+        if (uritoken == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
+                            "Uri-Token");
+        if (username == null)
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
+                            "Username");
+
+        try {
+            controller.confirmRegistration(uritoken, username);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok("success").build();
+    }
+
+    // todo: auditing!
+    @POST
+    @Path("requestReset")
+    @Produces(MediaType.TEXT_HTML)
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    public Response requestPasswordReset(@Context Locale locale, String json) {
+        JsonNode node = JsonUtils.readTree(json);
+        StringBuilder builder = new StringBuilder();
+        String username, email;
+        username = node.path(Attributes.USERNAME).asText();
+        email = node.path(Attributes.EMAIL).asText();
+
+        // deprecated --> depends on the client!
+        //        String url = config.getMailProperties()
+        //                .getProperty("korap.frontend.url", "");
+        //        if (url.isEmpty())
+        //            return Response.ok("URLException: Missing source URL").build();
+
+        //        URIUtils utils = new URIUtils(info);
+        // may inject the actual REST url in a redirect request?!
+        //        UriBuilder uriBuilder = UriBuilder.fromUri(url).fragment("reset");
+        Object[] objects;
+        try {
+            builder.append("?");
+            // just append the endpint fragment plus the query parameter.
+            // the address by which the data is handled depends on the frontend
+            objects = controller.validateResetPasswordRequest(username, email);
+            builder.append(Attributes.QUERY_PARAM_URI).append("=")
+                    .append(objects[0]);
+            builder.append(Attributes.QUERY_PARAM_USER).append("=")
+                    .append(username);
+        }catch (KustvaktException e) {
+            error.error("Eoxception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+
+        ObjectNode obj = JsonUtils.createObjectNode();
+        obj.put(Attributes.URI, builder.toString());
+        obj.put(Attributes.URI_EXPIRATION, String.valueOf(objects[1]));
+        return Response.ok(JsonUtils.toJSON(obj)).build();
+    }
+
+    @POST
+    @Path("reset")
+    @Produces(MediaType.TEXT_HTML)
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    public Response resetPassword(
+            @QueryParam(Attributes.QUERY_PARAM_URI) String uri,
+            @QueryParam(Attributes.QUERY_PARAM_USER) String username,
+            @Context HttpHeaders headers, String passphrase) {
+        try {
+            controller.resetPassword(uri, username, passphrase);
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            return Response.notModified().build();
+        }
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("info")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response getStatus(@Context SecurityContext context,
+            @QueryParam("scope") String scope) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        User user;
+        try {
+            user = controller.getUser(ctx.getUsername());
+            controller.getUserDetails(user);
+            Set<String> base_scope = StringUtils
+                    .toSet((String) ctx.getParameters().get(Attributes.SCOPES),
+                            " ");
+            base_scope.retainAll(StringUtils.toSet(scope));
+            scope = StringUtils.toString(base_scope);
+        }catch (KustvaktException e) {
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok(JsonUtils.toJSON(Scopes
+                .mapOpenIDConnectScopes(scope, user.getDetails()))).build();
+    }
+
+    @GET
+    @Path("settings")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response getUserSettings(@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        User user;
+        try {
+            user = controller.getUser(ctx.getUsername());
+            controller.getUserSettings(user);
+
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok(JsonUtils.toJSON(user.getSettings().toObjectMap()))
+                .build();
+    }
+
+    // todo: test
+    @POST
+    @Path("settings")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response updateSettings(@Context SecurityContext context,
+            @Context Locale locale, String values) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Map<String, Object> settings;
+        try {
+            settings = JsonUtils.read(values, Map.class);
+        }catch (IOException e) {
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.REQUEST_INVALID,
+                            "Could not read parameters", values);
+        }
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            UserSettings us = controller.getUserSettings(user);
+            // todo:
+            //            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);
+            us.updateObjectSettings(settings);
+            controller.updateUserSettings(user, us);
+            if (user.isDemo())
+                return Response.notModified().build();
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("details")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response getDetails(@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        User user;
+        try {
+            user = controller.getUser(ctx.getUsername());
+            controller.getUserDetails(user);
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+
+        return Response.ok(JsonUtils.toJSON(user.getDetails().toMap())).build();
+    }
+
+    @POST
+    @Path("details")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response updateDetails(@Context SecurityContext context,
+            @Context Locale locale, String values) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        System.out.println("TO BE UPDATED DATA " + values);
+        System.out.println("USER CONTEXT " + ctx);
+        Map<String, String> details;
+        try {
+            details = JsonUtils.read(values, Map.class);
+        }catch (IOException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler()
+                    .throwit(StatusCodes.REQUEST_INVALID,
+                            "Could not read parameters", values);
+        }
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            UserDetails det = controller.getUserDetails(user);
+            det.updateDetails(details);
+            controller.updateUserDetails(user, det);
+            if (user.isDemo())
+                return Response.notModified().build();
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+
+        return Response.ok().build();
+    }
+
+    //fixme: if policy allows, foreign user might be allowed to change search!
+    @POST
+    @Path("queries")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.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) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok(JsonUtils.toJSON(add)).build();
+    }
+
+    @DELETE
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response deleteUser(@Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            if (user.isDemo())
+                return Response.notModified().build();
+            controller.deleteAccount(user);
+        }catch (KustvaktException e) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("queries")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.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) {
+            error.error("Exception encountered!", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok(queryStr).build();
+    }
+
+    @GET
+    @Path("logout")
+    @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
+            PiwikFilter.class })
+    public Response logout(@Context SecurityContext ctx,
+            @Context Locale locale) {
+        TokenContext context = (TokenContext) ctx.getUserPrincipal();
+        try {
+            controller.logout(context);
+        }catch (KustvaktException e) {
+            error.error("Logout Exception", e);
+            throw BeanConfiguration.getResponseHandler().throwit(e);
+        }
+        return Response.ok().build();
+    }
+}
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/FormRequestWrapper.java b/src/main/java/de/ids_mannheim/korap/web/utils/FormRequestWrapper.java
new file mode 100644
index 0000000..143aa04
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/FormRequestWrapper.java
@@ -0,0 +1,64 @@
+package de.ids_mannheim.korap.web.utils;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.ws.rs.core.MultivaluedMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Helper class to wrapp multivaluedmap into a hashmap. Depending on the strict parameter,
+ * list values are retained in the resulting wrapper map.
+ *
+ * @author hanl
+ * @date 25/04/2015
+ */
+public class FormRequestWrapper extends HttpServletRequestWrapper {
+
+    private MultivaluedMap<String, String> form;
+
+    /**
+     * Constructs a request object wrapping the given request.
+     *
+     * @param request
+     * @throws IllegalArgumentException if the request is null
+     */
+    public FormRequestWrapper(HttpServletRequest request,
+            MultivaluedMap<String, String> form) {
+        super(request);
+        this.form = form;
+    }
+
+    @Override
+    public String getParameter(String name) {
+        String value = super.getParameter(name);
+        if (value == null)
+            value = form.getFirst(name);
+        return value;
+    }
+
+    @Override
+    public String[] getParameterValues(String name) {
+        String[] values = super.getParameterValues(name);
+        if (values == null && form.get(name) != null) {
+            values = new String[form.get(name).size()];
+            values = form.get(name).toArray(values);
+        }
+        return values;
+    }
+
+    public HashMap<String, Object> toMap(boolean strict) {
+        HashMap<String, Object> map = new HashMap<>();
+        for (Map.Entry<String, List<String>> e : form.entrySet()) {
+            if (e.getValue().size() == 1)
+                map.put(e.getKey(), e.getValue().get(0));
+            else if (!strict)
+                map.put(e.getKey(), e.getValue());
+        }
+        return map;
+    }
+
+}
+
+
diff --git a/src/test/java/CollectionQueryBuilderTest.java b/src/test/java/CollectionQueryBuilderTest.java
new file mode 100644
index 0000000..de9a089
--- /dev/null
+++ b/src/test/java/CollectionQueryBuilderTest.java
@@ -0,0 +1,87 @@
+import com.fasterxml.jackson.databind.JsonNode;
+import de.ids_mannheim.korap.utils.CollectionQueryBuilder3;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import org.junit.Test;
+
+/**
+ * @author hanl
+ * @date 12/08/2015
+ */
+public class CollectionQueryBuilderTest {
+
+    @Test
+    public void testsimpleAdd() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "WPD");
+        //        System.out.println(b.toJSON());
+    }
+
+    @Test
+    public void testSimpleConjunctive() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "WPD").and()
+                .addSegment("textClass", CollectionQueryBuilder3.EQ.EQUAL,
+                        "freizeit");
+        //        System.out.println(b.toJSON());
+    }
+
+    @Test
+    public void testSimpleDisjunctive() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "WPD").and()
+                .addSegment("textClass", CollectionQueryBuilder3.EQ.EQUAL,
+                        "freizeit");
+        //        System.out.println(b.toJSON());
+    }
+
+    @Test
+    public void testComplexSubQuery() {
+
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "ADF").and()
+                .addSub("textClass=freizeit & corpusID=WPD");
+        //        System.out.println(b.toJSON());
+    }
+
+    @Test // basically joining two or more resource queries
+    public void testAddResourceQueryAfter() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "ADF").and()
+                .addSub("textClass=freizeit & corpusID=WPD");
+        //        System.out.println(b.toJSON());
+
+        //        join.addSegment("textClass", "politik");
+    }
+
+    @Test // basically joining two or more resource queries
+    public void testAddResourceQueryBefore() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "ADF").and()
+                .addSub("textClass!=freizeit & corpusID=WPD");
+
+        //        CollectionQueryBuilder3 join = new CollectionQueryBuilder3();
+        //        join.addRaw(b.toJSON());
+        //        join.addSegment("textClass", "politik");
+        //        System.out.println("JOINED " + join.toJSON());
+    }
+
+    @Test
+    public void test1() {
+        CollectionQueryBuilder3 b = new CollectionQueryBuilder3();
+        b.addSegment("corpusID", CollectionQueryBuilder3.EQ.EQUAL, "ADF").or()
+                .addSub("textClass=freizeit & corpusID=WPD");
+
+        CollectionQueryBuilder3 c = new CollectionQueryBuilder3();
+        c.setBaseQuery(b.toJSON());
+        c.addSub("textClass=wissenschaft");
+
+        JsonNode node = JsonUtils.readTree(c.toJSON());
+
+        assert node != null;
+        assert node.at("/collection/operands/2/@type").asText()
+                .equals("koral:doc");
+        assert node.at("/collection/operands/2/value").asText()
+                .equals("wissenschaft");
+    }
+
+}
