Merge branch 'master' of
ssh://margaretha@korap.ids-mannheim.de:29418/KorAP/Krill

Change-Id: I0304454410c7da7833aa7e5ecc1bb78486c47641
diff --git a/src/main/java/de/ids_mannheim/korap/KrillQuery.java b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
index b55cd43..af1db1d 100644
--- a/src/main/java/de/ids_mannheim/korap/KrillQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/KrillQuery.java
@@ -415,12 +415,20 @@
                 return this._operationRepetitionFromJson(json, operands);
 
             case "operation:relation":
-                if (!json.has("relation")) {
+                // if (!json.has("relType")) {
+                // throw new QueryException(717,
+                // "Missing relation node");
+                // }
+                if (json.has("relType"))
+                    return _operationRelationFromJson(operands,
+                            json.get("relType"));
+                else if (json.has("relation")) {
+                    return _operationRelationFromJson(operands,
+                            json.get("relation"));
+                }
+                else {
                     throw new QueryException(717, "Missing relation node");
                 }
-
-                return _operationRelationFromJson(operands,
-                        json.get("relation"));
                 /*throw new QueryException(765,
                   "Relations are currently not supported");*/
 
@@ -1339,6 +1347,7 @@
             if (rootValue.equals("true") || rootValue.equals("false")) {
 
                 // TODO: Here do not refer to 'tokens'!!!
+                // EM: what should it be? property?
                 return new SpanAttributeQueryWrapper(
                         new SpanSimpleQueryWrapper("tokens", "@root",
                                 Boolean.valueOf(rootValue)));
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
index e0b8dd6..131c4ec 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationMatchQuery.java
@@ -42,21 +42,27 @@
 
         checkVariables(relation, source, target);
         SpanFocusQuery sq = null;
-        // match source
+        SpanFocusQuery sq2 = null;
+        // match source and then target
         if (relationQuery.getDirection() == 0) {
             sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
                     operandQuery, true), relation.getTempTargetNum());
+            sq.setSorted(false);
+            sq.setMatchTemporaryClass(true);
+            
+            sq2 = new SpanFocusQuery(new SpanSegmentQuery(operand2Query, sq,
+                    true), relation.getTempClassNumbers());
         }
-        // match target
+        // match target and then source
         else {
             sq = new SpanFocusQuery(new SpanSegmentQuery(relationQuery,
                     operandQuery, true), relation.getTempSourceNum());
+            sq.setMatchTemporaryClass(true);
+            
+            sq2 = new SpanFocusQuery(new SpanSegmentQuery(sq,
+                    operand2Query, true), relation.getTempClassNumbers());
         }
-        sq.setSorted(false);
-        sq.setMatchTemporaryClass(true);
-
-        SpanFocusQuery sq2 = new SpanFocusQuery(new SpanSegmentQuery(sq,
-                operand2Query, true), relation.getTempClassNumbers());
+        
         sq2.setMatchTemporaryClass(true);
         sq2.setRemoveTemporaryClasses(true);
         sq2.setSorted(false);
@@ -85,8 +91,7 @@
         this.operandQuery = operand;
     }
 
