Fixed KustvaktResponseHandler and missing exceptions in JsonUtils. 

Change-Id: I3a95361659cebf91dc9175d08891dd67815b1851
diff --git a/core/pom.xml b/core/pom.xml
index 51c7bab..465f0b9 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>de.ids_mannheim.korap</groupId>
 	<artifactId>Kustvakt-core</artifactId>
-	<version>0.59.8</version>
+	<version>0.59.9</version>
 
 	<properties>
 		<java.version>1.7</java.version>
diff --git a/core/src/main/java/de/ids_mannheim/korap/auditing/AuditRecord.java b/core/src/main/java/de/ids_mannheim/korap/auditing/AuditRecord.java
index c2e0791..5370c9f 100644
--- a/core/src/main/java/de/ids_mannheim/korap/auditing/AuditRecord.java
+++ b/core/src/main/java/de/ids_mannheim/korap/auditing/AuditRecord.java
@@ -2,6 +2,8 @@
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.Getter;
@@ -93,7 +95,7 @@
     }
 
 
-    public AuditRecord fromJson (String json) {
+    public AuditRecord fromJson (String json) throws KustvaktException {
         JsonNode n = JsonUtils.readTree(json);
         AuditRecord r = new AuditRecord();
         r.setCategory(CATEGORY.valueOf(n.path("category").asText()));
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java b/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
index d924fd1..79dc884 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/BeanConfiguration.java
@@ -106,7 +106,7 @@
             this.handler = new DefaultHandler();
             this.context = context;
             // todo: better method?!
-            KustvaktResponseHandler.init(getAuditingProvider());
+            new KustvaktResponseHandler(getAuditingProvider());
         }
 
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java b/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
index c0126da..60324c0 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
@@ -40,7 +40,7 @@
         this.handler = new DefaultHandler();
         this.context = context;
         // todo: better method?!
-        KustvaktResponseHandler.init(getAuditingProvider());
+        new KustvaktResponseHandler(getAuditingProvider());
     }
 
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java b/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
index 72e650c..e435b5b 100644
--- a/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
+++ b/core/src/main/java/de/ids_mannheim/korap/exceptions/KustvaktException.java
@@ -20,7 +20,8 @@
     private String userid;
     private Integer statusCode;
     private String entity;
-
+    private String notification;
+    private boolean isNotification;
 
     public KustvaktException (int status) {
         this.statusCode = status;
@@ -31,6 +32,15 @@
         this.entity = Arrays.asList(args).toString();
     }
 
