refactoring; test inits
diff --git a/src/main/java/de/ids_mannheim/korap/web/.DS_Store b/src/main/java/de/ids_mannheim/korap/web/.DS_Store
index 32f11f9..1383f97 100644
--- a/src/main/java/de/ids_mannheim/korap/web/.DS_Store
+++ b/src/main/java/de/ids_mannheim/korap/web/.DS_Store
Binary files differ
diff --git a/src/main/java/de/ids_mannheim/korap/web/ClientsHandler.java b/src/main/java/de/ids_mannheim/korap/web/ClientsHandler.java
index 8b846eb..65fdafa 100644
--- a/src/main/java/de/ids_mannheim/korap/web/ClientsHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/web/ClientsHandler.java
@@ -6,7 +6,7 @@
 import com.sun.jersey.api.client.config.ClientConfig;
 import com.sun.jersey.api.client.config.DefaultClientConfig;
 import com.sun.jersey.core.util.MultivaluedMapImpl;
-import de.ids_mannheim.korap.exceptions.KorAPException;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 
 import javax.ws.rs.core.MultivaluedMap;
@@ -27,17 +27,19 @@
         this.service = client.resource(address);
     }
 
-    public String getResponse(String path, String key, Object value) throws KorAPException {
+    public String getResponse(String path, String key, Object value) throws
+            KustvaktException {
         MultivaluedMap map = new MultivaluedMapImpl();
         map.add(key, value);
         try {
             return service.path(path).queryParams(map).get(String.class);
         } catch (UniformInterfaceException e) {
-            throw new KorAPException(StatusCodes.REQUEST_INVALID);
+            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
         }
     }
 
-    public String getResponse(MultivaluedMap map, String... paths) throws KorAPException {
+    public String getResponse(MultivaluedMap map, String... paths) throws
+            KustvaktException {
         try {
             WebResource resource = service;
             for (String p : paths)
@@ -45,7 +47,7 @@
             resource = resource.queryParams(map);
             return resource.get(String.class);
         } catch (UniformInterfaceException e) {
-            throw new KorAPException(StatusCodes.REQUEST_INVALID);
+            throw new KustvaktException(StatusCodes.REQUEST_INVALID);
         }
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java b/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java
index 1e97bd8..c8961932 100644
--- a/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java
+++ b/src/main/java/de/ids_mannheim/korap/web/KustvaktBaseServer.java
@@ -28,7 +28,7 @@
         else
             BeanConfiguration.loadClasspathContext();
 
-        kargs.setRootClasses(
+        kargs.setRootPackages(
                 new String[] { "de.ids_mannheim.korap.web.service.light" });
         startServer(kargs);
     }
@@ -71,7 +71,7 @@
 
             // http://stackoverflow.com/questions/9670363/how-do-i-programmatically-configure-jersey-to-use-jackson-for-json-deserializa
             final ResourceConfig rc = new PackagesResourceConfig(
-                    kargs.rootClasses);
+                    kargs.rootPackages);
 
             // from http://stackoverflow.com/questions/7421574/embedded-jetty-with-jersey-or-resteasy
             contextHandler
@@ -106,7 +106,7 @@
         private String config;
         private int port;
         private SslContextFactory sslContext;
-        private String[] rootClasses;
+        private String[] rootPackages;
 
         public KustvaktArgs() {
             this.port = -1;
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
index 8346e1f..eff8b57 100644
--- a/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/AuthFilter.java
@@ -9,6 +9,7 @@
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.web.utils.KorAPContext;
+import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
 import javax.ws.rs.ext.Provider;
 
@@ -40,7 +41,7 @@
                         .getTokenStatus(authentication, host, ua);
 
             }catch (KustvaktException e) {
-                throw BeanConfiguration.getResponseHandler().throwit(e);
+                throw KustvaktResponseHandler.throwit(e);
             }
 
             if (context != 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
index a8ffe89..e28be03 100644
--- a/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/DefaultFilter.java
@@ -39,7 +39,8 @@
 
     private TokenContext createShorterToken(String host, String agent) {
         User demo = User.UserFactory.getDemoUser();
-        TokenContext c = new TokenContext(demo.getUsername());
+        TokenContext c = new TokenContext();
+        c.setUsername(demo.getUsername());
         c.setHostAddress(host);
         c.setUserAgent(agent);
         c.setExpirationTime(TimeUtils.plusSeconds(
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
index 5e76016..d4b98fc 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/AuthService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/AuthService.java
@@ -18,6 +18,7 @@
 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.KustvaktResponseHandler;
 import org.slf4j.Logger;
 
 import javax.ws.rs.*;
@@ -82,6 +83,7 @@
         return Response.ok(ctx.toJSON()).build();
     }
 
+    // todo: rename scope to scopes!
     @GET
     @Path("apiToken")
     public Response requestAPIToken(@Context HttpHeaders headers,
@@ -89,29 +91,29 @@
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
             @HeaderParam(ContainerRequest.HOST) String host,
             @HeaderParam("referer-url") String referer,
-            @QueryParam("scope") String scope) {
+            @QueryParam("scopes") String scopes) {
         List<String> auth = headers
                 .getRequestHeader(ContainerRequest.AUTHORIZATION);
 
         if (auth == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.PERMISSION_DENIED);
         String[] values = BasicHttpAuth.decode(auth.get(0));
 
         // "Invalid syntax for username and password"
         if (values == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.PERMISSION_DENIED);
 
         if (values[0].equalsIgnoreCase("null") | values[1]
                 .equalsIgnoreCase("null"))
             // is actual an invalid request
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.REQUEST_INVALID);
 
         Map<String, Object> attr = new HashMap<>();
-        if (scope != null && !scope.isEmpty())
-            attr.put(Attributes.SCOPES, scope);
+        if (scopes != null && !scopes.isEmpty())
+            attr.put(Attributes.SCOPES, scopes);
         attr.put(Attributes.HOST, host);
         attr.put(Attributes.USER_AGENT, agent);
         TokenContext context;
@@ -121,7 +123,7 @@
             context = controller.createTokenContext(user, attr,
                     Attributes.API_AUTHENTICATION);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok(context.toResponse()).build();
@@ -140,7 +142,7 @@
         //            newContext = controller.refresh(ctx);
         //        }catch (KorAPException e) {
         //            KorAPLogger.ERROR_LOGGER.error("Exception encountered!", e);
-        //            throw BeanConfiguration.getResponseHandler().throwit(e);
+        //            throw KustvaktResponseHandler.throwit(e);
         //        }
         //        return Response.ok().entity(newContext.getToken()).build();
         return null;
@@ -156,7 +158,7 @@
                 .getRequestHeader(ContainerRequest.AUTHORIZATION);
 
         if (auth == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.PERMISSION_DENIED);
 
         String[] values = BasicHttpAuth.decode(auth.get(0));
@@ -167,12 +169,12 @@
 
         // "Invalid syntax for username and password"
         if (values == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.PERMISSION_DENIED);
 
         if (values[0].equalsIgnoreCase("null") | values[1]
                 .equalsIgnoreCase("null"))
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.REQUEST_INVALID);
 
         Map<String, Object> attr = new HashMap<>();
@@ -184,7 +186,7 @@
             context = controller.createTokenContext(user, attr,
                     Attributes.SESSION_AUTHENTICATION);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok().entity(context.toJSON()).build();
     }
@@ -215,7 +217,7 @@
             User user = controller.authenticate(1, null, null, attr);
             context = controller.createTokenContext(user, attr, null);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.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
index 525eca9..ae4c57e 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/OAuthService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/OAuthService.java
@@ -15,10 +15,11 @@
 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.BlockingFilter;
 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 de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 import org.apache.oltu.oauth2.as.issuer.MD5Generator;
 import org.apache.oltu.oauth2.as.issuer.OAuthIssuer;
 import org.apache.oltu.oauth2.as.issuer.OAuthIssuerImpl;
@@ -75,7 +76,7 @@
 
     @POST
     @Path("unregister")
-    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    @ResourceFilters({ AuthFilter.class, BlockingFilter.class })
     public Response unregisterClient(@Context SecurityContext context,
             @HeaderParam("Host") String host,
             @QueryParam("client_secret") String secret,
@@ -87,14 +88,14 @@
             this.handler.removeClient(info,
                     this.controller.getUser(ctx.getUsername()));
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
 
     @POST
     @Path("register")
-    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    @ResourceFilters({ AuthFilter.class, BlockingFilter.class })
     public Response registerClient(@Context SecurityContext context,
             @HeaderParam("Host") String host,
             @QueryParam("redirect_url") String rurl) {
@@ -102,7 +103,7 @@
                 crypto.createToken());
         info.setUrl(host);
         if (rurl == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.ILLEGAL_ARGUMENT, "Missing parameter!",
                             "redirect_url");
         info.setRedirect_uri(rurl);
@@ -111,17 +112,18 @@
             this.handler.registerClient(info,
                     this.controller.getUser(ctx.getUsername()));
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok(info.toJSON()).build();
     }
 
+    // todo: change parameter to scopes!
     @GET
     @Path("info")
     @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
             PiwikFilter.class })
     public Response getStatus(@Context SecurityContext context,
-            @QueryParam("scope") String scopes) {
+            @QueryParam("scopes") String scopes) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         User user;
         try {
@@ -133,7 +135,7 @@
             base_scope.retainAll(StringUtils.toSet(scopes));
             scopes = StringUtils.toString(base_scope);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         // json format with scope callback parameter
         return Response.ok(JsonUtils.toJSON(Scopes
@@ -142,7 +144,7 @@
 
     @GET
     @Path("authorizations")
-    @ResourceFilters({ AuthFilter.class, BlockFilter.class })
+    @ResourceFilters({ AuthFilter.class, BlockingFilter.class })
     public Response getAuthorizations(@Context SecurityContext context,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
             @HeaderParam(ContainerRequest.HOST) String host) {
@@ -156,18 +158,18 @@
                 return Response.noContent().build();
             return Response.ok(JsonUtils.toJSON(auths)).build();
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.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: if user already has an access token registered for client and application, then redirect to token endpoint to retrieve 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 })
+    @ResourceFilters({ BlockingFilter.class })
     public Response authorize(@Context HttpServletRequest request,
             @Context SecurityContext context,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
@@ -200,17 +202,13 @@
                 user = controller.getUser(c.getUsername());
                 controller.getUserDetails(user);
             }catch (KustvaktException e) {
-                throw BeanConfiguration.getResponseHandler().throwit(e);
+                throw KustvaktResponseHandler.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
@@ -240,8 +238,12 @@
 
             String accessToken = this.handler
                     .getToken(oauthRequest.getClientId(), user.getId());
-            //todo: test this with parameters
+
+            //todo: test correct redirect and parameters
             if (accessToken != null) {
+                // fixme: correct status code?
+                OAuthASResponse.OAuthResponseBuilder builder = OAuthASResponse
+                        .status(HttpServletResponse.SC_FOUND);
                 final OAuthResponse response = builder.location("/oauth2/token")
                         .setParam(OAuth.OAUTH_CLIENT_ID,
                                 oauthRequest.getClientId())
@@ -252,7 +254,21 @@
                         .location(new URI(response.getLocationUri())).build();
             }
 
+            final OAuthResponse response;
+            String redirectURI = oauthRequest.getRedirectURI();
+            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());
+            }
+
             if (responseType.equals(ResponseType.CODE.toString())) {
+                OAuthASResponse.OAuthAuthorizationResponseBuilder builder = OAuthASResponse
+                        .authorizationResponse(request,
+                                HttpServletResponse.SC_FOUND);
+                builder.location(redirectURI);
+
                 try {
                     AuthCodeInfo codeInfo = new AuthCodeInfo(
                             info.getClient_id(), authorizationCode);
@@ -260,32 +276,30 @@
                             .toString(oauthRequest.getScopes(), " "));
                     this.handler.authorize(codeInfo, user);
                 }catch (KustvaktException e) {
-                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                    throw KustvaktResponseHandler.throwit(e);
                 }
                 builder.setParam(OAuth.OAUTH_RESPONSE_TYPE,
                         ResponseType.CODE.toString());
                 builder.setCode(authorizationCode);
+                response = builder.buildBodyMessage();
 
             }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);
