Index: src/java/org/apache/lucene/analysis/StopFilter.java
===================================================================
--- src/java/org/apache/lucene/analysis/StopFilter.java	(revision 543080)
+++ src/java/org/apache/lucene/analysis/StopFilter.java	(working copy)
@@ -19,6 +19,7 @@
 
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.Set;
 
 /**
@@ -99,18 +100,65 @@
     return stopTable;
   }    
 
+  private final LinkedList<Token> inQueue = new LinkedList<Token>();
+  private final LinkedList<Token> outQueue = new LinkedList<Token>();
+
   /**
    * Returns the next input Token whose termText() is not a stop word.
    */
   public final Token next() throws IOException {
-    // return the first non-stop word found
-    for (Token token = input.next(); token != null; token = input.next())
-    {
-        String termText = ignoreCase ? token.termText.toLowerCase() : token.termText;
-        if (!stopWords.contains(termText))
-          return token;
-    }
-    // reached EOS -- return null
-    return null;
-  }
+	  while (true) {
+			if (!outQueue.isEmpty()) {
+				return outQueue.removeFirst();
+			}
+			Token token = null;
+			if (inQueue.isEmpty()) {
+				token = input.next();
+			} else {
+				token = inQueue.removeFirst();
+			}
+			if (null == token) {
+				return null;
+			}
+
+			Token next = null;
+			if (inQueue.isEmpty()) {
+				next = input.next();
+			} else {
+				next = inQueue.removeFirst();
+			}
+			boolean stopword = false;
+			
+			LinkedList<Token> checkQueue = new LinkedList<Token>();
+			checkQueue.addLast(token);
+
+			String termText = ignoreCase ? token.termText.toLowerCase()
+					: token.termText;
+			if (stopWords.contains(termText)) {
+				stopword = true;
+			}
+
+			while (next != null && next.getPositionIncrement() == 0) {
+				checkQueue.addLast(next);
+				termText = ignoreCase ? next.termText.toLowerCase()
+						: next.termText;
+				if (stopWords.contains(termText)) {
+					stopword = true;
+				}
+				if (inQueue.isEmpty()) {
+					next = input.next();
+				} else {
+					next = inQueue.removeFirst();
+				}
+			}
+			if (!stopword) {
+				for (Token out : checkQueue) {
+					outQueue.addLast(out);
+				}
+			}
+			if (next != null) {
+				inQueue.addFirst(next);
+			}
+		}
+	}
 }
Index: src/test/org/apache/lucene/analysis/TestStopFilter.java
===================================================================
--- src/test/org/apache/lucene/analysis/TestStopFilter.java	(revision 543080)
+++ src/test/org/apache/lucene/analysis/TestStopFilter.java	(working copy)
@@ -18,6 +18,8 @@
 
 import java.io.IOException;
 import java.io.StringReader;
+import java.util.Arrays;
+import java.util.Iterator;
 
 import junit.framework.TestCase;
 
@@ -44,5 +46,94 @@
     assertEquals("Now", stream.next().termText());
     assertEquals(null,stream.next());
   }
+  
+  
+  public Token newToken(String termText, int pos) {
+		Token token = new Token(termText, 0, 0);
+		token.setPositionIncrement(pos);
+		return token;
+  }
 
+  public void testPosInc( String[] stopWords, boolean ignoreCase, final String expectation, final Token... tokens)
+			throws IOException {
+
+	  final Iterator<Token> token = Arrays.asList(tokens).iterator();
+
+	  final TokenStream ts = new StopFilter(new TokenStream() {
+		  public Token next() {
+			  return token.hasNext() ? token.next() : null;
+		  }
+	  }, stopWords, ignoreCase);
+
+	  final String result = tokenStream2String(ts);
+	  assertEquals(expectation + " != " + result, expectation, result);
+//	  System.out.println(result) ;
+  }	  
+
+
+  public static String tokenStream2String(TokenStream input)
+			throws IOException {
+	  StringBuffer output = new StringBuffer();
+	  Token token = input.next();
+	  if (null != token) {
+		  output.append(token.termText());
+	  }
+	  for (token = input.next(); null != token; token = input.next()) {
+		  output.append(" ").append(token.termText());
+	  }
+	  input.close();
+	  return output.toString();
+  }
+
+  public void testPosIncs() throws IOException {
+
+		String[] stopWords = new String[] { "is", "the" };
+		testPosInc(stopWords, false, 
+				"A The B", 
+				newToken("A", 1), 
+				newToken("is", 1), 
+				newToken("The", 1), 
+				newToken("B", 1));
+		testPosInc(stopWords, true, 
+				"A B", 
+				newToken("A", 1), 
+				newToken("is", 1),
+				newToken("The", 1), 
+				newToken("B", 1));
+
+		testPosInc(stopWords, false,
+				"A B", 
+				newToken("A", 1),
+				newToken("is", 1), 
+				newToken("are", 0), 
+				newToken("be", 0),
+				newToken("B", 1));
+		
+		testPosInc(stopWords, false,
+				"A B", 
+				newToken("A", 1),
+				newToken("are", 1), 
+				newToken("is", 0), 
+				newToken("be", 0),
+				newToken("B", 1));
+
+		
+		testPosInc(stopWords, false, 
+				"A The B", 
+				newToken("A", 1), 
+				newToken("is", 1), 
+				newToken("are", 0),
+				newToken("be", 0), 
+				newToken("The", 1),
+				newToken("B", 1));
+		testPosInc(stopWords, true,
+				"A B", 
+				newToken("A", 1), 
+				newToken("is", 1),
+				newToken("are", 0), 
+				newToken("be", 0), 
+				newToken("The", 1),
+				newToken("B", 1));
+	}
+
 }
