Updated AttributeSpans and SpanRelationQuery.
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
index 6382222..4d8d875 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/AttributeSpans.java
@@ -40,9 +40,7 @@
 
     private List<CandidateAttributeSpan> candidateList;
     private int currentDoc, currentPosition;
-	// private short referentId;
     private boolean isFinish;
-	// private int elementEnd;
 
     protected Logger logger = LoggerFactory.getLogger(AttributeSpans.class);
 
@@ -91,7 +89,6 @@
                 this.matchStartPosition = cs.getStart();
                 this.matchEndPosition = cs.getEnd();
 				this.setSpanId(cs.getSpanId()); // referentId
-				// this.setElementEnd(cs.getElementEnd());
                 candidateList.remove(0);
                 return true;
             } else {
@@ -135,56 +132,24 @@
         List<byte[]> payload = (List<byte[]>) firstSpans.getPayload();
         ByteBuffer wrapper = ByteBuffer.wrap(payload.get(0));
 
-        short spanId = wrapper.getShort(0);
-        int elementEnd = -1;
-        if (payload.get(0).length == 6) {
-            elementEnd = wrapper.getInt(2);
-        }
-        return new CandidateAttributeSpan(firstSpans, spanId, elementEnd);
+		short spanId;
+		int start = 0, end;
+
+		if (payload.get(0).length == 6) {
+			end = wrapper.getInt(0);
+			spanId = wrapper.getShort(4);
+			return new CandidateAttributeSpan(firstSpans, spanId, end);
+		}
+		else if (payload.get(0).length == 10) {
+			end = wrapper.getInt(4);
+			spanId = wrapper.getShort(8);
+			return new CandidateAttributeSpan(firstSpans, spanId, start, end);
+		}
+        
+		throw new NullPointerException("Missing element end in payloads.");
     }
 
     /**
-     * Return the span id to which an attribute span belongs, for instance a
-     * relation id or an element id.
-     * 
-     * @return a span id, for instance a relation id or an element id
-     */
-	// public short getReferentId() {
-	// return this.referentId;
-	// }
-
-    /**
-     * Sets the span id to which an attribute span belongs, for instance a
-     * relation id or an element id.
-     * 
-     * @param refId the span id to which an attribute span belongs, for
-     *        instance a relation id or an element id.
-     */
-	// public void setReferentId(short refId) {
-	// this.referentId = refId;
-	// }
-
-    /**
-     * Returns the end position of the element to which an attribute span
-     * belongs.
-     * 
-     * @return an element end position
-     */
-	// public int getElementEnd() {
-	// return elementEnd;
-	// }
-
-    /**
-     * Sets the end position of the element to which an attribute span belongs.
-     * 
-     * @param elementEnd the end position of the element to which an attribute
-     *        span belongs.
-     */
-	// public void setElementEnd(int elementEnd) {
-	// this.elementEnd = elementEnd;
-	// }
-
-    /**
      * Tells if the enumeration of the AttributeSpans has come to an end.
      * 
      * @return true if the enumeration has finished.
@@ -234,7 +199,6 @@
             Comparable<CandidateSpan> {
 
         private short spanId;
-		// private int elementEnd;
 
         /**
          * Construct a CandidateAttributeSpan based on the given span, spanId,
@@ -253,10 +217,17 @@
             super(span);
 			setSpanId(spanId);
 			this.end = elementEnd;
-			// setElementEnd(elementEnd);
         }
 
-        public void setSpanId(short spanId) {
+		public CandidateAttributeSpan(Spans span, short spanId,
+				int start, int end) throws IOException {
+			super(span);
+			setSpanId(spanId);
+			this.start = start;
+			this.end = end;
+		}
+
+		public void setSpanId(short spanId) {
             this.spanId = spanId;
         }
 
@@ -264,14 +235,6 @@
             return spanId;
         }
 
-		// public int getElementEnd() {
-		// return elementEnd;
-		// }
-		//
-		// public void setElementEnd(int elementEnd) {
-		// this.elementEnd = elementEnd;
-		// }
-
         @Override
         public int compareTo(CandidateSpan o) {
             CandidateAttributeSpan cs = (CandidateAttributeSpan) o;
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/CandidateSpan.java b/src/main/java/de/ids_mannheim/korap/query/spans/CandidateSpan.java
index ca1132d..ce930d4 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/CandidateSpan.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/CandidateSpan.java
@@ -21,6 +21,9 @@
     private CandidateSpan childSpan; // used for example for multiple distance
                                      // with unordered constraint
     protected short spanId;
+	private short leftId, rightId;
+	private int leftStart, leftEnd;
+	private int rightStart, rightEnd;
 
     /**
      * Constructs a CandidateSpan for the given Span.
@@ -233,7 +236,55 @@
         this.spanId = spanId;
     }
 
-    @Override
+	public short getLeftId() {
+		return leftId;
+	}
+
+	public void setLeftId(short leftId) {
+		this.leftId = leftId;
+	}
+
+	public short getRightId() {
+		return rightId;
+	}
+
+	public void setRightId(short rightId) {
+		this.rightId = rightId;
+	}
+
+	public int getLeftStart() {
+		return leftStart;
+	}
+
+	public void setLeftStart(int leftStart) {
+		this.leftStart = leftStart;
+	}
+
+	public int getLeftEnd() {
+		return leftEnd;
+	}
+
+	public void setLeftEnd(int leftEnd) {
+		this.leftEnd = leftEnd;
+	}
+
+	public int getRightStart() {
+		return rightStart;
+	}
+
+	public void setRightStart(int rightStart) {
+		this.rightStart = rightStart;
+	}
+
+	public int getRightEnd() {
+		return rightEnd;
+	}
+
+	public void setRightEnd(int rightEnd) {
+		this.rightEnd = rightEnd;
+	}
+
+	@Override
     public int compareTo(CandidateSpan o) {
         if (this.doc == o.doc) {
             if (this.getStart() == o.getStart()) {
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/RelationBaseSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/RelationBaseSpans.java
index 0f29fcb..7897308 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/RelationBaseSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/RelationBaseSpans.java
@@ -23,9 +23,11 @@
  */
 public abstract class RelationBaseSpans extends SpansWithId {
 
-    protected short leftId, rightId;
+	protected short leftId, rightId;
 	protected int leftStart, leftEnd;
-    protected int rightStart, rightEnd;
+	protected int rightStart, rightEnd;
+
+    public RelationBaseSpans(){};
 
     /**
      * Constructs RelationBaseSpans based on the given SpanWithIdQuery.
@@ -61,11 +63,27 @@
         this.leftId = leftId;
     }
 
-    /**
-     * Returns the id of the right hand side of the relation.
-     * 
-     * @return an id
-     */
+	public int getLeftStart() {
+		return leftStart;
+	}
+
+	public void setLeftStart(int leftStart) {
+		this.leftStart = leftStart;
+	}
+
+	public int getLeftEnd() {
+		return leftEnd;
+	}
+
+	public void setLeftEnd(int leftEnd) {
+		this.leftEnd = leftEnd;
+	}
+
+	/**
+	 * Returns the id of the right hand side of the relation.
+	 * 
+	 * @return an id
+	 */
     public short getRightId() {
         return rightId;
     }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/RelationPartSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/RelationPartSpans.java
deleted file mode 100644
index 03b2f9c..0000000
--- a/src/main/java/de/ids_mannheim/korap/query/spans/RelationPartSpans.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package de.ids_mannheim.korap.query.spans;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.lucene.index.AtomicReaderContext;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermContext;
-import org.apache.lucene.util.Bits;
-
-import de.ids_mannheim.korap.query.SpanRelationPartQuery;
-
-/**
- * This span enumeration returns the right part of relation spans whose left
- * part token/element positions matching the second spans, or vice versa.
- * 
- * All relations within a certain window, e.g element-based or token-
- * distance-based, are sorted to resolve reference within that window.
- * Resolution is limited only within a window.
- * 
- * @author margaretha
- * */
-public class RelationPartSpans extends RelationBaseSpans {
-
-    private RelationBaseSpans relationSpans;
-    private SpansWithId matcheeSpans;
-    private ElementSpans element; // element as the window
-    private List<CandidateRelationSpan> candidateRelations;
-
-    private boolean matchRight;
-    private boolean inverse;
-    private boolean hasMoreMatchees;
-
-    private int window; // number of tokens as the window
-
-    /**
-     * Constructs RelationPartSpans from the specified
-     * {@link SpanRelationPartQuery}.
-     * 
-     * @param query a SpanRelationPartQuery
-     * @param context
-     * @param acceptDocs
-     * @param termContexts
-     * @throws IOException
-     */
-    public RelationPartSpans(SpanRelationPartQuery query,
-            AtomicReaderContext context, Bits acceptDocs,
-            Map<Term, TermContext> termContexts) throws IOException {
-        super(query, context, acceptDocs, termContexts);
-        if (query.getElementQuery() != null) {
-            element = (ElementSpans) query.getElementQuery().getSpans(context,
-                    acceptDocs, termContexts);
-        } else {
-            window = query.getWindow();
-        }
-        relationSpans = (RelationBaseSpans) firstSpans;
-        matcheeSpans = (SpansWithId) secondSpans;
-        // hack
-        matcheeSpans.hasSpanId = true;
-
-        hasMoreMatchees = matcheeSpans.next();
-        hasMoreSpans = relationSpans.next() && hasMoreMatchees;
-        if (element != null) {
-            hasMoreSpans &= element.next();
-        }
-        candidateRelations = new ArrayList<CandidateRelationSpan>();
-        matchRight = query.isMatchRight();
-        inverse = query.isInverseRelation();
-    }
-
-    @Override
-    public boolean next() throws IOException {
-        isStartEnumeration = false;
-        matchPayload.clear();
-        return advance();
-    }
-
-    /**
-     * Advances to the next match, by setting the first candidate relation from
-     * candidateRelations list, if it is not empty. Otherwise, set the candidate
-     * list first based on element or token window.
-     * 
-     * @return
-     * @throws IOException
-     */
-    protected boolean advance() throws IOException {
-        while (candidateRelations.size() > 0 || hasMoreSpans) {
-            if (candidateRelations.size() > 0) {
-                setMatchSpan(candidateRelations.get(0));
-                candidateRelations.remove(0);
-                return true;
-            } else if (element != null) {
-                setCandidateList();
-            } else {
-                setCandidateListWithWindow();
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Sets the specified {@link CandidateRelationSpan} as the current match. If
-     * the match should be sorted by the right side positions of the original
-     * relation, then it should be inverted. In this case, the start and end
-     * positions of the original <em>right</em> side, will be set as the match
-     * <em>left</em> start and end positions, and vice versa.
-     * 
-     * @param relationSpan a CandidateRelationSpan
-     */
-    private void setMatchSpan(CandidateRelationSpan relationSpan) {
-        matchDocNumber = relationSpan.getDoc();
-        if (!inverse) {
-            matchStartPosition = relationSpan.getStart();
-            matchEndPosition = relationSpan.getEnd();
-            setRightStart(relationSpan.getRightStart());
-            setRightEnd(relationSpan.getRightEnd());
-        } else { // maybe a bit confusing -- inverse relation
-            matchStartPosition = relationSpan.getRightStart();
-            matchEndPosition = relationSpan.getRightEnd();
-            setRightStart(relationSpan.getStart());
-            setRightEnd(relationSpan.getEnd());
-        }
-
-        setLeftId(relationSpan.getLeftId());
-        setRightId(relationSpan.getRightId());
-        setSpanId(relationSpan.getSpanId());
-    }
-
-    /**
-     * Sets the candidate relation list based on token window that starts at the
-     * same token position as a relation span, and ends at the start + window
-     * length.
-     * 
-     * @throws IOException
-     */
-    private void setCandidateListWithWindow() throws IOException {
-        if (hasMoreSpans && ensureSameDoc(relationSpans, matcheeSpans)) {
-            int windowEnd = relationSpans.start() + window;
-            if (relationSpans.end() > windowEnd) {
-                throw new IllegalArgumentException("The window length "
-                        + window + " is too small. The relation span ("
-                        + relationSpans.start() + "," + relationSpans.end()
-                        + ") is longer than " + "the window " + "length.");
-            } else {
-                collectRelations(relationSpans.doc(), windowEnd);
-                // sort results
-                Collections.sort(candidateRelations);
-            }
-        }
-    }
-
-    /**
-     * Sets the candidate relation list based on the element window.
-     * 
-     * @throws IOException
-     */
-    private void setCandidateList() throws IOException {
-        while (hasMoreSpans
-                && findSameDoc(element, relationSpans, matcheeSpans)) {
-            // if the relation is within a sentence
-            if (relationSpans.start() >= element.start()
-                    && relationSpans.end() <= element.end()) {
-                collectRelations(element.doc(), element.end());
-                // sort results
-                Collections.sort(candidateRelations);
-            } else if (relationSpans.end() < element.end()) {
-                hasMoreSpans = relationSpans.next();
-            } else {
-                hasMoreSpans = element.next();
-            }
-        }
-    }
-
-    /**
-     * Collects all relations whose end position is before or identical to the
-     * given window end, within the specified document number, and match either
-     * the left or right side of the relation to the matcheeSpans.
-     * 
-     * @param currentDoc the current document number
-     * @param windowEnd the end position of the current window
-     * @throws IOException
-     */
-    private void collectRelations(int currentDoc, int windowEnd)
-            throws IOException {
-        List<CandidateRelationSpan> temp = new ArrayList<CandidateRelationSpan>();
-        boolean sortRight = false;
-        if (matchRight)
-            sortRight = true;
-        // collect all relations within an element	
-        while (hasMoreSpans && relationSpans.doc() == currentDoc
-                && relationSpans.end() <= windowEnd) {
-            temp.add(new CandidateRelationSpan(relationSpans, sortRight));
-            hasMoreSpans = relationSpans.next();
-        }
-
-        if (matchRight)
-            Collections.sort(temp);
-
-        // do the matching for each relation
-        int i = 0;
-        CandidateRelationSpan r;
-        while (hasMoreMatchees && i < temp.size()) {
-            r = temp.get(i);
-            if (matchRight) {
-                /*
-                 * System.out.println(r.getStart()+","+r.getEnd()+" "+
-                 * r.getRightStart()+","+r.getRightEnd()+ " #"+r.getRightId()+
-                 * " "+matcheeSpans.start()+","+matcheeSpans.end()+
-                 * " #"+matcheeSpans.getSpanId() );
-                 */
-                i = matchRelation(i, r, r.getRightStart(), r.getRightEnd());
-            } else {
-                /*
-                 * System.out.println(r.getStart()+","+r.getEnd()+" "+
-                 * r.getRightStart()+","+r.getRightEnd()+" "
-                 * +matcheeSpans.start()+","+matcheeSpans.end()+
-                 * " #"+matcheeSpans.getSpanId());
-                 */
-                i = matchRelation(i, r, r.getStart(), r.getEnd());
-            }
-        }
-
-        hasMoreSpans &= hasMoreMatchees;
-    }
-
-    /**
-     * Matches the relation part from the given candidate relation, and start
-     * and end positions to the matcheeSpans.
-     * 
-     * @param i the position counter for iterating the collected relations
-     * @param r a CandidateRelationSpan
-     * @param startPos the start position of the relation part to match
-     * @param endPos the end position of the relation part to match
-     * @return the next position counter to compute
-     * @throws IOException
-     */
-    private int matchRelation(int i, CandidateRelationSpan r, int startPos,
-            int endPos) throws IOException {
-
-        if (startPos == matcheeSpans.start()) {
-            if (endPos == matcheeSpans.end()) {
-
-                int id;
-                if (matcheeSpans instanceof RelationPartSpans) {
-                    if (matchRight) {
-                        id = ((RelationPartSpans) matcheeSpans).getRightId();
-                    } else {
-                        id = ((RelationPartSpans) matcheeSpans).getLeftId();
-                    }
-                } else {
-                    id = matcheeSpans.getSpanId();
-                }
-
-                //if (!inverse && r.getRightId() == id) {
-                if (!inverse){
-                    if (matchRight && r.getRightId() == id ||
-                            !matchRight && r.getLeftId() == id){
-                        r.sortRight = false;
-                        candidateRelations.add(r);
-                    }                
-                } else if (inverse) {// && r.getLeftId() == id) {
-                    if (matchRight && r.getRightId() == id ||
-                            !matchRight && r.getLeftId() == id){
-                        r.sortRight = true;
-                        candidateRelations.add(r);
-                    }
-                }
-                i++;
-            } else if (endPos <= matcheeSpans.end()) {
-                i++;
-            } else {
-                hasMoreMatchees = matcheeSpans.next();
-            }
-        } else if (startPos < matcheeSpans.start()) {
-            i++;
-        } else {
-            hasMoreMatchees = matcheeSpans.next();
-        }
-        return i;
-    }
-
-    @Override
-    public boolean skipTo(int target) throws IOException {
-        if (hasMoreSpans && (relationSpans.doc() < target)) {
-            if (!relationSpans.skipTo(target)) {
-                candidateRelations.clear();
-                return false;
-            }
-        }
-        setCandidateList();
-        matchPayload.clear();
-        isStartEnumeration = false;
-        return advance();
-    }
-
-    @Override
-    public long cost() {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
-    /**
-     * CandidateRelationSpan stores a state of RelationSpans and enables sorting
-     * a relation list by the right side positions of the relations. Normally,
-     * such a list are sorted by left side positions of the relations.
-     * 
-     */
-    class CandidateRelationSpan extends CandidateSpan implements
-            Comparable<CandidateSpan> {
-
-        private int rightStart, rightEnd;
-        private short leftId, rightId;
-        private boolean sortRight;
-
-        public CandidateRelationSpan(RelationBaseSpans span, boolean sortRight)
-                throws IOException {
-            super(span);
-            this.rightStart = span.getRightStart();
-            this.rightEnd = span.getRightEnd();
-            this.sortRight = sortRight;
-            this.leftId = span.getLeftId();
-            this.rightId = span.getRightId();
-            this.spanId = span.getSpanId();
-        }
-
-        @Override
-        public int compareTo(CandidateSpan o) {
-            CandidateRelationSpan cs = (CandidateRelationSpan) o;
-            if (sortRight)
-                return sortByRight(cs);
-
-            return super.compareTo(o);
-        }
-
-        /**
-         * Determines the position of this CandidateRelationSpan relative to the
-         * given CandidateRelationSpan.
-         * 
-         * @param cs a CandidateRelationSpan
-         * @return 0 if this CandidateRelationSpan has identical position as cs,
-         *         1 if it should follows cs, and -1 if it should preceeds cs.
-         */
-        private int sortByRight(CandidateRelationSpan cs) {
-            if (this.getRightStart() == cs.getRightStart()) {
-                if (this.getRightEnd() == cs.getRightEnd())
-                    return 0;
-                if (this.getRightEnd() > cs.getRightEnd())
-                    return 1;
-                else
-                    return -1;
-            } else if (this.getRightStart() < cs.getRightStart())
-                return -1;
-            else
-                return 1;
-        }
-
-        public int getRightStart() {
-            return rightStart;
-        }
-
-        public void setRightStart(int rightStart) {
-            this.rightStart = rightStart;
-        }
-
-        public int getRightEnd() {
-            return rightEnd;
-        }
-
-        public void setRightEnd(int rightEnd) {
-            this.rightEnd = rightEnd;
-        }
-
-        public short getLeftId() {
-            return leftId;
-        }
-
-        public void setLeftId(short leftId) {
-            this.leftId = leftId;
-        }
-
-        public short getRightId() {
-            return rightId;
-        }
-
-        public void setRightId(short rightId) {
-            this.rightId = rightId;
-        }
-    }
-}
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 abb8fda..9a1d578 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
@@ -93,6 +93,7 @@
                 this.matchDocNumber = cs.getDoc();
                 this.matchStartPosition = cs.getStart();
                 this.matchEndPosition = cs.getEnd();
+				this.matchPayload = cs.getPayloads();
                 this.setRightStart(cs.getRightStart());
                 this.setRightEnd(cs.getRightEnd());
                 this.spanId = cs.getSpanId(); // relation id
@@ -100,7 +101,8 @@
                 this.rightId = cs.getRightId();
                 candidateList.remove(0);
                 return true;
-            } else {
+            } 
+            else {
                 setCandidateList();
                 currentDoc = relationTermSpan.doc();
                 currentPosition = relationTermSpan.start();
@@ -119,19 +121,13 @@
     private void setCandidateList() throws IOException {
         while (hasMoreSpans && relationTermSpan.doc() == currentDoc
                 && relationTermSpan.start() == currentPosition) {
-            CandidateRelationSpan cs = new CandidateRelationSpan(
-                    relationTermSpan);
+            CandidateRelationSpan cs = new CandidateRelationSpan(relationTermSpan);
             readPayload(cs);
-
+			setPayload(cs);
             candidateList.add(cs);
             hasMoreSpans = relationTermSpan.next();
         }
         Collections.sort(candidateList);
-
-        //		for (CandidateRelationSpan cs:candidateList){
-        //			System.out.println(cs.getStart()+","+cs.getEnd() //+" <size:" +payload.get(0).length 
-        //				+" target "+cs.getRightStart()+","+cs.getRightEnd() +" id:"+cs.getSpanId());
-        //		}
     }
 
     /**
@@ -180,6 +176,26 @@
         // Payload is cleared.		
     }
 
+	private void setPayload(CandidateRelationSpan cs) throws IOException {
+		ArrayList<byte[]> payload = new ArrayList<byte[]>();
+		if (relationTermSpan.isPayloadAvailable()) {
+			payload.addAll(relationTermSpan.getPayload());
+		}
+		payload.add(createClassPayload(cs.getLeftStart(), cs.getLeftEnd(),
+				(byte) 1));
+		payload.add(createClassPayload(cs.getRightStart(), cs.getRightEnd(),
+				(byte) 2));
+		cs.setPayloads(payload);
+	}
+
+	private byte[] createClassPayload(int start, int end, byte classNumber) {
+		ByteBuffer buffer = ByteBuffer.allocate(9);
+		buffer.putInt(start);
+		buffer.putInt(end);
+		buffer.put(classNumber);
+		return buffer.array();
+	}
+
     @Override
     public boolean skipTo(int target) throws IOException {
         if (hasMoreSpans && (firstSpans.doc() < target)) {
@@ -236,12 +252,11 @@
     }
 
     /**
-     * CandidateRelationSpan stores a state of RelationSpans. In a list,
-     * CandidateRelationSpans are ordered first by the position of the relation
-     * left side and then by the position of the relation right side.
-     */
-    class CandidateRelationSpan extends CandidateSpan implements
-            Comparable<CandidateSpan> {
+	 * CandidateRelationSpan stores a state of RelationSpans. In a list,
+	 * CandidateRelationSpans are ordered first by the position of the relation
+	 * left side.
+	 */
+	class CandidateRelationSpan extends CandidateSpan {
 
         private int rightStart, rightEnd;
         private short leftId, rightId;
@@ -250,29 +265,6 @@
             super(span);
         }
 
-        @Override
-        public int compareTo(CandidateSpan o) {
-
-            int sourcePositionComparison = super.compareTo(o);
-
-            CandidateRelationSpan cs = (CandidateRelationSpan) o;
-            if (sourcePositionComparison == 0) {
-                if (this.getRightStart() == cs.getRightStart()) {
-                    if (this.getRightEnd() == cs.getRightEnd())
-                        return 0;
-                    if (this.getRightEnd() > cs.getRightEnd())
-                        return 1;
-                    else
-                        return -1;
-                } else if (this.getRightStart() < cs.getRightStart())
-                    return -1;
-                else
-                    return 1;
-            }
-
-            return sourcePositionComparison;
-        }
-
         public int getRightEnd() {
             return rightEnd;
         }
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 432862f..b601d28 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
@@ -18,6 +18,7 @@
  * */
 public class SegmentSpans extends NonPartialOverlappingSpans {
 
+	private boolean isRelation;
     /**
      * Creates SegmentSpans from the given {@link SpanSegmentQuery}.
      * 
@@ -30,7 +31,13 @@
     public SegmentSpans(SpanSegmentQuery spanSegmentQuery,
             AtomicReaderContext context, Bits acceptDocs,
             Map<Term, TermContext> termContexts) throws IOException {
-        super(spanSegmentQuery, context, acceptDocs, termContexts);
+		super(spanSegmentQuery, context, acceptDocs, termContexts);
+		if (spanSegmentQuery.isRelation()) {
+			SpansWithId s2 = (SpansWithId) secondSpans;
+			// hacking for element query
+			s2.hasSpanId = true;
+			isRelation = true;
+		}
     }
 
     /**
@@ -40,16 +47,38 @@
      * */
     @Override
     protected int findMatch() {
+		RelationSpans s1;
+		SpansWithId s2;
         if (firstSpans.start() == secondSpans.start()
                 && firstSpans.end() == secondSpans.end()) {
-            matchDocNumber = firstSpans.doc();
-            matchStartPosition = firstSpans.start();
-            matchEndPosition = firstSpans.end();
-            return 0;
-        } else if (firstSpans.start() < secondSpans.start()
+
+			if (isRelation) {
+				s1 = (RelationSpans) firstSpans;
+				s2 = (SpansWithId) secondSpans;
+
+				//System.out.println("segment: " + s1.getRightStart() + " "
+				// + s1.getRightEnd());
+				if (s1.getLeftId() == s2.getSpanId()) {
+					setMatch();
+					return 0;
+				}
+			}
+			else {
+				setMatch();
+				return 0;
+			}            
+		}
+
+		if (firstSpans.start() < secondSpans.start()
                 || firstSpans.end() < secondSpans.end())
             return -1;
 
         return 1;
     }
+
+	private void setMatch() {
+		matchDocNumber = firstSpans.doc();
+		matchStartPosition = firstSpans.start();
+		matchEndPosition = firstSpans.end();
+	}
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SimpleSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/SimpleSpans.java
index c9ca2e6..5b141a6 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SimpleSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SimpleSpans.java
@@ -31,19 +31,22 @@
 	protected int matchDocNumber, matchStartPosition, matchEndPosition;	
 	protected Collection<byte[]> matchPayload;	
       
+	public SimpleSpans() {
+		collectPayloads = true;
+		matchDocNumber = -1;
+		matchStartPosition = -1;
+		matchEndPosition = -1;
+		matchPayload = new ArrayList<byte[]>();
+		isStartEnumeration = true;
+	};
+	
     public SimpleSpans (SimpleSpanQuery simpleSpanQuery,
 			AtomicReaderContext context,
 			Bits acceptDocs,
 			Map<Term,TermContext> termContexts) throws IOException {
-    	
+		this();
     	query = simpleSpanQuery;
     	collectPayloads = query.isCollectPayloads();
-    	
-  		matchDocNumber= -1;
-  		matchStartPosition= -1;
-  		matchEndPosition= -1;
-  		matchPayload = new ArrayList<byte[]>();
-  		
   		// Get the enumeration of the two spans to match
 		SpanQuery sq;
 		if ((sq = simpleSpanQuery.getFirstClause()) != null)
@@ -52,7 +55,6 @@
 		if ((sq = simpleSpanQuery.getSecondClause()) != null)
 			secondSpans = sq.getSpans(context, acceptDocs, termContexts);
   		
-  		isStartEnumeration=true;
       }
   	
   	/** If the current x and y are not in the same document, to skip the 
@@ -113,7 +115,7 @@
   		return matchEndPosition;
   	}
 
-  	@Override
+	@Override
   	public Collection<byte[]> getPayload() throws IOException {
   		return matchPayload;
   	}
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 6adeaf5..4446555 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
@@ -176,8 +176,8 @@
     private boolean advance() throws IOException {
 
         while (hasMoreSpans && searchSpanPosition()) {
-            //logger.info("element: " + withAttributeSpans.start() + ","+ withAttributeSpans.end() +
-            //	" ref:"+withAttributeSpans.getSpanId());
+//			System.out.println("element: " + referentSpans.start() + ","
+//					+ referentSpans.end() + " ref:"+ referentSpans.getSpanId());
 
 			if (checkReferentId() && checkNotReferentId(referentSpans)) {
                 this.matchDocNumber = referentSpans.doc();
@@ -258,9 +258,10 @@
             AttributeSpans attributes) throws IOException {
 
         while (hasMoreSpans && ensureSameDoc(spans, attributes)) {
-            if (attributes.start() == spans.start())
+			if (attributes.start() == spans.start()
+					&& attributes.end() == spans.end())
                 return true;
-            else if (attributes.start() > spans.start())
+			else if (attributes.start() >= spans.start())
                 hasMoreSpans = spans.next();
             else
                 hasMoreSpans = attributes.next();
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithId.java b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithId.java
index de4b8e6..77c975e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithId.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithId.java
@@ -36,11 +36,13 @@
         super(spanWithIdQuery, context, acceptDocs, termContexts);
     }
 
-    /**
-     * Returns the span id of the current span
-     * 
-     * @return the span id of the current span
-     */
+	public SpansWithId() {}
+
+	/**
+	 * Returns the span id of the current span
+	 * 
+	 * @return the span id of the current span
+	 */
     public short getSpanId() {
         return spanId;
     }