Element distance exclusion
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 95ff5cb..3368ef9 100644
--- a/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
+++ b/src/main/java/de/ids_mannheim/korap/query/SpanDistanceQuery.java
@@ -12,6 +12,7 @@
 import org.apache.lucene.util.ToStringUtils;
 
 import de.ids_mannheim.korap.query.spans.DistanceExclusionSpan;
+import de.ids_mannheim.korap.query.spans.ElementDistanceExclusionSpan;
 import de.ids_mannheim.korap.query.spans.ElementDistanceSpans;
 import de.ids_mannheim.korap.query.spans.TokenDistanceSpans;
 import de.ids_mannheim.korap.query.spans.UnorderedElementDistanceSpans;
@@ -19,7 +20,9 @@
 
 /** Match two ordered or unordered Spans with minimum and maximum 
  * 	distance constraints. The distance unit can be word (token), 
- * 	sentence or paragraph. 
+ * 	sentence or paragraph. The distance constraint can also be
+ * 	specified to match some Spans which do not co-occur with some 
+ * 	other Spans within a min and max distance. 
  * 
  * 	@author margaretha
  * */
@@ -105,7 +108,8 @@
 		
 		if (this.elementQuery != null) {
 			if (isExclusion()){
-				
+				return new ElementDistanceExclusionSpan(this, context, acceptDocs, 
+						termContexts, isOrdered);
 			}			
 			else if (isOrdered){
 				return new ElementDistanceSpans(this, context, acceptDocs, 
diff --git a/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceExclusionSpan.java b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceExclusionSpan.java
new file mode 100644
index 0000000..520ff75
--- /dev/null
+++ b/src/main/java/de/ids_mannheim/korap/query/spans/ElementDistanceExclusionSpan.java
@@ -0,0 +1,251 @@
+package de.ids_mannheim.korap.query.spans;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+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 de.ids_mannheim.korap.query.SpanDistanceQuery;
+
+/** Span enumeration of the first spans which do NOT occur together 
+ * 	with the second spans within a range of some element-based distance 
+ * 	(sentence or paragraph). Note: The element distance unit does not 
+ * 	overlap to each other.
+ * 
+ * 	@author margaretha
+ * */
+public class ElementDistanceExclusionSpan extends DistanceSpans{
+
+	private Spans elements;
+	private boolean hasMoreElements;
+	private int elementPosition;
+	
+	private boolean isOrdered;
+	private boolean hasMoreSecondSpans;
+		
+	protected List<CandidateSpan> candidateList, targetList;	
+	private int currentDocNum;
+	
+	private int minDistance, maxDistance;
+	private int firstSpanPostion;
+	
+	public ElementDistanceExclusionSpan(SpanDistanceQuery query,
+			AtomicReaderContext context, Bits acceptDocs,
+			Map<Term, TermContext> termContexts, boolean isOrdered) 
+			throws IOException {
+		super(query, context, acceptDocs, termContexts);
+		
+		elements = query.getElementQuery().
+	  			getSpans(context, acceptDocs, termContexts);	  		
+  		hasMoreElements = elements.next();  		
+  		hasMoreSpans = firstSpans.next() && hasMoreElements;  		  		
+  		hasMoreSecondSpans = secondSpans.next();
+  		
+  		elementPosition=0;
+  		this.isOrdered = isOrdered;
+  		candidateList = new ArrayList<CandidateSpan>();
+  		targetList = new ArrayList<CandidateSpan>();
+  		currentDocNum = firstSpans.doc();
+  		
+  		minDistance = query.getMinDistance();
+		maxDistance = query.getMaxDistance();	
+	}
+
+	@Override
+	protected boolean advance() throws IOException {
+		while(!targetList.isEmpty() || (hasMoreSpans && ensureSameDoc(firstSpans, elements))){
+			if (!targetList.isEmpty()){
+				if (isTargetValid()) return true;
+				else continue;
+			}
+			if (checkFirstSpan()) return true;			
+		}
+		return false;
+	}
+	
+	private boolean isTargetValid() throws IOException{
+		CandidateSpan target = targetList.get(0);
+		targetList.remove(0);			
+		firstSpanPostion = target.getPosition();
+		filterCandidateList(firstSpanPostion);
+		collectRightCandidates();
+		
+		if (isWithinDistance()){
+			return false;
+		}		
+		setMatchProperties(target);
+		return true;
+	}
+	
+	private boolean checkFirstSpan() throws IOException{
+		if (firstSpans.doc() != currentDocNum){
+			currentDocNum = firstSpans.doc();
+			candidateList.clear();
+		}
+		
+		if (hasMoreSecondSpans) {
+			if (secondSpans.doc() == firstSpans.doc()){ 
+				return (findMatch() ? true : false);
+			}			
+			else if (secondSpans.doc() < firstSpans.doc()){
+				hasMoreSecondSpans = secondSpans.skipTo(firstSpans.doc());
+				return false;
+			}
+		}		
+		return (isFirstSpanValid() ? true : false);
+	}
+	
+	private boolean isFirstSpanValid() throws IOException{
+		if (candidateList.isEmpty()){
+			if (isFirstSpanInElement()){		
+				setMatchProperties(new CandidateSpan(firstSpans,elementPosition));
+				hasMoreSpans = firstSpans.next();
+				return true;
+			}
+			hasMoreSpans = firstSpans.next();
+			return false;		
+		}
+		return (findMatch() ? true : false);			
+	}
+	
+	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;
+			}			
+			
+			hasMoreElements = elements.next();
+			elementPosition++;
+		}
+		return false;
+	}
+
+	private boolean findMatch() throws IOException {		
+		if (!isOrdered) collectLeftCandidates();
+		
+		if (isFirstSpanInElement()){
+			CandidateSpan target = new CandidateSpan(firstSpans,elementPosition);
+			hasMoreSpans = firstSpans.next();
+			// Checking the secondspans in the left side
+			if (!isOrdered && isWithinDistance()) return false;
+			// Checking the secondspans in the right side
+			collectRightCandidates();
+			if (isWithinDistance()) return false;
+			
+			setMatchProperties(target);
+			return true;
+		}
+		hasMoreSpans = firstSpans.next();
+		return false;
+	}
+	
+	private void collectRightCandidates() throws IOException{
+		while (hasMoreSecondSpans && secondSpans.doc() == currentDocNum){
+			
+			if (elementPosition > firstSpanPostion+maxDistance){
+				break;
+			}
+			if (hasMoreSpans && firstSpans.start() < secondSpans.start() &&
+					firstSpans.doc() == currentDocNum){
+				if (advanceElementTo(firstSpans)){
+					targetList.add(new CandidateSpan(firstSpans, elementPosition));
+				}
+				hasMoreSpans = firstSpans.next();
+				continue;
+			}
+			
+			if (advanceElementTo(secondSpans)){
+				candidateList.add(new CandidateSpan(secondSpans,elementPosition));
+			}
+			hasMoreSecondSpans = secondSpans.next();
+		}		
+	}
+	
+	private void collectLeftCandidates() throws IOException{
+		while(hasMoreSecondSpans && secondSpans.doc() == firstSpans.doc() &&
+				secondSpans.start() < firstSpans.end()){
+			if (advanceElementTo(secondSpans)){
+				candidateList.add(new CandidateSpan(secondSpans,elementPosition));
+				filterCandidateList(elementPosition);
+			}
+			hasMoreSecondSpans = secondSpans.next();
+		}	
+	}
+	
+	private boolean isWithinDistance(){
+		int actualDistance; 
+		for (CandidateSpan cs: candidateList){
+			actualDistance = cs.getPosition() - firstSpanPostion;
+			if (!isOrdered) actualDistance = Math.abs(actualDistance);
+			
+			if (minDistance <= actualDistance && actualDistance <= maxDistance)
+				return true;
+		}
+		return false;
+	}
+	
+	private boolean isFirstSpanInElement() throws IOException {
+		if (advanceElementTo(firstSpans)){
+			firstSpanPostion = elementPosition;
+			filterCandidateList(firstSpanPostion);
+			return true;
+		}
+		return false;
+	}
+	
+	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();
+		}		
+	}	
+	
+	private void setMatchProperties(CandidateSpan match) throws IOException{
+		matchDocNumber = match.getDoc();
+		matchStartPosition = match.getStart();
+		matchEndPosition = match.getEnd();
+		
+  		if (collectPayloads && match.getPayloads() != null)
+	    	matchPayload.addAll(match.getPayloads());
+  		
+  		setMatchFirstSpan(match);
+  		  		
+  		log.trace("doc# {}, start {}, end {}",matchDocNumber,matchStartPosition,
+				matchEndPosition);		
+	}
+
+	@Override
+	public boolean skipTo(int target) throws IOException {
+		if (hasMoreSpans && firstSpans.doc() < target){
+			if (!firstSpans.skipTo(target)){
+				hasMoreSpans = false;
+				return false;
+			}
+		}
+		return advance();
+	}
+
+	@Override
+	public long cost() {
+		return elements.cost() + firstSpans.cost() + secondSpans.cost();
+	}
+
+}
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 b079c72..229004e 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
@@ -19,6 +19,8 @@
  * 	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.
  * 
  * @author margaretha
  * */
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 440d76f..732eb42 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
@@ -109,8 +109,6 @@
 		
 		log.trace("doc# {}, start {}, end {}",matchDocNumber,matchStartPosition,
 				matchEndPosition);	