-                }
-
+                OAuthASResponse.OAuthTokenResponseBuilder builder = OAuthASResponse
+                        .tokenResponse(HttpServletResponse.SC_OK);
                 builder.setParam(OAuth.OAUTH_RESPONSE_TYPE,
                         ResponseType.TOKEN.toString());
-                builder.setCode(authorizationCode);
+                builder.location(redirectURI);
 
                 String token = oauthIssuerImpl.accessToken();
-                this.handler.addToken(authorizationCode, token,
+                String refresh = oauthIssuerImpl.refreshToken();
+
+                this.handler.addToken(token, refresh, user.getId(),
+                        oauthRequest.getClientId(),
+                        StringUtils.toString(oauthRequest.getScopes(), " "),
                         config.getLongTokenTTL());
                 builder.setAccessToken(token);
-                builder.setExpiresIn((long) config.getLongTokenTTL());
+                builder.setRefreshToken(refresh);
+                builder.setExpiresIn(String.valueOf(config.getLongTokenTTL()));
 
                 // skips authorization code type and returns id_token and access token directly
                 if (oauthRequest.getScopes().contains("openid")) {
@@ -295,9 +309,10 @@
                         builder.setParam(new_context.getTokenType(),
                                 new_context.getToken());
                     }catch (KustvaktException e) {
-                        throw BeanConfiguration.getResponseHandler().throwit(e);
+                        throw KustvaktResponseHandler.throwit(e);
                     }
                 }
