diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanRelationPartQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanRelationPartQuery.java
index 6989a81..508aa99 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanRelationPartQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanRelationPartQuery.java
@@ -13,9 +13,40 @@
 import de.ids_mannheim.korap.query.spans.RelationPartSpans;
 
 /**
- * This query match a part of a relation (either left or right) to certain
+ * This query matches a part of a relation (either left or right) to certain
  * elements or terms. If inversed, the start and end positions of the right part
- * of the relation are set as positions of the match.
+ * of the relation are set as the positions of the match.
+ * 
+ * Examples:
+ * <ul>
+ * <li>retrieve all dependency relations "<:xip/syntax-dep_rel" whose sources
+ * (right side) are noun phrases. This query matches the right side of the
+ * relations to NP.
+ * 
+ * <pre>
+ * SpanRelationQuery sq = new SpanRelationQuery(new SpanTermQuery(new Term(
+ *         &quot;tokens&quot;, &quot;&lt;:xip/syntax-dep_rel&quot;)), true);
+ * 
+ * SpanRelationPartQuery rv = new SpanRelationPartQuery(sq, new SpanElementQuery(
+ *         &quot;tokens&quot;, &quot;np&quot;), true, false, true);
+ * </pre>
+ * 
+ * </li>
+ * 
+ * <li>returns all the children of NP using "<:child-of" relations where the
+ * left side is the parent and then right side is the child. This query matches
+ * the left side to NP and requires inverse on the relations, because the it
+ * asks for the children which are on the right side of the relations.</li>
+ * 
+ * <pre>
+ * SpanRelationQuery sq = new SpanRelationQuery(new SpanTermQuery(new Term(
+ *         &quot;tokens&quot;, &quot;&lt;:child-of&quot;)), true);
+ * 
+ * SpanRelationPartQuery rv = new SpanRelationPartQuery(sq, new SpanElementQuery(
+ *         &quot;base&quot;, &quot;np&quot;), false, true, true);
+ * </pre>
+ * 
+ * </ul>
  * 
  * @author margaretha
  * */
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 3792f7e..201e9df 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
@@ -30,13 +30,17 @@
  * secondly by the element/relation id descendingly. This order helps to match
  * element and attributes faster.
  * 
+ * AttributeSpans contain information about the elements they belongs to, thus
+ * querying them alone is sufficient to get
+ * "any element having a specific attribute".
+ * 
  * @author margaretha
  * */
 public class AttributeSpans extends SimpleSpans {
 
     private List<CandidateAttributeSpan> candidateList;
     private int currentDoc, currentPosition;
-    private short spanId;
+    private short referentId;
     private boolean isFinish;
     private int elementEnd;
 
@@ -86,7 +90,7 @@
                 this.matchDocNumber = cs.getDoc();
                 this.matchStartPosition = cs.getStart();
                 this.matchEndPosition = cs.getEnd();
-                this.setSpanId(cs.getSpanId());
+                this.setReferentId(cs.getSpanId());
                 this.setElementEnd(cs.getElementEnd());
                 candidateList.remove(0);
                 return true;
@@ -145,19 +149,19 @@
      * 
      * @return a span id, for instance a relation id or an element id
      */
-    public short getSpanId() {
-        return this.spanId;
+    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 spanId the span id to which an attribute span belongs, for
+     * @param refId the span id to which an attribute span belongs, for
      *        instance a relation id or an element id.
      */
-    public void setSpanId(short spanId) {
-        this.spanId = spanId;
+    public void setReferentId(short refId) {
+        this.referentId = refId;
     }
 
     /**
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 528aec1..914bf7f 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
@@ -8,49 +8,110 @@
 import org.apache.lucene.index.TermContext;
 import org.apache.lucene.util.Bits;
 
+import de.ids_mannheim.korap.query.SpanElementQuery;
+import de.ids_mannheim.korap.query.SpanRelationQuery;
 import de.ids_mannheim.korap.query.SpanWithIdQuery;
 
-public abstract class RelationBaseSpans extends SpansWithId{
+/**
+ * RelationBaseSpans is a base class for relation spans containing properties
+ * about the start and end positions of right side of the relation. It can also
+ * store information about the id of the left/right side, for instance, when it
+ * is an element or another relation.
+ * 
+ * @author margaretha
+ * 
+ */
+public abstract class RelationBaseSpans extends SpansWithId {
 
-	protected short leftId, rightId;
-	protected int rightStart, rightEnd;
-	
-	public RelationBaseSpans(SpanWithIdQuery spanWithIdQuery,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(spanWithIdQuery, context, acceptDocs, termContexts);
-		// TODO Auto-generated constructor stub
-	}
-	
-	public short getLeftId() {
-		return leftId;
-	}
+    protected short leftId, rightId;
+    protected int rightStart, rightEnd;
 
-	public void setLeftId(short leftId) {
-		this.leftId = leftId;
-	}
+    /**
+     * Create a RelationBaseSpans based on the given SpanWithIdQuery.
+     * 
+     * @param spanWithIdQuery a SpanWithIdQuery, for instance a
+     *        {@link SpanElementQuery} or {@link SpanRelationQuery}.
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public RelationBaseSpans(SpanWithIdQuery spanWithIdQuery,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(spanWithIdQuery, context, acceptDocs, termContexts);
+    }
 
-	public short getRightId() {
-		return rightId;
-	}
+    /**
+     * Returns the id of the left hand side of the relation.
+     * 
+     * @return an id
+     */
+    public short getLeftId() {
+        return leftId;
+    }
 
-	public void setRightId(short rightId) {
-		this.rightId = rightId;
-	}
+    /**
+     * Sets the id of the left hand side of the relation.
+     * 
+     * @param leftId the id of the left hand side of the relation.
+     */
+    public void setLeftId(short leftId) {
+        this.leftId = leftId;
+    }
 
-	public int getRightStart() {
-		return rightStart;
-	}
+    /**
+     * Returns the id of the right hand side of the relation.
+     * 
+     * @return an id
+     */
+    public short getRightId() {
+        return rightId;
+    }
 
-	public void setRightStart(int rightStart) {
-		this.rightStart = rightStart;
-	}
+    /**
+     * Sets the id of the right hand side of the relation.
+     * 
+     * @param rightId the id of the right hand side of the relation.
+     */
+    public void setRightId(short rightId) {
+        this.rightId = rightId;
+    }
 
-	public int getRightEnd() {
-		return rightEnd;
-	}
+    /**
+     * Returns the start position of the right hand side of the relation.
+     * 
+     * @return the start position
+     */
+    public int getRightStart() {
+        return rightStart;
+    }
 
-	public void setRightEnd(int rightEnd) {
-		this.rightEnd = rightEnd;
-	}
+    /**
+     * Sets the start position of the right hand side of the relation.
+     * 
+     * @param rightStart the start position of the right hand side of the
+     *        relation.
+     */
+    public void setRightStart(int rightStart) {
+        this.rightStart = rightStart;
+    }
+
+    /**
+     * Returns the end position of the right hand side of the relation.
+     * 
+     * @return the end position
+     */
+    public int getRightEnd() {
+        return rightEnd;
+    }
+
+    /**
+     * Sets the start position of the right hand side of the relation.
+     * 
+     * @param rightEnd the end position of the right hand side of the relation.
+     */
+    public void setRightEnd(int rightEnd) {
+        this.rightEnd = rightEnd;
+    }
 }
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
index 871298e..98ccf18 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/RelationPartSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/RelationPartSpans.java
@@ -13,309 +13,373 @@
 
 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.
- * 	
- * 	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 an window. 
+/**
+ * This span enumeration returns the right part of relation spans whose left
+ * part token/element positions matching the second spans, or vice versa.
  * 
- * 	@author margaretha
+ * 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;
-	private List<CandidateRelationSpan> candidateRelations;
-	
-	private boolean matchRight;
-	private boolean inverse;
-	private boolean hasMoreMatchees;
-	
-//	private short leftId, rightId;
-	private int window;
-	
-	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();
-	}
+public class RelationPartSpans extends RelationBaseSpans {
 
-	@Override
-	public boolean next() throws IOException {
-		isStartEnumeration=false;
-  		matchPayload.clear();
-		return advance();
-	}
-	
-	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;
-	}
-	
-	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());
-	}
-	
-	/** A window starts at the same token position as a relation span, 
-	 * 	and ends at the start + window length.
-	 * */
-	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);
-			}
-		}
-	}
+    private RelationBaseSpans relationSpans;
+    private SpansWithId matcheeSpans;
+    private ElementSpans element; // element as the window
+    private List<CandidateRelationSpan> candidateRelations;
 
