Index: lucene/core/src/java/org/apache/lucene/codecs/block/BlockSkipReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/block/BlockSkipReader.java	(revision 1370367)
+++ lucene/core/src/java/org/apache/lucene/codecs/block/BlockSkipReader.java	(working copy)
@@ -152,6 +152,10 @@
     return lastPayloadByteUpto;
   }
 
+  public int getNextSkipDoc() {
+    return skipDoc[0];
+  }
+
   @Override
   protected void seekChild(int level) throws IOException {
     super.seekChild(level);
Index: lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java	(revision 1370367)
+++ lucene/core/src/java/org/apache/lucene/codecs/block/BlockPostingsReader.java	(working copy)
@@ -355,6 +355,10 @@
     // no skip data for this term):
     private int skipOffset;
 
+    // docID for next skip point, we won't use skipper if 
+    // target docID is not larger than this
+    private int nextSkipDoc;
+
     private Bits liveDocs;
 
     public BlockDocsEnum(FieldInfo fieldInfo) throws IOException {
@@ -391,6 +395,7 @@
       }
       accum = 0;
       docUpto = 0;
+      nextSkipDoc = BLOCK_SIZE - 1; // we won't skip if target is found in first block
       docBufferUpto = BLOCK_SIZE;
       skipped = false;
       return this;
@@ -475,11 +480,14 @@
     @Override
     public int advance(int target) throws IOException {
       // nocommit make frq block load lazy/skippable
+      if (DEBUG) {
+        System.out.println("  FPR.advance target=" + target);
+      }
 
-      // nocommit use skipper!!!  it has next last doc id!!
+      // current skip docID < docIDs generated from current buffer <= next skip docID
+      // we don't need to skip if target is buffered already
+      if (docFreq > BLOCK_SIZE && target > nextSkipDoc) {
 
-      if (docFreq > BLOCK_SIZE && target - accum > BLOCK_SIZE) {
-
         if (DEBUG) {
           System.out.println("load skipper");
         }
@@ -517,6 +525,7 @@
           accum = skipper.getDoc();               // actually, this is just lastSkipEntry
           docIn.seek(skipper.getDocPointer());    // now point to the block we want to search
         }
+        nextSkipDoc = skipper.getNextSkipDoc();
       }
 
       // Now scan... this is an inlined/pared down version
@@ -622,6 +631,8 @@
     // no skip data for this term):
     private int skipOffset;
 
+    private int nextSkipDoc;
+
     private Bits liveDocs;
     
     public BlockDocsAndPositionsEnum(FieldInfo fieldInfo) throws IOException {
@@ -664,6 +675,7 @@
       doc = -1;
       accum = 0;
       docUpto = 0;
+      nextSkipDoc = BLOCK_SIZE - 1;
       docBufferUpto = BLOCK_SIZE;
       skipped = false;
       return this;
@@ -785,9 +797,8 @@
 
       // nocommit 2 is heuristic guess!!
       // nocommit put cheating back!  does it help?
-      // nocommit use skipper!!!  it has next last doc id!!
       //if (docFreq > BLOCK_SIZE && target - (BLOCK_SIZE - docBufferUpto) - 2*BLOCK_SIZE > accum) {
-      if (docFreq > BLOCK_SIZE && target - accum > BLOCK_SIZE) {
+      if (docFreq > BLOCK_SIZE && target > nextSkipDoc) {
         if (DEBUG) {
           System.out.println("    try skipper");
         }
@@ -833,6 +844,7 @@
           posPendingFP = skipper.getPosPointer();
           posPendingCount = skipper.getPosBufferUpto();
         }
+        nextSkipDoc = skipper.getNextSkipDoc();
       }
 
       // Now scan... this is an inlined/pared down version
@@ -1047,6 +1059,8 @@
     // no skip data for this term):
     private int skipOffset;
 
+    private int nextSkipDoc;
+
     private Bits liveDocs;
     
     public EverythingEnum(FieldInfo fieldInfo) throws IOException {
@@ -1110,6 +1124,7 @@
       doc = -1;
       accum = 0;
       docUpto = 0;
+      nextSkipDoc = BLOCK_SIZE - 1;
       docBufferUpto = BLOCK_SIZE;
       skipped = false;
       return this;
@@ -1280,9 +1295,8 @@
 
       // nocommit 2 is heuristic guess!!
       // nocommit put cheating back!  does it help?
-      // nocommit use skipper!!!  it has next last doc id!!
       //if (docFreq > BLOCK_SIZE && target - (BLOCK_SIZE - docBufferUpto) - 2*BLOCK_SIZE > accum) {
-      if (docFreq > BLOCK_SIZE && target - accum > BLOCK_SIZE) {
+      if (docFreq > BLOCK_SIZE && target > nextSkipDoc) {
 
         if (DEBUG) {
           System.out.println("    try skipper");
@@ -1332,6 +1346,7 @@
           lastStartOffset = skipper.getStartOffset();
           payloadByteUpto = skipper.getPayloadByteUpto();
         }
+        nextSkipDoc = skipper.getNextSkipDoc();
       }
 
       // nocommit inline nextDoc here
Index: lucene/core/src/java/org/apache/lucene/codecs/MultiLevelSkipListReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/MultiLevelSkipListReader.java	(revision 1370367)
+++ lucene/core/src/java/org/apache/lucene/codecs/MultiLevelSkipListReader.java	(working copy)
@@ -59,7 +59,7 @@
   private int skipInterval[];         // skipInterval of each level
   private int[] numSkipped;           // number of docs skipped per level
     
-  private int[] skipDoc;              // doc id of current skip entry per level 
+  protected int[] skipDoc;            // doc id of current skip entry per level 
   private int lastDoc;                // doc id of last read skip entry with docId <= target
   private long[] childPointer;        // child pointer of current skip entry per level
   private long lastChildPointer;      // childPointer of last read skip entry with docId <= target
