Index: lucene/src/java/org/apache/lucene/document2/BinaryField.java
===================================================================
--- lucene/src/java/org/apache/lucene/document2/BinaryField.java	(revision 1146162)
+++ lucene/src/java/org/apache/lucene/document2/BinaryField.java	(working copy)
@@ -29,6 +29,11 @@
     super(name, BinaryField.TYPE_STORED, value);
     this.isBinary = true;
   }
+
+  public BinaryField(String name, FieldType custom, byte[] value) {
+    super(name, custom, value);
+    this.isBinary = true;
+  }
   
   public BinaryField(String name, byte[] value, int offset, int length) {
     super(name, BinaryField.TYPE_STORED, value, offset, length);
Index: lucene/src/java/org/apache/lucene/index/FieldsReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/FieldsReader.java	(revision 1146162)
+++ lucene/src/java/org/apache/lucene/index/FieldsReader.java	(working copy)
@@ -27,6 +27,8 @@
 import org.apache.lucene.document.FieldSelector;
 import org.apache.lucene.document.FieldSelectorResult;
 import org.apache.lucene.document.NumericField;
+import org.apache.lucene.document2.BinaryField;
+import org.apache.lucene.document2.FieldType;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.BufferedIndexInput;
 import org.apache.lucene.store.Directory;
@@ -251,7 +253,53 @@
 
     return doc;
   }
