Modified ANNIS relations (in progress).

Change-Id: Ib4e24947dac06c39f39f6ab06ecbb58f49f6eb31
diff --git a/src/main/antlr/annis/AqlParser.g4 b/src/main/antlr/annis/AqlParser.g4
index ea719d1..bd0d8d6 100644
--- a/src/main/antlr/annis/AqlParser.g4
+++ b/src/main/antlr/annis/AqlParser.g4
@@ -83,9 +83,13 @@
 ;
 
 pointing
-: POINTING qName (anno=edgeSpec)? # DirectPointing
-| POINTING qName (anno=edgeSpec)? STAR # IndirectPointing
-| POINTING qName (anno=edgeSpec)? COMMA? rangeSpec # RangePointing
+: POINTING edgeAnno (anno=edgeSpec)? # DirectPointing
+| POINTING edgeAnno (anno=edgeSpec)? STAR # IndirectPointing
+| POINTING edgeAnno (anno=edgeSpec)? COMMA? rangeSpec # RangePointing
+
+//: POINTING qName (anno=edgeSpec)? # DirectPointing
+//| POINTING qName (anno=edgeSpec)? STAR # IndirectPointing
+//| POINTING qName (anno=edgeSpec)? COMMA? rangeSpec # RangePointing
 ;
 
 spanrelation
diff --git a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
index e7c5b56..fc6cc49 100644
--- a/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
+++ b/src/main/java/de/ids_mannheim/korap/query/serialize/util/KoralObjectGenerator.java
@@ -201,13 +201,13 @@
         }
         group.put("key", key);
         group.put("boundary", makeBoundary(min, max));
-        group.put("min", min);
-        if (max != null) {
-            group.put("max", max);
-        }
-        qp.addMessage(
-                StatusCodes.DEPRECATED_QUERY_ELEMENT,
-                "Deprecated 2014-07-24: 'min' and 'max' to be supported until 3 months from deprecation date.");
+//        group.put("min", min);
+//        if (max != null) {
+//            group.put("max", max);
+//        }
+//        qp.addMessage(
+//                StatusCodes.DEPRECATED_QUERY_ELEMENT,
+//                "Deprecated 2014-07-24: 'min' and 'max' to be supported until 3 months from deprecation date.");
         return group;
     }
 
diff --git a/src/test/java/de/ids_mannheim/korap/query/test/annis/AnnisQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/test/annis/AnnisQueryProcessorTest.java
index 716f9f3..066e615 100644
--- a/src/test/java/de/ids_mannheim/korap/query/test/annis/AnnisQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/test/annis/AnnisQueryProcessorTest.java
@@ -1,9 +1,8 @@
-package de.ids_mannheim.korap.query.test;
+package de.ids_mannheim.korap.query.test.annis;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
-import java.util.ArrayList;
 
 import org.junit.Test;
 
@@ -21,13 +20,11 @@
  * @version 1.0
  */
 public class AnnisQueryProcessorTest {
+    private String query;
 
-    String query;
-    ArrayList<JsonNode> operands;
-
-    QuerySerializer qs = new QuerySerializer();
-    ObjectMapper mapper = new ObjectMapper();
-    JsonNode res;
+    private QuerySerializer qs = new QuerySerializer();
+    private ObjectMapper mapper = new ObjectMapper();
+    private JsonNode res;
 
 
     @Test
@@ -144,146 +141,10 @@
         assertEquals("tt", res.at("/query/wrap/foundry").asText());
     }
 
-
     @Test