-
-    public void checkVariables (SpanRelationQuery relation, SpanQuery operand,
+    public void checkVariables(SpanRelationQuery relation, SpanQuery operand,
             SpanQuery target) {
         checkVariables(relation, operand);
         if (target == null) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
index d62216b..61ec3db 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationQuery.java
@@ -23,7 +23,7 @@
  * prefix "<" or
  * ">". The direction of the angle bracket represents the direction of
  * the
- * corresponding relation. <br/><br/>
+ * corresponding relation. By default, the relation is set ">". <br/><br/>
  * 
  * This class provides two types of query:
  * <ol>
@@ -56,7 +56,7 @@
  * */
 public class SpanRelationQuery extends SimpleSpanQuery {
 
-    private int direction = 0;
+    private int direction = 0; // >
     private byte tempSourceNum = 1;
     private byte tempTargetNum = 2;
     private byte sourceClass;
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanWithAttributeQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanWithAttributeQuery.java
index ce08c62..edd22b4 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanWithAttributeQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanWithAttributeQuery.java
@@ -16,23 +16,27 @@
 import de.ids_mannheim.korap.query.spans.SpansWithAttribute;
 
 /**
+ * <p>
  * Enumeration of spans (e.g. element or relation spans) having some
  * specific attribute(s) or <em>not</em> having some attribute(s). It
  * is necessary that the spans have ids to be able to identify to
- * which span an attribute belongs. <br />
- * <br />
+ * which span an attribute belongs.
+ * </p>
  * 
+ * <p>
  * In the example below, the SpanWithAttributeQuery retrieves
  * <code>&lt;div&gt;</code> elements having attributes
  * <code>@:class=header</code>.
+ * </p>
+ * 
+ * <br/>
  * 
  * <pre>
- * SpanAttributeQuery saq = new SpanAttributeQuery(new
- * SpanTermQuery(new Term(
- * &quot;tokens&quot;, &quot;@:class=header&quot;)), true);
- * SpanWithAttributeQuery sq = new SpanWithAttributeQuery(new
- * SpanElementQuery(
- * &quot;tokens&quot;, &quot;div&quot;), saq, true);
+ * SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(new Term(
+ *         &quot;tokens&quot;, &quot;@:class=header&quot;)), true);
+ * <br/>
+ * SpanWithAttributeQuery sq = new SpanWithAttributeQuery(new SpanElementQuery(
+ *         &quot;tokens&quot;, &quot;div&quot;), saq, true);
  * </pre>
  * 
  * 
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
index 9049ddb..244c79d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/FocusSpans.java
@@ -91,15 +91,13 @@
         currentDoc = firstSpans.doc();
 
         this.query = query;
-        if (getSpanId() > 0) {
-            hasSpanId = true;
-        }
     }
 
 
     @Override
     public boolean next () throws IOException {
         matchPayload.clear();
+        spanId = 0;
         CandidateSpan cs;
         while (hasMoreSpans || candidateSpans.size() > 0) {
             if (isSorted) {
@@ -148,7 +146,38 @@
         matchEndPosition = cs.getEnd();
         matchDocNumber = cs.getDoc();
         matchPayload.addAll(cs.getPayloads());
-        setSpanId(cs.getSpanId());
+
+        if (firstSpans instanceof RelationSpans && classNumbers.size() == 1) {
+            RelationSpans relationSpans = (RelationSpans) firstSpans;
+            int direction = relationSpans.getDirection();
+
+            if (classNumbers.get(0) == relationSpans.getTempSourceNum()) {
+                if (direction == 0) {
+                    setSpanId(relationSpans.getLeftId());
+                }
+                else {
+                    setSpanId(relationSpans.getRightId());
+                }
+            }
+            else if (classNumbers.get(0) == relationSpans.getTempTargetNum()) {
+                if (direction == 0) {
+                    setSpanId(relationSpans.getRightId());
+                }
+                else {
+                    setSpanId(relationSpans.getLeftId());
+                }
+            }
+            // else {
+            // throw new
+            // IllegalArgumentException("Classnumber is not found.");
+            // }
+            if (spanId > 0) hasSpanId = true;
+         }
+        else if (cs.getSpanId() > 0) {
+            setSpanId(cs.getSpanId());
+            hasSpanId = true;
+         }
+
     }
 
 
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
index 34045fb..3db12a7 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/NextSpans.java
@@ -82,6 +82,7 @@
                 matchDocNumber = firstSpans.doc();
                 matchStartPosition = firstSpans.start();
                 matchEndPosition = matchList.get(0).getEnd();
+                spanId = matchList.get(0).getSpanId();
                 if (collectPayloads)
                     matchPayload.addAll(matchList.get(0).getPayloads());
                 matchList.remove(0);
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
index 572528e..42d391b 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/RelationSpans.java
@@ -194,46 +194,56 @@
             cs.setLeftEnd(cs.start + 1);
             cs.setRightStart(i);
             cs.setRightEnd(i + 1);
-            cs.setLeftId(bb.getShort(5)); // left id
-            cs.setRightId(bb.getShort(7)); // right id
-            if (length > 9) {
+            if (length > 5) {
+                cs.setLeftId(bb.getShort(5)); // left id
+                cs.setRightId(bb.getShort(7)); // right id
                 cs.setSpanId(bb.getShort(9)); // relation id
             }
         }
         else if (payloadTypeIdentifier == PayloadTypeIdentifier.TERM_TO_ELEMENT.value) { // length
             // 15
             cs.setLeftEnd(cs.start + 1);
-            cs.setRightStart(bb.getInt(1));
-            cs.setRightEnd(bb.getInt(5));
-            cs.setLeftId(bb.getShort(9)); // left id
-            cs.setRightId(bb.getShort(11)); // right id
-            if (length > 13) {
-                cs.setSpanId(bb.getShort(13)); // relation id
+            // 1-4 start element offset
+            // 5-8 end element offset
+            cs.setRightStart(bb.getInt(9));
+            cs.setRightEnd(bb.getInt(13));
+            if (length > 17) {
+                cs.setLeftId(bb.getShort(17)); // left id
+                cs.setRightId(bb.getShort(19)); // right id
+                cs.setSpanId(bb.getShort(21)); // relation id
             }
         }
         else if (payloadTypeIdentifier == PayloadTypeIdentifier.ELEMENT_TO_TERM.value) { // length
             // 15
-            cs.setEnd(bb.getInt(1));
+            // 1-4 start element offset
+            // 5-8 end element offset
+            cs.setEnd(bb.getInt(9));
             cs.setLeftEnd(cs.end);
-            i = bb.getInt(5);
+            i = bb.getInt(13);
             cs.setRightStart(i);
             cs.setRightEnd(i + 1);
-            cs.setLeftId(bb.getShort(9)); // left id
-            cs.setRightId(bb.getShort(11)); // right id
             if (length > 13) {
-                cs.setSpanId(bb.getShort(13)); // relation id
+                cs.setLeftId(bb.getShort(17)); // left id
+                cs.setRightId(bb.getShort(19)); // right id
+                cs.setSpanId(bb.getShort(21)); // relation id
             }
         }
         else if (payloadTypeIdentifier == PayloadTypeIdentifier.ELEMENT_TO_ELEMENT.value) {
             // length 19
-            cs.setEnd(bb.getInt(1));
+
+            // 1-4 start left-element offset
+            // 5-8 end left-element offset
+            // 9-12 start right-element offset
+            // 13-16 end right-element offset
+
+            cs.setEnd(bb.getInt(17));
             cs.setLeftEnd(cs.end);
-            cs.setRightStart(bb.getInt(5));
-            cs.setRightEnd(bb.getInt(9));
-            cs.setLeftId(bb.getShort(13)); // left id
-            cs.setRightId(bb.getShort(15)); // right id
+            cs.setRightStart(bb.getInt(21));
+            cs.setRightEnd(bb.getInt(25));
             if (length > 17) {
-                cs.setSpanId(bb.getShort(17)); // relation id
+                cs.setLeftId(bb.getShort(29)); // left id
+                cs.setRightId(bb.getShort(31)); // right id
+                cs.setSpanId(bb.getShort(33)); // relation id
             }
         }
 
@@ -362,4 +372,28 @@
         this.rightEnd = rightEnd;
     }
 
+    public byte getTempSourceNum() {
+        return tempSourceNum;
+    }
+
+    public void setTempSourceNum(byte tempSourceNum) {
+        this.tempSourceNum = tempSourceNum;
+    }
+
+    public byte getTempTargetNum() {
+        return tempTargetNum;
+    }
+
+    public void setTempTargetNum(byte tempTargetNum) {
+        this.tempTargetNum = tempTargetNum;
+    }
+
+    public int getDirection() {
+        return direction;
+    }
+
+    public void setDirection(int direction) {
+        this.direction = direction;
+    }
+
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
index 46e4b28..d6b5d12 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SegmentSpans.java
@@ -92,19 +92,16 @@
      * 
      * */
     protected int findMatch () {
-        RelationSpans s1;
-        SimpleSpans s2;
-
         if (firstSpans.start() == secondSpans.start()
                 && firstSpans.end() == secondSpans.end()) {
 
             if (isRelation) {
-                s1 = (RelationSpans) firstSpans;
-                s2 = (SimpleSpans) secondSpans;
+                RelationSpans s1 = (RelationSpans) firstSpans;
+                SimpleSpans s2 = (SimpleSpans) secondSpans;
 
                 if (s2.hasSpanId) {
                     if (s1.getLeftId() == s2.getSpanId()) {
-                        setSpanId(s2.getSpanId());
+                        // setSpanId(s2.getSpanId());
                         setMatch();
                         return 0;
                     }
@@ -115,6 +112,22 @@
                 }
 
             }
+            else if (firstSpans instanceof FocusSpans
+                    && secondSpans instanceof SimpleSpans) {
+                SimpleSpans s1 = (SimpleSpans) firstSpans;
+                SimpleSpans s2 = (SimpleSpans) secondSpans;
+
+                if (s1.hasSpanId && s2.hasSpanId) {
+                    if (s1.getSpanId() == s2.getSpanId()) {
+                        setSpanId(s2.getSpanId());
+                        hasSpanId = true;
+                    }
+                }
+                else {
+                    setMatch();
+                    return 0;
+                }
+            }
             else {
                 setMatch();
                 return 0;
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
index 147f9ed..30e57ef 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
@@ -160,6 +160,7 @@
     @Override
     public boolean next () throws IOException {
         isStartEnumeration = false;
+        matchPayload.clear();
         if (referentSpans == null) { // only one (positive) attribute
             return advanceAttribute();
         }
@@ -179,6 +180,9 @@
                 this.matchEndPosition = referentSpans.end();
                 this.matchPayload = referentSpans.getPayload();
                 this.spanId = referentSpans.getSpanId();
+                if (this.spanId > 0) {
+                    hasSpanId = true;
+                }
                 hasMoreSpans = referentSpans.next();
                 return true;
             }
@@ -210,7 +214,7 @@
                 this.matchDocNumber = referentSpans.doc();
                 this.matchStartPosition = referentSpans.start();
                 this.matchEndPosition = referentSpans.end();
-                this.matchPayload = referentSpans.getPayload();
+                this.matchPayload.addAll(referentSpans.getPayload());
                 this.spanId = referentSpans.getSpanId();
 
                 if (attributeList.size() > 0)
@@ -417,7 +421,12 @@
         for (AttributeSpans as : notAttributeList) {
             cost += as.cost();
         }
-        return referentSpans.cost() + cost;
+
+        if (referentSpans != null)
+            return referentSpans.cost() + cost;
+        else
+            return cost;
+
     }
 
 }
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
index a9d5534..f1aeb02 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestReferenceIndex.java
@@ -72,13 +72,13 @@
 
         kr = ki.search(ref, (short) 10);
         /*
-        for (Match km : kr.getMatches()) {
+         * for (Match km : kr.getMatches()) {
+         * 
+         * System.out.println(km.getStartPos() + "," + km.getEndPos()
+         * + " " + km.getSnippetBrackets()); }
+         * System.out.println(kr.getTotalResults());
+         */
 
-        	System.out.println(km.getStartPos() + "," + km.getEndPos() + " "
-        			+ km.getSnippetBrackets());
-        }
-        System.out.println(kr.getTotalResults());
-        */
         assertEquals(
                 "spanReference(spanDistance(focus(1: focus(#[1,2]spanSegment("
                         + "focus(#1: spanSegment(spanRelation(base:<:child-of), focus(2: spanNext("
@@ -103,12 +103,12 @@
         // .{0,2} #3 & #3 -> #2
 
         assertEquals(
-                "spanReference(focus(#[1,2]spanSegment(focus(#2: "
+                "spanReference(focus(#[1,2]spanSegment({2: <tokens:prp />}, focus(#2: "
                         + "spanSegment(spanRelation(tokens:>:stanford/d:tag), "
                         + "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, "
                         + "{2: <tokens:prp />}, [(w[1:2], notOrdered, notExcluded)])), "
-                        + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))), "
-                        + "{2: <tokens:prp />})), 2)", sq.toString());
+                        + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)]))))"
+                        + ")), 2)", sq.toString());
 
         SpanElementQuery seq1 = new SpanElementQuery("tokens", "vb");
         // new SpanTermQuery(new Term("tokens", "c:vb"));