+  
+  public final org.apache.lucene.document2.Document doc2(int n, FieldSelector fieldSelector) throws IOException {
+    seekIndex(n);
+    long position = indexStream.readLong();
+    fieldsStream.seek(position);
+    
+    org.apache.lucene.document2.Document doc = new org.apache.lucene.document2.Document();
+    int numFields = fieldsStream.readVInt();
+    out: for (int i = 0; i < numFields; i++) {
+      int fieldNumber = fieldsStream.readVInt();
+      FieldInfo fi = fieldInfos.fieldInfo(fieldNumber);
+      FieldSelectorResult acceptField = fieldSelector == null ? FieldSelectorResult.LOAD : fieldSelector.accept(fi.name);
+      
+      int bits = fieldsStream.readByte() & 0xFF;
+      assert bits <= (FieldsWriter.FIELD_IS_NUMERIC_MASK | FieldsWriter.FIELD_IS_TOKENIZED | FieldsWriter.FIELD_IS_BINARY): "bits=" + Integer.toHexString(bits);
 
+      boolean tokenize = (bits & FieldsWriter.FIELD_IS_TOKENIZED) != 0;
+      boolean binary = (bits & FieldsWriter.FIELD_IS_BINARY) != 0;
+      final int numeric = bits & FieldsWriter.FIELD_IS_NUMERIC_MASK;
+
+      switch (acceptField) {
+        case LOAD:
+          addField(doc, fi, binary, tokenize, numeric);
+          break;
+        case LOAD_AND_BREAK:
+          addField(doc, fi, binary, tokenize, numeric);
+          break out; //Get out of this loop
+        case LAZY_LOAD:
+          addFieldLazy(doc, fi, binary, tokenize, true, numeric);
+          break;
+        case LATENT:
+          addFieldLazy(doc, fi, binary, tokenize, false, numeric);
+          break;
+        case SIZE:
+          skipFieldBytes(addFieldSize(doc, fi, binary, numeric));
+          break;
+        case SIZE_AND_BREAK:
+          addFieldSize(doc, fi, binary, numeric);
+          break out; //Get out of this loop
+        default:
+          skipField(numeric);
+      }
+    }
+
+    return doc;
+  }
+
   /** Returns the length in bytes of each raw document in a
    *  contiguous range of length numDocs starting with
    *  startDocID.  Returns the IndexInput (the fieldStream),
@@ -322,6 +370,21 @@
         throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric));
     }
   }
+  private org.apache.lucene.document2.NumericField loadNumericField2(FieldInfo fi, int numeric, FieldType ft) throws IOException {
+    assert numeric != 0;
+    switch(numeric) {
+      case FieldsWriter.FIELD_IS_NUMERIC_INT:
+        return new org.apache.lucene.document2.NumericField(fi.name, ft).setIntValue(fieldsStream.readInt());
+      case FieldsWriter.FIELD_IS_NUMERIC_LONG:
+        return new org.apache.lucene.document2.NumericField(fi.name, ft).setLongValue(fieldsStream.readLong());
+      case FieldsWriter.FIELD_IS_NUMERIC_FLOAT:
+        return new org.apache.lucene.document2.NumericField(fi.name, ft).setFloatValue(Float.intBitsToFloat(fieldsStream.readInt()));
+      case FieldsWriter.FIELD_IS_NUMERIC_DOUBLE:
+        return new org.apache.lucene.document2.NumericField(fi.name, ft).setDoubleValue(Double.longBitsToDouble(fieldsStream.readLong()));
+      default:
+        throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric));
+    }
+  }
 
   private void addFieldLazy(Document doc, FieldInfo fi, boolean binary, boolean tokenize, boolean cacheResult, int numeric) throws IOException {
     final AbstractField f;
@@ -349,7 +412,42 @@
     f.setOmitTermFreqAndPositions(fi.omitTermFreqAndPositions);
     doc.add(f);
   }
+  private void addFieldLazy(org.apache.lucene.document2.Document doc, FieldInfo fi, boolean binary, boolean tokenize, boolean cacheResult, int numeric) throws IOException {
+    final IndexableField f;
+    if (binary) {
+      int toRead = fieldsStream.readVInt();
+      long pointer = fieldsStream.getFilePointer();
+      FieldType ft = new FieldType();
+      ft.setLazy(true);
+      ft.setStored(true);
+      f = new LazyField2(fi.name, ft, toRead, pointer, binary, cacheResult);
+      //Need to move the pointer ahead by toRead positions
+      fieldsStream.seek(pointer + toRead);
+    } else if (numeric != 0) {
+      FieldType ft = new FieldType(org.apache.lucene.document2.NumericField.TYPE_STORED);
+      ft.setOmitNorms(fi.omitNorms);
+      ft.setOmitTermFreqAndPositions(fi.omitTermFreqAndPositions);
+      f = loadNumericField2(fi, numeric, ft);
+    } else {
+      FieldType ft = new FieldType();
+      ft.setLazy(true);
+      ft.setStored(true);
+      ft.setIndexed(fi.isIndexed);
+      ft.setTokenized(tokenize);
+      ft.setStoreTermVectors(fi.storeTermVector);
+      ft.setStoreTermVectorOffsets(fi.storeOffsetWithTermVector);
+      ft.setStoreTermVectorPositions(fi.storePositionWithTermVector);
 
+      int length = fieldsStream.readVInt();
+      long pointer = fieldsStream.getFilePointer();
+      //Skip ahead of where we are by the length of what is stored
+      fieldsStream.seek(pointer+length);
+      f = new LazyField2(fi.name, ft, length, pointer, binary, cacheResult);
+    }
+    
+    doc.add(f);
+  }
+
   private void addField(Document doc, FieldInfo fi, boolean binary, boolean tokenize, int numeric) throws CorruptIndexException, IOException {
     final AbstractField f;
 
@@ -376,6 +474,41 @@
     doc.add(f);
   }
   
+  private void addField(org.apache.lucene.document2.Document doc, FieldInfo fi, boolean binary, boolean tokenize, int numeric) throws CorruptIndexException, IOException {
+    final IndexableField f;
+
+    if (binary) {
+      int toRead = fieldsStream.readVInt();
+      final byte[] b = new byte[toRead];
+      fieldsStream.readBytes(b, 0, b.length);
+      FieldType customType = new FieldType(BinaryField.TYPE_STORED);
+      customType.setOmitNorms(fi.omitNorms);
+      customType.setOmitTermFreqAndPositions(fi.omitTermFreqAndPositions);
+      f = new org.apache.lucene.document2.BinaryField(fi.name, customType, b);
+    } else if (numeric != 0) {
+      FieldType customType = new FieldType(org.apache.lucene.document2.NumericField.TYPE_STORED);
+      customType.setOmitNorms(fi.omitNorms);
+      customType.setOmitTermFreqAndPositions(fi.omitTermFreqAndPositions);
+      f = loadNumericField2(fi, numeric, customType);
+    } else {
+      FieldType customType = new FieldType();
+      customType.setIndexed(fi.isIndexed);
+      customType.setTokenized(tokenize);
+      customType.setStoreTermVectors(fi.storeTermVector);
+      customType.setStoreTermVectorOffsets(fi.storeOffsetWithTermVector);
+      customType.setStoreTermVectorPositions(fi.storePositionWithTermVector);
+      customType.setOmitNorms(fi.omitNorms);
+      customType.setOmitTermFreqAndPositions(fi.omitTermFreqAndPositions);
+
+      f = new org.apache.lucene.document2.Field(fi.name,     // name
+        false,
+        customType,
+        fieldsStream.readString()); // read value
+    }
+    
+    doc.add(f);
+  }
+  
   // Add the size of field as a byte[] containing the 4 bytes of the integer byte size (high order byte first; char = 2 bytes)
   // Read just the size -- caller must skip the field content to continue reading fields
   // Return the size in bytes or chars, depending on field type
@@ -405,6 +538,33 @@
     doc.add(new Field(fi.name, sizebytes));
     return size;
   }
+  
+  private int addFieldSize(org.apache.lucene.document2.Document doc, FieldInfo fi, boolean binary, int numeric) throws IOException {
+    final int bytesize, size;
+    switch(numeric) {
+      case 0:
+        size = fieldsStream.readVInt();
+        bytesize = binary ? size : 2*size;
+        break;
+      case FieldsWriter.FIELD_IS_NUMERIC_INT:
+      case FieldsWriter.FIELD_IS_NUMERIC_FLOAT:
+        size = bytesize = 4;
+        break;
+      case FieldsWriter.FIELD_IS_NUMERIC_LONG:
+      case FieldsWriter.FIELD_IS_NUMERIC_DOUBLE:
+        size = bytesize = 8;
+        break;
+      default:
+        throw new FieldReaderException("Invalid numeric type: " + Integer.toHexString(numeric));
+    }
+    byte[] sizebytes = new byte[4];
+    sizebytes[0] = (byte) (bytesize>>>24);
+    sizebytes[1] = (byte) (bytesize>>>16);
+    sizebytes[2] = (byte) (bytesize>>> 8);
+    sizebytes[3] = (byte)  bytesize      ;
+    doc.add(new org.apache.lucene.document2.BinaryField(fi.name, sizebytes));
+    return size;
+  }
 
   /**
    * A Lazy field implementation that defers loading of fields until asked for, instead of when the Document is
@@ -545,4 +705,127 @@
       }
     }
   }
+  private class LazyField2 extends org.apache.lucene.document2.Field {
+    private int toRead;
+    private long pointer;
+    private final boolean cacheResult;
+
+    public LazyField2(String name, FieldType ft, int toRead, long pointer, boolean isBinary, boolean cacheResult) {
+      super(name, ft);
+      this.toRead = toRead;
+      this.pointer = pointer;
+      this.isBinary = isBinary;
+      this.cacheResult = cacheResult;
+      if (isBinary)
+        binaryLength = toRead;
+    }
+
+    public Number numericValue() {
+      return null;
+    }
+
+    public NumericField.DataType numericDataType() {
+      return null;
+    }
+
+    private IndexInput getFieldStream() {
+      IndexInput localFieldsStream = fieldsStreamTL.get();
+      if (localFieldsStream == null) {
+        localFieldsStream = (IndexInput) cloneableFieldsStream.clone();
+        fieldsStreamTL.set(localFieldsStream);
+      }
+      return localFieldsStream;
+    }
+
+    /** The value of the field as a Reader, or null.  If null, the String value,
+     * binary value, or TokenStream value is used.  Exactly one of stringValue(), 
+     * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */
+    public Reader readerValue() {
+      ensureOpen();
+      return null;
+    }
+
+    /** The value of the field as a TokenStream, or null.  If null, the Reader value,
+     * String value, or binary value is used. Exactly one of stringValue(), 
+     * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */
+    public TokenStream tokenStreamValue() {
+      ensureOpen();
+      return null;
+    }
+
+    /** The value of the field as a String, or null.  If null, the Reader value,
+     * binary value, or TokenStream value is used.  Exactly one of stringValue(), 
+     * readerValue(), getBinaryValue(), and tokenStreamValue() must be set. */
+    public String stringValue() {
+      ensureOpen();
+      if (isBinary)
+        return null;
+      else {
+        if (fieldsData == null) {
+          String result = null;
+          IndexInput localFieldsStream = getFieldStream();
+          try {
+            localFieldsStream.seek(pointer);
+            byte[] bytes = new byte[toRead];
+            localFieldsStream.readBytes(bytes, 0, toRead);
+            result = new String(bytes, "UTF-8");
+          } catch (IOException e) {
+            throw new FieldReaderException(e);
+          }
+          if (cacheResult == true){
+            fieldsData = result;
+          }
+          return result;
+        } else {
+          return (String) fieldsData;
+        }
+      }
+    }
+
+    private byte[] getBinaryValue(byte[] result) {
+      ensureOpen();
+
+      if (isBinary) {
+        if (fieldsData == null) {
+          // Allocate new buffer if result is null or too small
+          final byte[] b;
+          if (result == null || result.length < toRead)
+            b = new byte[toRead];
+          else
+            b = result;
+   
+          IndexInput localFieldsStream = getFieldStream();
+
+          // Throw this IOException since IndexReader.document does so anyway, so probably not that big of a change for people
+          // since they are already handling this exception when getting the document
+          try {
+            localFieldsStream.seek(pointer);
+            localFieldsStream.readBytes(b, 0, toRead);
+          } catch (IOException e) {
+            throw new FieldReaderException(e);
+          }
+
+          binaryOffset = 0;
+          binaryLength = toRead;
+          if (cacheResult == true){
+            fieldsData = b;
+          }
+          return b;
+        } else {
+          return (byte[]) fieldsData;
+        }
+      } else
+        return null;     
+    }
+
+    @Override
+    public BytesRef binaryValue(BytesRef reuse) {
+      final byte[] bytes = getBinaryValue(reuse != null ? reuse.bytes : null);
+      if (bytes != null) {
+        return new BytesRef(bytes, 0, bytes.length);
+      } else {
+        return null;
+      }
+    }
+  }
 }
