SpanDistanceQuery
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
new file mode 100644
index 0000000..8b1e8a4
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
@@ -0,0 +1,57 @@
+package de.ids_mannheim.korap.query;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.spans.DistanceSpan;
+
+/** Match two ordered Spans with minimum and maximum distance constraints.
+ * 	In this query, the distance unit is the difference between two 
+ * 	token positions.
+ * 
+ * 	@author margaretha
+ * */
+public class SpanDistanceQuery extends SimpleSpanQuery {
+	
+	private int minDistance, maxDistance; // token positions
+	private boolean collectPayloads;
+	private SpanQuery firstClause, secondClause; 
+	
+	public SpanDistanceQuery(SpanQuery firstClause, SpanQuery secondClause, 
+			int minDistance, int maxDistance, boolean collectPayloads) {
+		super(firstClause, secondClause, "spanDistance");		
+    	this.firstClause=firstClause;
+    	this.secondClause=secondClause;
+    	this.minDistance =minDistance;
+		this.maxDistance = maxDistance;
+		this.collectPayloads = collectPayloads;
+	}
+	
+	@Override
+	public SpanDistanceQuery clone() {
+		SpanDistanceQuery spanDistanceQuery = new SpanDistanceQuery(
+			    (SpanQuery) firstClause.clone(),
+			    (SpanQuery) secondClause.clone(),
+			    this.minDistance,
+			    this.maxDistance,
+			    this.collectPayloads
+		        );
+		spanDistanceQuery.setBoost(getBoost());
+		return spanDistanceQuery;	
+	}
+
+	@Override
+	public Spans getSpans(AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts) throws IOException {		
+		return new DistanceSpan(this, context, acceptDocs, termContexts, 
+				minDistance, maxDistance);
+	}
+
+}
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
new file mode 100644
index 0000000..dd49894
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/CandidateSpan.java
@@ -0,0 +1,66 @@
+package de.ids_mannheim.korap.query.spans;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.lucene.search.spans.Spans;
+
+/** A span kept as a candidate for matching with another Span
+ * 	@author margaretha
+ * */
+public class CandidateSpan {	
+	private int doc,start,end;
+	private long cost;
+	private Collection<byte[]> payloads;
+	
+	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()){
+			this.payloads = span.getPayload();
+		}
+		else{ 
+			this.payloads = null;
+		}
+	}
+	
+	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;
+	}
+
+	public Collection<byte[]> getPayloads() {
+		return payloads;
+	}
+
+	public void setPayloads(Collection<byte[]> payloads) {
+		this.payloads = payloads;
+	}
+
+	public long getCost() {
+		return cost;
+	}
+
+	public void setCost(long cost) {
+		this.cost = cost;
+	}
+	
+	
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpan.java b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpan.java
new file mode 100644
index 0000000..022f5d4
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpan.java
@@ -0,0 +1,251 @@
+package de.ids_mannheim.korap.query.spans;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.ids_mannheim.korap.query.SimpleSpanQuery;
+import de.ids_mannheim.korap.query.SpanDistanceQuery;
+
+public class DistanceSpan extends Spans{
+	
+	private boolean isStartEnumeration;
+	private boolean hasMoreSpans;
+	private boolean hasMoreFirstSpans;	
+	private boolean collectPayloads;
+	private int minDistance,maxDistance;
+		
+	protected int doc, start, end;	
+	private List<byte[]> payload;   
+    
+    private SpanDistanceQuery query;
+    protected Spans firstSpans, secondSpans;   
+	private List<CandidateSpan> candidateList;
+	private int candidateListIndex;
+	private int candidateListDocNum;
+	
+    private Logger log = LoggerFactory.getLogger(SimpleSpans.class);
+    
+	public DistanceSpan(SpanDistanceQuery spanDistanceQuery,
+			AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts,
+			int minDistance,
+			int maxDistance)
+			throws IOException {
+		this(spanDistanceQuery, context, acceptDocs, termContexts, 
+			minDistance, maxDistance, true);		
+	}
+	
+	public DistanceSpan(SpanDistanceQuery spanDistanceQuery,
+			AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts,
+			int minDistance,
+			int maxDistance,
+			boolean collectPayloads)
+			throws IOException {
+		
+		this.query = spanDistanceQuery;
+		this.minDistance = minDistance;
+		this.maxDistance = maxDistance;		
+  		this.collectPayloads = collectPayloads; // TODO: always true ?
+  		this.payload = new LinkedList<byte[]>();
+  		this.doc = -1;
+  		this.start = -1;
+  		this.end = -1;
+		  		
+  		// Get the enumeration of the two spans to match
+  		firstSpans = spanDistanceQuery.getFirstClause().
+  			getSpans(context, acceptDocs, termContexts);
+  		secondSpans = spanDistanceQuery.getSecondClause().
+  			getSpans(context, acceptDocs, termContexts);  	  	
+  		 		  		
+  		hasMoreFirstSpans = firstSpans.next();
+  		hasMoreSpans = hasMoreFirstSpans;
+  		
+		candidateList = new ArrayList<>();
+		candidateListIndex = -1;
+		candidateListDocNum = firstSpans.doc();
+		
+		isStartEnumeration=true;
+	}	
+	
+	@Override
+	public boolean next() throws IOException {		
+		isStartEnumeration=false;
+  		payload.clear();
+		return advance();
+	}
+	
+	private boolean advance() throws IOException {
+		while( hasMoreSpans && candidateListIndex < candidateList.size() ){					
+			// Check candidates
+			for (candidateListIndex++;candidateListIndex < candidateList.size();
+					candidateListIndex++){
+				if (findMatch())					
+					return true;					
+			}			
+			// Forward secondspan
+			if (hasMoreSpans = secondSpans.next())			
+				setCandidateList();
+		}
+		return false;
+	}
+	
+ 	private void setCandidateList() throws IOException{
+ 		if (candidateListDocNum == secondSpans.doc()){						
+			copyPossibleCandidates();
+			addNewCandidates();
+			candidateListIndex = -1;
+ 		}
+ 		else {
+ 			candidateList.clear(); 			
+ 			if (hasMoreFirstSpans && ensureSameDoc()){
+ 				candidateListDocNum = firstSpans.doc();
+				addNewCandidates();
+				candidateListIndex = -1;
+			}		
+		} 		
+	}
+	
+	private void copyPossibleCandidates(){
+		List<CandidateSpan> temp = new ArrayList<>();
+		for (CandidateSpan cs : candidateList){
+			if (cs.getEnd()+maxDistance > secondSpans.start())
+				temp.add(cs);
+		}
+		candidateList = temp;
+	}
+	
+	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();
+		}
+	}
+	
+	
+	
+	/** Skip the current first or second span until both the spans are in the same doc.
+	 * @return true iff the first and second spans are in the same doc.
+	 * */
+  	private boolean ensureSameDoc() throws IOException {  		
+  		while (firstSpans.doc() != secondSpans.doc()) {
+  			if (firstSpans.doc() < secondSpans.doc()){
+  				if (!firstSpans.skipTo(secondSpans.doc())){
+  					hasMoreSpans = false;  					
+  					return false;
+  				}				
+  			}		
+  			else {
+  				if (!secondSpans.skipTo(firstSpans.doc())){
+  					hasMoreSpans = false;
+  					return false;
+  				}	
+  			}			
+  		}  		
+  		return true;
+  	}
+
+
+	protected boolean findMatch() throws IOException {
+		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);		
+		if (minDistance == 0 &&
+				// intersection
+				candidateSpan.getStart() < secondSpans.end() && 
+				secondSpans.start() < candidateSpan.getEnd()){
+			
+			this.start = Math.min(candidateSpan.getStart(), secondSpans.start());
+			this.end = Math.max(candidateSpan.getEnd(), secondSpans.end());
+			setDocAndPayload(candidateSpan);
+			return true;			
+		}
+		
+		int actualDistance = secondSpans.start() - candidateSpan.getEnd() +1;
+		if (candidateSpan.getStart() < secondSpans.start() &&
+				minDistance <= actualDistance && 
+				actualDistance <= maxDistance){
+						
+			this.start = candidateSpan.getStart();
+			this.end = secondSpans.end();
+			setDocAndPayload(candidateSpan);
+			return true;
+		}		
+		return false;
+	}
+	
+	private void setDocAndPayload(CandidateSpan candidateSpan) throws IOException{ 
+		this.doc = secondSpans.doc();		
+		if (collectPayloads){			
+  		    if (candidateSpan.getPayloads() != null) {  		    	
+  		    	payload.addAll(candidateSpan.getPayloads());
+  		    	log.trace("first",payload.size());
+  		    }
+  		    if (secondSpans.isPayloadAvailable()) {
+  		    	payload.addAll(secondSpans.getPayload());
+  		    	log.trace("second",payload.size());
+  		    }
+		} 
+	}
+
+	@Override
+	public boolean skipTo(int target) throws IOException {
+		if (hasMoreSpans && (secondSpans.doc() < target)){
+  			if (!secondSpans.skipTo(target)){
+  				candidateList.clear();
+  				return false;
+  			}
+  		} 	
+		
+		setCandidateList();
+		payload.clear();
+		isStartEnumeration=false;
+		return advance();
+	}
+
+	@Override
+	public int doc() {		
+		return this.doc;
+	}
+
+	@Override
+	public int start() {
+		return this.start;
+	}
+
+	@Override
+	public int end() {
+		return this.end;
+	}
+
+	@Override
+	public Collection<byte[]> getPayload() throws IOException {
+		return this.payload;
+	}
+
+	@Override
+	public boolean isPayloadAvailable() throws IOException {		
+		return !this.payload.isEmpty();
+	}
+
+	@Override
+	public long cost() {
+		CandidateSpan candidateSpan = candidateList.get(candidateListIndex);
+		return candidateSpan.getCost() + secondSpans.cost();
+	}
+}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestDistanceQuery.java b/src/test/java/de/ids_mannheim/korap/index/TestDistanceQuery.java
new file mode 100644
index 0000000..11f5a04
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/index/TestDistanceQuery.java
@@ -0,0 +1,298 @@
+package de.ids_mannheim.korap.index;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.spans.SpanQuery;
+import org.apache.lucene.search.spans.SpanTermQuery;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import de.ids_mannheim.korap.KorapIndex;
+import de.ids_mannheim.korap.KorapResult;
+import de.ids_mannheim.korap.query.SpanDistanceQuery;
+import de.ids_mannheim.korap.query.SpanElementQuery;
+import de.ids_mannheim.korap.query.SpanSegmentQuery;
+
+@RunWith(JUnit4.class)
+public class TestDistanceQuery {
+    KorapResult kr;
+    KorapIndex ki;   
+ 
+    private FieldDocument createFieldDoc0() {
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-0");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:b|s:c|_1#0-1]" +
+            "[(1-2)s:b|_2#1-2]" +             
+            "[(2-3)s:c|_3#2-3]" +
+            "[(3-4)s:c|_4#3-4]" + 
+            "[(4-5)s:d|_5#4-5]" +             
+            "[(5-6)s:d|_6#5-6]");
+        return fd;
+	}
+    
+    private FieldDocument createFieldDoc1(){
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:c|_1#0-1]" +
+            "[(1-2)s:e|_2#1-2]" +             
+            "[(2-3)s:c|_3#2-3|<>:y#2-4$<i>4]" +
+            "[(3-4)s:c|_4#3-4|<>:x#3-7$<i>7]" + 
+            "[(4-5)s:d|_5#4-5|<>:y#4-6$<i>6]" +             
+            "[(5-6)s:c|_6#5-6|<>:y#5-8$<i>8]" +
+            "[(6-7)s:d|_7#6-7]" +
+            "[(7-8)s:e|_8#7-8|<>:x#7-9$<i>9]" + 
+            "[(8-9)s:e|_9#8-9|<>:x#8-10$<i>10]" + 
+            "[(9-10)s:d|_10#9-10]");
+        return fd;
+    }
+    
+    private FieldDocument createFieldDoc2() {
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-2");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:b|_1#0-1]" +
+            "[(1-2)s:b|_2#1-2]" +             
+            "[(2-3)s:d|_3#2-3]" +
+            "[(3-4)s:e|_4#3-4]" + 
+            "[(4-5)s:d|_5#4-5]" +             
+            "[(5-6)s:e|_6#5-6]");
+        return fd;
+	}
+    
+    private SpanQuery createQuery(String x, String y, int min, int max){
+    	SpanQuery sq = new SpanDistanceQuery(
+        		new SpanTermQuery(new Term("base",x)),
+        		new SpanTermQuery(new Term("base",y)),
+        		min,
+        		max,
+        		true
+        );
+    	return sq;
+    }
+    
+    private SpanQuery createElementQuery(String x, String y, int min, int max){
+    	SpanQuery sq = new SpanDistanceQuery(
+        		new SpanElementQuery("base",x),
+        		new SpanElementQuery("base",y),
+        		min,
+        		max,
+        		true
+        );
+    	return sq;
+    }
+    
+    /**	- Intersection 
+     * 	- Multiple occurrences in the same doc  
+     *  - hasMoreFirstSpans = false for the current secondspan  
+     * */
+    @Test
+    public void testCase1() throws IOException{
+    	ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+        SpanQuery sq;
+        // ---- Distance 0 to 1
+        sq = createQuery("s:b","s:c",0,1);                
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(2, kr.totalResults());
+        assertEquals(0, kr.match(0).startPos);
+        assertEquals(1, kr.match(0).endPos);
+        assertEquals(1, kr.match(1).startPos);
+        assertEquals(3, kr.match(1).endPos);
+        
+        // ---- Distance 2 to 2
+        sq = createQuery("s:b","s:c",2,2);                
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(2, kr.totalResults());
+        assertEquals(0, kr.match(0).startPos);
+        assertEquals(3, kr.match(0).endPos);
+        assertEquals(1, kr.match(1).startPos);
+        assertEquals(4, kr.match(1).endPos);
+        
+        // ---- Distance 2 to 3
+        sq = createQuery("s:b","s:c",2,3);                
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(3, kr.totalResults());
+        
+        ki.close();
+    }
+    
+    /** - Check candidate list: 
+     * 	- CandidateList should not contain firstspans that are too far from 
+     * 	  the current secondspan
+     * 	- Add new candidates  
+     * */
+    @Test
+    public void testCase2() throws IOException{
+    	ki = new KorapIndex();
+	    ki.addDoc(createFieldDoc1()); 
+	    ki.commit();    
+	    
+	    // ---- Distance 1 to 3
+	    // Candidate list for the current secondspan, is empty
+	    SpanQuery sq = createQuery("s:c","s:d",1,3);                
+	    kr = ki.search(sq, (short) 10);
+	        	    
+	    assertEquals(4, kr.getTotalResults());
+	    assertEquals(2, kr.getMatch(0).startPos);
+	    assertEquals(5, kr.getMatch(0).endPos);
+	    assertEquals(3, kr.getMatch(2).startPos);
+	    assertEquals(7, kr.getMatch(2).endPos);
+	    
+	    ki.addDoc(createFieldDoc0());
+	    ki.commit();
+
+	    // ---- Distance 3 to 3
+	    // Candidate list is empty, but there are secondspans in the other doc
+	    sq = createQuery("s:c","s:d",3,3);                
+	    kr = ki.search(sq, (short) 10);
+	    assertEquals(2, kr.getTotalResults());
+	    
+	    ki.close();
+    }
+        
+    /** - Ensure the same document
+     *  - Multiple matches in multiple documents and atomic indices
+     * */
+    @Test
+    public void testCase3() throws IOException{
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());
+        ki.commit();
+        ki.addDoc(createFieldDoc2());
+        ki.addDoc(createFieldDoc1());
+        ki.commit();
+        
+        SpanQuery sq;
+        sq = createQuery("s:c","s:d",3,3);    
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(2, kr.totalResults());
+    }
+    
+    /** - Firstspan.next() is in the other doc, but there is
+     *    still a secondspans in the same doc
+     *  - hasMoreFirstSpan and secondspans.next() are true,
+     *    but ensureSameDoc() = false 
+     * */ 
+    @Test
+    public void testCase4() throws IOException{
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());
+        ki.commit();
+        ki.addDoc(createFieldDoc2());
+        ki.addDoc(createFieldDoc1());
+        ki.commit();
+               
+        // ---- Distance 1 to 2
+        SpanQuery sq = createQuery("s:b","s:c",1,2);                
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(3, kr.totalResults());
+        assertEquals(0, kr.getMatch(0).startPos);
+	    assertEquals(3, kr.getMatch(0).endPos);
+	    assertEquals(1, kr.getMatch(1).startPos);
+	    assertEquals(3, kr.getMatch(1).endPos);
+	    assertEquals(1, kr.getMatch(2).startPos);
+	    assertEquals(4, kr.getMatch(2).endPos);
+	    ki.close();      
+    }
+    
+    /** ElementQueries */    
+    @Test
+    public void testCase5() throws IOException{    	
+    	ki = new KorapIndex();
+	    ki.addDoc(createFieldDoc1()); 
+	    ki.commit();    
+	    
+	    // Intersection ---- Distance 0:0
+	    SpanQuery sq = createElementQuery("x","y",0,0);                
+	    kr = ki.search(sq, (short) 10);
+    	
+	    assertEquals(4, kr.totalResults());
+	    assertEquals(2, kr.getMatch(0).startPos);
+	    assertEquals(7, kr.getMatch(0).endPos);
+	    assertEquals(3, kr.getMatch(1).startPos);
+	    assertEquals(7, kr.getMatch(1).endPos);
+	    assertEquals(3, kr.getMatch(2).startPos);
+	    assertEquals(8, kr.getMatch(2).endPos);
+    	
+	    // Next to ---- Distance 1:1
+	    sq = createElementQuery("y","x",1,1);                
+	    kr = ki.search(sq, (short) 10);
+	    
+	    assertEquals(1, kr.totalResults());
+	    assertEquals(5, kr.getMatch(0).startPos);
+	    assertEquals(10, kr.getMatch(0).endPos);
+	    
+	    // ---- Distance 1:2
+	    sq = createElementQuery("y","x",1,2);                
+	    kr = ki.search(sq, (short) 10);
+	    
+	    assertEquals(2, kr.totalResults());	    
+	    assertEquals(4, kr.getMatch(0).startPos);
+	    assertEquals(9, kr.getMatch(0).endPos);
+	    assertEquals(5, kr.getMatch(1).startPos);
+	    assertEquals(10, kr.getMatch(1).endPos);
+	    
+	    // The same element type ---- Distance 1:2
+	    sq = createElementQuery("x","x",1,2);
+	    kr = ki.search(sq, (short) 10);
+	    
+	    assertEquals(2, kr.totalResults());
+	    
+//    	System.out.print(kr.getTotalResults()+"\n");
+//		for (int i=0; i< kr.getTotalResults(); i++){
+//			System.out.println(
+//				kr.match(i).startPos + " " +kr.match(i).endPos
+//		    );
+//		}
+    }
+    
+    /** Skip to */    
+    @Test
+    public void testCase6() throws IOException{    	
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc2());
+	    ki.addDoc(createFieldDoc1());
+	    ki.commit();
+	    	    
+	    SpanQuery firstClause = createQuery("s:d", "s:e", 3, 4);
+	    kr = ki.search(firstClause, (short) 10); 
+	    
+	    assertEquals(3, kr.totalResults());
+	    assertEquals(0, kr.getMatch(0).getLocalDocID());
+	    assertEquals(2, kr.getMatch(0).startPos);
+	    assertEquals(6, kr.getMatch(0).endPos);
+	    assertEquals(1, kr.getMatch(1).getLocalDocID());
+	    assertEquals(4, kr.getMatch(1).startPos);
+	    assertEquals(8, kr.getMatch(1).endPos);
+	    assertEquals(4, kr.getMatch(2).startPos);
+	    assertEquals(9, kr.getMatch(2).endPos);	    
+	    
+		// The secondspans is skipped to doc# of the current firstspans
+		SpanQuery sq = new SpanSegmentQuery(
+	    		createQuery("s:d","s:e",3,4),
+	    		createElementQuery("y","x",1,2)
+		);	    
+	    kr = ki.search(sq, (short) 10);
+	    
+	    assertEquals(1, kr.totalResults());
+	    assertEquals(4, kr.getMatch(0).startPos);
+	    assertEquals(9, kr.getMatch(0).endPos);	    
+    }
+    
+    
+}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestSegmentIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestSegmentIndex.java
index e6db8aa..2b52d9d 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestSegmentIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestSegmentIndex.java
@@ -30,9 +30,9 @@
 	
 	public TestSegmentIndex() throws IOException {
 		ki = new KorapIndex();
+		ki.addDoc(createFieldDoc0());
 		ki.addDoc(createFieldDoc1());
 		ki.addDoc(createFieldDoc2());
-		ki.addDoc(createFieldDoc3());
 		ki.commit();
 		
 		log = LoggerFactory.getLogger(getClass());
@@ -109,10 +109,10 @@
 //		log.trace("Testcase4");
 		
 		ki = new KorapIndex();
-		ki.addDoc(createFieldDoc1());
+		ki.addDoc(createFieldDoc0());
 		ki.commit();
-		ki.addDoc(createFieldDoc2());		
-		ki.addDoc(createFieldDoc3());
+		ki.addDoc(createFieldDoc1());		
+		ki.addDoc(createFieldDoc2());
 		ki.commit();
 		
 		sq = new SpanSegmentQuery(
@@ -183,7 +183,7 @@
 		assertEquals("EndPos (0)", 2, kr.match(1).endPos);
 	}
 	
-	private FieldDocument createFieldDoc1(){
+	private FieldDocument createFieldDoc0(){
 		fd = new FieldDocument();
 		fd.addString("ID", "doc-0");
 		fd.addTV("base",
@@ -197,7 +197,7 @@
 		return fd;
 	}
 	
-	private FieldDocument createFieldDoc2(){
+	private FieldDocument createFieldDoc1(){
 		fd = new FieldDocument();
 		fd.addString("ID", "doc-1");
 		fd.addTV("base",
@@ -210,7 +210,7 @@
 		return fd;
 	} 
 	
-	private FieldDocument createFieldDoc3(){
+	private FieldDocument createFieldDoc2(){
 		fd = new FieldDocument();
 		fd.addString("ID", "doc-2");
 		fd.addTV("base",