@@ -195,11 +195,13 @@
         // #3 & #3 ->stanford/d #2 & #1 ->stanford #3' annis
         // without layer=c and + relation key
         assertEquals(
-                "spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
-                        + "focus(1: spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
-                        + "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, {2: <tokens:prp />}, "
-                        + "[(w[1:2], notOrdered, notExcluded)])), {3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))), "
-                        + "{2: <tokens:prp />})), 2)))), {3: <tokens:nn />})), 3)",
+                "spanReference(focus(#[1,2]spanSegment({3: <tokens:nn />}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+                        + "focus(1: spanReference(focus(#[1,2]spanSegment({2: <tokens:prp />}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+                        + "focus(3: spanDistance(focus(1: spanDistance({1: <tokens:vb />}, "
+                        + "{2: <tokens:prp />}, [(w[1:2], notOrdered, notExcluded)])), "
+                        + "{3: <tokens:nn />}, [(w[1:3], notOrdered, notExcluded)])))))), 2)))))), 3)",
                 sq.toString());
         kr = ki.search(sq, (short) 10);
         // for (Match km : kr.getMatches()) {
@@ -247,14 +249,14 @@
                         + "<>:nn$<b>64<i>0<i>12<i>1<b>0<s>3|"
                         + "<>:np$<b>64<i>0<i>13<i>1<b>0<s>2|"
                         + "<>:s$<b>64<i>0<i>37<i>4<b>0<s>1|"
-                        + "<:stanford/d:tag$<b>32<i>1<s>3<s>1]"
+                        + "<:stanford/d:tag$<b>32<i>1<s>3<s>1<s>0]"
 
                         + "[(14-19)s:treat|_1$<i>14<i>19|"
                         + "<>:vb$<b>64<i>14<i>19<i>2<b>0<s>1|"
                         + "<>:vp$<b>64<i>14<i>36<i>4<b>0<s>2|"
-                        + ">:stanford/d:tag$<b>32<i>0<s>1<s>3|"
-                        + ">:stanford/d:tag$<b>32<i>3<s>1<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>4<s>1<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>0<s>1<s>3<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>3<s>1<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>4<s>1<s>1<s>0]"
 
                         + "[(20-22)s:my|_2$<i>20<i>22|"
                         + "<>:prp$<b>64<i>20<i>22<i>3<b>0<s>1|"
@@ -262,7 +264,7 @@
 
                         + "[(23-31)s:daughter|_3$<i>23<i>31|"
                         + "<>:nn$<b>64<i>23<i>31<i>4<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>2<s>1<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>2<s>1<s>1<s>0]"
 
                         + "[(32-36)s:well|_4$<i>32<i>36|"
                         + "<>:rb$<b>64<i>32<i>36<i>5<b>0<s>1|"
@@ -282,14 +284,14 @@
                         + "<>:nn$<b>64<i>0<i>12<i>1<b>0<s>3|"
                         + "<>:np$<b>64<i>0<i>13<i>1<b>0<s>2|"
                         + "<>:s$<b>64<i>0<i>37<i>5<b>0<s>1|"
-                        + "<:stanford/d:tag$<b>32<i>1<s>3<s>1]"
+                        + "<:stanford/d:tag$<b>32<i>1<s>3<s>1<s>0]"
 
                         + "[(14-19)s:treat|_1$<i>14<i>19|"
                         + "<>:vb$<b>64<i>14<i>19<i>2<b>0<s>1|"
                         + "<>:vp$<b>64<i>14<i>36<i>5<b>0<s>2|"
-                        + ">:stanford/d:tag$<b>32<i>0<s>1<s>2|"
-                        + ">:stanford/d:tag$<b>32<i>3<s>1<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>4<s>1<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>0<s>1<s>2<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>3<s>1<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>4<s>1<s>1<s>0]"
 
                         + "[(20-22)s:my|_2$<i>20<i>22|"
                         + "<>:prp$<b>64<i>20<i>22<i>3<b>0<s>1|"
@@ -297,7 +299,7 @@
 
                         + "[(23-31)s:daughter|_3$<i>23<i>31|"
                         + "<>:nn$<b>64<i>23<i>31<i>4<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>2<s>21<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>2<s>21<s>1<s>0]"
 
                         + "[(32-36)s:well|_4$<i>32<i>36|"
                         + "<>:rb$<b>64<i>32<i>36<i>5<b>0<s>1|"
@@ -319,10 +321,10 @@
 
                         + "[(49-52)s:one|_8$<i>49<i>52|"
                         + "<>:nn$<b>64<i>49<i>52<i>9<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>5<s>1<s>3|"
-                        + ">:stanford/d:tag$<b>32<i>6<s>1<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>7<s>1<s>3|"
-                        + ">:stanford/d:tag$<b>32<i>10<s>1<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>5<s>1<s>3<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>6<s>1<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>7<s>1<s>3<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>10<s>1<s>1<s>0]"
 
                         + "[(53-57)s:that|_9$<i>53<i>57|"
                         + "<>:rp$<b>64<i>53<i>57<i>10<b>0<s>1|"
@@ -332,9 +334,9 @@
                         + "<>:vb$<b>64<i>58<i>63<i>11<b>0<s>1|"
                         + "<>:s$<b>64<i>58<i>96<i>18<b>0<s>2|"
                         + "<>:vp$<b>64<i>58<i>96<i>18<b>0<s>3|"
-                        + ">:stanford/d:tag$<b>32<i>9<s>1<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>12<s>1<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>15<s>1<s>33]"
+                        + ">:stanford/d:tag$<b>32<i>9<s>1<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>12<s>1<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>15<s>1<s>33<s>0]"
 
                         + "[(64-68)s:your|_11$<i>64<i>68|"
                         + "<>:prp$<b>64<i>64<i>68<i>12<b>0<s>1|"
@@ -342,7 +344,7 @@
 
                         + "[(69-75)s:master|_12$<i>69<i>75|"
                         + "<>:nn$<b>64<i>69<i>75<i>13<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>11<s>1<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>11<s>1<s>1<s>0]"
 
                         + "[(76-79)s:who|_13$<i>76<i>79|"
                         + "<>:rp$<b>64<i>76<i>79<i>14<b>0<s>1|"
@@ -356,9 +358,9 @@
                         + "[(84-88)s:hold|_15$<i>84<i>88|"
                         + "<>:vb$<b>64<i>84<i>88<i>16<b>0<s>2|"
                         + "<>:vp$<b>64<i>84<i>96<i>18<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>13<s>2<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>14<s>2<s>3|"
-                        + ">:stanford/d:tag$<b>32<i>17<s>2<s>1]"
+                        + ">:stanford/d:tag$<b>32<i>13<s>2<s>1<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>14<s>2<s>3<s>0|"
+                        + ">:stanford/d:tag$<b>32<i>17<s>2<s>1<s>0]"
 
                         + "[(89-91)s:so|_16$<i>89<i>91|"
                         + "<>:rb$<b>64<i>89<i>91<i>17<b>0<s>1|"
@@ -366,7 +368,7 @@
 
                         + "[(92-96)s:dear|_17$<i>92<i>96|"
                         + "<>:jj$<b>64<i>92<i>96<i>18<b>0<s>1|"
-                        + ">:stanford/d:tag$<b>32<i>16<s>1<s>1]");
+                        + ">:stanford/d:tag$<b>32<i>16<s>1<s>1<s>0]");
 
         return fd;
     }
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
index c63ac56..2c4ca89 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestRelationIndex.java
@@ -3,6 +3,7 @@
 import static org.junit.Assert.assertEquals;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 import org.apache.lucene.index.Term;
 import org.apache.lucene.search.spans.SpanQuery;
@@ -16,8 +17,10 @@
 import de.ids_mannheim.korap.query.SpanFocusQuery;
 import de.ids_mannheim.korap.query.SpanRelationMatchQuery;
 import de.ids_mannheim.korap.query.SpanRelationQuery;
+import de.ids_mannheim.korap.query.SpanSegmentQuery;
 import de.ids_mannheim.korap.query.SpanTermWithIdQuery;
 import de.ids_mannheim.korap.query.SpanWithAttributeQuery;