Index: lucene/src/test/org/apache/lucene/index/TestFieldsReader.java
===================================================================
--- lucene/src/test/org/apache/lucene/index/TestFieldsReader.java	(revision 1146162)
+++ lucene/src/test/org/apache/lucene/index/TestFieldsReader.java	(working copy)
@@ -22,9 +22,8 @@
 import java.util.*;
 
 import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.document.NumericField;
+import org.apache.lucene.document2.Document;
+import org.apache.lucene.document2.Field;
 import org.apache.lucene.document.FieldSelector;
 import org.apache.lucene.document.FieldSelectorResult;
 import org.apache.lucene.document.Fieldable;
@@ -74,34 +73,34 @@
     assertTrue(fieldInfos != null);
     FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
     assertTrue(reader.size() == 1);
-    Document doc = reader.doc(0, null);
+    Document doc = reader.doc2(0, null);
     assertTrue(doc != null);
     assertTrue(doc.getField(DocHelper.TEXT_FIELD_1_KEY) != null);
 
-    Fieldable field = doc.getField(DocHelper.TEXT_FIELD_2_KEY);
+    IndexableField field = doc.getField(DocHelper.TEXT_FIELD_2_KEY);
     assertTrue(field != null);
-    assertTrue(field.isTermVectorStored() == true);
+    assertTrue(field.storeTermVectors() == true);
 