-	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();
-			}
-		}		
-	}
+    private boolean matchRight;
+    private boolean inverse;
+    private boolean hasMoreMatchees;
 
-	/** Collect all relations within an element whose left side matching the secondspans.
-	 * */
-	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;
-	}
-	
-	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){
-					r.sortRight = false;
-					candidateRelations.add(r);
-				}
-				else if (inverse && 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;
-	}
+    private int window; // number of tokens as the window
 
-	@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();	
-	}
+    /**
+     * Creates a 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;
 
-	@Override
-	public long cost() {
-		// TODO Auto-generated method stub
-		return 0;
-	}
+        hasMoreMatchees = matcheeSpans.next();
+        hasMoreSpans = relationSpans.next() && hasMoreMatchees;
+        if (element != null) {
+            hasMoreSpans &= element.next();
+        }
+        candidateRelations = new ArrayList<CandidateRelationSpan>();
+        matchRight = query.isMatchRight();
+        inverse = query.isInverseRelation();
+    }
 
-	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);
-		}
-		
-		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;	
-		}
-		
-		/*private void sortByLeft(CandidateSpan o) {
-			super.compareTo(o);
-		}*/
+    @Override
+    public boolean next() throws IOException {
+        isStartEnumeration = false;
+        matchPayload.clear();
+        return advance();
+    }
 
-		public int getRightStart() {
-			return rightStart;
-		}
+    /**
+     * 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;
+    }
 
-		public void setRightStart(int rightStart) {
-			this.rightStart = rightStart;
-		}
+    /**
+     * 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());
+        }
 
-		public int getRightEnd() {
-			return rightEnd;
-		}
+        setLeftId(relationSpan.getLeftId());
+        setRightId(relationSpan.getRightId());
+        setSpanId(relationSpan.getSpanId());
+    }
 
-		public void setRightEnd(int rightEnd) {
-			this.rightEnd = rightEnd;
-		}
+    /**
+     * 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);
+            }
+        }
+    }
 
-		public short getLeftId() {
-			return leftId;
-		}
+    /**
+     * 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();
+            }
+        }
+    }
 
-		public void setLeftId(short leftId) {
-			this.leftId = leftId;
-		}
+    /**
+     * 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();
+        }
 
-		public short getRightId() {
-			return rightId;
-		}
+        if (matchRight)
+            Collections.sort(temp);
 
-		public void setRightId(short rightId) {
-			this.rightId = rightId;
-		}	
-	}
+        // 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) {
+                    r.sortRight = false;
+                    candidateRelations.add(r);
+                } else if (inverse && 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 2c4bdb6..05de6d5 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
@@ -18,248 +18,293 @@
 
 import de.ids_mannheim.korap.query.SpanRelationQuery;
 
-/**	Enumeration of spans denoting relations between two tokens/elements. The start and end of 
- * 	a RelationSpan always denote the start and end of the left-side token/element.
+/**
+ * Enumeration of spans denoting relations between two tokens/elements. The
+ * start and end of a RelationSpan always denote the start and end of the
+ * left-side token/element.
  * 
- * 	There are 4 types of relations, which is differentiated by the payload length in bytes.  
- * 	1. Token to token relation (1 int & 3 short, length: 10) 
- * 	2. Token to span (2 int & 3 short, length: 14)
- * 	3. Span to token (int, byte, int, 3 short, length: 15)
- * 	4. Span to Span (3 int & 3 short, length: 18) 
- * 	
- * 	Every integer value denotes the start/end position of the start/target of a relation, 
- * 	in this format:	(sourceEndPos?, startTargetPos, endTargetPos?). The end position of a token is 
- * 	identical to its start position, and therefore not is saved in a payload.
- *
- *	The short values denote the relation id, left id, and right id.
- * 	The byte in relation #3 is just a dummy to create a different length from the relation #2.
+ * There are 4 types of relations, which is differentiated by the payload length
+ * in bytes.
+ * <ol>
+ * <li>Token to token relation (1 int & 3 short, length: 10)</li>
+ * <li>Token to span (2 int & 3 short, length: 14)</li>
+ * <li>Span to token (int, byte, int, 3 short, length: 15)</li>
+ * <li>Span to Span (3 int & 3 short, length: 18)</li>
+ * </ol>
+ * Every integer value denotes the start/end position of the start/target of a
+ * relation, in this format: (sourceEndPos?, startTargetPos, endTargetPos?). The
+ * end position of a token is identical to its start position, and therefore not
+ * is saved in a payload.
  * 
- * 	NOTE: Sorting of the candidate spans can alternatively be done in indexing, instead of here. 
- * 	(first by left positions and then by right positions)
+ * The short values denote the relation id, left id, and right id. The byte in
+ * relation #3 is just a dummy to create a different length from the relation
+ * #2.
  * 
- * 	@author margaretha
+ * NOTE: Sorting of the candidate spans can alternatively be done in indexing,
+ * instead of here. (first by left positions and then by right positions)
+ * 
+ * @author margaretha
  * */