+import de.ids_mannheim.korap.response.Match;
 import de.ids_mannheim.korap.response.Result;
 
 /*
@@ -76,20 +79,20 @@
                 "base",
                 "ceccecdeed",
                 "[(0-1)s:c$<s>1|_0$<i>0<i>1"
-                        + "|>:xip/syntax-dep_rel$<b>32<i>6<s>1<s>1]"
+                        + "|>:xip/syntax-dep_rel$<b>32<i>6<s>1<s>1<s>0]"
                         + "[(1-2)s:e$<s>1|_1$<i>1<i>2|"
-                        + "<:xip/syntax-dep_rel$<b>32<i>9<s>1<s>1|"
-                        + ">:xip/syntax-dep_rel$<b>32<i>4<s>1<s>1]"
+                        + "<:xip/syntax-dep_rel$<b>32<i>9<s>1<s>1<s>0|"
+                        + ">:xip/syntax-dep_rel$<b>32<i>4<s>1<s>1<s>0]"
                         + "[(2-3)s:c|_2$<i>2<i>3]"
-                        + "[(3-4)s:c$<s>1|s:b$<s>2|_3$<i>3<i>4|<:xip/syntax-dep_rel$<b>32<i>9<s>1<s>1]"
-                        + "[(4-5)s:e$<s>1|s:d$<s>2|_4$<i>4<i>5|<:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1]"
+                        + "[(3-4)s:c$<s>1|s:b$<s>2|_3$<i>3<i>4|<:xip/syntax-dep_rel$<b>32<i>9<s>1<s>1<s>0]"
+                        + "[(4-5)s:e$<s>1|s:d$<s>2|_4$<i>4<i>5|<:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1<s>0]"
                         + "[(5-6)s:c|_5$<i>5<i>6]"
-                        + "[(6-7)s:d$<s>1|_6$<i>6<i>7|<:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1]"
+                        + "[(6-7)s:d$<s>1|_6$<i>6<i>7|<:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1<s>0]"
                         + "[(7-8)s:e|_7$<i>7<i>8]"
                         + "[(8-9)s:e|s:b|_8$<i>8<i>9]"
                         + "[(9-10)s:d$<s>1|_9$<i>9<i>10|"
-                        + ">:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1|"
-                        + ">:xip/syntax-dep_rel$<b>32<i>3<s>1<s>1]");
+                        + ">:xip/syntax-dep_rel$<b>32<i>1<s>1<s>1<s>0|"
+                        + ">:xip/syntax-dep_rel$<b>32<i>3<s>1<s>1<s>0]");
         return fd;
     }
 
@@ -101,8 +104,8 @@
                 "base",
                 "ceccecdeed",
                 "[(0-1)s:c$<s>2|<>:p$<b>64<i>0<i>3<i>3<b>0<s>1|_0$<i>0<i>1|"
-                        + ">:xip/syntax-dep_rel$<b>35<i>3<i>6<i>9<s>1<s>1<s>2|"
-                        + ">:xip/syntax-dep_rel$<b>33<i>6<i>9<s>2<s>1|"
+                        + ">:xip/syntax-dep_rel$<b>35<i>0<i>1<i>1<i>2<i>3<i>6<i>9<s>1<s>1<s>2|"
+                        + ">:xip/syntax-dep_rel$<b>33<i>1<i>2<i>6<i>9<s>2<s>1<s>0|"
                         + "@:func=subj$<b>18<s>2]"
                         + "[(1-2)s:e|_1$<i>1<i>2|<>:p$<b>64<i>1<i>3<i>3<b>0<s>1]"
                         + "[(2-3)s:c|_2$<i>2<i>3]"
@@ -110,13 +113,14 @@
                         + "[(4-5)s:e|s:d|_4$<i>4<i>5]"
                         + "[(5-6)s:c|_5$<i>5<i>6]"
                         + "[(6-7)s:d$<s>2|<>:p$<b>64<i>6<i>9<i>9<b>0<s>1|_6$<i>6<i>7|"
-                        + ">:xip/syntax-dep_rel$<b>34<i>9<i>9<s>1<s>1|"
-                        + "<:xip/syntax-dep_rel$<b>35<i>9<i>1<i>3<s>1<s>1<s>2|"
-                        + "<:xip/syntax-dep_rel$<b>34<i>9<i>1<s>1<s>2|"
-                        + "@:func=obj$<b>18<s>2]" + "[(7-8)s:e|_7$<i>7<i>8]"
+                        + ">:xip/syntax-dep_rel$<b>34<i>3<i>4<i>9<i>9<s>1<s>1<s>0|"
+                        + "<:xip/syntax-dep_rel$<b>35<i>3<i>4<i>4<i>5<i>9<i>1<i>3<s>1<s>1<s>2|"
+                        + "<:xip/syntax-dep_rel$<b>34<i>5<i>6<i>9<i>1<s>1<s>2<s>0|"
+                        + "@:func=obj$<b>18<s>2]"
+                        + "[(7-8)s:e|_7$<i>7<i>8]"
                         + "[(8-9)s:e|s:b|_8$<i>8<i>9]"
                         + "[(9-10)s:d$<s>1|_9$<i>9<i>10|<"
-                        + ":xip/syntax-dep_rel$<b>33<i>6<i>9<s>2<s>1]");
+                        + ":xip/syntax-dep_rel$<b>33<i>6<i>7<i>6<i>9<s>2<s>1<s>0]");
         return fd;
     }
 
@@ -128,67 +132,70 @@
                 "base",
                 "Ich kaufe die Blümen für meine Mutter.",
                 "[(0-3)s:Ich|_0$<i>0<i>3|pos:NN$<s>1|<>:s$<b>64<i>0<i>38<i>7<b>0<s>2|<>:np$<b>64<i>0<i>3<i>1<b>0<s>3|"
-                        + ">:child-of$<b>33<i>0<i>7<s>3<s>2<s>4|"
-                        + ">:child-of$<b>33<i>0<i>1<s>1<s>3|"
-                        + "<:child-of$<b>32<i>0<s>3<s>1|"
-                        + "<:child-of$<b>35<i>7<i>0<i>1<s>2<s>3|"
-                        + "<:child-of$<b>35<i>7<i>1<i>7<s>2<s>2|"
-                        + "<:dep$<b>32<i>0<s>1<s>1|"
-                        + "@:func=sbj$<b>18<i>7<s>4]"
-                        +
+                        + ">:child-of$<b>33<i>0<i>38<i>0<i>7<s>3<s>2<s>4|"
+                        + ">:child-of$<b>33<i>0<i>3<i>0<i>1<s>1<s>3<s>0|"
+                        + "<:child-of$<b>32<i>0<s>3<s>1<s>0|"
+                        + "<:child-of$<b>35<i>0<i>38<i>0<i>3<i>7<i>0<i>1<s>2<s>3<s>0|"
+                        + "<:child-of$<b>35<i>0<i>38<i>4<i>9<i>7<i>1<i>7<s>2<s>2<s>0|"
+                        + "<:dep$<b>32<i>0<s>1<s>1<s>0|"
+                        + "@:func=sbj$<b>18<i>7<s>4|" // attribute belongs to a relation
+                        + "@:case=nominative$<b>18<i>1<s>3]" // attribute belongs to a relation node
 
-                        "[(1-2)s:kaufe|_1$<i>4<i>9|pos:V$<s>1|<>:vp$<b>64<i>4<i>38<i>7<b>0<s>2|"
-                        + ">:child-of$<b>35<i>7<i>0<i>7<s>2<s>2|"
-                        + ">:child-of$<b>33<i>1<i>7<s>2<s>7|"
-                        + "<:child-of$<b>34<i>7<i>2<s>2<s>1|"
-                        + "<:child-of$<b>35<i>7<i>2<i>7<s>2<s>4|"
-                        + ">:dep$<b>32<i>0<s>1<s>1|"
-                        + ">:dep$<b>32<i>3<s>1<s>1]"
-                        +
+                        + "[(1-2)s:kaufe|_1$<i>4<i>9|pos:V$<s>1|<>:vp$<b>64<i>4<i>38<i>7<b>0<s>2|"
+                        + ">:child-of$<b>35<i>4<i>38<i>0<i>38<i>7<i>0<i>7<s>2<s>2<s>0|"
+                        + ">:child-of$<b>33<i>4<i>9<i>1<i>7<s>2<s>7<s>0|"
+                        + "<:child-of$<b>34<i>4<i>38<i>7<i>2<s>2<s>1<s>0|"
+                        + "<:child-of$<b>35<i>4<i>38<i>10<i>38<i>7<i>2<i>7<s>2<s>4<s>0|"
+                        + ">:dep$<b>32<i>0<s>1<s>1<s>0|"
+                        + ">:dep$<b>32<i>3<s>1<s>1<s>0]"                        
 
-                        "[(2-3)s:die|_2$<i>10<i>13|pos:ART$<s>1|tt:DET$<s>2|"
+                        + "[(2-3)s:die|_2$<i>10<i>13|pos:ART$<s>1|tt:DET$<s>2|"
                         + "<>:np$<b>64<i>10<i>20<i>4<b>0<s>3|<>:np$<b>64<i>10<i>38<i>7<b>0<s>4|"
-                        + ">:child-of$<b>35<i>4<i>2<i>7<s>3<s>4|"
-                        + ">:child-of$<b>33<i>2<i>4<s>1<s>3|"
-                        + ">:child-of$<b>35<i>7<i>1<i>7<s>4<s>2|"
-                        + "<:child-of$<b>34<i>4<i>2<s>3<s>1|"
-                        + "<:child-of$<b>34<i>4<i>3<s>3<s>1|"
-                        + "<:child-of$<b>35<i>7<i>2<i>4<s>4<s>3|"
-                        + "<:child-of$<b>35<i>7<i>4<i>7<s>4<s>2|"
-                        + ">:parent-of$<b>35<i>7<i>4<i>7<s>4<s>2|"
+                        + ">:child-of$<b>35<i>10<i>24<i>10<i>38<i>4<i>2<i>7<s>3<s>4<s>0|"
+
+                        + ">:child-of$<b>33<i>10<i>24<i>2<i>4<s>1<s>3<s>0|"
+
+                        + ">:child-of$<b>35<i>10<i>38<i>4<i>38<i>7<i>1<i>7<s>4<s>2<s>0|"
+                        + "<:child-of$<b>34<i>10<i>24<i>4<i>2<s>3<s>1<s>0|"
+                        + "<:child-of$<b>34<i>10<i>24<i>4<i>3<s>3<s>1<s>0|"
+                        + "<:child-of$<b>35<i>10<i>38<i>10<i>24<i>7<i>2<i>4<s>4<s>3<s>0|"
+                        + "<:child-of$<b>35<i>10<i>38<i>21<i>38<i>7<i>4<i>7<s>4<s>2<s>0|"
+                        + ">:parent-of$<b>35<i>10<i>38<i>21<i>38<i>7<i>4<i>7<s>4<s>2<s>0|"
                         + "<:dep$<b>32<i>3<s>1<s>1<s>3|"
-                        + "@:func=head$<b>18<i>4<s>3]"
+                        + "@:func=head$<b>18<i>4<s>3|"
+                        + "@:case=accusative$<b>18<i>4<s>3|" // attribute belongs to a relation node
+                        + "@:case=accusative$<b>18<i>7<s>2]" // attribute belongs to a relation node
 
                         + "[(3-4)s:Blümen|_3$<i>14<i>20|pos:NN$<s>1|"
-                        + ">:child-of$<b>33<i>2<i>4<s>1<s>3|"
-                        + "<:dep$<b>32<i>1<s>1<s>1|"
+                        + ">:child-of$<b>33<i>10<i>24<i>2<i>4<s>1<s>3<s>0|"
+                        + "<:dep$<b>32<i>1<s>1<s>1<s>0|"
                         + ">:dep$<b>32<i>2<s>1<s>1<s>2|"
-                        + ">:dep$<b>32<i>4<s>1<s>1|"
+                        + ">:dep$<b>32<i>4<s>1<s>1<s>0|"
                         + "@:func=obj$<b>18<i>4<s>2]"
 
-
                         + "[(4-5)s:für|_4$<i>21<i>24|pos:PREP$<s>1|<>:pp$<b>64<i>21<i>38<i>7<b>0<s>2|"
-                        + ">:child-of$<b>33<i>4<i>7<s>1<s>2|"
-                        + ">:child-of$<b>35<i>7<i>2<i>7<s>2<s>4|"
-                        + "<:child-of$<b>34<i>7<i>5<s>2<s>1|"
-                        + "<:child-of$<b>35<i>7<i>5<i>7<s>2<s>2|"
-                        + "<:dep$<b>32<i>3<s>1<s>1|"
-                        + ">:dep$<b>32<i>6<s>1<s>1]"
-                        +
+                        + ">:child-of$<b>33<i>21<i>38<i>4<i>7<s>1<s>2<s>0|"
+                        + ">:child-of$<b>35<i>21<i>38<i>10<i>38<i>7<i>2<i>7<s>2<s>4<s>0|"
+                        + "<:child-of$<b>34<i>21<i>38<i>7<i>5<s>2<s>1<s>0|"
+                        + "<:child-of$<b>35<i>21<i>38<i>25<i>38<i>7<i>5<i>7<s>2<s>2<s>0|"
+                        + "<:dep$<b>32<i>3<s>1<s>1<s>0|"
+                        + ">:dep$<b>32<i>6<s>1<s>1<s>0]"
 
-                        "[(5-6)s:meine|_5$<i>25<i>30|pos:ART$<s>1|<>:np$<b>64<i>25<i>38<i>7<b>0<s>2|"
-                        + ">:child-of$<b>33<i>5<i>7<s>1<s>2|"
-                        + ">:child-of$<b>35<i>7<i>4<i>7<s>2<s>2|"
-                        + "<:child-of$<b>34<i>7<i>5<s>2<s>1|"
-                        + "<:child-of$<b>34<i>7<i>6<s>2<s>1|"
-                        + "<:dep$<b>32<i>6<s>1<s>1<s>3|"
-                        + "@:func=head$<b>18<i>7<s>3]"
+                        + "[(5-6)s:meine|_5$<i>25<i>30|pos:ART$<s>1|<>:np$<b>64<i>25<i>38<i>7<b>0<s>2|"
+
+                        + ">:child-of$<b>33<i>25<i>38<i>5<i>7<s>1<s>2<s>0|"
+
+                        + ">:child-of$<b>35<i>25<i>38<i>21<i>38<i>7<i>4<i>7<s>2<s>2<s>0|"
+                        + "<:child-of$<b>34<i>25<i>38<i>7<i>5<s>2<s>1<s>0|"
+                        + "<:child-of$<b>34<i>25<i>38<i>7<i>6<s>2<s>1<s>0|"
+                        + "<:dep$<b>32<i>6<s>1<s>1<s>3<s>0|"
+                        + "@:func=head$<b>18<i>7<s>3|"
+                        + "@:case=accusative$<b>18<i>7<s>2]" // attribute belongs to a relation node
 
                         + "[(6-7)s:Mutter.|_6$<i>31<i>38|pos:NN$<s>1|"
-                        + ">:child-of$<b>33<i>5<i>7<s>1<s>2|"
-                        + ">:dep$<b>32<i>5<s>1<s>1|"
-                        + "<:dep$<b>32<i>4<s>1<s>1]");
-
+                        + ">:child-of$<b>33<i>25<i>38<i>5<i>7<s>1<s>2<s>0|"
+                        + ">:dep$<b>32<i>5<s>1<s>1<s>0|"
+                        + "<:dep$<b>32<i>4<s>1<s>1<s>0]");
 
         return fd;
     }
@@ -316,15 +323,18 @@
         fq.setMatchTemporaryClass(true);
         fq.setRemoveTemporaryClasses(true);
         fq.setSorted(false);
-
+        // kr = ki.search(fq, (short) 20);
+        // for (Match m : kr.getMatches()) {
+        // System.out.println(m.getStartPos() + " " + m.getEndPos());
+        // }
+        
         SpanAttributeQuery saq = new SpanAttributeQuery(new SpanTermQuery(
                 new Term("base", "@:func=sbj")), true);
-
-        kr = ki.search(saq, (short) 20);
+        // kr = ki.search(saq, (short) 20);
 
         // child-of with attr func=sbj
         SpanWithAttributeQuery wq;
-        // wq = new SpanWithAttributeQuery(fq, saq, true);
+        wq = new SpanWithAttributeQuery(fq, saq, true);
         // kr = ki.search(wq, (short) 20);
         // assertEquals((long) 1, kr.getTotalResults());
         // assertEquals(0, kr.getMatch(0).getStartPos()); // token
@@ -576,23 +586,123 @@
         assertEquals(6, kr.getMatch(5).getEndPos());
         assertEquals(6, kr.getMatch(6).getStartPos());
         assertEquals(7, kr.getMatch(6).getEndPos());
+    }
 
-        // return all children of np that are articles
+    @Test
+    public void testCase9b() throws IOException {
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
 
         SpanTermWithIdQuery tiq = new SpanTermWithIdQuery(new Term("base",
                 "pos:ART"), true);
-        SpanClassQuery scq2 = new SpanClassQuery(tiq, (byte) 2);
+        SpanClassQuery scq1 = new SpanClassQuery(tiq, (byte) 1);
+        SpanElementQuery seq = new SpanElementQuery("base", "np");
+        SpanClassQuery scq2 = new SpanClassQuery(seq, (byte) 2);
 
-        srq = new SpanRelationQuery(new SpanTermQuery(new Term("base",
-                ">:child-of")), true);
-        rm = new SpanRelationMatchQuery(srq, scq2, scq1, true);
-        rv = new SpanFocusQuery(rm, (byte) 2);
+        SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+                new Term("base", ">:child-of")), true);
+        srq.setSourceClass((byte) 1);
+        srq.setTargetClass((byte) 2);
 
-        assertEquals(
-                "focus(2: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(base:>:child-of), {2: spanTermWithId(base:pos:ART)})), {1: <base:np />})))",
-                rv.toString());
+        SpanRelationMatchQuery rm = new SpanRelationMatchQuery(srq, scq1, scq2,
+                true);
+
+        // return all nps whose children are articles
+        SpanFocusQuery rv = new SpanFocusQuery(rm, (byte) 2);
+        rv.setSorted(false);
 
         kr = ki.search(rv, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(4, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // for (Match m : kr.getMatches()) {
+        // System.out.println(m.getStartPos() + " " + m.getEndPos());
+        // }
+    }
+
+    @Test
+    public void testCase9c() throws IOException {
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
+
+        SpanTermWithIdQuery tiq = new SpanTermWithIdQuery(new Term("base",
+                "pos:ART"), true);
+        SpanClassQuery scq1 = new SpanClassQuery(tiq, (byte) 1);
+
+        kr = ki.search(scq1, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(3, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(6, kr.getMatch(1).getEndPos());
+
+        SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+                new Term("base", ">:child-of")), true);
+        srq.setSourceClass((byte) 1);
+        srq.setTargetClass((byte) 2);
+
+        // match articles as relation sources (left side)
+        SpanSegmentQuery ssq1 = new SpanSegmentQuery(srq, scq1);
+        // NOTE: SegmentSpans can only always adopt the relation left
+        // side id.
+
+        kr = ki.search(ssq1, (short) 10);
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(3, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(6, kr.getMatch(1).getEndPos());
+
+        // return all parents of articles
+        SpanFocusQuery sfq = new SpanFocusQuery(ssq1, (byte) 2);
+        sfq.setSorted(false);
+
+        kr = ki.search(sfq, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(4, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        SpanElementQuery seq = new SpanElementQuery("base", "np");
+        SpanClassQuery scq2 = new SpanClassQuery(seq, (byte) 2);
+
+        kr = ki.search(scq2, (short) 10);
+        assertEquals((long) 4, kr.getTotalResults());
+        assertEquals(0, kr.getMatch(0).getStartPos());
+        assertEquals(1, kr.getMatch(0).getEndPos());
+        assertEquals(2, kr.getMatch(1).getStartPos());
+        assertEquals(4, kr.getMatch(1).getEndPos());
+        assertEquals(2, kr.getMatch(2).getStartPos());
+        assertEquals(7, kr.getMatch(2).getEndPos());
+        assertEquals(5, kr.getMatch(3).getStartPos());
+        assertEquals(7, kr.getMatch(3).getEndPos());
+
+        // match nps as relation targets (right side)
+        // return all nps whose children are articles
+        SpanSegmentQuery ssq2 = new SpanSegmentQuery(sfq, scq2);
+        kr = ki.search(ssq2, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(4, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // NOTE: cannot match the span id of the embedded relation
+        // target and the np. So the segment match here is only by
+        // positions. All nps in the same position will be matches.
+
+        // return the articles whos parents are nps
+        SpanFocusQuery sfq2 = new SpanFocusQuery(ssq2, (byte) 1);
+        sfq2.setSorted(false);
+        assertEquals("focus(1: spanSegment(focus(2: spanSegment({1: source:"
+                + "{2: target:spanRelation(base:>:child-of)}}, "
+                + "{1: spanTermWithId(base:pos:ART)})), "
+                + "{2: <base:np />}))", sfq2.toString());
+
+        kr = ki.search(sfq2, (short) 10);
 
         assertEquals((long) 2, kr.getTotalResults());
         assertEquals(2, kr.getMatch(0).getStartPos());
@@ -600,46 +710,203 @@
         assertEquals(5, kr.getMatch(1).getStartPos());
         assertEquals(6, kr.getMatch(1).getEndPos());
 
-        // return all nps whose children are articles
-        SpanFocusQuery sf = new SpanFocusQuery(rm, (byte) 1);
+        // for (Match m : kr.getMatches()) {
+        // System.out.println(m.getStartPos() + " " + m.getEndPos());
+        // }
+    }
+
+    /**
+     * Relation whose nodes have a specific attribute.
+     * 
+     * */
+    @Test
+    public void testCase10a() throws IOException {
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
+
+        SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:case=accusative")), true);
+        kr = ki.search(aq, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
+
+        SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+                new Term("base", ">:child-of")), true);
+        srq.setSourceClass((byte) 1);
+        srq.setTargetClass((byte) 2);
+        kr = ki.search(srq, (short) 20);
+        assertEquals((long) 13, kr.getTotalResults());
+
+        // Matching relation source node with an attribute
+        SpanFocusQuery sfq1 = new SpanFocusQuery(srq, (byte) 1);
+        SpanWithAttributeQuery swaq = new SpanWithAttributeQuery(sfq1, aq, true);
+        
+        kr = ki.search(swaq, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(4, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+        
+         // Returning relations whose source has a specific attribute
+         SpanFocusQuery fqr = new SpanFocusQuery(swaq,
+         srq.getTempClassNumbers());
+         fqr.setMatchTemporaryClass(true);
+         fqr.setRemoveTemporaryClasses(true);
+         assertEquals("focus(#[1,2]spanRelationWithAttribute(focus(1: "
+                + "{1: source:{2: target:spanRelation(base:>:child-of)}}), "
+                + "spanAttribute(base:@:case=accusative)))", fqr.toString());
+        
+         kr = ki.search(fqr, (short) 10);
+         assertEquals((long) 2, kr.getTotalResults());
+         assertEquals(2, kr.getMatch(0).getStartPos());
+         assertEquals(7, kr.getMatch(0).getEndPos());
+         assertEquals(4, kr.getMatch(1).getStartPos());
+         assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // Matching relation target nodes with an attribute
+        SpanFocusQuery sfq2 = new SpanFocusQuery(srq, (byte) 2);
+        sfq2.setSorted(false);
+        SpanWithAttributeQuery swaq2 = new SpanWithAttributeQuery(sfq2, aq,
+                true);
+
+        kr = ki.search(aq, (short) 20);
+
+        // for (Match m : kr.getMatches()) {
+        // System.out.println(m.getStartPos() + " " + m.getEndPos());
+        // }
+        kr = ki.search(swaq2, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // Returning relations whose target has a specific attribute
+        SpanFocusQuery fqr2 = new SpanFocusQuery(swaq2,
+                srq.getTempClassNumbers());
+        fqr2.setMatchTemporaryClass(true);
+        fqr2.setRemoveTemporaryClasses(true);
+
+        kr = ki.search(fqr2, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(7, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+    }
+
+    /**
+     * Relation whose nodes have a specific attribute. Alternative
+     * query (actually used in serialization)
+     * */
+    @Test
+    public void testCase10b() throws IOException {
+        ki.addDoc(createFieldDoc2());
+        ki.commit();
+
+        SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:case=accusative")), true);
+        kr = ki.search(aq, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
+
+        SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
+                new Term("base", ">:child-of")), true);
+        srq.setSourceClass((byte) 1);
+        srq.setTargetClass((byte) 2);
+        kr = ki.search(srq, (short) 20);
+        assertEquals((long) 13, kr.getTotalResults());
+
+        // Matching relation source node with an attribute
+        SpanWithAttributeQuery swaq = new SpanWithAttributeQuery(aq, true);
+        SpanSegmentQuery ssq = new SpanSegmentQuery(srq, swaq);
+
         assertEquals(
-                "focus(1: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(base:>:child-of), {2: spanTermWithId(base:pos:ART)})), {1: <base:np />})))",
-                sf.toString());
+                "spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+                        + "spanWithAttribute(spanAttribute(base:@:case=accusative)))",
+                ssq.toString());
 
-        kr = ki.search(sf, (short) 10);
-
+        kr = ki.search(ssq, (short) 10);
         assertEquals((long) 2, kr.getTotalResults());
         assertEquals(2, kr.getMatch(0).getStartPos());
         assertEquals(4, kr.getMatch(0).getEndPos());
         assertEquals(5, kr.getMatch(1).getStartPos());
         assertEquals(7, kr.getMatch(1).getEndPos());
 
+        // Matching relation target nodes with an attribute
+        // NOTE: swaq must be the first parameter
+        SpanFocusQuery sfq2 = new SpanFocusQuery(srq, (byte) 2);
+        sfq2.setSorted(false);
+        SpanSegmentQuery ssq2 = new SpanSegmentQuery(swaq, sfq2);
+
+        kr = ki.search(ssq2, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(7, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
+
+        // Matching specific relation source node with an attribute
+        SpanElementQuery seq = new SpanElementQuery("base", "np");
+        swaq = new SpanWithAttributeQuery(seq, aq, true);
+        ssq = new SpanSegmentQuery(srq, swaq);
+
+        assertEquals(
+                "spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+                        + "spanElementWithAttribute(<base:np />, "
+                        + "spanAttribute(base:@:case=accusative)))",
+                ssq.toString());
+
+        kr = ki.search(ssq, (short) 10);
+        assertEquals((long) 2, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
+        assertEquals(4, kr.getMatch(0).getEndPos());
+        assertEquals(5, kr.getMatch(1).getStartPos());
+        assertEquals(7, kr.getMatch(1).getEndPos());
     }
 
-
+    /**
+     * Matching both relation nodes whose a specific attribute
+     * */
     @Test
-    public void testCase10 () throws IOException {
+    public void testCase11() throws IOException {
         ki.addDoc(createFieldDoc2());
         ki.commit();
-        SpanElementQuery seq1 = new SpanElementQuery("base", "np");
-        SpanElementQuery seq2 = new SpanElementQuery("base", "np");
-        SpanClassQuery scq1 = new SpanClassQuery(seq1, (byte) 1);
-        SpanClassQuery scq2 = new SpanClassQuery(seq2, (byte) 2);
+
+        SpanAttributeQuery aq = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:case=accusative")), true);
+        kr = ki.search(aq, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
+
+        SpanAttributeQuery aq2 = new SpanAttributeQuery(new SpanTermQuery(
+                new Term("base", "@:case=accusative")), true);
+        kr = ki.search(aq2, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
 
         SpanRelationQuery srq = new SpanRelationQuery(new SpanTermQuery(
                 new Term("base", ">:child-of")), true);
-        SpanRelationMatchQuery rq = new SpanRelationMatchQuery(srq, scq2, true);
+        srq.setSourceClass((byte) 1);
+        srq.setTargetClass((byte) 2);
+        kr = ki.search(srq, (short) 20);
+        assertEquals((long) 13, kr.getTotalResults());
+        
+        SpanWithAttributeQuery swaq1 = new SpanWithAttributeQuery(aq, true);
+        SpanWithAttributeQuery swaq2 = new SpanWithAttributeQuery(aq2, true);
 
-        kr = ki.search(rq, (short) 10);
+        kr = ki.search(swaq1, (short) 10);
+        assertEquals((long) 3, kr.getTotalResults());
 
-        assertEquals((long) 4, kr.getTotalResults());
-        assertEquals(0, kr.getMatch(0).getStartPos());
+        SpanRelationMatchQuery srmq = new SpanRelationMatchQuery(srq, swaq1,
+                swaq2, true);
+        assertEquals(
+                "focus(#[1,2]spanSegment(spanWithAttribute(spanAttribute(base:@:case=accusative)), "
+                        + "focus(#2: spanSegment({1: source:{2: target:spanRelation(base:>:child-of)}}, "
+                        + "spanWithAttribute(spanAttribute(base:@:case=accusative))))))",
+                srmq.toString());
+        kr = ki.search(srmq, (short) 10);
+        assertEquals((long) 1, kr.getTotalResults());
+        assertEquals(2, kr.getMatch(0).getStartPos());
         assertEquals(7, kr.getMatch(0).getEndPos());
-        assertEquals(1, kr.getMatch(1).getStartPos());
-        assertEquals(7, kr.getMatch(1).getEndPos());
-        assertEquals(2, kr.getMatch(2).getStartPos());
-        assertEquals(7, kr.getMatch(2).getEndPos());
-        assertEquals(4, kr.getMatch(3).getStartPos());
-        assertEquals(7, kr.getMatch(3).getEndPos());
+
+        // for (Match m : kr.getMatches()) {
+        // System.out.println(m.getStartPos() + " " + m.getEndPos());
+        // }
     }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
index a5a65b4..b9ef7c4 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanReferenceQueryJSON.java
@@ -23,10 +23,12 @@
 
         // 'cat="V" & cat="NP" & cat="PP" & #2 . #1 & #1 ->dep #3 &
         // #3 . #2
+
         assertEquals(
-                "spanReference(spanNext({3: tokens:p:P}, focus(2: focus(#[1,2]spanSegment(focus(#2: "
-                        + "spanSegment(spanRelation(tokens:>:mate/d:HEAD), focus(1: spanNext("
-                        + "{2: tokens:p:V}, {1: <tokens:c:NP />})))), {3: tokens:p:P})))), 3)",
+                "spanReference(spanNext({3: tokens:p:P}, "
+                        + "focus(2: focus(#[1,2]spanSegment({3: tokens:p:P}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "focus(1: spanNext({2: tokens:p:V}, {1: <tokens:c:NP />})))))))), 3)",
                 sq.toString());
     }
 
