Added support for multiple cq parameters.

Change-Id: Ica7effe455cc9320ca0a5cc1c8f730167e78e1d8
diff --git a/core/Changes b/core/Changes
index 6aa58f1..291e020 100644
--- a/core/Changes
+++ b/core/Changes
@@ -4,6 +4,8 @@
 11/12/2019
    - Added errors when requesting VC in caching process (margaretha, 
      resolved #47) 
+12/12/2019
+   - Added support for multiple cq parameters (margaretha, resolved #46)
 
 # version 0.62.2
 13/11/2019
diff --git a/core/src/main/java/de/ids_mannheim/korap/service/BasicService.java b/core/src/main/java/de/ids_mannheim/korap/service/BasicService.java
new file mode 100644
index 0000000..040bdca
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/service/BasicService.java
@@ -0,0 +1,17 @@
+package de.ids_mannheim.korap.service;
+
+import java.util.List;
+
+public class BasicService {
+
+    protected String combineMultipleCorpusQuery (List<String> cqList) {
+        String combinedCorpusQuery = null;
+        if (cqList!=null && cqList.size() > 0) {
+            combinedCorpusQuery = cqList.get(0);
+            for (int i = 1; i < cqList.size(); i++) {
+                combinedCorpusQuery += "&" + cqList.get(i);
+            }
+        }
+        return combinedCorpusQuery;
+    }
+}
diff --git a/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java b/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
index 46452ca..0d1db18 100644
--- a/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
+++ b/core/src/main/java/de/ids_mannheim/korap/service/SearchService.java
@@ -38,7 +38,7 @@
 import de.ids_mannheim.korap.web.SearchKrill;
 
 @Service
-public class SearchService {
+public class SearchService extends BasicService{
 
     private static final boolean DEBUG = false;
 
@@ -123,7 +123,7 @@
 
     @SuppressWarnings("unchecked")
     public String search (String engine, String username, HttpHeaders headers,
-            String q, String ql, String v, String cq, String fields,
+            String q, String ql, String v, List<String> cqList, String fields,
             String pipes, Integer pageIndex, Integer pageInteger, String ctx,
             Integer pageLength, Boolean cutoff, boolean accessRewriteDisabled)
             throws KustvaktException {
@@ -151,6 +151,7 @@
         
         QuerySerializer serializer = new QuerySerializer();
         serializer.setQuery(q, ql, v);
+        String cq = combineMultipleCorpusQuery(cqList);
         if (cq != null) serializer.setCollection(cq);
 
         List<String> fieldList = convertFieldsToList(fields);
diff --git a/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java b/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java
new file mode 100644
index 0000000..694e57b
--- /dev/null
+++ b/core/src/main/java/de/ids_mannheim/korap/service/StatisticService.java
@@ -0,0 +1,98 @@
+package de.ids_mannheim.korap.service;
+
+import java.util.List;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import de.ids_mannheim.korap.config.KustvaktConfiguration;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.response.Notifications;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
+import de.ids_mannheim.korap.web.SearchKrill;
+
+@Service
+public class StatisticService extends BasicService {
+
+    @Autowired
+    private SearchKrill searchKrill;
+    @Autowired
+    private KustvaktConfiguration config;
+
+    public String retrieveStatisticsForCorpusQuery (List<String> cqList,
+            boolean isDeprecated) throws KustvaktException {
+
+        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+        String cq = combineMultipleCorpusQuery(cqList);
+        String json = null;
+        if (cq != null && !cq.isEmpty()) {
+            builder.with(cq);
+            json = builder.toJSON();
+        }
+
+        if (json != null) {
+            checkVC(json);
+        }
+        String stats = searchKrill.getStatistics(json);
+
+        if (isDeprecated) {
+            Notifications n = new Notifications();
+            n.addWarning(StatusCodes.DEPRECATED_PARAMETER,
+                    "Parameter corpusQuery is deprecated in favor of cq.");
+            ObjectNode warning = (ObjectNode) n.toJsonNode();
+            ObjectNode node = (ObjectNode) JsonUtils.readTree(stats);
+            node.setAll(warning);
+            stats = node.toString();
+        }
+        
+        if (stats.contains("-1")) {
+            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND);
+        }
+        return stats;
+    }
+
+    private void checkVC (String json) throws KustvaktException {
+        JsonNode node = JsonUtils.readTree(json);
+        node = node.at("/collection");
+        if (node.has("ref")) {
+            String vcName = node.path("ref").asText();
+            if (vcName.contains("/")) {
+                String[] names = vcName.split("/");
+                if (names.length == 2) {
+                    vcName = names[1];
+                }
+            }
+
+            String vcInCaching = config.getVcInCaching();
+            if (vcName.equals(vcInCaching)) {
+                throw new KustvaktException(
+                        de.ids_mannheim.korap.exceptions.StatusCodes.CACHING_VC,
+                        "VC is currently busy and unaccessible due to "
+                                + "caching process",
+                        node.get("ref").asText());
+            }
+        }
+    }
+
+    public String retrieveStatisticsForKoralQuery (String koralQuery)
+            throws KustvaktException {
+        String stats = null;
+        if (koralQuery != null && !koralQuery.isEmpty()) {
+            checkVC(koralQuery);
+            stats = searchKrill.getStatistics(koralQuery);
+        }
+        else {
+            stats = searchKrill.getStatistics(null);
+        }
+        
+        if (stats.contains("-1")) {
+            throw new KustvaktException(StatusCodes.NO_RESULT_FOUND);
+        }
+        return stats;
+    }
+}
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java b/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
index 76bf89d..383def3 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/controller/SearchController.java
@@ -2,6 +2,7 @@
                                              // de.ids_mannheim.korap.ext.web;
 
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
 import java.util.Set;
 
@@ -184,7 +185,7 @@
             @QueryParam("fields") String fields,
             @QueryParam("pipes") String pipes,
             @QueryParam("access-rewrite-disabled") boolean accessRewriteDisabled,
-            @QueryParam("cq") String cq, 
+            @QueryParam("cq") List<String> cq, 
             @QueryParam("engine") String engine) {
 
         TokenContext context =
@@ -270,7 +271,6 @@
             @QueryParam("fields") String fields,
             @Context SecurityContext ctx,
             @Context HttpHeaders headers
-            // @QueryParam("fields") Set<String> fields
     ) throws KustvaktException {
         TokenContext tokenContext = (TokenContext) ctx.getUserPrincipal();
         try {
diff --git a/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java b/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
index 51bcaae..9105af3 100644
--- a/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
+++ b/core/src/main/java/de/ids_mannheim/korap/web/controller/StatisticController.java
@@ -1,5 +1,6 @@
 package de.ids_mannheim.korap.web.controller;
 
+import java.util.List;
 import java.util.Locale;
 
 import javax.ws.rs.Consumes;
@@ -18,18 +19,11 @@
 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.ResourceFilters;
 
-import de.ids_mannheim.korap.config.KustvaktConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.response.Notifications;
-import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
+import de.ids_mannheim.korap.service.StatisticService;
 import de.ids_mannheim.korap.web.CoreResponseHandler;
-import de.ids_mannheim.korap.web.SearchKrill;
 import de.ids_mannheim.korap.web.filter.APIVersionFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 
@@ -54,10 +48,8 @@
     @Autowired
     private CoreResponseHandler kustvaktResponseHandler;
     @Autowired
-    private SearchKrill searchKrill;
-    @Autowired
-    private KustvaktConfiguration config;
-    
+    private StatisticService service;
+
     /**
      * Returns statistics of the virtual corpus defined by the given
      * corpusQuery parameter.
@@ -69,79 +61,32 @@
      * @param cq
      *            a collection query specifying a virtual corpus
      * @param corpusQuery
-     *            (DEPRECATED) a collection query specifying a virtual corpus 
+     *            (DEPRECATED) a collection query specifying a virtual
+     *            corpus
      * @return statistics of the virtual corpus defined by the given
      *         corpusQuery parameter.
      */
     @GET
     public Response getStatistics (@Context SecurityContext context,
-            @Context Locale locale,
-            @QueryParam("cq") String cq,
-            @QueryParam("corpusQuery") String corpusQuery) {
-
-        KoralCollectionQueryBuilder builder = new KoralCollectionQueryBuilder();
+            @Context Locale locale, @QueryParam("cq") List<String> cq,
+            @QueryParam("corpusQuery") List<String> corpusQuery) {
 
         String stats;
-        String json = null;
         boolean isDeprecated = false;
         try {
-            if (cq != null && !cq.isEmpty()) {
-                builder.with(cq);
-                json = builder.toJSON();
-            }
-            else if (corpusQuery != null && !corpusQuery.isEmpty()) {
-                builder.with(corpusQuery);
-                json = builder.toJSON();
+            if (cq.isEmpty() && corpusQuery != null && !corpusQuery.isEmpty()) {
                 isDeprecated = true;
+                cq = corpusQuery;
             }
-            
-            checkVC(json);
-            stats = searchKrill.getStatistics(json);
-            
-            if (isDeprecated){
-                Notifications n = new Notifications();
-                n.addWarning(StatusCodes.DEPRECATED_PARAMETER,
-                        "Parameter corpusQuery is deprecated in favor of cq.");
-                ObjectNode warning = (ObjectNode) n.toJsonNode();
-                ObjectNode node = (ObjectNode) JsonUtils.readTree(stats);
-                node.setAll(warning);
-                stats = node.toString();
+            stats = service.retrieveStatisticsForCorpusQuery(cq, isDeprecated);
+            if (DEBUG) {
+                jlog.debug("Stats: " + stats);
             }
+            return Response.ok(stats).build();
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
         }
-        
-        if (stats.contains("-1")) {
-            throw kustvaktResponseHandler.throwit(StatusCodes.NO_RESULT_FOUND);
-        }
-        if (DEBUG) {
-            jlog.debug("Stats: " + stats);
-        }
-        return Response.ok(stats).build();
-    }
-    
-    private void checkVC (String json) throws KustvaktException {
-        JsonNode node = JsonUtils.readTree(json);
-        node = node.at("/collection");
-        if (node.has("ref")){
-            String vcName = node.path("ref").asText();
-            if (vcName.contains("/")) {
-                String[] names = vcName.split("/");
-                if (names.length == 2) {
-                    vcName = names[1];
-                }
-            }
-            
-            String vcInCaching = config.getVcInCaching();
-            if (vcName.equals(vcInCaching)) {
-                throw new KustvaktException(
-                        de.ids_mannheim.korap.exceptions.StatusCodes.CACHING_VC,
-                        "VC is currently busy and unaccessible due to "
-                                + "caching process",
-                        node.get("ref").asText());
-            }
-        }
     }
 
     @POST
@@ -149,20 +94,8 @@
     public Response getStatisticsFromKoralQuery (
             @Context SecurityContext context, @Context Locale locale,
             String koralQuery) {
-        String stats;
         try {
-            if (koralQuery != null && !koralQuery.isEmpty()) {
-                checkVC(koralQuery);
-                stats = searchKrill.getStatistics(koralQuery);
-            }
-            else {
-                stats = searchKrill.getStatistics(null);
-            }
-
-            if (stats.contains("-1")) {
-                throw kustvaktResponseHandler
-                        .throwit(StatusCodes.NO_RESULT_FOUND);
-            }
+            String stats = service.retrieveStatisticsForKoralQuery(koralQuery);
             return Response.ok(stats).build();
         }
         catch (KustvaktException e) {
diff --git a/full/Changes b/full/Changes
index 8697d35..4ec9218 100644
--- a/full/Changes
+++ b/full/Changes
@@ -3,7 +3,10 @@
    - Implemented pipe extension in the search API (margaretha)
 11/12/2019
    - Added errors when requesting VC in caching process (margaretha, 
-     resolved #47) 
+     resolved #47)
+12/12/2019
+   - Added support for multiple cq parameters (margaretha, resolved #46)
+      
 
 # version 0.62.2
 17/10/2019
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java
new file mode 100644
index 0000000..1692fdc
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/MultipleCorpusQueryTest.java
@@ -0,0 +1,86 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+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.SpringJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class MultipleCorpusQueryTest extends SpringJerseyTest {
+
+    @Test
+    public void testSearchGet () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "das").queryParam("ql", "poliqarp")
+                .queryParam("cq", "pubPlace=München")
+                .queryParam("cq", "textSigle=\"GOE/AGA/01784\"")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        node = node.at("/collection/operands/1");
+        assertEquals("koral:docGroup", node.at("/@type").asText());
+        assertEquals("operation:and", node.at("/operation").asText());
+        assertEquals(2, node.at("/operands").size());
+        assertEquals("koral:doc", node.at("/operands/0/@type").asText());
+        assertEquals("match:eq", node.at("/operands/0/match").asText());
+        assertEquals("pubPlace", node.at("/operands/0/key").asText());
+        assertEquals("München", node.at("/operands/0/value").asText());
+        assertEquals("textSigle", node.at("/operands/1/key").asText());
+        assertEquals("GOE/AGA/01784", node.at("/operands/1/value").asText());
+    }
+
+    @Test
+    public void testStatisticsWithMultipleCq ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
+        ClientResponse response = resource().path(API_VERSION)
+                .path("statistics").queryParam("cq", "textType=Abhandlung")
+                .queryParam("cq", "corpusSigle=GOE")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(2, node.at("/documents").asInt());
+        assertEquals(138180, node.at("/tokens").asInt());
+        assertEquals(5687, node.at("/sentences").asInt());
+        assertEquals(258, node.at("/paragraphs").asInt());
+
+        assertTrue(node.at("/warnings").isMissingNode());
+    }
+
+    @Test
+    public void testStatisticsWithMultipleCorpusQuery ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
+        ClientResponse response =
+                resource().path(API_VERSION).path("statistics")
+                        .queryParam("corpusQuery", "textType=Autobiographie")
+                        .queryParam("corpusQuery", "corpusSigle=GOE")
+                        .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(9, node.at("/documents").asInt());
+        assertEquals(527662, node.at("/tokens").asInt());
+        assertEquals(19387, node.at("/sentences").asInt());
+        assertEquals(514, node.at("/paragraphs").asInt());
+
+        assertEquals(StatusCodes.DEPRECATED_PARAMETER,
+                node.at("/warnings/0/0").asInt());
+        assertEquals("Parameter corpusQuery is deprecated in favor of cq.",
+                node.at("/warnings/0/1").asText());
+    }
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
index dc5d3c7..8ac68fa 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/StatisticsControllerTest.java
@@ -228,10 +228,10 @@
                      response.getStatus());
         String ent = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
-        assertEquals(node.at("/errors/0/0").asInt(),
-                de.ids_mannheim.korap.util.StatusCodes.UNABLE_TO_PARSE_JSON);
-        assertEquals(node.at("/errors/0/1").asText(),
-                "Unable to parse JSON");
+        assertEquals(StatusCodes.DESERIALIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Failed deserializing json object: { \"collection\" : }",
+                node.at("/errors/0/1").asText());
     }
     
     @Test
diff --git a/lite/Changes b/lite/Changes
index d6991e0..0a06d87 100644
--- a/lite/Changes
+++ b/lite/Changes
@@ -1,6 +1,8 @@
 # version 0.62.3
 03/12/2019
    - Implemented pipe extension in the search API (margaretha)
+12/12/2019
+   - Added support for multiple cq parameters (margaretha, resolved #46)
 
 # version 0.62.2
 13/11/2019
diff --git a/lite/src/main/resources/lite-config.xml b/lite/src/main/resources/lite-config.xml
index e474b65..637977f 100644
--- a/lite/src/main/resources/lite-config.xml
+++ b/lite/src/main/resources/lite-config.xml
@@ -13,7 +13,8 @@
 
 
 	<context:component-scan
-		base-package="de.ids_mannheim.korap.rewrite, 
+		base-package="de.ids_mannheim.korap.rewrite,
+		de.ids_mannheim.korap.service, 
 	    de.ids_mannheim.korap.web.filter, 
 		de.ids_mannheim.korap.web.utils,
 		de.ids_mannheim.korap.authentication.http" />
@@ -159,10 +160,8 @@
 		class="de.ids_mannheim.korap.web.controller.StatisticController" />
 
 	<!-- Services -->
-	<bean id="annotationService" class="de.ids_mannheim.korap.service.AnnotationService"></bean>
 	<bean id="scopeService"
 		class="de.ids_mannheim.korap.oauth2.service.DummyOAuth2ScopeServiceImpl" />
-	<bean id="searchService" class="de.ids_mannheim.korap.service.SearchService"></bean>
 
 	<!-- DAO -->
 	<bean id="adminDao" class="de.ids_mannheim.korap.dao.DummyAdminDaoImpl" />
diff --git a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteMultipleCorpusQueryTest.java b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteMultipleCorpusQueryTest.java
new file mode 100644
index 0000000..ea7f964
--- /dev/null
+++ b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteMultipleCorpusQueryTest.java
@@ -0,0 +1,85 @@
+package de.ids_mannheim.korap.web.service;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+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.LiteJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.exceptions.StatusCodes;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class LiteMultipleCorpusQueryTest extends LiteJerseyTest {
+
+    @Test
+    public void testSearchGet () throws KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("search")
+                .queryParam("q", "das").queryParam("ql", "poliqarp")
+                .queryParam("cq", "pubPlace=München")
+                .queryParam("cq", "textSigle=\"GOE/AGA/01784\"")
+                .get(ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        node = node.at("/collection");
+        assertEquals("koral:docGroup", node.at("/@type").asText());
+        assertEquals("operation:and", node.at("/operation").asText());
+        assertEquals(2, node.at("/operands").size());
+        assertEquals("koral:doc", node.at("/operands/0/@type").asText());
+        assertEquals("match:eq", node.at("/operands/0/match").asText());
+        assertEquals("pubPlace", node.at("/operands/0/key").asText());
+        assertEquals("München", node.at("/operands/0/value").asText());
+        assertEquals("textSigle", node.at("/operands/1/key").asText());
+        assertEquals("GOE/AGA/01784", node.at("/operands/1/value").asText());
+    }
+
+    @Test
+    public void testStatisticsWithMultipleCq ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("statistics")
+                .queryParam("cq", "textType=Abhandlung")
+                .queryParam("cq", "corpusSigle=GOE")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(2, node.at("/documents").asInt());
+        assertEquals(138180, node.at("/tokens").asInt());
+        assertEquals(5687, node.at("/sentences").asInt());
+        assertEquals(258, node.at("/paragraphs").asInt());
+
+        assertTrue(node.at("/warnings").isMissingNode());
+    }
+
+    @Test
+    public void testStatisticsWithMultipleCorpusQuery ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
+        ClientResponse response = resource().path(API_VERSION).path("statistics")
+                .queryParam("corpusQuery", "textType=Autobiographie")
+                .queryParam("corpusQuery", "corpusSigle=GOE")
+                .method("GET", ClientResponse.class);
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(9, node.at("/documents").asInt());
+        assertEquals(527662, node.at("/tokens").asInt());
+        assertEquals(19387, node.at("/sentences").asInt());
+        assertEquals(514, node.at("/paragraphs").asInt());
+
+        assertEquals(StatusCodes.DEPRECATED_PARAMETER,
+                node.at("/warnings/0/0").asInt());
+        assertEquals("Parameter corpusQuery is deprecated in favor of cq.",
+                node.at("/warnings/0/1").asText());
+    }
+}
diff --git a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
index 268fdb1..0d56d92 100644
--- a/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
+++ b/lite/src/test/java/de/ids_mannheim/korap/web/service/LiteStatisticControllerTest.java
@@ -158,10 +158,10 @@
                      response.getStatus());
         String ent = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(ent);
-        assertEquals(node.at("/errors/0/0").asInt(),
-                de.ids_mannheim.korap.util.StatusCodes.UNABLE_TO_PARSE_JSON);
-        assertEquals(node.at("/errors/0/1").asText(),
-                "Unable to parse JSON");
+        assertEquals(StatusCodes.DESERIALIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Failed deserializing json object: { \"collection\" : }",
+                node.at("/errors/0/1").asText());
     }
     
     @Test
diff --git a/lite/src/test/resources/test-config.xml b/lite/src/test/resources/test-config.xml
index ba6713b..cda35c7 100644
--- a/lite/src/test/resources/test-config.xml
+++ b/lite/src/test/resources/test-config.xml
@@ -14,6 +14,7 @@
 
 	<context:component-scan
 		base-package="de.ids_mannheim.korap.rewrite,
+		de.ids_mannheim.korap.service,
 		de.ids_mannheim.korap.web.filter, 
 		de.ids_mannheim.korap.web.utils,
 		de.ids_mannheim.korap.authentication.http" />
@@ -156,10 +157,8 @@
 		class="de.ids_mannheim.korap.web.controller.StatisticController" />
 
 	<!-- Services -->
-	<bean id="annotationService" class="de.ids_mannheim.korap.service.AnnotationService"></bean>
 	<bean id="scopeService"
 		class="de.ids_mannheim.korap.oauth2.service.DummyOAuth2ScopeServiceImpl" />
-	<bean id="searchService" class="de.ids_mannheim.korap.service.SearchService"></bean>
 
 	<!-- DAO -->
 	<bean id="adminDao" class="de.ids_mannheim.korap.dao.DummyAdminDaoImpl" />