-    assertTrue(field.isStoreOffsetWithTermVector() == true);
-    assertTrue(field.isStorePositionWithTermVector() == true);
-    assertTrue(field.getOmitNorms() == false);
-    assertTrue(field.getOmitTermFreqAndPositions() == false);
+    assertTrue(field.storeTermVectorOffsets() == true);
+    assertTrue(field.storeTermVectorPositions() == true);
+    assertTrue(field.omitNorms() == false);
+    assertTrue(field.omitTermFreqAndPositions() == false);
 
     field = doc.getField(DocHelper.TEXT_FIELD_3_KEY);
     assertTrue(field != null);
-    assertTrue(field.isTermVectorStored() == false);
-    assertTrue(field.isStoreOffsetWithTermVector() == false);
-    assertTrue(field.isStorePositionWithTermVector() == false);
-    assertTrue(field.getOmitNorms() == true);
-    assertTrue(field.getOmitTermFreqAndPositions() == false);
+    assertTrue(field.storeTermVectors() == false);
+    assertTrue(field.storeTermVectorOffsets() == false);
+    assertTrue(field.storeTermVectorPositions() == false);
+    assertTrue(field.omitNorms() == true);
+    assertTrue(field.omitTermFreqAndPositions() == false);
 
     field = doc.getField(DocHelper.NO_TF_KEY);
     assertTrue(field != null);
