Index: lucene/src/test/org/apache/lucene/index/TestCodecs.java
===================================================================
--- lucene/src/test/org/apache/lucene/index/TestCodecs.java	(revision 1188635)
+++ lucene/src/test/org/apache/lucene/index/TestCodecs.java	(working copy)
@@ -33,6 +33,7 @@
 import org.apache.lucene.index.codecs.TermStats;
 import org.apache.lucene.index.codecs.TermsConsumer;
 import org.apache.lucene.index.codecs.mocksep.MockSepCodec;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.index.codecs.preflex.PreFlexCodec;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.IndexSearcher;
Index: lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java
===================================================================
--- lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java	(revision 1188635)
+++ lucene/src/test/org/apache/lucene/index/TestPerFieldCodecSupport.java	(working copy)
@@ -33,6 +33,7 @@
 import org.apache.lucene.index.codecs.mockintblock.MockFixedIntBlockCodec;
 import org.apache.lucene.index.codecs.mockintblock.MockVariableIntBlockCodec;
 import org.apache.lucene.index.codecs.mocksep.MockSepCodec;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.index.codecs.pulsing.PulsingCodec;
 import org.apache.lucene.index.codecs.simpletext.SimpleTextCodec;
 import org.apache.lucene.index.codecs.standard.StandardCodec;
Index: lucene/src/java/org/apache/lucene/index/FieldInfos.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/FieldInfos.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/FieldInfos.java	(working copy)
@@ -29,9 +29,9 @@
 import java.util.Map.Entry;
 
 import org.apache.lucene.index.FieldInfo.IndexOptions;