-		// System.out.println("firstspan "+getMatchFirstSpan().getStart()+" "+ getMatchFirstSpan().getEnd());
-		// System.out.println("secondspan "+getMatchSecondSpan().getStart()+" "+ getMatchSecondSpan().getEnd());
 	}
 
 	@Override
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestElementDistanceExclusionIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestElementDistanceExclusionIndex.java
new file mode 100644
index 0000000..49c1906
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/index/TestElementDistanceExclusionIndex.java
@@ -0,0 +1,207 @@
+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 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.SpanNextQuery;
+
+public class TestElementDistanceExclusionIndex {
+	
+    KorapResult kr;
+    KorapIndex ki; 
+    
+    private SpanQuery createQuery(String e, String x, String y, int min, int max, boolean isOrdered,
+    		boolean exclusion){
+    	SpanDistanceQuery sq = new SpanDistanceQuery(    			
+        		new SpanElementQuery("base",e),
+        		new SpanTermQuery(new Term("base",x)),
+        		new SpanTermQuery(new Term("base",y)),
+        		min,
+        		max,
+        		isOrdered,
+        		true        		
+        );
+    	sq.setExclusion(exclusion);
+    	return sq;
+    }
+	
+	private FieldDocument createFieldDoc0(){
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-0");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:c|_1#0-1|<>:s#0-1$<i>1]" +
+            "[(1-2)s:e|_2#1-2|<>:s#1-2$<i>2]" +         
+            "[(2-3)s:c|_3#2-3|<>:s#2-4$<i>4]" +
+            "[(3-4)s:c|_4#3-4]" + 
+            "[(4-5)s:d|_5#4-5|<>:s#4-6$<i>6]" +
+            "[(5-6)s:c|_6#5-6]" +
+            "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7]" +
+            "[(7-8)s:e|_8#7-8|<>:s#7-9$<i>9]" + 
+            "[(8-9)s:c|_9#8-9]" + 
+            "[(9-10)s:d|_10#9-10]");
+        return fd;
+    }
+    
+	private FieldDocument createFieldDoc1() {
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-1");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:e|_1#0-1|<>:s#0-1$<i>1]" +
+            "[(1-2)s:e|_2#1-2|<>:s#1-2$<i>2]" +             
+            "[(2-3)s:d|_3#2-3|<>:s#2-4$<i>4]" +
+            "[(3-4)s:a|_4#3-4]" + 
+            "[(4-5)s:d|_5#4-5|<>:s#4-7$<i>6]" +             
+            "[(5-6)s:a|_6#5-6]" +
+            "[(6-7)s:e|_7#6-7|<>:s#6-7$<i>9]" +
+            "[(7-8)s:e|_8#7-8]" + 
+            "[(8-9)s:d|_9#8-9]");
+        return fd;
+	}
+	
+	private FieldDocument createFieldDoc2(){
+    	FieldDocument fd = new FieldDocument();
+        fd.addString("ID", "doc-");
+        fd.addTV("base",
+            "text",             
+            "[(0-1)s:d|_1#0-1|<>:s#0-1$<i>1]" +
+            "[(1-2)s:c|_2#1-2|<>:s#1-2$<i>2]" +         
+            "[(2-3)s:a|_3#2-3|<>:s#2-4$<i>4]" +
+            "[(3-4)s:c|_4#3-4]" + 
+            "[(4-5)s:a|_5#4-5|<>:s#4-6$<i>6]" +
+            "[(5-6)s:c|_6#5-6]" +
+            "[(6-7)s:d|_7#6-7|<>:s#6-7$<i>7]" +
+            "[(7-8)s:a|_8#7-8|<>:s#7-9$<i>9]" + 
+            "[(8-9)s:c|_9#8-9]");
+        return fd;
+    }
+	
+    /** Distance Zero, unordered
+     * 	There is a secondspan on the right side
+     * */
+    @Test
+    public void testCase1() throws IOException{
+    	ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+        SpanQuery sq;
+        sq = createQuery("s","s:d","s:c",0,0,false,true);                
+        kr = ki.search(sq, (short) 10);
+        assertEquals(1, kr.totalResults());
+        assertEquals(6, kr.match(0).startPos);
+        assertEquals(7, kr.match(0).endPos);
+    }
+    
+    /** There is another firstspan within max distance
+     * 	Unordered
+     * */
+    @Test
+    public void testCase2() throws IOException{
+    	ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+        SpanQuery sq;       
+		        
+	    sq = createQuery("s","s:c","s:d",0,0,false,true);                
+	    kr = ki.search(sq, (short) 10);
+	    
+	    assertEquals(4, kr.totalResults());
+	    assertEquals(0, kr.match(0).startPos);
+        assertEquals(1, kr.match(0).endPos);
+        assertEquals(2, kr.match(1).startPos);
+        assertEquals(3, kr.match(1).endPos);
+        assertEquals(3, kr.match(2).startPos);
+        assertEquals(4, kr.match(2).endPos);
+        assertEquals(8, kr.match(3).startPos);
+        assertEquals(9, kr.match(3).endPos);
+    }
+    
+    /** Distance 0-1, ordered, unordered
+     * */
+    @Test
+    public void testCase3() throws IOException{
+    	ki = new KorapIndex();
+        ki.addDoc(createFieldDoc0()); 
+        ki.commit();
+        SpanQuery sq;
+        // unordered
+        sq = createQuery("s","s:c","s:e",0,1,false,true);                
+        kr = ki.search(sq, (short) 10);
+        assertEquals(1, kr.totalResults());
+        assertEquals(5, kr.match(0).startPos);
+        assertEquals(6, kr.match(0).endPos);
+        
+        //ordered 
+        sq = createQuery("s","s:c","s:e",0,1,true,true);                
+        kr = ki.search(sq, (short) 10);
+        assertEquals(3, kr.totalResults());
+        assertEquals(2, kr.match(0).startPos);
+        assertEquals(3, kr.match(0).endPos);
+        assertEquals(3, kr.match(1).startPos);
+        assertEquals(4, kr.match(1).endPos);
+    }
+    
+	/** Multiple documents, ordered
+	 * 	No more secondspans, but there is still a firstspan
+	 * */
+	@Test
+    public void testCase4() throws IOException{
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());
+        ki.addDoc(createFieldDoc1()); 
+        ki.commit();
+        SpanQuery sq;
+        
+        sq = createQuery("s","s:d","s:e",1,1,true,true);                
+        kr = ki.search(sq, (short) 10);
+        
+        assertEquals(3, kr.totalResults());
+	    assertEquals(4, kr.match(0).startPos);
+        assertEquals(5, kr.match(0).endPos);
+        assertEquals(1, kr.match(1).getLocalDocID());
+        assertEquals(2, kr.match(1).startPos);
+        assertEquals(3, kr.match(1).endPos);
+        assertEquals(8, kr.match(2).startPos);
+        assertEquals(9, kr.match(2).endPos);
+	}
+    
+	/** Skip to
+	 * */
+	@Test
+    public void testCase5() throws IOException{
+    	ki = new KorapIndex();
+    	ki.addDoc(createFieldDoc0());
+        ki.addDoc(createFieldDoc1());
+        ki.addDoc(createFieldDoc0());
+        ki.addDoc(createFieldDoc2());        
+        ki.commit();
+        
+        SpanQuery sq = createQuery("s","s:c","s:d",1,1,false,true);
+        kr = ki.search(sq, (short) 10);
+        assertEquals(3, kr.totalResults());        
+        assertEquals(3, kr.match(2).getLocalDocID());
+        assertEquals(3, kr.match(2).startPos);
+        assertEquals(4, kr.match(2).endPos);
+        
+        sq = new SpanNextQuery(
+        		createQuery("s","s:c","s:d",1,1,false,true), 
+        		new SpanTermQuery(new Term("base", "s:a")));
+        
+        kr = ki.search(sq, (short) 10);
+        assertEquals(1, kr.totalResults());
+        assertEquals(3, kr.match(0).getLocalDocID());
+        assertEquals(3, kr.match(0).startPos);
+        assertEquals(5, kr.match(0).endPos);
+	}
+}
diff --git a/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
index c21ebb1..2136f9c 100644
--- a/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
+++ b/src/test/java/de/ids_mannheim/korap/index/TestMultipleDistanceIndex.java
@@ -82,7 +82,8 @@
             "[(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]");
