diff --git a/lucene/core/src/java/org/apache/lucene/index/TermContext.java b/lucene/core/src/java/org/apache/lucene/index/TermContext.java
index f9431dc..ec5e234 100644
--- a/lucene/core/src/java/org/apache/lucene/index/TermContext.java
+++ b/lucene/core/src/java/org/apache/lucene/index/TermContext.java
@@ -17,10 +17,6 @@ package org.apache.lucene.index;
  * limitations under the License.
  */
 
-import org.apache.lucene.codecs.BlockTermState;
-import org.apache.lucene.util.BytesRef;
-
-import java.io.IOException;
 import java.util.Arrays;
 
 /**
@@ -73,36 +69,6 @@ public final class TermContext {
   }
 
   /**
-   * Creates a {@link TermContext} from a top-level {@link IndexReaderContext} and the
-   * given {@link Term}. This method will lookup the given term in all context's leaf readers 
-   * and register each of the readers containing the term in the returned {@link TermContext}
-   * using the leaf reader's ordinal.
-   * <p>
-   * Note: the given context must be a top-level context.
-   */
-  public static TermContext build(IndexReaderContext context, Term term)
-      throws IOException {
-    assert context != null && context.isTopLevel;
-    final String field = term.field();
-    final BytesRef bytes = term.bytes();
-    final TermContext perReaderTermState = new TermContext(context);
-    //if (DEBUG) System.out.println("prts.build term=" + term);
-    for (final LeafReaderContext ctx : context.leaves()) {
-      //if (DEBUG) System.out.println("  r=" + leaves[i].reader);
-      final Terms terms = ctx.reader().terms(field);
-      if (terms != null) {
-        final TermsEnum termsEnum = terms.iterator();
-        if (termsEnum.seekExact(bytes)) { 
-          final TermState termState = termsEnum.termState();
-          //if (DEBUG) System.out.println("    found");
-          perReaderTermState.register(termState, ctx.ord, termsEnum.docFreq(), termsEnum.totalTermFreq());
-        }
-      }
-    }
-    return perReaderTermState;
-  }
-
-  /**
    * Clears the {@link TermContext} internal state and removes all
    * registered {@link TermState}s
    */
diff --git a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
index d81913d..021da67 100644
--- a/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
+++ b/lucene/core/src/java/org/apache/lucene/search/IndexSearcher.java
@@ -30,19 +30,7 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
 
-import org.apache.lucene.index.DirectoryReader; // javadocs
-import org.apache.lucene.index.FieldInvertState;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.index.IndexWriter; // javadocs
-import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.MultiFields;
-import org.apache.lucene.index.ReaderUtil;
-import org.apache.lucene.index.StoredDocument;
-import org.apache.lucene.index.StoredFieldVisitor;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.index.TermContext;
-import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.*;
 import org.apache.lucene.search.similarities.DefaultSimilarity;
 import org.apache.lucene.search.similarities.Similarity;
 import org.apache.lucene.store.NIOFSDirectory;    // javadoc
@@ -769,4 +757,30 @@ public class IndexSearcher {
     }
     return new CollectionStatistics(field, reader.maxDoc(), docCount, sumTotalTermFreq, sumDocFreq);
   }
+
+  /**
+   * Creates a {@link TermContext} from this searcher's {@link IndexReaderContext} and the
+   * given {@link Term}. This method will lookup the given term in all the context's leaf readers
+   * and register each of the readers containing the term in the returned {@link TermContext}
+   * using the leaf reader's ordinal.
+   */
+  public TermContext buildTermContext(Term term) throws IOException {
+    final String field = term.field();
+    final BytesRef bytes = term.bytes();
+    final TermContext perReaderTermState = new TermContext(readerContext);
+    //if (DEBUG) System.out.println("prts.build term=" + term);
+    for (final LeafReaderContext ctx : readerContext.leaves()) {
+      //if (DEBUG) System.out.println("  r=" + leaves[i].reader);
+      final Terms terms = ctx.reader().terms(field);
+      if (terms != null) {
+        final TermsEnum termsEnum = terms.iterator();
+        if (termsEnum.seekExact(bytes)) {
+          final TermState termState = termsEnum.termState();
+          //if (DEBUG) System.out.println("    found");
+          perReaderTermState.register(termState, ctx.ord, termsEnum.docFreq(), termsEnum.totalTermFreq());
+        }
+      }
+    }
+    return perReaderTermState;
+  }
 }