@@ -42,9 +44,9 @@
         // 'cat="V" & cat="NP" & cat="PP" & #2 . #1 & #1 ->dep #3 &
         // #2 . #3
         assertEquals(
-                "spanReference(spanNext(focus(2: focus(#[1,2]spanSegment(focus(#2: "
-                        + "spanSegment(spanRelation(tokens:>:mate/d:HEAD), focus(1: spanNext("
-                        + "{2: tokens:p:V}, {1: <tokens:c:NP />})))), {3: tokens:p:P}))), "
+                "spanReference(spanNext(focus(2: focus(#[1,2]spanSegment({3: tokens:p:P}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "focus(1: spanNext({2: tokens:p:V}, {1: <tokens:c:NP />}))))))), "
                         + "{3: tokens:p:P}), 3)", sq.toString());
     }
 
@@ -59,10 +61,11 @@
         // 'cat="VP" & cat="NP" & cat="PP" & #1 . #2 & #2 . #3 & #1 .
         // #3 & #2 ->dep #1'
         assertEquals(
-                "spanReference(focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                "spanReference(focus(#[1,2]spanSegment({1: <tokens:c:VP />}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
                         + "focus(2: spanReference(spanNext(focus(1: spanNext(focus(2: spanNext({1: <tokens:c:VP />}, "
-                        + "{2: <tokens:c:NP />})), {3: <tokens:c:PP />})), {3: <tokens:c:PP />}), 3)))), "
-                        + "{1: <tokens:c:VP />})), 1)", sq.toString());
+                        + "{2: <tokens:c:NP />})), {3: <tokens:c:PP />})), {3: <tokens:c:PP />}), 3)))))), 1)",
+                sq.toString());
     }
 
 
