Index: lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
===================================================================
--- lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java	(revision 1535033)
+++ lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java	(working copy)
@@ -233,12 +233,7 @@
       case DELTA_COMPRESSED:
         final int blockSize = data.readVInt();
         final BlockPackedReader reader = new BlockPackedReader(data, entry.packedIntsVersion, blockSize, maxDoc, false);
-        return new NumericDocValues() {
-          @Override
-          public long get(int docID) {
-            return reader.get(docID);
-          }
-        };
+        return reader;
       case UNCOMPRESSED:
         final byte bytes[] = new byte[maxDoc];
         data.readBytes(bytes, 0, bytes.length);
Index: lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java	(working copy)
@@ -48,6 +48,7 @@
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.LongValues;
 import org.apache.lucene.util.packed.BlockPackedReader;
 import org.apache.lucene.util.packed.MonotonicBlockPackedReader;
 import org.apache.lucene.util.packed.PackedInts;
@@ -254,24 +255,19 @@
     return sizeInBytes;
   }
   
-  LongNumericDocValues getNumeric(NumericEntry entry) throws IOException {
+  LongValues getNumeric(NumericEntry entry) throws IOException {
     final IndexInput data = this.data.clone();
     data.seek(entry.offset);
 
     switch (entry.format) {
       case DELTA_COMPRESSED:
         final BlockPackedReader reader = new BlockPackedReader(data, entry.packedIntsVersion, entry.blockSize, entry.count, true);
-        return new LongNumericDocValues() {
-          @Override
-          public long get(long id) {
-            return reader.get(id);
-          }
-        };
+        return reader;
       case GCD_COMPRESSED:
         final long min = entry.minValue;
         final long mult = entry.gcd;
         final BlockPackedReader quotientReader = new BlockPackedReader(data, entry.packedIntsVersion, entry.blockSize, entry.count, true);
-        return new LongNumericDocValues() {
+        return new LongValues() {
           @Override
           public long get(long id) {
             return min + mult * quotientReader.get(id);
@@ -281,7 +277,7 @@
         final long table[] = entry.table;
         final int bitsRequired = PackedInts.bitsRequired(table.length - 1);
         final PackedInts.Reader ords = PackedInts.getDirectReaderNoHeader(data, PackedInts.Format.PACKED, entry.packedIntsVersion, (int) entry.count, bitsRequired);
-        return new LongNumericDocValues() {
+        return new LongValues() {
           @Override
           public long get(long id) {
             return table[(int) ords.get((int) id)];
@@ -473,7 +469,7 @@
     final long valueCount = binaries.get(field.number).count;
     // we keep the byte[]s and list of ords on disk, these could be large
     final LongBinaryDocValues binary = (LongBinaryDocValues) getBinary(field);
-    final LongNumericDocValues ordinals = getNumeric(ords.get(field.number));
+    final LongValues ordinals = getNumeric(ords.get(field.number));
     // but the addresses to the ord stream are in RAM
     final MonotonicBlockPackedReader ordIndex = getOrdIndexInstance(data, field, ordIndexes.get(field.number));
     
@@ -621,15 +617,6 @@
   }
   
   // internally we compose complex dv (sorted/sortedset) from other ones
-  static abstract class LongNumericDocValues extends NumericDocValues {
-    @Override
-    public final long get(int docID) {
-      return get((long) docID);
-    }
-    
-    abstract long get(long id);
-  }
-  
   static abstract class LongBinaryDocValues extends BinaryDocValues {
     @Override
     public final void get(int docID, BytesRef result) {
Index: lucene/core/src/java/org/apache/lucene/util/LongValues.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/LongValues.java	(revision 0)
+++ lucene/core/src/java/org/apache/lucene/util/LongValues.java	(working copy)
@@ -0,0 +1,38 @@
+package org.apache.lucene.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.index.NumericDocValues;
+import org.apache.lucene.util.packed.PackedInts;
+
+/** Abstraction over an array of longs.
+ *  This class extends NumericDocValues so that we don't need to add another
+ *  level of abstraction every time we want eg. to use the {@link PackedInts}
+ *  utility classes to represent a {@link NumericDocValues} instance.
+ *  @lucene.internal */
+public abstract class LongValues extends NumericDocValues {
+
+  /** Get value at <code>index</code>. */
+  public abstract long get(long index);
+
+  @Override
+  public long get(int idx) {
+    return get((long) idx);
+  }
+
+}

Property changes on: lucene/core/src/java/org/apache/lucene/util/LongValues.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/core/src/java/org/apache/lucene/util/packed/AbstractAppendingLongBuffer.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/AbstractAppendingLongBuffer.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/AbstractAppendingLongBuffer.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.LongValues;
 import org.apache.lucene.util.RamUsageEstimator;
 
 import java.util.Arrays;
@@ -25,7 +26,7 @@
 import static org.apache.lucene.util.packed.PackedInts.checkBlockSize;
 
 /** Common functionality shared by {@link AppendingDeltaPackedLongBuffer} and {@link MonotonicAppendingLongBuffer}. */
-abstract class AbstractAppendingLongBuffer {
+abstract class AbstractAppendingLongBuffer extends LongValues {
 
   static final int MIN_PAGE_SIZE = 64;
   // More than 1M doesn't really makes sense with these appending buffers
@@ -92,7 +93,7 @@
 
   abstract void packPendingValues();
 
-  /** Get a value from this buffer. */
+  @Override
   public final long get(long index) {
     assert index >= 0 && index < size();
     final int block = (int) (index >> pageShift);
Index: lucene/core/src/java/org/apache/lucene/util/packed/AbstractPagedMutable.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/AbstractPagedMutable.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/AbstractPagedMutable.java	(working copy)
@@ -21,13 +21,14 @@
 import static org.apache.lucene.util.packed.PackedInts.numBlocks;
 
 import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.LongValues;
 import org.apache.lucene.util.RamUsageEstimator;
 
 /**
  * Base implementation for {@link PagedMutable} and {@link PagedGrowableWriter}.
  * @lucene.internal
  */
-abstract class AbstractPagedMutable<T extends AbstractPagedMutable<T>> {
+abstract class AbstractPagedMutable<T extends AbstractPagedMutable<T>> extends LongValues {
 
   static final int MIN_BLOCK_SIZE = 1 << 6;
   static final int MAX_BLOCK_SIZE = 1 << 30;
@@ -80,7 +81,7 @@
     return (int) index & pageMask;
   }
 
-  /** Get value at <code>index</code>. */
+  @Override
   public final long get(long index) {
     assert index >= 0 && index < size;
     final int pageIndex = pageIndex(index);
Index: lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReader.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReader.java	(working copy)
@@ -29,12 +29,13 @@
 import java.io.IOException;
 
 import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.LongValues;
 
 /**
  * Provides random access to a stream written with {@link BlockPackedWriter}.
  * @lucene.internal
  */
-public final class BlockPackedReader {
+public final class BlockPackedReader extends LongValues {
 
   private final int blockShift, blockMask;
   private final long valueCount;
@@ -77,7 +78,7 @@
     this.minValues = minValues;
   }
 
-  /** Get value at <code>index</code>. */
+  @Override
   public long get(long index) {
     assert index >= 0 && index < valueCount;
     final int block = (int) (index >>> blockShift);
Index: lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReaderIterator.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReaderIterator.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/BlockPackedReaderIterator.java	(working copy)
@@ -21,8 +21,6 @@
 import static org.apache.lucene.util.packed.AbstractBlockPackedWriter.MAX_BLOCK_SIZE;
 import static org.apache.lucene.util.packed.AbstractBlockPackedWriter.MIN_BLOCK_SIZE;
 import static org.apache.lucene.util.packed.AbstractBlockPackedWriter.MIN_VALUE_EQUALS_0;
-import static org.apache.lucene.util.packed.BlockPackedReaderIterator.readVLong;
-import static org.apache.lucene.util.packed.BlockPackedReaderIterator.zigZagDecode;
 import static org.apache.lucene.util.packed.PackedInts.checkBlockSize;
 
 import java.io.EOFException;
Index: lucene/core/src/java/org/apache/lucene/util/packed/MonotonicBlockPackedReader.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/MonotonicBlockPackedReader.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/MonotonicBlockPackedReader.java	(working copy)
@@ -26,6 +26,7 @@
 import java.io.IOException;
 
 import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.LongValues;
 import org.apache.lucene.util.RamUsageEstimator;
 
 /**
@@ -33,7 +34,7 @@
  * {@link MonotonicBlockPackedWriter}.
  * @lucene.internal
  */
-public final class MonotonicBlockPackedReader {
+public final class MonotonicBlockPackedReader extends LongValues {
 
   private final int blockShift, blockMask;
   private final long valueCount;
@@ -72,14 +73,14 @@
     }
   }
 
-  /** Get value at <code>index</code>. */
+  @Override
   public long get(long index) {
     assert index >= 0 && index < valueCount;
     final int block = (int) (index >>> blockShift);
     final int idx = (int) (index & blockMask);
     return minValues[block] + (long) (idx * averages[block]) + zigZagDecode(subReaders[block].get(idx));
   }
-  
+
   /** Returns the number of values */
   public long size() {
     return valueCount;
Index: lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java
===================================================================
--- lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java	(revision 1535033)
+++ lucene/core/src/java/org/apache/lucene/util/packed/PackedInts.java	(working copy)
@@ -24,6 +24,7 @@
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.DataOutput;
 import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.util.LongValues;
 import org.apache.lucene.util.LongsRef;
 import org.apache.lucene.util.RamUsageEstimator;
 
@@ -599,7 +600,7 @@
    * A simple base for Readers that keeps track of valueCount and bitsPerValue.
    * @lucene.internal
    */
-  static abstract class ReaderImpl implements Reader {
+  static abstract class ReaderImpl extends LongValues implements Reader {
     protected final int bitsPerValue;
     protected final int valueCount;
 
@@ -610,6 +611,17 @@
     }
 
     @Override
+    public final long get(long index) {
+      if (index < 0 || index > Integer.MAX_VALUE) {
+        throw new IllegalArgumentException("PackedInts.Reader only support positive integer addressing, got index=" + index);
+      }
+      return get((int) index);
+    }
+
+    @Override
+    public abstract long get(int index);
+
+    @Override
     public int getBitsPerValue() {
       return bitsPerValue;
     }
