Index: src/java/org/apache/lucene/index/AllDocsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/AllDocsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/AllDocsEnum.java	(working copy)
@@ -38,7 +38,12 @@
   }
 
   @Override
-  public int next() throws IOException {
+  public int docID() {
+    return doc;
+  }
+
+  @Override
+  public int nextDoc() throws IOException {
     return advance(doc+1);
   }
 
Index: src/java/org/apache/lucene/index/CheckIndex.java
===================================================================
--- src/java/org/apache/lucene/index/CheckIndex.java	(revision 886336)
+++ src/java/org/apache/lucene/index/CheckIndex.java	(working copy)
@@ -611,7 +611,7 @@
 
           int lastDoc = -1;
           while(true) {
-            final int doc = docs.next();
+            final int doc = docs.nextDoc();
             if (doc == DocsEnum.NO_MORE_DOCS) {
               break;
             }
@@ -652,7 +652,7 @@
           if (reader.hasDeletions()) {
             final DocsEnum docsNoDel = terms.docs(null);
             int count = 0;
-            while(docsNoDel.next() != DocsEnum.NO_MORE_DOCS) {
+            while(docsNoDel.nextDoc() != DocsEnum.NO_MORE_DOCS) {
               count++;
             }
             if (count != docFreq) {
Index: src/java/org/apache/lucene/index/codecs/DocsConsumer.java
===================================================================
--- src/java/org/apache/lucene/index/codecs/DocsConsumer.java	(revision 886336)
+++ src/java/org/apache/lucene/index/codecs/DocsConsumer.java	(working copy)
@@ -59,7 +59,7 @@
       final int base = toMerge[i].docBase;
 
       while(true) {
-        final int startDoc = docs.next();
+        final int startDoc = docs.nextDoc();
         if (startDoc == DocsEnum.NO_MORE_DOCS) {
           break;
         }
Index: src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java
===================================================================
--- src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java	(revision 886336)
+++ src/java/org/apache/lucene/index/codecs/preflex/PreFlexFields.java	(working copy)
@@ -314,7 +314,7 @@
     }
 
     @Override
-    public int next() throws IOException {
+    public int nextDoc() throws IOException {
       if (Codec.DEBUG) {
         System.out.println("pff.docs.next");
       }
@@ -340,6 +340,11 @@
     }
 
     @Override
+    public int docID() {
+      return current.doc();
+    }
+
+    @Override
     public int read(int[] docIDs, int[] freqs) throws IOException {
       if (current != docs) {
         docs.skipTo(current.doc());
Index: src/java/org/apache/lucene/index/codecs/pulsing/PulsingDocsReader.java
===================================================================
--- src/java/org/apache/lucene/index/codecs/pulsing/PulsingDocsReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/codecs/pulsing/PulsingDocsReader.java	(working copy)
@@ -203,7 +203,7 @@
       }
 
       @Override
-      public int next() {
+      public int nextDoc() {
         while(true) {
           if (nextRead >= docFreq) {
             return NO_MORE_DOCS;
@@ -244,6 +244,11 @@
         return doc.numPositions;
       }
 
+      @Override
+      public int docID() {
+        return doc.docID;
+      }
+
       class PulsingPositionsEnum extends PositionsEnum {
         int nextRead;
         PulsingDocsWriter.Position pos;
@@ -301,7 +306,7 @@
       @Override
       public int advance(int target) throws IOException {
         int doc;
-        while((doc=next()) != NO_MORE_DOCS) {
+        while((doc=nextDoc()) != NO_MORE_DOCS) {
           if (doc >= target)
             return doc;
         }
Index: src/java/org/apache/lucene/index/codecs/sep/SepDocsReader.java
===================================================================
--- src/java/org/apache/lucene/index/codecs/sep/SepDocsReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/codecs/sep/SepDocsReader.java	(working copy)
@@ -280,7 +280,7 @@
       }
 
       @Override
-      public int next() throws IOException {
+      public int nextDoc() throws IOException {
 
         if (Codec.DEBUG) {
           if (!omitTF) {
@@ -292,7 +292,7 @@
 
         while(true) {
           if (count == docFreq) {
-            return NO_MORE_DOCS;
+            return doc = NO_MORE_DOCS;
           }
 
           count++;
@@ -363,6 +363,11 @@
         return freq;
       }
 
+      @Override
+      public int docID() {
+        return doc;
+      }
+
       // Holds pending seek data for positions:
       IntIndexInput.Index posIndex;
       long payloadOffset;
@@ -522,7 +527,7 @@
         
         // Now, linear scan for the rest:
         do {
-          if (next() == NO_MORE_DOCS) {
+          if (nextDoc() == NO_MORE_DOCS) {
             return NO_MORE_DOCS;
           }
         } while (target > doc);
Index: src/java/org/apache/lucene/index/codecs/standard/StandardDocsReader.java
===================================================================
--- src/java/org/apache/lucene/index/codecs/standard/StandardDocsReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/codecs/standard/StandardDocsReader.java	(working copy)
@@ -294,7 +294,7 @@
       }
 
       @Override
-      public int next() throws IOException {
+      public int nextDoc() throws IOException {
         if (Codec.DEBUG) {
           System.out.println("sdr.next [" + desc + "] count=" + count + " vs df=" + docFreq + " freq pointer=" + freqIn.getFilePointer() + " (in=" + freqIn + "; this=" + this + ") + has skip docs=" + (skipDocs != null));
         }
@@ -384,7 +384,8 @@
         return i;
       }
 
-      public int doc() {
+      @Override
+      public int docID() {
         return doc;
       }
 
@@ -503,7 +504,7 @@
         
         // Now, linear scan for the rest:
         do {
-          if (next() == NO_MORE_DOCS)
+          if (nextDoc() == NO_MORE_DOCS)
             return NO_MORE_DOCS;
         } while (target > doc);
 
Index: src/java/org/apache/lucene/index/DirectoryReader.java
===================================================================
--- src/java/org/apache/lucene/index/DirectoryReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/DirectoryReader.java	(working copy)
@@ -1513,6 +1513,7 @@
     DocsEnum currentDocs;
     int currentBase;
     Bits skipDocs;
+    int doc = -1;
 
     MultiDocsEnum(int count) {
       subs = new DocsEnumWithBase[count];
@@ -1564,6 +1565,11 @@
     }
 
     @Override
+    public int docID() {
+      return doc;
+    }
+
+    @Override
     public int read(final int docs[], final int freqs[]) throws IOException {
       while (true) {
         while (currentDocs == null) {
@@ -1595,10 +1601,10 @@
           if (doc == NO_MORE_DOCS) {
             currentDocs = null;
           } else {
-            return doc + currentBase;
+            return this.doc = doc + currentBase;
           }
         } else if (upto == numSubs-1) {
-          return NO_MORE_DOCS;
+          return this.doc = NO_MORE_DOCS;
         } else {
           upto++;
           currentDocs = subs[upto].docs;
@@ -1608,11 +1614,11 @@
     }
 
     @Override
-    public int next() throws IOException {
+    public int nextDoc() throws IOException {
       while(true) {
         if (currentDocs == null) {
           if (upto == numSubs-1) {
-            return NO_MORE_DOCS;
+            return this.doc = NO_MORE_DOCS;
           } else {
             upto++;
             currentDocs = subs[upto].docs;
@@ -1620,9 +1626,9 @@
           }
         }
 
-        final int doc = currentDocs.next();
+        final int doc = currentDocs.nextDoc();
         if (doc != NO_MORE_DOCS) {
-          return currentBase + doc;
+          return this.doc = currentBase + doc;
         } else {
           currentDocs = null;
         }
Index: src/java/org/apache/lucene/index/DocsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/DocsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/DocsEnum.java	(working copy)
@@ -19,24 +19,28 @@
 
 import java.io.IOException;
 
+import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.util.AttributeSource;
 
 /** On obtaining a DocsEnum, you must first call next() */
 
-public abstract class DocsEnum extends AttributeSource {
+public abstract class DocsEnum extends DocIdSetIterator {
+
+  private AttributeSource atts = null;
+
   // nocommit
   public String desc;
 
-  public final static int NO_MORE_DOCS = Integer.MAX_VALUE;
-
-  /** Moves forward to the doc id >= target */
-  public abstract int advance(int target) throws IOException;
-
-  /** Returns the next docID, {@link #NO_MORE_DOCS} at the end. */
-  public abstract int next() throws IOException;
-
   public abstract int freq();
   
+  /**
+   * Returns the related attributes.
+   */
+  public final AttributeSource attributes() {
+    if (atts == null) atts = new AttributeSource();
+    return atts;
+  }
+  
   // nocommit -- fix this API so that intblock codecs are
   // able to return their own int arrays, to save a copy
   /** Bulk read: returns number of docs read.  Subclass may
@@ -44,7 +48,7 @@
   public int read(int[] docs, int[] freqs) throws IOException {
     int count = 0;
     while(count < docs.length) {
-      final int doc = next();
+      final int doc = nextDoc();
       if (doc != NO_MORE_DOCS) {
         docs[count] = doc;
         freqs[count] = freq();
Index: src/java/org/apache/lucene/index/DocumentsWriter.java
===================================================================
--- src/java/org/apache/lucene/index/DocumentsWriter.java	(revision 886336)
+++ src/java/org/apache/lucene/index/DocumentsWriter.java	(working copy)
@@ -1030,7 +1030,7 @@
           if (docs != null) {
             int limit = entry.getValue().getNum();
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS || docIDStart+docID >= limit) {
                 break;
               }
Index: src/java/org/apache/lucene/index/FieldsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/FieldsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/FieldsEnum.java	(working copy)
@@ -25,8 +25,18 @@
  *
  * NOTE: this API is experimental and will likely change */
 
-public abstract class FieldsEnum extends AttributeSource {
+public abstract class FieldsEnum {
 
+  private AttributeSource atts = null;
+
+  /**
+   * Returns the related attributes.
+   */
+  public final AttributeSource attributes() {
+    if (atts == null) atts = new AttributeSource();
+    return atts;
+  }
+  
   // nocommit -- do we need seek?
 
   /** Increments the enumeration to the next field.
Index: src/java/org/apache/lucene/index/IndexReader.java
===================================================================
--- src/java/org/apache/lucene/index/IndexReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/IndexReader.java	(working copy)
@@ -909,10 +909,14 @@
       return NO_MORE_DOCS;
     }
     @Override
-    public int next() {
+    public int nextDoc() {
       return NO_MORE_DOCS;
     }
     @Override
+    public int docID() {
+      return -1;
+    }
+    @Override
     public int freq() {
       return 1;
     }
Index: src/java/org/apache/lucene/index/LegacyFieldsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/LegacyFieldsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/LegacyFieldsEnum.java	(working copy)
@@ -171,6 +171,7 @@
     final Bits skipDocs;
 
     TermPositions tp;
+    int doc = -1;
 
     LegacyDocsEnum(IndexReader r, String field, Term term, Bits skipDocs) throws IOException {
       this.r = r;
@@ -184,20 +185,20 @@
     // always secretly skip deleted docs, and we can't work
     // around that for external readers?
     @Override
-    public int next() throws IOException {
+    public int nextDoc() throws IOException {
       if (td.next()) {
-        return td.doc();
+        return doc = td.doc();
       } else {
-        return NO_MORE_DOCS;
+        return doc = NO_MORE_DOCS;
       }
     }
 
     @Override
     public int advance(int target) throws IOException {
       if (td.skipTo(target)) {
-        return td.doc();
+        return doc = td.doc();
       } else {
-        return NO_MORE_DOCS;
+        return doc = NO_MORE_DOCS;
       }
     }
 
@@ -207,6 +208,11 @@
     }
 
     @Override
+    public int docID() {
+      return doc;
+    }
+
+    @Override
     public int read(int[] docs, int[] freqs) throws IOException {
       return td.read(docs, freqs);
     }
Index: src/java/org/apache/lucene/index/PositionsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/PositionsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/PositionsEnum.java	(working copy)
@@ -21,8 +21,18 @@
 
 import org.apache.lucene.util.AttributeSource;
 
-public abstract class PositionsEnum extends AttributeSource {
+public abstract class PositionsEnum {
 
+  private AttributeSource atts = null;
+
+  /**
+   * Returns the related attributes.
+   */
+  public final AttributeSource attributes() {
+    if (atts == null) atts = new AttributeSource();
+    return atts;
+  }
+  
   // nocommit
   public String desc;
 
Index: src/java/org/apache/lucene/index/SegmentReader.java
===================================================================
--- src/java/org/apache/lucene/index/SegmentReader.java	(revision 886336)
+++ src/java/org/apache/lucene/index/SegmentReader.java	(working copy)
@@ -1546,7 +1546,7 @@
 
     public boolean next() throws IOException {
       if (docs == null) return false;
-      doc = docs.next();
+      doc = docs.nextDoc();
       return doc != DocsEnum.NO_MORE_DOCS;
     }
   }
Index: src/java/org/apache/lucene/index/TermsEnum.java
===================================================================
--- src/java/org/apache/lucene/index/TermsEnum.java	(revision 886336)
+++ src/java/org/apache/lucene/index/TermsEnum.java	(working copy)
@@ -33,8 +33,18 @@
  * 
  * <p>On obtaining a TermsEnum, you must first call
  * {@link #next} or {@link #seek}. */
-public abstract class TermsEnum extends AttributeSource {
+public abstract class TermsEnum {
 
+  private AttributeSource atts = null;
+
+  /**
+   * Returns the related attributes.
+   */
+  public final AttributeSource attributes() {
+    if (atts == null) atts = new AttributeSource();
+    return atts;
+  }
+  
   /** Represents returned result from {@link TermsEnum.seek}.
    *  If status is FOUND, then the precise term was found.
    *  If status is NOT_FOUND, then a different term was
Index: src/java/org/apache/lucene/search/FieldCacheImpl.java
===================================================================
--- src/java/org/apache/lucene/search/FieldCacheImpl.java	(revision 886336)
+++ src/java/org/apache/lucene/search/FieldCacheImpl.java	(working copy)
@@ -281,7 +281,7 @@
             final byte termval = parser.parseByte(term);
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -334,7 +334,7 @@
             final short termval = parser.parseShort(term);
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -397,7 +397,7 @@
 
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -468,7 +468,7 @@
 
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -534,7 +534,7 @@
 
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -602,7 +602,7 @@
 
             final DocsEnum docs = termsEnum.docs(delDocs);
             while (true) {
-              final int docID = docs.next();
+              final int docID = docs.nextDoc();
               if (docID == DocsEnum.NO_MORE_DOCS) {
                 break;
               }
@@ -647,7 +647,7 @@
           final DocsEnum docs = termsEnum.docs(delDocs);
           final String termval = term.toString();
           while (true) {
-            final int docID = docs.next();
+            final int docID = docs.nextDoc();
             if (docID == DocsEnum.NO_MORE_DOCS) {
               break;
             }
@@ -707,7 +707,7 @@
 
           final DocsEnum docs = termsEnum.docs(delDocs);
           while (true) {
-            final int docID = docs.next();
+            final int docID = docs.nextDoc();
             if (docID == DocsEnum.NO_MORE_DOCS) {
               break;
             }
Index: src/java/org/apache/lucene/search/MultiPhraseQuery.java
===================================================================
--- src/java/org/apache/lucene/search/MultiPhraseQuery.java	(revision 886336)
+++ src/java/org/apache/lucene/search/MultiPhraseQuery.java	(working copy)
@@ -399,7 +399,7 @@
       Iterator i = docsEnums.iterator();
       while (i.hasNext()) {
         DocsEnumWrapper docs = (DocsEnumWrapper) i.next();
-        docs.doc = docs.docsEnum.next();
+        docs.doc = docs.docsEnum.nextDoc();
         if (docs.doc != DocsEnum.NO_MORE_DOCS) {
           add(docs);
         }
@@ -485,7 +485,7 @@
   }
 
   @Override
-  public final int next() throws IOException {
+  public final int nextDoc() throws IOException {
     if (_queue.size() == 0) {
       return NO_MORE_DOCS;
     }
@@ -507,7 +507,7 @@
         _posList.add(positions.next());
       }
 
-      docs.doc = docs.docsEnum.next();
+      docs.doc = docs.docsEnum.nextDoc();
 
       if (docs.doc != NO_MORE_DOCS) {
         _queue.updateTop();
@@ -554,7 +554,7 @@
         _queue.add(docs);
       }
     }
-    return next();
+    return nextDoc();
   }
 
   @Override
@@ -562,6 +562,11 @@
     return _freq;
   }
 
+  @Override
+  public final int docID() {
+    return _doc;
+  }
+
   /**
    * Not implemented.
    * @throws UnsupportedOperationException
Index: src/java/org/apache/lucene/search/PhrasePositions.java
===================================================================
--- src/java/org/apache/lucene/search/PhrasePositions.java	(revision 886336)
+++ src/java/org/apache/lucene/search/PhrasePositions.java	(working copy)
@@ -39,7 +39,7 @@
   }
 
   final boolean next() throws IOException {	  // increments to next doc
-    doc = docs.next();
+    doc = docs.nextDoc();
     if (doc == docs.NO_MORE_DOCS) {
       return false;
     }
Index: src/java/org/apache/lucene/search/spans/TermSpans.java
===================================================================
--- src/java/org/apache/lucene/search/spans/TermSpans.java	(revision 886336)
+++ src/java/org/apache/lucene/search/spans/TermSpans.java	(working copy)
@@ -46,7 +46,7 @@
   @Override
   public boolean next() throws IOException {
     if (count == freq) {
-      doc = docs.next();
+      doc = docs.nextDoc();
       if (doc == DocsEnum.NO_MORE_DOCS) {
         return false;
       }
Index: src/test/org/apache/lucene/index/TestCodecs.java
===================================================================
--- src/test/org/apache/lucene/index/TestCodecs.java	(revision 886336)
+++ src/test/org/apache/lucene/index/TestCodecs.java	(working copy)
@@ -359,14 +359,14 @@
 
     private void verifyDocs(int[] docs, PositionData[][] positions, DocsEnum docsEnum, boolean doPos) throws Throwable {
       for(int i=0;i<docs.length;i++) {
-        int doc = docsEnum.next();
+        int doc = docsEnum.nextDoc();
         assertTrue(doc != DocsEnum.NO_MORE_DOCS);
         assertEquals(docs[i], doc);
         if (doPos) {
           verifyPositions(positions[i], docsEnum.positions());
         }
       }
-      assertEquals(DocsEnum.NO_MORE_DOCS, docsEnum.next());
+      assertEquals(DocsEnum.NO_MORE_DOCS, docsEnum.nextDoc());
     }
 
     byte[] data = new byte[10];
@@ -524,7 +524,7 @@
                 // nocommit -- test skipping to non-existent doc
                 assertEquals(term.docs[upto2], doc);
               } else {
-                doc = docs.next();
+                doc = docs.nextDoc();
                 assertTrue(doc != -1);
                 if (Codec.DEBUG) {
                   System.out.println("TEST [" + getDesc(field, term) + "]: got next doc...");
@@ -547,7 +547,7 @@
               }
             }
 
-            assertEquals(DocsEnum.NO_MORE_DOCS, docs.next());
+            assertEquals(DocsEnum.NO_MORE_DOCS, docs.nextDoc());
 
           } else if (Codec.DEBUG) {
             System.out.println("\nTEST [" + getDesc(field, term) + "]: skip docs");
Index: src/test/org/apache/lucene/TestExternalCodecs.java
===================================================================
--- src/test/org/apache/lucene/TestExternalCodecs.java	(revision 886336)
+++ src/test/org/apache/lucene/TestExternalCodecs.java	(working copy)
@@ -346,9 +346,10 @@
       }
 
       @Override
+      // nocommit: Is this ok? it always return NO_MORE_DOCS
       public int advance(int targetDocID) {
         do {
-          next();
+          nextDoc();
         } while (upto < ramTerm.docs.size() && current.docID < targetDocID);
         return NO_MORE_DOCS;
       }
@@ -356,7 +357,7 @@
       // TODO: override bulk read, for better perf
 
       @Override
-      public int next() {
+      public int nextDoc() {
         while(true) {
           upto++;
           if (upto < ramTerm.docs.size()) {
@@ -376,6 +377,11 @@
       }
 
       @Override
+      public int docID() {
+        return current.docID;
+      }
+
+      @Override
       public PositionsEnum positions() {
         positions.reset(current);
         return positions;
