MultipleDistanceQuery
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
index 634a887..e219818 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
@@ -12,19 +12,19 @@
 
 import de.ids_mannheim.korap.query.spans.ElementDistanceSpans;
 import de.ids_mannheim.korap.query.spans.TokenDistanceSpans;
-import de.ids_mannheim.korap.query.spans.UnorderedDistanceSpans;
 import de.ids_mannheim.korap.query.spans.UnorderedElementDistanceSpans;
 import de.ids_mannheim.korap.query.spans.UnorderedTokenDistanceSpans;
 
-/** Match two ordered Spans with minimum and maximum distance constraints.
- * 	The distance unit can be word (token), sentence or paragraph. 
+/** Match two ordered or unordered Spans with minimum and maximum 
+ * 	distance constraints. The distance unit can be word (token), 
+ * 	sentence or paragraph. 
  * 
  * 	@author margaretha
  * */
 public class SpanDistanceQuery extends SimpleSpanQuery {
 	
 	protected int minDistance, maxDistance;
-	protected boolean isOrdered, collectPayloads;
+	public boolean isOrdered, collectPayloads;
 	protected SpanQuery firstClause, secondClause; 
 	private SpanQuery elementQuery; // element distance unit
 
@@ -52,11 +52,6 @@
 		this.collectPayloads = collectPayloads;
 		this.elementQuery = elementQuery;
 	}