diff --git a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
index feb7863..2fbcfa1 100644
--- a/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/MultiPhraseQuery.java
@@ -20,18 +20,17 @@ package org.apache.lucene.search;
 import java.io.IOException;
 import java.util.*;
 
-import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.LeafReader;
+import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.PostingsEnum;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermContext;
 import org.apache.lucene.index.TermState;
 import org.apache.lucene.index.Terms;
 import org.apache.lucene.index.TermsEnum;
-import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.search.similarities.Similarity;
+import org.apache.lucene.search.similarities.Similarity.SimScorer;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
@@ -139,15 +138,14 @@ public class MultiPhraseQuery extends Query {
       super(MultiPhraseQuery.this);
       this.needsScores = needsScores;
       this.similarity = searcher.getSimilarity(needsScores);
-      final IndexReaderContext context = searcher.getTopReaderContext();
-      
+
       // compute idf
       ArrayList<TermStatistics> allTermStats = new ArrayList<>();
       for(final Term[] terms: termArrays) {
         for (Term term: terms) {
           TermContext termContext = termContexts.get(term);
           if (termContext == null) {
-            termContext = TermContext.build(context, term);
+            termContext = searcher.buildTermContext(term);
             termContexts.put(term, termContext);
           }
           allTermStats.add(searcher.termStatistics(term, termContext));
diff --git a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
index bb78587..5a6f7dd 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PhraseQuery.java
@@ -23,11 +23,10 @@ import java.util.Arrays;
 import java.util.Objects;
 import java.util.Set;
 
-import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.LeafReader;
 import org.apache.lucene.index.LeafReaderContext;
+import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermContext;
 import org.apache.lucene.index.TermState;
@@ -256,12 +255,11 @@ public class PhraseQuery extends Query {
       }
       this.needsScores = needsScores;
       this.similarity = searcher.getSimilarity(needsScores);
-      final IndexReaderContext context = searcher.getTopReaderContext();
       states = new TermContext[terms.size()];
       TermStatistics termStats[] = new TermStatistics[terms.size()];
       for (int i = 0; i < terms.size(); i++) {
         final Term term = terms.get(i);
-        states[i] = TermContext.build(context, term);
+        states[i] = searcher.buildTermContext(term);
         termStats[i] = searcher.termStatistics(term, states[i]);
       }
       stats = similarity.computeWeight(getBoost(), searcher.collectionStatistics(field), termStats);
diff --git a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
index ebbfdb8..d967132 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TermQuery.java
@@ -190,7 +190,7 @@ public class TermQuery extends Query {
         || perReaderTermState.topReaderContext != context) {
       // make TermQuery single-pass if we don't have a PRTS or if the context
       // differs!
-      termState = TermContext.build(context, term);
+      termState = searcher.buildTermContext(term);
     } else {
       // PRTS was pre-build for this IS
       termState = this.perReaderTermState;
diff --git a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
index 4fe571f..7b12d0e 100644
--- a/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
@@ -17,6 +17,11 @@ package org.apache.lucene.search.payloads;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.PostingsEnum;
 import org.apache.lucene.index.Term;
@@ -35,11 +40,6 @@ import org.apache.lucene.search.spans.Spans;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
 
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-
 /**
  * This class is very similar to
  * {@link org.apache.lucene.search.spans.SpanTermQuery} except that it factors
@@ -70,7 +70,7 @@ public class PayloadTermQuery extends SpanTermQuery {
 
   @Override
   public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
-    TermContext context = TermContext.build(searcher.getTopReaderContext(), term);
+    TermContext context = searcher.buildTermContext(term);
     return new PayloadTermWeight(context, searcher, needsScores ? Collections.singletonMap(term, context) : null);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
index 4ea9b3f..8212b0c 100644
--- a/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
@@ -17,6 +17,12 @@ package org.apache.lucene.search.spans;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
 import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.PostingsEnum;
@@ -30,12 +36,6 @@ import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.ToStringUtils;
 
-import java.io.IOException;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
 /** Matches spans containing a term.
  * This should not be used for terms that are indexed at position Integer.MAX_VALUE.
  */
@@ -70,7 +70,7 @@ public class SpanTermQuery extends SpanQuery {
     final TermContext context;
     final IndexReaderContext topContext = searcher.getTopReaderContext();
     if (termContext == null || termContext.topReaderContext != topContext) {
-      context = TermContext.build(topContext, term);
+      context = searcher.buildTermContext(term);
     }
     else {
       context = termContext;
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestMinShouldMatch2.java b/lucene/core/src/test/org/apache/lucene/search/TestMinShouldMatch2.java
index 23f4e6b..2096254 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestMinShouldMatch2.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestMinShouldMatch2.java
@@ -333,7 +333,7 @@ public class TestMinShouldMatch2 extends LuceneTestCase {
         if (ord >= 0) {
           boolean success = ords.add(ord);
           assert success; // no dups
-          TermContext context = TermContext.build(reader.getContext(), term);
+          TermContext context = searcher.buildTermContext(term);
           SimWeight w = weight.similarity.computeWeight(1f, 
                         searcher.collectionStatistics("field"),
                         searcher.termStatistics(term, context));
diff --git a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
index e300994..f1d334b 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/search/TermAutomatonQuery.java
@@ -194,7 +194,7 @@ public class TermAutomatonQuery extends Query {
 
     for (Map.Entry<BytesRef,Integer> ent : termToID.entrySet()) {
       if (ent.getKey() != null) {
-        termStates.put(ent.getValue(), TermContext.build(context, new Term(field, ent.getKey())));
+        termStates.put(ent.getValue(), searcher.buildTermContext(new Term(field, ent.getKey())));
       }
     }
 
diff --git a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
index 9d60a1b..11c138d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/search/ShardSearchingTestBase.java
@@ -185,7 +185,7 @@ public abstract class ShardSearchingTestBase extends LuceneTestCase {
     }
     try {
       for(Term term : terms) {
-        final TermContext termContext = TermContext.build(s.getIndexReader().getContext(), term);
+        final TermContext termContext = s.buildTermContext(term);
         stats.put(term, s.termStatistics(term, termContext));
       }
     } finally {
diff --git a/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java b/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
index 2e7aa94..77713e3 100644
--- a/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
+++ b/solr/core/src/java/org/apache/solr/search/stats/ExactStatsCache.java
@@ -17,6 +17,15 @@ package org.apache.solr.search.stats;
  * limitations under the License.
  */
 
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
 import org.apache.lucene.index.IndexReaderContext;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermContext;
@@ -38,15 +47,6 @@ import org.apache.solr.search.SolrIndexSearcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
 /**
  * This class implements exact caching of statistics. It requires an additional
  * round-trip to parse query at shard servers, and return term statistics for
@@ -166,7 +166,7 @@ public class ExactStatsCache extends StatsCache {
       HashMap<String,TermStats> statsMap = new HashMap<String,TermStats>();
       HashMap<String,CollectionStats> colMap = new HashMap<String,CollectionStats>();
       for (Term t : terms) {
-        TermContext termContext = TermContext.build(context, t);
+        TermContext termContext = searcher.buildTermContext(t);
         
         TermStatistics tst = searcher.localTermStatistics(t, termContext);
         if (tst.docFreq() == 0) { // skip terms that are not present here