+                response = builder.buildBodyMessage();
             }else {
                 OAuthResponse res = OAuthASResponse
                         .errorResponse(HttpServletResponse.SC_BAD_REQUEST)
@@ -308,23 +323,22 @@
                 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());
-            }
+            //
+            //            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();
@@ -454,18 +468,20 @@
                     }else {
                         openid_valid = codeInfo.getScopes().contains("openid");
                         String accessToken = oauthIssuerImpl.accessToken();
+                        String refreshToken = oauthIssuerImpl.refreshToken();
                         // auth code posesses the user reference. native apps access_tokens are directly associated with the user
                         this.handler
                                 .addToken(oauthRequest.getCode(), accessToken,
-                                        config.getTokenTTL());
+                                        refreshToken, config.getTokenTTL());
 
                         builder.setTokenType(TokenType.BEARER.toString());
                         builder.setExpiresIn(
                                 String.valueOf(config.getLongTokenTTL()));
                         builder.setAccessToken(accessToken);
+                        builder.setRefreshToken(refreshToken);
                     }
                 }catch (KustvaktException e) {
-                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                    throw KustvaktResponseHandler.throwit(e);
                 }
                 // todo: errors for invalid scopes or different scopes then during authorization request?
                 //todo ??
@@ -492,18 +508,22 @@
                             .authenticate(0, oauthRequest.getUsername(),
                                     oauthRequest.getPassword(), attr);
                 }catch (KustvaktException e) {
-                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                    throw KustvaktResponseHandler.throwit(e);
                 }
 
                 try {
                     String accessToken = this.handler
                             .getToken(oauthRequest.getClientId(), user.getId());
                     if (accessToken == null) {
+                        String refresh = oauthIssuerImpl.refreshToken();
                         accessToken = oauthIssuerImpl.accessToken();
-                        this.handler.addToken(accessToken, user.getId(),
-                                oauthRequest.getClientId(), StringUtils
-                                        .toString(oauthRequest.getScopes(),
-                                                " "), config.getLongTokenTTL());
+                        this.handler
+                                .addToken(accessToken, refresh, user.getId(),
+                                        oauthRequest.getClientId(), StringUtils
+                                                .toString(oauthRequest
+                                                        .getScopes(), " "),
+                                        config.getLongTokenTTL());
+                        builder.setRefreshToken(refresh);
                     }
                     builder.setTokenType(TokenType.BEARER.toString());
                     builder.setExpiresIn(
@@ -511,7 +531,7 @@
                     builder.setAccessToken(accessToken);
 
                 }catch (KustvaktException e) {
-                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                    throw KustvaktResponseHandler.throwit(e);
                 }
             }
 