-    assertTrue(field.isTermVectorStored() == false);
-    assertTrue(field.isStoreOffsetWithTermVector() == false);
-    assertTrue(field.isStorePositionWithTermVector() == false);
-    assertTrue(field.getOmitNorms() == false);
-    assertTrue(field.getOmitTermFreqAndPositions() == true);
+    assertTrue(field.storeTermVectors() == false);
+    assertTrue(field.storeTermVectorOffsets() == false);
+    assertTrue(field.storeTermVectorPositions() == false);
+    assertTrue(field.omitNorms() == false);
+    assertTrue(field.omitTermFreqAndPositions() == true);
     reader.close();
   }
 
@@ -121,30 +120,30 @@
     lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY);
     lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY);
     SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames);
-    Document doc = reader.doc(0, fieldSelector);
+    Document doc = reader.doc2(0, fieldSelector);
     assertTrue("doc is null and it shouldn't be", doc != null);
-    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
+    Field field = (Field) doc.getField(DocHelper.LAZY_FIELD_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("field is not lazy and it should be", field.isLazy());
+    assertTrue("field is not lazy and it should be", field.lazy());
     String value = field.stringValue();
     assertTrue("value is null and it shouldn't be", value != null);
     assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true);
     assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
 
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_1_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF1_KEY);
+    assertTrue("Field is lazy and it should not be", field.lazy() == false);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_UTF1_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
+    assertTrue("Field is lazy and it should not be", field.lazy() == false);
     assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true);
 
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF2_KEY);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_UTF2_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == true);
+    assertTrue("Field is lazy and it should not be", field.lazy() == true);
     assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true);
 
-    field = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY);
+    field = (Field) doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
     assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null);
 
@@ -187,34 +186,34 @@
         }
       };
 
-    Document doc = reader.doc(0, fieldSelector);
+    Document doc = reader.doc2(0, fieldSelector);
     assertTrue("doc is null and it shouldn't be", doc != null);
-    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
+    Field field = (Field) doc.getField(DocHelper.LAZY_FIELD_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("field is not lazy and it should be", field.isLazy());
+    assertTrue("field is not lazy and it should be", field.lazy());
     String value = field.stringValue();
     assertTrue("value is null and it shouldn't be", value != null);
     assertTrue(value + " is not equal to " + DocHelper.LAZY_FIELD_TEXT, value.equals(DocHelper.LAZY_FIELD_TEXT) == true);
     assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue());
 
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_1_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
+    assertTrue("Field is lazy and it should not be", field.lazy() == false);
     assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
 
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF1_KEY);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_UTF1_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == false);
+    assertTrue("Field is lazy and it should not be", field.lazy() == false);
     assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF1_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF1_TEXT) == true);
     assertTrue("calling stringValue() twice should give same reference", field.stringValue() == field.stringValue());
 
-    field = doc.getFieldable(DocHelper.TEXT_FIELD_UTF2_KEY);
+    field = (Field) doc.getField(DocHelper.TEXT_FIELD_UTF2_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("Field is lazy and it should not be", field.isLazy() == true);
+    assertTrue("Field is lazy and it should not be", field.lazy() == true);
     assertTrue(field.stringValue() + " is not equal to " + DocHelper.FIELD_UTF2_TEXT, field.stringValue().equals(DocHelper.FIELD_UTF2_TEXT) == true);
     assertTrue("calling stringValue() twice should give different references", field.stringValue() != field.stringValue());
 
-    field = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY);
+    field = (Field) doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
     assertTrue("stringValue isn't null for lazy binary field", field.stringValue() == null);
     assertTrue("calling binaryValue() twice should give different references", field.binaryValue(null).bytes != field.binaryValue(null).bytes);