-	
-	public SpanDistanceQuery(SpanQuery firstClause2, SpanQuery secondClause2,
-			String string) {
-		super(firstClause2, secondClause2, string);
-	}
 
 	@Override
 	public SpanDistanceQuery clone() {
diff --git a/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java b/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java
new file mode 100644
index 0000000..4fac9e6
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanMultipleDistanceQuery.java
@@ -0,0 +1,107 @@
+package de.ids_mannheim.korap.query;
+
+import java.io.IOException;
+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.SpanQuery;
+import org.apache.lucene.search.spans.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.spans.MultipleDistanceSpans;
+
+/** Match two spans with respect to a list of distance constraints.
+ * 	No repetition of constraints of the same type is allowed. For example,
+ * 	there must only exactly one constraint for word/token-based distance.
+ * 	
+ * 	@author margaretha
+ * */
+public class SpanMultipleDistanceQuery extends SimpleSpanQuery{
+	
+	private SpanQuery firstClause, secondClause;	 
+	private List<DistanceConstraint> constraints;  
+	private boolean isOrdered;
+	private boolean collectPayloads;	
+			
+	public SpanMultipleDistanceQuery(SpanQuery firstClause, SpanQuery secondClause,
+			List<DistanceConstraint> constraints, boolean isOrdered, 
+			boolean collectPayloads) {
+		super(firstClause, secondClause, "spanMultipleDistance");
+		this.constraints = constraints;
+    	this.firstClause=firstClause;
+    	this.secondClause=secondClause;
+		this.isOrdered = isOrdered;
+		this.collectPayloads = collectPayloads;
+	}
+
+	@Override
+	public SpanMultipleDistanceQuery clone() {
+		SpanMultipleDistanceQuery query = new SpanMultipleDistanceQuery(
+		    (SpanQuery) firstClause.clone(),
+		    (SpanQuery) secondClause.clone(),
+		    this.constraints,
+		    this.isOrdered,
+		    this.collectPayloads
+        );		
+		
+		query.setBoost(getBoost());
+		return query;
+	}	
+	
+	/** Filter the span matches of each constraint, returning only the matches 
+	 * 	meeting all the constraints.
+	 * 	@return only the span matches meeting all the constraints.
+	 * */
+	@Override
+	public Spans getSpans(AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts) throws IOException {			
+		
+		DistanceConstraint c;		
+		SpanDistanceQuery sdq,sdq2;		
+		Spans ds,ds2;
+		MultipleDistanceSpans mds = null;
+		
+		c = constraints.get(0);
+		sdq = createSpanDistanceQuery(c);
+		ds = sdq.getSpans(context, acceptDocs, termContexts);
+				
+		for (int i=1; i< constraints.size(); i++){
+			sdq2 = createSpanDistanceQuery(constraints.get(i));
+			ds2 = sdq2.getSpans(context, acceptDocs, termContexts);			
+						
+			mds = new MultipleDistanceSpans(this, context, acceptDocs, 
+					termContexts, ds, ds2, isOrdered); 
+			ds = mds;
+		}
+		
+		return mds;
+	}
+	
+	/** Create a SpanDistanceQuery based on the given constraint.
+	 * 	@return a SpanDistanceQuery 
+	 * */
+	private SpanDistanceQuery createSpanDistanceQuery(DistanceConstraint c) {		
+				
+		if (c.getUnit().equals("w")){
+			return new SpanDistanceQuery(firstClause, secondClause,
+					c.getMinDistance(), c.getMaxDistance(),isOrdered, 
+					collectPayloads);
+		}
+		
+		return new SpanDistanceQuery(c.getElementQuery(), firstClause, 
+				secondClause, c.getMinDistance(), c.getMaxDistance(),
+				isOrdered, collectPayloads);
+	}
+
+	public List<DistanceConstraint> getConstraints() {
+		return constraints;
+	}
+
+	public void setConstraints(List<DistanceConstraint> constraints) {
+		this.constraints = constraints;
+	}
+	
+}
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
index 6bc0c23..aedd6c1 100644
--- a/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/DistanceSpans.java
@@ -24,11 +24,11 @@
  * @author margaretha
  * */
 public abstract class DistanceSpans extends SimpleSpans{	
-	
+
 	protected CandidateSpan matchFirstSpan,matchSecondSpan;	
 	protected Logger log = LoggerFactory.getLogger(DistanceSpans.class);
     
-	public DistanceSpans(SpanDistanceQuery query,
+	public DistanceSpans(SimpleSpanQuery query,
 			AtomicReaderContext context, Bits acceptDocs,
 			Map<Term, TermContext> termContexts) throws IOException {
 		super(query, context, acceptDocs, termContexts);
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java b/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java
new file mode 100644
index 0000000..f9c5e68
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/MultipleDistanceSpans.java
@@ -0,0 +1,125 @@
+package de.ids_mannheim.korap.query.spans;
+
+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.Spans;
+import org.apache.lucene.util.Bits;
+
+import de.ids_mannheim.korap.query.SimpleSpanQuery;
+
+/**	Span enumeration of matches whose two sub-spans has exactly the same 
+ * 	first and second sub-sub-spans. This class basically filters the span 
+ * 	matches of its child spans.
+ * 	 
+ *	@author margaretha
+ * */
+public class MultipleDistanceSpans extends DistanceSpans{
+		
+	private DistanceSpans x,y;
+	private boolean isOrdered;
+	
+	public MultipleDistanceSpans(SimpleSpanQuery query,
+			AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts, 
+			Spans firstSpans, Spans secondSpans, boolean isOrdered) 
+			throws IOException {
+		super(query, context, acceptDocs, termContexts);
+		this.isOrdered =isOrdered;
+		x = (DistanceSpans) firstSpans;
+		y = (DistanceSpans) secondSpans;		
+		hasMoreSpans = x.next() && y.next();
+	}
+
+	@Override
+	public boolean next() throws IOException {
+		isStartEnumeration=false;
+  		matchPayload.clear();
+		return advance();		
+	}
+	
+	/** Find the next match.
+	 * */
+	protected boolean advance() throws IOException {
+		
+		while (hasMoreSpans && ensureSameDoc(x, y)){ 
+			if (findMatch()){
+				advanceChild();
+				return true;
+			}
+			advanceChild();
+		}		
+		return false;
+	}
+	
+	/** Find the next match of one of the sub/child-span.
+	 * */
+	private void advanceChild() throws IOException{
+		if (isOrdered){
+			if (x.end() < y.end() || 
+					(x.end() == y.end() && x.start() < y.start()) )
+				hasMoreSpans = x.next();			 
+			else hasMoreSpans = y.next();
+		}
+		// The matches of unordered distance spans are ordered by the 
+		// start position
+		else {
+			if (x.start() < y.start() || 
+					(x.start() == y.start() && x.end() < y.end()) )
+				hasMoreSpans = x.next();			 
+			else hasMoreSpans = y.next();
+		}
+	}
+	
+	/** Check if the sub-spans of x and y having exactly the same position.  
+	 * 	This is basically an AND operation.
+	 * 	@return true iff the sub-spans are identical.
+	 * */	
+	protected boolean findMatch() throws IOException {
+		 		
+		CandidateSpan xf = x.getMatchFirstSpan();
+		CandidateSpan xs = x.getMatchSecondSpan();
+		
+		CandidateSpan yf = y.getMatchFirstSpan();
+		CandidateSpan ys = y.getMatchSecondSpan();
+		
+		if (xf.getStart() == yf.getStart() &&
+				xf.getEnd() == yf.getEnd() &&
+				xs.getStart() == ys.getStart() &&
+				xs.getEnd() == ys.getEnd()){
+			
+			matchStartPosition = x.start();
+			matchEndPosition = x.end();
+			matchDocNumber = x.doc();
+			matchPayload = x.matchPayload;	
+			
+			setMatchFirstSpan(x.getMatchFirstSpan());
+			setMatchSecondSpan(x.getMatchSecondSpan());
+			log.trace("doc# {}, start {}, end {}",matchDocNumber,
+					matchStartPosition,matchEndPosition);	
+			return true;
+		}		
+		return false;
+	}
+
+	@Override
+	public boolean skipTo(int target) throws IOException {
+		if (hasMoreSpans && (y.doc() < target)){
+  			if (!y.skipTo(target)){  				
+  				return false;
+  			}
+  		}
+		matchPayload.clear();
+		isStartEnumeration=false;
+		return advance();
+	}
+
+	@Override
+	public long cost() {		
+		return x.cost() + y.cost();
+	}
+
+}
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 2c29093..3a03560 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
@@ -29,7 +29,7 @@
 	protected List<CandidateSpan> firstSpanList, secondSpanList;	
 	protected List<CandidateSpan> matchList;
 	private long matchCost;
-	private int matchListSpanNum; 
+	private int matchListSpanNum; 	
 	
 	public UnorderedDistanceSpans(SpanDistanceQuery query,
 			AtomicReaderContext context, Bits acceptDocs,
@@ -49,10 +49,10 @@
 	}
 
 	@Override
-	protected boolean advance() throws IOException {
+	protected boolean advance() throws IOException {		
 		while (hasMoreSpans || !matchList.isEmpty()){			
 			if (!matchList.isEmpty()){
-				setMatchProperties();
+				setMatchProperties();				
 				return true;
 			}
 			
@@ -92,12 +92,13 @@
 			currentFirstSpan = firstSpanList.get(0)	;
 			currentSecondSpan = secondSpanList.get(0);
 			
-			if (currentFirstSpan.getEnd() <= currentSecondSpan.getEnd()){
+			if (currentFirstSpan.getEnd() < currentSecondSpan.getEnd() ||					 
+					isLastCandidateSmaller(currentFirstSpan, currentSecondSpan)){
 				matchList = findMatches(currentFirstSpan, secondSpanList);
 				setMatchFirstSpan(currentFirstSpan);
 				matchListSpanNum = 2;
 				updateList(firstSpanList);
-			}
+			}			
 			else {
 				matchList = findMatches(currentSecondSpan, firstSpanList);
 				setMatchSecondSpan(currentSecondSpan);
@@ -113,6 +114,17 @@
 		}
 	}
 	
+	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.
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
new file mode 100644
index 0000000..c7640cd
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
@@ -0,0 +1,270 @@
+package de.ids_mannheim.korap.index;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+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.DistanceConstraint;
+import de.ids_mannheim.korap.query.SpanElementQuery;
+import de.ids_mannheim.korap.query.SpanMultipleDistanceQuery;
+import de.ids_mannheim.korap.query.SpanNextQuery;
+
+@RunWith(JUnit4.class)
+public class TestMultipleDistanceIndex {
+	
+	private KorapIndex ki;
+	private KorapResult kr;
+
+	public SpanQuery createQuery(String x, String y, List<DistanceConstraint> 
+			constraints, boolean isOrdered){
+		
+		SpanQuery sx = new SpanTermQuery(new Term("base",x)); 
+		SpanQuery sy = new SpanTermQuery(new Term("base",y));
+		
+		return new SpanMultipleDistanceQuery(sx, sy, constraints, isOrdered, true);
+	}
+	
+	public DistanceConstraint createConstraint(String unit, int min, int max){		
+		if (unit.equals("w")){
+			return new DistanceConstraint(unit, min, max);
+		}
+		SpanQuery sq = new SpanElementQuery("base", unit);
+		return new DistanceConstraint(sq, unit, min, max);	
+	}
+	
+    private FieldDocument createFieldDoc0() {
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-0");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:b|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+            "[(1-2)s:b|s:c|_2#1-2]" +             
+            "[(2-3)s:c|_3#2-3|<>:s#2-3$<i>4]" +
+            "[(3-4)s:b|_4#3-4]" + 
+            "[(4-5)s:c|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +             
+            "[(5-6)s:e|_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|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+            "[(1-2)s:c|s:e|_2#1-2]" +             
+            "[(2-3)s:e|_3#2-3|<>:s#2-3$<i>4]" +
+            "[(3-4)s:c|_4#3-4]" + 
+            "[(4-5)s:e|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +             
+            "[(5-6)s:c|_6#5-6]");
+        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|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+            "[(1-2)s:b|s:e|_2#1-2]" +             
+            "[(2-3)s:e|_3#2-3|<>:s#2-3$<i>4]" +
+            "[(3-4)s:b|s:c|_4#3-4]" + 
+            "[(4-5)s:e|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +             
+            "[(5-6)s:d|_6#5-6]");
+        return fd;
+	}
+    
+    private FieldDocument createFieldDoc3() {
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-0");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:b|_1#0-1|<>:s#0-2$<i>2|<>:p#0-4$<i>4]" +
+            "[(1-2)s:b|s:c|_2#1-2]" +             
+            "[(2-3)s:c|_3#2-3|<>:s#2-3$<i>4]" +
+            "[(3-4)s:b|_4#3-4]" + 
+            "[(4-5)s:c|_5#4-5|<>:s#4-6$<i>6|<>:p#4-6$<i>6]" +             
+            "[(5-6)s:d|_6#5-6]");
+        return fd;
+	}
+    
+  
+    /** Unordered, same sentence
+     * */
+    @Test
+	public void testCase1() throws IOException {
+    	ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+        
+    	List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+ 	    constraints.add(createConstraint("w", 0, 2));	    
+ 	    constraints.add(createConstraint("s", 0, 0));
+ 	    
+ 	    SpanQuery mdq;	   
+		mdq = createQuery("s:b", "s:c", constraints, false);
+		kr = ki.search(mdq, (short) 10);
+		
+		assertEquals(3, kr.getTotalResults());
+	    assertEquals(0, kr.getMatch(0).getStartPos());
+	    assertEquals(2, kr.getMatch(0).getEndPos());
+	    assertEquals(1, kr.getMatch(1).getStartPos());
+	    assertEquals(2, kr.getMatch(1).getEndPos());
+	    assertEquals(2, kr.getMatch(2).getStartPos());
+	    assertEquals(4, kr.getMatch(2).getEndPos());
+    }
+	
+    /** Ordered
+     * 	Unordered
+     * 	Two constraints
+     * 	Three constraints 	
+     * */
+	@Test
+	public void testCase2() throws IOException {
+		ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+		
+	    List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+	    constraints.add(createConstraint("w", 0, 2));	    
+	    constraints.add(createConstraint("s", 1, 1));
+	    
+	    SpanQuery mdq;
+	    // Ordered
+		mdq = createQuery("s:b", "s:c", constraints, true);
+		kr = ki.search(mdq, (short) 10);
+		
+	    assertEquals(3, kr.getTotalResults());
+	    assertEquals(0, kr.getMatch(0).getStartPos());
+	    assertEquals(3, kr.getMatch(0).getEndPos());
+	    assertEquals(1, kr.getMatch(1).getStartPos());
+	    assertEquals(3, kr.getMatch(1).getEndPos());
+	    assertEquals(3, kr.getMatch(2).getStartPos());
+	    assertEquals(5, kr.getMatch(2).getEndPos());
+	    
+	    // Unordered
+	    mdq = createQuery("s:c", "s:b", constraints, false);
+	    kr = ki.search(mdq, (short) 10);
+	    assertEquals(4, kr.getTotalResults());
+	    assertEquals(1, kr.getMatch(2).getStartPos());
+	    assertEquals(4, kr.getMatch(2).getEndPos());
+				
+		// Three constraints
+		constraints.add(createConstraint("p", 0, 0));		
+		mdq = createQuery("s:b", "s:c", constraints, true);
+		kr = ki.search(mdq, (short) 10);
+		assertEquals(2, kr.getTotalResults());
+		
+		mdq = createQuery("s:b", "s:c", constraints, false);
+		kr = ki.search(mdq, (short) 10);		
+		assertEquals(3, kr.getTotalResults());		
+
+	}
+    
+    /** Multiple documents
+     * 	Ensure same doc (inner term span)
+     * */
+    @Test
+   	public void testCase3() throws IOException {
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0()); 
+    	ki.addDoc(createFieldDoc1());
+    	ki.addDoc(createFieldDoc2());
+    	ki.commit();
+           
+       	List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+	    constraints.add(createConstraint("w", 1, 2));	    
+	    constraints.add(createConstraint("s", 1, 2));
+    	    
+	    SpanQuery mdq;	   
+		mdq = createQuery("s:b", "s:e", constraints, false);
+		kr = ki.search(mdq, (short) 10);
+		
+		assertEquals(3, kr.getTotalResults());
+		assertEquals(2, kr.getMatch(0).getLocalDocID());
+	    assertEquals(0, kr.getMatch(0).getStartPos());
+	    assertEquals(3, kr.getMatch(0).getEndPos());
+	    assertEquals(1, kr.getMatch(1).getStartPos());
+	    assertEquals(4, kr.getMatch(1).getEndPos());
+	    assertEquals(3, kr.getMatch(2).getStartPos());
+	    assertEquals(5, kr.getMatch(2).getEndPos());	
+		
+    }
+    
+	/**	Multiple documents 
+     * 	Skip to
+     * */
+    @Test
+   	public void testCase4() throws IOException {
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());
+    	ki.addDoc(createFieldDoc3());
+    	ki.addDoc(createFieldDoc1());
+    	ki.addDoc(createFieldDoc2());
+    	ki.commit();
+    	
+    	List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+	    constraints.add(createConstraint("w", 1, 2));	    
+	    constraints.add(createConstraint("s", 1, 2));
+		
+	    SpanQuery mdq;	   
+		mdq = createQuery("s:b", "s:c", constraints, false);
+		
+		SpanQuery sq = new SpanNextQuery(mdq, 
+				new SpanTermQuery(new Term("base","s:e")));
+		kr = ki.search(sq, (short) 10);
+	    
+		assertEquals(2, kr.getTotalResults());
+	    assertEquals(3, kr.getMatch(0).getStartPos());
+	    assertEquals(6, kr.getMatch(0).getEndPos());
+	    assertEquals(3, kr.getMatch(1).getLocalDocID());
+	    assertEquals(1, kr.getMatch(1).getStartPos());
+	    assertEquals(5, kr.getMatch(1).getEndPos());
+
+    }
+    
+    /** Multiple documents
+	 * 	Same tokens: ordered and unordered yield the same results
+	 * */
+    @Test
+   	public void testCase5() throws IOException {
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());    	
+    	ki.addDoc(createFieldDoc1());    	
+    	ki.commit();
+    	
+    	List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
+	    constraints.add(createConstraint("w", 1, 2));	    
+	    constraints.add(createConstraint("s", 1, 2));
+		
+	    SpanQuery mdq;	   
+		mdq = createQuery("s:c", "s:c", constraints, false);
+		kr = ki.search(mdq, (short) 10);
+		
+		assertEquals(4, kr.getTotalResults());
+	    assertEquals(1, kr.getMatch(0).getStartPos());
+	    assertEquals(3, kr.getMatch(0).getEndPos());
+	    assertEquals(2, kr.getMatch(1).getStartPos());
+	    assertEquals(5, kr.getMatch(1).getEndPos());
+	    assertEquals(1, kr.getMatch(2).getLocalDocID());
+	    assertEquals(1, kr.getMatch(2).getStartPos());
+	    assertEquals(4, kr.getMatch(2).getEndPos());
+	    assertEquals(3, kr.getMatch(3).getStartPos());
+	    assertEquals(6, kr.getMatch(3).getEndPos());	
+
+    }
+	
+}
+