@@ -70,6 +73,7 @@
     public void testDistanceReferences () throws QueryException {
 
         // ND: I don't understand what this query should be about ...
+        // EM: There was just a bug with multiple distance
         String filepath = getClass().getResource(
                 "/queries/reference/bug-multiple-distance-simple.jsonld")
                 .getFile();
@@ -88,14 +92,12 @@
 
         // 'cat="VP" & cat="NP" & cat="PP" & #1 . #2 & #2 . #3 & #1 .
         // #3 & #2 ->dep #1'
-        assertEquals("spanReference(" + "focus(" + "#[1,2]spanSegment("
-                + "focus(" + "#2: spanSegment("
-                + "spanRelation(tokens:>:stanford/d:tag), " + "focus("
-                + "2: spanDistance(" + "focus(" + "1: spanDistance("
-                + "<tokens:c:vb />, " + "{1: <tokens:c:prp />}, "
-                + "[(w[1:1], notOrdered, notExcluded)]" + ")" + "), "
-                + "{2: <tokens:c:nn />}, " + "[(w[1:3], ordered, notExcluded)]"
-                + ")" + ")" + ")" + "), " + "{1: <tokens:c:prp />}" + ")"
-                + "), 1" + ")", sq.toString());
+        assertEquals(
+                "spanReference(focus(#[1,2]spanSegment({1: <tokens:c:prp />}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:stanford/d:tag), "
+                        + "focus(2: spanDistance(focus(1: spanDistance(<tokens:c:vb />, "
+                        + "{1: <tokens:c:prp />}, [(w[1:1], notOrdered, notExcluded)])), "
+                        + "{2: <tokens:c:nn />}, [(w[1:3], ordered, notExcluded)])))))), 1)",
+                sq.toString());
     }
 }
