Merge remote-tracking branch 'origin/master' into fcs-ql-branch
diff --git a/Changes b/Changes
index 8c6defd..739f58c 100644
--- a/Changes
+++ b/Changes
@@ -4,7 +4,7 @@
 	  now serialize to unordered sequences (diewald)
 	- Cleanup POM (diewald)
 	- Fix deserialization of unnecessary brackets
-	  around terms in Poliqarp (diewald)
+	  around terms and termGroups in Poliqarp (diewald)
 
 0.21 2015-10-27
         - Improved meta query builder (hanl)
diff --git a/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4 b/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
index f1f9110..1907773 100644
--- a/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
+++ b/src/main/antlr/poliqarpplus/PoliqarpPlusParser.g4
@@ -102,6 +102,7 @@
 
 termGroup
 : (term | LRPAREN termGroup RRPAREN) boolOp (term | LRPAREN termGroup RRPAREN | termGroup)
+| LRPAREN termGroup RRPAREN
 ;
 
 repetition
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
index 8eb859d..d92613a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessor.java
@@ -864,6 +864,12 @@
             return term;
         }
         else if (nodeCat.equals("termGroup")) {
+
+            // TermGroup is defined recursive with non-necessary brackets
+            if (getNodeCat(node.getChild(0)).equals("(")) {
+                return parseTermOrTermGroup(node.getChild(1), negatedGlobal, mode);
+            };
+
             // For termGroups, establish a boolean relation between
             // operands and recursively call this function with
             // the term or termGroup operands
diff --git a/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
index d7bddfa..1142ae9 100644
--- a/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/serialize/PoliqarpPlusQueryProcessorTest.java
@@ -1013,6 +1013,59 @@
         assertEquals("lemma", res.at("/query/wrap/layer").asText());
         assertEquals("match:eq", res.at("/query/wrap/match").asText());
 
+        query = "[(base=Mann&cas=N)]";
+        qs.setQuery(query, "poliqarpplus");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("koral:token", res.at("/query/@type").asText());
+        assertEquals("koral:termGroup", res.at("/query/wrap/@type")
+                .asText());
+        assertEquals("relation:and", res.at("/query/wrap/relation")
+                     .asText());
+        assertEquals("Mann", res.at("/query/wrap/operands/0/key")
+                     .asText());
+        assertEquals("lemma", res.at("/query/wrap/operands/0/layer")
+                     .asText());
+        assertEquals("N", res.at("/query/wrap/operands/1/key")
+                     .asText());
+        assertEquals("cas", res.at("/query/wrap/operands/1/layer")
+                     .asText());
+
+
+        query = "[(((base=Mann&cas=N)))]";
+        qs.setQuery(query, "poliqarpplus");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("koral:token", res.at("/query/@type").asText());
+        assertEquals("koral:termGroup", res.at("/query/wrap/@type")
+                .asText());
+        assertEquals("relation:and", res.at("/query/wrap/relation")
+                     .asText());
+        assertEquals("Mann", res.at("/query/wrap/operands/0/key")
+                     .asText());
+        assertEquals("lemma", res.at("/query/wrap/operands/0/layer")
+                     .asText());
+        assertEquals("N", res.at("/query/wrap/operands/1/key")
+                     .asText());
+        assertEquals("cas", res.at("/query/wrap/operands/1/layer")
+                     .asText());
+
+
+        query = "[(((base=Mann&((cas=N)))))]";
+        qs.setQuery(query, "poliqarpplus");
+        res = mapper.readTree(qs.toJSON());
+        assertEquals("koral:token", res.at("/query/@type").asText());
+        assertEquals("koral:termGroup", res.at("/query/wrap/@type")
+                .asText());
+        assertEquals("relation:and", res.at("/query/wrap/relation")
+                     .asText());
+        assertEquals("Mann", res.at("/query/wrap/operands/0/key")
+                     .asText());
+        assertEquals("lemma", res.at("/query/wrap/operands/0/layer")
+                     .asText());
+        assertEquals("N", res.at("/query/wrap/operands/1/key")
+                     .asText());
+        assertEquals("cas", res.at("/query/wrap/operands/1/layer")
+                     .asText());
+
     };
 
     @Test