+    public KustvaktException (int status, String notification, boolean isNotification) {
+        this.statusCode = status;
+        this.notification = notification;
+        this.isNotification = isNotification;
+    }
+    
+    public boolean hasNotification () {
+        return isNotification;
+    }
 
     public KustvaktException (Object userid, int status) {
         this(status);
diff --git a/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java b/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
index 1bbe4ce..b555efb 100644
--- a/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
+++ b/core/src/main/java/de/ids_mannheim/korap/exceptions/StatusCodes.java
@@ -28,19 +28,24 @@
      */
 
     public static final int NO_QUERY = 301;
-    public static final int SERIALIZATION_FAILED = 302;
+    // EM: e.g. vc type
+    public static final int INVALID_TYPE = 302;
     public static final int MISSING_ATTRIBUTE = 303;
     public static final int INVALID_ATTRIBUTE = 304;
     public static final int UNSUPPORTED_VALUE = 305;
-
+    public static final int SERIALIZATION_FAILED = 306;
+    public static final int DESERIALIZATION_FAILED = 307;
+    
     /**
      *  400 status codes for authorization and rewrite functions
      */
 
     // fixme: use unsupported resource and include type in return message
     public static final int POLICY_ERROR_DEFAULT = 400;
+    public static final int UNAUTHORIZED_OPERATION = 401;
+    
     public static final int UNSUPPORTED_RESOURCE = 402;
-    public static final int REWRITE_FAILED = 403;
+//    public static final int REWRITE_FAILED = 403;
     //public static final int UNSUPPORTED_FOUNDRY = 403;
     //public static final int UNSUPPORTED_CORPUS = 404;
     //public static final int UNSUPPORTED_LAYER = 405;
@@ -49,13 +54,14 @@
     //public static final int CORPUS_REWRITE = 407;
     //public static final int FOUNDRY_REWRITE = 408;
     //public static final int FOUNDRY_INJECTION = 409;
-    public static final int MISSING_RESOURCE = 405;
+//    public static final int MISSING_RESOURCE = 405;
     public static final int NO_POLICY_TARGET = 406;
     public static final int NO_POLICY_CONDITION = 407;
     public static final int NO_POLICY_PERMISSION = 408;
     public static final int NO_POLICIES = 409;
 
-
+    
+    
     /**
      * 500 status codes for access control related components (also
      * policy rewrite)
diff --git a/core/src/main/java/de/ids_mannheim/korap/resources/KustvaktResource.java b/core/src/main/java/de/ids_mannheim/korap/resources/KustvaktResource.java
index 7bbb43f..20908ad 100644
--- a/core/src/main/java/de/ids_mannheim/korap/resources/KustvaktResource.java
+++ b/core/src/main/java/de/ids_mannheim/korap/resources/KustvaktResource.java
@@ -2,6 +2,8 @@
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.AccessLevel;
@@ -9,6 +11,7 @@
 import lombok.Setter;
 import org.joda.time.DateTime;
 
+import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -86,11 +89,15 @@
 
 
     public void setFields (String fields) {
-        Map s = JsonUtils.readSimple(fields, Map.class);
-        if (s == null)
+        Map s = null;
+        try {
+            s = JsonUtils.convertToClass(fields, Map.class);
+        }
+        catch (KustvaktException e) {
             throw new RuntimeException(
                     "Fields could not be read for resource '" + persistentID
                             + "'!");
+        }
         this.fields = s;
     }
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/user/DataFactory.java b/core/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
index 5d3f85f..e9b1387 100644
--- a/core/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
+++ b/core/src/main/java/de/ids_mannheim/korap/user/DataFactory.java
@@ -93,7 +93,12 @@
         public Object convertData (String data) {
             if (data == null)
                 return JsonUtils.createObjectNode();
-            return JsonUtils.readTree(data);
+            try {
+                return JsonUtils.readTree(data);
+            }
+            catch (KustvaktException e) {
+                return null;
+            }
         }
 
 
diff --git a/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java b/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
index 6a7f92e..d3b1944 100644
--- a/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
+++ b/core/src/main/java/de/ids_mannheim/korap/user/TokenContext.java
@@ -3,6 +3,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import lombok.AccessLevel;
@@ -98,7 +99,7 @@
 
 
     //todo: complete
-    public static TokenContext fromJSON (String s) {
+    public static TokenContext fromJSON (String s) throws KustvaktException {
         JsonNode node = JsonUtils.readTree(s);
         TokenContext c = new TokenContext();
         if (node != null) {
@@ -109,7 +110,7 @@
     }
 
 
-    public static TokenContext fromOAuth2 (String s) {
+    public static TokenContext fromOAuth2 (String s) throws KustvaktException {
         JsonNode node = JsonUtils.readTree(s);
         TokenContext c = new TokenContext();
         if (node != null) {
diff --git a/core/src/main/java/de/ids_mannheim/korap/user/User.java b/core/src/main/java/de/ids_mannheim/korap/user/User.java
index 1792682..1de5d5d 100644
--- a/core/src/main/java/de/ids_mannheim/korap/user/User.java
+++ b/core/src/main/java/de/ids_mannheim/korap/user/User.java
@@ -3,6 +3,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.ParamFields;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.utils.KustvaktMap;
@@ -293,7 +294,7 @@
         }
 
 
-        public static KorAPUser toUser (String value) {
+        public static KorAPUser toUser (String value) throws KustvaktException {
             JsonNode node = JsonUtils.readTree(value);
             KorAPUser user = UserFactory.getUser(node.path(Attributes.USERNAME)
                     .asText());
diff --git a/core/src/main/java/de/ids_mannheim/korap/utils/JsonUtils.java b/core/src/main/java/de/ids_mannheim/korap/utils/JsonUtils.java
index c9f0a25..d011ba7 100644
--- a/core/src/main/java/de/ids_mannheim/korap/utils/JsonUtils.java
+++ b/core/src/main/java/de/ids_mannheim/korap/utils/JsonUtils.java
@@ -1,11 +1,5 @@
 package de.ids_mannheim.korap.utils;
 
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -13,6 +7,15 @@
 import java.util.List;
 import java.util.Map;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+
 /**
  * @author hanl
  * @date 28/01/2014
@@ -33,12 +36,13 @@
     }
 
 
-    public static JsonNode readTree (String s) {
+    public static JsonNode readTree (String json) throws KustvaktException {
         try {
-            return mapper.readTree(s);
+            return mapper.readTree(json);
         }
         catch (IOException e) {
-            return null;
+            throw new KustvaktException(StatusCodes.DESERIALIZATION_FAILED,
+                    "Failed deserializing json object: " + json, json, e);
         }
     }
 
@@ -57,10 +61,11 @@
         return mapper.valueToTree(value);
     }
 
-    public static <T> T convert (JsonNode json, Class<T> cl) throws IOException {
+    public static <T> T convert (JsonNode json, Class<T> cl)
+            throws IOException {
         return mapper.convertValue(json, cl);
     }
-    
+
     public static <T> T read (String json, Class<T> cl) throws IOException {
         return mapper.readValue(json, cl);
     }
@@ -78,25 +83,28 @@
     }
 
 
-    public static <T> T readSimple (String json, Class<T> cl) {
+    public static <T> T convertToClass (String json, Class<T> cl) throws KustvaktException {
+        T t = null;
         try {
-            return mapper.readValue(json, cl);
+            t = mapper.readValue(json, cl);
         }
         catch (IOException e) {
-            return null;
+            throw new KustvaktException(StatusCodes.DESERIALIZATION_FAILED,
+                    "Failed deserializing json object: " + json, json, e);
         }
+        return t;
     }
 
 
     public static List<Map<String, Object>> convertToList (String json)
-            throws JsonProcessingException {
+            throws JsonProcessingException, KustvaktException {
         List d = new ArrayList();
         JsonNode node = JsonUtils.readTree(json);
         if (node.isArray()) {
             Iterator<JsonNode> nodes = node.iterator();
             while (nodes.hasNext()) {
-                Map<String, Object> map = mapper.treeToValue(nodes.next(),
-                        Map.class);
+                Map<String, Object> map =
+                        mapper.treeToValue(nodes.next(), Map.class);
                 d.add(map);
             }
         }
diff --git a/core/src/main/java/de/ids_mannheim/korap/utils/KoralCollectionQueryBuilder.java b/core/src/main/java/de/ids_mannheim/korap/utils/KoralCollectionQueryBuilder.java
index d2671be..361ab2b 100644
--- a/core/src/main/java/de/ids_mannheim/korap/utils/KoralCollectionQueryBuilder.java
+++ b/core/src/main/java/de/ids_mannheim/korap/utils/KoralCollectionQueryBuilder.java
@@ -2,10 +2,15 @@
 
 import java.util.List;
 
+import javax.ws.rs.WebApplicationException;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.query.serialize.CollectionQueryProcessor;
 import de.ids_mannheim.korap.response.Notifications;
@@ -28,6 +33,8 @@
     private JsonNode base;
     private StringBuilder builder;
     private String mergeOperator;
+    @Autowired
+    private KustvaktResponseHandler responseHandler;
 
 
     public KoralCollectionQueryBuilder () {
@@ -84,8 +91,7 @@
 
 
     public KoralCollectionQueryBuilder and () {
-        if (this.builder.length() != 0)
-            this.builder.append(" & ");
+        if (this.builder.length() != 0) this.builder.append(" & ");
         if (this.base != null && this.mergeOperator == null)
             this.mergeOperator = "AND";
         return this;
@@ -93,37 +99,37 @@
 
 
     public KoralCollectionQueryBuilder or () {
-        if (this.builder.length() != 0)
-            this.builder.append(" | ");
+        if (this.builder.length() != 0) this.builder.append(" | ");
         if (this.base != null && this.mergeOperator == null)
             this.mergeOperator = "OR";
         return this;
     }
 
 
-    public Object rebaseCollection (){
-        if (this.builder.length() == 0 && this.base == null)
-            return null;
+    public JsonNode rebaseCollection () throws KustvaktException {
+        if (this.builder.length() == 0 && this.base == null) return null;
 
         JsonNode request = null;
         if (this.builder.length() != 0) {
-            CollectionQueryProcessor tree = new CollectionQueryProcessor(
-                    this.verbose);
+            CollectionQueryProcessor tree =
+                    new CollectionQueryProcessor(this.verbose);
             tree.process(this.builder.toString());
-            if (tree.getErrors().size() > 0){
+            if (tree.getErrors().size() > 0) {
                 Notifications notif = new Notifications();
-                int code; 
-                for (List<Object> e : tree.getErrors()){
+                int code;
+                for (List<Object> e : tree.getErrors()) {
                     code = (int) e.get(0);
-                    if (e.get(1) instanceof String){
+                    if (e.get(1) instanceof String) {
                         notif.addError(code, (String) e.get(1));
                     }
-                    else{
+                    else {
                         notif.addError(code, (String[]) e.get(1));
                     }
                 }
-                
-                throw KustvaktResponseHandler.throwit(StatusCodes.SERIALIZATION_FAILED,notif.toJsonString());
+
+                String notificationStr = notif.toJsonString();
+                throw new KustvaktException(StatusCodes.SERIALIZATION_FAILED,
+                        notificationStr, true);
             }
             request = JsonUtils.valueToTree(tree.getRequestMap());
         }
@@ -153,8 +159,9 @@
                     return base;
                 else {
                     result = JsonBuilder.buildDocGroup(
-                            this.mergeOperator != null ? this.mergeOperator
-                                    .toLowerCase() : "and", result, tobase);
+                            this.mergeOperator != null
+                                    ? this.mergeOperator.toLowerCase() : "and",
+                            result, tobase);
                 }
                 ((ObjectNode) base).put("collection", result);
                 return base;
@@ -171,8 +178,9 @@
      * If no group in base query, consequent queries are skipped.
      * 
      * @param query
+     * @throws KustvaktException 
      */
-    public KoralCollectionQueryBuilder setBaseQuery (String query) {
+    public KoralCollectionQueryBuilder setBaseQuery (String query) throws KustvaktException {
         this.base = JsonUtils.readTree(query);
         return this;
     }
@@ -184,7 +192,7 @@
     }
 
 
-    public String toJSON () {
+    public String toJSON () throws KustvaktException {
         return JsonUtils.toJSON(rebaseCollection());
     }
 
@@ -208,7 +216,8 @@
         }
 
 
-        public static ObjectNode buildDocGroup (String op, JsonNode ... groups) {
+        public static ObjectNode buildDocGroup (String op,
+                JsonNode ... groups) {
             ObjectNode node = JsonUtils.createObjectNode();
             node.put("@type", "koral:docGroup");
             node.put("operation", "operation:" + op);
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java b/core/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
index 377efaa..f78b1a1 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
@@ -13,7 +13,6 @@
 import com.sun.jersey.spi.container.ResourceFilter;
 
 import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
@@ -32,12 +31,15 @@
 
     @Autowired
 	private AuthenticationManagerIface authManager;
+    
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
 
 	@Override
 	public ContainerRequest filter(ContainerRequest cr) {
 		String authentication = cr.getHeaderValue(ContainerRequest.AUTHORIZATION);
 		if (authentication == null) {
-			throw KustvaktResponseHandler.throwAuthenticationException("The authorization header value is missing.");
+			throw kustvaktResponseHandler.throwAuthenticationException("The authorization header value is missing.");
 		}
 
 		// decode password
@@ -60,12 +62,12 @@
 		try {
 			User user = authManager.authenticate(tokenType, username, token, attributes);
 			if (!user.isAdmin()){
-				throw KustvaktResponseHandler.throwAuthenticationException("Admin authentication failed.");
+				throw kustvaktResponseHandler.throwAuthenticationException("Admin authentication failed.");
 			}
 			Map<String, Object> properties = cr.getProperties();
 			properties.put("user", user);
 		} catch (KustvaktException e) {
-			throw KustvaktResponseHandler.throwAuthenticationException("User authentication failed.");
+			throw kustvaktResponseHandler.throwAuthenticationException("User authentication failed.");
 		}
 
 		TokenContext c = new TokenContext();
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java b/core/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
index 976c051..b8faf76 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/filter/BlockingFilter.java
@@ -9,6 +9,9 @@
 
 import javax.ws.rs.ext.Provider;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 /**
  * @author hanl
  * @date 11/12/2014
@@ -16,9 +19,13 @@
  *       endpoint filter to block access to an endpoint, in case no
  *       anonymous access should be allowed!
  */
+@Component
 @Provider
 public class BlockingFilter implements ContainerRequestFilter, ResourceFilter {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     @Override
     public ContainerRequest filter (ContainerRequest request) {
         TokenContext context;
@@ -26,11 +33,11 @@
             context = (TokenContext) request.getUserPrincipal();
         }
         catch (UnsupportedOperationException e) {
-            throw KustvaktResponseHandler.throwAuthenticationException("");
+            throw kustvaktResponseHandler.throwAuthenticationException("");
         }
 
         if(context == null || context.isDemo())
-            throw KustvaktResponseHandler.throwAuthenticationException("");
+            throw kustvaktResponseHandler.throwAuthenticationException("");
 
         return request;
     }
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java b/core/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
index 3724fc5..95cb077 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/filter/NonDemoBlockingFilter.java
@@ -9,6 +9,9 @@
 
 import javax.ws.rs.ext.Provider;
 
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
 /**
  * @author hanl
  * @date 11/12/2014
@@ -16,10 +19,14 @@
  *       endpoint filter to block access to an endpoint, in case no
  *       anonymous access should be allowed!
  */
+@Component
 @Provider
 public class NonDemoBlockingFilter implements ContainerRequestFilter,
         ResourceFilter {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     @Override
     public ContainerRequest filter (ContainerRequest request) {
         TokenContext context;
@@ -27,11 +34,11 @@
             context = (TokenContext) request.getUserPrincipal();
         }
         catch (UnsupportedOperationException e) {
-            throw KustvaktResponseHandler.throwAuthenticationException("");
+            throw kustvaktResponseHandler.throwAuthenticationException("");
         }
 
         if (context == null || context.isDemo())
-            throw KustvaktResponseHandler
+            throw kustvaktResponseHandler
                     .throwAuthenticationException("Service not available for non-authenticated "
                             + "or demo account users!");
         return request;
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java b/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
index 44fb085..e5517b6 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/utils/KustvaktResponseHandler.java
@@ -1,32 +1,31 @@
 package de.ids_mannheim.korap.web.utils;
 
+import java.util.List;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+
 import de.ids_mannheim.korap.auditing.AuditRecord;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.response.Notifications;
 
-import javax.ws.rs.WebApplicationException;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.Response;
-import java.util.List;
-
 /**
- * @author hanl
+ * @author hanl, margaretha
  * @date 29/01/2014
+ * @last 08/11/2017
  */
 public class KustvaktResponseHandler {
 
-    private static AuditingIface auditing;
+    private AuditingIface auditing;
 
-
-    public static void init (AuditingIface iface) {
-        if (auditing == null)
-            auditing = iface;
+    public KustvaktResponseHandler (AuditingIface iface) {
+        this.auditing = iface;
     }
-
-
-    private static void register (List<AuditRecord> records) {
+    
+    private void register (List<AuditRecord> records) {
         if (auditing != null && !records.isEmpty())
             auditing.audit(records);
         else if (auditing == null)
@@ -34,37 +33,44 @@
     }
 
 
-    public static WebApplicationException throwit (KustvaktException e) {
-        Response s = Response.status(getStatus(e.getStatusCode()))
-                .entity(buildNotification(e)).build();
+    public WebApplicationException throwit (KustvaktException e) {
+        Response s;
+        if (e.hasNotification()){
+            s = Response.status(getStatus(e.getStatusCode()))
+                    .entity(e.getNotification()).build();
+        }
+        else{
+            s = Response.status(getStatus(e.getStatusCode()))
+                    .entity(buildNotification(e)).build();
+        }
         return new WebApplicationException(s);
     }
 
-    public static WebApplicationException throwit (int code) {
+    public WebApplicationException throwit (int code) {
         return new WebApplicationException(Response.status(getStatus(code))
                 .entity(buildNotification(code, "", "")).build());
     }
 
 
-    public static WebApplicationException throwit (int code, String message,
+    public WebApplicationException throwit (int code, String message,
             String entity) {
         return new WebApplicationException(Response.status(getStatus(code))
                 .entity(buildNotification(code, message, entity)).build());
     }
 
-    public static WebApplicationException throwit (int code, String notification) {
+    public WebApplicationException throwit (int code, String notification) {
         return new WebApplicationException(Response.status(getStatus(code))
                 .entity(notification).build());
     }
     
-    private static String buildNotification (KustvaktException e) {
+    private String buildNotification (KustvaktException e) {
         register(e.getRecords());
         return buildNotification(e.getStatusCode(), e.getMessage(),
                 e.getEntity());
     }
 
 
-    public static String buildNotification (int code, String message,
+    public String buildNotification (int code, String message,
             String entity) {
         Notifications notif = new Notifications();
         notif.addError(code, message, entity);
@@ -73,7 +79,7 @@
 
 
     //todo:  if exception, make exception message and error code available if not masked!
-    public static WebApplicationException throwAuthenticationException (String username) {
+    public WebApplicationException throwAuthenticationException (String username) {
         return new WebApplicationException(Response
                 .status(Response.Status.UNAUTHORIZED)
                 .header(HttpHeaders.WWW_AUTHENTICATE,
@@ -84,7 +90,7 @@
 
 
 
-    private static Response.Status getStatus (int code) {
+    private Response.Status getStatus (int code) {
         Response.Status status = Response.Status.BAD_REQUEST;
         switch (code) {
 //            case StatusCodes.NO_VALUE_FOUND:
diff --git a/full/pom.xml b/full/pom.xml
index 7d476e4..1bfb4af 100644
--- a/full/pom.xml
+++ b/full/pom.xml
@@ -154,12 +154,13 @@
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Kustvakt-core</artifactId>
-			<version>0.59.8</version>
+			<version>0.59.9</version>
+			<type>jar</type>
 		</dependency>
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Kustvakt-core</artifactId>
-			<version>0.59.8</version>
+			<version>0.59.9</version>
 			<type>test-jar</type>
 			<scope>test</scope>
 		</dependency>
diff --git a/full/src/main/java/de/ids_mannheim/korap/filter/AuthFilter.java b/full/src/main/java/de/ids_mannheim/korap/filter/AuthFilter.java
index 79d5511..146879d 100644
--- a/full/src/main/java/de/ids_mannheim/korap/filter/AuthFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/filter/AuthFilter.java
@@ -27,6 +27,8 @@
     @Autowired
     private AuthenticationManagerIface userController;
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
 
 //    public AuthFilter () {
 //        this.userController = BeansFactory.getKustvaktContext()
@@ -48,7 +50,7 @@
                         ua);
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwAuthenticationException(authentication);
+                throw kustvaktResponseHandler.throwAuthenticationException(authentication);
             }
             // fixme: give reason why access is not granted?
             if (context != null
@@ -57,7 +59,7 @@
                             .isSecureRequired()))
                 request.setSecurityContext(new KustvaktContext(context));
             else
-                throw KustvaktResponseHandler.throwAuthenticationException("");
+                throw kustvaktResponseHandler.throwAuthenticationException("");
         }
         return request;
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java b/full/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
index 5520ffc..9cdc277 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/DocumentDao.java
@@ -29,6 +29,7 @@
  * @date 05/11/2014
  */
 // todo: error handling
+@Deprecated
 public class DocumentDao implements ResourceOperationIface<Document> {
 
     private NamedParameterJdbcTemplate jdbcTemplate;
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/AnnotationService.java b/full/src/main/java/de/ids_mannheim/korap/service/AnnotationService.java
index 164887b..c913e51 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/AnnotationService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/AnnotationService.java
@@ -24,6 +24,9 @@
             LoggerFactory.getLogger(AnnotationService.class);
 
     @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+
+    @Autowired
     private AnnotationDao annotationDao;
 
     @Autowired
@@ -59,7 +62,7 @@
                 }
                 else {
                     jlog.error("Annotation code is wrong: " + annotationCode);
-                    throw KustvaktResponseHandler.throwit(
+                    kustvaktResponseHandler.throwit(
                             new KustvaktException(StatusCodes.INVALID_ATTRIBUTE,
                                     "Bad attribute:", code));
                 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AdminController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AdminController.java
index c9e8a4b..53f0acf 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AdminController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AdminController.java
@@ -16,17 +16,16 @@
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
 
 import com.sun.jersey.api.core.HttpContext;
 import com.sun.jersey.spi.container.ResourceFilters;
 
 import de.ids_mannheim.korap.auditing.AuditRecord;
-import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.handlers.DocumentDao;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
-import de.ids_mannheim.korap.resources.Document;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.resources.Permissions;
 import de.ids_mannheim.korap.resources.ResourceFactory;
@@ -43,25 +42,22 @@
 /**
  * @author hanl, margaretha 
  * Created date 6/11/14. 
- * Last update: 04/2017
+ * Last update: 08/11/2017
+ * Last changes:
+ *  removed DocumentDao (EM)
  */
+@Controller
 @Path(KustvaktServer.API_VERSION + "/admin")
 @ResourceFilters({ AdminFilter.class, PiwikFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class AdminController {
 
     private static Logger jlog = LoggerFactory.getLogger(AdminController.class);
-
+    @Autowired
     private AuditingIface auditingController;
-    private DocumentDao documentDao;
 
-
-    public AdminController () {
-        this.auditingController = BeansFactory.getKustvaktContext()
-                .getAuditingProvider();
-        this.documentDao = new DocumentDao(
-                BeansFactory.getKustvaktContext().getPersistenceClient());
-    }
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
 
     // EM: not documented and tested, not sure what the purpose of the service is
     @GET
@@ -87,7 +83,7 @@
             integer_limit = Integer.valueOf(limit);
         }
         catch (NumberFormatException | NullPointerException e) {
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
+            throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT);
         }
         String result = JsonUtils.toJSON(auditingController.retrieveRecords(
                 AuditRecord.CATEGORY.valueOf(type.toUpperCase()), from_date,
@@ -112,31 +108,31 @@
             KustvaktException e = new KustvaktException(
                     StatusCodes.MISSING_ARGUMENT,
                     "The value of parameter type is missing.");
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         else if (name == null | name.isEmpty()) {
             KustvaktException e = new KustvaktException(
                     StatusCodes.MISSING_ARGUMENT,
                     "The value of parameter name is missing.");
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         else if (description == null | description.isEmpty()) {
             KustvaktException e = new KustvaktException(
                     StatusCodes.MISSING_ARGUMENT,
                     "The value of parameter description is missing.");
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         else if (group == null | group.isEmpty()) {
             KustvaktException e = new KustvaktException(
                     StatusCodes.MISSING_ARGUMENT,
                     "The value of parameter group is missing.");
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         else if (permissions == null | permissions.isEmpty()) {
             KustvaktException e = new KustvaktException(
                     StatusCodes.MISSING_ARGUMENT,
                     "The value of parameter permissions is missing.");
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
 
 
@@ -167,25 +163,10 @@
             pb.create();
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok().build();
     }
 
-
-    @POST
-    @Path("doc/{id}/add")
-    @Deprecated
-    public Response addDocument (@PathParam("id") String id) {
-        Document document = new Document(id);
-        try {
-            this.documentDao.storeResource(document, null);
-        }
-        catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok().build();
-    }
-
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
index 331ed6f..ac4f69f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AnnotationController.java
@@ -44,6 +44,9 @@
             LoggerFactory.getLogger(AnnotationController.class);
 
     @Autowired
+    KustvaktResponseHandler responseHandler;
+    
+    @Autowired
     private AnnotationService annotationService;
 
     /**
@@ -73,12 +76,19 @@
     @Path("description")
     @Consumes(MediaType.APPLICATION_JSON)
     public Response getFoundryDescriptions (String json) {
-        JsonNode node = JsonUtils.readTree(json);
-        if (node == null) {
-            throw KustvaktResponseHandler
+        if (json == null || json.isEmpty()) {
+            throw responseHandler
                     .throwit(new KustvaktException(StatusCodes.MISSING_ARGUMENT,
                             "Missing a json string.", ""));
         }
+        
+        JsonNode node;
+        try {
+            node = JsonUtils.readTree(json);
+        }
+        catch (KustvaktException e1) {
+            throw responseHandler.throwit(e1);
+        }
 
         String language;
         if (!node.has("language")) {
@@ -90,7 +100,7 @@
                 language = "en";
             }
             else if (!(language.equals("en") || language.equals("de"))) {
-                throw KustvaktResponseHandler.throwit(
+                throw responseHandler.throwit(
                         new KustvaktException(StatusCodes.UNSUPPORTED_VALUE,
                                 "Unsupported value:", language));
             }
@@ -101,16 +111,16 @@
             codes = JsonUtils.convert(node.get("codes"), List.class);
         }
         catch (IOException | NullPointerException e) {
-            throw KustvaktResponseHandler.throwit(new KustvaktException(
+            throw responseHandler.throwit(new KustvaktException(
                     StatusCodes.INVALID_ARGUMENT, "Bad argument:", json));
         }
         if (codes == null) {
-            throw KustvaktResponseHandler.throwit(
+            throw responseHandler.throwit(
                     new KustvaktException(StatusCodes.MISSING_ATTRIBUTE,
                             "Missing attribute:", "codes"));
         }
         else if (codes.isEmpty()) {
-            throw KustvaktResponseHandler
+            throw responseHandler
                     .throwit(new KustvaktException(StatusCodes.NO_RESULT_FOUND,
                             "No result found.", "codes:[]"));
         }
@@ -121,7 +131,7 @@
                     .toJSON(annotationService.getFoundryDtos(codes, language));
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
         return Response.ok(result).build();
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
index b475c9c..f772224 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/AuthenticationController.java
@@ -1,5 +1,29 @@
 package de.ids_mannheim.korap.web.controller;
 
+import java.util.HashMap;
+import java.util.Iterator; // 07.02.17/FB
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
 import com.sun.jersey.spi.container.ContainerRequest;
 import com.sun.jersey.spi.container.ResourceFilters;
 
@@ -10,62 +34,42 @@
 import de.ids_mannheim.korap.filter.AuthFilter;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
-import de.ids_mannheim.korap.server.KustvaktServer;
-import de.ids_mannheim.korap.user.*;
+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.KustvaktLogger;
 import de.ids_mannheim.korap.utils.ServiceInfo;
-import de.ids_mannheim.korap.web.filter.*;
+import de.ids_mannheim.korap.web.filter.BlockingFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
-import org.eclipse.jetty.util.log.Log;
-import org.slf4j.Logger;
-
-import javax.servlet.http.HttpServletRequest; // FB
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
-import javax.xml.ws.WebServiceContext; // FB
-import javax.xml.ws.handler.MessageContext; // FB
-import javax.annotation.Resource; // FB
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.ArrayList;
-import java.util.Iterator; // 07.02.17/FB
-
 //import com.sun.xml.internal.messaging.saaj.util.Base64;
 
 /**
  * @author hanl
  * @date 24/01/2014
  */
+@Controller
 @Path("/auth")
 @ResourceFilters({ PiwikFilter.class })
 @Produces(MediaType.TEXT_HTML + ";charset=utf-8")
 public class AuthenticationController {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     private static Boolean DEBUG_LOG = true;
 
     //todo: bootstrap function to transmit certain default configuration settings and examples (example user queries,
     // default usersettings, etc.)
     private static Logger jlog = KustvaktLogger.getLogger(AuthenticationController.class);
 
+    @Autowired
     private AuthenticationManagerIface controller;
 
-
     //    private SendMail mail;
 
-    public AuthenticationController () {
-        this.controller =
-                BeansFactory.getKustvaktContext().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
@@ -117,7 +121,7 @@
         List<String> auth =
                 headers.getRequestHeader(ContainerRequest.AUTHORIZATION);
         if (auth == null || auth.isEmpty()) {
-            throw KustvaktResponseHandler
+            throw kustvaktResponseHandler
                     .throwit(new KustvaktException(StatusCodes.MISSING_ARGUMENT,
                             "Authorization header is missing.",
                             "Authorization header"));
@@ -163,12 +167,12 @@
 
         // "Invalid syntax for username and password"
         if (values == null)
-            throw KustvaktResponseHandler.throwit(StatusCodes.ACCESS_DENIED);
+            throw kustvaktResponseHandler.throwit(StatusCodes.ACCESS_DENIED);
 
         if (values[0].equalsIgnoreCase("null")
                 | values[1].equalsIgnoreCase("null"))
             // is actual an invalid request
-            throw KustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
+            throw kustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
 
         Map<String, Object> attr = new HashMap<>();
         if (scopes != null && !scopes.isEmpty())
@@ -193,7 +197,7 @@
                     Attributes.API_AUTHENTICATION);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok(context.toJson()).build();
@@ -238,14 +242,14 @@
 
         // "Invalid syntax for username and password"
         if (values == null)
-            throw KustvaktResponseHandler.throwit(StatusCodes.BAD_CREDENTIALS);
+            throw kustvaktResponseHandler.throwit(StatusCodes.BAD_CREDENTIALS);
 
         // Implementation Hanl mit '|'. 16.02.17/FB
         //if (values[0].equalsIgnoreCase("null")
         //        | values[1].equalsIgnoreCase("null"))
         if (values[0].equalsIgnoreCase("null")
                 || values[1].equalsIgnoreCase("null"))
-            throw KustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
+            throw kustvaktResponseHandler.throwit(StatusCodes.REQUEST_INVALID);
 
         Map<String, Object> attr = new HashMap<>();
         attr.put(Attributes.HOST, host);
@@ -260,7 +264,7 @@
             jlog.debug(contextJson);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().entity(contextJson).build();
     }
@@ -293,7 +297,7 @@
             context = controller.createTokenContext(user, attr, null);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().entity(context.toJson()).build();
     }
@@ -312,7 +316,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Logout Exception: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/DocumentController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/DocumentController.java
index c23db52..f60a91e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/DocumentController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/DocumentController.java
@@ -12,6 +12,8 @@
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
 
 import javax.ws.rs.*;
 import javax.ws.rs.core.MediaType;
@@ -24,23 +26,21 @@
  * @author hanl
  * @date 19/11/2014
  */
+@Deprecated
+@Controller
 @Path(KustvaktServer.API_VERSION + "/doc")
 @ResourceFilters({ AdminFilter.class })
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 public class DocumentController {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     private static Logger jlog =
             LoggerFactory.getLogger(DocumentController.class);
     private DocumentDao documentDao;
 
 
-    // todo: error handling
-    public DocumentController () {
-        this.documentDao = new DocumentDao(
-                BeansFactory.getKustvaktContext().getPersistenceClient());
-    }
-
-
     @POST
     @Path("{doc}")
     public Response store (@PathParam("doc") String docid,
@@ -51,7 +51,7 @@
             this.documentDao.storeResource(doc, null);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -72,7 +72,7 @@
             return Response.ok(JsonUtils.toJSON(docs)).build();
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
     }
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
index 7192e3e..c21c406 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthController.java
@@ -33,6 +33,7 @@
 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 org.springframework.beans.factory.annotation.Autowired;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -54,7 +55,11 @@
 @Path(KustvaktServer.API_VERSION + "/oauth2")
 public class OAuthController {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     private OAuth2Handler handler;
+    @Autowired
     private AuthenticationManagerIface controller;
     private EncryptionIface crypto;
     private KustvaktConfiguration config;
@@ -85,7 +90,7 @@
                     this.controller.getUser(ctx.getUsername()));
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -101,7 +106,7 @@
                 crypto.createToken());
         info.setUrl(host);
         if (rurl == null)
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "Missing parameter!", "redirect_url");
         info.setRedirect_uri(rurl);
         TokenContext ctx = (TokenContext) context.getUserPrincipal();
@@ -110,7 +115,7 @@
             this.handler.getPersistenceHandler().registerClient(info, user);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(info.toJSON()).build();
     }
@@ -131,7 +136,7 @@
             scopes = StringUtils.toString(base_scope);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         // json format with scope callback parameter
         // todo: add other scopes as well!
@@ -157,7 +162,7 @@
             return Response.ok(JsonUtils.toJSON(auths)).build();
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
     }
 
@@ -205,7 +210,7 @@
 //                user.addUserData(data);
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwit(e);
+                throw kustvaktResponseHandler.throwit(e);
             }
 
             // register response according to response_type
@@ -281,7 +286,7 @@
                     this.handler.authorize(codeInfo, user);
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw kustvaktResponseHandler.throwit(e);
                 }
                 builder.setParam(OAuth.OAUTH_RESPONSE_TYPE,
                         ResponseType.CODE.toString());
@@ -316,7 +321,7 @@
                                 new_context.getToken());
                     }
                     catch (KustvaktException e) {
-                        throw KustvaktResponseHandler.throwit(e);
+                        throw kustvaktResponseHandler.throwit(e);
                     }
                 }
                 response = builder.buildBodyMessage();
@@ -501,7 +506,7 @@
                     }
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw kustvaktResponseHandler.throwit(e);
                 }
                 // todo: errors for invalid scopes or different scopes then during authorization request?
                 //todo ??
@@ -530,7 +535,7 @@
                             oauthRequest.getPassword(), attr);
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw kustvaktResponseHandler.throwit(e);
                 }
 
                 try {
@@ -552,7 +557,7 @@
 
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw kustvaktResponseHandler.throwit(e);
                 }
             }
 
@@ -575,7 +580,7 @@
                     builder.setParam(c.getTokenType(), c.getToken());
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw kustvaktResponseHandler.throwit(e);
                 }
             }
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index 363477a..5e37692 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.web.controller;// package
                                              // de.ids_mannheim.korap.ext.web;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -31,6 +32,8 @@
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.jersey.core.util.MultivaluedMapImpl;
 import com.sun.jersey.spi.container.ResourceFilters;
@@ -66,7 +69,9 @@
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
 /**
- * EM: To Do: restructure codes regarding service and controller layers
+ * EM: To Do: restructure codes regarding service and controller
+ * layers
+ * 
  * @author hanl, margaretha
  * @date 29/01/2014
  * @lastUpdate 06/2017
@@ -82,6 +87,8 @@
             LoggerFactory.getLogger(SearchController.class);
 
     @Autowired
+    KustvaktResponseHandler responseHandler;
+    @Autowired
     private SearchKrill searchKrill;
     private ResourceHandler resourceHandler;
     @Autowired
@@ -104,106 +111,6 @@
         this.processor.defaultRewriteConstraints();
     }
 
-    /**
-     * retrieve resources dependent by type. determines based on the
-     * user's
-     * permission or resource owner if the user can access the
-     * resource.
-     * 
-     * @param locale
-     * @param context
-     * @param type
-     * @return valid resources in json format
-     */
-    @Deprecated
-    @GET
-    @Path("{type}")
-    public Response getResources (@Context Locale locale,
-            @Context SecurityContext context, @PathParam("type") String type) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        Set<KustvaktResource> resources = new HashSet<>();
-        type = StringUtils.normalize(type);
-
-        try {
-            Class cl_type = ResourceFactory.getResourceClass(type);
-            if (cl_type == null) throw KustvaktResponseHandler.throwit(
-                    StatusCodes.MISSING_ARGUMENT,
-                    "Resource type not available!", "");
-
-            User user = controller.getUser(ctx.getUsername());
-
-            resources = ResourceFinder.search(user,
-                    ResourceFactory.getResourceClass(type));
-        }
-        catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
-        }
-
-        Set values = new HashSet();
-        for (KustvaktResource resource : resources)
-            values.add(resource.toMap());
-        return Response.ok(JsonUtils.toJSON(values)).build();
-    }
-
-
-    @Deprecated
-    @GET
-    @Path("{type}/{id}/{child}")
-    public Response getResource (@Context SecurityContext context,
-            @Context Locale locale, @PathParam("type") String type,
-            @PathParam("id") String id, @PathParam("child") String child) {
-        return getResource(context, locale, type,
-                StringUtils.joinResources(id, child));
-    }
-
-
-    /**
-     * @param context
-     * @param locale
-     * @param id
-     * @param type
-     * @return
-     */
-    @Deprecated
-    @GET
-    @Path("{type}/{id}")
-    public Response getResource (@Context SecurityContext context,
-            @Context Locale locale, @PathParam("type") String type,
-            @PathParam("id") String id) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        type = StringUtils.normalize(type);
-        KustvaktResource resource;
-        try {
-            Class cl_type = ResourceFactory.getResourceClass(type);
-
-            if (ctx.isDemo()) {
-                Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
-                resource = (KustvaktResource) set.toArray()[0];
-            }
-            else {
-                User user = controller.getUser(ctx.getUsername());
-                if (StringUtils.isInteger(id))
-                    resource = resourceHandler.findbyIntId(Integer.valueOf(id),
-                            user);
-                else
-                    resource = resourceHandler.findbyStrId(id, user, cl_type);
-            }
-        }
-        catch (KustvaktException e) {
-            // if (e.getStatusCode() != StatusCodes.ACCESS_DENIED)
-            throw KustvaktResponseHandler.throwit(e);
-
-            // try {
-            // Set set = ResourceFinder.searchPublicFiltered(cl_type, id);
-            // resource = (KustvaktResource) set.toArray()[0];
-            // }
-            // catch (KustvaktException e1) {
-            // throw KustvaktResponseHandler.throwit(e);
-            // }
-        }
-        return Response.ok(JsonUtils.toJSON(resource.toMap())).build();
-    }
-
     // @GET
     // @Path("colloc")
     // public Response getCollocationsAll(@Context SecurityContext ctx,
@@ -313,7 +220,7 @@
             result = graphDBhandler.getResponse("distCollo", "q", query);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
         return Response.ok(result).build();
     }
@@ -418,7 +325,12 @@
         ss.setMeta(meta.raw());
 
         KoralCollectionQueryBuilder cquery = new KoralCollectionQueryBuilder();
-        cquery.setBaseQuery(ss.toJSON());
+        try {
+            cquery.setBaseQuery(ss.toJSON());
+        }
+        catch (KustvaktException e1) {
+            throw responseHandler.throwit(e1);
+        }
 
         String query = "";
         // EM: is this necessary at all?
@@ -431,7 +343,12 @@
             else if (resource instanceof Corpus) {
                 cquery.and().with(Attributes.CORPUS_SIGLE, "=",
                         resource.getPersistentID());
-                query = cquery.toJSON();
+                try {
+                    query = cquery.toJSON();
+                }
+                catch (KustvaktException e) {
+                   throw responseHandler.throwit(e);
+                }
             }
         }
 
@@ -487,7 +404,7 @@
             // jsonld = this.processor.processQuery(jsonld, user);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
         jlog.info("Serialized search: {}", jsonld);
 
@@ -522,7 +439,7 @@
         catch (KustvaktException e) {
             jlog.error("Failed retrieving user in the search service: {}",
                     e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         QuerySerializer serializer = new QuerySerializer();
@@ -539,7 +456,7 @@
             jlog.info("the serialized query {}", query);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         String result = doSearch(eng, query, pageLength, meta);
@@ -584,7 +501,7 @@
             MetaQueryBuilder meta, boolean raw) {
 
         if (raw) {
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw responseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "raw not supported!", null);
         }
 
@@ -598,7 +515,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Failed searching in Neo4J: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
     }
@@ -636,7 +553,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Failed retrieving resource: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         if (resource instanceof VirtualCollection) {
@@ -648,10 +565,15 @@
         else if (resource instanceof Corpus) {
             builder.and().with(Attributes.CORPUS_SIGLE, "=",
                     resource.getPersistentID());
-            return builder.toJSON();
+            try {
+                return builder.toJSON();
+            }
+            catch (KustvaktException e) {
+                throw responseHandler.throwit(e);
+            }
         }
         else {
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw responseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "Type parameter not supported", type);
         }
     }
@@ -675,7 +597,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         VirtualCollection tmp = resourceHandler.getCache(cache.getId(),
@@ -684,12 +606,12 @@
             String query;
             try {
                 query = this.processor.processQuery(cache.getData(), user);
+                String stats = searchKrill.getStatistics(query);
+                cache.setStats(JsonUtils.convertToClass(stats, Map.class));
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwit(e);
+                throw responseHandler.throwit(e);
             }
-            String stats = searchKrill.getStatistics(query);
-            cache.setStats(JsonUtils.readSimple(stats, Map.class));
             resourceHandler.cache(cache);
         }
         else
@@ -762,7 +684,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -793,24 +715,29 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
         if (VirtualCollection.class.equals(ctype)) {
             VirtualCollection cachetmp, collection;
 
-            JsonNode base;
+            JsonNode base = null;
             if (reference != null && !reference.equals("null")) {
                 try {
                     base = resourceHandler.findbyStrId(reference, user,
                             VirtualCollection.class).getData();
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw responseHandler.throwit(e);
                 }
 
             }
             else if (query != null)
-                base = JsonUtils.readTree(query);
+                try {
+                    base = JsonUtils.readTree(query);
+                }
+                catch (KustvaktException e) {
+                  responseHandler.throwit(e);
+                }
             else
                 // todo: throw exception response for no resource to save!
                 return null;
@@ -828,7 +755,8 @@
                 // if not cached, fill with stats values
                 if (tmp == null) {
                     String stats = searchKrill.getStatistics(cquery.toJSON());
-                    cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
+                    cachetmp.setStats(
+                            JsonUtils.convertToClass(stats, Map.class));
                 }
 
                 if (!cache) {
@@ -844,7 +772,7 @@
 
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwit(e);
+                throw responseHandler.throwit(e);
             }
         }
         return Response.ok(JsonUtils.toJSON(vals)).build();
@@ -889,7 +817,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         if (VirtualCollection.class.equals(ctype)) {
@@ -904,7 +832,7 @@
 
                 }
                 catch (KustvaktException e) {
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw responseHandler.throwit(e);
                 }
             }
             if (query != null && !query.isEmpty()) cquery.with(query);
@@ -918,7 +846,7 @@
             // if not cached, fill with stats values
             if (tmp == null) {
                 String stats = searchKrill.getStatistics(cquery.toJSON());
-                cachetmp.setStats(JsonUtils.readSimple(stats, Map.class));
+                cachetmp.setStats(JsonUtils.convertToClass(stats, Map.class));
                 if (query != null && !query.isEmpty())
                     cachetmp.setFields(cquery.toJSON());
             }
@@ -932,7 +860,7 @@
                 }
                 catch (KustvaktException e) {
                     jlog.error("Exception encountered: {}", e.string());
-                    throw KustvaktResponseHandler.throwit(e);
+                    throw responseHandler.throwit(e);
                 }
             }
             else {
@@ -941,7 +869,7 @@
             }
         }
         else {
-            throw KustvaktResponseHandler.throwit(
+            throw responseHandler.throwit(
                     new KustvaktException(StatusCodes.UNSUPPORTED_RESOURCE,
                             "Unsupported operation for the given resource type.",
                             type));
@@ -977,7 +905,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         return Response.ok().build();
@@ -1015,7 +943,7 @@
         catch (KustvaktException e) {
             jlog.error("Failed getting user in the matchInfo service: {}",
                     e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         CorpusAccess corpusAccess = user.getCorpusAccess();
@@ -1058,7 +986,7 @@
         }
         catch (Exception e) {
             jlog.error("Exception in the MatchInfo service encountered!", e);
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw responseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     e.getMessage(), "");
         }
         jlog.debug("MatchInfo results: " + results);
@@ -1114,7 +1042,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw responseHandler.throwit(e);
         }
 
         return Response.ok().build();
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
index d9d0cd2..cfe46ce 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
@@ -31,7 +31,7 @@
  * @author hanl
  * @author margaretha
  *
- * @date 27/09/2017
+ * @date 08/11/2017
  * 
  */
 @Controller
@@ -43,7 +43,8 @@
 
     private static Logger jlog =
             LoggerFactory.getLogger(StatisticController.class);
-
+    @Autowired
+    private KustvaktResponseHandler kustvaktResponseHandler;
     @Autowired
     private SearchKrill searchKrill;
 
@@ -67,7 +68,7 @@
             @QueryParam("collectionQuery") String collectionQuery) {
 
         if (collectionQuery == null || collectionQuery.isEmpty()) {
-            throw KustvaktResponseHandler
+            throw kustvaktResponseHandler
                     .throwit(new KustvaktException(StatusCodes.MISSING_ARGUMENT,
                             "Parameter collectionQuery is missing.",
                             "collectionQuery"));
@@ -76,11 +77,17 @@
 
         KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
         builder.with(collectionQuery);
-        String json = builder.toJSON();
+        String json = null;
+        try {
+            json = builder.toJSON();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
 
         String stats = searchKrill.getStatistics(json);
         if (stats.contains("-1"))
-            throw KustvaktResponseHandler.throwit(StatusCodes.NO_RESULT_FOUND);
+            throw kustvaktResponseHandler.throwit(StatusCodes.NO_RESULT_FOUND);
         jlog.debug("Stats: " + stats);
         return Response.ok(stats).build();
     }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
index 1399c5c..ff8ccf9 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
@@ -1,19 +1,55 @@
 package de.ids_mannheim.korap.web.controller;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
 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.Attributes;
-import de.ids_mannheim.korap.config.BeansFactory;
 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.filter.AuthFilter;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
-import de.ids_mannheim.korap.server.KustvaktServer;
-import de.ids_mannheim.korap.user.*;
+import de.ids_mannheim.korap.user.KorAPUser;
+import de.ids_mannheim.korap.user.TokenContext;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.UserDetails;
+import de.ids_mannheim.korap.user.UserQuery;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.StringUtils;
 import de.ids_mannheim.korap.utils.TimeUtils;
@@ -21,34 +57,27 @@
 import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
-import java.util.*;
 
 /**
  * @author hanl, margaretha
- * @lastUpdate 04/2017
+ * @lastUpdate 11/2017
  */
+@Controller
 @Path("/user")
 @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
 @ResourceFilters({ PiwikFilter.class })
 public class UserController {
 
+    @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    
     private static Logger jlog = LoggerFactory.getLogger(UserController.class);
+    @Autowired
     private AuthenticationManagerIface controller;
 
     private @Context UriInfo info;
 
 
-    public UserController () {
-        this.controller = BeansFactory.getKustvaktContext()
-                .getAuthenticationManager();
-    }
-
-
     // fixme: json contains password in clear text. Encrypt request?
     // EM: no encryption is needed for communications over https. 
     // It should not be necessary in IDS internal network. 
@@ -72,7 +101,7 @@
             user = controller.createUserAccount(values, true);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         URIParam uri = user.getField(URIParam.class);
         if (uri.hasValues()) {
@@ -92,7 +121,7 @@
         else {
             jlog.error("Failed creating confirmation and expiry tokens.");
             // EM: why illegal argument when uri fragment/param is self-generated 
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "failed to validate uri parameter", "confirmation fragment");
         }
 
@@ -119,7 +148,7 @@
             //            controller.updateAccount(user);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -131,10 +160,10 @@
     public Response confirmRegistration (@QueryParam("uri") String uritoken,
             @Context Locale locale, @QueryParam("user") String username) {
         if (uritoken == null || uritoken.isEmpty())
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "parameter missing", "uri parameter");
         if (username == null || username.isEmpty())
-            throw KustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
+            throw kustvaktResponseHandler.throwit(StatusCodes.ILLEGAL_ARGUMENT,
                     "parameter missing", "Username");
 
         try {
@@ -142,7 +171,7 @@
         }
         catch (KustvaktException e) {
             e.printStackTrace();
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -155,7 +184,13 @@
     @Consumes({ MediaType.APPLICATION_JSON,
             MediaType.APPLICATION_FORM_URLENCODED })
     public Response requestPasswordReset (@Context Locale locale, String json) {
-        JsonNode node = JsonUtils.readTree(json);
+        JsonNode node;
+        try {
+            node = JsonUtils.readTree(json);
+        }
+        catch (KustvaktException e1) {
+            throw kustvaktResponseHandler.throwit(e1);
+        }
         StringBuilder builder = new StringBuilder();
         String username, email;
         username = node.path(Attributes.USERNAME).asText();
@@ -183,7 +218,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Eoxception encountered!", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
 
         ObjectNode obj = JsonUtils.createObjectNode();
@@ -233,7 +268,7 @@
             m = Scopes.mapScopes(scopes, data);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler
+            throw kustvaktResponseHandler
                     .throwAuthenticationException(ctx.getUsername());
         }
         return Response.ok(m.toEntity()).build();
@@ -256,7 +291,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(result).build();
     }
@@ -293,7 +328,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
 
         return Response.ok().build();
@@ -319,7 +354,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered: {}", e.string());
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(result).build();
     }
@@ -351,7 +386,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -407,7 +442,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(JsonUtils.toJSON(add)).build();
     }
@@ -425,7 +460,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
@@ -449,7 +484,7 @@
         }
         catch (KustvaktException e) {
             jlog.error("Exception encountered!", e);
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(queryStr).build();
     }
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
similarity index 95%
rename from core/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
rename to full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
index 26cde36..ee8ee15 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/PiwikFilter.java
@@ -18,6 +18,8 @@
 import net.minidev.json.JSONArray;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
 
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriBuilder;
@@ -29,6 +31,7 @@
  * @author hanl
  * @date 13/05/2014
  */
+@Component
 @Provider
 public class PiwikFilter implements ContainerRequestFilter, ResourceFilter {
 
@@ -38,12 +41,13 @@
     private static Logger jlog = LoggerFactory.getLogger(PiwikFilter.class);
     public static boolean ENABLED = false;
     private Map<String, String> customVars;
+    @Autowired
     private AuthenticationManagerIface controller;
 
 
     public PiwikFilter () {
-        controller = BeansFactory.getKustvaktContext()
-                .getAuthenticationManager();
+//        controller = BeansFactory.getKustvaktContext()
+//                .getAuthenticationManager();
         ClientConfig config = new DefaultClientConfig();
         Client client = Client.create(config);
         if (jlog.isDebugEnabled())
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index 869059b..cae9cdc 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -101,8 +101,8 @@
 		<!-- <property name="validateOnMigrate" value="false" /> -->
 		<!-- <property name="cleanOnValidationError" value="true" /> -->
 		<property name="locations" value="${jdbc.schemaPath}" />
-		<property name="dataSource" ref="dataSource" />
-		<!-- <property name="dataSource" ref="sqliteDataSource" /> -->
+		<!-- <property name="dataSource" ref="dataSource" /> -->
+		<property name="dataSource" ref="sqliteDataSource" />
 	</bean>
 	
 	
@@ -114,7 +114,9 @@
 
 	<bean id="entityManagerFactory"
 		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
-		<property name="dataSource" ref="dataSource" />
+		<!-- <property name="dataSource" ref="dataSource" /> -->
+		<property name="dataSource" ref="sqliteDataSource" />
+		
 		<property name="packagesToScan" value="de.ids_mannheim.korap.entity" />
 		<property name="jpaVendorAdapter">
 			<bean id="jpaVendorAdapter"
@@ -139,6 +141,7 @@
 
 	<tx:annotation-driven proxy-target-class="true"
 		transaction-manager="transactionManager" />
+		
 	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
 		<property name="entityManagerFactory" ref="entityManagerFactory" />
 	</bean>
@@ -161,6 +164,11 @@
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
 
+	<bean id="kustvakt_response"
+          class="de.ids_mannheim.korap.web.utils.KustvaktResponseHandler">
+          <constructor-arg index="0" name="iface" ref="kustvakt_auditing"/>
+    </bean>
+    
 	<bean id="kustvakt_userdb" class="de.ids_mannheim.korap.handlers.EntityDao">
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
@@ -283,7 +291,8 @@
 	<!-- similarly, don't forget the PlatformTransactionManager -->
 	<bean id="txManager"
 		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
-		<property name="dataSource" ref="dataSource" />
+		<!-- <property name="dataSource" ref="dataSource" /> -->
+		<property name="dataSource" ref="sqliteDataSource" />
 	</bean>
 	
 </beans>
\ No newline at end of file
diff --git a/full/src/test/java/de/ids_mannheim/korap/misc/CollectionQueryBuilderTest.java b/full/src/test/java/de/ids_mannheim/korap/misc/CollectionQueryBuilderTest.java
index 0656c02..3142330 100644
--- a/full/src/test/java/de/ids_mannheim/korap/misc/CollectionQueryBuilderTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/misc/CollectionQueryBuilderTest.java
@@ -1,5 +1,7 @@
 package de.ids_mannheim.korap.misc;
 import com.fasterxml.jackson.databind.JsonNode;
+
+import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.resources.VirtualCollection;
@@ -19,7 +21,7 @@
 public class CollectionQueryBuilderTest {
 
     @Test
-    public void testsimpleAdd () {
+    public void testsimpleAdd () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("corpusSigle=WPD");
 
@@ -32,7 +34,7 @@
 
 
     @Test
-    public void testSimpleConjunction () {
+    public void testSimpleConjunction () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("corpusSigle=WPD & textClass=freizeit");
         JsonNode node = JsonUtils.readTree(b.toJSON());
@@ -49,7 +51,7 @@
 
 
     @Test
-    public void testSimpleDisjunction () {
+    public void testSimpleDisjunction () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("corpusSigle=WPD | textClass=freizeit");
         JsonNode node = JsonUtils.readTree(b.toJSON());
@@ -64,7 +66,7 @@
 
 
     @Test
-    public void testComplexSubQuery () {
+    public void testComplexSubQuery () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("(corpusSigle=WPD) | (textClass=freizeit & corpusSigle=BRZ13)");
         JsonNode node = JsonUtils.readTree(b.toJSON());
@@ -80,7 +82,7 @@
 
 
     @Test
-    public void testAddResourceQueryAfter () {
+    public void testAddResourceQueryAfter () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("(textClass=politik & title=\"random title\") | textClass=wissenschaft");
 
@@ -109,7 +111,7 @@
 
 
     @Test
-    public void testAddComplexResourceQueryAfter () {
+    public void testAddComplexResourceQueryAfter () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("(title=\"random title\") | (textClass=wissenschaft)");
 
@@ -135,7 +137,7 @@
 
 
     @Test
-    public void testBuildQuery () {
+    public void testBuildQuery () throws KustvaktException {
         String coll = "corpusSigle=WPD";
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
@@ -171,7 +173,7 @@
 
 
     @Test
-    public void testBaseQueryBuild () {
+    public void testBaseQueryBuild () throws KustvaktException {
         KoralCollectionQueryBuilder b = new KoralCollectionQueryBuilder();
         b.with("(corpusSigle=ADF) | (textClass=freizeit & corpusSigle=WPD)");
 
@@ -192,7 +194,7 @@
 
 
     @Test
-    public void testNodeMergeWithBase () {
+    public void testNodeMergeWithBase () throws KustvaktException {
         String coll = "corpusSigle=WPD";
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
@@ -214,7 +216,7 @@
 
 
     @Test
-    public void testNodeMergeWithoutBase () {
+    public void testNodeMergeWithoutBase () throws KustvaktException {
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
         check.setQuery(query, "poliqarp");
@@ -235,7 +237,7 @@
 
 
     @Test
-    public void testNodeMergeWithoutBaseWrongOperator () {
+    public void testNodeMergeWithoutBaseWrongOperator () throws KustvaktException {
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
         check.setQuery(query, "poliqarp");
@@ -263,7 +265,7 @@
 
 
     @Test
-    public void testAddOROperator () {
+    public void testAddOROperator () throws KustvaktException {
         String coll = "corpusSigle=WPD";
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
@@ -282,7 +284,7 @@
 
 
     @Test
-    public void testAddANDOperator () {
+    public void testAddANDOperator () throws KustvaktException {
         String coll = "corpusSigle=WPD";
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
@@ -301,7 +303,7 @@
 
 
     @Test
-    public void testAddDefaultOperator () {
+    public void testAddDefaultOperator () throws KustvaktException {
         String coll = "corpusSigle=WPD";
         String query = "[base=Haus]";
         QuerySerializer check = new QuerySerializer();
@@ -320,7 +322,7 @@
 
 
     @Test
-    public void testCollectionMergeWithFromResource () {
+    public void testCollectionMergeWithFromResource () throws KustvaktException {
         KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
         builder.with("textClass=politik & corpusSigle=WPD");
         KustvaktResource resource = new VirtualCollection();
@@ -339,7 +341,7 @@
 
 
     @Test
-    public void testCollectionMergeWithFromResourceNoCollection () {
+    public void testCollectionMergeWithFromResourceNoCollection () throws KustvaktException {
         KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
         builder.with("textClass=politik & corpusSigle=WPD");
         KustvaktResource resource = new VirtualCollection();
@@ -358,7 +360,7 @@
 
 
     @Test
-    public void testCollectionMergeFromQuerySerializer () {
+    public void testCollectionMergeFromQuerySerializer () throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[base=Haus]", "poliqarp");
         KoralCollectionQueryBuilder total = new KoralCollectionQueryBuilder();
@@ -384,7 +386,7 @@
 
 
     @Test
-    public void testBaseCollectionNull () {
+    public void testBaseCollectionNull () throws KustvaktException {
         // base is missing collection segment
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[base=Haus]", "poliqarp");
@@ -412,7 +414,7 @@
 
 
     @Test
-    public void testMergeCollectionNull () {
+    public void testMergeCollectionNull () throws KustvaktException {
         // merge json is missing collection segment
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[base=Haus]", "poliqarp");
diff --git a/full/src/test/java/de/ids_mannheim/korap/misc/LocalQueryTest.java b/full/src/test/java/de/ids_mannheim/korap/misc/LocalQueryTest.java
index e5020f9..ff8df15 100644
--- a/full/src/test/java/de/ids_mannheim/korap/misc/LocalQueryTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/misc/LocalQueryTest.java
@@ -37,7 +37,7 @@
 
 
     @Test
-    public void testQuery () {
+    public void testQuery () throws KustvaktException {
         SearchKrill krill = new SearchKrill(index);
         KoralCollectionQueryBuilder coll = new KoralCollectionQueryBuilder();
         coll.with(qstring);
diff --git a/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
index 43ff936..439462a 100644
--- a/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/user/UserdataTest.java
@@ -131,7 +131,7 @@
 
 
     @Test
-    public void testDataFactoryAdd () {
+    public void testDataFactoryAdd () throws KustvaktException {
         String data = "{}";
         Object node = JsonUtils.readTree(data);
 
@@ -153,7 +153,7 @@
 
 
     @Test
-    public void testDataFactoryGet () {
+    public void testDataFactoryGet () throws KustvaktException {
         String data = "{}";
         Object node = JsonUtils.readTree(data);
 
@@ -203,7 +203,7 @@
 
 
     @Test
-    public void testDataFactoryEmbeddedProperty () {
+    public void testDataFactoryEmbeddedProperty () throws KustvaktException {
         String data = "{}";
         JsonNode node = JsonUtils.readTree(data);
 
@@ -247,7 +247,7 @@
 
 
     @Test
-    public void testDataFactoryMerge () {
+    public void testDataFactoryMerge () throws KustvaktException {
         String data = "{}";
         Object node = JsonUtils.readTree(data);
 
@@ -277,7 +277,7 @@
 
     @Test
     @Ignore
-    public void testDataFactoryRemove () {
+    public void testDataFactoryRemove () throws KustvaktException {
         String data = "{}";
         Object node = JsonUtils.readTree(data);
 
@@ -382,7 +382,7 @@
 
 
     @Test
-    public void testDataFactoryKeys () {
+    public void testDataFactoryKeys () throws KustvaktException {
         String data = "{}";
         Object node = JsonUtils.readTree(data);
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
index 4e06330..f8e664a 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/SearchKrillTest.java
@@ -65,7 +65,7 @@
 	}
 
     @Test
-    public void testSearch () {
+    public void testSearch () throws KustvaktException {
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[orth=der]", "poliqarp");
 
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
index 77eeb10..58d3ad6 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/AuthServiceTest.java
@@ -53,7 +53,7 @@
     }
 
     @Test
-    public void testSessionToken() {
+    public void testSessionToken() throws KustvaktException {
         String auth = BasicHttpAuth.encode(credentials[0], credentials[1]);
         ClientResponse response = resource().path("auth")
                 .path("sessionToken").header(Attributes.AUTHORIZATION, auth)
@@ -89,7 +89,7 @@
     }
 
     @Test
-    public void testSessionTokenExpire() {
+    public void testSessionTokenExpire() throws KustvaktException {
         String auth = BasicHttpAuth.encode(credentials[0], credentials[1]);
         ClientResponse response = resource().path("auth")
                 .path("sessionToken").header(Attributes.AUTHORIZATION, auth)
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
index 374f9fc..3b575d4 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/MatchInfoServiceTest.java
@@ -20,7 +20,7 @@
 public class MatchInfoServiceTest extends FastJerseyTest {
 
     @Test
-    public void testGetMatchInfoPublicCorpus () {
+    public void testGetMatchInfoPublicCorpus () throws KustvaktException {
 
         ClientResponse response = resource()
                 .path("corpus").path("GOE").path("AGA").path("01784")
@@ -46,7 +46,7 @@
     }
     
     @Test
-    public void testGetMatchInfoNotAllowed () {
+    public void testGetMatchInfoNotAllowed () throws KustvaktException {
 
         ClientResponse response = resource()
                 .path("corpus").path("GOE").path("AGI").path("04846")
@@ -67,7 +67,7 @@
     }
 
     @Test
-    public void testGetMatchInfoWithAuthentication () {
+    public void testGetMatchInfoWithAuthentication () throws KustvaktException {
         ClientResponse response = resource()
                 .path("corpus").path("GOE").path("AGI").path("04846")
                 .path("p36875-36876").path("matchInfo")
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
index f4d0144..807ee1f 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/OAuth2EndpointTest.java
@@ -8,7 +8,9 @@
 import org.junit.Test;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.ClientHandlerException;
 import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.UniformInterfaceException;
 
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.TestHelper;
@@ -32,7 +34,7 @@
 
 
     @Test
-    public void testAuthorizeClient () {
+    public void testAuthorizeClient () throws ClientHandlerException, UniformInterfaceException, KustvaktException {
         String auth = BasicHttpAuth.encode(helper().getUser().getUsername(),
                 (String) TestHelper.getUserCredentials().get(Attributes.PASSWORD));
         ClientResponse response = resource().path(getAPIVersion()).path("oauth2")
@@ -53,7 +55,7 @@
 
     @Test
     @Ignore
-    public void testRevokeClient () {
+    public void testRevokeClient () throws ClientHandlerException, UniformInterfaceException, KustvaktException {
         ClientResponse response = resource().path(getAPIVersion()).path("oauth2")
                 .path("register")
                 .queryParam("redirect_url", "korap.ids-mannheim.de/redirect")
@@ -68,7 +70,7 @@
 
     @Test
     @Ignore
-    public void authenticate () {
+    public void authenticate () throws KustvaktException {
         Map<String, Object> cred = TestHelper.getUserCredentials();
         String enc = BasicHttpAuth.encode((String) cred.get(Attributes.USERNAME), (String) cred.get(Attributes.PASSWORD));
         ClientResponse response = resource().path(getAPIVersion()).path("oauth2")
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
index eed1024..88fd598 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/QuerySerializationServiceTest.java
@@ -37,7 +37,7 @@
 
 
     @Test
-    public void testQuerySerializationFilteredPublic () {
+    public void testQuerySerializationFilteredPublic () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("corpus/WPD13/query").queryParam("q", "[orth=der]")
@@ -55,7 +55,7 @@
 
 
     @Test
-    public void testQuerySerializationUnexistingResource () {
+    public void testQuerySerializationUnexistingResource () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("corpus/ZUW19/query").queryParam("q", "[orth=der]")
@@ -72,7 +72,7 @@
 
 
     @Test
-    public void testQuerySerializationWithNonPublicCorpus () {
+    public void testQuerySerializationWithNonPublicCorpus () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("corpus/BRZ10/query").queryParam("q", "[orth=der]")
@@ -89,7 +89,7 @@
 
 
     @Test
-    public void testQuerySerializationWithAuthentication () {
+    public void testQuerySerializationWithAuthentication () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("corpus/BRZ10/query").queryParam("q", "[orth=der]")
@@ -109,7 +109,7 @@
 
 
     @Test
-    public void testQuerySerializationWithNewCollection () {
+    public void testQuerySerializationWithNewCollection () throws KustvaktException {
         // Add Virtual Collection
         ClientResponse response = resource()
 
@@ -191,7 +191,7 @@
 
 
     @Test
-    public void testQuerySerializationOfVirtualCollection () {
+    public void testQuerySerializationOfVirtualCollection () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("collection/GOE-VC/query").queryParam("q", "[orth=der]")
@@ -218,7 +218,7 @@
 
 
     @Test
-    public void testMetaQuerySerialization () {
+    public void testMetaQuerySerialization () throws KustvaktException {
         ClientResponse response = resource()
 
                 .path("query").queryParam("context", "sentence")
@@ -245,7 +245,7 @@
 
 
     @Test
-    public void testMetaQuerySerializationWithOffset () {
+    public void testMetaQuerySerializationWithOffset () throws KustvaktException{
         ClientResponse response = resource()
 
                 .path("query").queryParam("context", "sentence")
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceInfoServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceInfoServiceTest.java
index 2ef3fd1..06741be 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceInfoServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceInfoServiceTest.java
@@ -31,7 +31,7 @@
     }
 
     @Test
-    public void testGetPublicVirtualCollectionInfo () {
+    public void testGetPublicVirtualCollectionInfo () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("collection").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -44,7 +44,7 @@
 
 
     @Test
-    public void testGetVirtualCollectionInfoWithAuthentication () {
+    public void testGetVirtualCollectionInfoWithAuthentication () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("collection")
                 .header(Attributes.AUTHORIZATION,
@@ -61,7 +61,7 @@
 
 
     @Test
-    public void testGetVirtualCollectionInfoById () {
+    public void testGetVirtualCollectionInfoById () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("collection").path("GOE-VC").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -77,7 +77,7 @@
     }
     
     @Test
-    public void testGetVirtualCollectionInfoByIdUnauthorized () {
+    public void testGetVirtualCollectionInfoByIdUnauthorized () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("collection").path("WPD15-VC").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
@@ -92,7 +92,7 @@
     }
     
     @Test
-    public void testGetPublicCorporaInfo () {
+    public void testGetPublicCorporaInfo () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -106,7 +106,7 @@
 
 
     @Test
-    public void testGetCorpusInfoById () {
+    public void testGetCorpusInfoById () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").path("WPD13").get(ClientResponse.class);
         
@@ -122,7 +122,7 @@
 
 
     @Test
-    public void testGetCorpusInfoById2 () {
+    public void testGetCorpusInfoById2 () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").path("GOE").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -136,7 +136,7 @@
 
 
     @Test
-    public void testGetPublicFoundriesInfo () {
+    public void testGetPublicFoundriesInfo () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("foundry").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -150,7 +150,7 @@
 
 
     @Test
-    public void testGetFoundryInfoById () {
+    public void testGetFoundryInfoById () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("foundry").path("tt").get(ClientResponse.class);
         String ent = response.getEntity(String.class);
@@ -164,7 +164,7 @@
 
 
     @Test
-    public void testGetUnexistingCorpusInfo () {
+    public void testGetUnexistingCorpusInfo () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").path("ZUW19").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
@@ -182,7 +182,7 @@
     // EM: queries for an unauthorized corpus get the same responses / treatment as 
     // asking for an unexisting corpus info. Does it need a specific exception instead?
     @Test
-    public void testGetUnauthorizedCorpusInfo () {
+    public void testGetUnauthorizedCorpusInfo () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("corpus").path("BRZ10").get(ClientResponse.class);
         assertEquals(ClientResponse.Status.BAD_REQUEST.getStatusCode(),
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
index 0ccc272..3b6850b 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/ResourceServiceTest.java
@@ -39,7 +39,7 @@
     // create a simple test collection for user kustvakt, otherwise test fails
     @Test
     @Ignore
-    public void testStats () {
+    public void testStats () throws KustvaktException{
         ClientResponse response = resource().path(getAPIVersion())
                 .path("collection")
                 .header(Attributes.AUTHORIZATION,
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
index 1362f33..f40ba1b 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchServiceTest.java
@@ -46,7 +46,7 @@
 
 
     @Test
-    public void testSearchQueryPublicCorpora () {
+    public void testSearchQueryPublicCorpora () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=der]")
                 .queryParam("ql", "poliqarp")
@@ -68,7 +68,7 @@
 
 
     @Test
-    public void testSearchQueryWithMeta () {
+    public void testSearchQueryWithMeta () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=der]")
                 .queryParam("ql", "poliqarp").queryParam("cutoff", "true")
@@ -89,7 +89,7 @@
     }
 
     @Test
-    public void testSearchQueryFreeExtern () {
+    public void testSearchQueryFreeExtern () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=die]")
                 .queryParam("ql", "poliqarp")
@@ -111,7 +111,7 @@
     }
     
     @Test
-    public void testSearchQueryFreeIntern () {
+    public void testSearchQueryFreeIntern () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=die]")
                 .queryParam("ql", "poliqarp")
@@ -134,7 +134,7 @@
     
     
     @Test
-    public void testSearchQueryExternAuthorized () {
+    public void testSearchQueryExternAuthorized () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=die]")
                 .queryParam("ql", "poliqarp")
@@ -160,7 +160,7 @@
     }
 
     @Test
-    public void testSearchQueryInternAuthorized () {
+    public void testSearchQueryInternAuthorized () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=die]")
                 .queryParam("ql", "poliqarp")
@@ -191,7 +191,7 @@
  // EM: shouldn't this case gets CorpusAccess.PUB ? 
     @Test
     @Ignore
-    public void testSearchQueryWithCollectionQueryAuthorizedWithoutIP () {
+    public void testSearchQueryWithCollectionQueryAuthorizedWithoutIP () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp")
@@ -221,7 +221,7 @@
     
     @Test
     @Ignore
-    public void testSearchQueryAuthorizedWithoutIP () {
+    public void testSearchQueryAuthorizedWithoutIP () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=die]")
                 .queryParam("ql", "poliqarp")
@@ -247,7 +247,7 @@
 
     @Test
     @Ignore
-    public void testSearchForPublicCorpusWithStringId () {
+    public void testSearchForPublicCorpusWithStringId () throws KustvaktException {
         ClientResponse response = resource()
                 .path("corpus").path("GOE").path("search")
                 .queryParam("q", "blau").queryParam("ql", "poliqarp")
@@ -273,7 +273,7 @@
 
     @Test
     @Ignore
-    public void testSearchForVirtualCollectionWithStringId () {
+    public void testSearchForVirtualCollectionWithStringId () throws KustvaktException{
         ClientResponse response = resource()
                 .path("collection").path("GOE-VC").path("search")
                 .queryParam("q", "blau").queryParam("ql", "poliqarp")
@@ -338,7 +338,7 @@
 
     @Test
     @Ignore
-    public void testSearchForCorpusWithStringIdUnauthorized () {
+    public void testSearchForCorpusWithStringIdUnauthorized () throws KustvaktException {
         ClientResponse response = resource()
                 .path("corpus").path("WPD15").path("search")
                 .queryParam("q", "blau").queryParam("ql", "poliqarp")
@@ -355,7 +355,7 @@
 
     @Test
     @Ignore
-    public void testSearchForSpecificCorpus () {
+    public void testSearchForSpecificCorpus () throws KustvaktException{
         ClientResponse response = resource()
                 .path("corpus").path("GOE").path("search")
                 .queryParam("q", "[orth=das]").queryParam("ql", "poliqarp")
@@ -423,7 +423,7 @@
 
 
     @Test
-    public void testSearchSentenceMeta () {
+    public void testSearchSentenceMeta () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=der]")
                 .queryParam("ql", "poliqarp").queryParam("context", "sentence")
@@ -439,7 +439,7 @@
 
 
     @Test
-    public void testSearchSimpleCQL () {
+    public void testSearchSimpleCQL () throws KustvaktException{
         QuerySerializer s = new QuerySerializer();
         s.setQuery("(der) or (das)", "CQL");
 
@@ -457,7 +457,7 @@
 
 
     @Test
-    public void testSearchRawQuery () {
+    public void testSearchRawQuery () throws KustvaktException{
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[orth=der]", "poliqarp");
         s.setCollection("corpusSigle=GOE");
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
index 5427fd0..cbf1b3e 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/SearchWithAvailabilityTest.java
@@ -22,7 +22,7 @@
 //        helper().runBootInterfaces();
     }
 
-    private void checkAndFree (String json) {
+    private void checkAndFree (String json) throws KustvaktException{
         JsonNode node = JsonUtils.readTree(json);
         assertEquals("availability",
                 node.at("/collection/operands/0/key").asText());
@@ -35,7 +35,7 @@
     }
 
 
-    private void checkAndPublic (String json) {
+    private void checkAndPublic (String json) throws KustvaktException{
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
         assertEquals("operation:and",
@@ -58,7 +58,7 @@
                 node.at("/collection/rewrites/0/scope").asText());
     }
     
-    private void checkAndPublicWithoutACA (String json) {
+    private void checkAndPublicWithoutACA (String json) throws KustvaktException{
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
         assertEquals("operation:and",
@@ -87,7 +87,7 @@
                 node.at("/collection/rewrites/0/scope").asText());
     }
     
-    private void checkAndAll (String json) {
+    private void checkAndAll (String json) throws KustvaktException{
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
         assertEquals("availability(ALL)",
@@ -127,7 +127,7 @@
         
     }
 
-    private void checkAndAllWithoutACA (String json) {
+    private void checkAndAllWithoutACA (String json) throws KustvaktException{
         JsonNode node = JsonUtils.readTree(json);
         assertNotNull(node);
         assertEquals("operation:and",
@@ -172,7 +172,7 @@
 
 
     @Test
-    public void testAvailabilityFreeAuthorized () {
+    public void testAvailabilityFreeAuthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = CC-BY-SA");
 
@@ -184,7 +184,7 @@
 
 
     @Test
-    public void testAvailabilityRegexFreeAuthorized () {
+    public void testAvailabilityRegexFreeAuthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = /.*BY.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -195,7 +195,7 @@
 
 
     @Test
-    public void testAvailabilityFreeUnauthorized () {
+    public void testAvailabilityFreeUnauthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = ACA-NC");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -206,7 +206,7 @@
 
 
     @Test
-    public void testAvailabilityRegexFreeUnauthorized () {
+    public void testAvailabilityRegexFreeUnauthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = /ACA.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -216,7 +216,7 @@
     }
 
     @Test
-    public void testAvailabilityRegexNoRewrite () {
+    public void testAvailabilityRegexNoRewrite () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = /CC-BY.*/ & availability = /ACA.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -242,7 +242,7 @@
 
 
     @Test
-    public void testAvailabilityRegexFreeUnauthorized3 () {
+    public void testAvailabilityRegexFreeUnauthorized3 () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability = /.*NC.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -254,7 +254,7 @@
 
 
     @Test
-    public void testNegationAvailabilityFreeUnauthorized () {
+    public void testNegationAvailabilityFreeUnauthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability != /CC-BY.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -265,7 +265,7 @@
 
 
     @Test
-    public void testNegationAvailabilityFreeUnauthorized2 () {
+    public void testNegationAvailabilityFreeUnauthorized2 () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "availability != /.*BY.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -276,7 +276,7 @@
 
 
     @Test
-    public void testComplexNegationAvailabilityFreeUnauthorized () {
+    public void testComplexNegationAvailabilityFreeUnauthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "textClass=politik & availability != /CC-BY.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -287,7 +287,7 @@
 
 
     @Test
-    public void testComplexAvailabilityFreeUnauthorized () {
+    public void testComplexAvailabilityFreeUnauthorized () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "textClass=politik & availability=ACA-NC");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -298,7 +298,7 @@
 
 
     @Test
-    public void testComplexAvailabilityFreeUnauthorized3 () {
+    public void testComplexAvailabilityFreeUnauthorized3 () throws KustvaktException{
         ClientResponse response = builtSimpleClientResponse(
                 "textClass=politik & availability=/.*NC.*/");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -309,7 +309,7 @@
 
 
     @Test
-    public void testAvailabilityPublicAuthorized () {
+    public void testAvailabilityPublicAuthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability=ACA-NC", "149.27.0.32");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -320,7 +320,7 @@
 
 
     @Test
-    public void testAvailabilityPublicUnauthorized () {
+    public void testAvailabilityPublicUnauthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability=QAO-NC-LOC:ids", "149.27.0.32");
 
@@ -332,7 +332,7 @@
 
 
     @Test
-    public void testAvailabilityRegexPublicAuthorized () {
+    public void testAvailabilityRegexPublicAuthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability= /ACA.*/", "149.27.0.32");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -343,7 +343,7 @@
 
 
     @Test
-    public void testNegationAvailabilityPublicUnauthorized () {
+    public void testNegationAvailabilityPublicUnauthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability != ACA-NC", "149.27.0.32");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -354,7 +354,7 @@
 
 
     @Test
-    public void testNegationAvailabilityRegexPublicUnauthorized () {
+    public void testNegationAvailabilityRegexPublicUnauthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability != /ACA.*/", "149.27.0.32");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
@@ -365,7 +365,7 @@
 
 
     @Test
-    public void testComplexAvailabilityPublicUnauthorized () {
+    public void testComplexAvailabilityPublicUnauthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "textClass=politik & availability=QAO-NC-LOC:ids",
                 "149.27.0.32");
@@ -378,7 +378,7 @@
 
 
     @Test
-    public void testNegationComplexAvailabilityPublicUnauthorized () {
+    public void testNegationComplexAvailabilityPublicUnauthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "textClass=politik & availability!=QAO-NC-LOC:ids",
                 "149.27.0.32");
@@ -390,7 +390,7 @@
     }
 
     @Test
-    public void testAvailabilityRegexAllAuthorized () {
+    public void testAvailabilityRegexAllAuthorized () throws KustvaktException{
         ClientResponse response = builtClientResponseWithIP(
                 "availability= /ACA.*/", "10.27.0.32");
         assertEquals(ClientResponse.Status.OK.getStatusCode(),
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserServiceTest.java b/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserServiceTest.java
index 4c84a67..b754d26 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserServiceTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/service/full/UserServiceTest.java
@@ -60,7 +60,7 @@
 	}
 
 	@Test
-	public void testRegisterMissingFields() {
+	public void testRegisterMissingFields() throws KustvaktException{
 
 		MultivaluedMap map = new MultivaluedMapImpl();
 		map.putSingle("username", "testuser"); // bodmer funktioniert noch nicht
@@ -114,7 +114,7 @@
 
 	// should be run over https, since password is transmitted in plain text
 	@Test
-	public void testRegisterAndConfirm() {
+	public void testRegisterAndConfirm() throws KustvaktException{
 		MultivaluedMap map = new MultivaluedMapImpl();
 		map.putSingle("username", "testuser");
 		map.putSingle("email", "hanl@ids-mannheim.de");
@@ -154,7 +154,7 @@
 	// EM: This test require VPN / IDS Intranet
 	@Test
 	@Ignore
-	public void loginJWT() {
+	public void loginJWT() throws KustvaktException{
 		String en = BasicHttpAuth.encode(credentials[0], credentials[1]);
 		/* lauffähige Version von Hanl: */
 		ClientResponse response = resource().path("auth").path("apiToken")
@@ -238,7 +238,7 @@
 	}
 
 	@Test
-	public void testUpdateUserDetailsMerge() {
+	public void testUpdateUserDetailsMerge() throws KustvaktException{
 		String enc = BasicHttpAuth.encode(credentials[0], credentials[1]);
 		Map m = new LinkedMap();
 		m.put("test", "test value 1");
@@ -294,7 +294,7 @@
 	}
 
 	@Test
-	public void testUpdateUserDetailsJson() {
+	public void testUpdateUserDetailsJson() throws KustvaktException{
 		String enc = BasicHttpAuth.encode(credentials[0], credentials[1]);
 		Map m = new LinkedMap();
 		m.put("firstName", "newName");
@@ -329,7 +329,7 @@
 
 	@Test
 	@Ignore
-	public void testUpdateUserSettingsForm() throws IOException {
+	public void testUpdateUserSettingsForm() throws IOException, KustvaktException{
 		String enc = BasicHttpAuth.encode(credentials[0], credentials[1]);
 		MultivaluedMap m = new MultivaluedMapImpl();
 		m.putSingle("queryLanguage", "poliqarp_test");
@@ -367,7 +367,7 @@
 	}
 
 	@Test
-	public void testUpdateUserSettingsJson() throws IOException {
+	public void testUpdateUserSettingsJson() throws IOException, KustvaktException {
 		String enc = BasicHttpAuth.encode(credentials[0], credentials[1]);
 		Map m = new HashMap<>();
 		m.put("queryLanguage", "poliqarp_test");
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index c5c47af..43cc494 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -160,6 +160,11 @@
 	<bean id="kustvakt_auditing" class="de.ids_mannheim.korap.handlers.JDBCAuditing">
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
+	
+	<bean id="kustvakt_response"
+          class="de.ids_mannheim.korap.web.utils.KustvaktResponseHandler">
+          <constructor-arg index="0" name="iface" ref="kustvakt_auditing"/>
+    </bean>
 
 	<bean id="kustvakt_userdb" class="de.ids_mannheim.korap.handlers.EntityDao">
 		<constructor-arg ref="kustvakt_db" />
diff --git a/lite/pom.xml b/lite/pom.xml
index fc394fb..4215b5e 100644
--- a/lite/pom.xml
+++ b/lite/pom.xml
@@ -155,7 +155,7 @@
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Kustvakt-core</artifactId>
-			<version>0.59.8</version>
+			<version>0.59.9</version>
 		</dependency>
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
diff --git a/lite/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java b/lite/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
index 05f8056..1b745b7 100644
--- a/lite/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
+++ b/lite/src/main/java/de/ids_mannheim/korap/web/service/light/LightService.java
@@ -58,6 +58,8 @@
     private static Logger jlog = LoggerFactory.getLogger(LightService.class);
 
     @Autowired
+    KustvaktResponseHandler kustvaktResponseHandler;
+    @Autowired
     private SearchKrill searchKrill;
     private ClientsHandler graphDBhandler;
     @Autowired
@@ -86,7 +88,7 @@
             result = graphDBhandler.getResponse("distCollo", "q", query);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(result).build();
     }
@@ -126,7 +128,7 @@
             query = this.processor.processQuery(ss.toJSON(), null);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok(query).build();
     }
@@ -140,7 +142,7 @@
             jsonld = processor.processQuery(jsonld, null);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         // todo: should be possible to add the meta part to the query serialization
         jlog.info("Serialized search: {}", jsonld);
@@ -184,7 +186,7 @@
             query = this.processor.processQuery(serializer.toJSON(), null);
         }
         catch (KustvaktException e) {
-            throw KustvaktResponseHandler.throwit(e);
+            throw kustvaktResponseHandler.throwit(e);
         }
         jlog.info("the serialized query {}", query);
 
@@ -202,7 +204,7 @@
                 result = this.graphDBhandler.getResponse(map, "distKwic");
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwit(e);
+                throw kustvaktResponseHandler.throwit(e);
             }
         }
         else
@@ -261,13 +263,13 @@
                 query = this.processor.processQuery(s.toJSON(), null);
             }
             catch (KustvaktException e) {
-                throw KustvaktResponseHandler.throwit(e);
+                throw kustvaktResponseHandler.throwit(e);
             }
         }
         String result;
         try {
             if (eng.equals(KustvaktConfiguration.BACKENDS.NEO4J)) {
-                if (raw) throw KustvaktResponseHandler.throwit(
+                if (raw) throw kustvaktResponseHandler.throwit(
                         StatusCodes.ILLEGAL_ARGUMENT, "raw not supported!",
                         null);
                 MultivaluedMap map = new MultivaluedMapImpl();
@@ -285,7 +287,7 @@
         }
         catch (Exception e) {
             jlog.error("Exception for serialized query: " + query, e);
-            throw KustvaktResponseHandler.throwit(500, e.getMessage(), null);
+            throw kustvaktResponseHandler.throwit(500, e.getMessage(), null);
         }
 
         jlog.debug("The result set: {}", result);
@@ -300,11 +302,17 @@
 
         KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
         builder.with(collectionQuery);
-        String json = builder.toJSON();
+        String json;
+        try {
+            json = builder.toJSON();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
 
         String stats = searchKrill.getStatistics(json);
         if (stats.contains("-1"))
-            throw KustvaktResponseHandler.throwit(StatusCodes.NO_RESULT_FOUND);
+            throw kustvaktResponseHandler.throwit(StatusCodes.NO_RESULT_FOUND);
         jlog.debug("Stats: " + stats);
         return Response.ok(stats).build();
     }
diff --git a/lite/src/main/resources/test-config.xml b/lite/src/main/resources/test-config.xml
index 3ff2ef1..6b1fa49 100644
--- a/lite/src/main/resources/test-config.xml
+++ b/lite/src/main/resources/test-config.xml
@@ -34,6 +34,11 @@
     <bean id="kustvakt_auditing"
           class="de.ids_mannheim.korap.interfaces.defaults.DefaultAuditing">
     </bean>
+    
+    <bean id="kustvakt_response"
+          class="de.ids_mannheim.korap.web.utils.KustvaktResponseHandler">
+          <constructor-arg index="0" name="iface" ref="kustvakt_auditing"/>
+    </bean>
 
     <bean id="kustvakt_config"
           class="de.ids_mannheim.korap.config.KustvaktConfiguration">
diff --git a/lite/src/test/java/de/ids_mannheim/korap/web/service/LightServiceTest.java b/lite/src/test/java/de/ids_mannheim/korap/web/service/LightServiceTest.java
index e0ecf31..99312ec 100644
--- a/lite/src/test/java/de/ids_mannheim/korap/web/service/LightServiceTest.java
+++ b/lite/src/test/java/de/ids_mannheim/korap/web/service/LightServiceTest.java
@@ -30,7 +30,7 @@
     public void initMethod () throws KustvaktException {}
 
     @Test
-    public void testStatistics () {
+    public void testStatistics () throws KustvaktException{
         ClientResponse response = resource()
                 .path("statistics")
                 .queryParam("collectionQuery", "textType=Autobiographie & corpusSigle=GOE")
@@ -46,7 +46,7 @@
     }
 
     @Test
-    public void testGetJSONQuery () {
+    public void testGetJSONQuery () throws KustvaktException{
         ClientResponse response = resource()
                 .path("query").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp").queryParam("context", "sentence")
@@ -66,7 +66,7 @@
 
 
     @Test
-    public void testbuildAndPostQuery () {
+    public void testbuildAndPostQuery () throws KustvaktException{
         ClientResponse response = resource()
                 .path("query").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp")
@@ -91,7 +91,7 @@
 
 
     @Test
-    public void testQueryGet () {
+    public void testQueryGet () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp").queryParam("context", "sentence")
@@ -109,7 +109,7 @@
 
 
     @Test
-    public void testFoundryRewrite () {
+    public void testFoundryRewrite () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp").queryParam("context", "sentence")
@@ -125,7 +125,7 @@
 
 
     @Test
-    public void testQueryPost () {
+    public void testQueryPost () throws KustvaktException{
         QuerySerializer s = new QuerySerializer();
         s.setQuery("[orth=das]", "poliqarp");
 
@@ -142,7 +142,7 @@
 
 
     @Test
-    public void testParameterField () {
+    public void testParameterField () throws KustvaktException{
         ClientResponse response = resource()
                 .path("search").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp")
@@ -161,7 +161,7 @@
     }
 
 	@Test
-	public void testMatchInfoGetWithoutSpans () {
+	public void testMatchInfoGetWithoutSpans () throws KustvaktException{
         ClientResponse response = resource()
 			
 			.path("corpus/GOE/AGA/01784/p36-46/matchInfo")
@@ -178,7 +178,7 @@
 	};
 
 	@Test
-	public void testMatchInfoGet2 () {
+	public void testMatchInfoGet2 () throws KustvaktException{
         ClientResponse response = resource()
 			
 			.path("corpus/GOE/AGA/01784/p36-46/matchInfo")
@@ -194,7 +194,7 @@
 	};
 
     @Test
-    public void testCollectionQueryParameter () {
+    public void testCollectionQueryParameter () throws KustvaktException{
         ClientResponse response = resource()
                 .path("query").queryParam("q", "[orth=das]")
                 .queryParam("ql", "poliqarp")