diff --git a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
index b051509..7e1a4ab 100644
--- a/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
+++ b/src/test/java/de/ids_mannheim/korap/query/TestSpanRelationQueryJSON.java
@@ -12,6 +12,71 @@
 public class TestSpanRelationQueryJSON {
 
     @Test
+    public void testMatchAnyRelationSourceWithAttribute() throws QueryException {
+        String filepath = getClass().getResource(
+                "/queries/relation/any-source-with-attribute.json").getFile();
+        SpanQueryWrapper sqwi = getJSONQuery(filepath);
+        SpanQuery sq = sqwi.toQuery();
+
+        assertEquals(
+                "focus(#[1,2]spanSegment(<tokens:c:vp />, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "spanWithAttribute(spanAttribute(tokens:type:case:accusative))))))",
+                sq.toString());
+    }
+
+    @Test
+    public void testMatchAnyRelationTargetWithAttribute() throws QueryException {
+        String filepath = getClass().getResource(
+                "/queries/relation/any-target-with-attribute.json").getFile();
+        SpanQueryWrapper sqwi = getJSONQuery(filepath);
+        SpanQuery sq = sqwi.toQuery();
+        assertEquals(
+        // "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+        // +
+        // "<tokens:c:vp />)), spanWithAttribute(spanAttribute(tokens:type:case:accusative))))",
+        //
+                "focus(#[1,2]spanSegment(spanWithAttribute(spanAttribute(tokens:type:case:accusative)), " +
+                "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "<tokens:c:vp />))))",
+                sq.toString());
+
+        // System.out.println(sq.toString());
+    }
+
+    @Test
+    public void testMatchSpecificRelationSourceWithAttribute()
+            throws QueryException {
+        String filepath = getClass().getResource(
+                "/queries/relation/specific-source-with-attribute.json")
+                .getFile();
+        SpanQueryWrapper sqwi = getJSONQuery(filepath);
+        SpanQuery sq = sqwi.toQuery();
+
+        assertEquals("focus(#[1,2]spanSegment(<tokens:c:vp />, "
+                + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                + "spanElementWithAttribute(<tokens:c:np />, "
+                + "spanAttribute(tokens:type:case:accusative))))))",
+                sq.toString());
+    }
+
+    @Test
+    public void testMatchBothRelationNodeWithAttribute() throws QueryException {
+        String filepath = getClass().getResource(
+                "/queries/relation/both-operands-with-attribute.json")
+                .getFile();
+        SpanQueryWrapper sqwi = getJSONQuery(filepath);
+        SpanQuery sq = sqwi.toQuery();
+        assertEquals(
+                "focus(#[1,2]spanSegment(spanElementWithAttribute(<tokens:c: />, "
+                        + "spanAttribute(tokens:type:case:accusative)), "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "spanElementWithAttribute(<tokens:c: />, "
+                        + "spanAttribute(tokens:type:case:accusative))))))",
+                sq.toString());
+    }
+
+    @Test
     public void testMatchRelationSource () throws QueryException {
         //
         String filepath = getClass().getResource(
@@ -45,7 +110,8 @@
         SpanQueryWrapper sqwi = getJSONQuery(filepath);
         SpanQuery sq = sqwi.toQuery();
         assertEquals(
-                "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />)), <tokens:c:vp />))",
+                "focus(#[1,2]spanSegment(<tokens:c:vp />, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), <tokens:c:s />))))",
                 sq.toString());
     }
 
@@ -58,8 +124,8 @@
         SpanQueryWrapper sqwi = getJSONQuery(filepath);
         SpanQuery sq = sqwi.toQuery();
         assertEquals(
-                "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
-                        + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:@root)))), <tokens:c:vp />))",
+                "focus(#[1,2]spanSegment(<tokens:c:vp />, focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:@root))))))",
                 sq.toString());
     }
 
@@ -72,8 +138,8 @@
         SpanQueryWrapper sqwi = getJSONQuery(filepath);
         SpanQuery sq = sqwi.toQuery();
         assertEquals(
-                "focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
-                        + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:type:top)))), <tokens:c:vp />))",
+                "focus(#[1,2]spanSegment(<tokens:c:vp />, focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), "
+                        + "spanElementWithAttribute(<tokens:c:s />, spanAttribute(tokens:type:top))))))",
                 sq.toString());
     }
 
@@ -110,8 +176,8 @@
         SpanQueryWrapper sqwi = getJSONQuery(filepath);
         SpanQuery sq = sqwi.toQuery();
         assertEquals(
-                "focus(2: focus(#[1,2]spanSegment(focus(#2: spanSegment(spanRelation("
-                        + "tokens:>:mate/d:HEAD), {1: <tokens:c:s />})), {2: <tokens:c:np />})))",
+                "focus(2: focus(#[1,2]spanSegment({2: <tokens:c:np />}, "
+                        + "focus(#2: spanSegment(spanRelation(tokens:>:mate/d:HEAD), {1: <tokens:c:s />})))))",
                 sq.toString());
     }
 
diff --git a/src/test/resources/queries/reference/bug-multiple-distance.jsonld b/src/test/resources/queries/reference/bug-multiple-distance.jsonld
index de9bee6..dd8c419 100644
--- a/src/test/resources/queries/reference/bug-multiple-distance.jsonld
+++ b/src/test/resources/queries/reference/bug-multiple-distance.jsonld
@@ -83,7 +83,7 @@
         "classRef": [1]
       }
     ],
-    "relation": {
+    "relType": {
       "@type": "koral:relation",
       "wrap": {
         "@type": "koral:term",
diff --git a/src/test/resources/queries/reference/distance-multiple-references.jsonld b/src/test/resources/queries/reference/distance-multiple-references.jsonld
index 31ef098..f3d6c50 100644
--- a/src/test/resources/queries/reference/distance-multiple-references.jsonld
+++ b/src/test/resources/queries/reference/distance-multiple-references.jsonld
@@ -93,7 +93,7 @@
                             "classRef": [2]
                         }
                     ],
-                    "relation": {
+                    "relType": {
                         "@type": "koral:relation",
                         "wrap": {
                             "@type": "koral:term",
@@ -110,7 +110,7 @@
                 "classRef": [3]
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/reference/distance-reference.jsonld b/src/test/resources/queries/reference/distance-reference.jsonld
index cf23596..4db7b87 100644
--- a/src/test/resources/queries/reference/distance-reference.jsonld
+++ b/src/test/resources/queries/reference/distance-reference.jsonld
@@ -85,7 +85,7 @@
                 "classRef": [2]
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/reference/first-operand-reference.jsonld b/src/test/resources/queries/reference/first-operand-reference.jsonld
index 44792db..d83fa83 100644
--- a/src/test/resources/queries/reference/first-operand-reference.jsonld
+++ b/src/test/resources/queries/reference/first-operand-reference.jsonld
@@ -68,7 +68,7 @@
                             }]
                         }
                     ],