-    public void testDirectDeclarationRelations ()
-            throws JsonProcessingException, IOException {
-        query = "node > node";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-
-        query = "node > cnx/c=\"np\"";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("np", res.at("/query/operands/1/key").asText());
-        assertEquals("c", res.at("/query/operands/1/layer").asText());
-        assertEquals("cnx", res.at("/query/operands/1/foundry").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-
-        query = "cnx/c=\"np\" > node";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals(true, res.at("/query/operands/1/key").isMissingNode());
-        assertEquals("np", res.at("/query/operands/0/key").asText());
-
-        query = "cat=/NP/ & cat=/PP/ > #1";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("PP", res.at("/query/operands/0/key").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("NP", res.at("/query/operands/1/key").asText());
-        assertEquals(true, res.at("/query/operands/2").isMissingNode());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-    }
-
-
-    @Test
-    public void testDefPredicationInversion () throws JsonProcessingException,
+    public void testLeftMostChild () throws JsonProcessingException,
             IOException {
-        query = "#1 > #2 & cnx/cat=\"vp\" & cnx/cat=\"np\"";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("vp", res.at("/query/operands/0/key").asText());
-        assertEquals("c", res.at("/query/operands/0/layer").asText());
-        assertEquals("cnx", res.at("/query/operands/0/foundry").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("np", res.at("/query/operands/1/key").asText());
-        assertEquals("c", res.at("/query/operands/1/layer").asText());
-        assertEquals("cnx", res.at("/query/operands/1/foundry").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-    }
-
-
-    @Test
-    public void testSimpleDominance () throws JsonProcessingException,
-            IOException {
-        query = "node & node & #2 > #1";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-
-        query = "\"Mann\" & node & #2 > #1";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:token", res.at("/query/operands/1/@type").asText());
-        assertEquals("Mann", res.at("/query/operands/1/wrap/key").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-
-        query = "\"Mann\" & node & #2 >[func=\"SB\"] #1";  //coordinates the func=SB term and requires a "c"-layer term (consituency relation/dominance)
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:termGroup", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("relation:and", res.at("/query/relation/wrap/relation")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/operands/1/layer")
-                .asText());
-        assertEquals("func", res.at("/query/relation/wrap/operands/0/layer")
-                .asText());
-        assertEquals("SB", res.at("/query/relation/wrap/operands/0/key")
-                .asText());
-
-        query = "cat=\"S\" & node & #1 >[func=\"SB\" func=\"MO\"] #2";  // quite meaningless (function is subject and modifier), but this is allowed by Annis, however its backend only regards the 1st option
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals("koral:termGroup", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("relation:and", res.at("/query/relation/wrap/relation")
-                .asText());
-        assertEquals("func", res.at("/query/relation/wrap/operands/0/layer")
-                .asText());
-        assertEquals("SB", res.at("/query/relation/wrap/operands/0/key")
-                .asText());
-        assertEquals("func", res.at("/query/relation/wrap/operands/1/layer")
-                .asText());
-        assertEquals("MO", res.at("/query/relation/wrap/operands/1/key")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/operands/2/layer")
-                .asText());
-
+        
         query = "cat=\"S\" & cat=\"NP\" & #1 >@l #2";  // all sentences starting with NP  -> wrap relation in startswith and retrieve 2nd operand with focus
         qs.setQuery(query, "annis");
         res = mapper.readTree(qs.toJSON());
@@ -310,7 +171,11 @@
         assertEquals("operation:focus", res.at("/query/operands/1/operation")
                 .asText());
         assertEquals(130, res.at("/query/operands/1/classRef/0").asInt());
+    }
 
+    @Test
+    public void testRightMostChild () throws JsonProcessingException,
+            IOException {
         query = "cat=\"S\" & cat=\"NP\" & #1 >@r #2";
         qs.setQuery(query, "annis");
         res = mapper.readTree(qs.toJSON());
@@ -339,148 +204,6 @@
         assertEquals(130, res.at("/query/operands/1/classRef/0").asInt());
     }
 
-
-    @Test
-    public void testIndirectDominance () throws JsonProcessingException,
-            IOException {
-        query = "node & node & #1 >2,4 #2";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());
-        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());
-        assertEquals("koral:relation", res.at("/query/relation/@type").asText());
-        assertEquals(2, res.at("/query/relation/boundary/min").asInt());
-        assertEquals(4, res.at("/query/relation/boundary/max").asInt());
-        assertEquals("koral:term", res.at("/query/relation/wrap/@type")
-                .asText());
-        assertEquals("c", res.at("/query/relation/wrap/layer").asText());
-
-        query = "node & node & #1 >* #2";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals(0, res.at("/query/relation/boundary/min").asInt());
-        assertEquals(true, res.at("/query/relation/boundary/max")
-                .isMissingNode());
-    }
-
-
-    @Test
-    public void testMultipleDominance () throws JsonProcessingException,
-            IOException {
-        query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
-        qs.setQuery(query, "annis");
-        res = mapper.readTree(qs.toJSON());
-        assertEquals("koral:group", res.at("/query/@type").asText());
-        assertEquals("operation:relation", res.at("/query/operation").asText());
-        assertEquals("koral:reference", res.at("/query/operands/0/@type")
-                .asText());
-        assertEquals("operation:focus", res.at("/query/operands/0/operation")
-                .asText());
-        assertEquals(129, res.at("/query/operands/0/classRef/0").asInt());
-        assertEquals("koral:group", res
-                .at("/query/operands/0/operands/0/@type").asText());
-        assertEquals("operation:relation",
-                res.at("/query/operands/0/operands/0/operation").asText());
-        assertEquals("koral:relation",
-                res.at("/query/operands/0/operands/0/relation/@type").asText());
-        assertEquals("c",
-                res.at("/query/operands/0/operands/0/relation/wrap/layer")
-                        .asText());
-        assertEquals("koral:span",
-                res.at("/query/operands/0/operands/0/operands/0/@type")
-                        .asText());
-        assertEquals("c",
-                res.at("/query/operands/0/operands/0/operands/0/layer")
-                        .asText());
-        assertEquals("CP", res
-                .at("/query/operands/0/operands/0/operands/0/key").asText());
-        assertEquals("koral:group",
-                res.at("/query/operands/0/operands/0/operands/1/@type")
-                        .asText());
-        assertEquals("operation:class",
-                res.at("/query/operands/0/operands/0/operands/1/operation")
-                        .asText());
-        assertEquals(129,
-                res.at("/query/operands/0/operands/0/operands/1/classOut")
-                        .asInt());
-        assertEquals(
-                "VP",
-                res.at("/query/operands/0/operands/0/operands/1/operands/0/key")
-                        .asText());
-    }
-
-
-    //		query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";
-    //		String dom1 = 
-    //				"{@type=koral:group, operation=operation:relation, operands=[" +
-    //						"{@type=koral:reference, operation=operation:focus, classRef=[0], operands=[" +
-    //							"{@type=koral:group, operation=operation:relation, operands=[" +
-    //								"{@type=koral:span, layer=cat, key=CP, match=match:eq}," +
-    //								"{@type=koral:group, operation=operation:class, class=1, classOut=1, operands=[" +
-    //									"{@type=koral:span, layer=cat, key=VP, match=match:eq}" +
-    //								"]}" +
-    //							"], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +
-    //						"]}," +
-    //						"{@type=koral:span, layer=cat, key=NP, match=match:eq}" +
-    //				"], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}" +
-    //				"}";
-    //		aqlt = new AqlTree(query);
-    //		map = aqlt.getRequestMap().get("query").toString();
-    //		assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));
-    //		
-    //		query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & cat=\"DP\" & #1 > #2 > #3 > #4";
-    //		String dom2 = 
-    //				"{@type=koral:group, operation=operation:relation, operands=[" +
-    //						"{@type=koral:reference, operation=operation:focus, classRef=[1], operands=[" +
-    //							"{@type=koral:group, operation=operation:relation, operands=[" +
-    //								"{@type=koral:reference, operation=operation:focus, classRef=[0], operands=[" +
-    //									"{@type=koral:group, operation=operation:relation, operands=[" +
-    //										"{@type=koral:span, layer=cat, key=CP, match=match:eq}," +
-    //										"{@type=koral:group, operation=operation:class, class=1, classOut=1, operands=[" +
-    //											"{@type=koral:span, layer=cat, key=VP, match=match:eq}" +
-    //										"]}" +
-    //									"], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +
-    //								"]}," +
-    //								"{@type=koral:group, operation=operation:class, class=2, classOut=2, operands=[" +
-    //									"{@type=koral:span, layer=cat, key=NP, match=match:eq}" +
-    //								"]}" +
-    //							"], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +
-    //						"]}," +
-    //						"{@type=koral:span, layer=cat, key=DP, match=match:eq}" +
-    //					"], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}" +
-    //				"}";
-    //		aqlt = new AqlTree(query);
-    //		map = aqlt.getRequestMap().get("query").toString();
-    //		assertEquals(dom2.replaceAll(" ", ""), map.replaceAll(" ", ""));
-    //	}
-    //	
-    //	@Test
-    //	public void testPointingRelations() throws Exception {
-    //		query = "node & node & #2 ->coref[val=\"true\"] #1";
-    //		String dom1 = 
-    //				"{@type=koral:group, operation=operation:relation, operands=[" +
-    //						"{@type=koral:span}," +
-    //						"{@type=koral:span}" +
-    //				"], relation={@type=koral:relation, wrap={@type=koral:term, layer=coref, key=true, match=match:eq}}" +
-    //				"}";
-    //		aqlt = new AqlTree(query);
-    //		map = aqlt.getRequestMap().get("query").toString();
-    //		assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));
-    //		
-    //		query = "node & node & #2 ->mate/coref[val=\"true\"] #1";
-    //		String dom2 = 
-    //				"{@type=koral:group, operation=operation:relation, operands=[" +
-    //						"{@type=koral:span}," +
-    //						"{@type=koral:span}" +
-    //				"], relation={@type=koral:relation, wrap={@type=koral:term, foundry=mate, layer=coref, key=true, match=match:eq}}" +
-    //				"}";
-    //		aqlt = new AqlTree(query);
-    //		map = aqlt.getRequestMap().get("query").toString();
-    //		assertEquals(dom2.replaceAll(" ", ""), map.replaceAll(" ", ""));
-    //	}
-
     @Test
     public void testSequence () throws Exception {
         query = "tok=\"der\" & tok=\"die\" & #1 . #2";
diff --git a/src/test/java/de/ids_mannheim/korap/query/test/annis/DominanceTests.java b/src/test/java/de/ids_mannheim/korap/query/test/annis/DominanceTests.java
new file mode 100644
index 0000000..b36f6e4
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/query/test/annis/DominanceTests.java
@@ -0,0 +1,272 @@
+package de.ids_mannheim.korap.query.test.annis;

+

+import static org.junit.Assert.assertEquals;

+

+import java.io.IOException;

+

+import org.junit.Test;

+

+import com.fasterxml.jackson.core.JsonProcessingException;

+import com.fasterxml.jackson.databind.JsonNode;

+import com.fasterxml.jackson.databind.ObjectMapper;

+

+import de.ids_mannheim.korap.query.serialize.QuerySerializer;

+

+public class DominanceTests {

+    private String query;

+    private QuerySerializer qs = new QuerySerializer();

+    private ObjectMapper mapper = new ObjectMapper();

+    private JsonNode res;

+

+    @Test

+    public void testDominanceWithArbitrarySpans ()

+            throws JsonProcessingException, IOException {

+        query = "node > node";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+        //        assertEquals("koral:group", res.at("/query/@type").asText());

+        //        assertEquals("operation:relation", res.at("/query/operation").asText());

+        //        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+        //        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());

+        //        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+        //        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+        //                .asText());

+        //        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+    }

+

+

+    @Test

+    public void testDominanceWithAnnotation1 ()

+            throws JsonProcessingException, IOException {

+        query = "node > cnx/c=\"np\"";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+        //        assertEquals("koral:group", res.at("/query/@type").asText());

+        //        assertEquals("operation:relation", res.at("/query/operation").asText());

+        //        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+        //        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());

+        //        assertEquals("np", res.at("/query/operands/1/key").asText());

+        //        assertEquals("c", res.at("/query/operands/1/layer").asText());

+        //        assertEquals("cnx", res.at("/query/operands/1/foundry").asText());

+        //        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+        //        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+        //                .asText());

+        //        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+    }

+

+

+    @Test

+    public void testDominanceWithAnnotation2 ()

+            throws JsonProcessingException, IOException {

+        query = "cnx/c=\"np\" > node";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+    

+    @Test

+    public void testDominanceWithReference ()

+            throws JsonProcessingException, IOException {

+        query = "cat=/NP/ & cat=/PP/ > #1";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+

+    @Test

+    public void testDominanceWithReference2 () throws JsonProcessingException,

+            IOException {

+        query = "node & node & #2 > #1";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+//        assertEquals("koral:group", res.at("/query/@type").asText());

+//        assertEquals("operation:relation", res.at("/query/operation").asText());

+//        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+//        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());

+//        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+//        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+//                .asText());

+//        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+    }

+    

+    @Test

+    public void testDominanceWithToken ()

+            throws JsonProcessingException, IOException {

+        query = "\"Mann\" & node & #2 > #1";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+//        assertEquals("koral:group", res.at("/query/@type").asText());

+//        assertEquals("operation:relation", res.at("/query/operation").asText());

+//        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+//        assertEquals("koral:token", res.at("/query/operands/1/@type").asText());

+//        assertEquals("Mann", res.at("/query/operands/1/wrap/key").asText());

+//        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+//        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+//                .asText());

+//        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+    }

+       

+    

+    @Test

+    public void testDominanceFollowedByAnnotations () throws JsonProcessingException,

+            IOException {

+        query = "#1 > #2 & cnx/cat=\"vp\" & cnx/cat=\"np\"";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+//        assertEquals("koral:group", res.at("/query/@type").asText());

+//        assertEquals("operation:relation", res.at("/query/operation").asText());

+//        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+//        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+//        assertEquals("vp", res.at("/query/operands/0/key").asText());

+//        assertEquals("c", res.at("/query/operands/0/layer").asText());

+//        assertEquals("cnx", res.at("/query/operands/0/foundry").asText());

+//        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());

+//        assertEquals("np", res.at("/query/operands/1/key").asText());

+//        assertEquals("c", res.at("/query/operands/1/layer").asText());

+//        assertEquals("cnx", res.at("/query/operands/1/foundry").asText());

+//        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+//        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+//                .asText());

+//        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+    }

+   

+    @Test

+    public void testIndirectDominance () throws JsonProcessingException,

+            IOException {

+        query = "node & node & #1 >2,4 #2";

+        qs.setQuery(query, "annis");

+//        res = mapper.readTree(qs.toJSON());

+//        assertEquals("koral:group", res.at("/query/@type").asText());

+//        assertEquals("operation:relation", res.at("/query/operation").asText());

+//        assertEquals("koral:span", res.at("/query/operands/0/@type").asText());

+//        assertEquals("koral:span", res.at("/query/operands/1/@type").asText());

+//        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+//        assertEquals(2, res.at("/query/relation/boundary/min").asInt());

+//        assertEquals(4, res.at("/query/relation/boundary/max").asInt());

+//        assertEquals("koral:term", res.at("/query/relation/wrap/@type")

+//                .asText());

+//        assertEquals("c", res.at("/query/relation/wrap/layer").asText());

+

+        query = "node & node & #1 >* #2";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+//        assertEquals(0, res.at("/query/relation/boundary/min").asInt());

+//        assertEquals(true, res.at("/query/relation/boundary/max")

+//                .isMissingNode());

+    }

+

+    

+    @Test

+    public void testDominanceWithType ()

+            throws JsonProcessingException, IOException {

+        query = "\"Mann\" & node & #2 >[func=\"SB\"] #1";  //coordinates the func=SB term and requires a "c"-layer term (consituency relation/dominance)

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+//        assertEquals("koral:relation", res.at("/query/relation/@type").asText());

+//        assertEquals("koral:termGroup", res.at("/query/relation/wrap/@type")

+//                .asText());

+//        assertEquals("relation:and", res.at("/query/relation/wrap/relation")

+//                .asText());

+//        assertEquals("c", res.at("/query/relation/wrap/operands/1/layer")

+//                .asText());

+//        assertEquals("func", res.at("/query/relation/wrap/operands/0/layer")

+//                .asText());

+//        assertEquals("SB", res.at("/query/relation/wrap/operands/0/key")

+//                .asText());

+    }

+    

+    @Test

+    public void testDominanceWithMultipleTypes ()

+            throws JsonProcessingException, IOException {

+        query = "corenlp/c=\"VP\" & corenlp/c=\"NP\" & #1 >[malt/d=\"PP\" malt/d=\"PN\"] #2";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+    

+    @Test

+    public void testMultipleDominance () throws JsonProcessingException,

+            IOException {

+        query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+        assertEquals("koral:group", res.at("/query/@type").asText());

+        assertEquals("operation:relation", res.at("/query/operation").asText());

+        assertEquals("koral:reference", res.at("/query/operands/0/@type")

+                .asText());

+        assertEquals("operation:focus", res.at("/query/operands/0/operation")

+                .asText());

+        assertEquals(129, res.at("/query/operands/0/classRef/0").asInt());

+        assertEquals("koral:group", res

+                .at("/query/operands/0/operands/0/@type").asText());

+        assertEquals("operation:relation",

+                res.at("/query/operands/0/operands/0/operation").asText());

+        assertEquals("koral:relation",

+                res.at("/query/operands/0/operands/0/relation/@type").asText());

+        assertEquals("c",

+                res.at("/query/operands/0/operands/0/relation/wrap/layer")

+                        .asText());

+        assertEquals("koral:span",

+                res.at("/query/operands/0/operands/0/operands/0/@type")

+                        .asText());

+        assertEquals("c",

+                res.at("/query/operands/0/operands/0/operands/0/layer")

+                        .asText());

+        assertEquals("CP", res

+                .at("/query/operands/0/operands/0/operands/0/key").asText());

+        assertEquals("koral:group",

+                res.at("/query/operands/0/operands/0/operands/1/@type")

+                        .asText());

+        assertEquals("operation:class",

+                res.at("/query/operands/0/operands/0/operands/1/operation")

+                        .asText());

+        assertEquals(129,

+                res.at("/query/operands/0/operands/0/operands/1/classOut")

+                        .asInt());

+        assertEquals(

+                "VP",

+                res.at("/query/operands/0/operands/0/operands/1/operands/0/key")

+                        .asText());

+    }

+

+    //      query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & #1 > #2 > #3";

+    //      String dom1 = 

+    //              "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                      "{@type=koral:reference, operation=operation:focus, classRef=[0], operands=[" +

+    //                          "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                              "{@type=koral:span, layer=cat, key=CP, match=match:eq}," +

+    //                              "{@type=koral:group, operation=operation:class, class=1, classOut=1, operands=[" +

+    //                                  "{@type=koral:span, layer=cat, key=VP, match=match:eq}" +

+    //                              "]}" +

+    //                          "], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +

+    //                      "]}," +

+    //                      "{@type=koral:span, layer=cat, key=NP, match=match:eq}" +

+    //              "], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}" +

+    //              "}";

+    //      aqlt = new AqlTree(query);

+    //      map = aqlt.getRequestMap().get("query").toString();

+    //      assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));

+    //      

+    //      query = "cat=\"CP\" & cat=\"VP\" & cat=\"NP\" & cat=\"DP\" & #1 > #2 > #3 > #4";

+    //      String dom2 = 

+    //              "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                      "{@type=koral:reference, operation=operation:focus, classRef=[1], operands=[" +

+    //                          "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                              "{@type=koral:reference, operation=operation:focus, classRef=[0], operands=[" +

+    //                                  "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                                      "{@type=koral:span, layer=cat, key=CP, match=match:eq}," +

+    //                                      "{@type=koral:group, operation=operation:class, class=1, classOut=1, operands=[" +

+    //                                          "{@type=koral:span, layer=cat, key=VP, match=match:eq}" +

+    //                                      "]}" +

+    //                                  "], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +

+    //                              "]}," +

+    //                              "{@type=koral:group, operation=operation:class, class=2, classOut=2, operands=[" +

+    //                                  "{@type=koral:span, layer=cat, key=NP, match=match:eq}" +

+    //                              "]}" +

+    //                          "], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}}" +

+    //                      "]}," +

+    //                      "{@type=koral:span, layer=cat, key=DP, match=match:eq}" +

+    //                  "], relation={@type=koral:relation, wrap={@type=koral:term, layer=c}}" +

+    //              "}";

+    //      aqlt = new AqlTree(query);

+    //      map = aqlt.getRequestMap().get("query").toString();

+    //      assertEquals(dom2.replaceAll(" ", ""), map.replaceAll(" ", ""));

+    //  }

+}

diff --git a/src/test/java/de/ids_mannheim/korap/query/test/annis/RelationTests.java b/src/test/java/de/ids_mannheim/korap/query/test/annis/RelationTests.java
new file mode 100644
index 0000000..5acb0bb
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/query/test/annis/RelationTests.java
@@ -0,0 +1,72 @@
+package de.ids_mannheim.korap.query.test.annis;

+

+import java.io.IOException;

+

+import org.junit.BeforeClass;

+import org.junit.Test;

+

+import com.fasterxml.jackson.core.JsonProcessingException;

+import com.fasterxml.jackson.databind.JsonNode;

+import com.fasterxml.jackson.databind.ObjectMapper;

+

+import de.ids_mannheim.korap.query.serialize.QuerySerializer;

+

+public class RelationTests {

+    private String query;

+

+    private QuerySerializer qs = new QuerySerializer();

+    private ObjectMapper mapper = new ObjectMapper();

+    private JsonNode res;

+

+    @Test

+    public void testLabelledRelationWithArbritraryNodes ()

+            throws JsonProcessingException, IOException {

+        query = "node & node & #1 ->malt/d=\"PP\" #2";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+    

+    @Test

+    public void testLabelledRelation ()

+            throws JsonProcessingException, IOException {

+        query = "corenlp/c=\"VP\" & corenlp/c=\"NP\" & #1 ->malt/d=\"PP\" #2";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+

+

+    @Test

+    public void testLabelledRelationWithType ()

+            throws JsonProcessingException, IOException {

+        query = "corenlp/c=\"VP\" & corenlp/c=\"NP\" & #1 ->malt/d=\"PP\"[func=\"SB\"] #2";

+        qs.setQuery(query, "annis");

+        res = mapper.readTree(qs.toJSON());

+    }

+

+    //  

+    //  @Test

+    //  public void testPointingRelations() throws Exception {

+    //      query = "node & node & #2 ->coref[val=\"true\"] #1";

+    //      String dom1 = 

+    //              "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                      "{@type=koral:span}," +

+    //                      "{@type=koral:span}" +

+    //              "], relation={@type=koral:relation, wrap={@type=koral:term, layer=coref, key=true, match=match:eq}}" +

+    //              "}";

+    //      aqlt = new AqlTree(query);

+    //      map = aqlt.getRequestMap().get("query").toString();

+    //      assertEquals(dom1.replaceAll(" ", ""), map.replaceAll(" ", ""));

+    //      

+    //      query = "node & node & #2 ->mate/coref[val=\"true\"] #1";

+    //      String dom2 = 

+    //              "{@type=koral:group, operation=operation:relation, operands=[" +

+    //                      "{@type=koral:span}," +

+    //                      "{@type=koral:span}" +

+    //              "], relation={@type=koral:relation, wrap={@type=koral:term, foundry=mate, layer=coref, key=true, match=match:eq}}" +

+    //              "}";

+    //      aqlt = new AqlTree(query);

+    //      map = aqlt.getRequestMap().get("query").toString();

+    //      assertEquals(dom2.replaceAll(" ", ""), map.replaceAll(" ", ""));

+    //  }

+

+}

diff --git a/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLComplexTest.java b/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLComplexTest.java
index 7a0ae47..60199bb 100644
--- a/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLComplexTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLComplexTest.java
@@ -17,9 +17,9 @@
  */
 public class FCSQLComplexTest {
 
-    String query;
-    String jsonLd;
-    List<Object> error;
+    private String query;
+    private String jsonLd;
+    private List<Object> error;
 
     // -------------------------------------------------------------------------
     // simple-query ::= '(' main_query ')' /* grouping */
diff --git a/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLQueryProcessorTest.java b/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLQueryProcessorTest.java
index 552867d..4876943 100644
--- a/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLQueryProcessorTest.java
+++ b/src/test/java/de/ids_mannheim/korap/query/test/fcsql/FCSQLQueryProcessorTest.java
@@ -20,12 +20,12 @@
  */
 public class FCSQLQueryProcessorTest {
 
-    static QuerySerializer qs = new QuerySerializer();
-    static ObjectMapper mapper = new ObjectMapper();
-    static JsonNode node;
-    String query;
-    String jsonLd;
-    List<Object> error;
+    private static QuerySerializer qs = new QuerySerializer();
+    private static ObjectMapper mapper = new ObjectMapper();
+    private static JsonNode node;
+    private String query;
+    private String jsonLd;
+    private List<Object> error;
 
     public static void runAndValidate(String query, String jsonLd)
             throws JsonProcessingException {