-import org.apache.lucene.index.SegmentCodecs; // Required for Java 1.5 javadocs
-import org.apache.lucene.index.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.index.codecs.CodecProvider;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.index.values.ValueType;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
@@ -235,7 +235,7 @@
    * <p>
    * Note: this ctor should not be used during indexing use
    * {@link FieldInfos#FieldInfos(FieldInfos)} or
-   * {@link FieldInfos#FieldInfos(FieldNumberBiMap,org.apache.lucene.index.SegmentCodecs.SegmentCodecsBuilder)}
+   * {@link FieldInfos#FieldInfos(FieldNumberBiMap,org.apache.lucene.index.codecs.perfield.SegmentCodecs.SegmentCodecsBuilder)}
    * instead.
    */
   public FieldInfos() {
Index: lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java	(working copy)
@@ -27,6 +27,7 @@
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.index.DocumentsWriterDeleteQueue.DeleteSlice;
 import org.apache.lucene.index.codecs.CodecProvider;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.search.similarities.SimilarityProvider;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.FlushInfo;
Index: lucene/src/java/org/apache/lucene/index/SegmentInfo.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentInfo.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/SegmentInfo.java	(working copy)
@@ -30,6 +30,7 @@
 import org.apache.lucene.index.codecs.Codec;
 import org.apache.lucene.index.codecs.CodecProvider;
 import org.apache.lucene.index.codecs.DefaultSegmentInfosWriter;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.store.CompoundFileDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
Index: lucene/src/java/org/apache/lucene/index/CheckIndex.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/CheckIndex.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/CheckIndex.java	(working copy)
@@ -40,6 +40,7 @@
 
 import org.apache.lucene.index.codecs.BlockTreeTermsReader;
 import org.apache.lucene.index.codecs.PerDocValues;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.index.values.IndexDocValues;
 import org.apache.lucene.index.values.IndexDocValues.Source;
 import org.apache.lucene.store.FSDirectory;
Index: lucene/src/java/org/apache/lucene/index/PerDocWriteState.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/PerDocWriteState.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/PerDocWriteState.java	(working copy)
@@ -18,6 +18,7 @@
 import java.io.PrintStream;
 
 import org.apache.lucene.index.codecs.PerDocConsumer;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.util.Counter;
@@ -38,7 +39,7 @@
   public final int codecId;
   public final IOContext context;
 
-  PerDocWriteState(PrintStream infoStream, Directory directory,
+  public PerDocWriteState(PrintStream infoStream, Directory directory,
       String segmentName, FieldInfos fieldInfos, Counter bytesUsed,
       int codecId, IOContext context) {
     this.infoStream = infoStream;
@@ -51,7 +52,7 @@
     this.context = context;
   }
 
-  PerDocWriteState(SegmentWriteState state) {
+  public PerDocWriteState(SegmentWriteState state) {
     infoStream = state.infoStream;
     directory = state.directory;
     segmentCodecs = state.segmentCodecs;
@@ -62,7 +63,7 @@
     context = state.context;
   }
 
-  PerDocWriteState(PerDocWriteState state, int codecId) {
+  public PerDocWriteState(PerDocWriteState state, int codecId) {
     this.infoStream = state.infoStream;
     this.directory = state.directory;
     this.segmentName = state.segmentName;
Index: lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/DocumentsWriterPerThreadPool.java	(working copy)
@@ -20,8 +20,8 @@
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.lucene.index.FieldInfos.FieldNumberBiMap;
-import org.apache.lucene.index.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.index.codecs.CodecProvider;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.util.SetOnce;
 
 /**
Index: lucene/src/java/org/apache/lucene/index/SegmentMerger.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentMerger.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/SegmentMerger.java	(working copy)
@@ -33,6 +33,7 @@
 import org.apache.lucene.index.codecs.FieldsWriter;
 import org.apache.lucene.index.codecs.MergeState;
 import org.apache.lucene.index.codecs.PerDocConsumer;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.store.CompoundFileDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
Index: lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/DocFieldProcessor.java	(working copy)
@@ -28,6 +28,7 @@
 import org.apache.lucene.index.codecs.Codec;
 import org.apache.lucene.index.codecs.DocValuesConsumer;
 import org.apache.lucene.index.codecs.PerDocConsumer;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.index.values.PerDocFieldValues;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.IOUtils;
Index: lucene/src/java/org/apache/lucene/index/SegmentCodecs.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentCodecs.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/SegmentCodecs.java	(working copy)
@@ -1,167 +0,0 @@
-package org.apache.lucene.index;
-
-/**
- * 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 java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.lucene.index.codecs.Codec;
-import org.apache.lucene.index.codecs.CodecProvider;
-import org.apache.lucene.index.codecs.preflex.PreFlexCodec;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.IndexInput;
-import org.apache.lucene.store.IndexOutput;
-
-/**
- * SegmentCodecs maintains an ordered list of distinct codecs used within a
- * segment. Within a segment on codec is used to write multiple fields while
- * each field could be written by a different codec. To enable codecs per field
- * within a single segment we need to record the distinct codecs and map them to
- * each field present in the segment. SegmentCodecs is created together with
- * {@link SegmentWriteState} for each flush and is maintained in the
- * corresponding {@link SegmentInfo} until it is committed.
- * <p>
- * During indexing {@link FieldInfos} uses {@link SegmentCodecsBuilder} to incrementally
- * build the {@link SegmentCodecs} mapping. Once a segment is flushed
- * DocumentsWriter creates a {@link SegmentCodecs} instance from
- * {@link FieldInfos#buildSegmentCodecs(boolean)} The {@link FieldInfo#codecId}
- * assigned by {@link SegmentCodecsBuilder} refers to the codecs ordinal
- * maintained inside {@link SegmentCodecs}. This ord is later used to get the
- * right codec when the segment is opened in a reader.The {@link Codec} returned
- * from {@link SegmentCodecs#codec()} in turn uses {@link SegmentCodecs}
- * internal structure to select and initialize the right codec for a fields when
- * it is written.
- * <p>
- * Once a flush succeeded the {@link SegmentCodecs} is maintained inside the
- * {@link SegmentInfo} for the flushed segment it was created for.
- * {@link SegmentInfo} writes the name of each codec in {@link SegmentCodecs}
- * for each segment and maintains the order. Later if a segment is opened by a
- * reader this mapping is deserialized and used to create the codec per field.
- * 
- * 
- * @lucene.internal
- */
-final class SegmentCodecs implements Cloneable {
-  /**
-   * internal structure to map codecs to fields - don't modify this from outside
-   * of this class!
-   */
-  final Codec[] codecs;
-  final CodecProvider provider;
-  private final Codec codec;
-  
-  SegmentCodecs(CodecProvider provider, IndexInput input) throws IOException {
-    this(provider, read(input, provider));
-  }
-  
-  SegmentCodecs(CodecProvider provider, Codec... codecs) {
-    this.provider = provider;
-    this.codecs = codecs;
-    if (codecs.length == 1 && codecs[0] instanceof PreFlexCodec) {
-      this.codec = codecs[0]; // hack for backwards break... don't wrap the codec in preflex
-    } else {
-      this.codec = new PerFieldCodecWrapper(this);
-    }
-  }
-
-  Codec codec() {
-    return codec;
-  }
-
-  void write(IndexOutput out) throws IOException {
-    out.writeVInt(codecs.length);
-    for (Codec codec : codecs) {
-      out.writeString(codec.name);
-    }
-  }
-
-  private static Codec[] read(IndexInput in, CodecProvider provider) throws IOException {
-    final int size = in.readVInt();
-    final ArrayList<Codec> list = new ArrayList<Codec>();
-    for (int i = 0; i < size; i++) {
-      final String codecName = in.readString();
-      final Codec lookup = provider.lookup(codecName);
-      list.add(i, lookup);
-    }
-    return list.toArray(Codec.EMPTY);
-  }
-
-  void files(Directory dir, SegmentInfo info, Set<String> files)
-      throws IOException {
-    final Codec[] codecArray = codecs;
-    for (int i = 0; i < codecArray.length; i++) {
-      codecArray[i].files(dir, info, i, files);
-    }      
-      
-  }
-
-  @Override
-  public String toString() {
-    return "SegmentCodecs [codecs=" + Arrays.toString(codecs) + ", provider=" + provider + "]";
-  }
-  
-  /**
-   * Used in {@link FieldInfos} to incrementally build the codec ID mapping for
-   * {@link FieldInfo} instances.
-   * <p>
-   * Note: this class is not thread-safe
-   * </p>
-   * @see FieldInfo#getCodecId()
-   */
-  final static class SegmentCodecsBuilder {
-    private final Map<Codec, Integer> codecRegistry = new IdentityHashMap<Codec, Integer>();
-    private final ArrayList<Codec> codecs = new ArrayList<Codec>();
-    private final CodecProvider provider;
-
-    private SegmentCodecsBuilder(CodecProvider provider) {
-      this.provider = provider;
-    }
-    
-    static SegmentCodecsBuilder create(CodecProvider provider) {
-      return new SegmentCodecsBuilder(provider);
-    }
-    
-    SegmentCodecsBuilder tryAddAndSet(FieldInfo fi) {
-      if (fi.getCodecId() == FieldInfo.UNASSIGNED_CODEC_ID) {
-        final Codec fieldCodec = provider.lookup(provider
-            .getFieldCodec(fi.name));
-        Integer ord = codecRegistry.get(fieldCodec);
-        if (ord == null) {
-          ord = Integer.valueOf(codecs.size());
-          codecRegistry.put(fieldCodec, ord);
-          codecs.add(fieldCodec);
-        }
-        fi.setCodecId(ord.intValue());
-      }
-      return this;
-    }
-    
-    SegmentCodecs build() {
-      return new SegmentCodecs(provider, codecs.toArray(Codec.EMPTY));
-    }
-    
-    SegmentCodecsBuilder clear() {
-      codecRegistry.clear();
-      codecs.clear();
-      return this;
-    }
-  }
-}
\ No newline at end of file
Index: lucene/src/java/org/apache/lucene/index/FieldInfo.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/FieldInfo.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/FieldInfo.java	(working copy)
@@ -78,7 +78,7 @@
     assert indexOptions == IndexOptions.DOCS_AND_FREQS_AND_POSITIONS || !storePayloads;
   }
 
-  void setCodecId(int codecId) {
+  public void setCodecId(int codecId) {
     assert this.codecId == UNASSIGNED_CODEC_ID : "CodecId can only be set once.";
     this.codecId = codecId;
   }
Index: lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/PerFieldCodecWrapper.java	(working copy)
@@ -1,286 +0,0 @@
-package org.apache.lucene.index;
-
-/**
- * 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 java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import org.apache.lucene.index.codecs.Codec;
-import org.apache.lucene.index.codecs.FieldsConsumer;
-import org.apache.lucene.index.codecs.FieldsProducer;
-import org.apache.lucene.index.codecs.PerDocConsumer;
-import org.apache.lucene.index.codecs.PerDocValues;
-import org.apache.lucene.index.codecs.TermsConsumer;
-import org.apache.lucene.index.codecs.DocValuesConsumer;
-import org.apache.lucene.index.values.IndexDocValues;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.IOContext;
-import org.apache.lucene.util.IOUtils;
-
-/**
- * Enables native per field codec support. This class selects the codec used to
- * write a field depending on the provided {@link SegmentCodecs}. For each field
- * seen it resolves the codec based on the {@link FieldInfo#codecId} which is
- * only valid during a segment merge. See {@link SegmentCodecs} javadoc for
- * details.
- * 
- * @lucene.internal
- */
-final class PerFieldCodecWrapper extends Codec {
-  private final SegmentCodecs segmentCodecs;
-
-  PerFieldCodecWrapper(SegmentCodecs segmentCodecs) {
-    super("PerField");
-    this.segmentCodecs = segmentCodecs;
-  }
-
-  @Override
-  public FieldsConsumer fieldsConsumer(SegmentWriteState state)
-      throws IOException {
-    return new FieldsWriter(state);
-  }
-
-  private class FieldsWriter extends FieldsConsumer {
-    private final ArrayList<FieldsConsumer> consumers = new ArrayList<FieldsConsumer>();
-
-    public FieldsWriter(SegmentWriteState state) throws IOException {
-      assert segmentCodecs == state.segmentCodecs;
-      final Codec[] codecs = segmentCodecs.codecs;
-      for (int i = 0; i < codecs.length; i++) {
-        boolean success = false;
-        try {
-          consumers.add(codecs[i].fieldsConsumer(new SegmentWriteState(state, i)));
-          success = true;
-        } finally {
-          if (!success) {
-            IOUtils.closeWhileHandlingException(consumers);
-          }
-        }
-      }
-    }
-
-    @Override
-    public TermsConsumer addField(FieldInfo field) throws IOException {
-      assert field.getCodecId() != FieldInfo.UNASSIGNED_CODEC_ID;
-      final FieldsConsumer fields = consumers.get(field.getCodecId());
-      return fields.addField(field);
-    }
-
-    @Override
-    public void close() throws IOException {
-      IOUtils.close(consumers);
-    }
-  }
-
-  private class FieldsReader extends FieldsProducer {
-
-    private final Set<String> fields = new TreeSet<String>();
-    private final Map<String, FieldsProducer> codecs = new HashMap<String, FieldsProducer>();
-
-    public FieldsReader(Directory dir, FieldInfos fieldInfos, SegmentInfo si,
-        IOContext context, int indexDivisor) throws IOException {
-
-      final Map<Codec, FieldsProducer> producers = new HashMap<Codec, FieldsProducer>();
-      boolean success = false;
-      try {
-        for (FieldInfo fi : fieldInfos) {
-          if (fi.isIndexed) { 
-            fields.add(fi.name);
-            assert fi.getCodecId() != FieldInfo.UNASSIGNED_CODEC_ID;
-            Codec codec = segmentCodecs.codecs[fi.getCodecId()];
-            if (!producers.containsKey(codec)) {
-              producers.put(codec, codec.fieldsProducer(new SegmentReadState(dir,
-                                                                             si, fieldInfos, context, indexDivisor, fi.getCodecId())));
-            }
-            codecs.put(fi.name, producers.get(codec));
-          }
-        }
-        success = true;
-      } finally {
-        if (!success) {
-          // If we hit exception (eg, IOE because writer was
-          // committing, or, for any other reason) we must
-          // go back and close all FieldsProducers we opened:
-          IOUtils.closeWhileHandlingException(producers.values());
-        }
-      }
-    }
-    
-
-    private final class FieldsIterator extends FieldsEnum {
-      private final Iterator<String> it;
-      private String current;
-
-      public FieldsIterator() {
-        it = fields.iterator();
-      }
-
-      @Override
-      public String next() {
-        if (it.hasNext()) {
-          current = it.next();
-        } else {
-          current = null;
-        }
-
-        return current;
-      }
-
-      @Override
-      public TermsEnum terms() throws IOException {
-        Terms terms = codecs.get(current).terms(current);
-        if (terms != null) {
-          return terms.iterator();
-        } else {
-          return TermsEnum.EMPTY;
-        }
-      }
-    }
-
-    @Override
-    public FieldsEnum iterator() throws IOException {
-      return new FieldsIterator();
-    }
-
-    @Override
-    public Terms terms(String field) throws IOException {
-      FieldsProducer fields = codecs.get(field);
-      return fields == null ? null : fields.terms(field);
-    }
-    
-    @Override
-    public void close() throws IOException {
-      IOUtils.close(codecs.values());
-    }
-  }
-
-  @Override
-  public FieldsProducer fieldsProducer(SegmentReadState state)
-      throws IOException {
-    return new FieldsReader(state.dir, state.fieldInfos, state.segmentInfo,
-        state.context, state.termsIndexDivisor);
-  }
-
-  @Override
-  public void files(Directory dir, SegmentInfo info, int codecId, Set<String> files)
-      throws IOException {
-    // ignore codecid since segmentCodec will assign it per codec
-    segmentCodecs.files(dir, info, files);
-  }
-
-  @Override
-  public void getExtensions(Set<String> extensions) {
-    for (Codec codec : segmentCodecs.codecs) {
-      codec.getExtensions(extensions);
-    }
-  }
-
-  @Override
-  public PerDocConsumer docsConsumer(PerDocWriteState state) throws IOException {
-    return new PerDocConsumers(state);
-  }
-
-  @Override
-  public PerDocValues docsProducer(SegmentReadState state) throws IOException {
-    return new PerDocProducers(state.dir, state.fieldInfos, state.segmentInfo,
-    state.context, state.termsIndexDivisor);
-  }
-  
-  private final class PerDocProducers extends PerDocValues {
-    private final TreeMap<String, PerDocValues> codecs = new TreeMap<String, PerDocValues>();
-
-    public PerDocProducers(Directory dir, FieldInfos fieldInfos, SegmentInfo si,
-        IOContext context, int indexDivisor) throws IOException {
-      final Map<Codec, PerDocValues> producers = new HashMap<Codec, PerDocValues>();
-      boolean success = false;
-      try {
-        for (FieldInfo fi : fieldInfos) {
-          if (fi.hasDocValues()) { 
-            assert fi.getCodecId() != FieldInfo.UNASSIGNED_CODEC_ID;
-            Codec codec = segmentCodecs.codecs[fi.getCodecId()];
-            if (!producers.containsKey(codec)) {
-              producers.put(codec, codec.docsProducer(new SegmentReadState(dir,
-                si, fieldInfos, context, indexDivisor, fi.getCodecId())));
-            }
-            codecs.put(fi.name, producers.get(codec));
-          }
-        }
-        success = true;
-      } finally {
-        if (!success) {
-          IOUtils.closeWhileHandlingException(producers.values());
-        }
-      }
-    }
-    
-    @Override
-    public Collection<String> fields() {
-      return codecs.keySet();
-    }
-    @Override
-    public IndexDocValues docValues(String field) throws IOException {
-      final PerDocValues perDocProducer = codecs.get(field);
-      if (perDocProducer == null) {
-        return null;
-      }
-      return perDocProducer.docValues(field);
-    }
-    
-    public void close() throws IOException {
-      IOUtils.close(codecs.values());
-    }
-  }
-  
-  private final class PerDocConsumers extends PerDocConsumer {
-    private final PerDocConsumer[] consumers;
-    private final Codec[] codecs;
-    private final PerDocWriteState state;
-
-    public PerDocConsumers(PerDocWriteState state) throws IOException {
-      assert segmentCodecs == state.segmentCodecs;
-      this.state = state;
-      codecs = segmentCodecs.codecs;
-      consumers = new PerDocConsumer[codecs.length];
-    }
-
-    public void close() throws IOException {
-      IOUtils.close(consumers);
-    }
-
-    @Override
-    public DocValuesConsumer addValuesField(FieldInfo field) throws IOException {
-      final int codecId = field.getCodecId();
-      assert codecId != FieldInfo.UNASSIGNED_CODEC_ID;
-      PerDocConsumer perDoc = consumers[codecId];
-      if (perDoc == null) {
-        perDoc = codecs[codecId].docsConsumer(new PerDocWriteState(state, codecId));
-        assert perDoc != null;
-        consumers[codecId] = perDoc;
-      }
-      return perDoc.addValuesField(field);
-    }
-    
-  }
-}
Index: lucene/src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexWriter.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/IndexWriter.java	(working copy)
@@ -39,8 +39,8 @@
 import org.apache.lucene.index.FieldInfos.FieldNumberBiMap;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.index.PayloadProcessorProvider.DirPayloadProcessor;
-import org.apache.lucene.index.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.index.codecs.CodecProvider;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs.SegmentCodecsBuilder;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.CompoundFileDirectory;
Index: lucene/src/java/org/apache/lucene/index/SegmentWriteState.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentWriteState.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/SegmentWriteState.java	(working copy)
@@ -19,6 +19,7 @@
 
 import java.io.PrintStream;
 
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.util.BitVector;
@@ -43,7 +44,7 @@
   // Lazily created:
   public BitVector liveDocs;
 
-  final SegmentCodecs segmentCodecs;
+  public final SegmentCodecs segmentCodecs;
   public final int codecId;
 
   /** Expert: The fraction of terms in the "dictionary" which should be stored
@@ -72,7 +73,7 @@
   /**
    * Create a shallow {@link SegmentWriteState} copy final a codec ID
    */
-  SegmentWriteState(SegmentWriteState state, int codecId) {
+  public SegmentWriteState(SegmentWriteState state, int codecId) {
     infoStream = state.infoStream;
     directory = state.directory;
     segmentName = state.segmentName;
Index: lucene/src/java/org/apache/lucene/index/codecs/perfield/SegmentCodecs.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/codecs/perfield/SegmentCodecs.java	(revision 0)
+++ lucene/src/java/org/apache/lucene/index/codecs/perfield/SegmentCodecs.java	(working copy)
@@ -1,4 +1,4 @@
-package org.apache.lucene.index;
+package org.apache.lucene.index.codecs.perfield;
 
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -23,6 +23,10 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.FieldInfos;
+import org.apache.lucene.index.SegmentInfo;
+import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.codecs.Codec;
 import org.apache.lucene.index.codecs.CodecProvider;
 import org.apache.lucene.index.codecs.preflex.PreFlexCodec;
@@ -59,20 +63,20 @@
  * 
  * @lucene.internal
  */
-final class SegmentCodecs implements Cloneable {
+public final class SegmentCodecs implements Cloneable {
   /**
    * internal structure to map codecs to fields - don't modify this from outside
    * of this class!
    */
-  final Codec[] codecs;
-  final CodecProvider provider;
+  public final Codec[] codecs;
+  public final CodecProvider provider;
   private final Codec codec;
   
-  SegmentCodecs(CodecProvider provider, IndexInput input) throws IOException {
+  public SegmentCodecs(CodecProvider provider, IndexInput input) throws IOException {
     this(provider, read(input, provider));
   }
   
-  SegmentCodecs(CodecProvider provider, Codec... codecs) {
+  public SegmentCodecs(CodecProvider provider, Codec... codecs) {
     this.provider = provider;
     this.codecs = codecs;
     if (codecs.length == 1 && codecs[0] instanceof PreFlexCodec) {
@@ -82,11 +86,11 @@
     }
   }
 
-  Codec codec() {
+  public Codec codec() {
     return codec;
   }
 
-  void write(IndexOutput out) throws IOException {
+  public void write(IndexOutput out) throws IOException {
     out.writeVInt(codecs.length);
     for (Codec codec : codecs) {
       out.writeString(codec.name);
@@ -104,7 +108,7 @@
     return list.toArray(Codec.EMPTY);
   }
 
-  void files(Directory dir, SegmentInfo info, Set<String> files)
+  public void files(Directory dir, SegmentInfo info, Set<String> files)
       throws IOException {
     final Codec[] codecArray = codecs;
     for (int i = 0; i < codecArray.length; i++) {
@@ -126,7 +130,7 @@
    * </p>
    * @see FieldInfo#getCodecId()
    */
-  final static class SegmentCodecsBuilder {
+  public final static class SegmentCodecsBuilder {
     private final Map<Codec, Integer> codecRegistry = new IdentityHashMap<Codec, Integer>();
     private final ArrayList<Codec> codecs = new ArrayList<Codec>();
     private final CodecProvider provider;
@@ -135,11 +139,11 @@
       this.provider = provider;
     }
     
-    static SegmentCodecsBuilder create(CodecProvider provider) {
+    public static SegmentCodecsBuilder create(CodecProvider provider) {
       return new SegmentCodecsBuilder(provider);
     }
     
-    SegmentCodecsBuilder tryAddAndSet(FieldInfo fi) {
+    public SegmentCodecsBuilder tryAddAndSet(FieldInfo fi) {
       if (fi.getCodecId() == FieldInfo.UNASSIGNED_CODEC_ID) {
         final Codec fieldCodec = provider.lookup(provider
             .getFieldCodec(fi.name));
@@ -154,11 +158,11 @@
       return this;
     }
     
-    SegmentCodecs build() {
+    public SegmentCodecs build() {
       return new SegmentCodecs(provider, codecs.toArray(Codec.EMPTY));
     }
     
-    SegmentCodecsBuilder clear() {
+    public SegmentCodecsBuilder clear() {
       codecRegistry.clear();
       codecs.clear();
       return this;
Index: lucene/src/java/org/apache/lucene/index/codecs/perfield/PerFieldCodecWrapper.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/codecs/perfield/PerFieldCodecWrapper.java	(revision 0)
+++ lucene/src/java/org/apache/lucene/index/codecs/perfield/PerFieldCodecWrapper.java	(working copy)
@@ -1,4 +1,4 @@
-package org.apache.lucene.index;
+package org.apache.lucene.index.codecs.perfield;
 
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -27,6 +27,15 @@
 import java.util.TreeMap;
 import java.util.TreeSet;
 
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.FieldInfos;
+import org.apache.lucene.index.FieldsEnum;
+import org.apache.lucene.index.PerDocWriteState;
+import org.apache.lucene.index.SegmentInfo;
+import org.apache.lucene.index.SegmentReadState;
+import org.apache.lucene.index.SegmentWriteState;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
 import org.apache.lucene.index.codecs.Codec;
 import org.apache.lucene.index.codecs.FieldsConsumer;
 import org.apache.lucene.index.codecs.FieldsProducer;
Index: lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java	(revision 1188635)
+++ lucene/src/java/org/apache/lucene/index/SegmentCoreReaders.java	(working copy)
@@ -24,6 +24,7 @@
 import org.apache.lucene.index.codecs.FieldsProducer;
 import org.apache.lucene.index.codecs.FieldsReader;
 import org.apache.lucene.index.codecs.PerDocValues;
+import org.apache.lucene.index.codecs.perfield.SegmentCodecs;
 import org.apache.lucene.store.CompoundFileDirectory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