-                    "relation": {
+                    "relType": {
                         "@type": "koral:relation",
                         "wrap": {
                             "@type": "koral:term",
diff --git a/src/test/resources/queries/reference/multiple-references.jsonld b/src/test/resources/queries/reference/multiple-references.jsonld
index f94cfb5..8de4852 100644
--- a/src/test/resources/queries/reference/multiple-references.jsonld
+++ b/src/test/resources/queries/reference/multiple-references.jsonld
@@ -83,7 +83,7 @@
                 "classRef": [1]
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/reference/second-operand-reference.jsonld b/src/test/resources/queries/reference/second-operand-reference.jsonld
index 47388cc..0f170eb 100644
--- a/src/test/resources/queries/reference/second-operand-reference.jsonld
+++ b/src/test/resources/queries/reference/second-operand-reference.jsonld
@@ -63,7 +63,7 @@
                             }]
                         }
                     ],
-                    "relation": {
+                    "relType": {
                         "@type": "koral:relation",
                         "wrap": {
                             "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/any-source-with-attribute.json b/src/test/resources/queries/relation/any-source-with-attribute.json
new file mode 100644
index 0000000..8a4582d
--- /dev/null
+++ b/src/test/resources/queries/relation/any-source-with-attribute.json
@@ -0,0 +1,33 @@
+{
+    "query": {
+        "@type": "koral:group",
+        "operation": "operation:relation",
+        "operands": [
+            {
+                "@type": "koral:span",
+                "match": "match:eq",
+                "attr": {
+		            "@type": "koral:term",
+		            "layer": "type",
+		            "key": "case:accusative",
+		            "match": "match:eq"
+		        }           
+            },
+            {
+                "@type": "koral:span",
+                "layer": "c",
+                "key": "vp"
+            }
+        ],
+        "relType": {
+            "@type": "koral:relation",
+            "wrap": {
+                "@type": "koral:term",
+                "foundry": "mate",
+                "layer": "d",
+                "key": "HEAD"
+            }
+        }
+    },
+    "meta": {}
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/any-target-with-attribute.json b/src/test/resources/queries/relation/any-target-with-attribute.json
new file mode 100644
index 0000000..63fdd14
--- /dev/null
+++ b/src/test/resources/queries/relation/any-target-with-attribute.json
@@ -0,0 +1,33 @@
+{
+    "query": {
+        "@type": "koral:group",
+        "operation": "operation:relation",
+        "operands": [
+            {
+                "@type": "koral:span",
+                "layer": "c",
+                "key": "vp"
+            },
+            {
+                "@type": "koral:span",
+                "match": "match:eq",
+                "attr": {
+		            "@type": "koral:term",
+		            "layer": "type",
+		            "key": "case:accusative",
+		            "match": "match:eq"
+		        }           
+            }
+        ],
+        "relType": {
+            "@type": "koral:relation",
+            "wrap": {
+                "@type": "koral:term",
+                "foundry": "mate",
+                "layer": "d",
+                "key": "HEAD"
+            }
+        }
+    },
+    "meta": {}
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/both-operands-with-attribute.json b/src/test/resources/queries/relation/both-operands-with-attribute.json
new file mode 100644
index 0000000..f83118f
--- /dev/null
+++ b/src/test/resources/queries/relation/both-operands-with-attribute.json
@@ -0,0 +1,40 @@
+{
+    "query": {
+        "@type": "koral:group",
+        "operation": "operation:relation",
+        "operands": [
+            {
+                "@type": "koral:span",
+                "layer": "c",                
+                "match": "match:eq",
+                "attr": {
+		            "@type": "koral:term",
+		            "layer": "type",
+		            "key": "case:accusative",
+		            "match": "match:eq"
+		        }           
+            },
+            {
+                "@type": "koral:span",
+                "layer": "c",
+                "match": "match:eq",
+                 "attr": {
+		            "@type": "koral:term",
+		            "layer": "type",
+		            "key": "case:accusative",
+		            "match": "match:eq"
+		        }
+            }
+        ],
+        "relType": {
+            "@type": "koral:relation",
+            "wrap": {
+                "@type": "koral:term",
+                "foundry": "mate",
+                "layer": "d",
+                "key": "HEAD"
+            }
+        }
+    },
+    "meta": {}
+}
\ No newline at end of file
diff --git a/src/test/resources/queries/relation/focus-empty-both.json b/src/test/resources/queries/relation/focus-empty-both.json
index 1e9fa16..fb6aa83 100644
--- a/src/test/resources/queries/relation/focus-empty-both.json
+++ b/src/test/resources/queries/relation/focus-empty-both.json
@@ -24,7 +24,7 @@
                     }]
                 }
             ],
-            "relation": {
+            "relType": {
                 "@type": "koral:relation",
                 "wrap": {
                     "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/focus-empty-target.json b/src/test/resources/queries/relation/focus-empty-target.json
index 78ac125..e2fb447 100644
--- a/src/test/resources/queries/relation/focus-empty-target.json
+++ b/src/test/resources/queries/relation/focus-empty-target.json
@@ -27,7 +27,7 @@
                     }]
                 }
             ],
-            "relation": {
+            "relType": {
                 "@type": "koral:relation",
                 "wrap": {
                     "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/focus-source.json b/src/test/resources/queries/relation/focus-source.json
index 68d5ce4..0055911 100644
--- a/src/test/resources/queries/relation/focus-source.json
+++ b/src/test/resources/queries/relation/focus-source.json
@@ -22,7 +22,7 @@
                     }]
                 }
             ],
-            "relation": {
+            "relType": {
                 "@type": "koral:relation",
                 "wrap": {
                     "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/focus-target.json b/src/test/resources/queries/relation/focus-target.json
index 46282a8..3c36eb0 100644
--- a/src/test/resources/queries/relation/focus-target.json
+++ b/src/test/resources/queries/relation/focus-target.json
@@ -30,7 +30,7 @@
                     }]
                 }
             ],
-            "relation": {
+            "relType": {
                 "@type": "koral:relation",
                 "wrap": {
                     "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/match-source-and-target.json b/src/test/resources/queries/relation/match-source-and-target.json
index 860528f..9be7eb3 100644
--- a/src/test/resources/queries/relation/match-source-and-target.json
+++ b/src/test/resources/queries/relation/match-source-and-target.json
@@ -14,7 +14,7 @@
                 "key": "vp"
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/match-source.json b/src/test/resources/queries/relation/match-source.json
index 3ca5686..0f50094 100644
--- a/src/test/resources/queries/relation/match-source.json
+++ b/src/test/resources/queries/relation/match-source.json
@@ -12,7 +12,7 @@
                 "@type": "koral:token"             
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/match-target.json b/src/test/resources/queries/relation/match-target.json
index 7fe4ef0..26ea532 100644
--- a/src/test/resources/queries/relation/match-target.json
+++ b/src/test/resources/queries/relation/match-target.json
@@ -10,7 +10,7 @@
                 "key": "vp"                
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/operand-with-attribute.json b/src/test/resources/queries/relation/operand-with-attribute.json
index 570031c..a89855e 100644
--- a/src/test/resources/queries/relation/operand-with-attribute.json
+++ b/src/test/resources/queries/relation/operand-with-attribute.json
@@ -21,7 +21,7 @@
                 "key": "vp"
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/operand-with-property.json b/src/test/resources/queries/relation/operand-with-property.json
index 407c900..6540ae1 100644
--- a/src/test/resources/queries/relation/operand-with-property.json
+++ b/src/test/resources/queries/relation/operand-with-property.json
@@ -19,7 +19,7 @@
                 "key": "vp"
             }
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/relation-only.json b/src/test/resources/queries/relation/relation-only.json
index 8801184..7ada14a 100644
--- a/src/test/resources/queries/relation/relation-only.json
+++ b/src/test/resources/queries/relation/relation-only.json
@@ -6,7 +6,7 @@
             {"@type": "koral:token"},
             {"@type": "koral:token"}
         ],
-        "relation": {
+        "relType": {
             "@type": "koral:relation",
             "wrap": {
                 "@type": "koral:term",
diff --git a/src/test/resources/queries/relation/specific-source-with-attribute.json b/src/test/resources/queries/relation/specific-source-with-attribute.json
new file mode 100644
index 0000000..930e082
--- /dev/null
+++ b/src/test/resources/queries/relation/specific-source-with-attribute.json
@@ -0,0 +1,35 @@
+{
+    "query": {
+        "@type": "koral:group",
+        "operation": "operation:relation",
+        "operands": [
+            {
+                "@type": "koral:span",
+                "layer": "c",   
+                "key": "np",           
+                "match": "match:eq",
+                "attr": {
+		            "@type": "koral:term",
+		            "layer": "type",
+		            "key": "case:accusative",
+		            "match": "match:eq"
+		        }           
+            },
+            {
+                "@type": "koral:span",
+                "layer": "c",
+                "key": "vp"
+            }
+        ],
+        "relType": {
+            "@type": "koral:relation",
+            "wrap": {
+                "@type": "koral:term",
+                "foundry": "mate",
+                "layer": "d",
+                "key": "HEAD"
+            }
+        }
+    },
+    "meta": {}
+}
\ No newline at end of file