@@ -246,11 +245,11 @@
     lazyFieldNames.add(DocHelper.LAZY_FIELD_BINARY_KEY);
     lazyFieldNames.add(DocHelper.TEXT_FIELD_UTF2_KEY);
     SetBasedFieldSelector fieldSelector = new SetBasedFieldSelector(loadFieldNames, lazyFieldNames);
-    Document doc = reader.doc(0, fieldSelector);
+    Document doc = reader.doc2(0, fieldSelector);
     assertTrue("doc is null and it shouldn't be", doc != null);
-    Fieldable field = doc.getFieldable(DocHelper.LAZY_FIELD_KEY);
+    Field field = (Field) doc.getField(DocHelper.LAZY_FIELD_KEY);
     assertTrue("field is null and it shouldn't be", field != null);
-    assertTrue("field is not lazy and it should be", field.isLazy());
+    assertTrue("field is not lazy and it should be", field.lazy());
     reader.close();
     try {
       field.stringValue();
@@ -266,12 +265,12 @@
     FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
     assertTrue(reader.size() == 1);
     LoadFirstFieldSelector fieldSelector = new LoadFirstFieldSelector();
-    Document doc = reader.doc(0, fieldSelector);
+    Document doc = reader.doc2(0, fieldSelector);
     assertTrue("doc is null and it shouldn't be", doc != null);
     int count = 0;
-    List<Fieldable> l = doc.getFields();
-    for (final Fieldable fieldable : l ) {
-      Field field = (Field) fieldable;
+    List<IndexableField> l = doc.getFields();
+    for (final IndexableField ifield : l ) {
+      Field field = (Field) ifield;
 
       assertTrue("field is null and it shouldn't be", field != null);
       String sv = field.stringValue();
@@ -315,11 +314,11 @@
       assertTrue(reader.size() == 1);
 
       Document doc;
-      doc = reader.doc(0, null);//Load all of them
+      doc = reader.doc2(0, null);//Load all of them
       assertTrue("doc is null and it shouldn't be", doc != null);
-      Fieldable field = doc.getFieldable(DocHelper.LARGE_LAZY_FIELD_KEY);
+      Field field = (Field) doc.getField(DocHelper.LARGE_LAZY_FIELD_KEY);
       assertTrue("field is null and it shouldn't be", field != null);
-      assertTrue("field is lazy", field.isLazy() == false);
+      assertTrue("field is lazy", field.lazy() == false);
       String value;
       long start;
       long finish;
@@ -335,9 +334,9 @@
       //Hmmm, are we still in cache???
       System.gc();
       reader = new FieldsReader(tmpDir, TEST_SEGMENT_NAME, fieldInfos);
-      doc = reader.doc(0, fieldSelector);
-      field = doc.getFieldable(DocHelper.LARGE_LAZY_FIELD_KEY);
-      assertTrue("field is not lazy", field.isLazy() == true);
+      doc = reader.doc2(0, fieldSelector);
+      field = (Field) doc.getField(DocHelper.LARGE_LAZY_FIELD_KEY);
+      assertTrue("field is not lazy", field.lazy() == true);
       start = System.currentTimeMillis();
       //On my machine this took around 50 - 70ms
       value = field.stringValue();
@@ -358,7 +357,7 @@
     FieldsReader reader = new FieldsReader(dir, TEST_SEGMENT_NAME, fieldInfos);
     Document doc;
     
-    doc = reader.doc(0, new FieldSelector(){
+    doc = reader.doc2(0, new FieldSelector(){
       public FieldSelectorResult accept(String fieldName) {
         if (fieldName.equals(DocHelper.TEXT_FIELD_1_KEY) ||
             fieldName.equals(DocHelper.LAZY_FIELD_BINARY_KEY))
@@ -369,12 +368,12 @@
           return FieldSelectorResult.NO_LOAD;
       }
     });
-    Fieldable f1 = doc.getFieldable(DocHelper.TEXT_FIELD_1_KEY);
-    Fieldable f3 = doc.getFieldable(DocHelper.TEXT_FIELD_3_KEY);
-    Fieldable fb = doc.getFieldable(DocHelper.LAZY_FIELD_BINARY_KEY);
-    assertTrue(f1.isBinary());
-    assertTrue(!f3.isBinary());
-    assertTrue(fb.isBinary());
+    IndexableField f1 = doc.getField(DocHelper.TEXT_FIELD_1_KEY);
+    IndexableField f3 = doc.getField(DocHelper.TEXT_FIELD_3_KEY);
+    IndexableField fb = doc.getField(DocHelper.LAZY_FIELD_BINARY_KEY);
+    assertTrue(f1.binaryValue(null) != null);
+    assertTrue(f3.binaryValue(null) == null);
+    assertTrue(fb.binaryValue(null) != null);
     assertSizeEquals(2*DocHelper.FIELD_1_TEXT.length(), f1.binaryValue(null).bytes);
     assertEquals(DocHelper.FIELD_3_TEXT, f3.stringValue());
     assertSizeEquals(DocHelper.LAZY_FIELD_BINARY_BYTES.length, fb.binaryValue(null).bytes);
@@ -518,25 +517,25 @@
     RandomIndexWriter w = new RandomIndexWriter(random, dir);
     final int numDocs = atLeast(500);
     final Number[] answers = new Number[numDocs];
-    final NumericField.DataType[] typeAnswers = new NumericField.DataType[numDocs];
+    final org.apache.lucene.document.NumericField.DataType[] typeAnswers = new org.apache.lucene.document.NumericField.DataType[numDocs];
     for(int id=0;id<numDocs;id++) {
-      Document doc = new Document();
-      NumericField nf = new NumericField("nf", Field.Store.YES, false);
+      org.apache.lucene.document2.Document doc = new org.apache.lucene.document2.Document();
+      org.apache.lucene.document2.NumericField nf = new org.apache.lucene.document2.NumericField("nf", org.apache.lucene.document2.NumericField.TYPE_STORED);
       doc.add(nf);
       final Number answer;
-      final NumericField.DataType typeAnswer;
+      final org.apache.lucene.document.NumericField.DataType typeAnswer;
       if (random.nextBoolean()) {
         // float/double
         if (random.nextBoolean()) {
           final float f = random.nextFloat();
           nf.setFloatValue(f);
           answer = Float.valueOf(f);
-          typeAnswer = NumericField.DataType.FLOAT;
+          typeAnswer = org.apache.lucene.document.NumericField.DataType.FLOAT;
         } else {
           final double d = random.nextDouble();
           nf.setDoubleValue(d);
           answer = Double.valueOf(d);
-          typeAnswer = NumericField.DataType.DOUBLE;
+          typeAnswer = org.apache.lucene.document.NumericField.DataType.DOUBLE;
         }
       } else {
         // int/long
@@ -544,18 +543,17 @@
           final int i = random.nextInt();
           nf.setIntValue(i);
           answer = Integer.valueOf(i);
-          typeAnswer = NumericField.DataType.INT;
+          typeAnswer = org.apache.lucene.document.NumericField.DataType.INT;
         } else {
           final long l = random.nextLong();
           nf.setLongValue(l);
           answer = Long.valueOf(l);
-          typeAnswer = NumericField.DataType.LONG;
+          typeAnswer = org.apache.lucene.document.NumericField.DataType.LONG;
         }
       }
       answers[id] = answer;
       typeAnswers[id] = typeAnswer;
-      // nocommit need to cutover
-      doc.add(new NumericField("id", Integer.MAX_VALUE, Field.Store.NO, true).setIntValue(id));
+      doc.add(new org.apache.lucene.document2.NumericField("id", Integer.MAX_VALUE).setIntValue(id));
       w.addDocument(doc);
     }
     final IndexReader r = w.getReader();
@@ -566,10 +564,10 @@
     for(IndexReader sub : r.getSequentialSubReaders()) {
       final int[] ids = FieldCache.DEFAULT.getInts(sub, "id");
       for(int docID=0;docID<sub.numDocs();docID++) {
-        final Document doc = sub.document(docID);
+        final org.apache.lucene.document.Document doc = sub.document(docID);
         final Fieldable f = doc.getFieldable("nf");
-        assertTrue("got f=" + f, f instanceof NumericField);
-        final NumericField nf = (NumericField) f;
+        assertTrue("got f=" + f, f instanceof org.apache.lucene.document.NumericField);
+        final org.apache.lucene.document.NumericField nf = (org.apache.lucene.document.NumericField) f;
         assertEquals(answers[ids[docID]], nf.getNumericValue());
         assertSame(typeAnswers[ids[docID]], nf.getDataType());
       }
