diff --git a/lucene/src/java/org/apache/lucene/index/values/Bytes.java b/lucene/src/java/org/apache/lucene/index/values/Bytes.java
index 70f32fa..57a9d86 100644
--- a/lucene/src/java/org/apache/lucene/index/values/Bytes.java
+++ b/lucene/src/java/org/apache/lucene/index/values/Bytes.java
@@ -253,7 +253,7 @@ public final class Bytes {
     public ValuesEnum getEnum(AttributeSource attrSource) throws IOException {
       return new SourceEnum(attrSource, type(), this, maxDoc()) {
         @Override
-        public int advance(int target) throws IOException {
+        public int seek(int target) throws IOException {
           if (target >= numDocs) {
             return pos = NO_MORE_DOCS;
           }
@@ -374,7 +374,7 @@ public final class Bytes {
       return new SourceEnum(attrSource, type(), this, maxDoc()) {
 
         @Override
-        public int advance(int target) throws IOException {
+        public int seek(int target) throws IOException {
           if (target >= numDocs) {
             return pos = NO_MORE_DOCS;
           }
@@ -714,7 +714,7 @@ public final class Bytes {
   }
   
   abstract static class DerefBytesEnumBase extends ValuesEnum {
-    private final PackedInts.ReaderIterator idx;
+    private final PackedInts.SeekableReaderIterator idx;
     private final int valueCount;
     private int pos = -1;
     protected final IndexInput datIn;
@@ -726,7 +726,7 @@ public final class Bytes {
       super(source, enumType);
       this.datIn = datIn;
       this.size = size;
-      idx = PackedInts.getReaderIterator(idxIn);
+      idx = PackedInts.getSeekableReaderIterator(idxIn);
       fp = datIn.getFilePointer();
       if (size > 0) {
         bytesRef.grow(this.size);
@@ -746,10 +746,10 @@ public final class Bytes {
     }
 
     @Override
-    public int advance(int target) throws IOException {
+    public int seek(int target) throws IOException {
       if (target < valueCount) {
         long address;
-        while ((address = idx.advance(target)) == 0) {
+        while ((address = idx.seek(target)) == 0) {
           if (++target >= valueCount) {
             return pos = NO_MORE_DOCS;
           }
@@ -766,7 +766,7 @@ public final class Bytes {
       if (pos >= valueCount) {
         return pos = NO_MORE_DOCS;
       }
-      return advance(pos + 1);
+      return seek(pos + 1);
     }
 
     public void close() throws IOException {
diff --git a/lucene/src/java/org/apache/lucene/index/values/FixedStraightBytesImpl.java b/lucene/src/java/org/apache/lucene/index/values/FixedStraightBytesImpl.java
index 64357b0..36c0f79 100644
--- a/lucene/src/java/org/apache/lucene/index/values/FixedStraightBytesImpl.java
+++ b/lucene/src/java/org/apache/lucene/index/values/FixedStraightBytesImpl.java
@@ -294,7 +294,7 @@ class FixedStraightBytesImpl {
       public ValuesEnum getEnum(AttributeSource attrSource) throws IOException {
         return new SourceEnum(attrSource, type(), this, maxDoc) {
           @Override
-          public int advance(int target) throws IOException {
+          public int seek(int target) throws IOException {
             if (target >= numDocs) {
               return pos = NO_MORE_DOCS;
             }
@@ -381,7 +381,7 @@ class FixedStraightBytesImpl {
     }
 
     @Override
-    public int advance(int target) throws IOException {
+    public int seek(int target) throws IOException {
       if (target >= maxDoc || size == 0) {
         return pos = NO_MORE_DOCS;
       }
@@ -401,7 +401,7 @@ class FixedStraightBytesImpl {
       if (pos >= maxDoc) {
         return pos = NO_MORE_DOCS;
       }
-      return advance(pos + 1);
+      return seek(pos + 1);
     }
   }
 }
diff --git a/lucene/src/java/org/apache/lucene/index/values/IndexDocValues.java b/lucene/src/java/org/apache/lucene/index/values/IndexDocValues.java
index 305a076..6255f84 100644
--- a/lucene/src/java/org/apache/lucene/index/values/IndexDocValues.java
+++ b/lucene/src/java/org/apache/lucene/index/values/IndexDocValues.java
@@ -340,7 +340,7 @@ public abstract class IndexDocValues implements Closeable {
     public int nextDoc() throws IOException {
       if (pos == NO_MORE_DOCS)
         return NO_MORE_DOCS;
-      return advance(pos + 1);
+      return seek(pos + 1);
     }
   }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/IndexDocValuesArray.java b/lucene/src/java/org/apache/lucene/index/values/IndexDocValuesArray.java
index b9041d0..248aeda 100644
--- a/lucene/src/java/org/apache/lucene/index/values/IndexDocValuesArray.java
+++ b/lucene/src/java/org/apache/lucene/index/values/IndexDocValuesArray.java
@@ -76,7 +76,7 @@ abstract class IndexDocValuesArray extends Source {
       return new SourceEnum(attrSource, type(), this, maxDocID + 1) {
 
         @Override
-        public int advance(int target) throws IOException {
+        public int seek(int target) throws IOException {
           if (target >= numDocs) {
             return pos = NO_MORE_DOCS;
           }
@@ -89,7 +89,7 @@ abstract class IndexDocValuesArray extends Source {
       return new SourceEnum(attrSource, type(), this, maxDocID + 1) {
 
         @Override
-        public int advance(int target) throws IOException {
+        public int seek(int target) throws IOException {
           if (target >= numDocs) {
             return pos = NO_MORE_DOCS;
           }
@@ -414,8 +414,8 @@ abstract class IndexDocValuesArray extends Source {
     }
 
     @Override
-    public int advance(int target) throws IOException {
-      final int advance = super.advance(target);
+    public int seek(int target) throws IOException {
+      final int advance = super.seek(target);
       if (advance != NO_MORE_DOCS) {
         intsRef.ints[0] = toLong(this.bytesRef);
       }
@@ -441,8 +441,8 @@ abstract class IndexDocValuesArray extends Source {
     }
     
     @Override
-    public int advance(int target) throws IOException {
-      final int retVal = super.advance(target);
+    public int seek(int target) throws IOException {
+      final int retVal = super.seek(target);
       if (retVal != NO_MORE_DOCS) {
         floatsRef.floats[floatsRef.offset] = toDouble(bytesRef);
       }
diff --git a/lucene/src/java/org/apache/lucene/index/values/MultiIndexDocValues.java b/lucene/src/java/org/apache/lucene/index/values/MultiIndexDocValues.java
index e0b126d..eefc4b3 100644
--- a/lucene/src/java/org/apache/lucene/index/values/MultiIndexDocValues.java
+++ b/lucene/src/java/org/apache/lucene/index/values/MultiIndexDocValues.java
@@ -131,15 +131,13 @@ public class MultiIndexDocValues extends IndexDocValues {
     }
 
     @Override
-    public int advance(int target) throws IOException {
-      assert target > currentDoc : "target " + target
-          + " must be > than the current doc " + currentDoc;
+    public int seek(int target) throws IOException {
       int relativeDoc = target - currentStart;
       do {
         if (target >= maxDoc) {// we are beyond max doc
           return currentDoc = NO_MORE_DOCS;
         }
-        if (target >= currentMax) {
+        if (target >= currentMax || target < currentStart) {
           final int idx = ReaderUtil.subIndex(target, starts);
           currentEnum.close();
           currentEnum = docValuesIdx[idx].docValues.getEnum();
@@ -150,7 +148,7 @@ public class MultiIndexDocValues extends IndexDocValues {
         }
         target = currentMax; // make sure that we advance to the next enum if the current is exhausted
 
-      } while ((relativeDoc = currentEnum.advance(relativeDoc)) == NO_MORE_DOCS);
+      } while ((relativeDoc = currentEnum.seek(relativeDoc)) == NO_MORE_DOCS);
       return currentDoc = currentStart + relativeDoc;
     }
 
@@ -161,7 +159,7 @@ public class MultiIndexDocValues extends IndexDocValues {
 
     @Override
     public int nextDoc() throws IOException {
-      return advance(currentDoc + 1);
+      return seek(currentDoc + 1);
     }
   }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/PackedIntValues.java b/lucene/src/java/org/apache/lucene/index/values/PackedIntValues.java
index b73d651..bac5d5e 100644
--- a/lucene/src/java/org/apache/lucene/index/values/PackedIntValues.java
+++ b/lucene/src/java/org/apache/lucene/index/values/PackedIntValues.java
@@ -268,7 +268,7 @@ class PackedIntValues {
     public ValuesEnum getEnum(AttributeSource attrSource) throws IOException {
       return new SourceEnum(attrSource, type(), this, values.size()) {
         @Override
-        public int advance(int target) throws IOException {
+        public int seek(int target) throws IOException {
           if (target >= numDocs)
             return pos = NO_MORE_DOCS;
           intsRef.ints[intsRef.offset] = source.getInt(target);
@@ -284,7 +284,7 @@ class PackedIntValues {
   }
 
   private static final class PackedIntsEnumImpl extends ValuesEnum {
-    private final PackedInts.ReaderIterator ints;
+    private final PackedInts.SeekableReaderIterator ints;
     private long minValue;
     private final IndexInput dataIn;
     private final long defaultValue;
@@ -298,7 +298,7 @@ class PackedIntValues {
       this.dataIn = dataIn;
       minValue = dataIn.readLong();
       defaultValue = dataIn.readLong();
-      this.ints = PackedInts.getReaderIterator(dataIn);
+      this.ints = PackedInts.getSeekableReaderIterator(dataIn);
       maxDoc = ints.size();
     }
 
@@ -309,11 +309,11 @@ class PackedIntValues {
     }
 
     @Override
-    public int advance(int target) throws IOException {
+    public int seek(int target) throws IOException {
       if (target >= maxDoc) {
         return pos = NO_MORE_DOCS;
       }
-      final long val = ints.advance(target);
+      final long val = ints.seek(target);
       intsRef.ints[intsRef.offset] = val == defaultValue ? 0 : minValue + val;
       return pos = target;
     }
@@ -328,7 +328,7 @@ class PackedIntValues {
       if (pos >= maxDoc) {
         return pos = NO_MORE_DOCS;
       }
-      return advance(pos + 1);
+      return seek(pos + 1);
     }
   }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/ValuesEnum.java b/lucene/src/java/org/apache/lucene/index/values/ValuesEnum.java
index 3c48476..48b3c41 100644
--- a/lucene/src/java/org/apache/lucene/index/values/ValuesEnum.java
+++ b/lucene/src/java/org/apache/lucene/index/values/ValuesEnum.java
@@ -41,7 +41,8 @@ import org.apache.lucene.util.LongsRef;
  * 
  * @lucene.experimental
  */
-public abstract class ValuesEnum extends DocIdSetIterator {
+public abstract class ValuesEnum extends DocIdSetIterator{
+  
   private AttributeSource source;
   private final ValueType enumType;
   protected BytesRef bytesRef = new BytesRef(1);
@@ -63,6 +64,22 @@ public abstract class ValuesEnum extends DocIdSetIterator {
     this.source = source;
     this.enumType = enumType;
   }
+  
+  @Override
+  public int advance(int target) throws IOException {
+    return seek(target);
+  }
+  
+  /**
+   * Seeks to the first document id greater or equal to the <i>target</i>.
+   * 
+   * @param target
+   *          the doc id to seek to
+   * @return the current document number or {@link #NO_MORE_DOCS} if there is no
+   *         document id greater or equal to the given <i>target</i>
+   * @throws IOException
+   */
+  public abstract int seek(int target) throws IOException;
 
   /**
    * Returns the type of this enum
@@ -142,7 +159,7 @@ public abstract class ValuesEnum extends DocIdSetIterator {
       }
 
       @Override
-      public int advance(int target) throws IOException {
+      public int seek(int target) throws IOException {
         return NO_MORE_DOCS;
       }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/VarSortedBytesImpl.java b/lucene/src/java/org/apache/lucene/index/values/VarSortedBytesImpl.java
index 36caf0b..0fe4cfd 100644
--- a/lucene/src/java/org/apache/lucene/index/values/VarSortedBytesImpl.java
+++ b/lucene/src/java/org/apache/lucene/index/values/VarSortedBytesImpl.java
@@ -198,7 +198,7 @@ class VarSortedBytesImpl {
       }
 
       @Override
-      public int advance(int target) throws IOException {
+      public int seek(int target) throws IOException {
         if (target >= docCount) {
           return pos = NO_MORE_DOCS;
         }
@@ -235,7 +235,7 @@ class VarSortedBytesImpl {
         if (pos >= docCount) {
           return pos = NO_MORE_DOCS;
         }
-        return advance(pos + 1);
+        return seek(pos + 1);
       }
     }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/VarStraightBytesImpl.java b/lucene/src/java/org/apache/lucene/index/values/VarStraightBytesImpl.java
index 0d1282a..56aae7a 100644
--- a/lucene/src/java/org/apache/lucene/index/values/VarStraightBytesImpl.java
+++ b/lucene/src/java/org/apache/lucene/index/values/VarStraightBytesImpl.java
@@ -251,7 +251,7 @@ class VarStraightBytesImpl {
       public ValuesEnum getEnum(AttributeSource attrSource) throws IOException {
         return new SourceEnum(attrSource, type(), this, maxDoc()) {
           @Override
-          public int advance(int target) throws IOException {
+          public int seek(int target) throws IOException {
             if (target >= numDocs) {
               return pos = NO_MORE_DOCS;
             }
@@ -268,7 +268,7 @@ class VarStraightBytesImpl {
     }
 
     private class VarStraightBytesEnum extends ValuesEnum {
-      private final PackedInts.ReaderIterator addresses;
+      private final PackedInts.SeekableReaderIterator addresses;
       private final IndexInput datIn;
       private final IndexInput idxIn;
       private final long fp;
@@ -281,7 +281,7 @@ class VarStraightBytesImpl {
         super(source, ValueType.BYTES_VAR_STRAIGHT);
         totBytes = idxIn.readVLong();
         fp = datIn.getFilePointer();
-        addresses = PackedInts.getReaderIterator(idxIn);
+        addresses = PackedInts.getSeekableReaderIterator(idxIn);
         this.datIn = datIn;
         this.idxIn = idxIn;
         nextAddress = addresses.next();
@@ -294,11 +294,11 @@ class VarStraightBytesImpl {
       }
 
       @Override
-      public int advance(final int target) throws IOException {
+      public int seek(final int target) throws IOException {
         if (target >= maxDoc) {
           return pos = NO_MORE_DOCS;
         }
-        final long addr = pos+1 == target ? nextAddress : addresses.advance(target);
+        final long addr = pos+1 == target ? nextAddress : addresses.seek(target);
         if (addr == totBytes) { // empty values at the end
           bytesRef.length = 0;
           bytesRef.offset = 0;
@@ -322,7 +322,7 @@ class VarStraightBytesImpl {
 
       @Override
       public int nextDoc() throws IOException {
-        return advance(pos + 1);
+        return seek(pos + 1);
       }
     }
 
diff --git a/lucene/src/java/org/apache/lucene/index/values/Writer.java b/lucene/src/java/org/apache/lucene/index/values/Writer.java
index db22b12..116c0d6 100644
--- a/lucene/src/java/org/apache/lucene/index/values/Writer.java
+++ b/lucene/src/java/org/apache/lucene/index/values/Writer.java
@@ -151,11 +151,11 @@ public abstract class Writer extends DocValuesConsumer {
       final Bits liveDocs = state.liveDocs;
       final int docCount = state.docCount;
       int currentDocId;
-      if ((currentDocId = valEnum.advance(0)) != ValuesEnum.NO_MORE_DOCS) {
+      if ((currentDocId = valEnum.seek(0)) != ValuesEnum.NO_MORE_DOCS) {
         for (int i = 0; i < docCount; i++) {
           if (liveDocs == null || liveDocs.get(i)) {
             if (currentDocId < i) {
-              if ((currentDocId = valEnum.advance(i)) == ValuesEnum.NO_MORE_DOCS) {
+              if ((currentDocId = valEnum.seek(i)) == ValuesEnum.NO_MORE_DOCS) {
                 break; // advance can jump over default values
               }
             }
diff --git a/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java b/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java
index 589c8bc..35849c5 100644
--- a/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java
+++ b/lucene/src/java/org/apache/lucene/util/packed/PackedInts.java
@@ -83,6 +83,17 @@ public class PackedInts {
      * @return the value at the given position
      * @throws IOException if reading the value throws an IOException*/
     long advance(int ord) throws IOException;
+   
+  }
+  
+  /**
+   * Seekable enum interface, to decode previously saved PackedInts.
+   */
+  public static interface SeekableReaderIterator extends ReaderIterator {
+    /** Seeks to the given ordinal and returns its value.
+     * @return the value at the given position
+     * @throws IOException if reading the value throws an IOException*/
+    long seek(int ord) throws IOException;
   }
   
   /**
@@ -195,6 +206,17 @@ public class PackedInts {
    * @lucene.internal
    */
   public static ReaderIterator getReaderIterator(IndexInput in) throws IOException {
+    return getSeekableReaderIterator(in);
+  }
+  
+  /**
+   * Retrieve PackedInts as a {@link SeekableReaderIterator}
+   * @param in positioned at the beginning of a stored packed int structure.
+   * @return an iterator to access the values
+   * @throws IOException if the structure could not be retrieved.
+   * @lucene.internal
+   */
+  public static SeekableReaderIterator getSeekableReaderIterator(IndexInput in) throws IOException {
     CodecUtil.checkHeader(in, CODEC_NAME, VERSION_START, VERSION_START);
     final int bitsPerValue = in.readVInt();
     assert bitsPerValue > 0 && bitsPerValue <= 64: "bitsPerValue=" + bitsPerValue;
diff --git a/lucene/src/java/org/apache/lucene/util/packed/PackedReaderIterator.java b/lucene/src/java/org/apache/lucene/util/packed/PackedReaderIterator.java
index 90c67dc..5f5ba8a 100644
--- a/lucene/src/java/org/apache/lucene/util/packed/PackedReaderIterator.java
+++ b/lucene/src/java/org/apache/lucene/util/packed/PackedReaderIterator.java
@@ -21,13 +21,15 @@ import org.apache.lucene.store.IndexInput;
 
 import java.io.IOException;
 
-final class PackedReaderIterator implements PackedInts.ReaderIterator {
+final class PackedReaderIterator implements PackedInts.SeekableReaderIterator {
   private long pending;
   private int pendingBitsLeft;
   private final IndexInput in;
   private final int bitsPerValue;
   private final int valueCount;
   private int position = -1;
+  private long currentValue;
+  private final long startPointer;
 
   // masks[n-1] masks for bottom n bits
   private final long[] masks;
@@ -39,6 +41,7 @@ final class PackedReaderIterator implements PackedInts.ReaderIterator {
     this.bitsPerValue = bitsPerValue;
     
     this.in = in;
+    startPointer = in.getFilePointer();
     masks = new long[bitsPerValue];
 
     long v = 1;
@@ -76,7 +79,7 @@ final class PackedReaderIterator implements PackedInts.ReaderIterator {
     }
     
     ++position;
-    return result;
+    return currentValue = result;
   }
 
   public void close() throws IOException {
@@ -106,6 +109,24 @@ final class PackedReaderIterator implements PackedInts.ReaderIterator {
       pendingBitsLeft = 64 - (int)(skip % 64);
     }
     position = ord-1;
-    return next();
+    return currentValue = next();
+  }
+  
+  public long seek(final int ord) throws IOException {
+    assert ord < valueCount : "ord must be less than valueCount";
+    if (ord < position) {
+      pendingBitsLeft = 0;
+      final long bitsToSkip = (((long) bitsPerValue) * (long) ord);
+      final long skip = bitsToSkip - pendingBitsLeft;
+      final long closestByte = (skip >> 6) << 3;
+      in.seek(startPointer + closestByte);
+      pending = in.readLong();
+      pendingBitsLeft = 64 - (int) (skip % 64);
+      position = ord - 1;
+      return currentValue = next();
+    } else if (ord == position) {
+      return currentValue;
+    }
+    return advance(ord);
   }
 }
diff --git a/lucene/src/test/org/apache/lucene/index/values/TestDocValues.java b/lucene/src/test/org/apache/lucene/index/values/TestDocValues.java
index 35c1586..45e778a 100644
--- a/lucene/src/test/org/apache/lucene/index/values/TestDocValues.java
+++ b/lucene/src/test/org/apache/lucene/index/values/TestDocValues.java
@@ -87,15 +87,17 @@ public class TestDocValues extends LuceneTestCase {
       assertNotNull("enum is null", bytesEnum);
       BytesRef ref = bytesEnum.bytes();
 
-      for (int i = 0; i < 2; i++) {
+      for (int i = 0; i < 100; i++) {
         final int idx = 2 * i;
-        assertEquals("doc: " + idx, idx, bytesEnum.advance(idx));
+        maybeRandomSeek(bytesEnum, maxDoc);
+        assertEquals("doc: " + idx, idx, bytesEnum.seek(idx));
         String utf8String = ref.utf8ToString();
         assertEquals("doc: " + idx + " lenLeft: " + values[idx].length()
             + " lenRight: " + utf8String.length(), values[idx], utf8String);
       }
-      assertEquals(ValuesEnum.NO_MORE_DOCS, bytesEnum.advance(maxDoc));
-      assertEquals(ValuesEnum.NO_MORE_DOCS, bytesEnum.advance(maxDoc + 1));
+      maybeRandomSeek(bytesEnum, maxDoc);
+      assertEquals(ValuesEnum.NO_MORE_DOCS, bytesEnum.seek(maxDoc));
+      assertEquals(ValuesEnum.NO_MORE_DOCS, bytesEnum.seek(maxDoc + 1));
 
       bytesEnum.close();
     }
@@ -394,14 +396,16 @@ public class TestDocValues extends LuceneTestCase {
         assertEquals(type, iEnum.type());
         LongsRef ints = iEnum.getInt();
         for (int i = 0; i < NUM_VALUES + additionalDocs; i += 1 + random.nextInt(25)) {
-          assertEquals(i, iEnum.advance(i));
+          maybeRandomSeek(iEnum, NUM_VALUES);
+          assertEquals(i, iEnum.seek(i));
           if (i < NUM_VALUES) {
             assertEquals(values[i], ints.get());
           } else {
             assertEquals(0, ints.get());
           }
         }
-        assertEquals(ValuesEnum.NO_MORE_DOCS, iEnum.advance(NUM_VALUES + additionalDocs));
+        maybeRandomSeek(iEnum, NUM_VALUES);
+        assertEquals(ValuesEnum.NO_MORE_DOCS, iEnum.seek(NUM_VALUES + additionalDocs));
         iEnum.close();
       }
       r.close();
@@ -455,14 +459,16 @@ public class TestDocValues extends LuceneTestCase {
       ValuesEnum fEnum = getEnum(r);
       FloatsRef floats = fEnum.getFloat();
       for (int i = 0; i < NUM_VALUES + additionalValues; i += 1 + random.nextInt(25)) {
-        assertEquals(i, fEnum.advance(i));
+        maybeRandomSeek(fEnum, NUM_VALUES);
+        assertEquals(i, fEnum.seek(i));
         if (i < NUM_VALUES) {
           assertEquals(values[i], floats.get(), delta);
         } else {
           assertEquals(0.0d, floats.get(), delta);
         }
       }
-      assertEquals(ValuesEnum.NO_MORE_DOCS, fEnum.advance(NUM_VALUES + additionalValues));
+      maybeRandomSeek(fEnum, NUM_VALUES);
+      assertEquals(ValuesEnum.NO_MORE_DOCS, fEnum.seek(NUM_VALUES + additionalValues));
       fEnum.close();
     }
 
@@ -489,4 +495,10 @@ public class TestDocValues extends LuceneTestCase {
     return random.nextBoolean() ? values.loadSorted(comparator) : values
         .getSortedSorted(comparator);
   }
+  
+  public static void maybeRandomSeek(ValuesEnum valuesEnum, int maxOrd) throws IOException {
+    if(random.nextInt(5) == 0) {
+      valuesEnum.seek(random.nextInt(maxOrd));
+    }
+  }
 }
diff --git a/lucene/src/test/org/apache/lucene/index/values/TestDocValuesIndexing.java b/lucene/src/test/org/apache/lucene/index/values/TestDocValuesIndexing.java
index bff0c88..88f4b06 100644
--- a/lucene/src/test/org/apache/lucene/index/values/TestDocValuesIndexing.java
+++ b/lucene/src/test/org/apache/lucene/index/values/TestDocValuesIndexing.java
@@ -186,7 +186,8 @@ public class TestDocValuesIndexing extends LuceneTestCase {
     case FIXED_INTS_32:
     case FIXED_INTS_64:
     case FIXED_INTS_8:
-      assertEquals(msg, valuesPerIndex-1, vE_2_merged.advance(valuesPerIndex-1));
+      maybeRandomSeek(vE_2_merged, merged.maxDoc());
+      assertEquals(msg, valuesPerIndex-1, vE_2_merged.seek(valuesPerIndex-1));
     }
     
     for (int i = 0; i < valuesPerIndex; i++) {
@@ -196,9 +197,10 @@ public class TestDocValuesIndexing extends LuceneTestCase {
       assertEquals(msg, i, vE_2.nextDoc());
       assertEquals(msg, i + valuesPerIndex, vE_2_merged.nextDoc());
     }
+    maybeRandomSeek(vE_1_merged, merged.maxDoc());
     assertEquals(msg, ValuesEnum.NO_MORE_DOCS, vE_1.nextDoc());
     assertEquals(msg, ValuesEnum.NO_MORE_DOCS, vE_2.nextDoc());
-    assertEquals(msg, ValuesEnum.NO_MORE_DOCS, vE_1_merged.advance(valuesPerIndex*2));
+    assertEquals(msg, ValuesEnum.NO_MORE_DOCS, vE_1_merged.seek(valuesPerIndex*2));
     assertEquals(msg, ValuesEnum.NO_MORE_DOCS, vE_2_merged.nextDoc());
 
     // close resources
@@ -261,7 +263,7 @@ public class TestDocValuesIndexing extends LuceneTestCase {
         }
 
         ValuesEnum intsEnum = getValuesEnum(intsReader);
-        assertTrue(intsEnum.advance(base) >= base);
+        assertTrue(intsEnum.seek(base) >= base);
 
         intsEnum = getValuesEnum(intsReader);
         LongsRef enumRef = intsEnum.getInt();
@@ -272,7 +274,7 @@ public class TestDocValuesIndexing extends LuceneTestCase {
             expected++;
           }
           assertEquals("advance failed at index: " + i + " of " + r.numDocs()
-              + " docs", i, intsEnum.advance(i));
+              + " docs", i, intsEnum.seek(i));
           assertEquals(val + " mod: " + mod + " index: " +  i, expected%mod, ints.getInt(i));
           assertEquals(expected%mod, enumRef.get());
 
@@ -290,7 +292,7 @@ public class TestDocValuesIndexing extends LuceneTestCase {
               0.0d, value, 0.0d);
         }
         ValuesEnum floatEnum = getValuesEnum(floatReader);
-        assertTrue(floatEnum.advance(base) >= base);
+        assertTrue(floatEnum.seek(base) >= base);
 
         floatEnum = getValuesEnum(floatReader);
         FloatsRef enumRef = floatEnum.getFloat();
@@ -299,8 +301,9 @@ public class TestDocValuesIndexing extends LuceneTestCase {
           while (deleted.get(expected)) {
             expected++;
           }
+          maybeRandomSeek(floatEnum, r.maxDoc());// do a random seek to test repositioning
           assertEquals("advance failed at index: " + i + " of " + r.numDocs()
-              + " docs base:" + base, i, floatEnum.advance(i));
+              + " docs base:" + base, i, floatEnum.seek(i));
           assertEquals(floatEnum.getClass() + " index " + i, 2.0 * expected,
               enumRef.get(), 0.00001);
           assertEquals("index " + i, 2.0 * expected, floats.getFloat(i),
@@ -320,7 +323,13 @@ public class TestDocValuesIndexing extends LuceneTestCase {
     w.close();
     d.close();
   }
-
+  
+  public static void maybeRandomSeek(ValuesEnum valuesEnum, int maxOrd) throws IOException {
+    if(random.nextInt(5) == 0) {
+      valuesEnum.seek(random.nextInt(maxOrd));
+    }
+  }
+  
   public void runTestIndexBytes(IndexWriterConfig cfg, boolean withDeletions)
       throws CorruptIndexException, LockObtainFailedException, IOException {
     final Directory d = newDirectory();
@@ -374,7 +383,8 @@ public class TestDocValuesIndexing extends LuceneTestCase {
           assertEquals(0, br.length);
           // make sure we advance at least until base
           ValuesEnum bytesEnum = getValuesEnum(bytesReader);
-          final int advancedTo = bytesEnum.advance(0);
+          maybeRandomSeek(bytesEnum, r.maxDoc());
+          final int advancedTo = bytesEnum.seek(0);
           assertTrue(byteIndexValue.name() + " advanced failed base:" + base
               + " advancedTo: " + advancedTo, base <= advancedTo);
         }
@@ -393,9 +403,10 @@ public class TestDocValuesIndexing extends LuceneTestCase {
           upto += bytesSize;
         }
         BytesRef br = bytes.getBytes(i, new BytesRef());
+        maybeRandomSeek(bytesEnum, r.maxDoc());
         if (bytesEnum.docID() != i) {
           assertEquals("seek failed for index " + i + " " + msg, i, bytesEnum
-              .advance(i));
+              .seek(i));
         }
         assertTrue(msg, br.length > 0);
         for (int j = 0; j < br.length; j++, upto++) {
diff --git a/lucene/src/test/org/apache/lucene/util/packed/TestPackedInts.java b/lucene/src/test/org/apache/lucene/util/packed/TestPackedInts.java
index 107bf02..4933e73 100644
--- a/lucene/src/test/org/apache/lucene/util/packed/TestPackedInts.java
+++ b/lucene/src/test/org/apache/lucene/util/packed/TestPackedInts.java
@@ -115,12 +115,38 @@ public class TestPackedInts extends LuceneTestCase {
           assertEquals(fp, in.getFilePointer());
           in.close();
         }
+        
+        { // test reader iterator seek
+          IndexInput in = d.openInput("out.bin", newIOContext(random));
+          PackedInts.SeekableReaderIterator intsEnum = PackedInts.getSeekableReaderIterator(in);
+          for (int i = 0; i < valueCount; i++) {
+            final String msg = "index=" + i + " ceil=" + ceil + " valueCount="
+                + valueCount + " nbits=" + nbits + " for "
+                + intsEnum.getClass().getSimpleName();
+            final int ord = random.nextInt(valueCount);
+            long seek = intsEnum.seek(ord);
+            assertEquals(msg, seek, values[ord]);
+            if (random.nextBoolean() && ord < valueCount-1) {
+              if (random.nextBoolean()) {
+                assertEquals(msg, values[ord+1], intsEnum.advance(ord+1));
+              } else {
+                assertEquals(msg, values[ord+1], intsEnum.next());
+              }
+            }
+          }
+          if (intsEnum.ord() < valueCount - 1)
+            assertEquals(values[valueCount - 1], intsEnum
+                .advance(valueCount - 1));
+          assertEquals(valueCount - 1, intsEnum.ord());
+          assertEquals(fp, in.getFilePointer());
+          in.close();
+        }
         ceil *= 2;
         d.close();
       }
     }
   }
-
+  
   public void testControlledEquality() {
     final int VALUE_COUNT = 255;
     final int BITS_PER_VALUE = 8;
