diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexReader.java
index 2066fcf..187e7ee 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexReader.java
@@ -20,6 +20,7 @@ package org.apache.lucene.codecs.blockterms;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.index.CorruptIndexException;
 import org.apache.lucene.index.FieldInfos;
@@ -43,6 +44,8 @@ import org.apache.lucene.index.IndexFileNames;
  */
 public class FixedGapTermsIndexReader extends TermsIndexReaderBase {
 
+  public static final int DEFAULT_TERM_INDEX_DIVISOR = 1;
+  public static final String TERM_INDEX_DIVISOR_KEY = "terms_reader.term_index_divisor";
   // NOTE: long is overkill here, since this number is 128
   // by default and only indexDivisor * 128 if you change
   // the indexDivisor at search time.  But, we use this in a
@@ -74,13 +77,10 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase {
   
   private final int version;
 
-  public FixedGapTermsIndexReader(Directory dir, FieldInfos fieldInfos, String segment, int indexDivisor, Comparator<BytesRef> termComp, String segmentSuffix, IOContext context)
+  public FixedGapTermsIndexReader(Directory dir, FieldInfos fieldInfos, String segment, CodecSettings settings, Comparator<BytesRef> termComp, String segmentSuffix, IOContext context)
     throws IOException {
 
     this.termComp = termComp;
-
-    assert indexDivisor == -1 || indexDivisor > 0;
-
     in = dir.openInput(IndexFileNames.segmentFileName(segment, segmentSuffix, FixedGapTermsIndexWriter.TERMS_INDEX_EXTENSION), context);
     
     boolean success = false;
@@ -92,8 +92,9 @@ public class FixedGapTermsIndexReader extends TermsIndexReaderBase {
       if (indexInterval < 1) {
         throw new CorruptIndexException("invalid indexInterval: " + indexInterval + " (resource=" + in + ")");
       }
-      this.indexDivisor = indexDivisor;
-
+      boolean loadTermIndex = settings.getAsBoolean(CodecSettings.LOAD_TERM_INDEX, true);
+      indexDivisor = settings.getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, loadTermIndex ? FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR : -1);
+      assert indexDivisor == -1 || indexDivisor > 0;
       if (indexDivisor < 0) {
         totalIndexInterval = indexInterval;
       } else {
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
index 2e375b7..4776a0e 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/FixedGapTermsIndexWriter.java
@@ -18,6 +18,7 @@ package org.apache.lucene.codecs.blockterms;
  */
 
 import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.codecs.TermStats;
 import org.apache.lucene.index.FieldInfos;
@@ -43,7 +44,8 @@ import java.io.IOException;
  * @lucene.experimental */
 public class FixedGapTermsIndexWriter extends TermsIndexWriterBase {
   protected final IndexOutput out;
-
+  public static final int DEFAULT_TERM_INDEX_INTERVAL = 32;
+  public static final String TERM_INDEX_INTERVAL_KEY = "terms_writer.term_index_interval";
   /** Extension of terms index file */
   static final String TERMS_INDEX_EXTENSION = "tii";
 
@@ -60,7 +62,8 @@ public class FixedGapTermsIndexWriter extends TermsIndexWriterBase {
 
   public FixedGapTermsIndexWriter(SegmentWriteState state) throws IOException {
     final String indexFileName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, TERMS_INDEX_EXTENSION);
-    termIndexInterval = state.termIndexInterval;
+    CodecSettings codecSettings = state.codecSettings;
+    termIndexInterval = codecSettings.getAsInt(TERM_INDEX_INTERVAL_KEY, DEFAULT_TERM_INDEX_INTERVAL);
     out = state.directory.createOutput(indexFileName, state.context);
     boolean success = false;
     try {
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/VariableGapTermsIndexReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/VariableGapTermsIndexReader.java
index 532c9e6..be37f1c 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/VariableGapTermsIndexReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/blockterms/VariableGapTermsIndexReader.java
@@ -23,6 +23,7 @@ import java.io.OutputStreamWriter; // for toDot
 import java.io.Writer;             // for toDot
 import java.util.HashMap;
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.index.CorruptIndexException;
 import org.apache.lucene.index.FieldInfo;
@@ -59,16 +60,18 @@ public class VariableGapTermsIndexReader extends TermsIndexReaderBase {
   private final int version;
 
   final String segment;
-  public VariableGapTermsIndexReader(Directory dir, FieldInfos fieldInfos, String segment, int indexDivisor, String segmentSuffix, IOContext context)
+  public VariableGapTermsIndexReader(Directory dir, FieldInfos fieldInfos, String segment, CodecSettings codecSettings, String segmentSuffix, IOContext context)
     throws IOException {
     in = dir.openInput(IndexFileNames.segmentFileName(segment, segmentSuffix, VariableGapTermsIndexWriter.TERMS_INDEX_EXTENSION), new IOContext(context, true));
     this.segment = segment;
     boolean success = false;
-    assert indexDivisor == -1 || indexDivisor > 0;
 
     try {
       
       version = readHeader(in);
+      boolean loadTermIndex = codecSettings.getAsBoolean(CodecSettings.LOAD_TERM_INDEX, true);
+      int indexDivisor = codecSettings.getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, loadTermIndex ? FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR : -1);
+      assert indexDivisor == -1 || indexDivisor > 0;
       this.indexDivisor = indexDivisor;
 
       seekDir(in, dirOffset);
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/pulsing/PulsingPostingsFormat.java b/lucene/codecs/src/java/org/apache/lucene/codecs/pulsing/PulsingPostingsFormat.java
index da53cc5..5a237f9 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/pulsing/PulsingPostingsFormat.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/pulsing/PulsingPostingsFormat.java
@@ -99,12 +99,11 @@ public abstract class PulsingPostingsFormat extends PostingsFormat {
     try {
       docsReader = wrappedPostingsBaseFormat.postingsReaderBase(state);
       pulsingReader = new PulsingPostingsReader(docsReader);
-      FieldsProducer ret = new BlockTreeTermsReader(
-                                                    state.dir, state.fieldInfos, state.segmentInfo,
+      FieldsProducer ret = new BlockTreeTermsReader(state.dir, state.fieldInfos, state.segmentInfo,
                                                     pulsingReader,
                                                     state.context,
                                                     state.segmentSuffix,
-                                                    state.termsIndexDivisor);
+                                                    state.codecSettings);
       success = true;
       return ret;
     } finally {
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
index 3360602..04ed39e 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java
@@ -112,11 +112,12 @@ public class BlockTreeTermsReader extends FieldsProducer {
   /** Sole constructor. */
   public BlockTreeTermsReader(Directory dir, FieldInfos fieldInfos, SegmentInfo info,
                               PostingsReaderBase postingsReader, IOContext ioContext,
-                              String segmentSuffix, int indexDivisor)
+                              String segmentSuffix, CodecSettings codecSettings)
     throws IOException {
     
     this.postingsReader = postingsReader;
-
+    final boolean loadTermIndex = codecSettings.getAsBoolean(CodecSettings.LOAD_TERM_INDEX, true);
+    
     this.segment = info.name;
     in = dir.openInput(IndexFileNames.segmentFileName(segment, segmentSuffix, BlockTreeTermsWriter.TERMS_EXTENSION),
                        ioContext);
@@ -126,7 +127,7 @@ public class BlockTreeTermsReader extends FieldsProducer {
 
     try {
       version = readHeader(in);
-      if (indexDivisor != -1) {
+      if (loadTermIndex) {
         indexIn = dir.openInput(IndexFileNames.segmentFileName(segment, segmentSuffix, BlockTreeTermsWriter.TERMS_INDEX_EXTENSION),
                                 ioContext);
         int indexVersion = readIndexHeader(indexIn);
@@ -140,7 +141,7 @@ public class BlockTreeTermsReader extends FieldsProducer {
 
       // Read per-field details
       seekDir(in, dirOffset);
-      if (indexDivisor != -1) {
+      if (loadTermIndex) {
         seekDir(indexIn, indexDirOffset);
       }
 
@@ -171,13 +172,13 @@ public class BlockTreeTermsReader extends FieldsProducer {
         if (sumTotalTermFreq != -1 && sumTotalTermFreq < sumDocFreq) { // #positions must be >= #postings
           throw new CorruptIndexException("invalid sumTotalTermFreq: " + sumTotalTermFreq + " sumDocFreq: " + sumDocFreq + " (resource=" + in + ")");
         }
-        final long indexStartFP = indexDivisor != -1 ? indexIn.readVLong() : 0;
+        final long indexStartFP = loadTermIndex ? indexIn.readVLong() : 0;
         FieldReader previous = fields.put(fieldInfo.name, new FieldReader(fieldInfo, numTerms, rootCode, sumTotalTermFreq, sumDocFreq, docCount, indexStartFP, indexIn));
         if (previous != null) {
           throw new CorruptIndexException("duplicate field: " + fieldInfo.name + " (resource=" + in + ")");
         }
       }
-      if (indexDivisor != -1) {
+      if (loadTermIndex) {
         indexIn.close();
       }
 
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/CodecSettings.java b/lucene/core/src/java/org/apache/lucene/codecs/CodecSettings.java
new file mode 100644
index 0000000..f3b4aff
--- /dev/null
+++ b/lucene/core/src/java/org/apache/lucene/codecs/CodecSettings.java
@@ -0,0 +1,169 @@
+package org.apache.lucene.codecs;
+
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+
+/**
+ * 
+ */
+//nocommit javadocs
+public class CodecSettings {
+  
+  // nocommit should we really expose this as public? it might be dangerous!
+  public static final String LOAD_TERM_INDEX = "load_term_index";
+  private static final CodecSettings DEFAULT_SETTINGS = CodecSettings.builder().build();
+  private final Map<String,String> settingsMap;
+  
+  private CodecSettings(Map<String,String> settings) {
+    settingsMap = settings;
+  }
+
+  public String get(String key) {
+    return settingsMap.get(key);
+  }
+  
+  public String get(String key, String defaultValue) {
+    String string = get(key);
+    if (string == null) {
+      return defaultValue;
+    }
+    return string;
+  }
+  
+  public int getAsInt(String setting, int defaultValue) {
+    String value = get(setting);
+    if (value == null) {
+      return defaultValue;
+    }
+    try {
+      return Integer.parseInt(value);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException("Failed to parse int setting ["
+          + setting + "] with value [" + value + "]", e);
+    }
+  }
+  
+  public float getAsFloat(String setting, float defaultValue) {
+    String value = get(setting);
+    if (value == null) {
+      return defaultValue;
+    }
+    try {
+      return Float.parseFloat(value);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException("Failed to parse int setting ["
+          + setting + "] with value [" + value + "]", e);
+    }
+  }
+  
+  public double getAsDouble(String setting, double defaultValue) {
+    String value = get(setting);
+    if (value == null) {
+      return defaultValue;
+    }
+    try {
+      return Double.parseDouble(value);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException("Failed to parse int setting ["
+          + setting + "] with value [" + value + "]", e);
+    }
+  }
+  
+  public long getAsLong(String setting, long defaultValue) {
+    String value = get(setting);
+    if (value == null) {
+      return defaultValue;
+    }
+    try {
+      return Long.parseLong(value);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException("Failed to parse int setting ["
+          + setting + "] with value [" + value + "]", e);
+    }
+  }
+  
+  public boolean getAsBoolean(String setting, boolean defaultValue) {
+    String value = get(setting);
+    if (value == null) {
+      return defaultValue;
+    }
+    try {
+      return Boolean.parseBoolean(value);
+    } catch (NumberFormatException e) {
+      throw new IllegalArgumentException("Failed to parse int setting ["
+          + setting + "] with value [" + value + "]", e);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "CodecSettings [settingsMap=" + settingsMap + "]";
+  }
+
+  public static SettingsBuilder builder(CodecSettings settings) {
+    return new SettingsBuilder(new HashMap<String,String>(settings.settingsMap));
+  }
+
+  
+  public static SettingsBuilder builder() {
+    return new SettingsBuilder(new HashMap<String,String>());
+  }
+  
+  public static class SettingsBuilder {
+    private final Map<String,String> settings;
+    
+    private SettingsBuilder(Map<String, String> settings) {
+      this.settings = settings;
+    }
+    
+    public void put(String key, int value) {
+      put(key, String.valueOf(value));
+    }
+    
+    public void put(String key, long value) {
+      put(key, String.valueOf(value));
+    }
+    
+    public void put(String key, double value) {
+      put(key, String.valueOf(value));
+    }
+    
+    public void put(String key, float value) {
+      put(key, String.valueOf(value));
+    }
+    
+    public void put(String key, boolean value) {
+      put(key, String.valueOf(value));
+    }
+    
+    public void put(String key, String value) {
+      settings.put(key, value);
+    }
+
+    public CodecSettings build() {
+      return new CodecSettings(settings);
+    }
+  }
+
+  public static CodecSettings defaults() {
+    return DEFAULT_SETTINGS;
+  }
+  
+}
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40PostingsFormat.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40PostingsFormat.java
index 1f9c28e..a2cc634 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40PostingsFormat.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene40/Lucene40PostingsFormat.java
@@ -259,7 +259,7 @@ public class Lucene40PostingsFormat extends PostingsFormat {
                                                     postings,
                                                     state.context,
                                                     state.segmentSuffix,
-                                                    state.termsIndexDivisor);
+                                                    state.codecSettings);
       success = true;
       return ret;
     } finally {
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene41/Lucene41PostingsFormat.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene41/Lucene41PostingsFormat.java
index ce91686..1035451 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene41/Lucene41PostingsFormat.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene41/Lucene41PostingsFormat.java
@@ -440,7 +440,7 @@ public final class Lucene41PostingsFormat extends PostingsFormat {
                                                     postingsReader,
                                                     state.context,
                                                     state.segmentSuffix,
-                                                    state.termsIndexDivisor);
+                                                    state.codecSettings);
       success = true;
       return ret;
     } finally {
diff --git a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
index 371c489..a86f7d0 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
@@ -30,6 +30,7 @@ import java.util.Map;
 
 import org.apache.lucene.codecs.BlockTreeTermsReader;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.PostingsFormat; // javadocs
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.FieldType; // for javadocs
@@ -534,7 +535,7 @@ public class CheckIndex {
         }
         if (infoStream != null)
           infoStream.print("    test: open reader.........");
-        reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, IOContext.DEFAULT);
+        reader = new SegmentReader(info, CodecSettings.defaults() , IOContext.DEFAULT);
 
         segInfoStat.openReaderPassed = true;
 
diff --git a/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java b/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
index b173c43..bae1ff7 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DirectoryReader.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.search.SearcherManager; // javadocs
 import org.apache.lucene.store.Directory;
 
@@ -50,8 +51,6 @@ import org.apache.lucene.store.Directory;
 */
 public abstract class DirectoryReader extends BaseCompositeReader<AtomicReader> {
 
-  /** Default termInfosIndexDivisor. */
-  public static final int DEFAULT_TERMS_INDEX_DIVISOR = 1;
 
   /** The index directory. */
   protected final Directory directory;
@@ -62,15 +61,14 @@ public abstract class DirectoryReader extends BaseCompositeReader<AtomicReader>
    * @throws IOException if there is a low-level IO error
    */
   public static DirectoryReader open(final Directory directory) throws IOException {
-    return StandardDirectoryReader.open(directory, null, DEFAULT_TERMS_INDEX_DIVISOR);
+    return StandardDirectoryReader.open(directory, null, CodecSettings.defaults());
   }
   
   /** Expert: Returns a IndexReader reading the index in the given
    *  Directory with the given termInfosIndexDivisor.
    * @param directory the index directory
-   * @param termInfosIndexDivisor Subsamples which indexed
-   *  terms are loaded into RAM. This has the same effect as {@link
-   *  IndexWriterConfig#setTermIndexInterval} except that setting
+   * @param settings Subsamples which indexed
+   *  terms are loaded into RAM. This has the same effect as  except that setting
    *  must be done at indexing time while this setting can be
    *  set per reader.  When set to N, then one in every
    *  N*termIndexInterval terms in the index is loaded into
@@ -82,9 +80,11 @@ public abstract class DirectoryReader extends BaseCompositeReader<AtomicReader>
    *  implementations, including the default one in this release. It only makes
    *  sense for terms indexes that can efficiently re-sample terms at load time.
    * @throws IOException if there is a low-level IO error
+   *
+   * nocommit fix javadoc
    */
-  public static DirectoryReader open(final Directory directory, int termInfosIndexDivisor) throws IOException {
-    return StandardDirectoryReader.open(directory, null, termInfosIndexDivisor);
+  public static DirectoryReader open(final Directory directory, CodecSettings settings) throws IOException {
+    return StandardDirectoryReader.open(directory, null, settings);
   }
   
   /**
@@ -116,15 +116,14 @@ public abstract class DirectoryReader extends BaseCompositeReader<AtomicReader>
    * @throws IOException if there is a low-level IO error
    */
   public static DirectoryReader open(final IndexCommit commit) throws IOException {
-    return StandardDirectoryReader.open(commit.getDirectory(), commit, DEFAULT_TERMS_INDEX_DIVISOR);
+    return StandardDirectoryReader.open(commit.getDirectory(), commit, CodecSettings.defaults());
   }
 
   /** Expert: returns an IndexReader reading the index in the given
    *  {@link IndexCommit} and termInfosIndexDivisor.
    * @param commit the commit point to open
-   * @param termInfosIndexDivisor Subsamples which indexed
-   *  terms are loaded into RAM. This has the same effect as {@link
-   *  IndexWriterConfig#setTermIndexInterval} except that setting
+   * @param settings Subsamples which indexed
+   *  terms are loaded into RAM. This has the same effect as  except that setting
    *  must be done at indexing time while this setting can be
    *  set per reader.  When set to N, then one in every
    *  N*termIndexInterval terms in the index is loaded into
@@ -136,9 +135,10 @@ public abstract class DirectoryReader extends BaseCompositeReader<AtomicReader>
    *  implementations, including the default one in this release. It only makes
    *  sense for terms indexes that can efficiently re-sample terms at load time.
    * @throws IOException if there is a low-level IO error
+   * nocommit javadoc
    */
-  public static DirectoryReader open(final IndexCommit commit, int termInfosIndexDivisor) throws IOException {
-    return StandardDirectoryReader.open(commit.getDirectory(), commit, termInfosIndexDivisor);
+  public static DirectoryReader open(final IndexCommit commit, CodecSettings settings) throws IOException {
+    return StandardDirectoryReader.open(commit.getDirectory(), commit, settings);
   }
 
   /**
diff --git a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
index 705a42c..9009c80 100644
--- a/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
+++ b/lucene/core/src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
@@ -449,7 +449,7 @@ class DocumentsWriterPerThread {
     assert deleteSlice == null : "all deletes must be applied in prepareFlush";
     segmentInfo.setDocCount(numDocsInRAM);
     flushState = new SegmentWriteState(infoStream, directory, segmentInfo, fieldInfos.finish(),
-        writer.getConfig().getTermIndexInterval(),
+        writer.getConfig().getCodecSettings(),
         pendingDeletes, new IOContext(new FlushInfo(numDocsInRAM, bytesUsed())));
     final double startMBUsed = parent.flushControl.netBytes() / 1024. / 1024.;
 
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
index 04e61fb..4f0f2d6 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriter.java
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.index.FieldInfos.FieldNumbers;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.index.MergePolicy.MergeTrigger;
@@ -2336,7 +2337,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
    * call. Also, if the given readers are {@link DirectoryReader}s, they can be
    * opened with {@code termIndexInterval=-1} to save RAM, since during merge
    * the in-memory structure is not used. See
-   * {@link DirectoryReader#open(Directory, int)}.
+   * {@link DirectoryReader#open(Directory, CodecSettings)}.
    * 
    * <p>
    * <b>NOTE</b>: if you call {@link #close(boolean)} with <tt>false</tt>, which
@@ -2371,7 +2372,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
       SegmentInfo info = new SegmentInfo(directory, Constants.LUCENE_MAIN_VERSION, mergedName, -1,
                                          false, codec, null, null);
 
-      SegmentMerger merger = new SegmentMerger(info, infoStream, trackingDir, config.getTermIndexInterval(),
+      SegmentMerger merger = new SegmentMerger(info, infoStream, trackingDir, config.getCodecSettings(),
                                                MergeState.CheckAbort.NONE, globalFieldNumberMap, context);
 
       for (IndexReader reader : readers) {    // add new indexes
@@ -3541,7 +3542,7 @@ public class IndexWriter implements Closeable, TwoPhaseCommit {
     final MergeState.CheckAbort checkAbort = new MergeState.CheckAbort(merge, directory);
     final TrackingDirectoryWrapper dirWrapper = new TrackingDirectoryWrapper(directory);
 
-    SegmentMerger merger = new SegmentMerger(merge.info.info, infoStream, dirWrapper, config.getTermIndexInterval(), checkAbort,
+    SegmentMerger merger = new SegmentMerger(merge.info.info, infoStream, dirWrapper, config.getCodecSettings(), checkAbort,
                                              globalFieldNumberMap, context);
 
     if (infoStream.isEnabled("IW")) {
diff --git a/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java b/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java
index c773326..ebb1773 100644
--- a/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java
+++ b/lucene/core/src/java/org/apache/lucene/index/IndexWriterConfig.java
@@ -21,6 +21,7 @@ import java.io.PrintStream;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.index.DocumentsWriterPerThread.IndexingChain;
 import org.apache.lucene.index.IndexWriter.IndexReaderWarmer;
 import org.apache.lucene.search.IndexSearcher;
@@ -71,9 +72,6 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig implements Cl
     CREATE_OR_APPEND 
   }
 
-  /** Default value is 32. Change using {@link #setTermIndexInterval(int)}. */
-  public static final int DEFAULT_TERM_INDEX_INTERVAL = 32; // TODO: this should be private to the codec, not settable here
-
   /** Denotes a flush trigger is disabled. */
   public final static int DISABLE_AUTO_FLUSH = -1;
 
@@ -99,9 +97,6 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig implements Cl
   /** Default setting for {@link #setReaderPooling}. */
   public final static boolean DEFAULT_READER_POOLING = false;
 
-  /** Default value is 1. Change using {@link #setReaderTermsIndexDivisor(int)}. */
-  public static final int DEFAULT_READER_TERMS_INDEX_DIVISOR = DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR;
-
   /** Default value is 1945. Change using {@link #setRAMPerThreadHardLimitMB(int)} */
   public static final int DEFAULT_RAM_PER_THREAD_HARD_LIMIT_MB = 1945;
   
@@ -456,15 +451,6 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig implements Cl
     return super.getRAMBufferSizeMB();
   }
   
-  @Override
-  public int getReaderTermsIndexDivisor() {
-    return super.getReaderTermsIndexDivisor();
-  }
-  
-  @Override
-  public int getTermIndexInterval() {
-    return super.getTermIndexInterval();
-  }
   
   /** If non-null, information about merges, deletes and a
    * message when maxFieldLength is reached will be printed
@@ -505,13 +491,14 @@ public final class IndexWriterConfig extends LiveIndexWriterConfig implements Cl
   }
   
   @Override
-  public IndexWriterConfig setReaderTermsIndexDivisor(int divisor) {
-    return (IndexWriterConfig) super.setReaderTermsIndexDivisor(divisor);
+  public CodecSettings getCodecSettings() {
+    return super.getCodecSettings();
   }
-  
+
   @Override
-  public IndexWriterConfig setTermIndexInterval(int interval) {
-    return (IndexWriterConfig) super.setTermIndexInterval(interval);
+  public IndexWriterConfig setCodecSettings(CodecSettings settings) {
+    return  (IndexWriterConfig) super.setCodecSettings(settings);
   }
+  
 
 }
diff --git a/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java b/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java
index 9201642..4c8781f 100755
--- a/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java
+++ b/lucene/core/src/java/org/apache/lucene/index/LiveIndexWriterConfig.java
@@ -19,6 +19,8 @@ package org.apache.lucene.index;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
 import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat; // javadocs
 import org.apache.lucene.index.DocumentsWriterPerThread.IndexingChain;
 import org.apache.lucene.index.IndexWriter.IndexReaderWarmer;
@@ -41,9 +43,8 @@ public class LiveIndexWriterConfig {
   private volatile int maxBufferedDocs;
   private volatile double ramBufferSizeMB;
   private volatile int maxBufferedDeleteTerms;
-  private volatile int readerTermsIndexDivisor;
+  private volatile CodecSettings codecSettings;
   private volatile IndexReaderWarmer mergedSegmentWarmer;
-  private volatile int termIndexInterval; // TODO: this should be private to the codec, not settable here
 
   // modified by IndexWriterConfig
   /** {@link IndexDeletionPolicy} controlling when commit
@@ -97,6 +98,8 @@ public class LiveIndexWriterConfig {
 
   /** {@link Version} that {@link IndexWriter} should emulate. */
   protected final Version matchVersion;
+  
+  
 
   // used by IndexWriterConfig
   LiveIndexWriterConfig(Analyzer analyzer, Version matchVersion) {
@@ -105,9 +108,7 @@ public class LiveIndexWriterConfig {
     ramBufferSizeMB = IndexWriterConfig.DEFAULT_RAM_BUFFER_SIZE_MB;
     maxBufferedDocs = IndexWriterConfig.DEFAULT_MAX_BUFFERED_DOCS;
     maxBufferedDeleteTerms = IndexWriterConfig.DEFAULT_MAX_BUFFERED_DELETE_TERMS;
-    readerTermsIndexDivisor = IndexWriterConfig.DEFAULT_READER_TERMS_INDEX_DIVISOR;
     mergedSegmentWarmer = null;
-    termIndexInterval = IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL; // TODO: this should be private to the codec, not settable here
     delPolicy = new KeepOnlyLastCommitDeletionPolicy();
     commit = null;
     openMode = OpenMode.CREATE_OR_APPEND;
@@ -116,6 +117,7 @@ public class LiveIndexWriterConfig {
     writeLockTimeout = IndexWriterConfig.WRITE_LOCK_TIMEOUT;
     indexingChain = DocumentsWriterPerThread.defaultIndexingChain;
     codec = Codec.getDefault();
+    codecSettings = CodecSettings.defaults();
     infoStream = InfoStream.getDefault();
     mergePolicy = new TieredMergePolicy();
     flushPolicy = new FlushByRamOrCountsPolicy();
@@ -133,8 +135,6 @@ public class LiveIndexWriterConfig {
     maxBufferedDocs = config.getMaxBufferedDocs();
     mergedSegmentWarmer = config.getMergedSegmentWarmer();
     ramBufferSizeMB = config.getRAMBufferSizeMB();
-    readerTermsIndexDivisor = config.getReaderTermsIndexDivisor();
-    termIndexInterval = config.getTermIndexInterval();
     matchVersion = config.matchVersion;
     analyzer = config.getAnalyzer();
     delPolicy = config.getIndexDeletionPolicy();
@@ -151,6 +151,7 @@ public class LiveIndexWriterConfig {
     readerPooling = config.getReaderPooling();
     flushPolicy = config.getFlushPolicy();
     perThreadHardLimitMB = config.getRAMPerThreadHardLimitMB();
+    codecSettings = config.getCodecSettings();
   }
 
   /** Returns the default analyzer to use for indexing documents. */
@@ -159,69 +160,6 @@ public class LiveIndexWriterConfig {
   }
   
   /**
-   * Expert: set the interval between indexed terms. Large values cause less
-   * memory to be used by IndexReader, but slow random-access to terms. Small
-   * values cause more memory to be used by an IndexReader, and speed
-   * random-access to terms.
-   * <p>
-   * This parameter determines the amount of computation required per query
-   * term, regardless of the number of documents that contain that term. In
-   * particular, it is the maximum number of other terms that must be scanned
-   * before a term is located and its frequency and position information may be
-   * processed. In a large index with user-entered query terms, query processing
-   * time is likely to be dominated not by term lookup but rather by the
-   * processing of frequency and positional data. In a small index or when many
-   * uncommon query terms are generated (e.g., by wildcard queries) term lookup
-   * may become a dominant cost.
-   * <p>
-   * In particular, <code>numUniqueTerms/interval</code> terms are read into
-   * memory by an IndexReader, and, on average, <code>interval/2</code> terms
-   * must be scanned for each random term access.
-   * 
-   * <p>
-   * Takes effect immediately, but only applies to newly flushed/merged
-   * segments.
-   * 
-   * <p>
-   * <b>NOTE:</b> This parameter does not apply to all PostingsFormat implementations,
-   * including the default one in this release. It only makes sense for term indexes
-   * that are implemented as a fixed gap between terms. For example, 
-   * {@link Lucene41PostingsFormat} implements the term index instead based upon how
-   * terms share prefixes. To configure its parameters (the minimum and maximum size
-   * for a block), you would instead use  {@link Lucene41PostingsFormat#Lucene41PostingsFormat(int, int)}.
-   * which can also be configured on a per-field basis:
-   * <pre class="prettyprint">
-   * //customize Lucene41PostingsFormat, passing minBlockSize=50, maxBlockSize=100
-   * final PostingsFormat tweakedPostings = new Lucene41PostingsFormat(50, 100);
-   * iwc.setCodec(new Lucene41Codec() {
-   *   &#64;Override
-   *   public PostingsFormat getPostingsFormatForField(String field) {
-   *     if (field.equals("fieldWithTonsOfTerms"))
-   *       return tweakedPostings;
-   *     else
-   *       return super.getPostingsFormatForField(field);
-   *   }
-   * });
-   * </pre>
-   * Note that other implementations may have their own parameters, or no parameters at all.
-   * 
-   * @see IndexWriterConfig#DEFAULT_TERM_INDEX_INTERVAL
-   */
-  public LiveIndexWriterConfig setTermIndexInterval(int interval) { // TODO: this should be private to the codec, not settable here
-    this.termIndexInterval = interval;
-    return this;
-  }
-
-  /**
-   * Returns the interval between indexed terms.
-   *
-   * @see #setTermIndexInterval(int)
-   */
-  public int getTermIndexInterval() { // TODO: this should be private to the codec, not settable here
-    return termIndexInterval;
-  }
-
-  /**
    * Determines the minimal number of delete terms required before the buffered
    * in-memory delete terms and queries are applied and flushed.
    * <p>
@@ -383,37 +321,6 @@ public class LiveIndexWriterConfig {
     return mergedSegmentWarmer;
   }
 
-  /**
-   * Sets the termsIndexDivisor passed to any readers that IndexWriter opens,
-   * for example when applying deletes or creating a near-real-time reader in
-   * {@link DirectoryReader#open(IndexWriter, boolean)}. If you pass -1, the
-   * terms index won't be loaded by the readers. This is only useful in advanced
-   * situations when you will only .next() through all terms; attempts to seek
-   * will hit an exception.
-   * 
-   * <p>
-   * Takes effect immediately, but only applies to readers opened after this
-   * call
-   * <p>
-   * <b>NOTE:</b> divisor settings &gt; 1 do not apply to all PostingsFormat
-   * implementations, including the default one in this release. It only makes
-   * sense for terms indexes that can efficiently re-sample terms at load time.
-   */
-  public LiveIndexWriterConfig setReaderTermsIndexDivisor(int divisor) {
-    if (divisor <= 0 && divisor != -1) {
-      throw new IllegalArgumentException("divisor must be >= 1, or -1 (got " + divisor + ")");
-    }
-    readerTermsIndexDivisor = divisor;
-    return this;
-  }
-
-  /** Returns the {@code termInfosIndexDivisor}.
-   * 
-   * @see #setReaderTermsIndexDivisor(int) */
-  public int getReaderTermsIndexDivisor() {
-    return readerTermsIndexDivisor;
-  }
-  
   /** Returns the {@link OpenMode} set by {@link IndexWriterConfig#setOpenMode(OpenMode)}. */
   public OpenMode getOpenMode() {
     return openMode;
@@ -539,6 +446,18 @@ public class LiveIndexWriterConfig {
     return infoStream;
   }
   
+  public LiveIndexWriterConfig setCodecSettings(CodecSettings settings) {
+    if (settings == null) {
+      throw new IllegalArgumentException("setting must not be null");
+    }
+    codecSettings = settings;
+    return this;
+  }
+  
+  public CodecSettings getCodecSettings() {
+    return codecSettings;
+  }
+  
   @Override
   public String toString() {
     StringBuilder sb = new StringBuilder();
@@ -548,8 +467,6 @@ public class LiveIndexWriterConfig {
     sb.append("maxBufferedDocs=").append(getMaxBufferedDocs()).append("\n");
     sb.append("maxBufferedDeleteTerms=").append(getMaxBufferedDeleteTerms()).append("\n");
     sb.append("mergedSegmentWarmer=").append(getMergedSegmentWarmer()).append("\n");
-    sb.append("readerTermsIndexDivisor=").append(getReaderTermsIndexDivisor()).append("\n");
-    sb.append("termIndexInterval=").append(getTermIndexInterval()).append("\n"); // TODO: this should be private to the codec, not settable here
     sb.append("delPolicy=").append(getIndexDeletionPolicy().getClass().getName()).append("\n");
     IndexCommit commit = getIndexCommit();
     sb.append("commit=").append(commit == null ? "null" : commit).append("\n");
diff --git a/lucene/core/src/java/org/apache/lucene/index/ReadersAndLiveDocs.java b/lucene/core/src/java/org/apache/lucene/index/ReadersAndLiveDocs.java
index e5a2468..f82fa81 100644
--- a/lucene/core/src/java/org/apache/lucene/index/ReadersAndLiveDocs.java
+++ b/lucene/core/src/java/org/apache/lucene/index/ReadersAndLiveDocs.java
@@ -20,6 +20,8 @@ package org.apache.lucene.index;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
 import org.apache.lucene.codecs.LiveDocsFormat;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
@@ -117,7 +119,7 @@ class ReadersAndLiveDocs {
 
     if (reader == null) {
       // We steal returned ref:
-      reader = new SegmentReader(info, writer.getConfig().getReaderTermsIndexDivisor(), context);
+      reader = new SegmentReader(info, writer.getConfig().getCodecSettings(), context);
       if (liveDocs == null) {
         liveDocs = reader.getLiveDocs();
       }
@@ -149,7 +151,12 @@ class ReadersAndLiveDocs {
       } else {
         //System.out.println(Thread.currentThread().getName() + ": getMergeReader seg=" + info.name);
         // We steal returned ref:
-        mergeReader = new SegmentReader(info, -1, context);
+        // nocommit - we need to tell the reader to not load the term index if it can here!
+        SettingsBuilder builder = CodecSettings.builder(writer.getConfig().getCodecSettings());
+        builder.put(CodecSettings.LOAD_TERM_INDEX, false);
+        CodecSettings build = builder.build();
+        System.out.println(build);
+        mergeReader = new SegmentReader(info, builder.build(), context);
         if (liveDocs == null) {
           liveDocs = mergeReader.getLiveDocs();
         }
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java b/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java
index 92a33d2..f9bc8c8 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentCoreReaders.java
@@ -24,6 +24,7 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PerDocProducer;
 import org.apache.lucene.codecs.PostingsFormat;
@@ -54,13 +55,13 @@ final class SegmentCoreReaders {
   final PerDocProducer perDocProducer;
   final PerDocProducer norms;
 
-  final int termsIndexDivisor;
-  
   private final SegmentReader owner;
   
   final StoredFieldsReader fieldsReaderOrig;
   final TermVectorsReader termVectorsReaderOrig;
   final CompoundFileDirectory cfsReader;
+  final CodecSettings codecSettings;
+
 
   final CloseableThreadLocal<StoredFieldsReader> fieldsReaderLocal = new CloseableThreadLocal<StoredFieldsReader>() {
     @Override
@@ -80,12 +81,8 @@ final class SegmentCoreReaders {
   private final Set<CoreClosedListener> coreClosedListeners = 
       Collections.synchronizedSet(new LinkedHashSet<CoreClosedListener>());
   
-  SegmentCoreReaders(SegmentReader owner, Directory dir, SegmentInfoPerCommit si, IOContext context, int termsIndexDivisor) throws IOException {
-    
-    if (termsIndexDivisor == 0) {
-      throw new IllegalArgumentException("indexDivisor must be < 0 (don't load terms index) or greater than 0 (got 0)");
-    }
-    
+  SegmentCoreReaders(SegmentReader owner, Directory dir, SegmentInfoPerCommit si, IOContext context, CodecSettings codecSettings) throws IOException {
+    this.codecSettings = codecSettings;
     final Codec codec = si.info.getCodec();
     final Directory cfsDir; // confusing name: if (cfs) its the cfsdir, otherwise its the segment's directory.
 
@@ -100,9 +97,8 @@ final class SegmentCoreReaders {
       }
       fieldInfos = codec.fieldInfosFormat().getFieldInfosReader().read(cfsDir, si.info.name, IOContext.READONCE);
 
-      this.termsIndexDivisor = termsIndexDivisor;
       final PostingsFormat format = codec.postingsFormat();
-      final SegmentReadState segmentReadState = new SegmentReadState(cfsDir, si.info, fieldInfos, context, termsIndexDivisor);
+      final SegmentReadState segmentReadState = new SegmentReadState(cfsDir, si.info, fieldInfos, context, codecSettings);
       // Ask codec for its Fields
       fields = format.fieldsProducer(segmentReadState);
       assert fields != null;
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java b/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java
index cd1a616..75d170f 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentMerger.java
@@ -24,6 +24,7 @@ import java.util.List;
 import java.util.Map;
 
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.FieldInfosWriter;
 import org.apache.lucene.codecs.FieldsConsumer;
 import org.apache.lucene.codecs.PerDocConsumer;
@@ -45,7 +46,7 @@ import org.apache.lucene.util.InfoStream;
  */
 final class SegmentMerger {
   private final Directory directory;
-  private final int termIndexInterval;
+  private final CodecSettings codecSettings;
 
   private final Codec codec;
   
@@ -55,14 +56,14 @@ final class SegmentMerger {
   private final FieldInfos.Builder fieldInfosBuilder;
 
   // note, just like in codec apis Directory 'dir' is NOT the same as segmentInfo.dir!!
-  SegmentMerger(SegmentInfo segmentInfo, InfoStream infoStream, Directory dir, int termIndexInterval,
+  SegmentMerger(SegmentInfo segmentInfo, InfoStream infoStream, Directory dir, CodecSettings codecSettings,
                 MergeState.CheckAbort checkAbort, FieldInfos.FieldNumbers fieldNumbers, IOContext context) {
     mergeState.segmentInfo = segmentInfo;
     mergeState.infoStream = infoStream;
     mergeState.readers = new ArrayList<AtomicReader>();
     mergeState.checkAbort = checkAbort;
     directory = dir;
-    this.termIndexInterval = termIndexInterval;
+    this.codecSettings = codecSettings;
     this.codec = segmentInfo.getCodec();
     this.context = context;
     this.fieldInfosBuilder = new FieldInfos.Builder(fieldNumbers);
@@ -103,7 +104,7 @@ final class SegmentMerger {
     assert numMerged == mergeState.segmentInfo.getDocCount();
 
     final SegmentWriteState segmentWriteState = new SegmentWriteState(mergeState.infoStream, directory, mergeState.segmentInfo,
-                                                                      mergeState.fieldInfos, termIndexInterval, null, context);
+                                                                      mergeState.fieldInfos, codecSettings, null, context);
     mergeTerms(segmentWriteState);
     mergePerDoc(segmentWriteState);
     
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentReadState.java b/lucene/core/src/java/org/apache/lucene/index/SegmentReadState.java
index 74d3073..c037caa 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentReadState.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentReadState.java
@@ -17,6 +17,7 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.PostingsFormat; // javadocs
 import org.apache.lucene.codecs.perfield.PerFieldPostingsFormat; // javadocs
 import org.apache.lucene.store.Directory;
@@ -41,16 +42,8 @@ public class SegmentReadState {
    *  Directory#openInput(String,IOContext)}. */
   public final IOContext context;
 
-  /** The {@code termInfosIndexDivisor} to use, if
-   *  appropriate (not all {@link PostingsFormat}s support
-   *  it; in particular the current default does not).
-   *
-   * <p>  NOTE: if this is &lt; 0, that means "defer terms index
-   *  load until needed".  But if the codec must load the
-   *  terms index on init (preflex is the only once currently
-   *  that must do so), then it should negate this value to
-   *  get the app's terms divisor */
-  public int termsIndexDivisor;
+  // nocommit javadocs
+  public final CodecSettings codecSettings;
 
   /** Unique suffix for any postings files read for this
    *  segment.  {@link PerFieldPostingsFormat} sets this for
@@ -62,8 +55,8 @@ public class SegmentReadState {
 
   /** Create a {@code SegmentReadState}. */
   public SegmentReadState(Directory dir, SegmentInfo info,
-      FieldInfos fieldInfos, IOContext context, int termsIndexDivisor) {
-    this(dir, info, fieldInfos,  context, termsIndexDivisor, "");
+      FieldInfos fieldInfos, IOContext context, CodecSettings codecSettings) {
+    this(dir, info, fieldInfos,  context, codecSettings, "");
   }
   
   /** Create a {@code SegmentReadState}. */
@@ -71,13 +64,13 @@ public class SegmentReadState {
                           SegmentInfo info,
                           FieldInfos fieldInfos,
                           IOContext context,
-                          int termsIndexDivisor,
+                          CodecSettings codecSettings,
                           String segmentSuffix) {
     this.dir = dir;
     this.segmentInfo = info;
     this.fieldInfos = fieldInfos;
     this.context = context;
-    this.termsIndexDivisor = termsIndexDivisor;
+    this.codecSettings = codecSettings;
     this.segmentSuffix = segmentSuffix;
   }
 
@@ -88,7 +81,7 @@ public class SegmentReadState {
     this.segmentInfo = other.segmentInfo;
     this.fieldInfos = other.fieldInfos;
     this.context = other.context;
-    this.termsIndexDivisor = other.termsIndexDivisor;
+    this.codecSettings = other.codecSettings;
     this.segmentSuffix = newSegmentSuffix;
   }
 }
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java b/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
index 221b853..625db05 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentReader.java
@@ -20,6 +20,7 @@ package org.apache.lucene.index;
 import java.io.IOException;
 
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.PerDocProducer;
 import org.apache.lucene.codecs.StoredFieldsReader;
 import org.apache.lucene.codecs.TermVectorsReader;
@@ -52,9 +53,9 @@ public final class SegmentReader extends AtomicReader {
    * @throws IOException if there is a low-level IO error
    */
   // TODO: why is this public?
-  public SegmentReader(SegmentInfoPerCommit si, int termInfosIndexDivisor, IOContext context) throws IOException {
+  public SegmentReader(SegmentInfoPerCommit si, CodecSettings codecSettings, IOContext context) throws IOException {
     this.si = si;
-    core = new SegmentCoreReaders(this, si.info.dir, si, context, termInfosIndexDivisor);
+    core = new SegmentCoreReaders(this, si.info.dir, si, context, codecSettings);
     boolean success = false;
     try {
       if (si.hasDeletions()) {
@@ -219,12 +220,6 @@ public final class SegmentReader extends AtomicReader {
     return this;
   }
 
-  /** Returns term infos index divisor originally passed to
-   *  {@link #SegmentReader(SegmentInfoPerCommit, int, IOContext)}. */
-  public int getTermInfosIndexDivisor() {
-    return core.termsIndexDivisor;
-  }
-  
   @Override
   public DocValues docValues(String field) throws IOException {
     ensureOpen();
@@ -276,4 +271,8 @@ public final class SegmentReader extends AtomicReader {
     ensureOpen();
     core.removeCoreClosedListener(listener);
   }
+  
+  CodecSettings getCodecSetting() {
+    return core.codecSettings;
+  }
 }
diff --git a/lucene/core/src/java/org/apache/lucene/index/SegmentWriteState.java b/lucene/core/src/java/org/apache/lucene/index/SegmentWriteState.java
index ed390c0..9fcefe7 100644
--- a/lucene/core/src/java/org/apache/lucene/index/SegmentWriteState.java
+++ b/lucene/core/src/java/org/apache/lucene/index/SegmentWriteState.java
@@ -17,6 +17,7 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.PostingsFormat; // javadocs
 import org.apache.lucene.codecs.perfield.PerFieldPostingsFormat; // javadocs
 import org.apache.lucene.store.Directory;
@@ -67,12 +68,8 @@ public class SegmentWriteState {
    *  {@link IndexFileNames#segmentFileName(String,String,String)}). */
   public final String segmentSuffix;
 
-  /** Expert: The fraction of terms in the "dictionary" which should be stored
-   * in RAM.  Smaller values use more memory, but make searching slightly
-   * faster, while larger values use less memory and make searching slightly
-   * slower.  Searching is typically not dominated by dictionary lookup, so
-   * tweaking this is rarely useful.*/
-  public int termIndexInterval;                   // TODO: this should be private to the codec, not settable here or in IWC
+  // nocommit - javadoc
+  public final CodecSettings codecSettings;
   
   /** {@link IOContext} for all writes; you should pass this
    *  to {@link Directory#createOutput(String,IOContext)}. */
@@ -80,13 +77,13 @@ public class SegmentWriteState {
 
   /** Sole constructor. */
   public SegmentWriteState(InfoStream infoStream, Directory directory, SegmentInfo segmentInfo, FieldInfos fieldInfos,
-      int termIndexInterval, BufferedDeletes segDeletes, IOContext context) {
+      CodecSettings codecSettings, BufferedDeletes segDeletes, IOContext context) {
     this.infoStream = infoStream;
     this.segDeletes = segDeletes;
     this.directory = directory;
     this.segmentInfo = segmentInfo;
     this.fieldInfos = fieldInfos;
-    this.termIndexInterval = termIndexInterval;
+    this.codecSettings = codecSettings;
     segmentSuffix = "";
     this.context = context;
   }
@@ -99,7 +96,7 @@ public class SegmentWriteState {
     directory = state.directory;
     segmentInfo = state.segmentInfo;
     fieldInfos = state.fieldInfos;
-    termIndexInterval = state.termIndexInterval;
+    codecSettings = state.codecSettings;
     context = state.context;
     this.segmentSuffix = segmentSuffix;
     segDeletes = state.segDeletes;
diff --git a/lucene/core/src/java/org/apache/lucene/index/StandardDirectoryReader.java b/lucene/core/src/java/org/apache/lucene/index/StandardDirectoryReader.java
index 2debf37..8d71310 100644
--- a/lucene/core/src/java/org/apache/lucene/index/StandardDirectoryReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/StandardDirectoryReader.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.util.IOUtils;
@@ -33,22 +34,22 @@ final class StandardDirectoryReader extends DirectoryReader {
 
   private final IndexWriter writer;
   private final SegmentInfos segmentInfos;
-  private final int termInfosIndexDivisor;
+  private final CodecSettings codecSettings;
   private final boolean applyAllDeletes;
   
   /** called only from static open() methods */
   StandardDirectoryReader(Directory directory, AtomicReader[] readers, IndexWriter writer,
-    SegmentInfos sis, int termInfosIndexDivisor, boolean applyAllDeletes) {
+    SegmentInfos sis, CodecSettings codecSettings, boolean applyAllDeletes) {
     super(directory, readers);
     this.writer = writer;
     this.segmentInfos = sis;
-    this.termInfosIndexDivisor = termInfosIndexDivisor;
+    this.codecSettings = codecSettings;
     this.applyAllDeletes = applyAllDeletes;
   }
 
   /** called from DirectoryReader.open(...) methods */
   static DirectoryReader open(final Directory directory, final IndexCommit commit,
-                          final int termInfosIndexDivisor) throws IOException {
+                          final CodecSettings codecSettings) throws IOException {
     return (DirectoryReader) new SegmentInfos.FindSegmentsFile(directory) {
       @Override
       protected Object doBody(String segmentFileName) throws IOException {
@@ -59,7 +60,7 @@ final class StandardDirectoryReader extends DirectoryReader {
           IOException prior = null;
           boolean success = false;
           try {
-            readers[i] = new SegmentReader(sis.info(i), termInfosIndexDivisor, IOContext.READ);
+            readers[i] = new SegmentReader(sis.info(i), codecSettings, IOContext.READ);
             success = true;
           } catch(IOException ex) {
             prior = ex;
@@ -68,7 +69,7 @@ final class StandardDirectoryReader extends DirectoryReader {
               IOUtils.closeWhileHandlingException(prior, readers);
           }
         }
-        return new StandardDirectoryReader(directory, readers, null, sis, termInfosIndexDivisor, false);
+        return new StandardDirectoryReader(directory, readers, null, sis, codecSettings, false);
       }
     }.run(commit);
   }
@@ -115,12 +116,12 @@ final class StandardDirectoryReader extends DirectoryReader {
       }
     }
     return new StandardDirectoryReader(dir, readers.toArray(new SegmentReader[readers.size()]),
-      writer, segmentInfos, writer.getConfig().getReaderTermsIndexDivisor(), applyAllDeletes);
+      writer, segmentInfos, writer.getConfig().getCodecSettings(), applyAllDeletes);
   }
 
   /** This constructor is only used for {@link #doOpenIfChanged(SegmentInfos, IndexWriter)} */
   private static DirectoryReader open(Directory directory, IndexWriter writer, SegmentInfos infos, List<? extends AtomicReader> oldReaders,
-    int termInfosIndexDivisor) throws IOException {
+    CodecSettings codecSettings) throws IOException {
     // we put the old SegmentReaders in a map, that allows us
     // to lookup a reader using its segment name
     final Map<String,Integer> segmentReaders = new HashMap<String,Integer>();
@@ -157,7 +158,7 @@ final class StandardDirectoryReader extends DirectoryReader {
         if (newReaders[i] == null || infos.info(i).info.getUseCompoundFile() != newReaders[i].getSegmentInfo().info.getUseCompoundFile()) {
 
           // this is a new reader; in case we hit an exception we can close it safely
-          newReader = new SegmentReader(infos.info(i), termInfosIndexDivisor, IOContext.READ);
+          newReader = new SegmentReader(infos.info(i), codecSettings, IOContext.READ);
           readerShared[i] = false;
           newReaders[i] = newReader;
         } else {
@@ -207,7 +208,7 @@ final class StandardDirectoryReader extends DirectoryReader {
         }
       }
     }    
-    return new StandardDirectoryReader(directory, newReaders, writer, infos, termInfosIndexDivisor, false);
+    return new StandardDirectoryReader(directory, newReaders, writer, infos, codecSettings, false);
   }
 
   @Override
@@ -304,7 +305,7 @@ final class StandardDirectoryReader extends DirectoryReader {
   }
 
   DirectoryReader doOpenIfChanged(SegmentInfos infos, IndexWriter writer) throws IOException {
-    return StandardDirectoryReader.open(directory, writer, infos, getSequentialSubReaders(), termInfosIndexDivisor);
+    return StandardDirectoryReader.open(directory, writer, infos, getSequentialSubReaders(), codecSettings);
   }
 
   @Override
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java b/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java
index 582e774..f6d4b79 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/perfield/TestPerFieldPostingsFormat2.java
@@ -192,7 +192,7 @@ public class TestPerFieldPostingsFormat2 extends LuceneTestCase {
     if (VERBOSE) {
       System.out.println("\nTEST: assertQuery " + t);
     }
-    IndexReader reader = DirectoryReader.open(dir, 1);
+    IndexReader reader = DirectoryReader.open(dir);
     IndexSearcher searcher = newSearcher(reader);
     TopDocs search = searcher.search(new TermQuery(t), num + 10);
     assertEquals(num, search.totalHits);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java b/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java
index b2f41dd..353df88 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestCodecs.java
@@ -24,6 +24,7 @@ import java.util.Iterator;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.FieldsConsumer;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PostingsConsumer;
@@ -257,7 +258,7 @@ public class TestCodecs extends LuceneTestCase {
     Codec codec = Codec.getDefault();
     final SegmentInfo si = new SegmentInfo(dir, Constants.LUCENE_MAIN_VERSION, SEGMENT, 10000, false, codec, null, null);
 
-    final FieldsProducer reader = codec.postingsFormat().fieldsProducer(new SegmentReadState(dir, si, fieldInfos, newIOContext(random()), DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR));
+    final FieldsProducer reader = codec.postingsFormat().fieldsProducer(new SegmentReadState(dir, si, fieldInfos, newIOContext(random()), CodecSettings.defaults()));
 
     final Iterator<String> fieldsEnum = reader.iterator();
     String fieldName = fieldsEnum.next();
@@ -318,7 +319,7 @@ public class TestCodecs extends LuceneTestCase {
     if (VERBOSE) {
       System.out.println("TEST: now read postings");
     }
-    final FieldsProducer terms = codec.postingsFormat().fieldsProducer(new SegmentReadState(dir, si, fieldInfos, newIOContext(random()), DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR));
+    final FieldsProducer terms = codec.postingsFormat().fieldsProducer(new SegmentReadState(dir, si, fieldInfos, newIOContext(random()), CodecSettings.defaults()));
 
     final Verify[] threads = new Verify[NUM_TEST_THREADS-1];
     for(int i=0;i<NUM_TEST_THREADS-1;i++) {
@@ -616,10 +617,9 @@ public class TestCodecs extends LuceneTestCase {
 
   private void write(final FieldInfos fieldInfos, final Directory dir, final FieldData[] fields) throws Throwable {
 
-    final int termIndexInterval = _TestUtil.nextInt(random(), 13, 27);
     final Codec codec = Codec.getDefault();
     final SegmentInfo si = new SegmentInfo(dir, Constants.LUCENE_MAIN_VERSION, SEGMENT, 10000, false, codec, null, null);
-    final SegmentWriteState state = new SegmentWriteState(InfoStream.getDefault(), dir, si, fieldInfos, termIndexInterval, null, newIOContext(random()));
+    final SegmentWriteState state = new SegmentWriteState(InfoStream.getDefault(), dir, si, fieldInfos, newCodecSettings(random()), null, newIOContext(random()));
 
     final FieldsConsumer consumer = codec.postingsFormat().fieldsConsumer(state);
     Arrays.sort(fields);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
index ee1ff1c..9a05f2f 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
@@ -131,6 +131,8 @@ public class TestConcurrentMergeScheduler extends LuceneTestCase {
     IndexWriter writer = new IndexWriter(directory, newIndexWriterConfig(
         TEST_VERSION_CURRENT, new MockAnalyzer(random()))
         .setMergePolicy(mp));
+    
+    System.out.println(writer.getConfig().getCodecSettings());
 
     Document doc = new Document();
     Field idField = newStringField("id", "", Field.Store.YES);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java b/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
index 0881914..5e72c1c 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestDirectoryReader.java
@@ -28,6 +28,9 @@ import java.util.Random;
 import java.util.Set;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexReader;
 import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -835,8 +838,9 @@ public void testFilesOpenClose() throws IOException {
     writer.addDocument(doc);
     writer.addDocument(doc);
     writer.close();
-  
-    DirectoryReader r = DirectoryReader.open(dir, -1);
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(CodecSettings.LOAD_TERM_INDEX, false);
+    DirectoryReader r = DirectoryReader.open(dir, builder.build());
     try {
       r.docFreq(new Term("field", "f"));
       fail("did not hit expected exception");
@@ -844,7 +848,7 @@ public void testFilesOpenClose() throws IOException {
       // expected
     }
   
-    assertEquals(-1, ((SegmentReader) r.leaves().get(0).reader()).getTermInfosIndexDivisor());
+    assertFalse(((SegmentReader) r.leaves().get(0).reader()).getCodecSetting().getAsBoolean(CodecSettings.LOAD_TERM_INDEX, true));
     writer = new IndexWriter(
         dir,
         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())).
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDoc.java b/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
index db78ffd..06cf652 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestDoc.java
@@ -31,6 +31,7 @@ import java.util.LinkedList;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
@@ -211,14 +212,14 @@ public class TestDoc extends LuceneTestCase {
    private SegmentInfoPerCommit merge(Directory dir, SegmentInfoPerCommit si1, SegmentInfoPerCommit si2, String merged, boolean useCompoundFile)
    throws Exception {
       IOContext context = newIOContext(random());
-      SegmentReader r1 = new SegmentReader(si1, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, context);
-      SegmentReader r2 = new SegmentReader(si2, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, context);
+      SegmentReader r1 = new SegmentReader(si1, CodecSettings.defaults(), context);
+      SegmentReader r2 = new SegmentReader(si2, CodecSettings.defaults(), context);
 
       final Codec codec = Codec.getDefault();
       TrackingDirectoryWrapper trackingDir = new TrackingDirectoryWrapper(si1.info.dir);
       final SegmentInfo si = new SegmentInfo(si1.info.dir, Constants.LUCENE_MAIN_VERSION, merged, -1, false, codec, null, null);
 
-      SegmentMerger merger = new SegmentMerger(si, InfoStream.getDefault(), trackingDir, IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL,
+      SegmentMerger merger = new SegmentMerger(si, InfoStream.getDefault(), trackingDir, CodecSettings.defaults(),
                                                MergeState.CheckAbort.NONE, new FieldInfos.FieldNumbers(), context);
 
       merger.add(r1);
@@ -245,7 +246,7 @@ public class TestDoc extends LuceneTestCase {
 
    private void printSegment(PrintWriter out, SegmentInfoPerCommit si)
    throws Exception {
-      SegmentReader reader = new SegmentReader(si, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+      SegmentReader reader = new SegmentReader(si, CodecSettings.defaults(), newIOContext(random()));
 
       for (int i = 0; i < reader.numDocs(); i++)
         out.println(reader.document(i));
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java b/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
index 68d5d69..1a49fd0 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestDocValuesIndexing.java
@@ -90,7 +90,7 @@ public class TestDocValuesIndexing extends LuceneTestCase {
 
     writer.close(true);
 
-    DirectoryReader reader = DirectoryReader.open(dir, 1);
+    DirectoryReader reader = DirectoryReader.open(dir);
     assertEquals(1, reader.leaves().size());
 
     IndexSearcher searcher = new IndexSearcher(reader);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestDocumentWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestDocumentWriter.java
index 203ea5c..db1f49c 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestDocumentWriter.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestDocumentWriter.java
@@ -24,6 +24,7 @@ import org.apache.lucene.analysis.*;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
@@ -65,7 +66,7 @@ public class TestDocumentWriter extends LuceneTestCase {
     SegmentInfoPerCommit info = writer.newestSegment();
     writer.close();
     //After adding the document, we should be able to read it back in
-    SegmentReader reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+    SegmentReader reader = new SegmentReader(info,  CodecSettings.defaults(), newIOContext(random()));
     assertTrue(reader != null);
     StoredDocument doc = reader.document(0);
     assertTrue(doc != null);
@@ -126,7 +127,7 @@ public class TestDocumentWriter extends LuceneTestCase {
     writer.commit();
     SegmentInfoPerCommit info = writer.newestSegment();
     writer.close();
-    SegmentReader reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+    SegmentReader reader = new SegmentReader(info,  CodecSettings.defaults(), newIOContext(random()));
 
     DocsAndPositionsEnum termPositions = MultiFields.getTermPositionsEnum(reader, MultiFields.getLiveDocs(reader),
                                                                           "repeated", new BytesRef("repeated"));
@@ -198,7 +199,7 @@ public class TestDocumentWriter extends LuceneTestCase {
     writer.commit();
     SegmentInfoPerCommit info = writer.newestSegment();
     writer.close();
-    SegmentReader reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+    SegmentReader reader = new SegmentReader(info,  CodecSettings.defaults(), newIOContext(random()));
 
     DocsAndPositionsEnum termPositions = MultiFields.getTermPositionsEnum(reader, reader.getLiveDocs(), "f1", new BytesRef("a"));
     assertTrue(termPositions.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
@@ -241,7 +242,7 @@ public class TestDocumentWriter extends LuceneTestCase {
     writer.commit();
     SegmentInfoPerCommit info = writer.newestSegment();
     writer.close();
-    SegmentReader reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+    SegmentReader reader = new SegmentReader(info,  CodecSettings.defaults(), newIOContext(random()));
 
     DocsAndPositionsEnum termPositions = reader.termPositionsEnum(new Term("preanalyzed", "term1"));
     assertTrue(termPositions.nextDoc() != DocIdSetIterator.NO_MORE_DOCS);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
index aba4965..b1f512c 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriter.java
@@ -30,6 +30,9 @@ import org.apache.lucene.analysis.*;
 import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
 import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexWriter;
 import org.apache.lucene.codecs.simpletext.SimpleTextCodec;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
@@ -1240,7 +1243,9 @@ public class TestIndexWriter extends LuceneTestCase {
   public void testIndexDivisor() throws Exception {
     Directory dir = newDirectory();
     IndexWriterConfig config = new IndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
-    config.setTermIndexInterval(2);
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, 2);
+    config.setCodecSettings(builder.build());
     IndexWriter w = new IndexWriter(dir, config);
     StringBuilder s = new StringBuilder();
     // must be > 256
@@ -1639,8 +1644,9 @@ public class TestIndexWriter extends LuceneTestCase {
   public void testEmptyFieldNameTIIOne() throws IOException {
     Directory dir = newDirectory();
     IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
-    iwc.setTermIndexInterval(1);
-    iwc.setReaderTermsIndexDivisor(1);
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, 1);
+    iwc.setCodecSettings(builder.build());
     IndexWriter writer = new IndexWriter(dir, iwc);
     Document doc = new Document();
     doc.add(newTextField("", "a b c", Field.Store.NO));
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
index 093d3b6..cef1154 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterConfig.java
@@ -25,6 +25,7 @@ import java.util.Set;
 
 import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.index.DocumentsWriterPerThread.IndexingChain;
@@ -62,7 +63,6 @@ public class TestIndexWriterConfig extends LuceneTestCase {
     assertEquals(OpenMode.CREATE_OR_APPEND, conf.getOpenMode());
     // we don't need to assert this, it should be unspecified
     assertTrue(IndexSearcher.getDefaultSimilarity() == conf.getSimilarity());
-    assertEquals(IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL, conf.getTermIndexInterval());
     assertEquals(IndexWriterConfig.getDefaultWriteLockTimeout(), conf.getWriteLockTimeout());
     assertEquals(IndexWriterConfig.WRITE_LOCK_TIMEOUT, IndexWriterConfig.getDefaultWriteLockTimeout());
     assertEquals(IndexWriterConfig.DEFAULT_MAX_BUFFERED_DELETE_TERMS, conf.getMaxBufferedDeleteTerms());
@@ -71,7 +71,7 @@ public class TestIndexWriterConfig extends LuceneTestCase {
     assertEquals(IndexWriterConfig.DEFAULT_READER_POOLING, conf.getReaderPooling());
     assertTrue(DocumentsWriterPerThread.defaultIndexingChain == conf.getIndexingChain());
     assertNull(conf.getMergedSegmentWarmer());
-    assertEquals(IndexWriterConfig.DEFAULT_READER_TERMS_INDEX_DIVISOR, conf.getReaderTermsIndexDivisor());
+    assertEquals(CodecSettings.defaults(), conf.getCodecSettings());
     assertEquals(TieredMergePolicy.class, conf.getMergePolicy().getClass());
     assertEquals(ThreadAffinityDocumentsWriterThreadPool.class, conf.getIndexerThreadPool().getClass());
     assertEquals(FlushByRamOrCountsPolicy.class, conf.getFlushPolicy().getClass());
@@ -87,7 +87,6 @@ public class TestIndexWriterConfig extends LuceneTestCase {
     getters.add("getMergeScheduler");
     getters.add("getOpenMode");
     getters.add("getSimilarity");
-    getters.add("getTermIndexInterval");
     getters.add("getWriteLockTimeout");
     getters.add("getDefaultWriteLockTimeout");
     getters.add("getMaxBufferedDeleteTerms");
@@ -99,11 +98,11 @@ public class TestIndexWriterConfig extends LuceneTestCase {
     getters.add("getMaxThreadStates");
     getters.add("getReaderPooling");
     getters.add("getIndexerThreadPool");
-    getters.add("getReaderTermsIndexDivisor");
     getters.add("getFlushPolicy");
     getters.add("getRAMPerThreadHardLimitMB");
     getters.add("getCodec");
     getters.add("getInfoStream");
+    getters.add("getCodecSettings");
     
     for (Method m : IndexWriterConfig.class.getDeclaredMethods()) {
       if (m.getDeclaringClass() == IndexWriterConfig.class && m.getName().startsWith("get")) {
@@ -182,13 +181,11 @@ public class TestIndexWriterConfig extends LuceneTestCase {
   public void testConstants() throws Exception {
     // Tests that the values of the constants does not change
     assertEquals(1000, IndexWriterConfig.WRITE_LOCK_TIMEOUT);
-    assertEquals(32, IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL);
     assertEquals(-1, IndexWriterConfig.DISABLE_AUTO_FLUSH);
     assertEquals(IndexWriterConfig.DISABLE_AUTO_FLUSH, IndexWriterConfig.DEFAULT_MAX_BUFFERED_DELETE_TERMS);
     assertEquals(IndexWriterConfig.DISABLE_AUTO_FLUSH, IndexWriterConfig.DEFAULT_MAX_BUFFERED_DOCS);
     assertEquals(16.0, IndexWriterConfig.DEFAULT_RAM_BUFFER_SIZE_MB, 0.0);
     assertEquals(false, IndexWriterConfig.DEFAULT_READER_POOLING);
-    assertEquals(DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, IndexWriterConfig.DEFAULT_READER_TERMS_INDEX_DIVISOR);
   }
 
   @Test
@@ -289,23 +286,6 @@ public class TestIndexWriterConfig extends LuceneTestCase {
       // this is expected
     }
 
-    // Test setReaderTermsIndexDivisor
-    try {
-      conf.setReaderTermsIndexDivisor(0);
-      fail("should not have succeeded to set termsIndexDivisor to 0");
-    } catch (IllegalArgumentException e) {
-      // this is expected
-    }
-    
-    // Setting to -1 is ok
-    conf.setReaderTermsIndexDivisor(-1);
-    try {
-      conf.setReaderTermsIndexDivisor(-2);
-      fail("should not have succeeded to set termsIndexDivisor to < -1");
-    } catch (IllegalArgumentException e) {
-      // this is expected
-    }
-    
     try {
       conf.setRAMPerThreadHardLimitMB(2048);
       fail("should not have succeeded to set RAMPerThreadHardLimitMB to >= 2048");
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java
index e3042cb..9f35710 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterForceMerge.java
@@ -20,6 +20,7 @@ package org.apache.lucene.index;
 import java.io.IOException;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
@@ -130,7 +131,7 @@ public class TestIndexWriterForceMerge extends LuceneTestCase {
     for(int j=0;j<500;j++) {
       TestIndexWriter.addDocWithIndex(writer, j);
     }
-    final int termIndexInterval = writer.getConfig().getTermIndexInterval();
+    CodecSettings settings = writer.getConfig().getCodecSettings();
     // force one extra segment w/ different doc store so
     // we see the doc stores get merged
     writer.commit();
@@ -155,7 +156,7 @@ public class TestIndexWriterForceMerge extends LuceneTestCase {
     // Import to use same term index interval else a
     // smaller one here could increase the disk usage and
     // cause a false failure:
-    writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setOpenMode(OpenMode.APPEND).setTermIndexInterval(termIndexInterval).setMergePolicy(newLogMergePolicy()));
+    writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setOpenMode(OpenMode.APPEND).setCodecSettings(settings).setMergePolicy(newLogMergePolicy()));
     writer.forceMerge(1);
     writer.close();
     long maxDiskUsage = dir.getMaxUsedSizeInBytes();
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java
index 02897e3..052db13 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestIndexWriterReader.java
@@ -26,6 +26,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexWriter;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.TextField;
@@ -313,7 +316,9 @@ public class TestIndexWriterReader extends LuceneTestCase {
     boolean doFullMerge = true;
 
     Directory dir1 = newDirectory();
-    IndexWriter writer = new IndexWriter(dir1, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setReaderTermsIndexDivisor(2));
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, 2);
+    IndexWriter writer = new IndexWriter(dir1, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setCodecSettings(builder.build()));
     // create the index
     createIndexNoClose(!doFullMerge, "index1", writer);
     writer.flush(false, true);
@@ -968,8 +973,10 @@ public class TestIndexWriterReader extends LuceneTestCase {
   public void testNoTermsIndex() throws Exception {
     // Some Codecs don't honor the ReaderTermsIndexDivisor, so skip the test if
     // they're picked.
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(CodecSettings.LOAD_TERM_INDEX, false);
     IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT,
-        new MockAnalyzer(random())).setReaderTermsIndexDivisor(-1);
+        new MockAnalyzer(random())).setCodecSettings(builder.build());
     
     // Don't proceed if picked Codec is in the list of illegal ones.
     final String format = _TestUtil.getPostingsFormat("f");
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java b/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java
index 3df987c..0c51b3d 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestSegmentMerger.java
@@ -20,6 +20,7 @@ package org.apache.lucene.index;
 import java.io.IOException;
 
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.store.Directory;
@@ -55,8 +56,8 @@ public class TestSegmentMerger extends LuceneTestCase {
     SegmentInfoPerCommit info1 = DocHelper.writeDoc(random(), merge1Dir, doc1);
     DocHelper.setupDoc(doc2);
     SegmentInfoPerCommit info2 = DocHelper.writeDoc(random(), merge2Dir, doc2);
-    reader1 = new SegmentReader(info1, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
-    reader2 = new SegmentReader(info2, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+    reader1 = new SegmentReader(info1, CodecSettings.defaults(), newIOContext(random()));
+    reader2 = new SegmentReader(info2, CodecSettings.defaults(), newIOContext(random()));
   }
 
   @Override
@@ -81,7 +82,7 @@ public class TestSegmentMerger extends LuceneTestCase {
     final Codec codec = Codec.getDefault();
     final SegmentInfo si = new SegmentInfo(mergedDir, Constants.LUCENE_MAIN_VERSION, mergedSegment, -1, false, codec, null, null);
 
-    SegmentMerger merger = new SegmentMerger(si, InfoStream.getDefault(), mergedDir, IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL,
+    SegmentMerger merger = new SegmentMerger(si, InfoStream.getDefault(), mergedDir, CodecSettings.defaults(),
                                              MergeState.CheckAbort.NONE, new FieldInfos.FieldNumbers(), newIOContext(random()));
     merger.add(reader1);
     merger.add(reader2);
@@ -93,7 +94,7 @@ public class TestSegmentMerger extends LuceneTestCase {
                                                          new SegmentInfo(mergedDir, Constants.LUCENE_MAIN_VERSION, mergedSegment, docsMerged,
                                                                          false, codec, null, null),
                                                          0, -1L),
-                                                   DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, newIOContext(random()));
+                                                         CodecSettings.defaults(), newIOContext(random()));
     assertTrue(mergedReader != null);
     assertTrue(mergedReader.numDocs() == 2);
     StoredDocument newDoc1 = mergedReader.document(0);
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSegmentReader.java b/lucene/core/src/test/org/apache/lucene/index/TestSegmentReader.java
index 280ab6e..7b9df3a 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestSegmentReader.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestSegmentReader.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.store.Directory;
@@ -42,7 +43,7 @@ public class TestSegmentReader extends LuceneTestCase {
     dir = newDirectory();
     DocHelper.setupDoc(testDoc);
     SegmentInfoPerCommit info = DocHelper.writeDoc(random(), dir, testDoc);
-    reader = new SegmentReader(info, DirectoryReader.DEFAULT_TERMS_INDEX_DIVISOR, IOContext.READ);
+    reader = new SegmentReader(info, CodecSettings.defaults(), IOContext.READ);
   }
   
   @Override
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermDocs.java b/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermDocs.java
index 5f52bf1..ec31fc1 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermDocs.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestSegmentTermDocs.java
@@ -20,6 +20,8 @@ package org.apache.lucene.index;
 import java.io.IOException;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexReader;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.search.DocIdSetIterator;
@@ -52,14 +54,14 @@ public class TestSegmentTermDocs extends LuceneTestCase {
   }
   
   public void testTermDocs() throws IOException {
-    testTermDocs(1);
+    testTermDocs(CodecSettings.defaults());
   }
 
-  public void testTermDocs(int indexDivisor) throws IOException {
+  public void testTermDocs(CodecSettings settings) throws IOException {
     //After adding the document, we should be able to read it back in
-    SegmentReader reader = new SegmentReader(info, indexDivisor, newIOContext(random()));
+    SegmentReader reader = new SegmentReader(info, settings, newIOContext(random()));
     assertTrue(reader != null);
-    assertEquals(indexDivisor, reader.getTermInfosIndexDivisor());
+    assertEquals(settings.getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR), reader.getCodecSetting().getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR));
 
     TermsEnum terms = reader.fields().terms(DocHelper.TEXT_FIELD_2_KEY).iterator(null);
     terms.seekCeil(new BytesRef("field"));
@@ -74,13 +76,13 @@ public class TestSegmentTermDocs extends LuceneTestCase {
   }  
   
   public void testBadSeek() throws IOException {
-    testBadSeek(1);
+    testBadSeek(CodecSettings.defaults());
   }
 
-  public void testBadSeek(int indexDivisor) throws IOException {
+  public void testBadSeek(CodecSettings codecSettings) throws IOException {
     {
       //After adding the document, we should be able to read it back in
-      SegmentReader reader = new SegmentReader(info, indexDivisor, newIOContext(random()));
+      SegmentReader reader = new SegmentReader(info, codecSettings, newIOContext(random()));
       assertTrue(reader != null);
       DocsEnum termDocs = _TestUtil.docs(random(), reader,
                                          "textField2",
@@ -94,7 +96,7 @@ public class TestSegmentTermDocs extends LuceneTestCase {
     }
     {
       //After adding the document, we should be able to read it back in
-      SegmentReader reader = new SegmentReader(info, indexDivisor, newIOContext(random()));
+      SegmentReader reader = new SegmentReader(info, codecSettings, newIOContext(random()));
       assertTrue(reader != null);
       DocsEnum termDocs = _TestUtil.docs(random(), reader,
                                          "junk",
@@ -108,10 +110,10 @@ public class TestSegmentTermDocs extends LuceneTestCase {
   }
   
   public void testSkipTo() throws IOException {
-    testSkipTo(1);
+    testSkipTo(CodecSettings.defaults());
   }
 
-  public void testSkipTo(int indexDivisor) throws IOException {
+  public void testSkipTo(CodecSettings settings) throws IOException {
     Directory dir = newDirectory();
     IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random())).setMergePolicy(newLogMergePolicy()));
     
@@ -131,7 +133,7 @@ public class TestSegmentTermDocs extends LuceneTestCase {
     writer.forceMerge(1);
     writer.close();
     
-    IndexReader reader = DirectoryReader.open(dir, indexDivisor);
+    IndexReader reader = DirectoryReader.open(dir, settings);
 
     DocsEnum tdocs = _TestUtil.docs(random(), reader,
                                     ta.field(),
@@ -272,9 +274,9 @@ public class TestSegmentTermDocs extends LuceneTestCase {
     testDoc = new Document();
     DocHelper.setupDoc(testDoc);
     DocHelper.writeDoc(random(), dir, testDoc);
-    testTermDocs(2);
-    testBadSeek(2);
-    testSkipTo(2);
+    testTermDocs(newCodecSettings(random()));
+    testBadSeek(newCodecSettings(random()));
+    testSkipTo(newCodecSettings(random()));
   }
 
   private void addDoc(IndexWriter writer, String value) throws IOException
diff --git a/lucene/facet/src/examples/org/apache/lucene/facet/example/merge/TaxonomyMergeUtils.java b/lucene/facet/src/examples/org/apache/lucene/facet/example/merge/TaxonomyMergeUtils.java
index 25bee49..3d5db9d 100644
--- a/lucene/facet/src/examples/org/apache/lucene/facet/example/merge/TaxonomyMergeUtils.java
+++ b/lucene/facet/src/examples/org/apache/lucene/facet/example/merge/TaxonomyMergeUtils.java
@@ -11,6 +11,8 @@ import org.apache.lucene.index.IndexWriterConfig;
 import org.apache.lucene.index.MultiReader;
 import org.apache.lucene.store.Directory;
 
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
 import org.apache.lucene.facet.example.ExampleUtils;
 import org.apache.lucene.facet.index.OrdinalMappingAtomicReader;
 import org.apache.lucene.facet.index.params.DefaultFacetIndexingParams;
@@ -89,8 +91,9 @@ public class TaxonomyMergeUtils {
 
     int ordinalMap[] = map.getMap();
     FacetIndexingParams params = new DefaultFacetIndexingParams();
-
-    DirectoryReader reader = DirectoryReader.open(srcIndexDir, -1);
+    final SettingsBuilder builder = CodecSettings.builder();
+    builder.put(CodecSettings.LOAD_TERM_INDEX, false);
+    DirectoryReader reader = DirectoryReader.open(srcIndexDir, builder.build());
     List<AtomicReaderContext> leaves = reader.leaves();
     AtomicReader wrappedLeaves[] = new AtomicReader[leaves.size()];
     for (int i = 0; i < leaves.size(); i++) {
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41ords/Lucene41WithOrds.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41ords/Lucene41WithOrds.java
index 8865136..3220b5b 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41ords/Lucene41WithOrds.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/lucene41ords/Lucene41WithOrds.java
@@ -99,7 +99,7 @@ public final class Lucene41WithOrds extends PostingsFormat {
       indexReader = new FixedGapTermsIndexReader(state.dir,
                                                  state.fieldInfos,
                                                  state.segmentInfo.name,
-                                                 state.termsIndexDivisor,
+                                                 state.codecSettings,
                                                  BytesRef.getUTF8SortedAsUnicodeComparator(),
                                                  state.segmentSuffix, state.context);
       success = true;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockFixedIntBlockPostingsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockFixedIntBlockPostingsFormat.java
index 0cf6779..985bc71 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockFixedIntBlockPostingsFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockFixedIntBlockPostingsFormat.java
@@ -168,7 +168,7 @@ public final class MockFixedIntBlockPostingsFormat extends PostingsFormat {
       indexReader = new FixedGapTermsIndexReader(state.dir,
                                                        state.fieldInfos,
                                                        state.segmentInfo.name,
-                                                       state.termsIndexDivisor,
+                                                       state.codecSettings,
                                                        BytesRef.getUTF8SortedAsUnicodeComparator(), state.segmentSuffix,
                                                        IOContext.DEFAULT);
       success = true;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockVariableIntBlockPostingsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockVariableIntBlockPostingsFormat.java
index bb9195e..e38202c 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockVariableIntBlockPostingsFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockintblock/MockVariableIntBlockPostingsFormat.java
@@ -192,7 +192,7 @@ public final class MockVariableIntBlockPostingsFormat extends PostingsFormat {
       indexReader = new FixedGapTermsIndexReader(state.dir,
                                                        state.fieldInfos,
                                                        state.segmentInfo.name,
-                                                       state.termsIndexDivisor,
+                                                       state.codecSettings,
                                                        BytesRef.getUTF8SortedAsUnicodeComparator(),
                                                        state.segmentSuffix, state.context);
       success = true;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java
index 55958b1..078cb6c 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/mockrandom/MockRandomPostingsFormat.java
@@ -24,6 +24,8 @@ import java.util.Random;
 
 import org.apache.lucene.codecs.BlockTreeTermsReader;
 import org.apache.lucene.codecs.BlockTreeTermsWriter;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
 import org.apache.lucene.codecs.FieldsConsumer;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PostingsFormat;
@@ -162,9 +164,9 @@ public final class MockRandomPostingsFormat extends PostingsFormat {
     } finally {
       out.close();
     }
-
+    CodecSettings codecSettings = LuceneTestCase.newCodecSettings(new Random(seed));
     final Random random = new Random(seed);
-    
+
     random.nextInt(); // consume a random for buffersize
 
     PostingsWriterBase postingsWriter;
@@ -220,9 +222,8 @@ public final class MockRandomPostingsFormat extends PostingsFormat {
       final TermsIndexWriterBase indexWriter;
       try {
         if (random.nextBoolean()) {
-          state.termIndexInterval = _TestUtil.nextInt(random, 1, 100);
           if (LuceneTestCase.VERBOSE) {
-            System.out.println("MockRandomCodec: fixed-gap terms index (tii=" + state.termIndexInterval + ")");
+            System.out.println("MockRandomCodec: fixed-gap terms index (tii=" + codecSettings.getAsInt(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, FixedGapTermsIndexWriter.DEFAULT_TERM_INDEX_INTERVAL) + ")");
           }
           indexWriter = new FixedGapTermsIndexWriter(state);
         } else {
@@ -341,7 +342,7 @@ public final class MockRandomPostingsFormat extends PostingsFormat {
                                           postingsReader,
                                           state.context,
                                           state.segmentSuffix,
-                                          state.termsIndexDivisor);
+                                          state.codecSettings);
         success = true;
       } finally {
         if (!success) {
@@ -357,22 +358,29 @@ public final class MockRandomPostingsFormat extends PostingsFormat {
       boolean success = false;
       try {
         final boolean doFixedGap = random.nextBoolean();
-
+        CodecSettings settings = state.codecSettings;
         // randomness diverges from writer, here:
-        if (state.termsIndexDivisor != -1) {
-          state.termsIndexDivisor = _TestUtil.nextInt(random, 1, 10);
+        boolean loadTermIndex = settings.getAsBoolean(CodecSettings.LOAD_TERM_INDEX, true);
+        if (loadTermIndex) {
+          SettingsBuilder builder = CodecSettings.builder();
+          builder.put(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, _TestUtil.nextInt(random, 1, 10));
+          settings = builder.build();
+        } else {
+          SettingsBuilder builder = CodecSettings.builder();
+          builder.put(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, -1);
+          settings = builder.build();
         }
 
         if (doFixedGap) {
           // if termsIndexDivisor is set to -1, we should not touch it. It means a
           // test explicitly instructed not to load the terms index.
           if (LuceneTestCase.VERBOSE) {
-            System.out.println("MockRandomCodec: fixed-gap terms index (divisor=" + state.termsIndexDivisor + ")");
+            System.out.println("MockRandomCodec: fixed-gap terms index (divisor=" + settings.getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR) + ")");
           }
           indexReader = new FixedGapTermsIndexReader(state.dir,
                                                      state.fieldInfos,
                                                      state.segmentInfo.name,
-                                                     state.termsIndexDivisor,
+                                                     settings,
                                                      BytesRef.getUTF8SortedAsUnicodeComparator(),
                                                      state.segmentSuffix, state.context);
         } else {
@@ -383,12 +391,12 @@ public final class MockRandomPostingsFormat extends PostingsFormat {
             random.nextLong();
           }
           if (LuceneTestCase.VERBOSE) {
-            System.out.println("MockRandomCodec: variable-gap terms index (divisor=" + state.termsIndexDivisor + ")");
+            System.out.println("MockRandomCodec: variable-gap terms index (divisor=" + settings.getAsInt(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, FixedGapTermsIndexReader.DEFAULT_TERM_INDEX_DIVISOR) + ")");
           }
           indexReader = new VariableGapTermsIndexReader(state.dir,
                                                         state.fieldInfos,
                                                         state.segmentInfo.name,
-                                                        state.termsIndexDivisor,
+                                                        state.codecSettings,
                                                         state.segmentSuffix, state.context);
 
         }
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/mocksep/MockSepPostingsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/mocksep/MockSepPostingsFormat.java
index d954d46..94b7b62 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/mocksep/MockSepPostingsFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/mocksep/MockSepPostingsFormat.java
@@ -92,7 +92,7 @@ public final class MockSepPostingsFormat extends PostingsFormat {
       indexReader = new FixedGapTermsIndexReader(state.dir,
                                                        state.fieldInfos,
                                                        state.segmentInfo.name,
-                                                       state.termsIndexDivisor,
+                                                       state.codecSettings,
                                                        BytesRef.getUTF8SortedAsUnicodeComparator(),
                                                        state.segmentSuffix, state.context);
       success = true;
diff --git a/lucene/test-framework/src/java/org/apache/lucene/codecs/nestedpulsing/NestedPulsingPostingsFormat.java b/lucene/test-framework/src/java/org/apache/lucene/codecs/nestedpulsing/NestedPulsingPostingsFormat.java
index 31f897e..5afa536 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/codecs/nestedpulsing/NestedPulsingPostingsFormat.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/codecs/nestedpulsing/NestedPulsingPostingsFormat.java
@@ -85,7 +85,7 @@ public final class NestedPulsingPostingsFormat extends PostingsFormat {
                                                     pulsingReader,
                                                     state.context,
                                                     state.segmentSuffix,
-                                                    state.termsIndexDivisor);
+                                                    state.codecSettings);
       success = true;
       return ret;
     } finally {
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BasePostingsFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BasePostingsFormatTestCase.java
index bb1f7c1..ebd0868 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/BasePostingsFormatTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/BasePostingsFormatTestCase.java
@@ -33,6 +33,7 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.lucene.codecs.Codec;
+import org.apache.lucene.codecs.CodecSettings;
 import org.apache.lucene.codecs.FieldsConsumer;
 import org.apache.lucene.codecs.FieldsProducer;
 import org.apache.lucene.codecs.PostingsConsumer;
@@ -482,7 +483,7 @@ public abstract class BasePostingsFormatTestCase extends LuceneTestCase {
 
     SegmentWriteState writeState = new SegmentWriteState(null, dir,
                                                          segmentInfo, newFieldInfos,
-                                                         32, null, new IOContext(new FlushInfo(maxDoc, bytes)));
+                                                         CodecSettings.defaults(), null, new IOContext(new FlushInfo(maxDoc, bytes)));
     FieldsConsumer fieldsConsumer = codec.postingsFormat().fieldsConsumer(writeState);
 
     for(Map.Entry<String,Map<BytesRef,Long>> fieldEnt : fields.entrySet()) {
@@ -566,7 +567,7 @@ public abstract class BasePostingsFormatTestCase extends LuceneTestCase {
 
     currentFieldInfos = newFieldInfos;
 
-    SegmentReadState readState = new SegmentReadState(dir, segmentInfo, newFieldInfos, IOContext.DEFAULT, 1);
+    SegmentReadState readState = new SegmentReadState(dir, segmentInfo, newFieldInfos, IOContext.DEFAULT, CodecSettings.defaults());
 
     return codec.postingsFormat().fieldsProducer(readState);
   }
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java b/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java
index cf6d3a8..bde257d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/RandomIndexWriter.java
@@ -439,7 +439,7 @@ public class RandomIndexWriter implements Closeable {
       w.commit();
       switchDoDocValues();
       if (r.nextBoolean()) {
-        return DirectoryReader.open(w.getDirectory(), _TestUtil.nextInt(r, 1, 10));
+        return DirectoryReader.open(w.getDirectory(), LuceneTestCase.newCodecSettings(r)); 
       } else {
         return w.getReader(applyDeletions);
       }
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
index 64c123a..6c0f4b9 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
@@ -26,6 +26,10 @@ import java.util.concurrent.*;
 import java.util.logging.Logger;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexReader;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexWriter;
 import org.apache.lucene.document.Field.Store;
 import org.apache.lucene.document.Field;
 import org.apache.lucene.document.FieldType;
@@ -705,15 +709,7 @@ public abstract class LuceneTestCase extends Assert {
         c.setMaxBufferedDocs(_TestUtil.nextInt(r, 16, 1000));
       }
     }
-    if (r.nextBoolean()) {
-      if (rarely(r)) {
-        // crazy value
-        c.setTermIndexInterval(r.nextBoolean() ? _TestUtil.nextInt(r, 1, 31) : _TestUtil.nextInt(r, 129, 1000));
-      } else {
-        // reasonable value
-        c.setTermIndexInterval(_TestUtil.nextInt(r, 32, 128));
-      }
-    }
+    c.setCodecSettings(newCodecSettings(r));
     if (r.nextBoolean()) {
       int maxNumThreadStates = rarely(r) ? _TestUtil.nextInt(r, 5, 20) // crazy value
           : _TestUtil.nextInt(r, 1, 4); // reasonable value
@@ -764,7 +760,6 @@ public abstract class LuceneTestCase extends Assert {
       c.setMergePolicy(newLogMergePolicy());
     }
     c.setReaderPooling(r.nextBoolean());
-    c.setReaderTermsIndexDivisor(_TestUtil.nextInt(r, 1, 4));
     return c;
   }
 
@@ -1266,4 +1261,21 @@ public abstract class LuceneTestCase extends Assert {
       throw new IOException("Cannot find resource: " + name);
     }
   }
+  
+  public static CodecSettings newCodecSettings(Random r) {
+    CodecSettings settings = CodecSettings.defaults();
+    SettingsBuilder builder = CodecSettings.builder(settings);
+    if (r.nextBoolean()) {
+      if (rarely(r)) {
+        // crazy value
+        builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, r.nextBoolean() ? _TestUtil.nextInt(r, 1, 31) : _TestUtil.nextInt(r, 129, 1000));
+      } else {
+        // reasonable value
+        builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, _TestUtil.nextInt(r, 32, 128));
+      }
+    }
+    
+    builder.put(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, _TestUtil.nextInt(r, 1, 4));
+    return builder.build();
+  }
 }
diff --git a/solr/core/src/java/org/apache/solr/core/StandardIndexReaderFactory.java b/solr/core/src/java/org/apache/solr/core/StandardIndexReaderFactory.java
index 133eba8..4ad9655 100644
--- a/solr/core/src/java/org/apache/solr/core/StandardIndexReaderFactory.java
+++ b/solr/core/src/java/org/apache/solr/core/StandardIndexReaderFactory.java
@@ -18,6 +18,9 @@ package org.apache.solr.core;
 
 import java.io.IOException;
 
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexReader;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.store.Directory;
 
@@ -31,6 +34,11 @@ public class StandardIndexReaderFactory extends IndexReaderFactory {
   
   @Override
   public DirectoryReader newReader(Directory indexDir, SolrCore core) throws IOException {
-    return DirectoryReader.open(indexDir, termInfosIndexDivisor);
+    SettingsBuilder builder = CodecSettings.builder();
+    builder.put(FixedGapTermsIndexReader.TERM_INDEX_DIVISOR_KEY, termInfosIndexDivisor);
+    if (termInfosIndexDivisor == -1) {
+      builder.put(CodecSettings.LOAD_TERM_INDEX, false);
+    }
+    return DirectoryReader.open(indexDir, builder.build());
   }
 }
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java
index 6035304..1febfda 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexConfig.java
@@ -17,6 +17,9 @@
 
 package org.apache.solr.update;
 
+import org.apache.lucene.codecs.CodecSettings;
+import org.apache.lucene.codecs.CodecSettings.SettingsBuilder;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexWriter;
 import org.apache.lucene.index.*;
 import org.apache.lucene.util.Version;
 import org.apache.solr.common.SolrException;
@@ -53,7 +56,7 @@ public class SolrIndexConfig {
   public final String lockType;
   public final PluginInfo mergePolicyInfo;
   public final PluginInfo mergeSchedulerInfo;
-  public final int termIndexInterval;
+  public final CodecSettings codecSettings;
   
   public String infoStreamFile = null;
 
@@ -77,10 +80,10 @@ public class SolrIndexConfig {
     ramBufferSizeMB = 32;
     writeLockTimeout = -1;
     lockType = LOCK_TYPE_NATIVE;
-    termIndexInterval = IndexWriterConfig.DEFAULT_TERM_INDEX_INTERVAL;
     mergePolicyInfo = null;
     mergeSchedulerInfo = null;
     defaultMergePolicyClassName = TieredMergePolicy.class.getName();
+    codecSettings = CodecSettings.defaults();
   }
   
   /**
@@ -127,8 +130,15 @@ public class SolrIndexConfig {
 
     mergeSchedulerInfo = getPluginInfo(prefix + "/mergeScheduler", solrConfig, def.mergeSchedulerInfo);
     mergePolicyInfo = getPluginInfo(prefix + "/mergePolicy", solrConfig, def.mergePolicyInfo);
+    if (solrConfig.getVal(prefix + "/termIndexInterval", false) != null) {
+      int termIndexInterval = solrConfig.getInt(prefix + "/termIndexInterval", 1);
+      SettingsBuilder builder = CodecSettings.builder();
+      builder.put(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, termIndexInterval);
+      this.codecSettings = builder.build();
+    } else {
+      this.codecSettings = CodecSettings.defaults();
+    }
     
-    termIndexInterval = solrConfig.getInt(prefix + "/termIndexInterval", def.termIndexInterval);
     
     boolean infoStreamEnabled = solrConfig.getBool(prefix + "/infoStream", false);
     if(infoStreamEnabled) {
@@ -169,9 +179,6 @@ public class SolrIndexConfig {
     if (ramBufferSizeMB != -1)
       iwc.setRAMBufferSizeMB(ramBufferSizeMB);
 
-    if (termIndexInterval != -1)
-      iwc.setTermIndexInterval(termIndexInterval);
-
     if (writeLockTimeout != -1)
       iwc.setWriteLockTimeout(writeLockTimeout);
 
@@ -182,7 +189,7 @@ public class SolrIndexConfig {
     if (maxIndexingThreads != -1) {
       iwc.setMaxThreadStates(maxIndexingThreads);
     }
-
+    iwc.setCodecSettings(codecSettings);
     return iwc;
   }
 
diff --git a/solr/core/src/test/org/apache/solr/core/TestConfig.java b/solr/core/src/test/org/apache/solr/core/TestConfig.java
index df353ae..d45f9ba 100644
--- a/solr/core/src/test/org/apache/solr/core/TestConfig.java
+++ b/solr/core/src/test/org/apache/solr/core/TestConfig.java
@@ -17,6 +17,8 @@
 
 package org.apache.solr.core;
 
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexReader;
+import org.apache.lucene.codecs.blockterms.FixedGapTermsIndexWriter;
 import org.apache.lucene.index.IndexWriter;
 import org.apache.lucene.index.TieredMergePolicy;
 import org.apache.solr.SolrTestCaseJ4;
@@ -121,7 +123,7 @@ public class TestConfig extends SolrTestCaseJ4 {
     int interval = 0;
     try {
       IndexWriter writer = iw.get();
-      interval = writer.getConfig().getTermIndexInterval();
+      interval = writer.getConfig().getCodecSettings().getAsInt(FixedGapTermsIndexWriter.TERM_INDEX_INTERVAL_KEY, 0);
     } finally {
       iw.decref();
     }