-public class RelationSpans extends RelationBaseSpans{
+public class RelationSpans extends RelationBaseSpans {
 
-	//short relationId;
-//	private int rightStart, rightEnd;
-	private int currentDoc, currentPosition;
-//	private short leftId, rightId;
-	
-	private TermSpans relationTermSpan;
-	
-	protected Logger logger = LoggerFactory.getLogger(RelationSpans.class);
-	private List<CandidateRelationSpan> candidateList;
-	
-	public RelationSpans(SpanRelationQuery relationSpanQuery,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(relationSpanQuery, context, acceptDocs, termContexts);
-		candidateList = new ArrayList<>();
-		relationTermSpan = (TermSpans) firstSpans;
-		hasMoreSpans = relationTermSpan.next();
-	}
+    private int currentDoc, currentPosition;
+    private TermSpans relationTermSpan;
 
-	@Override
-	public boolean next() throws IOException {
-		isStartEnumeration=false;
-		return advance();
-	}
-	
-	private boolean advance() throws IOException{
-		while(hasMoreSpans || !candidateList.isEmpty()){
-			if (!candidateList.isEmpty()){
-				CandidateRelationSpan cs = candidateList.get(0);
-				this.matchDocNumber = cs.getDoc();
-				this.matchStartPosition = cs.getStart();
-				this.matchEndPosition = cs.getEnd();
-				this.setRightStart(cs.getRightStart());
-				this.setRightEnd(cs.getRightEnd());
-				this.spanId = cs.getSpanId(); // relation id
-				this.leftId = cs.getLeftId();
-				this.rightId = cs.getRightId();
-				candidateList.remove(0);
-				return true;
-			}
-			else{
-				setCandidateList();				
-				currentDoc = relationTermSpan.doc();
-				currentPosition = relationTermSpan.start();
-			}
-		}
-		return false;
-	}
+    protected Logger logger = LoggerFactory.getLogger(RelationSpans.class);
+    private List<CandidateRelationSpan> candidateList;
 
-	private void setCandidateList() throws IOException {
-		while (hasMoreSpans &&	relationTermSpan.doc() == currentDoc && 
-				relationTermSpan.start() == currentPosition){
-			CandidateRelationSpan cs = new CandidateRelationSpan(relationTermSpan);
-			readPayload(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());
-//		}
-	}
+    /**
+     * Creates a RelationSpans from the given {@link SpanRelationQuery}.
+     * 
+     * @param relationSpanQuery a SpanRelationQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public RelationSpans(SpanRelationQuery relationSpanQuery,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(relationSpanQuery, context, acceptDocs, termContexts);
+        candidateList = new ArrayList<>();
+        relationTermSpan = (TermSpans) firstSpans;
+        hasMoreSpans = relationTermSpan.next();
+    }
 
-	private void readPayload(CandidateRelationSpan cs) {
-		List<byte[]> payload = (List<byte[]>) cs.getPayloads();
-		int length = payload.get(0).length;
-		ByteBuffer bb = ByteBuffer.allocate(length);
-		bb.put(payload.get(0));
-		
-		int i;		
-		switch (length) {
-			case 10: // Token to token				
-				i = bb.getInt(0);
-				cs.setRightStart(i-1);
-				cs.setRightEnd(i);
-				break;
-	
-			case 14: // Token to span
-				cs.setRightStart(bb.getInt(0));
-				cs.setRightEnd(bb.getInt(4));
-				break;
-				
-			case 15: // Span to token
-				cs.setEnd(bb.getInt(0));
-				i = bb.getInt(5);
-				cs.setRightStart(i-1);
-				cs.setRightEnd(i);
-				break;
-			
-			case 18: // Span to span
-				cs.setEnd(bb.getInt(0));
-				cs.setRightStart(bb.getInt(4));
-				cs.setRightEnd(bb.getInt(8));
-				break;
-		}		
-		
-		cs.setRightId(bb.getShort(length-2)); //right id
-		cs.setLeftId(bb.getShort(length-4)); //left id
-		cs.setSpanId(bb.getShort(length-6)); //relation id
-		// Payload is cleared.		
-	}
+    @Override
+    public boolean next() throws IOException {
+        isStartEnumeration = false;
+        return advance();
+    }
 
-	@Override
-	public boolean skipTo(int target) throws IOException {
-		if (hasMoreSpans && (firstSpans.doc() < target)){
-  			if (!firstSpans.skipTo(target)){
-  				candidateList.clear();
-  				return false;
-  			}
-  		}		
-		setCandidateList();
-		matchPayload.clear();
-		isStartEnumeration=false;
-		return advance();	
-	}
-	
-	@Override
-	public long cost() {
-		return firstSpans.cost();
-	}
+    /**
+     * Returns true if there is a next match by checking if the CandidateList is
+     * not empty and set the first element of the list as the next match.
+     * Otherwise, if the RelationSpan has not ended yet, try to set the
+     * CandidateList.
+     * 
+     * @return true if there is a next match.
+     * @throws IOException
+     */
+    private boolean advance() throws IOException {
+        while (hasMoreSpans || !candidateList.isEmpty()) {
+            if (!candidateList.isEmpty()) {
+                CandidateRelationSpan cs = candidateList.get(0);
+                this.matchDocNumber = cs.getDoc();
+                this.matchStartPosition = cs.getStart();
+                this.matchEndPosition = cs.getEnd();
+                this.setRightStart(cs.getRightStart());
+                this.setRightEnd(cs.getRightEnd());
+                this.spanId = cs.getSpanId(); // relation id
+                this.leftId = cs.getLeftId();
+                this.rightId = cs.getRightId();
+                candidateList.remove(0);
+                return true;
+            } else {
+                setCandidateList();
+                currentDoc = relationTermSpan.doc();
+                currentPosition = relationTermSpan.start();
+            }
+        }
+        return false;
+    }
 
-	public int getRightStart() {
-		return rightStart;
-	}
+    /**
+     * Setting the CandidateList by adding all relationTermSpan whose start
+     * position is the same as the current span position, and sort the
+     * candidateList.
+     * 
+     * @throws IOException
+     */
+    private void setCandidateList() throws IOException {
+        while (hasMoreSpans && relationTermSpan.doc() == currentDoc
+                && relationTermSpan.start() == currentPosition) {
+            CandidateRelationSpan cs = new CandidateRelationSpan(
+                    relationTermSpan);
+            readPayload(cs);
 
-	public void setRightStart(int rightStart) {
-		this.rightStart = rightStart;
-	}
+            candidateList.add(cs);
+            hasMoreSpans = relationTermSpan.next();
+        }
+        Collections.sort(candidateList);
 
-	public int getRightEnd() {
-		return rightEnd;
-	}
+        //		for (CandidateRelationSpan cs:candidateList){
+        //			System.out.println(cs.getStart()+","+cs.getEnd() //+" <size:" +payload.get(0).length 
+        //				+" target "+cs.getRightStart()+","+cs.getRightEnd() +" id:"+cs.getSpanId());
+        //		}
+    }
 
-	public void setRightEnd(int rightEnd) {
-		this.rightEnd = rightEnd;
-	}
+    /**
+     * Identify the relation type of the given {@link CandidateRelationSpan} by
+     * checking the length of its payloads, and set some properties of the span
+     * based on the payloads.
+     * 
+     * @param cs a CandidateRelationSpan
+     */
+    private void readPayload(CandidateRelationSpan cs) {
+        List<byte[]> payload = (List<byte[]>) cs.getPayloads();
+        int length = payload.get(0).length;
+        ByteBuffer bb = ByteBuffer.allocate(length);
+        bb.put(payload.get(0));
 
-//	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;
-//	}
+        int i;
+        switch (length) {
+            case 10: // Token to token				
+                i = bb.getInt(0);
+                cs.setRightStart(i - 1);
+                cs.setRightEnd(i);
+                break;
 
-	class CandidateRelationSpan extends CandidateSpan implements Comparable<CandidateSpan>{
-		
-		private int rightStart, rightEnd;
-		private short leftId, rightId;
-		
-		public CandidateRelationSpan(Spans span) throws IOException{
-			super(span);
-		}
+            case 14: // Token to span
+                cs.setRightStart(bb.getInt(0));
+                cs.setRightEnd(bb.getInt(4));
+                break;
 
-		@Override
-		public int compareTo(CandidateSpan o) {
+            case 15: // Span to token
+                cs.setEnd(bb.getInt(0));
+                i = bb.getInt(5);
+                cs.setRightStart(i - 1);
+                cs.setRightEnd(i);
+                break;
 
-			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;	
-			}
+            case 18: // Span to span
+                cs.setEnd(bb.getInt(0));
+                cs.setRightStart(bb.getInt(4));
+                cs.setRightEnd(bb.getInt(8));
+                break;
+        }
 
-			return sourcePositionComparison;
-		}
-		
-		public int getRightEnd() {
-			return rightEnd;
-		}
+        cs.setRightId(bb.getShort(length - 2)); //right id
+        cs.setLeftId(bb.getShort(length - 4)); //left id
+        cs.setSpanId(bb.getShort(length - 6)); //relation id
+        // Payload is cleared.		
+    }
 
-		public void setRightEnd(int rightEnd) {
-			this.rightEnd = rightEnd;
-		}
+    @Override
+    public boolean skipTo(int target) throws IOException {
+        if (hasMoreSpans && (firstSpans.doc() < target)) {
+            if (!firstSpans.skipTo(target)) {
+                candidateList.clear();
+                return false;
+            }
+        }
+        setCandidateList();
+        matchPayload.clear();
+        isStartEnumeration = false;
+        return advance();
+    }
 
-		public int getRightStart() {
-			return rightStart;
-		}
+    @Override
+    public long cost() {
+        return firstSpans.cost();
+    }
 
-		public void setRightStart(int rightStart) {
-			this.rightStart = rightStart;
-		}
+    /**
+     * Returns the right start position of the current RelationSpan.
+     * 
+     * @return the right start position of the current RelationSpan.
+     */
+    public int getRightStart() {
+        return rightStart;
+    }
 
-		public short getLeftId() {
-			return leftId;
-		}
+    /**
+     * Sets the right start position of the current RelationSpan.
+     * 
+     * @param rightStart the right start position of the current RelationSpan
+     */
+    public void setRightStart(int rightStart) {
+        this.rightStart = rightStart;
+    }
 
-		public void setLeftId(short leftId) {
-			this.leftId = leftId;
-		}
+    /**
+     * Returns the right end position of the current RelationSpan.
+     * 
+     * @return the right end position of the current RelationSpan.
+     */
+    public int getRightEnd() {
+        return rightEnd;
+    }
 
-		public short getRightId() {
-			return rightId;
-		}
+    /**
+     * Sets the right end position of the current RelationSpan.
+     * 
+     * @param rightEnd the right end position of the current RelationSpan.
+     */
+    public void setRightEnd(int rightEnd) {
+        this.rightEnd = rightEnd;
+    }
 
-		public void setRightId(short rightId) {
-			this.rightId = rightId;
-		}
+    /**
+     * 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> {
 
-	}
-	
+        private int rightStart, rightEnd;
+        private short leftId, rightId;
+
+        public CandidateRelationSpan(Spans span) throws IOException {
+            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;
+        }
+
+        public void setRightEnd(int rightEnd) {
+            this.rightEnd = rightEnd;
+        }
+
+        public int getRightStart() {
+            return rightStart;
+        }
+
+        public void setRightStart(int rightStart) {
+            this.rightStart = rightStart;
+        }
+
+        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/SpansWithAttribute.java b/src/main/java/de/ids_mannheim/korap/query/spans/SpansWithAttribute.java
index 344d974..a9723e8 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
@@ -16,244 +16,293 @@
 import de.ids_mannheim.korap.query.SpanAttributeQuery;
 import de.ids_mannheim.korap.query.SpanWithAttributeQuery;
 
-/** Span enumeration of element or relation spans having and/or <em>not</em> 
- * 	having some attributes. This class handles <em>and</em> operation on attributes.
+/**
+ * Span enumeration of element or relation spans (referent spans) having and/or
+ * <em>not</em> having some attributes. This class only handles <em>and</em>
+ * operation on attributes.
  * 
- * 	Use SpanOrQuery to perform <em>or</em> operation on attributes, i.e. choose 
- * 	between two elements with some attribute constraints. Note that the attribute 
- * 	constraints have to be in Conjunctive Normal Form (CNF). 
- *
- * 	@author margaretha
+ * Use SpanOrQuery to perform <em>or</em> operation on attributes, i.e. choose
+ * between two elements with some attribute constraints. Note that the attribute
+ * constraints have to be formulated in Conjunctive Normal Form (CNF).
+ * 
+ * @author margaretha
  * */
-public class SpansWithAttribute extends SpansWithId{
-	
-	private SpansWithId withAttributeSpans;
-	private List<AttributeSpans> attributeList;
-	private List<AttributeSpans> notAttributeList;
-	
-	protected Logger logger = LoggerFactory.getLogger(SpansWithAttribute.class);
+public class SpansWithAttribute extends SpansWithId {
 
-	public SpansWithAttribute(SpanWithAttributeQuery spanWithAttributeQuery,
-			SpansWithId withIdSpans,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(spanWithAttributeQuery, context, acceptDocs, termContexts);		
-		withAttributeSpans = withIdSpans;
-		withAttributeSpans.hasSpanId = true; // dummy setting enabling reading elementRef
-		hasMoreSpans = withAttributeSpans.next();
-		
-		attributeList = new ArrayList<AttributeSpans>();
-		notAttributeList = new ArrayList<AttributeSpans>();		
-		
-		List<SpanQuery> sqs = spanWithAttributeQuery.getClauseList();
-		if (sqs != null){
-			for (SpanQuery sq: sqs){
-				addAttributes(sq, context, acceptDocs, termContexts);
-			}
-		}
-		else {
-			addAttributes(spanWithAttributeQuery.getSecondClause(), 
-					context, acceptDocs, termContexts);
-		}
-	}
-	
-	private void addAttributes(SpanQuery sq, AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		AttributeSpans as = (AttributeSpans) sq.getSpans(context, acceptDocs, termContexts);
-		if (((SpanAttributeQuery) sq).isNegation()){
-			notAttributeList.add(as);
-			as.next();
-		}
-		else {
-			attributeList.add(as);
-			hasMoreSpans &= as.next();
-		}	
-	}
+    private SpansWithId referentSpans;
+    private List<AttributeSpans> attributeList;
+    private List<AttributeSpans> notAttributeList;
 
-	@Override
-	public boolean next() throws IOException {
-		isStartEnumeration=false;
-		return advance();
-	}
-	
-	/** Search for the next match by first identify a possible 
-	 * 	element position, and then ensuring that the element contains
-	 * 	all the attributes and <em>do not</em> contain any of the 
-	 *  not attributes.
-	 * */
-	private boolean advance() throws IOException {
-		
-		while (hasMoreSpans && searchSpanPosition()){			
-		 	    //logger.info("element: " + withAttributeSpans.start() + ","+ withAttributeSpans.end() +
-				//	" ref:"+withAttributeSpans.getSpanId());
-			
-			if (checkSpanId() && checkNotSpanId()){			
-				this.matchDocNumber = withAttributeSpans.doc();
-				this.matchStartPosition = withAttributeSpans.start();
-				this.matchEndPosition = withAttributeSpans.end();
-				this.matchPayload = withAttributeSpans.getPayload();
-				this.spanId = withAttributeSpans.getSpanId();
-				
-				if (attributeList.size() > 0)
-					hasMoreSpans = attributeList.get(0).next();
-				
-			    //logger.info("MATCH "+matchDocNumber);
-				
-				hasMoreSpans &= withAttributeSpans.next();		
-				return true;
-			}
-		}
-		return false;
-	}
-	
-	/** Ensuring all the attribute spans having the same elementRef with 
-	 * 	the actual element's elementRef.
-	 * */
-	private boolean checkSpanId() throws IOException{
-		
-		for (AttributeSpans attribute: attributeList){			
-			if (withAttributeSpans.getSpanId() != attribute.getSpanId()){
-//				    logger.info("attribute ref doesn't match");
-				if (withAttributeSpans.getSpanId() < attribute.getSpanId())
-					hasMoreSpans = attribute.next();
-				else {
-					hasMoreSpans = withAttributeSpans.next();				
-				}
-				
-				return false;
-			}
-		}		
-		return true;
-	}
-	
-	/** Ensuring elements do not contain the not attributes. In other words, 
-	 * 	the elementRef is not the same as the not attribute's elementRefs. 
-	 * */
-	private boolean checkNotSpanId() throws IOException{
-		for (AttributeSpans notAttribute: notAttributeList){
-			if (!notAttribute.isFinish() && 
-					withAttributeSpans.start() == notAttribute.start() &&
-					withAttributeSpans.getSpanId() == notAttribute.getSpanId()){
-//				    logger.info("not attribute ref exists");
-				hasMoreSpans = withAttributeSpans.next();	
-				return false;
-			}
-		}
-		return true;
-	}
-	
-	/**	Search for a possible element having the same doc and start position as
-	 * 	the attributes.
-	 * */
-	private boolean searchSpanPosition() throws IOException {		
+    protected Logger logger = LoggerFactory.getLogger(SpansWithAttribute.class);
 
-		while (hasMoreSpans){
-			
-			if (withAttributeSpans.getSpanId() < 1){ // the element does not have an attribute
-				hasMoreSpans = withAttributeSpans.next();
-//			    logger.info("skip");
-				continue;
-			}
-			
-			if (checkAttributeListPosition() && 
-					checkNotAttributeListPosition()){
-//				    logger.info("element is found: "+ withAttributeSpans.start());
-				return true;
-			}			
-		}		
-		
-		return false;
-	}
-	
-	/**	Advancing the not attributes to be in the same or greater doc# than 
-	 * 	element doc#. If a not attribute is in the same doc, advance it to
-	 * 	be in the same or greater start position than the element.
-	 * 
-	 * */
-	private boolean checkNotAttributeListPosition() throws IOException{
-		
-		for (AttributeSpans a : notAttributeList){
-			// advance the doc# of not AttributeSpans
-			// logger.info("a "+a.start());
-			while (!a.isFinish() &&	 a.doc() <= withAttributeSpans.doc()){
-				
-				if (a.doc() == withAttributeSpans.doc() &&
-						a.start() >= withAttributeSpans.start())
-					break;
-				
-				if (!a.next()) a.setFinish(true);
-			}
-		}
-		
-		return true;
-	}
-	
-	/** Advancing the attributes to be in the same doc and start position 
-	 * 	as the element.
-	 * */
-	private boolean checkAttributeListPosition() throws IOException{
-		int currentPosition = withAttributeSpans.start();
-		boolean isSame = true;
-		boolean isFirst = true;
-		
-		for (AttributeSpans a : attributeList){
-			if(!ensureSamePosition(withAttributeSpans, a)) return false;
-			//	    logger.info("pos:" + withAttributeSpans.start());
-				if (isFirst){ 
-					isFirst = false;
-					currentPosition = withAttributeSpans.start();
-				}
-				else if (currentPosition != withAttributeSpans.start()){					
-					currentPosition = withAttributeSpans.start();
-					isSame = false;
-				
-			}				 
-		}
-		//    logger.info("same pos: "+isSame+ ", pos "+withAttributeSpans.start());
-		return isSame;
-	}
-	
-	/** Advance the element or attribute spans to be in the same doc 
-	 * 	and start position.
-	 * */
-	private boolean ensureSamePosition(SpansWithId spans,
-			AttributeSpans attributes) throws IOException {
-		
-		while (hasMoreSpans && ensureSameDoc(spans, attributes)){
-			if (attributes.start() == spans.start())
-				return true;
-			else if (attributes.start() > spans.start()) 
-				hasMoreSpans = spans.next();
-			else 
-				hasMoreSpans= attributes.next();
-		}
-		
-		return false;
-	}
+    /**
+     * Creates a SpansWithAttribute from the given
+     * {@link SpanWithAttributeQuery} and {@link SpansWithId}, such as
+     * elementSpans and relationSpans.
+     * 
+     * @param spanWithAttributeQuery a spanWithAttributeQuery
+     * @param spansWithId a SpansWithId
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public SpansWithAttribute(SpanWithAttributeQuery spanWithAttributeQuery,
+            SpansWithId spansWithId, AtomicReaderContext context,
+            Bits acceptDocs, Map<Term, TermContext> termContexts)
+            throws IOException {
+        super(spanWithAttributeQuery, context, acceptDocs, termContexts);
+        referentSpans = spansWithId;
+        referentSpans.hasSpanId = true; // dummy setting enabling reading elementRef
+        hasMoreSpans = referentSpans.next();
 
-	@Override
-	public boolean skipTo(int target) throws IOException {
-		if (hasMoreSpans && (withAttributeSpans.doc() < target)){
-  			if (!withAttributeSpans.skipTo(target)){
-  				return false;
-  			}
-  		}		
-		isStartEnumeration=false;
-		return advance();
-	}
+        attributeList = new ArrayList<AttributeSpans>();
+        notAttributeList = new ArrayList<AttributeSpans>();
 
-	@Override
-	public long cost() {
-		
-		long cost = 0;
-		for (AttributeSpans as: attributeList){
-			cost += as.cost();
-		}
-		for (AttributeSpans as: notAttributeList){
-			cost += as.cost();
-		}
-		return withAttributeSpans.cost() + cost;
-	}
+        List<SpanQuery> sqs = spanWithAttributeQuery.getClauseList();
+        if (sqs != null) {
+            for (SpanQuery sq : sqs) {
+                addAttributes((SpanAttributeQuery) sq, context, acceptDocs,
+                        termContexts);
+            }
+        } else {
+            addAttributes(
+                    (SpanAttributeQuery) spanWithAttributeQuery
+                            .getSecondClause(),
+                    context, acceptDocs, termContexts);
+        }
+    }
 
+    /**
+     * Adds the given {@link SpanAttributeQuery} to the attributeList or
+     * notAttributeList depending on the query, whether it is a negation or not.
+     * 
+     * @param sq a SpanAttributeQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    private void addAttributes(SpanAttributeQuery sq,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        AttributeSpans as = (AttributeSpans) sq.getSpans(context, acceptDocs,
+                termContexts);
+        if (sq.isNegation()) {
+            notAttributeList.add(as);
+            as.next();
+        } else {
+            attributeList.add(as);
+            hasMoreSpans &= as.next();
+        }
+    }
+
+    @Override
+    public boolean next() throws IOException {
+        isStartEnumeration = false;
+        return advance();
+    }
+
+    /**
+     * Searches for the next match by first identify a possible element
+     * position, and then ensuring that the element contains all the attributes
+     * and <em>do not</em> contain any of the not attributes.
+     * 
+     * @return <code>true</code> if the a match is found, <code>false</code>
+     *         otherwise.
+     * @throws IOException
+     */
+    private boolean advance() throws IOException {
+
+        while (hasMoreSpans && searchSpanPosition()) {
+            //logger.info("element: " + withAttributeSpans.start() + ","+ withAttributeSpans.end() +
+            //	" ref:"+withAttributeSpans.getSpanId());
+
+            if (checkReferentId() && checkNotReferentId()) {
+                this.matchDocNumber = referentSpans.doc();
+                this.matchStartPosition = referentSpans.start();
+                this.matchEndPosition = referentSpans.end();
+                this.matchPayload = referentSpans.getPayload();
+                this.spanId = referentSpans.getSpanId();
+
+                if (attributeList.size() > 0)
+                    hasMoreSpans = attributeList.get(0).next();
+
+                hasMoreSpans &= referentSpans.next();
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Searches for a possible referentSpan having the same document number and
+     * start position as the attributes', and the position is different from the
+     * <em>not attributes'</em> positions.
+     * 
+     * @return <code>true</code> if the referentSpan position is valid,
+     *         <code>false</code> otherwise.
+     * @throws IOException
+     */
+    private boolean searchSpanPosition() throws IOException {
+        while (hasMoreSpans) {
+            if (referentSpans.getSpanId() < 1) { // the element does not have an attribute
+                hasMoreSpans = referentSpans.next();
+                continue;
+            }
+            if (checkAttributeListPosition()) {
+                advanceNotAttributes();
+                //				    logger.info("element is found: "+ withAttributeSpans.start());
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Advances the attributes to be in the same document and start position as
+     * the referentSpan.
+     * 
+     * @return <code>true</code> if the attributes are in the same document and
+     *         start position as the referentSpan.
+     * @throws IOException
+     */
+    private boolean checkAttributeListPosition() throws IOException {
+        int currentPosition = referentSpans.start();
+        boolean isSame = true;
+        boolean isFirst = true;
+
+        for (AttributeSpans a : attributeList) {
+            if (!ensureSamePosition(referentSpans, a))
+                return false;
+            //	    logger.info("pos:" + withAttributeSpans.start());
+            if (isFirst) {
+                isFirst = false;
+                currentPosition = referentSpans.start();
+            } else if (currentPosition != referentSpans.start()) {
+                currentPosition = referentSpans.start();
+                isSame = false;
+
+            }
+        }
+        //    logger.info("same pos: "+isSame+ ", pos "+withAttributeSpans.start());
+        return isSame;
+    }
+
+    /**
+     * Advances the element or attribute spans to be in the same document and
+     * start position.
+     * */
+    private boolean ensureSamePosition(SpansWithId spans,
+            AttributeSpans attributes) throws IOException {
+
+        while (hasMoreSpans && ensureSameDoc(spans, attributes)) {
+            if (attributes.start() == spans.start())
+                return true;
+            else if (attributes.start() > spans.start())
+                hasMoreSpans = spans.next();
+            else
+                hasMoreSpans = attributes.next();
+        }
+
+        return false;
+    }
+
+    /**
+     * Advances the <em>not-attributes</em> to be in the same or greater
+     * document number than referentSpans' document number. If a
+     * <em>not-attribute</em> is in the same document, it is advanced to be in
+     * the same as or greater start position than the current referentSpan.
+     * 
+     * @throws IOException
+     */
+    private void advanceNotAttributes() throws IOException {
+
+        for (AttributeSpans a : notAttributeList) {
+            // advance the doc# of not AttributeSpans
+            // logger.info("a "+a.start());
+            while (!a.isFinish() && a.doc() <= referentSpans.doc()) {
+
+                if (a.doc() == referentSpans.doc()
+                        && a.start() >= referentSpans.start())
+                    break;
+
+                if (!a.next())
+                    a.setFinish(true);
+            }
+        }
+        //return true;
+    }
+
+    /**
+     * Ensures that the referent id of each attributeSpans in the attributeList
+     * is the same as the spanId of the actual referentSpans.
+     * 
+     * @return <code>true</code> if the spanId of the current referentSpans is
+     *         the same as all the referentId of all the attributeSpans in the
+     *         attributeList, <code>false</code> otherwise.
+     * @throws IOException
+     */
+    private boolean checkReferentId() throws IOException {
+        for (AttributeSpans attribute : attributeList) {
+            if (referentSpans.getSpanId() != attribute.getReferentId()) {
+                if (referentSpans.getSpanId() < attribute.getReferentId())
+                    hasMoreSpans = attribute.next();
+                else {
+                    hasMoreSpans = referentSpans.next();
+                }
+
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Ensures that the referentSpans do <em>not</em> contain the
+     * <em>not attributes</em> (with negation). In other words, the spanId must
+     * not the same as the <em>not attribute</em>'s referentId.
+     * 
+     * @return <code>true</code> if the referentSpan does not have the same
+     *         spanId as the referentIds of all the not attributes,
+     *         <code>false</code> otherwise.
+     * @throws IOException
+     */
+    private boolean checkNotReferentId() throws IOException {
+        for (AttributeSpans notAttribute : notAttributeList) {
+            if (!notAttribute.isFinish()
+                    && referentSpans.start() == notAttribute.start()
+                    && referentSpans.getSpanId() == notAttribute
+                            .getReferentId()) {
+                hasMoreSpans = referentSpans.next();
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean skipTo(int target) throws IOException {
+        if (hasMoreSpans && (referentSpans.doc() < target)) {
+            if (!referentSpans.skipTo(target)) {
+                return false;
+            }
+        }
+        isStartEnumeration = false;
+        return advance();
+    }
+
+    @Override
+    public long cost() {
+
+        long cost = 0;
+        for (AttributeSpans as : attributeList) {
+            cost += as.cost();
+        }
+        for (AttributeSpans as : notAttributeList) {
+            cost += as.cost();
+        }
+        return referentSpans.cost() + cost;
+    }
 
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/TermSpansWithId.java b/src/main/java/de/ids_mannheim/korap/query/spans/TermSpansWithId.java
index 17844ae..b34a3f5 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/TermSpansWithId.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/TermSpansWithId.java
@@ -13,65 +13,88 @@
 
 import de.ids_mannheim.korap.query.SpanTermWithIdQuery;
 
-/** Enumeration of termSpans whose an id. This class just wraps the usual Lucene TermSpans, 
- * 	and adds spanid property. It reads the term-id from a term span payload. The term-id 
- * 	is encoded in a short, starting from (offset) 0 in the payload.
+/**
+ * Enumeration of termSpans having an id. This class just wraps the usual Lucene
+ * TermSpans, and adds spanid property. It reads the term-id from a term span
+ * payload. The term-id is encoded in a short, starting from (offset) 0 in the
+ * payload.
  * 
- * 	@author margaretha
+ * @author margaretha
  * */
-public class TermSpansWithId extends SpansWithId{
+public class TermSpansWithId extends SpansWithId {
 
-	private TermSpans termSpans;
+    private TermSpans termSpans;
 
-	public TermSpansWithId(SpanTermWithIdQuery spanTermWithIdQuery,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(spanTermWithIdQuery, context, acceptDocs, termContexts);
-		termSpans = (TermSpans) firstSpans;
-		hasMoreSpans = termSpans.next();
-	}
+    /**
+     * Creates TermSpansWithId from the given spanTermWithIdQuery.
+     * 
+     * @param spanTermWithIdQuery a spanTermWithIdQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public TermSpansWithId(SpanTermWithIdQuery spanTermWithIdQuery,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(spanTermWithIdQuery, context, acceptDocs, termContexts);
+        termSpans = (TermSpans) firstSpans;
+        hasMoreSpans = termSpans.next();
+    }
 
-	@Override
-	public boolean next() throws IOException {
-		isStartEnumeration=false;
-		return advance();
-	}
+    @Override
+    public boolean next() throws IOException {
+        isStartEnumeration = false;
+        return advance();
+    }
 
-	private boolean advance() throws IOException{
-		while (hasMoreSpans){
-			readPayload();
-			matchDocNumber = firstSpans.doc();
-			matchStartPosition = firstSpans.start();
-			matchEndPosition = firstSpans.end();
-			hasMoreSpans = firstSpans.next();
-			return true;
-		}
-		return false;
-	}
-	
-	private void readPayload() throws IOException{
-		List<byte[]> payload = (List<byte[]>) firstSpans.getPayload();
-		ByteBuffer bb = ByteBuffer.allocate(payload.get(0).length);
-		bb.put(payload.get(0));
-		setSpanId(bb.getShort(0)); //term id
-	}
-	
+    /**
+     * Advances to the next match and set it as the current match.
+     * 
+     * @return <code>true</code> if a match is found, <code>false</code>
+     *         otherwise.
+     * @throws IOException
+     */
+    private boolean advance() throws IOException {
+        while (hasMoreSpans) {
+            readPayload();
+            matchDocNumber = firstSpans.doc();
+            matchStartPosition = firstSpans.start();
+            matchEndPosition = firstSpans.end();
+            hasMoreSpans = firstSpans.next();
+            return true;
+        }
+        return false;
+    }
 
-	@Override
-	public boolean skipTo(int target) throws IOException {
-		if (hasMoreSpans && (firstSpans.doc() < target)){
-  			if (!firstSpans.skipTo(target)){
-  				return false;
-  			}
-  		}		
-		matchPayload.clear();
-		isStartEnumeration=false;
-		return advance();	
-	}
+    /**
+     * Read the payloads of the current firstspan and set the term id info from
+     * the payloads.
+     * 
+     * @throws IOException
+     */
+    private void readPayload() throws IOException {
+        List<byte[]> payload = (List<byte[]>) firstSpans.getPayload();
+        ByteBuffer bb = ByteBuffer.allocate(payload.get(0).length);
+        bb.put(payload.get(0));
+        setSpanId(bb.getShort(0)); //term id
+    }
 
-	@Override
-	public long cost() {
-		return firstSpans.cost(); // plus cost from reading payload
-	}
+    @Override
+    public boolean skipTo(int target) throws IOException {
+        if (hasMoreSpans && (firstSpans.doc() < target)) {
+            if (!firstSpans.skipTo(target)) {
+                return false;
+            }
+        }
+        matchPayload.clear();
+        isStartEnumeration = false;
+        return advance();
+    }
+
+    @Override
+    public long cost() {
+        return firstSpans.cost(); // plus cost from reading payload
+    }
 
 }