@@ -529,7 +549,7 @@
                             Attributes.OPENID_AUTHENTICATION);
                     builder.setParam(c.getTokenType(), c.getToken());
                 }catch (KustvaktException e) {
-                    throw BeanConfiguration.getResponseHandler().throwit(e);
+                    throw KustvaktResponseHandler.throwit(e);
                 }
             }
 
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
index befa736..d3bc6a2 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/UserService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/UserService.java
@@ -20,9 +20,11 @@
 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 de.ids_mannheim.korap.web.utils.FormRequestWrapper;
+import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 import org.slf4j.Logger;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.*;
 import javax.ws.rs.core.*;
 import java.io.IOException;
@@ -60,18 +62,19 @@
     @Path("register")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     public Response signUp(
+            @Context HttpServletRequest request,
             @HeaderParam(ContainerRequest.USER_AGENT) String agent,
             @HeaderParam(ContainerRequest.HOST) String host,
             @Context Locale locale, MultivaluedMap form_values) {
 
-        FormWrapper wrapper = new FormWrapper(form_values);
+        FormRequestWrapper wrapper = new FormRequestWrapper(request, 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()
+        if (wrapper.getParameter(Attributes.EMAIL) == null)
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
                             "email");
 
@@ -80,10 +83,10 @@
             uriBuilder.path(KustvaktServer.API_VERSION).path("user")
                     .path("confirm");
 
-            user = controller.createUserAccount(wrapper);
+            user = controller.createUserAccount(wrapper.toMap(true));
 
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         URIParam uri = user.getField(URIParam.class);
         if (uri.hasValues()) {
@@ -124,7 +127,7 @@
             //                            node.path("new_password").asText());
             controller.updateAccount(user);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -135,18 +138,19 @@
     public Response confirmRegistration(@QueryParam("uri") String uritoken,
             @Context Locale locale, @QueryParam("user") String username) {
         if (uritoken == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
                             "Uri-Token");
         if (username == null)
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.ILLEGAL_ARGUMENT, "parameter missing",
                             "Username");
 
         try {
             controller.confirmRegistration(uritoken, username);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler
+                    .throwit(e);
         }
         return Response.ok("success").build();
     }
@@ -184,7 +188,7 @@
                     .append(username);
         }catch (KustvaktException e) {
             error.error("Eoxception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         ObjectNode obj = JsonUtils.createObjectNode();
@@ -215,7 +219,7 @@
     @ResourceFilters({ AuthFilter.class, DefaultFilter.class,
             PiwikFilter.class })
     public Response getStatus(@Context SecurityContext context,
-            @QueryParam("scope") String scope) {
+            @QueryParam("scopes") String scope) {
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
         User user;
         try {
@@ -227,7 +231,7 @@
             base_scope.retainAll(StringUtils.toSet(scope));
             scope = StringUtils.toString(base_scope);
         }catch (KustvaktException e) {
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok(JsonUtils.toJSON(Scopes
                 .mapOpenIDConnectScopes(scope, user.getDetails()))).build();
@@ -247,7 +251,7 @@
 
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok(JsonUtils.toJSON(user.getSettings().toObjectMap()))
                 .build();
@@ -266,7 +270,7 @@
         try {
             settings = JsonUtils.read(values, Map.class);
         }catch (IOException e) {
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.REQUEST_INVALID,
                             "Could not read parameters", values);
         }
@@ -285,7 +289,7 @@
                 return Response.notModified().build();
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok().build();
@@ -304,7 +308,7 @@
             controller.getUserDetails(user);
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok(JsonUtils.toJSON(user.getDetails().toMap())).build();
@@ -325,7 +329,7 @@
             details = JsonUtils.read(values, Map.class);
         }catch (IOException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler()
+            throw KustvaktResponseHandler
                     .throwit(StatusCodes.REQUEST_INVALID,
                             "Could not read parameters", values);
         }
@@ -339,7 +343,7 @@
                 return Response.notModified().build();
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok().build();
@@ -394,7 +398,7 @@
             //            }
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok(JsonUtils.toJSON(add)).build();
     }
@@ -411,7 +415,7 @@
             controller.deleteAccount(user);
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -433,7 +437,7 @@
             queryStr = "";
         }catch (KustvaktException e) {
             error.error("Exception encountered!", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok(queryStr).build();
     }
@@ -449,7 +453,7 @@
             controller.logout(context);
         }catch (KustvaktException e) {
             error.error("Logout Exception", e);
-            throw BeanConfiguration.getResponseHandler().throwit(e);
+            throw KustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
index 2f300be..b7463d9 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
@@ -8,7 +8,9 @@
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.query.serialize.MetaQueryBuilder;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.resource.RewriteProcessor;
+import de.ids_mannheim.korap.resource.rewrite.FoundryInject;
+import de.ids_mannheim.korap.resource.rewrite.PublicCollection;
+import de.ids_mannheim.korap.resource.rewrite.RewriteHandler;
 import de.ids_mannheim.korap.utils.KustvaktLogger;
 import de.ids_mannheim.korap.web.ClientsHandler;
 import de.ids_mannheim.korap.web.SearchKrill;
@@ -37,7 +39,7 @@
 
     private SearchKrill searchKrill;
     private ClientsHandler graphDBhandler;
-    private RewriteProcessor processor;
+    private RewriteHandler processor;
     private KustvaktConfiguration config;
 
     public LightService() {
@@ -45,7 +47,9 @@
         this.searchKrill = new SearchKrill(config.getIndexDir());
         UriBuilder builder = UriBuilder.fromUri("http://10.0.10.13").port(9997);
         this.graphDBhandler = new ClientsHandler(builder.build());
-        this.processor = new RewriteProcessor(this.config);
+        this.processor = new RewriteHandler();
+        this.processor.add(new FoundryInject(this.config));
+        this.processor.add(new PublicCollection());
     }
 
     /**
@@ -92,14 +96,14 @@
         ss.setMeta(meta);
         if (cq != null)
             ss.setCollection(cq);
-        return Response.ok(processor.process(ss.toJSON())).build();
+        return Response.ok(processor.apply(ss.toJSON(), null)).build();
     }
 
     @POST
     @Path("search")
     public Response queryRaw(@QueryParam("engine") String engine,
             String jsonld) {
-        jsonld = processor.process(jsonld);
+        jsonld = processor.apply(jsonld, null);
         // todo: should be possible to add the meta part to the query serialization
         jlog.info("Serialized search: {}", jsonld);
 
@@ -133,7 +137,7 @@
         if (cq != null)
             serializer.setCollection(cq);
 
-        String query = processor.process(serializer.toJSON());
+        String query = processor.apply(serializer.toJSON(), null);
         jlog.info("the serialized query {}", query);
 
         // This may not work with the the KoralQuery
@@ -200,7 +204,7 @@
             //                meta.addEntry("itemsPerResource", 1);
             QuerySerializer s = new QuerySerializer().setQuery(query, ql, v)
                     .setMeta(meta);
-            query = processor.process(s.toJSON());
+            query = processor.apply(s.toJSON(), null);
         }
         String result;
         try {
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
index 143aa04..05a1bb5 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/FormRequestWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/FormRequestWrapper.java
@@ -3,9 +3,7 @@
 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;
+import java.util.*;
 
 /**
  * Helper class to wrapp multivaluedmap into a hashmap. Depending on the strict parameter,
@@ -59,6 +57,14 @@
         return map;
     }
 
+    public void put(String key, String value) {
+        this.form.putSingle(key, value);
+    }
+
+    public void put(String key, String... values) {
+        this.form.put(key, Arrays.asList(values));
+    }
+
 }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/FormWrapper.java b/src/main/java/de/ids_mannheim/korap/web/utils/FormWrapper.java
index 913c848..f099158 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/FormWrapper.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/FormWrapper.java
@@ -12,6 +12,7 @@
  * @author hanl
  * @date 18/05/2015
  */
+@Deprecated
 public class FormWrapper extends HashMap<String, Object> {
 
     public FormWrapper(MultivaluedMap form, boolean strict) {
diff --git a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
index c35ce5b..1a52c3d 100644
--- a/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
+++ b/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
@@ -1,8 +1,7 @@
 package de.ids_mannheim.korap.web.utils;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
-import de.ids_mannheim.korap.exceptions.BaseException;
-import de.ids_mannheim.korap.exceptions.KorAPException;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuditingIface;
 import de.ids_mannheim.korap.response.Notifications;
@@ -32,32 +31,24 @@
             throw new RuntimeException("Auditing handler must be set!");
     }
 
-    public static WebApplicationException throwit(BaseException e) {
-        //fixme: ??!
-        e.printStackTrace();
+    public static WebApplicationException throwit(KustvaktException e) {
         return new WebApplicationException(
                 Response.status(Response.Status.BAD_REQUEST)
                         .entity(buildNotification(e)).build());
     }
 
-    @Deprecated
     public static WebApplicationException throwit(int code) {
-        KorAPException e = new KorAPException(code);
-        return new WebApplicationException(
-                Response.status(Response.Status.OK).entity(buildNotification(e))
-                        .build());
+        return new WebApplicationException(Response.status(Response.Status.OK)
+                .entity(buildNotification(code, "", "")).build());
     }
 
-    @Deprecated
     public static WebApplicationException throwit(int code, String message,
             String entity) {
-        KorAPException e = new KorAPException(code, message, entity);
-        return new WebApplicationException(
-                Response.status(Response.Status.OK).entity(buildNotification(e))
-                        .build());
+        return new WebApplicationException(Response.status(Response.Status.OK)
+                .entity(buildNotification(code, message, entity)).build());
     }
 
-    private static String buildNotification(BaseException e) {
+    private static String buildNotification(KustvaktException e) {
         register(e.getRecords());
         return buildNotification(e.getStatusCode(), e.getMessage(),
                 e.getEntity());
@@ -71,7 +62,8 @@
     }
 
     public static WebApplicationException throwAuthenticationException() {
-        KorAPException e = new KorAPException(StatusCodes.BAD_CREDENTIALS);
+        KustvaktException e = new KustvaktException(
+                StatusCodes.BAD_CREDENTIALS);
         return new WebApplicationException(
                 Response.status(Response.Status.UNAUTHORIZED)
                         .header(HttpHeaders.WWW_AUTHENTICATE,