+            "[(5-6)s:d|_6#5-6]" +
+        	"[(6-7)s:b|_7#6-7|<>:s#6-7$<i>7|<>:p#6-7$<i>7]" );
         return fd;
 	}
     
@@ -193,7 +194,7 @@
 		mdq = createQuery("s:b", "s:e", constraints, false);
 		kr = ki.search(mdq, (short) 10);		
 
-		assertEquals(4, kr.getTotalResults());		
+		assertEquals(5, kr.getTotalResults());		
 	    assertEquals(3, kr.getMatch(0).getStartPos());
 	    assertEquals(6, kr.getMatch(0).getEndPos());
 	    assertEquals(2, kr.getMatch(1).getLocalDocID());
@@ -201,6 +202,17 @@
 	    assertEquals(4, kr.getMatch(2).getEndPos());
 	    assertEquals(3, kr.getMatch(3).getStartPos());
 	    assertEquals(5, kr.getMatch(3).getEndPos());	
+	    assertEquals(4, kr.getMatch(4).getStartPos());
+	    assertEquals(7, kr.getMatch(4).getEndPos());
+	    
+//	    System.out.print(kr.getTotalResults()+"\n");
+//		for (int i=0; i< kr.getTotalResults(); i++){
+//			System.out.println(
+//				kr.match(i).getLocalDocID()+" "+
+//				kr.match(i).startPos + " " +
+//				kr.match(i).endPos
+//		    );
+//		}
 		
     }
     
