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 968fa39..7beedc0 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
@@ -6,133 +6,251 @@
 
 import org.apache.lucene.search.spans.Spans;
 
-/** A span kept as a candidate for matching with another Span
- * 	@author margaretha
+/**
+ * A CandidateSpan works as an object storing the current state of the
+ * corresponding Lucene {@link Spans}, which is an enumeration. CandidateSpan is
+ * used for various purposes, such as for collecting spans which will be used in
+ * a latter process or next matching.
+ * 
+ * @author margaretha
  * */
-public class CandidateSpan implements Comparable<CandidateSpan>, Cloneable{	
-	private int doc,start,end;
-	private long cost;
-	private Collection<byte[]> payloads = new ArrayList<>();
-	private int position;
-	private CandidateSpan childSpan; // used for example for multiple distance with unordered constraint 
-	protected short spanId;
-	
-	
-	public CandidateSpan(Spans span) throws IOException {
-		this.doc = span.doc();
-		this.start = span.start();
-		this.end = span.end();
-		this.cost = span.cost();
-		if (span.isPayloadAvailable())
-			setPayloads(span.getPayload());
-	}	
-	
-	@Override
-	protected CandidateSpan clone() throws CloneNotSupportedException {
-		return new CandidateSpan(
-				this.start,
-				this.end,
-				this.doc,
-				this.cost,
-				this.payloads
-		);		
-	}
-	
-	public CandidateSpan(Spans span, int position) throws IOException {
-		this(span);
-		this.position = position;		
-	}
-	
-	public CandidateSpan(int start, int end, int doc, long cost,
-			Collection<byte[]> payloads) {
-		this.start = start;
-		this.end = end;
-		this.doc = doc;
-		this.cost = cost;
-		if (payloads != null) setPayloads(payloads);
-	}
+public class CandidateSpan implements Comparable<CandidateSpan>, Cloneable {
+    private int doc, start, end;
+    private long cost;
+    private Collection<byte[]> payloads = new ArrayList<>();
+    private int position;
+    private CandidateSpan childSpan; // used for example for multiple distance
+                                     // with unordered constraint
+    protected short spanId;
 
-	public int getDoc() {
-		return doc;
-	}
-	public void setDoc(int doc) {
-		this.doc = doc;
-	}
-	public int getStart() {
-		return start;
-	}
-	public void setStart(int start) {
-		this.start = start;
-	}
-	public int getEnd() {
-		return end;
-	}
-	public void setEnd(int end) {
-		this.end = end;
-	}
+    /**
+     * Constructs a CandidateSpan for the given Span.
+     * 
+     * @param span a Span
+     * @throws IOException
+     */
+    public CandidateSpan(Spans span) throws IOException {
+        this.doc = span.doc();
+        this.start = span.start();
+        this.end = span.end();
+        this.cost = span.cost();
+        if (span.isPayloadAvailable())
+            setPayloads(span.getPayload());
+    }
 
-	public Collection<byte[]> getPayloads() {
-		return payloads;
-	}
+    /**
+     * Constructs a CandidateSpan for the given Span and element position (where
+     * the span is included in a document). The element position is important
+     * for the matching process in {@link ElementDistanceSpans}.
+     * 
+     * @param span a Span
+     * @param position an element position
+     * @throws IOException
+     */
+    public CandidateSpan(Spans span, int position) throws IOException {
+        this(span);
+        this.position = position;
+    }
 
-	public void setPayloads(Collection<byte[]> payloads) {		
-		
-		for (byte[] b : payloads){			
-			if (b == null)				
-				this.payloads.add(null);			
-			else 
-				this.payloads.add(b.clone());			
-		}
-	}
+    /**
+     * Constructs a CandidateSpan from all the given variables which are
+     * properties of a Span.
+     * 
+     * @param start the start position of a span
+     * @param end the end position of a span
+     * @param doc the document including the span
+     * @param cost the cost of finding a span
+     * @param payloads the payloads of a span
+     */
+    public CandidateSpan(int start, int end, int doc, long cost,
+            Collection<byte[]> payloads) {
+        this.start = start;
+        this.end = end;
+        this.doc = doc;
+        this.cost = cost;
+        if (payloads != null)
+            setPayloads(payloads);
+    }
 
-	public long getCost() {
-		return cost;
-	}
+    @Override
+    protected CandidateSpan clone() throws CloneNotSupportedException {
+        return new CandidateSpan(this.start, this.end, this.doc, this.cost,
+                this.payloads);
+    }
 
-	public void setCost(long cost) {
-		this.cost = cost;
-	}
+    /**
+     * Returns the document number containing the CandidateSpan.
+     * 
+     * @return the document number
+     */
+    public int getDoc() {
+        return doc;
+    }
 
-	public int getPosition() {
-		return position;
-	}
+    /**
+     * Sets the document number containing the CandidateSpan.
+     * 
+     * @param doc the document number
+     */
+    public void setDoc(int doc) {
+        this.doc = doc;
+    }
 
-	public void setPosition(int position) {
-		this.position = position;
-	}
+    /**
+     * Returns the start position of the CandidateSpan.
+     * 
+     * @return the start position
+     */
+    public int getStart() {
+        return start;
+    }
 
-	public CandidateSpan getChildSpan() {
-		return childSpan;
-	}
+    /**
+     * Sets the start position of the CandidateSpan.
+     * 
+     * @param start the start position
+     */
+    public void setStart(int start) {
+        this.start = start;
+    }
 
-	public void setChildSpan(CandidateSpan childSpan) {
-		this.childSpan = childSpan;
-	}
+    /**
+     * Returns the end position of the CandidateSpan.
+     * 
+     * @return the end position
+     */
+    public int getEnd() {
+        return end;
+    }
 
-	public short getSpanId() {
-		return spanId;
-	}
+    /**
+     * Sets the end position of the CandidateSpan.
+     * 
+     * @param end the end position
+     */
+    public void setEnd(int end) {
+        this.end = end;
+    }
 
-	public void setSpanId(short elementRef) {
-		this.spanId = elementRef;
-	}
+    /**
+     * Returns the payloads of the CandidateSpan.
+     * 
+     * @return the payloads
+     */
+    public Collection<byte[]> getPayloads() {
+        return payloads;
+    }
 
-	@Override
-	public int compareTo(CandidateSpan o) {
-		if (this.doc == o.doc){
-			if (this.getStart() == o.getStart()){
-				if (this.getEnd() == o.getEnd())
-					return 0;	
-				if (this.getEnd() > o.getEnd() )
-					return 1;
-				else return -1;
-			}
-			else if (this.getStart() < o.getStart())
-				return -1;
-			else return 1;	
-		}
-		else if (this.doc < o.doc)
-			return -1;
-		else return 1;
-	}
+    /**
+     * Sets the payloads of the CandidateSpan.
+     * 
+     * @param payloads the payloads
+     */
+    public void setPayloads(Collection<byte[]> payloads) {
+
+        for (byte[] b : payloads) {
+            if (b == null)
+                this.payloads.add(null);
+            else
+                this.payloads.add(b.clone());
+        }
+    }
+
+    /**
+     * Returns the cost of finding the CandidateSpan.
+     * 
+     * @return the cost
+     */
+    public long getCost() {
+        return cost;
+    }
+
+    /**
+     * Sets the cost of finding the CandidateSpan.
+     * 
+     * @param cost the cost
+     */
+    public void setCost(long cost) {
+        this.cost = cost;
+    }
+
+    /**
+     * Returns the element position number containing the CandidateSpan.
+     * 
+     * @return the element position number
+     */
+    public int getPosition() {
+        return position;
+    }
+
+    /**
+     * Sets the element position number containing the CandidateSpan.
+     * 
+     * @param position the element position number
+     */
+    public void setPosition(int position) {
+        this.position = position;
+    }
+
+    /**
+     * Returns a child/sub Span of the CandidateSpan.
+     * 
+     * @return a child/sub span of the CandidateSpan
+     */
+    public CandidateSpan getChildSpan() {
+        return childSpan;
+    }
+
+    /**
+     * Sets the child/sub span of the CandidateSpan.
+     * 
+     * @param childSpan a child/sub span of the CandidateSpan
+     */
+    public void setChildSpan(CandidateSpan childSpan) {
+        this.childSpan = childSpan;
+    }
+
+    /**
+     * Returns the span id of another Span related to the CandidateSpan. Only
+     * CandidateSpan of particular Spans such as {@link AttributeSpans} having
+     * this property. For instance, an AttributeSpan has a spanId of the element
+     * it belongs to.
+     * 
+     * @return the span id of another Span related to the CandidateSpan
+     */
+    public short getSpanId() {
+        return spanId;
+    }
+
+    /**
+     * Sets the span id of another Span related to the CandidateSpan. Only
+     * CandidateSpan of particular Spans such as {@link AttributeSpans} having
+     * this property. For instance, an AttributeSpan has a spanId of the element
+     * it belongs to.
+     * 
+     * @param spanId the span id of another Span related to the CandidateSpan
+     */
+    public void setSpanId(short spanId) {
+        this.spanId = spanId;
+    }
+
+    @Override
+    public int compareTo(CandidateSpan o) {
+        if (this.doc == o.doc) {
+            if (this.getStart() == o.getStart()) {
+                if (this.getEnd() == o.getEnd())
+                    return 0;
+                if (this.getEnd() > o.getEnd())
+                    return 1;
+                else
+                    return -1;
+            } else if (this.getStart() < o.getStart())
+                return -1;
+            else
+                return 1;
+        } else if (this.doc < o.doc)
+            return -1;
+        else
+            return 1;
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
index 229004e..cad169a 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceSpans.java
@@ -12,145 +12,158 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/** Span enumeration of element-based distance span matches. 	
- * 	Each match consists of two child spans. The element-distance between 
- * 	the child spans is the difference between the element position numbers 
- * 	where the child spans are. The element-distance unit can be a sentence 
- * 	or a paragraph. All other child spans occurrence which are not in 
- * 	a sentence or a paragraph (with respect to the element distance type 
- * 	current used), are ignored.
- * 	
- * 	Note: elements cannot overlap to each other.
+/**
+ * Span enumeration of element-based distance span matches. Each match consists
+ * of two child spans. The element-distance between the child spans is the
+ * difference between the element position numbers where the child spans are.
+ * The element-distance unit can be a sentence or a paragraph. All other child
+ * spans' occurrences which are not in a sentence or a paragraph (with respect
+ * to the element distance type currently used), are ignored.
+ * 
+ * Note: elements cannot overlap to each other.
  * 
  * @author margaretha
  * */
 public class ElementDistanceSpans extends OrderedDistanceSpans {
 
-	private Spans elements;	
-	private boolean hasMoreElements;
-	private int elementPosition;	
-	private int secondSpanPostion;	
-		
-	public ElementDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts)
-			throws IOException {
-		super(query, context, acceptDocs, termContexts);
-  		
-  		elements = query.getElementQuery().
-  			getSpans(context, acceptDocs, termContexts);
-  		
-  		hasMoreElements = elements.next();
-  		hasMoreSpans = hasMoreFirstSpans && hasMoreElements;
-  		elementPosition=0;
-	}
+    private Spans elements;
+    private boolean hasMoreElements;
+    private int elementPosition;
+    private int secondSpanPostion;
 
-	@Override
-	protected boolean findMatch() throws IOException {
-		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
-		int actualDistance = secondSpanPostion - candidateSpan.getPosition();
-		
-		// In the same element
-		if (minDistance == 0 && actualDistance == 0){			
-			setMatchProperties(candidateSpan, true);
-			return true;			
-		}		
-		
-		if (minDistance <= actualDistance && actualDistance <= maxDistance){
-			setMatchProperties(candidateSpan, false);
-			return true;
-		}
-		
-		return false;
-	}
-	
-	@Override
-	protected void setCandidateList() throws IOException{
- 		if (candidateListDocNum == elements.doc() && 
- 				candidateListDocNum == secondSpans.doc()){
- 			candidateListIndex = -1;
- 			addNewCandidates();
- 		}
- 		else {
- 			candidateList.clear(); 			
- 			if (hasMoreFirstSpans && findSameDoc(firstSpans, secondSpans, elements)){
- 				candidateListDocNum = firstSpans.doc();
- 				elementPosition=0;
- 				candidateListIndex = -1;
- 				addNewCandidates();				
-			}		
-		}		
-	}
-	
-	/** Add new possible candidates. Candidates must be in an element 
-	 * 	and not too far from the secondspan.
-	 * */
-	private void addNewCandidates() throws IOException{		
-		while ( hasMoreFirstSpans && 
-				firstSpans.doc() == candidateListDocNum &&
-				firstSpans.start() < secondSpans.end()){
-			
-			if (advanceElementTo(firstSpans)){
-				candidateList.add(new CandidateSpan(firstSpans,elementPosition));				
-				filterCandidateList(elementPosition);
-			}
-			hasMoreFirstSpans = firstSpans.next();
-		}
-	}
-	
-	
-	/** Advance elements until encountering a span within the given document.
-	 * @return true iff an element containing the span, is found.
-	 */
-	private boolean advanceElementTo(Spans span) throws IOException{
-		while (hasMoreElements && 
-				elements.doc() == candidateListDocNum &&
-				elements.start() < span.end()){
-			
-			if (span.start() >= elements.start() &&
-					span.end() <= elements.end()){
-				return true;
-			}			
-			
-			hasMoreElements = elements.next();
-			elementPosition++;
-		}
-		return false;
-	}
-	
+    /**
+     * Constructs ElementDistanceSpans based on the given SpanDistanceQuery.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public ElementDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
 
-	/** Reduce the number of candidates by removing all candidates that are 
-	 * 	not within the max distance from the given element position.
-	 * */
-	private void filterCandidateList(int position){
-		
-		Iterator<CandidateSpan> i = candidateList.iterator();
-		CandidateSpan cs;
-		while(i.hasNext()){
-			cs = i.next();
-			if (cs.getPosition() == position || 
-					cs.getPosition()+maxDistance >= position){
-				break;
-			}
-			i.remove();
-		}		
-		//System.out.println("pos "+position+" " +candidateList.size());
-	}
-	
-	@Override
-	protected boolean isSecondSpanValid() throws IOException{
-		if (advanceElementTo(secondSpans)){
-			secondSpanPostion = elementPosition;
-			filterCandidateList(secondSpanPostion);
-			return true;
-		}
-		// second span is not in an element
-		return false;
-	}
-	
-	@Override
-	public long cost() {
-		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
-		return elements.cost() + candidateSpan.getCost() + secondSpans.cost();
-	}
+        elements = query.getElementQuery().getSpans(context, acceptDocs,
+                termContexts);
+
+        hasMoreElements = elements.next();
+        hasMoreSpans = hasMoreFirstSpans && hasMoreElements;
+        elementPosition = 0;
+    }
+
+    @Override
+    protected boolean findMatch() throws IOException {
+        CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
+        int actualDistance = secondSpanPostion - candidateSpan.getPosition();
+
+        // In the same element
+        if (minDistance == 0 && actualDistance == 0) {
+            setMatchProperties(candidateSpan, true);
+            return true;
+        }
+
+        if (minDistance <= actualDistance && actualDistance <= maxDistance) {
+            setMatchProperties(candidateSpan, false);
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    protected void setCandidateList() throws IOException {
+        if (candidateListDocNum == elements.doc()
+                && candidateListDocNum == secondSpans.doc()) {
+            candidateListIndex = -1;
+            addNewCandidates();
+        } else {
+            candidateList.clear();
+            if (hasMoreFirstSpans
+                    && findSameDoc(firstSpans, secondSpans, elements)) {
+                candidateListDocNum = firstSpans.doc();
+                elementPosition = 0;
+                candidateListIndex = -1;
+                addNewCandidates();
+            }
+        }
+    }
+
+    /**
+     * Add new possible (candidate) firstspans. Candidate firstspans must be in
+     * an element and not too far from the secondspan.
+     * 
+     * @throws IOException
+     */
+    private void addNewCandidates() throws IOException {
+        while (hasMoreFirstSpans && firstSpans.doc() == candidateListDocNum
+                && firstSpans.start() < secondSpans.end()) {
+
+            if (advanceElementTo(firstSpans)) {
+                candidateList
+                        .add(new CandidateSpan(firstSpans, elementPosition));
+                filterCandidateList(elementPosition);
+            }
+            hasMoreFirstSpans = firstSpans.next();
+        }
+    }
+
+    /**
+     * Advance elements until encountering a span within the given document.
+     * 
+     * @return true iff an element containing the span, is found.
+     */
+    private boolean advanceElementTo(Spans span) throws IOException {
+        while (hasMoreElements && elements.doc() == candidateListDocNum
+                && elements.start() < span.end()) {
+
+            if (span.start() >= elements.start()
+                    && span.end() <= elements.end()) {
+                return true;
+            }
+
+            hasMoreElements = elements.next();
+            elementPosition++;
+        }
+        return false;
+    }
+
+    /**
+     * Reduce the number of candidates by removing all candidates that are not
+     * within the max distance from the given element position.
+     * 
+     * @param position an element position
+     */
+    private void filterCandidateList(int position) {
+
+        Iterator<CandidateSpan> i = candidateList.iterator();
+        CandidateSpan cs;
+        while (i.hasNext()) {
+            cs = i.next();
+            if (cs.getPosition() == position
+                    || cs.getPosition() + maxDistance >= position) {
+                break;
+            }
+            i.remove();
+        }
+        // System.out.println("pos "+position+" " +candidateList.size());
+    }
+
+    @Override
+    protected boolean isSecondSpanValid() throws IOException {
+        if (advanceElementTo(secondSpans)) {
+            secondSpanPostion = elementPosition;
+            filterCandidateList(secondSpanPostion);
+            return true;
+        }
+        // second span is not in an element
+        return false;
+    }
+
+    @Override
+    public long cost() {
+        CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
+        return elements.cost() + candidateSpan.getCost() + secondSpans.cost();
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/OrderedDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/OrderedDistanceSpans.java
index 1dd1a04..52185e8 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/OrderedDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/OrderedDistanceSpans.java
@@ -12,120 +12,145 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/** Base class for calculating a distance between two ordered spans.
- * 	@author margaretha
+/**
+ * Base class for calculating a distance between two ordered spans.
+ * 
+ * @author margaretha
  * */
 public abstract class OrderedDistanceSpans extends DistanceSpans {
 
-        public static final boolean DEBUG = false;
+    protected boolean hasMoreFirstSpans;
+    protected int minDistance, maxDistance;
 
-	protected boolean hasMoreFirstSpans;	
-	protected int minDistance,maxDistance;
-	
-	protected List<CandidateSpan> candidateList;
-	protected int candidateListIndex;
-	protected int candidateListDocNum;
-	
-    
-	public OrderedDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts)
-			throws IOException {		
-		super(query, context, acceptDocs, termContexts);
-		
-		minDistance = query.getMinDistance();
-		maxDistance = query.getMaxDistance();		
-  		 		  		
-  		hasMoreFirstSpans = firstSpans.next();
-  		
-		candidateList = new ArrayList<>();
-		candidateListIndex = -1;
-		candidateListDocNum = firstSpans.doc();
-	}
-	
-	/** Find a span match in the candidate list.
-	 * */
-	@Override
-	protected boolean advance() throws IOException {
-		while( hasMoreSpans && candidateListIndex < candidateList.size() ){					
-			// Check candidates
-			for (candidateListIndex++;candidateListIndex < candidateList.size();
-					candidateListIndex++){
-				if (findMatch())					
-					return true;					
-			}			
-			
-			do { // Forward secondspan 
-				hasMoreSpans = secondSpans.next();
-				setCandidateList();
-			}
-			while (hasMoreSpans && !isSecondSpanValid());
-		}
-		return false;
-	}
-	
-	/** Determine if the current second span is valid. It is always valid in 
-	 * 	TokenDistanceSpan, but it can be invalid in the ElementDistanceSpan,
-	 * 	namely when it is not within a particular element (a sentence or a 
-	 * 	paragraph depends on the element distance unit).
-	 *  
-	 * */
-	protected abstract boolean isSecondSpanValid() throws IOException;
-	
-	/** Collect all possible firstspan instances as candidate spans for
-	 * 	the current secondspan. The candidate spans are within the max 
-	 * 	distance from the current secondspan. 
-	 * */
-	protected abstract void setCandidateList() throws IOException;
-	
-	/** Define the conditions for a match. 
-	 * */
-	protected abstract boolean findMatch() throws IOException;	
-	
-	/** Define the properties of a span match.
-	 * */
-	protected void setMatchProperties(CandidateSpan candidateSpan, 
-			boolean isDistanceZero) throws IOException{
-		
-		setMatchFirstSpan(candidateSpan);
-		setMatchSecondSpan(new CandidateSpan(secondSpans));
-		
-		if (isDistanceZero){
-			matchStartPosition = Math.min(candidateSpan.getStart(), secondSpans.start());
-			matchEndPosition = Math.max(candidateSpan.getEnd(), secondSpans.end());
-		}
-		else {
-			matchStartPosition = candidateSpan.getStart();
-			matchEndPosition = secondSpans.end();
-		}
-		
-		this.matchDocNumber = secondSpans.doc();		
-		if (collectPayloads){			
-  		    if (candidateSpan.getPayloads() != null) {
-  		    	matchPayload.addAll(candidateSpan.getPayloads()); 
-  		    }
-  		    if (secondSpans.isPayloadAvailable()) {
-  		    	matchPayload.addAll(secondSpans.getPayload());  		    	
-  		    }
-		}
+    protected List<CandidateSpan> candidateList;
+    protected int candidateListIndex;
+    protected int candidateListDocNum;
 
-		if (DEBUG)
-		    log.trace("doc# {}, start {}, end {}",matchDocNumber,matchStartPosition,
-			      matchEndPosition);	
-	}
+    /**
+     * Constructs an OrderedDistanceSpans based on the given SpanDistanceQuery.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public OrderedDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
 
-	@Override
-	public boolean skipTo(int target) throws IOException {
-		if (hasMoreSpans && (secondSpans.doc() < target)){
-  			if (!secondSpans.skipTo(target)){
-  				candidateList.clear();
-  				return false;
-  			}
-  		} 	
-		
-		setCandidateList();
-		matchPayload.clear();
-		isStartEnumeration=false;
-		return advance();
-	}
+        minDistance = query.getMinDistance();
+        maxDistance = query.getMaxDistance();
+
+        hasMoreFirstSpans = firstSpans.next();
+
+        candidateList = new ArrayList<>();
+        candidateListIndex = -1;
+        candidateListDocNum = firstSpans.doc();
+    }
+
+    /**
+     * Finds a span match in the candidate list.
+     * */
+    @Override
+    protected boolean advance() throws IOException {
+        while (hasMoreSpans && candidateListIndex < candidateList.size()) {
+            // Check candidates
+            for (candidateListIndex++; candidateListIndex < candidateList
+                    .size(); candidateListIndex++) {
+                if (findMatch())
+                    return true;
+            }
+
+            do { // Forward secondspan
+                hasMoreSpans = secondSpans.next();
+                setCandidateList();
+            } while (hasMoreSpans && !isSecondSpanValid());
+        }
+        return false;
+    }
+
+    /**
+     * Determines if the current second span is valid (i.e. within an element).
+     * It is always valid in TokenDistanceSpan, but it can be invalid in the
+     * ElementDistanceSpan, namely when it is not within a particular element (a
+     * sentence or a paragraph depends on the element distance unit).
+     * 
+     * @return <code>true</code> of the current second span is valid,
+     *         <code>false</code> otherwise.
+     * @throws IOException
+     */
+    protected abstract boolean isSecondSpanValid() throws IOException;
+
+    /**
+     * Stores/collects the states of all possible firstspans as candidate spans
+     * for the current secondspan. The candidate spans must be within the
+     * maximum distance from the current secondspan.
+     * 
+     * @throws IOException
+     */
+    protected abstract void setCandidateList() throws IOException;
+
+    /**
+     * Defines the conditions for a match and tells if a match is found.
+     * 
+     * @return <code>true</code> if a match is found, <code>false</code>
+     *         otherwise.
+     * @throws IOException
+     */
+    protected abstract boolean findMatch() throws IOException;
+
+    /**
+     * Defines the properties of a span match. The distance between the first
+     * and the second spans is zero, when there is an intersection between them
+     * in {@link TokenDistanceSpans}, or they occur in the same element in
+     * {@link ElementDistanceSpans}.
+     * 
+     * @param candidateSpan a match span
+     * @param isDistanceZero <code>true</code> if the distance between the first
+     *        and the second spans is zero, <code>false</code> otherwise.
+     * @throws IOException
+     */
+    protected void setMatchProperties(CandidateSpan candidateSpan,
+            boolean isDistanceZero) throws IOException {
+
+        setMatchFirstSpan(candidateSpan);
+        setMatchSecondSpan(new CandidateSpan(secondSpans));
+
+        if (isDistanceZero) {
+            matchStartPosition = Math.min(candidateSpan.getStart(),
+                    secondSpans.start());
+            matchEndPosition = Math.max(candidateSpan.getEnd(),
+                    secondSpans.end());
+        } else {
+            matchStartPosition = candidateSpan.getStart();
+            matchEndPosition = secondSpans.end();
+        }
+
+        this.matchDocNumber = secondSpans.doc();
+        if (collectPayloads) {
+            if (candidateSpan.getPayloads() != null) {
+                matchPayload.addAll(candidateSpan.getPayloads());
+            }
+            if (secondSpans.isPayloadAvailable()) {
+                matchPayload.addAll(secondSpans.getPayload());
+            }
+        }
+    }
+
+    @Override
+    public boolean skipTo(int target) throws IOException {
+        if (hasMoreSpans && (secondSpans.doc() < target)) {
+            if (!secondSpans.skipTo(target)) {
+                candidateList.clear();
+                return false;
+            }
+        }
+
+        setCandidateList();
+        matchPayload.clear();
+        isStartEnumeration = false;
+        return advance();
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
index f3c4907..150c61e 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/TokenDistanceSpans.java
@@ -12,95 +12,108 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/** Enumeration of token-based distance span matches. 
- * 	Each match consists of two specified spans having an actual distance
- *  in the range of the min and max distance parameters given in the query.
+/**
+ * Enumeration of token-based distance span matches consisting of two child
+ * spans having an actual distance in the range of the minimum and maximum
+ * distance parameters specified in the corresponding query.
  * 
- *	@author margaretha 
+ * @author margaretha
  * */
-public class TokenDistanceSpans extends OrderedDistanceSpans{
+public class TokenDistanceSpans extends OrderedDistanceSpans {
 
-	public TokenDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(query, context, acceptDocs, termContexts);		
-		hasMoreSpans = hasMoreFirstSpans;
-	}
-	
-	@Override
-	protected void setCandidateList() throws IOException{
- 		if (candidateListDocNum == secondSpans.doc()){						
-			copyPossibleCandidates();
-			addNewCandidates();
-			candidateListIndex = -1;
- 		}
- 		else {
- 			candidateList.clear(); 			
- 			if (hasMoreFirstSpans && ensureSameDoc(firstSpans,secondSpans)){
- 				candidateListDocNum = firstSpans.doc();
-				addNewCandidates();
-				candidateListIndex = -1;
-			}		
-		} 		
-	}
-	
-	/** Copy candidate spans which are still possible to create a match,
-	 * 	from the candidate list prepared for the previous second spans. 
-	 * */
-	private void copyPossibleCandidates(){
-		List<CandidateSpan> temp = new ArrayList<>();
-		for (CandidateSpan cs : candidateList){
-			if (cs.getEnd()+maxDistance > secondSpans.start())
-				temp.add(cs);
-		}
-		candidateList = temp;
-	}
-	
-	/** Add new possible candidates for the current secondspan.
-	 * */
-	private void addNewCandidates() throws IOException{
-		while ( hasMoreFirstSpans && 
-				firstSpans.doc() == candidateListDocNum &&
-				firstSpans.start() < secondSpans.end()){
-			
-			if (firstSpans.end()+maxDistance > secondSpans.start())
-				candidateList.add(new CandidateSpan(firstSpans));
-			
-			hasMoreFirstSpans = firstSpans.next();
-		}
-	}
-	
-	@Override
-	protected boolean findMatch() throws IOException {
-		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);		
-		if (minDistance == 0 &&
-				// intersection
-				candidateSpan.getStart() < secondSpans.end() && 
-				secondSpans.start() < candidateSpan.getEnd()){		
-			
-			setMatchProperties(candidateSpan, true);
-			return true;			
-		}
-		
-		int actualDistance = secondSpans.start() - candidateSpan.getEnd() +1;
-		if (candidateSpan.getStart() < secondSpans.start() &&
-				minDistance <= actualDistance && 
-				actualDistance <= maxDistance){					
-			
-			setMatchProperties(candidateSpan, false);
-			return true;
-		}		
-		return false;
-	}
-	
-	@Override
-	public long cost() {
-		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
-		return candidateSpan.getCost() + secondSpans.cost();
-	}
+    /**
+     * Constructs a TokenDistanceSpans from the given query.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public TokenDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
+        hasMoreSpans = hasMoreFirstSpans;
+    }
 
-	@Override
-	protected boolean isSecondSpanValid() throws IOException {
-		return true;
-	}
+    @Override
+    protected void setCandidateList() throws IOException {
+        if (candidateListDocNum == secondSpans.doc()) {
+            copyPossibleCandidates();
+            addNewCandidates();
+            candidateListIndex = -1;
+        } else {
+            candidateList.clear();
+            if (hasMoreFirstSpans && ensureSameDoc(firstSpans, secondSpans)) {
+                candidateListDocNum = firstSpans.doc();
+                addNewCandidates();
+                candidateListIndex = -1;
+            }
+        }
+    }
+
+    /**
+     * Restructures the candidateList to contain only candidate (first) spans
+     * which are still possible to create a match, from the candidate list
+     * prepared for the previous second spans.
+     * 
+     * */
+    private void copyPossibleCandidates() {
+        List<CandidateSpan> temp = new ArrayList<>();
+        for (CandidateSpan cs : candidateList) {
+            if (cs.getEnd() + maxDistance > secondSpans.start())
+                temp.add(cs);
+        }
+        candidateList = temp;
+    }
+
+    /**
+     * Add new possible firstspan candidates for the current secondspan.
+     * */
+    private void addNewCandidates() throws IOException {
+        while (hasMoreFirstSpans && firstSpans.doc() == candidateListDocNum
+                && firstSpans.start() < secondSpans.end()) {
+
+            if (firstSpans.end() + maxDistance > secondSpans.start())
+                candidateList.add(new CandidateSpan(firstSpans));
+
+            hasMoreFirstSpans = firstSpans.next();
+        }
+    }
+
+    @Override
+    protected boolean findMatch() throws IOException {
+        CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
+        if (minDistance == 0
+                &&
+                // intersection
+                candidateSpan.getStart() < secondSpans.end()
+                && secondSpans.start() < candidateSpan.getEnd()) {
+
+            setMatchProperties(candidateSpan, true);
+            return true;
+        }
+
+        int actualDistance = secondSpans.start() - candidateSpan.getEnd() + 1;
+        if (candidateSpan.getStart() < secondSpans.start()
+                && minDistance <= actualDistance
+                && actualDistance <= maxDistance) {
+
+            setMatchProperties(candidateSpan, false);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public long cost() {
+        CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
+        return candidateSpan.getCost() + secondSpans.cost();
+    }
+
+    @Override
+    protected boolean isSecondSpanValid() throws IOException {
+        return true;
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
index 7934f34..8f68c8d 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedDistanceSpans.java
@@ -15,227 +15,283 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/** Enumeration of span matches, whose two child spans have a specific range 
- * 	of distance (within a min and a max distance) and can be in any order. 
- * 	
- * 	@author margaretha
+/**
+ * Enumeration of span matches, whose two child spans have a specific range of
+ * distance (within a minimum and a maximum distance) and can occur in any
+ * order.
+ * 
+ * @author margaretha
  * */
-public abstract class UnorderedDistanceSpans extends DistanceSpans{
+public abstract class UnorderedDistanceSpans extends DistanceSpans {
 
-	protected int minDistance, maxDistance;
-	protected boolean hasMoreFirstSpans, hasMoreSecondSpans;
-	protected List<CandidateSpan> firstSpanList, secondSpanList;	
-	protected List<CandidateSpan> matchList;
-	private long matchCost;
-	private int matchListSpanNum; 	
-	protected int currentDocNum;
+    protected int minDistance, maxDistance;
+    protected boolean hasMoreFirstSpans, hasMoreSecondSpans;
+    protected List<CandidateSpan> firstSpanList, secondSpanList;
+    protected List<CandidateSpan> matchList;
+    private long matchCost;
+    private int matchListSpanNum;
+    protected int currentDocNum;
 
-    // This advices the java compiler to ignore all loggings
-    public static final boolean DEBUG = false;
+    /**
+     * Constructs an UnorderedDistanceSpans for the given
+     * {@link SpanDistanceQuery}.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public UnorderedDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
+        minDistance = query.getMinDistance();
+        maxDistance = query.getMaxDistance();
 
-	public UnorderedDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(query, context, acceptDocs, termContexts);
-		minDistance = query.getMinDistance();
-		maxDistance =  query.getMaxDistance();
-		
-		firstSpanList = new ArrayList<CandidateSpan>();
-		secondSpanList = new ArrayList<CandidateSpan>();
-		matchList = new ArrayList<CandidateSpan>();
-		
-		hasMoreFirstSpans = firstSpans.next();
-		hasMoreSecondSpans = secondSpans.next();
-		hasMoreSpans = hasMoreFirstSpans && hasMoreSecondSpans;
-	}
+        firstSpanList = new ArrayList<CandidateSpan>();
+        secondSpanList = new ArrayList<CandidateSpan>();
+        matchList = new ArrayList<CandidateSpan>();
 
-	@Override
-	protected boolean advance() throws IOException {		
-		while (hasMoreSpans || !matchList.isEmpty()){			
-			if (!matchList.isEmpty()){
-				setMatchProperties();				
-				return true;
-			} 			
-			if (prepareLists()) setMatchList();
-		}
-		return false;
-	}
-	
-	/** Add the next possible first and second spans. Both the spans must be in the
-	 * 	same document. In UnorderedElementDistanceSpans, a span that is not in 
-	 * 	an element, is not added to its candidate list. The element must also be in
-	 * 	the same document.
-	 *   
-	 * 	@return true iff at least one of the candidate lists can be filled.
-	 * */
-	protected abstract boolean prepareLists() throws IOException;
-	
-	/** Set the list of matches between the span having the smallest position, and 
-	 * 	its candidates. Simply remove the span if it does not have any candidates.
-	 * */
-	protected void setMatchList() throws IOException {
-		
-		hasMoreFirstSpans = setCandidateList(firstSpanList,firstSpans,
-				hasMoreFirstSpans,secondSpanList);
-		hasMoreSecondSpans = setCandidateList(secondSpanList,secondSpans,
-				hasMoreSecondSpans,firstSpanList);
-//		System.out.println("--------------------");
-//		System.out.println("firstSpanList:");
-//		for (CandidateSpan cs: firstSpanList) {
-//			System.out.println(cs.getStart() +" "+ cs.getEnd());
-//		}
-//		
-//		System.out.println("secondSpanList:");
-//		for (CandidateSpan cs: secondSpanList) {
-//			System.out.println(cs.getStart() +" "+ cs.getEnd());
-//		}
-		
-		CandidateSpan currentFirstSpan, currentSecondSpan;
-		if (!firstSpanList.isEmpty() && !secondSpanList.isEmpty()){
-			
-			currentFirstSpan = firstSpanList.get(0)	;
-			currentSecondSpan = secondSpanList.get(0);
-			
-			if (currentFirstSpan.getEnd() < currentSecondSpan.getEnd() ||					 
-					isLastCandidateSmaller(currentFirstSpan, currentSecondSpan)){
-			    if (DEBUG)
-				log.trace("current target: "+firstSpanList.get(0).getStart() +" "+firstSpanList.get(0).getEnd());				
-//				System.out.println("candidates:");
-//				for (CandidateSpan cs: secondSpanList) {
-//					System.out.println(cs.getStart() +" "+ cs.getEnd());
-//				}
-				
-				matchList = findMatches(currentFirstSpan, secondSpanList);
-				setMatchFirstSpan(currentFirstSpan);
-				matchListSpanNum = 2;
-				updateList(firstSpanList);
-			}			
-			else {
-			    if (DEBUG)
-				log.trace("current target: "+secondSpanList.get(0).getStart() +" "+secondSpanList.get(0).getEnd());
-//				System.out.println("candidates:");
-//				for (CandidateSpan cs: firstSpanList) {
-//					System.out.println(cs.getStart() +" "+ cs.getEnd());
-//				}
-				
-				matchList = findMatches(currentSecondSpan, firstSpanList);
-				setMatchSecondSpan(currentSecondSpan);
-				matchListSpanNum = 1;
-				updateList(secondSpanList);
-			}
-		}
-		else if (firstSpanList.isEmpty()){
-		    if (DEBUG) {
-			log.trace("current target: "+secondSpanList.get(0).getStart() +" "+secondSpanList.get(0).getEnd());
-			log.trace("candidates: empty");
-		    };
-			updateList(secondSpanList);			
-		}
-		else{
-		    if (DEBUG) {
-			log.trace("current target: "+firstSpanList.get(0).getStart() +" "+firstSpanList.get(0).getEnd());
-			log.trace("candidates: empty");
-		    };
-			updateList(firstSpanList);			
-		}
-	}
-	
-	private boolean isLastCandidateSmaller(CandidateSpan currentFirstSpan, CandidateSpan 
-			currentSecondSpan){
-		if (currentFirstSpan.getEnd() == currentSecondSpan.getEnd() ){
-			int secondEnd = secondSpanList.get(secondSpanList.size()-1).getEnd();
-			int firstEnd = firstSpanList.get(firstSpanList.size()-1).getEnd();
-			return (secondEnd < firstEnd ? true : false);
-		}
-		
-		return false;
-	}
-	
-	protected abstract void updateList(List<CandidateSpan> candidateList);
-	
-	/** Set the candidate list for the first element in the target list.
-	 * @return true iff the spans enumeration still has a next element 
-	 * to be a candidate
-	 */
-	protected abstract boolean setCandidateList(List<CandidateSpan> 
-			candidateList, Spans candidate, boolean hasMoreCandidates,
-			List<CandidateSpan> targetList) throws IOException;
-	
-	/** Search all matches between the target span and its candidates in the candidate 
-	 * 	list.
-	 * 	@return the matches in a list 
-	 * */
-	protected abstract List<CandidateSpan> findMatches(CandidateSpan target, 
-			List<CandidateSpan> candidateList);
-	
-	/** Compute match properties and create a candidate span match 
-	 * 	to be added to the match list.
-	 * 	@return a candidate span match 
-	 * */
-	protected CandidateSpan createMatchCandidate(CandidateSpan target,
-			CandidateSpan cs, boolean isDistanceZero) {
-		
-		int start = Math.min(target.getStart(), cs.getStart());
-		int end = Math.max(target.getEnd(),cs.getEnd());
-		int doc = target.getDoc();
-		long cost = target.getCost() + cs.getCost();
-		
-		Collection<byte[]> payloads = new LinkedList<byte[]>();
-		if (collectPayloads) {
-			if (target.getPayloads() != null){
-				payloads.addAll(target.getPayloads());
-			}
-			if (cs.getPayloads() != null){
-				payloads.addAll(cs.getPayloads());
-			}
-		}
-		
-		CandidateSpan match = new CandidateSpan(start,end,doc,cost,payloads);
-		match.setChildSpan(cs);
-		return match;
-	}
+        hasMoreFirstSpans = firstSpans.next();
+        hasMoreSecondSpans = secondSpans.next();
+        hasMoreSpans = hasMoreFirstSpans && hasMoreSecondSpans;
+    }
 
-	/** Assign the first candidate span in the match list as the current span match.
-	 * */
-	private void setMatchProperties() {
-		CandidateSpan cs = matchList.get(0);
-		matchDocNumber = cs.getDoc();
-		matchStartPosition = cs.getStart();
-		matchEndPosition = cs.getEnd();
-		matchCost = cs.getCost();
-		matchPayload.addAll(cs.getPayloads());
-		matchList.remove(0);
-		
-		if (matchListSpanNum == 1)
-			setMatchFirstSpan(cs.getChildSpan());
-		else setMatchSecondSpan(cs.getChildSpan());
+    @Override
+    protected boolean advance() throws IOException {
+        while (hasMoreSpans || !matchList.isEmpty()) {
+            if (!matchList.isEmpty()) {
+                setMatchProperties();
+                return true;
+            }
+            if (prepareLists())
+                setMatchList();
+        }
+        return false;
+    }
 
-		if (DEBUG) {
-		    log.trace("Match doc#={} start={} end={}",matchDocNumber,matchStartPosition,matchEndPosition);
-		    log.trace("firstspan "+getMatchFirstSpan().getStart()+" "+ getMatchFirstSpan().getEnd());
-		    log.trace("secondspan "+getMatchSecondSpan().getStart()+" "+ getMatchSecondSpan().getEnd());
-		};
-	}
+    /**
+     * Updates the firstSpanList and secondSpanList by adding the next possible
+     * first and second spans. Both the spans must be in the same document. In
+     * UnorderedElementDistanceSpans, a span that is not in an element (distance
+     * unit), is not added to its candidate list. The element must also be in
+     * the same document.
+     * 
+     * @return <code>true</code> if at least one of the candidate lists can be
+     *         filled, <code>false</code> otherwise.
+     * @throws IOException
+     */
+    protected abstract boolean prepareLists() throws IOException;
 
-	@Override
-	public boolean skipTo(int target) throws IOException {
-		if (hasMoreSpans && (secondSpans.doc() < target)){
-  			if (!secondSpans.skipTo(target)){
-  				hasMoreSpans = false;
-  				return false;
-  			}  			
-  		}
-		
-		firstSpanList.clear();
-		secondSpanList.clear();
-		matchPayload.clear();
-		isStartEnumeration=false;
-		return advance();		
-	}
+    /**
+     * Sets the list of matches for the span having the smallest position (i.e.
+     * between the first and the second spans), and its candidates (i.e. its
+     * counterparts). The candidates also must have smaller positions. Simply
+     * remove the span if it does not have any candidates.
+     * 
+     * @throws IOException
+     */
+    protected void setMatchList() throws IOException {
 
-	@Override
-	public long cost() {
-		return matchCost;
-	}
+        hasMoreFirstSpans = setCandidateList(firstSpanList, firstSpans,
+                hasMoreFirstSpans, secondSpanList);
+        hasMoreSecondSpans = setCandidateList(secondSpanList, secondSpans,
+                hasMoreSecondSpans, firstSpanList);
+        // System.out.println("--------------------");
+        // System.out.println("firstSpanList:");
+        // for (CandidateSpan cs: firstSpanList) {
+        // System.out.println(cs.getStart() +" "+ cs.getEnd());
+        // }
+        //
+        // System.out.println("secondSpanList:");
+        // for (CandidateSpan cs: secondSpanList) {
+        // System.out.println(cs.getStart() +" "+ cs.getEnd());
+        // }
+
+        CandidateSpan currentFirstSpan, currentSecondSpan;
+        if (!firstSpanList.isEmpty() && !secondSpanList.isEmpty()) {
+
+            currentFirstSpan = firstSpanList.get(0);
+            currentSecondSpan = secondSpanList.get(0);
+
+            if (currentFirstSpan.getEnd() < currentSecondSpan.getEnd()
+                    || isLastCandidateSmaller(currentFirstSpan,
+                            currentSecondSpan)) {
+                // log.trace("current target: "
+                // + firstSpanList.get(0).getStart() + " "
+                // + firstSpanList.get(0).getEnd());
+                // System.out.println("candidates:");
+                // for (CandidateSpan cs: secondSpanList) {
+                // System.out.println(cs.getStart() +" "+ cs.getEnd());
+                // }
+
+                matchList = findMatches(currentFirstSpan, secondSpanList);
+                setMatchFirstSpan(currentFirstSpan);
+                matchListSpanNum = 2;
+                updateList(firstSpanList);
+            } else {
+                // log.trace("current target: "
+                // + secondSpanList.get(0).getStart() + " "
+                // + secondSpanList.get(0).getEnd());
+                // System.out.println("candidates:");
+                // for (CandidateSpan cs: firstSpanList) {
+                // System.out.println(cs.getStart() +" "+ cs.getEnd());
+                // }
+
+                matchList = findMatches(currentSecondSpan, firstSpanList);
+                setMatchSecondSpan(currentSecondSpan);
+                matchListSpanNum = 1;
+                updateList(secondSpanList);
+            }
+        } else if (firstSpanList.isEmpty()) {
+            // log.trace("current target: " + secondSpanList.get(0).getStart()
+            // + " " + secondSpanList.get(0).getEnd());
+            // log.trace("candidates: empty");
+            updateList(secondSpanList);
+        } else {
+            // log.trace("current target: " + firstSpanList.get(0).getStart()
+            // + " " + firstSpanList.get(0).getEnd());
+            // log.trace("candidates: empty");
+            updateList(firstSpanList);
+        }
+    }
+
+    /**
+     * Tells if the last candidate from the secondSpanList has a smaller end
+     * position than the end position of the the last candidate from the
+     * firstSpanList.
+     * 
+     * @param currentFirstSpan the current firstspan
+     * @param currentSecondSpan the current secondspan
+     * @return <code>true</code> if the end position of the last candidate from
+     *         the secondSpanList is smaller than that from the firstSpanList,
+     *         <code>false</code> otherwise.
+     */
+    private boolean isLastCandidateSmaller(CandidateSpan currentFirstSpan,
+            CandidateSpan currentSecondSpan) {
+        if (currentFirstSpan.getEnd() == currentSecondSpan.getEnd()) {
+            int secondEnd = secondSpanList.get(secondSpanList.size() - 1)
+                    .getEnd();
+            int firstEnd = firstSpanList.get(firstSpanList.size() - 1).getEnd();
+            return (secondEnd < firstEnd ? true : false);
+        }
+
+        return false;
+    }
+
+    /**
+     * Performs an update based on the given candidateList. In
+     * {@link UnorderedTokenDistanceSpans}, the first candidate in the
+     * candidateList is simply removed. In {@link UnorderedElementDistanceSpans}
+     * , the elementList is also updated.
+     * 
+     * @param candidateList a candidateList
+     */
+    protected abstract void updateList(List<CandidateSpan> candidateList);
+
+    /**
+     * Sets the candidate list for the first element in the target list and
+     * tells if the the specified spans has finished or not.
+     * 
+     * @param candidateList a list of candidate spans
+     * @param candidate a Spans
+     * @param hasMoreCandidates a boolean
+     * @param targetList a list of target spans
+     * @return <code>true</code> if the span enumeration still has a next
+     *         element to be a candidate, <code>false</code> otherwise.
+     * @throws IOException
+     */
+    protected abstract boolean setCandidateList(
+            List<CandidateSpan> candidateList, Spans candidate,
+            boolean hasMoreCandidates, List<CandidateSpan> targetList)
+            throws IOException;
+
+    /**
+     * Finds all matches between the target span and its candidates in the
+     * candidate list.
+     * 
+     * @param target a target span
+     * @param candidateList a candidate list
+     * @return the matches in a list
+     */
+    protected abstract List<CandidateSpan> findMatches(CandidateSpan target,
+            List<CandidateSpan> candidateList);
+
+    /**
+     * Computes match properties and creates a candidate span match to be added
+     * to the match list.
+     * 
+     * @return a candidate span match
+     * */
+    protected CandidateSpan createMatchCandidate(CandidateSpan target,
+            CandidateSpan cs, boolean isDistanceZero) {
+
+        int start = Math.min(target.getStart(), cs.getStart());
+        int end = Math.max(target.getEnd(), cs.getEnd());
+        int doc = target.getDoc();
+        long cost = target.getCost() + cs.getCost();
+
+        Collection<byte[]> payloads = new LinkedList<byte[]>();
+        if (collectPayloads) {
+            if (target.getPayloads() != null) {
+                payloads.addAll(target.getPayloads());
+            }
+            if (cs.getPayloads() != null) {
+                payloads.addAll(cs.getPayloads());
+            }
+        }
+
+        CandidateSpan match = new CandidateSpan(start, end, doc, cost, payloads);
+        match.setChildSpan(cs);
+        return match;
+    }
+
+    /**
+     * Assigns the first candidate span in the match list as the current span
+     * match, and removes it from the matchList.
+     * */
+    private void setMatchProperties() {
+        CandidateSpan cs = matchList.get(0);
+        matchDocNumber = cs.getDoc();
+        matchStartPosition = cs.getStart();
+        matchEndPosition = cs.getEnd();
+        matchCost = cs.getCost();
+        matchPayload.addAll(cs.getPayloads());
+        matchList.remove(0);
+
+        if (matchListSpanNum == 1)
+            setMatchFirstSpan(cs.getChildSpan());
+        else
+            setMatchSecondSpan(cs.getChildSpan());
+
+        // log.trace("Match doc#={} start={} end={}", matchDocNumber,
+        // matchStartPosition, matchEndPosition);
+        // log.trace("firstspan " + getMatchFirstSpan().getStart() + " "
+        // + getMatchFirstSpan().getEnd());
+        // log.trace("secondspan " + getMatchSecondSpan().getStart() + " "
+        // + getMatchSecondSpan().getEnd());
+    }
+
+    @Override
+    public boolean skipTo(int target) throws IOException {
+        if (hasMoreSpans && (secondSpans.doc() < target)) {
+            if (!secondSpans.skipTo(target)) {
+                hasMoreSpans = false;
+                return false;
+            }
+        }
+
+        firstSpanList.clear();
+        secondSpanList.clear();
+        matchPayload.clear();
+        isStartEnumeration = false;
+        return advance();
+    }
+
+    @Override
+    public long cost() {
+        return matchCost;
+    }
 
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
index a0c4474..102b5c9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedElementDistanceSpans.java
@@ -14,213 +14,248 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/**	Enumeration of span matches, whose two child spans have a specific range 
- * 	of distance (within a min and a max distance) and can be in any order. 
- * 	The unit distance is an element position, where element can be a sentence 
- * 	or a paragraph.
+/**
+ * Enumeration of span matches, whose two child spans have a specific range of
+ * distance (within a min and a max distance) and can be in any order. The unit
+ * distance is an element, which can be a sentence or a paragraph for instance.
+ * The distance is the difference between the positions of elements containing
+ * the spans.
  * 
  * @author margaretha
  * */
-public class UnorderedElementDistanceSpans extends UnorderedDistanceSpans{
-	
-	private Spans elements;	
-	private boolean hasMoreElements;
-	private int elementPosition;
-	
-	// contains all previous elements whose position is greater than the last 
-	// target span
-	private List<CandidateSpan> elementList;
-	
-	public UnorderedElementDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(query, context, acceptDocs, termContexts);		
-		elements = query.getElementQuery().
-	  			getSpans(context, acceptDocs, termContexts);	  		
-  		hasMoreElements = elements.next();  		
-  		elementPosition=0;  		
-  		elementList = new ArrayList<CandidateSpan>();  		
-	}
-	
-	@Override
-	protected boolean prepareLists() throws IOException {
-		
-		if (firstSpanList.isEmpty() && secondSpanList.isEmpty()){			
-			if (hasMoreFirstSpans && hasMoreSecondSpans && hasMoreElements &&
-					findSameDoc(firstSpans, secondSpans, elements)){				
-				
-				if (currentDocNum != firstSpans.doc()){
-					currentDocNum = firstSpans.doc();
-					elementList.clear();
-				}				
-								
-				hasMoreFirstSpans = addSpan(firstSpans,firstSpanList,hasMoreFirstSpans);
-				hasMoreSecondSpans = addSpan(secondSpans, secondSpanList, hasMoreSecondSpans);												
-			}
-			else {
-				hasMoreSpans = false;
-				return false;
-			}
-		}		
-		else if (firstSpanList.isEmpty() && hasMoreFirstSpans && 
-				firstSpans.doc() == currentDocNum){
-			hasMoreFirstSpans = addSpan(firstSpans,firstSpanList,hasMoreFirstSpans);
-		}
-		else if (secondSpanList.isEmpty() && hasMoreSecondSpans && 
-				secondSpans.doc() == currentDocNum){
-			hasMoreSecondSpans = addSpan(secondSpans, secondSpanList, hasMoreSecondSpans);
-		}
-		
-		return true;
-	}
-	
-	private boolean addSpan(Spans span, List<CandidateSpan> list, boolean hasMoreSpan) 
-			throws IOException {
-		int position;
-		while (hasMoreSpan && span.doc() == currentDocNum){
-			position = findElementPosition(span);
-			if (position != -1){
-				list.add(new CandidateSpan(span,position));
-				hasMoreSpan = span.next();
-				return hasMoreSpan;
-			}
-			hasMoreSpan = span.next();
-		}
-		return hasMoreSpan;
-	}
-	
-	
-	/** Find the element position of the span in the element list or by advancing 
-	 * 	the element spans until encountering the span.
-	 * 
-	 * 	@return the element position
-	 * */
-	private int findElementPosition(Spans span) throws IOException {
-		// Check in the element list
-		if (!elementList.isEmpty() && 
-				span.end() <= elementList.get(elementList.size()-1).getEnd()){
-			
-			for (CandidateSpan e : elementList)
-				if (e.getEnd() >= span.end() && e.getStart() <= span.start()){
-					return e.getPosition();
-				}
-			return -1; // The span is not in an element.
-		}
-		
-		return ( advanceElementTo(span) ? elementPosition : -1 );			
-	}
-		
-	/** Advance the element spans until encountering the given span.
-	 * 	
-	 * @return true iff such an element is found, false if the span is not in 
-	 * 	an element.
-	 * */
-	private boolean advanceElementTo(Spans span) throws IOException {
-		while (hasMoreElements && 
-				elements.doc() == currentDocNum &&
-				elements.start() < span.end()){
-			
-			if (span.start() >= elements.start() &&
-					span.end() <= elements.end()){
-				return true;
-			}
-			elementList.add(new CandidateSpan(elements,elementPosition));
-			hasMoreElements = elements.next();
-			elementPosition++;			
-		}
-		
-		return false; // invalid
-	}
+public class UnorderedElementDistanceSpans extends UnorderedDistanceSpans {
 
-	@Override
-	protected boolean setCandidateList(List<CandidateSpan> 
-			candidateList, Spans candidate, boolean hasMoreCandidates,
-			List<CandidateSpan> targetList) throws IOException {
-		 
-		if (!targetList.isEmpty()){			
-			CandidateSpan cs;
-			CandidateSpan target = targetList.get(0);
-			int position;
-			while (hasMoreCandidates && candidate.doc() == target.getDoc()){
-				position = findElementPosition(candidate); 
-				if (position != -1){
-					cs = new CandidateSpan(candidate,position);
-					
-					if (isWithinMaxDistance(target, cs)){
-						candidateList.add(cs);						
-					}
-					else break;
-				}
-				hasMoreCandidates = candidate.next();
-			}
-		}
-		return hasMoreCandidates;
-	}
-	
-	/** Check if the target and candidate spans are not too far from each other.
-	 *  
-	 *  @return true iff the target and candidate spans are within the maximum
-	 *  distance
-	 * */
-	protected boolean isWithinMaxDistance(CandidateSpan target, CandidateSpan candidate) {
-		int candidatePos = candidate.getPosition();
-		int targetPos = target.getPosition();
-		
-		// left candidate
-		if (candidatePos < targetPos && 
-				candidatePos + maxDistance < targetPos){
-			return false;
-		}
-		// right candidate
-		if (candidatePos > targetPos &&
-				targetPos + maxDistance < candidatePos){
-			return false;
-		}
-		return true;
-	}
-	
-	@Override
-	protected List<CandidateSpan> findMatches(CandidateSpan target, List<CandidateSpan> 
-			candidateList) {
-		
-		List<CandidateSpan> matches = new ArrayList<>();
-		
-		int actualDistance;
-		int targetPos = target.getPosition();		
-		
-		for (CandidateSpan cs : candidateList){						
-			actualDistance = Math.abs( targetPos - cs.getPosition() );
-			
-			if (minDistance == 0 && actualDistance == 0){
-				matches.add(createMatchCandidate(target,cs,true));
-				continue;
-			}
-			 
-			if (minDistance <= actualDistance && actualDistance <= maxDistance)
-				matches.add(createMatchCandidate(target, cs, false));
-		}		
-		return matches;
-	}
+    private Spans elements;
+    private boolean hasMoreElements;
+    private int elementPosition;
 
-	@Override
-	protected void updateList(List<CandidateSpan> candidateList) {
-		updateElementList(candidateList.get(0).getPosition());
-		candidateList.remove(0);
-	}
-	
-	/** Reduce the number of elements kept in the element list by removing the element
-	 * 	whose position is smaller than or identical to the position of the last target 
-	 * 	span.
-	 * */
-	private void updateElementList(int position){
-		Iterator<CandidateSpan> i = elementList.iterator();
-		CandidateSpan e;
-		while(i.hasNext()){
-			e = i.next();			
-			if (e.getPosition() <= position) {
-				i.remove();
-			}
-			break;
-		}
-	}
+    // contains all previous elements whose position is greater than the last
+    // target span
+    private List<CandidateSpan> elementList;
+
+    /**
+     * Constructs an UnorderedElementDistanceSpans for the given
+     * {@link SpanDistanceQuery}.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public UnorderedElementDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
+        elements = query.getElementQuery().getSpans(context, acceptDocs,
+                termContexts);
+        hasMoreElements = elements.next();
+        elementPosition = 0;
+        elementList = new ArrayList<CandidateSpan>();
+    }
+
+    @Override
+    protected boolean prepareLists() throws IOException {
+
+        if (firstSpanList.isEmpty() && secondSpanList.isEmpty()) {
+            if (hasMoreFirstSpans && hasMoreSecondSpans && hasMoreElements
+                    && findSameDoc(firstSpans, secondSpans, elements)) {
+
+                if (currentDocNum != firstSpans.doc()) {
+                    currentDocNum = firstSpans.doc();
+                    elementList.clear();
+                }
+
+                hasMoreFirstSpans = addSpan(firstSpans, firstSpanList,
+                        hasMoreFirstSpans);
+                hasMoreSecondSpans = addSpan(secondSpans, secondSpanList,
+                        hasMoreSecondSpans);
+            } else {
+                hasMoreSpans = false;
+                return false;
+            }
+        } else if (firstSpanList.isEmpty() && hasMoreFirstSpans
+                && firstSpans.doc() == currentDocNum) {
+            hasMoreFirstSpans = addSpan(firstSpans, firstSpanList,
+                    hasMoreFirstSpans);
+        } else if (secondSpanList.isEmpty() && hasMoreSecondSpans
+                && secondSpans.doc() == currentDocNum) {
+            hasMoreSecondSpans = addSpan(secondSpans, secondSpanList,
+                    hasMoreSecondSpans);
+        }
+
+        return true;
+    }
+
+    /**
+     * Adds all the spans occurring in the current document, as CandidateSpans
+     * to the specified candidate list, and tells if the enumeration of the
+     * spans has finished, or not.
+     * 
+     * @param span a Span
+     * @param list a candidateList
+     * @param hasMoreSpan a boolean describing if the span enumeration has
+     *        finished or not.
+     * @return <code>true</code> if the the span enumeration has finished,
+     *         <code>false</code> otherwise.
+     * @throws IOException
+     */
+    private boolean addSpan(Spans span, List<CandidateSpan> list,
+            boolean hasMoreSpan) throws IOException {
+        int position;
+        while (hasMoreSpan && span.doc() == currentDocNum) {
+            position = findElementPosition(span);
+            if (position != -1) {
+                list.add(new CandidateSpan(span, position));
+                hasMoreSpan = span.next();
+                return hasMoreSpan;
+            }
+            hasMoreSpan = span.next();
+        }
+        return hasMoreSpan;
+    }
+
+    /**
+     * Finds the element position of the specified span in the element list or
+     * by advancing the element spans until encountering the span.
+     * 
+     * @param span a Span
+     * @return the element position
+     * @throws IOException
+     */
+    private int findElementPosition(Spans span) throws IOException {
+        // Check in the element list
+        if (!elementList.isEmpty()
+                && span.end() <= elementList.get(elementList.size() - 1)
+                        .getEnd()) {
+
+            for (CandidateSpan e : elementList)
+                if (e.getEnd() >= span.end() && e.getStart() <= span.start()) {
+                    return e.getPosition();
+                }
+            return -1; // The span is not in an element.
+        }
+
+        return (advanceElementTo(span) ? elementPosition : -1);
+    }
+
+    /**
+     * Advances the element spans until encountering the given span.
+     * 
+     * @param span
+     * @return <code>true</code> if such an element is found, <code>false</code>
+     *         if the span is not in an element.
+     * @throws IOException
+     */
+    private boolean advanceElementTo(Spans span) throws IOException {
+        while (hasMoreElements && elements.doc() == currentDocNum
+                && elements.start() < span.end()) {
+
+            if (span.start() >= elements.start()
+                    && span.end() <= elements.end()) {
+                return true;
+            }
+            elementList.add(new CandidateSpan(elements, elementPosition));
+            hasMoreElements = elements.next();
+            elementPosition++;
+        }
+
+        return false; // invalid
+    }
+
+    @Override
+    protected boolean setCandidateList(List<CandidateSpan> candidateList,
+            Spans candidate, boolean hasMoreCandidates,
+            List<CandidateSpan> targetList) throws IOException {
+
+        if (!targetList.isEmpty()) {
+            CandidateSpan cs;
+            CandidateSpan target = targetList.get(0);
+            int position;
+            while (hasMoreCandidates && candidate.doc() == target.getDoc()) {
+                position = findElementPosition(candidate);
+                if (position != -1) {
+                    cs = new CandidateSpan(candidate, position);
+
+                    if (isWithinMaxDistance(target, cs)) {
+                        candidateList.add(cs);
+                    } else
+                        break;
+                }
+                hasMoreCandidates = candidate.next();
+            }
+        }
+        return hasMoreCandidates;
+    }
+
+    /**
+     * Tells if the target and candidate spans are not too far from each other
+     * (within the maximum distance).
+     * 
+     * @return <code>true</code> if the target and candidate spans are within
+     *         the maximum distance, <code>false</code> otherwise.
+     * */
+    protected boolean isWithinMaxDistance(CandidateSpan target,
+            CandidateSpan candidate) {
+        int candidatePos = candidate.getPosition();
+        int targetPos = target.getPosition();
+
+        // left candidate
+        if (candidatePos < targetPos && candidatePos + maxDistance < targetPos) {
+            return false;
+        }
+        // right candidate
+        if (candidatePos > targetPos && targetPos + maxDistance < candidatePos) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    protected List<CandidateSpan> findMatches(CandidateSpan target,
+            List<CandidateSpan> candidateList) {
+
+        List<CandidateSpan> matches = new ArrayList<>();
+
+        int actualDistance;
+        int targetPos = target.getPosition();
+
+        for (CandidateSpan cs : candidateList) {
+            actualDistance = Math.abs(targetPos - cs.getPosition());
+
+            if (minDistance == 0 && actualDistance == 0) {
+                matches.add(createMatchCandidate(target, cs, true));
+                continue;
+            }
+
+            if (minDistance <= actualDistance && actualDistance <= maxDistance)
+                matches.add(createMatchCandidate(target, cs, false));
+        }
+        return matches;
+    }
+
+    @Override
+    protected void updateList(List<CandidateSpan> candidateList) {
+        updateElementList(candidateList.get(0).getPosition());
+        candidateList.remove(0);
+    }
+
+    /**
+     * Reduces the number of elements kept in the element list by removing the
+     * elements whose position is smaller than or identical to the position of
+     * the last target span.
+     * 
+     * @param position the last target span position
+     */
+    private void updateElementList(int position) {
+        Iterator<CandidateSpan> i = elementList.iterator();
+        CandidateSpan e;
+        while (i.hasNext()) {
+            e = i.next();
+            if (e.getPosition() <= position) {
+                i.remove();
+            }
+            break;
+        }
+    }
 }
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedTokenDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedTokenDistanceSpans.java
index 5f1abd9..bc9f0e5 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedTokenDistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/UnorderedTokenDistanceSpans.java
@@ -13,114 +13,129 @@
 
 import de.ids_mannheim.korap.query.SpanDistanceQuery;
 
-/** Enumeration of span matches, whose two child spans have a specific range 
- * 	of distance (within a min and a max distance) and can be in any order. 
- * 	The unit distance is a token position.
+/**
+ * Enumeration of span matches, whose two child spans have a specific range of
+ * distance (within a min and a max distance) and can be in any order. The unit
+ * distance is a token position.
  * 
  * @author margaretha
  * */
-public class UnorderedTokenDistanceSpans extends UnorderedDistanceSpans{
+public class UnorderedTokenDistanceSpans extends UnorderedDistanceSpans {
 
-	public UnorderedTokenDistanceSpans(SpanDistanceQuery query,
-			AtomicReaderContext context, Bits acceptDocs,
-			Map<Term, TermContext> termContexts) throws IOException {
-		super(query, context, acceptDocs, termContexts);		
-	}
-	
-	@Override
-	protected boolean prepareLists() throws IOException {		
-		
-		if (firstSpanList.isEmpty() && secondSpanList.isEmpty()){
-			if (hasMoreFirstSpans && hasMoreSecondSpans &&
-					ensureSameDoc(firstSpans, secondSpans)){			
-				firstSpanList.add(new CandidateSpan(firstSpans));
-				secondSpanList.add(new CandidateSpan(secondSpans));
-				currentDocNum = firstSpans.doc();
-				hasMoreFirstSpans = firstSpans.next();
-				hasMoreSecondSpans = secondSpans.next();				
-			}
-			else { 
-				hasMoreSpans = false;
-				return false;
-			}
-		}
-		else if (firstSpanList.isEmpty() && hasMoreFirstSpans && 
-				firstSpans.doc() == currentDocNum){
-			firstSpanList.add(new CandidateSpan(firstSpans));
-			hasMoreFirstSpans = firstSpans.next();
-		}
-		else if (secondSpanList.isEmpty() && hasMoreSecondSpans && 
-				secondSpans.doc() == currentDocNum){
-			secondSpanList.add(new CandidateSpan(secondSpans));
-			hasMoreSecondSpans = secondSpans.next();
-		}
-		return true;
-	}
-	
-	@Override
-	protected boolean setCandidateList(List<CandidateSpan> 
-			candidateList, Spans candidate, boolean hasMoreCandidates,
-			List<CandidateSpan> targetList) throws IOException {
-		
-		if (!targetList.isEmpty()){
-			CandidateSpan target = targetList.get(0);
-			while (hasMoreCandidates && candidate.doc() == target.getDoc()
-					&& isWithinMaxDistance(target,candidate)){
-				candidateList.add(new CandidateSpan(candidate));
-				hasMoreCandidates = candidate.next();
-			}
-		}
-		return hasMoreCandidates;
-	}
-	
-	/** Check if the target and candidate spans are not too far from each other.
-	 *  @return true iff the target and candidate spans are within the maximum
-	 *  distance
-	 * */
-	protected boolean isWithinMaxDistance(CandidateSpan target, Spans candidate) {
-		// left candidate
-		if (candidate.end() < target.getStart() && 
-				candidate.end() + maxDistance <= target.getStart()){
-			return false;
-		}
-		// right candidate
-		if (candidate.start() > target.getEnd() &&
-				target.getEnd() + maxDistance <= candidate.start()){
-			return false;
-		}
-		return true;
-	}
-	
-	@Override	
-	protected List<CandidateSpan> findMatches(CandidateSpan target, List<CandidateSpan> 
-			candidateList) {
-		
-		List<CandidateSpan> matches = new ArrayList<>();		
-		int actualDistance;
-		for (CandidateSpan cs : candidateList){
-			if (minDistance == 0 &&
-					//intersection
-					target.getStart() < cs.getEnd() &&
-					cs.getStart() < target.getEnd()){
-				matches.add(createMatchCandidate(target,cs,true));
-				continue;
-			}
-			
-			// left candidate
-			if (cs.getEnd() < target.getStart())
-				actualDistance = target.getStart() - cs.getEnd() +1;			 
-			else // right candidate
-				actualDistance = cs.getStart() - target.getEnd() +1;
-			 
-			if (minDistance <= actualDistance && actualDistance <= maxDistance)
-				matches.add(createMatchCandidate(target, cs, false));			
-		}		
-		return matches;
-	}
+    /**
+     * Constructs an UnorderedTokenDistanceSpans for the given
+     * SpanDistanceQuery.
+     * 
+     * @param query a SpanDistanceQuery
+     * @param context
+     * @param acceptDocs
+     * @param termContexts
+     * @throws IOException
+     */
+    public UnorderedTokenDistanceSpans(SpanDistanceQuery query,
+            AtomicReaderContext context, Bits acceptDocs,
+            Map<Term, TermContext> termContexts) throws IOException {
+        super(query, context, acceptDocs, termContexts);
+    }
 
-	@Override
-	protected void updateList(List<CandidateSpan> candidateList) {
-		candidateList.remove(0);		
-	}
+    @Override
+    protected boolean prepareLists() throws IOException {
+
+        if (firstSpanList.isEmpty() && secondSpanList.isEmpty()) {
+            if (hasMoreFirstSpans && hasMoreSecondSpans
+                    && ensureSameDoc(firstSpans, secondSpans)) {
+                firstSpanList.add(new CandidateSpan(firstSpans));
+                secondSpanList.add(new CandidateSpan(secondSpans));
+                currentDocNum = firstSpans.doc();
+                hasMoreFirstSpans = firstSpans.next();
+                hasMoreSecondSpans = secondSpans.next();
+            } else {
+                hasMoreSpans = false;
+                return false;
+            }
+        } else if (firstSpanList.isEmpty() && hasMoreFirstSpans
+                && firstSpans.doc() == currentDocNum) {
+            firstSpanList.add(new CandidateSpan(firstSpans));
+            hasMoreFirstSpans = firstSpans.next();
+        } else if (secondSpanList.isEmpty() && hasMoreSecondSpans
+                && secondSpans.doc() == currentDocNum) {
+            secondSpanList.add(new CandidateSpan(secondSpans));
+            hasMoreSecondSpans = secondSpans.next();
+        }
+        return true;
+    }
+
+    @Override
+    protected boolean setCandidateList(List<CandidateSpan> candidateList,
+            Spans candidate, boolean hasMoreCandidates,
+            List<CandidateSpan> targetList) throws IOException {
+
+        if (!targetList.isEmpty()) {
+            CandidateSpan target = targetList.get(0);
+            while (hasMoreCandidates && candidate.doc() == target.getDoc()
+                    && isWithinMaxDistance(target, candidate)) {
+                candidateList.add(new CandidateSpan(candidate));
+                hasMoreCandidates = candidate.next();
+            }
+        }
+        return hasMoreCandidates;
+    }
+
+    /**
+     * Tells if the target and candidate spans are not too far from each other
+     * (within the maximum distance).
+     * 
+     * @param target a target span
+     * @param candidate a candidate span
+     * @return <code>true</code> if the target and candidate spans are within
+     *         the maximum distance, <code>false</code> otherwise.
+     */
+    protected boolean isWithinMaxDistance(CandidateSpan target, Spans candidate) {
+        // left candidate
+        if (candidate.end() < target.getStart()
+                && candidate.end() + maxDistance <= target.getStart()) {
+            return false;
+        }
+        // right candidate
+        if (candidate.start() > target.getEnd()
+                && target.getEnd() + maxDistance <= candidate.start()) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    protected List<CandidateSpan> findMatches(CandidateSpan target,
+            List<CandidateSpan> candidateList) {
+
+        List<CandidateSpan> matches = new ArrayList<>();
+        int actualDistance;
+        for (CandidateSpan cs : candidateList) {
+            if (minDistance == 0
+                    &&
+                    // intersection
+                    target.getStart() < cs.getEnd()
+                    && cs.getStart() < target.getEnd()) {
+                matches.add(createMatchCandidate(target, cs, true));
+                continue;
+            }
+
+            // left candidate
+            if (cs.getEnd() < target.getStart())
+                actualDistance = target.getStart() - cs.getEnd() + 1;
+            else
+                // right candidate
+                actualDistance = cs.getStart() - target.getEnd() + 1;
+
+            if (minDistance <= actualDistance && actualDistance <= maxDistance)
+                matches.add(createMatchCandidate(target, cs, false));
+        }
+        return matches;
+    }
+
+    @Override
+    protected void updateList(List<CandidateSpan> candidateList) {
+        candidateList.remove(0);
+    }
 
 }