@@ -310,16 +322,23 @@
     /** Exclusion, multiple documents
      * 	wait for element distance exclusion 
      * */
-/*    @Test
+    @Test
     public void testCase7() throws IOException {
-    	ki = new KorapIndex();
-    	//ki.addDoc(createFieldDoc3());
-    	ki.addDoc(createFieldDoc0());
+    	ki = new KorapIndex();   	
     	ki.addDoc(createFieldDoc2());    	
     	ki.commit();
     	
+    	SpanQuery sx = new SpanTermQuery(new Term("base","s:b")); 
+		SpanQuery sy = new SpanTermQuery(new Term("base","s:c"));
+    	// Second constraint
+		SpanDistanceQuery sq = new SpanDistanceQuery(new SpanElementQuery("base", "s"), sx,
+				sy, 0, 0, false, true);
+    	sq.setExclusion(true);
+		kr = ki.search(sq, (short) 10);	
+    	// 0-1, 1-2, 6-7
+				
     	List<DistanceConstraint> constraints = new ArrayList<DistanceConstraint>();
-	    constraints.add(new DistanceConstraint(0, 1,true));
+	    constraints.add(new DistanceConstraint(0, 2,true));
 	    constraints.add(new DistanceConstraint(new SpanElementQuery("base", "s"), 
 				0, 0,true));
 	    	    
@@ -327,14 +346,27 @@
 		mdq = createQuery("s:b", "s:c", constraints, false);
 		kr = ki.search(mdq, (short) 10);
 		
-		System.out.print(kr.getTotalResults()+"\n");
-		for (int i=0; i< kr.getTotalResults(); i++){
-			System.out.println(
-				kr.match(i).getLocalDocID()+" "+
-				kr.match(i).startPos + " " +
-				kr.match(i).endPos
-		    );
-		}
-	}*/
+		assertEquals(2, kr.getTotalResults());
+	    assertEquals(0, kr.getMatch(0).getStartPos());
+	    assertEquals(1, kr.getMatch(0).getEndPos());
+	    assertEquals(6, kr.getMatch(1).getStartPos());
+	    assertEquals(7, kr.getMatch(1).getEndPos());
+		
+	    // Third constraint
+	    sq = new SpanDistanceQuery(new SpanElementQuery("base", "p"), sx,
+				sy, 0, 0, false, true);
+    	sq.setExclusion(true);
+		// 6-7
+	    
+		constraints.add(new DistanceConstraint(new SpanElementQuery("base", "p"), 
+				0, 0,true));
+	    mdq = createQuery("s:b", "s:c", constraints, false);
+		kr = ki.search(mdq, (short) 10);			
+		
+	    assertEquals(1, kr.getTotalResults());
+	    assertEquals(6, kr.getMatch(0).getStartPos());
+	    assertEquals(7, kr.getMatch(0).getEndPos());
+
+	}
 }