This is an automated email from the ASF dual-hosted git repository.

markrmiller pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new 797bb38  SOLR-15538 Update Lucene Preview Release dependency.
797bb38 is described below

commit 797bb38c50fed9e533ca20de920c63c6c35256a9
Author: Mark Robert Miller <[email protected]>
AuthorDate: Thu Jul 29 12:05:55 2021 -0500

    SOLR-15538 Update Lucene Preview Release dependency.
---
 gradle/globals.gradle                              |   2 +-
 .../apache/solr/schema/TestICUCollationField.java  |   2 +-
 .../org/apache/solr/analysis/TokenizerChain.java   |   1 -
 .../solr/highlight/DefaultSolrHighlighter.java     |   3 +
 .../solr/index/SlowCompositeReaderWrapper.java     |   8 +-
 .../apache/solr/parser/SolrQueryParserBase.java    |   2 +-
 .../src/java/org/apache/solr/schema/FieldType.java |   4 -
 .../apache/solr/schema/FieldTypePluginLoader.java  |   1 -
 .../java/org/apache/solr/schema/SchemaField.java   |   6 +-
 .../apache/solr/search/ExtendedDismaxQParser.java  |   2 +-
 .../solr/search/PayloadCheckQParserPlugin.java     |   2 +-
 .../solr/search/PayloadScoreQParserPlugin.java     |   2 +-
 .../search/similarities/BM25SimilarityFactory.java |   1 +
 .../similarities/SchemaSimilarityFactory.java      |  46 +-
 .../spelling/suggest/jaspell/JaspellLookup.java    | 208 ++++++
 .../suggest/jaspell/JaspellLookupFactory.java      |   1 -
 .../suggest/jaspell/JaspellTernarySearchTrie.java  | 831 +++++++++++++++++++++
 .../spelling/suggest/jaspell/package-info.java     |   2 +-
 .../java/org/apache/solr/util/PayloadUtils.java    |   9 +-
 .../solr/collection1/conf/schema-bm25.xml          |   1 +
 .../conf/solrconfig-tieredmergepolicyfactory.xml   |   2 +-
 .../solr/analysis/TestLuceneMatchVersion.java      |   1 -
 .../TestReversedWildcardFilterFactory.java         |   2 +-
 .../apache/solr/core/TestMergePolicyConfig.java    |   1 -
 .../solr/handler/TestSnapshotCoreBackup.java       |   2 +-
 .../solr/handler/TestStressThreadBackup.java       |   2 +-
 .../org/apache/solr/highlight/HighlighterTest.java |   2 +-
 .../apache/solr/rest/schema/TestBulkSchemaAPI.java |   3 +-
 .../search/ApacheLuceneSolrNearQueryBuilder.java   |   6 +-
 .../solr/search/ChooseOneWordQueryBuilder.java     |   4 +-
 .../org/apache/solr/search/FuzzySearchTest.java    |  67 --
 .../org/apache/solr/search/HandyQueryBuilder.java  |   4 +-
 .../test/org/apache/solr/search/TestDocSet.java    |  13 +-
 .../org/apache/solr/search/TestSolrCoreParser.java |  22 +-
 .../apache/solr/update/SolrIndexConfigTest.java    |   3 +-
 .../solr/client/solrj/request/SchemaTest.java      |   2 -
 versions.lock                                      |  54 +-
 versions.props                                     |   2 +-
 38 files changed, 1144 insertions(+), 182 deletions(-)

diff --git a/gradle/globals.gradle b/gradle/globals.gradle
index 816d77b..bf84fca 100644
--- a/gradle/globals.gradle
+++ b/gradle/globals.gradle
@@ -20,7 +20,7 @@ allprojects {
 
   group "org.apache"
 
-  def lucenePrereleaseBuild = '5'
+  def lucenePrereleaseBuild = '9'
 
   // Repositories to fetch dependencies from.
   repositories {
diff --git 
a/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationField.java
 
b/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationField.java
index 844abad..6c4ecb5 100644
--- 
a/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationField.java
+++ 
b/solr/contrib/analysis-extras/src/test/org/apache/solr/schema/TestICUCollationField.java
@@ -98,7 +98,7 @@ public class TestICUCollationField extends SolrTestCaseJ4 {
       Mockito.when(loader.openResource(Mockito.anyString()))
              .thenReturn(new 
ByteArrayInputStream(tailoredRules.getBytes(StandardCharsets.UTF_8)));
     } else {
-      loader = new FilesystemResourceLoader(confDir.toPath());
+      loader = new FilesystemResourceLoader(confDir.toPath(), 
TestICUCollationField.class.getClassLoader());
     }
     final Collator readCollator = 
ICUCollationField.createFromRules(osFileName, loader);
     assertEquals(tailoredCollator, readCollator);
diff --git a/solr/core/src/java/org/apache/solr/analysis/TokenizerChain.java 
b/solr/core/src/java/org/apache/solr/analysis/TokenizerChain.java
index 9533f3d..611e3cf 100644
--- a/solr/core/src/java/org/apache/solr/analysis/TokenizerChain.java
+++ b/solr/core/src/java/org/apache/solr/analysis/TokenizerChain.java
@@ -49,7 +49,6 @@ public final class TokenizerChain extends SolrAnalyzer {
         customAnalyzer.getTokenizerFactory(),
         customAnalyzer.getTokenFilterFactories().toArray(new 
TokenFilterFactory[0]));
     setPositionIncrementGap(customAnalyzer.getPositionIncrementGap(null));
-    setVersion(customAnalyzer.getVersion());
     assert customAnalyzer.getOffsetGap(null) == 1; // note: we don't support 
setting the offset gap
   }
 
diff --git 
a/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java 
b/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
index dba39e6..a92005f 100644
--- a/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
+++ b/solr/core/src/java/org/apache/solr/highlight/DefaultSolrHighlighter.java
@@ -972,12 +972,14 @@ public class DefaultSolrHighlighter extends 
SolrHighlighter implements PluginInf
     }
   }
 
+
   /**
    * Wraps a DirectoryReader that caches the {@link 
LeafReader#getTermVectors(int)} so that
    * if the next call has the same ID, then it is reused.
    */
   static class TermVectorReusingLeafReader extends FilterLeafReader {
 
+
     private int lastDocId = -1;
     private Fields tvFields;
 
@@ -994,6 +996,7 @@ public class DefaultSolrHighlighter extends SolrHighlighter 
implements PluginInf
       return tvFields;
     }
 
+
     @Override
     public CacheHelper getCoreCacheHelper() {
       return null;
diff --git 
a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java 
b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
index 14b4c0f..981f5a9 100644
--- a/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
+++ b/solr/core/src/java/org/apache/solr/index/SlowCompositeReaderWrapper.java
@@ -241,10 +241,9 @@ public final class SlowCompositeReaderWrapper extends 
LeafReader {
     ensureOpen();
     return MultiDocValues.getNormValues(in, field); // TODO cache?
   }
-  
+
   @Override
   public Fields getTermVectors(int docID) throws IOException {
-    ensureOpen();
     return in.getTermVectors(docID);
   }
 
@@ -281,13 +280,12 @@ public final class SlowCompositeReaderWrapper extends 
LeafReader {
   @Override
   public VectorValues getVectorValues(String field) {
     ensureOpen();
-    return null; // because not supported.  Throw UOE?
+    return VectorValues.EMPTY;
   }
 
   @Override
-  public TopDocs searchNearestVectors(String field, float[] target, int k, int 
fanout)
+  public TopDocs searchNearestVectors(String field, float[] target, int k, 
Bits acceptDocs)
       throws IOException {
-    ensureOpen();
     return null; // because not supported.  Throw UOE?
   }
 
diff --git a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java 
b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
index fc12c6b..54b0574 100644
--- a/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
+++ b/solr/core/src/java/org/apache/solr/parser/SolrQueryParserBase.java
@@ -1254,7 +1254,7 @@ public abstract class SolrQueryParserBase extends 
QueryBuilder {
             Automata.makeChar(factory.getMarkerChar()),
             Automata.makeAnyString());
         // subtract these away
-        automaton = Operations.minus(automaton, falsePositives, 
Operations.DEFAULT_MAX_DETERMINIZED_STATES);
+        automaton = Operations.minus(automaton, falsePositives, 
Operations.DEFAULT_DETERMINIZE_WORK_LIMIT);
       }
       return new AutomatonQuery(term, automaton) {
         // override toString so it's completely transparent
diff --git a/solr/core/src/java/org/apache/solr/schema/FieldType.java 
b/solr/core/src/java/org/apache/solr/schema/FieldType.java
index f3e995c..0a7a47a 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldType.java
@@ -64,7 +64,6 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.CharsRef;
 import org.apache.lucene.util.CharsRefBuilder;
-import org.apache.lucene.util.Version;
 import org.apache.solr.analysis.SolrAnalyzer;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.common.IteratorWriter;
@@ -1264,9 +1263,6 @@ public abstract class FieldType extends FieldProperties {
       }
     } else { // analyzer is not instanceof TokenizerChain
       analyzerProps.add(CLASS_NAME, analyzer.getClass().getName());
-      if (analyzer.getVersion() != Version.LATEST) {
-        analyzerProps.add(LUCENE_MATCH_VERSION_PARAM, 
analyzer.getVersion().toString());
-      }
     }
     return analyzerProps;
   }
diff --git 
a/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java 
b/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
index 2e35dc5..8693e76 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
@@ -221,7 +221,6 @@ public final class FieldTypePluginLoader
               "Configuration Error: Analyzer '" + clazz.getName() +
                   "' needs a '" + IndexSchema.LUCENE_MATCH_VERSION_PARAM + "' 
parameter");
         }
-        analyzer.setVersion(luceneMatchVersion);
         return analyzer;
       } catch (Exception e) {
         log.error("Cannot load analyzer: {}", analyzerName, e);
diff --git a/solr/core/src/java/org/apache/solr/schema/SchemaField.java 
b/solr/core/src/java/org/apache/solr/schema/SchemaField.java
index 3d7740e..ebb3c0c 100644
--- a/solr/core/src/java/org/apache/solr/schema/SchemaField.java
+++ b/solr/core/src/java/org/apache/solr/schema/SchemaField.java
@@ -26,7 +26,7 @@ import org.apache.lucene.index.DocValuesType;
 import org.apache.lucene.index.IndexOptions;
 import org.apache.lucene.index.IndexableField;
 import org.apache.lucene.index.IndexableFieldType;
-import org.apache.lucene.index.VectorValues;
+import org.apache.lucene.index.VectorSimilarityFunction;
 import org.apache.lucene.search.SortField;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.util.SimpleOrderedMap;
@@ -454,8 +454,8 @@ public final class SchemaField extends FieldProperties 
implements IndexableField
   }
 
   @Override
-  public VectorValues.SimilarityFunction vectorSimilarityFunction() {
-    return VectorValues.SimilarityFunction.NONE;
+  public VectorSimilarityFunction vectorSimilarityFunction() {
+    return VectorSimilarityFunction.EUCLIDEAN;
   }
 
   @Override
diff --git 
a/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParser.java 
b/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParser.java
index 42fa504..1663c93 100644
--- a/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParser.java
+++ b/solr/core/src/java/org/apache/solr/search/ExtendedDismaxQParser.java
@@ -40,6 +40,7 @@ import org.apache.lucene.queries.function.FunctionScoreQuery;
 import org.apache.lucene.queries.function.ValueSource;
 import org.apache.lucene.queries.function.valuesource.ProductFloatFunction;
 import org.apache.lucene.queries.function.valuesource.QueryValueSource;
+import org.apache.lucene.queries.spans.SpanQuery;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.BoostQuery;
@@ -48,7 +49,6 @@ import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.MultiPhraseQuery;
 import org.apache.lucene.search.PhraseQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
diff --git 
a/solr/core/src/java/org/apache/solr/search/PayloadCheckQParserPlugin.java 
b/solr/core/src/java/org/apache/solr/search/PayloadCheckQParserPlugin.java
index a4a3db5..811fe6b 100644
--- a/solr/core/src/java/org/apache/solr/search/PayloadCheckQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/PayloadCheckQParserPlugin.java
@@ -31,8 +31,8 @@ import org.apache.lucene.analysis.payloads.PayloadEncoder;
 import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery;
 import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.MatchOperation;
 import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery.PayloadType;
+import org.apache.lucene.queries.spans.SpanQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.SolrParams;
diff --git 
a/solr/core/src/java/org/apache/solr/search/PayloadScoreQParserPlugin.java 
b/solr/core/src/java/org/apache/solr/search/PayloadScoreQParserPlugin.java
index 45f39c7..a2797a2 100644
--- a/solr/core/src/java/org/apache/solr/search/PayloadScoreQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/PayloadScoreQParserPlugin.java
@@ -23,8 +23,8 @@ import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.queries.payloads.PayloadDecoder;
 import org.apache.lucene.queries.payloads.PayloadFunction;
 import org.apache.lucene.queries.payloads.PayloadScoreQuery;
+import org.apache.lucene.queries.spans.SpanQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.request.SolrQueryRequest;
diff --git 
a/solr/core/src/java/org/apache/solr/search/similarities/BM25SimilarityFactory.java
 
b/solr/core/src/java/org/apache/solr/search/similarities/BM25SimilarityFactory.java
index 2a01d28..8c1661e 100644
--- 
a/solr/core/src/java/org/apache/solr/search/similarities/BM25SimilarityFactory.java
+++ 
b/solr/core/src/java/org/apache/solr/search/similarities/BM25SimilarityFactory.java
@@ -23,6 +23,7 @@ import org.apache.solr.schema.SimilarityFactory;
 
 /**
  * Factory for BM25Similarity. This is the default similarity since 8.x.
+ *
  * <p>
  * Parameters:
  * <ul>
diff --git 
a/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
 
b/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
index d08e918..9609e0f 100644
--- 
a/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
+++ 
b/solr/core/src/java/org/apache/solr/search/similarities/SchemaSimilarityFactory.java
@@ -31,11 +31,15 @@ import org.apache.solr.util.plugin.SolrCoreAware;
  * <p>
  * <code>SimilarityFactory</code> that returns a global {@link 
PerFieldSimilarityWrapper}
  * that delegates to the field type, if it's configured.  For field types that
- * do not have a <code>Similarity</code> explicitly configured, the global 
<code>Similarity</code> 
- * will use per fieldtype defaults -- either based on an explicitly configured 
- * <code>defaultSimFromFieldType</code> or {@link BM25Similarity} as a 
sensible default.
+ * do not have a <code>Similarity</code> explicitly configured, the global 
<code>Similarity</code>
+ * will use per fieldtype defaults -- either based on an explicitly configured
+ * <code>defaultSimFromFieldType</code> a sensible default:
+ * </p>
+ * <ul>
+ *  <li><code>luceneMatchVersion &gt;= 8.0</code> = {@link BM25Similarity}</li>
+ * </ul>
  * <p>
- * The <code>defaultSimFromFieldType</code> option accepts the name of any 
fieldtype, and uses 
+ * The <code>defaultSimFromFieldType</code> option accepts the name of any 
fieldtype, and uses
  * whatever <code>Similarity</code> is explicitly configured for that 
fieldType as the default for
  * all other field types.  For example:
  * </p>
@@ -55,15 +59,15 @@ import org.apache.solr.util.plugin.SolrCoreAware;
  *   &lt;/fieldType&gt;
  * </pre>
  * <p>
- * In the example above, any fieldtypes that do not define their own 
<code>&lt;/similarity/&gt;</code> 
+ * In the example above, any fieldtypes that do not define their own 
<code>&lt;/similarity/&gt;</code>
  * will use the <code>Similarity</code> configured for the 
<code>type-using-custom-dfr</code>.
  * </p>
- * 
+ *
  * <p>
- * <b>NOTE:</b> Users should be aware that even when this factory uses a 
single default 
- * <code>Similarity</code> for some or all fields in a Query, the behavior can 
be inconsistent 
- * with the behavior of explicitly configuring that same 
<code>Similarity</code> globally, because 
- * of differences in how some multi-field / multi-clause behavior is defined 
in 
+ * <b>NOTE:</b> Users should be aware that even when this factory uses a 
single default
+ * <code>Similarity</code> for some or all fields in a Query, the behavior can 
be inconsistent
+ * with the behavior of explicitly configuring that same 
<code>Similarity</code> globally, because
+ * of differences in how some multi-field / multi-clause behavior is defined in
  * <code>PerFieldSimilarityWrapper</code>.
  * </p>
  *
@@ -72,9 +76,9 @@ import org.apache.solr.util.plugin.SolrCoreAware;
 public class SchemaSimilarityFactory extends SimilarityFactory implements 
SolrCoreAware {
 
   private static final String INIT_OPT = "defaultSimFromFieldType";
-  
+
   private String defaultSimFromFieldType; // set by init, if null use sensible 
implicit default
-  
+
   private volatile SolrCore core; // set by inform(SolrCore)
   private volatile Similarity similarity; // lazy instantiated
 
@@ -82,7 +86,7 @@ public class SchemaSimilarityFactory extends 
SimilarityFactory implements SolrCo
   public void inform(SolrCore core) {
     this.core = core;
   }
-  
+
   @Override
   public void init(SolrParams args) {
     defaultSimFromFieldType = args.get(INIT_OPT, null);
@@ -97,7 +101,7 @@ public class SchemaSimilarityFactory extends 
SimilarityFactory implements SolrCo
     if (null == similarity) {
       // Need to instantiate lazily, can't do this in inform(SolrCore) because 
of chicken/egg
       // circular initialization hell with core.getLatestSchema() to lookup 
defaultSimFromFieldType
-      
+
       Similarity defaultSim = null;
       if (null == defaultSimFromFieldType) {
         // nothing configured, choose a sensible implicit default...
@@ -106,23 +110,23 @@ public class SchemaSimilarityFactory extends 
SimilarityFactory implements SolrCo
         FieldType defSimFT = 
core.getLatestSchema().getFieldTypeByName(defaultSimFromFieldType);
         if (null == defSimFT) {
           throw new SolrException(ErrorCode.SERVER_ERROR,
-                                  "SchemaSimilarityFactory configured with " + 
INIT_OPT + "='" +
-                                  defaultSimFromFieldType + "' but that 
<fieldType> does not exist");
-                                  
+              "SchemaSimilarityFactory configured with " + INIT_OPT + "='" +
+                  defaultSimFromFieldType + "' but that <fieldType> does not 
exist");
+
         }
         defaultSim = defSimFT.getSimilarity();
         if (null == defaultSim) {
           throw new SolrException(ErrorCode.SERVER_ERROR,
-                                  "SchemaSimilarityFactory configured with " + 
INIT_OPT + "='" + 
-                                  defaultSimFromFieldType +
-                                  "' but that <fieldType> does not define a 
<similarity>");
+              "SchemaSimilarityFactory configured with " + INIT_OPT + "='" +
+                  defaultSimFromFieldType +
+                  "' but that <fieldType> does not define a <similarity>");
         }
       }
       similarity = new SchemaSimilarity(defaultSim);
     }
     return similarity;
   }
-  
+
   private class SchemaSimilarity extends PerFieldSimilarityWrapper {
     private Similarity defaultSimilarity;
 
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookup.java
 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookup.java
new file mode 100644
index 0000000..ecbb7f6
--- /dev/null
+++ 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookup.java
@@ -0,0 +1,208 @@
+/*
+ * 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.
+ */
+package org.apache.solr.spelling.suggest.jaspell;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import org.apache.lucene.search.suggest.InputIterator;
+import org.apache.lucene.search.suggest.Lookup;
+import org.apache.lucene.store.DataInput;
+import org.apache.lucene.store.DataOutput;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.CharsRef;
+import org.apache.lucene.util.CharsRefBuilder;
+import 
org.apache.solr.spelling.suggest.jaspell.JaspellTernarySearchTrie.TSTNode;
+
+/**
+ * Suggest implementation based on <a 
href="http://jaspell.sourceforge.net/";>JaSpell</a>.
+ *
+ * @see JaspellTernarySearchTrie
+ * @deprecated Migrate to one of the newer suggesters which are much more RAM 
efficient.
+ */
+@Deprecated
+public class JaspellLookup extends Lookup {
+  JaspellTernarySearchTrie trie = new JaspellTernarySearchTrie();
+  private boolean usePrefix = true;
+  private int editDistance = 2;
+
+  /** Number of entries the lookup was built with */
+  private long count = 0;
+
+  /**
+   * Creates a new empty trie
+   *
+   * @see #build(InputIterator)
+   */
+  public JaspellLookup() {}
+
+  @Override
+  public void build(InputIterator iterator) throws IOException {
+    if (iterator.hasPayloads()) {
+      throw new IllegalArgumentException("this suggester doesn't support 
payloads");
+    }
+    if (iterator.hasContexts()) {
+      throw new IllegalArgumentException("this suggester doesn't support 
contexts");
+    }
+    count = 0;
+    trie = new JaspellTernarySearchTrie();
+    trie.setMatchAlmostDiff(editDistance);
+    BytesRef spare;
+    final CharsRefBuilder charsSpare = new CharsRefBuilder();
+
+    while ((spare = iterator.next()) != null) {
+      final long weight = iterator.weight();
+      if (spare.length == 0) {
+        continue;
+      }
+      charsSpare.copyUTF8Bytes(spare);
+      trie.put(charsSpare.toString(), weight);
+      count++;
+    }
+  }
+
+  /**
+   * Adds a new node if <code>key</code> already exists, otherwise replaces 
its value.
+   *
+   * <p>This method always returns false.
+   */
+  public boolean add(CharSequence key, Object value) {
+    trie.put(key, value);
+    // XXX
+    return false;
+  }
+
+  /** Returns the value for the specified key, or null if the key does not 
exist. */
+  public Object get(CharSequence key) {
+    return trie.get(key);
+  }
+
+  @Override
+  public List<LookupResult> lookup(
+      CharSequence key, Set<BytesRef> contexts, boolean onlyMorePopular, int 
num) {
+    if (contexts != null) {
+      throw new IllegalArgumentException("this suggester doesn't support 
contexts");
+    }
+    List<LookupResult> res = new ArrayList<>();
+    List<String> list;
+    int count = onlyMorePopular ? num * 2 : num;
+    if (usePrefix) {
+      list = trie.matchPrefix(key, count);
+    } else {
+      list = trie.matchAlmost(key, count);
+    }
+    if (list == null || list.size() == 0) {
+      return res;
+    }
+    int maxCnt = Math.min(num, list.size());
+    if (onlyMorePopular) {
+      LookupPriorityQueue queue = new LookupPriorityQueue(num);
+      for (String s : list) {
+        long freq = ((Number) trie.get(s)).longValue();
+        queue.insertWithOverflow(new LookupResult(new CharsRef(s), freq));
+      }
+      for (LookupResult lr : queue.getResults()) {
+        res.add(lr);
+      }
+    } else {
+      for (int i = 0; i < maxCnt; i++) {
+        String s = list.get(i);
+        long freq = ((Number) trie.get(s)).longValue();
+        res.add(new LookupResult(new CharsRef(s), freq));
+      }
+    }
+    return res;
+  }
+
+  private static final byte LO_KID = 0x01;
+  private static final byte EQ_KID = 0x02;
+  private static final byte HI_KID = 0x04;
+  private static final byte HAS_VALUE = 0x08;
+
+  private void readRecursively(DataInput in, TSTNode node) throws IOException {
+    node.splitchar = in.readString().charAt(0);
+    byte mask = in.readByte();
+    if ((mask & HAS_VALUE) != 0) {
+      node.data = in.readLong();
+    }
+    if ((mask & LO_KID) != 0) {
+      TSTNode kid = new TSTNode('\0', node);
+      node.relatives[TSTNode.LOKID] = kid;
+      readRecursively(in, kid);
+    }
+    if ((mask & EQ_KID) != 0) {
+      TSTNode kid = new TSTNode('\0', node);
+      node.relatives[TSTNode.EQKID] = kid;
+      readRecursively(in, kid);
+    }
+    if ((mask & HI_KID) != 0) {
+      TSTNode kid = new TSTNode('\0', node);
+      node.relatives[TSTNode.HIKID] = kid;
+      readRecursively(in, kid);
+    }
+  }
+
+  private void writeRecursively(DataOutput out, TSTNode node) throws 
IOException {
+    if (node == null) {
+      return;
+    }
+    out.writeString(new String(new char[] {node.splitchar}, 0, 1));
+    byte mask = 0;
+    if (node.relatives[TSTNode.LOKID] != null) mask |= LO_KID;
+    if (node.relatives[TSTNode.EQKID] != null) mask |= EQ_KID;
+    if (node.relatives[TSTNode.HIKID] != null) mask |= HI_KID;
+    if (node.data != null) mask |= HAS_VALUE;
+    out.writeByte(mask);
+    if (node.data != null) {
+      out.writeLong(((Number) node.data).longValue());
+    }
+    writeRecursively(out, node.relatives[TSTNode.LOKID]);
+    writeRecursively(out, node.relatives[TSTNode.EQKID]);
+    writeRecursively(out, node.relatives[TSTNode.HIKID]);
+  }
+
+  @Override
+  public boolean store(DataOutput output) throws IOException {
+    output.writeVLong(count);
+    TSTNode root = trie.getRoot();
+    if (root == null) { // empty tree
+      return false;
+    }
+    writeRecursively(output, root);
+    return true;
+  }
+
+  @Override
+  public boolean load(DataInput input) throws IOException {
+    count = input.readVLong();
+    TSTNode root = new TSTNode('\0', null);
+    readRecursively(input, root);
+    trie.setRoot(root);
+    return true;
+  }
+
+  @Override
+  public long ramBytesUsed() {
+    return trie.ramBytesUsed();
+  }
+
+  @Override
+  public long getCount() {
+    return count;
+  }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookupFactory.java
 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookupFactory.java
index f64bc98..07c9978 100644
--- 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookupFactory.java
+++ 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellLookupFactory.java
@@ -19,7 +19,6 @@ package org.apache.solr.spelling.suggest.jaspell;
 import java.lang.invoke.MethodHandles;
 
 import org.apache.lucene.search.suggest.Lookup;
-import org.apache.lucene.search.suggest.jaspell.JaspellLookup;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.spelling.suggest.LookupFactory;
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellTernarySearchTrie.java
 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellTernarySearchTrie.java
new file mode 100644
index 0000000..4aad9c3
--- /dev/null
+++ 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/JaspellTernarySearchTrie.java
@@ -0,0 +1,831 @@
+/*
+ * Copyright (c) 2005 Bruno Martins
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the organization nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.apache.solr.spelling.suggest.jaspell;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.zip.GZIPInputStream;
+import org.apache.lucene.util.Accountable;
+import org.apache.lucene.util.IOUtils;
+import org.apache.lucene.util.RamUsageEstimator;
+
+/**
+ * Implementation of a Ternary Search Trie, a data structure for storing 
<code>String</code> objects
+ * that combines the compact size of a binary search tree with the speed of a 
digital search trie,
+ * and is therefore ideal for practical use in sorting and searching data.
+ *
+ * <p>This data structure is faster than hashing for many typical search 
problems, and supports a
+ * broader range of useful problems and operations. Ternary searches are 
faster than hashing and
+ * more powerful, too.
+ *
+ * <p>The theory of ternary search trees was described at a symposium in 1997 
(see "Fast Algorithms
+ * for Sorting and Searching Strings," by J.L. Bentley and R. Sedgewick, 
Proceedings of the 8th
+ * Annual ACM-SIAM Symposium on Discrete Algorithms, January 1997). Algorithms 
in C, Third Edition,
+ * by Robert Sedgewick (Addison-Wesley, 1998) provides yet another view of 
ternary search trees.
+ *
+ * @deprecated Migrate to one of the newer suggesters which are much more RAM 
efficient.
+ */
+@Deprecated
+public class JaspellTernarySearchTrie implements Accountable {
+
+  /** An inner class of Ternary Search Trie that represents a node in the 
trie. */
+  protected static final class TSTNode implements Accountable {
+
+    /** Index values for accessing relatives array. */
+    protected static final int PARENT = 0, LOKID = 1, EQKID = 2, HIKID = 3;
+
+    /** The key to the node. */
+    protected Object data;
+
+    /** The relative nodes. */
+    protected final TSTNode[] relatives = new TSTNode[4];
+
+    /** The char used in the split. */
+    protected char splitchar;
+
+    /**
+     * Constructor method.
+     *
+     * @param splitchar The char used in the split.
+     * @param parent The parent node.
+     */
+    protected TSTNode(char splitchar, TSTNode parent) {
+      this.splitchar = splitchar;
+      relatives[PARENT] = parent;
+    }
+
+    @Override
+    public long ramBytesUsed() {
+      long mem = RamUsageEstimator.shallowSizeOf(this) + 
RamUsageEstimator.shallowSizeOf(relatives);
+      // We don't need to add parent since our parent added itself:
+      for (int i = 1; i < 4; i++) {
+        TSTNode node = relatives[i];
+        if (node != null) {
+          mem += node.ramBytesUsed();
+        }
+      }
+      return mem;
+    }
+  }
+
+  /**
+   * Compares characters by alphabetical order.
+   *
+   * @param cCompare2 The first char in the comparison.
+   * @param cRef The second char in the comparison.
+   * @return A negative number, 0 or a positive number if the second char is 
less, equal or greater.
+   */
+  private static int compareCharsAlphabetically(char cCompare2, char cRef) {
+    return Character.toLowerCase(cCompare2) - Character.toLowerCase(cRef);
+  }
+
+  /* what follows is the original Jaspell code.
+  private static int compareCharsAlphabetically(int cCompare2, int cRef) {
+    int cCompare = 0;
+    if (cCompare2 >= 65) {
+      if (cCompare2 < 89) {
+        cCompare = (2 * cCompare2) - 65;
+      } else if (cCompare2 < 97) {
+        cCompare = cCompare2 + 24;
+      } else if (cCompare2 < 121) {
+        cCompare = (2 * cCompare2) - 128;
+      } else cCompare = cCompare2;
+    } else cCompare = cCompare2;
+    if (cRef < 65) {
+      return cCompare - cRef;
+    }
+    if (cRef < 89) {
+      return cCompare - ((2 * cRef) - 65);
+    }
+    if (cRef < 97) {
+      return cCompare - (cRef + 24);
+    }
+    if (cRef < 121) {
+      return cCompare - ((2 * cRef) - 128);
+    }
+    return cCompare - cRef;
+  }
+  */
+
+  /** The default number of values returned by the <code>matchAlmost</code> 
method. */
+  private int defaultNumReturnValues = -1;
+
+  /** the number of differences allowed in a call to the 
<code>matchAlmostKey</code> method. */
+  private int matchAlmostDiff;
+
+  /** The base node in the trie. */
+  private TSTNode rootNode;
+
+  private final Locale locale;
+
+  /** Constructs an empty Ternary Search Trie. */
+  public JaspellTernarySearchTrie() {
+    this(Locale.ROOT);
+  }
+
+  /** Constructs an empty Ternary Search Trie, specifying the Locale used for 
lowercasing. */
+  public JaspellTernarySearchTrie(Locale locale) {
+    this.locale = locale;
+  }
+
+  // for loading
+  void setRoot(TSTNode newRoot) {
+    rootNode = newRoot;
+  }
+
+  // for saving
+  TSTNode getRoot() {
+    return rootNode;
+  }
+
+  /**
+   * Constructs a Ternary Search Trie and loads data from a <code>Path</code> 
into the Trie. The
+   * file is a normal text document, where each line is of the form word TAB 
float.
+   *
+   * @param file The <code>Path</code> with the data to load into the Trie.
+   * @exception IOException A problem occurred while reading the data.
+   */
+  public JaspellTernarySearchTrie(Path file) throws IOException {
+    this(file, false);
+  }
+
+  /**
+   * Constructs a Ternary Search Trie and loads data from a <code>File</code> 
into the Trie. The
+   * file is a normal text document, where each line is of the form "word TAB 
float".
+   *
+   * @param file The <code>File</code> with the data to load into the Trie.
+   * @param compression If true, the file is compressed with the GZIP 
algorithm, and if false, the
+   *     file is a normal text document.
+   * @exception IOException A problem occurred while reading the data.
+   */
+  public JaspellTernarySearchTrie(Path file, boolean compression) throws 
IOException {
+    this();
+    BufferedReader in;
+    if (compression)
+      in =
+          new BufferedReader(
+              IOUtils.getDecodingReader(
+                  new GZIPInputStream(Files.newInputStream(file)), 
StandardCharsets.UTF_8));
+    else in = Files.newBufferedReader(file, StandardCharsets.UTF_8);
+    try {
+      String word;
+      int pos;
+      Float occur, one = 1f;
+      while ((word = in.readLine()) != null) {
+        pos = word.indexOf("\t");
+        occur = one;
+        if (pos != -1) {
+          occur = Float.parseFloat(word.substring(pos + 1).trim());
+          word = word.substring(0, pos);
+        }
+        String key = word.toLowerCase(locale);
+        if (rootNode == null) {
+          rootNode = new TSTNode(key.charAt(0), null);
+        }
+        TSTNode node = null;
+        if (key.length() > 0 && rootNode != null) {
+          TSTNode currentNode = rootNode;
+          int charIndex = 0;
+          while (true) {
+            if (currentNode == null) break;
+            int charComp = compareCharsAlphabetically(key.charAt(charIndex), 
currentNode.splitchar);
+            if (charComp == 0) {
+              charIndex++;
+              if (charIndex == key.length()) {
+                node = currentNode;
+                break;
+              }
+              currentNode = currentNode.relatives[TSTNode.EQKID];
+            } else if (charComp < 0) {
+              currentNode = currentNode.relatives[TSTNode.LOKID];
+            } else {
+              currentNode = currentNode.relatives[TSTNode.HIKID];
+            }
+          }
+          Float occur2 = null;
+          if (node != null) occur2 = ((Float) (node.data));
+          if (occur2 != null) {
+            occur += occur2.floatValue();
+          }
+          currentNode = getOrCreateNode(word.trim().toLowerCase(locale));
+          currentNode.data = occur;
+        }
+      }
+    } finally {
+      IOUtils.close(in);
+    }
+  }
+
+  /**
+   * Deletes the node passed in as an argument. If this node has non-null 
data, then both the node
+   * and the data will be deleted. It also deletes any other nodes in the trie 
that are no longer
+   * needed after the deletion of the node.
+   *
+   * @param nodeToDelete The node to delete.
+   */
+  private void deleteNode(TSTNode nodeToDelete) {
+    if (nodeToDelete == null) {
+      return;
+    }
+    nodeToDelete.data = null;
+    while (nodeToDelete != null) {
+      nodeToDelete = deleteNodeRecursion(nodeToDelete);
+      // deleteNodeRecursion(nodeToDelete);
+    }
+  }
+
+  /**
+   * Recursively visits each node to be deleted.
+   *
+   * <p>To delete a node, first set its data to null, then pass it into this 
method, then pass the
+   * node returned by this method into this method (make sure you don't delete 
the data of any of
+   * the nodes returned from this method!) and continue in this fashion until 
the node returned by
+   * this method is <code>null</code>.
+   *
+   * <p>The TSTNode instance returned by this method will be next node to be 
operated on by <code>
+   * deleteNodeRecursion</code> (This emulates recursive method call while 
avoiding the JVM overhead
+   * normally associated with a recursive method.)
+   *
+   * @param currentNode The node to delete.
+   * @return The next node to be called in deleteNodeRecursion.
+   */
+  private TSTNode deleteNodeRecursion(TSTNode currentNode) {
+    if (currentNode == null) {
+      return null;
+    }
+    if (currentNode.relatives[TSTNode.EQKID] != null || currentNode.data != 
null) {
+      return null;
+    }
+    // can't delete this node if it has a non-null eq kid or data
+    TSTNode currentParent = currentNode.relatives[TSTNode.PARENT];
+    boolean lokidNull = currentNode.relatives[TSTNode.LOKID] == null;
+    boolean hikidNull = currentNode.relatives[TSTNode.HIKID] == null;
+    int childType;
+    if (currentParent.relatives[TSTNode.LOKID] == currentNode) {
+      childType = TSTNode.LOKID;
+    } else if (currentParent.relatives[TSTNode.EQKID] == currentNode) {
+      childType = TSTNode.EQKID;
+    } else if (currentParent.relatives[TSTNode.HIKID] == currentNode) {
+      childType = TSTNode.HIKID;
+    } else {
+      rootNode = null;
+      return null;
+    }
+    if (lokidNull && hikidNull) {
+      currentParent.relatives[childType] = null;
+      return currentParent;
+    }
+    if (lokidNull) {
+      currentParent.relatives[childType] = 
currentNode.relatives[TSTNode.HIKID];
+      currentNode.relatives[TSTNode.HIKID].relatives[TSTNode.PARENT] = 
currentParent;
+      return currentParent;
+    }
+    if (hikidNull) {
+      currentParent.relatives[childType] = 
currentNode.relatives[TSTNode.LOKID];
+      currentNode.relatives[TSTNode.LOKID].relatives[TSTNode.PARENT] = 
currentParent;
+      return currentParent;
+    }
+    int deltaHi = currentNode.relatives[TSTNode.HIKID].splitchar - 
currentNode.splitchar;
+    int deltaLo = currentNode.splitchar - 
currentNode.relatives[TSTNode.LOKID].splitchar;
+    int movingKid;
+    TSTNode targetNode;
+    if (deltaHi == deltaLo) {
+      if (Math.random() < 0.5) {
+        deltaHi++;
+      } else {
+        deltaLo++;
+      }
+    }
+    if (deltaHi > deltaLo) {
+      movingKid = TSTNode.HIKID;
+      targetNode = currentNode.relatives[TSTNode.LOKID];
+    } else {
+      movingKid = TSTNode.LOKID;
+      targetNode = currentNode.relatives[TSTNode.HIKID];
+    }
+    while (targetNode.relatives[movingKid] != null) {
+      targetNode = targetNode.relatives[movingKid];
+    }
+    targetNode.relatives[movingKid] = currentNode.relatives[movingKid];
+    currentParent.relatives[childType] = targetNode;
+    targetNode.relatives[TSTNode.PARENT] = currentParent;
+    if (!lokidNull) {
+      currentNode.relatives[TSTNode.LOKID] = null;
+    }
+    if (!hikidNull) {
+      currentNode.relatives[TSTNode.HIKID] = null;
+    }
+    return currentParent;
+  }
+
+  /**
+   * Retrieve the object indexed by a key.
+   *
+   * @param key A <code>String</code> index.
+   * @return The object retrieved from the Ternary Search Trie.
+   */
+  public Object get(CharSequence key) {
+    TSTNode node = getNode(key);
+    if (node == null) {
+      return null;
+    }
+    return node.data;
+  }
+
+  /**
+   * Retrieve the <code>Float</code> indexed by key, increment it by one unit 
and store the new
+   * <code>Float</code>.
+   *
+   * @param key A <code>String</code> index.
+   * @return The <code>Float</code> retrieved from the Ternary Search Trie.
+   */
+  public Float getAndIncrement(String key) {
+    String key2 = key.trim().toLowerCase(locale);
+    TSTNode node = getNode(key2);
+    if (node == null) {
+      return null;
+    }
+    Float aux = (Float) (node.data);
+    if (aux == null) {
+      aux = 1f;
+    } else {
+      aux = (float) (aux.intValue() + 1);
+    }
+    put(key2, aux);
+    return aux;
+  }
+
+  /**
+   * Returns the key that indexes the node argument.
+   *
+   * @param node The node whose index is to be calculated.
+   * @return The <code>String</code> that indexes the node argument.
+   */
+  protected String getKey(TSTNode node) {
+    StringBuilder getKeyBuffer = new StringBuilder();
+    getKeyBuffer.setLength(0);
+    getKeyBuffer.append("").append(node.splitchar);
+    TSTNode currentNode;
+    TSTNode lastNode;
+    currentNode = node.relatives[TSTNode.PARENT];
+    lastNode = node;
+    while (currentNode != null) {
+      if (currentNode.relatives[TSTNode.EQKID] == lastNode) {
+        getKeyBuffer.append("").append(currentNode.splitchar);
+      }
+      lastNode = currentNode;
+      currentNode = currentNode.relatives[TSTNode.PARENT];
+    }
+    getKeyBuffer.reverse();
+    return getKeyBuffer.toString();
+  }
+
+  /**
+   * Returns the node indexed by key, or <code>null</code> if that node 
doesn't exist. Search begins
+   * at root node.
+   *
+   * @param key A <code>String</code> that indexes the node that is returned.
+   * @return The node object indexed by key. This object is an instance of an 
inner class named
+   *     <code>TernarySearchTrie.TSTNode</code>.
+   */
+  public TSTNode getNode(CharSequence key) {
+    return getNode(key, rootNode);
+  }
+
+  /**
+   * Returns the node indexed by key, or <code>null</code> if that node 
doesn't exist. The search
+   * begins at root node.
+   *
+   * @param key A <code>String</code> that indexes the node that is returned.
+   * @param startNode The top node defining the subtrie to be searched.
+   * @return The node object indexed by key. This object is an instance of an 
inner class named
+   *     <code>TernarySearchTrie.TSTNode</code>.
+   */
+  protected TSTNode getNode(CharSequence key, TSTNode startNode) {
+    if (key == null || startNode == null || key.length() == 0) {
+      return null;
+    }
+    TSTNode currentNode = startNode;
+    int charIndex = 0;
+    while (true) {
+      if (currentNode == null) {
+        return null;
+      }
+      int charComp = compareCharsAlphabetically(key.charAt(charIndex), 
currentNode.splitchar);
+      if (charComp == 0) {
+        charIndex++;
+        if (charIndex == key.length()) {
+          return currentNode;
+        }
+        currentNode = currentNode.relatives[TSTNode.EQKID];
+      } else if (charComp < 0) {
+        currentNode = currentNode.relatives[TSTNode.LOKID];
+      } else {
+        currentNode = currentNode.relatives[TSTNode.HIKID];
+      }
+    }
+  }
+
+  /**
+   * Returns the node indexed by key, creating that node if it doesn't exist, 
and creating any
+   * required intermediate nodes if they don't exist.
+   *
+   * @param key A <code>String</code> that indexes the node that is returned.
+   * @return The node object indexed by key. This object is an instance of an 
inner class named
+   *     <code>TernarySearchTrie.TSTNode</code>.
+   * @exception NullPointerException If the key is <code>null</code>.
+   * @exception IllegalArgumentException If the key is an empty 
<code>String</code>.
+   */
+  protected TSTNode getOrCreateNode(CharSequence key)
+      throws NullPointerException, IllegalArgumentException {
+    if (key == null) {
+      throw new NullPointerException("attempt to get or create node with null 
key");
+    }
+    if (key.length() == 0) {
+      throw new IllegalArgumentException("attempt to get or create node with 
key of zero length");
+    }
+    if (rootNode == null) {
+      rootNode = new TSTNode(key.charAt(0), null);
+    }
+    TSTNode currentNode = rootNode;
+    int charIndex = 0;
+    while (true) {
+      int charComp = compareCharsAlphabetically(key.charAt(charIndex), 
currentNode.splitchar);
+      if (charComp == 0) {
+        charIndex++;
+        if (charIndex == key.length()) {
+          return currentNode;
+        }
+        if (currentNode.relatives[TSTNode.EQKID] == null) {
+          currentNode.relatives[TSTNode.EQKID] = new 
TSTNode(key.charAt(charIndex), currentNode);
+        }
+        currentNode = currentNode.relatives[TSTNode.EQKID];
+      } else if (charComp < 0) {
+        if (currentNode.relatives[TSTNode.LOKID] == null) {
+          currentNode.relatives[TSTNode.LOKID] = new 
TSTNode(key.charAt(charIndex), currentNode);
+        }
+        currentNode = currentNode.relatives[TSTNode.LOKID];
+      } else {
+        if (currentNode.relatives[TSTNode.HIKID] == null) {
+          currentNode.relatives[TSTNode.HIKID] = new 
TSTNode(key.charAt(charIndex), currentNode);
+        }
+        currentNode = currentNode.relatives[TSTNode.HIKID];
+      }
+    }
+  }
+
+  /**
+   * Returns a <code>List</code> of keys that almost match the argument key. 
Keys returned will have
+   * exactly diff characters that do not match the target key, where diff is 
equal to the last value
+   * passed in as an argument to the <code>setMatchAlmostDiff</code> method.
+   *
+   * <p>If the <code>matchAlmost</code> method is called before the 
<code>setMatchAlmostDiff</code>
+   * method has been called for the first time, then diff = 0.
+   *
+   * @param key The target key.
+   * @return A <code>List</code> with the results.
+   */
+  public List<String> matchAlmost(String key) {
+    return matchAlmost(key, defaultNumReturnValues);
+  }
+
+  /**
+   * Returns a <code>List</code> of keys that almost match the argument key. 
Keys returned will have
+   * exactly diff characters that do not match the target key, where diff is 
equal to the last value
+   * passed in as an argument to the <code>setMatchAlmostDiff</code> method.
+   *
+   * <p>If the <code>matchAlmost</code> method is called before the 
<code>setMatchAlmostDiff</code>
+   * method has been called for the first time, then diff = 0.
+   *
+   * @param key The target key.
+   * @param numReturnValues The maximum number of values returned by this 
method.
+   * @return A <code>List</code> with the results
+   */
+  public List<String> matchAlmost(CharSequence key, int numReturnValues) {
+    return matchAlmostRecursion(
+        rootNode,
+        0,
+        matchAlmostDiff,
+        key,
+        ((numReturnValues < 0) ? -1 : numReturnValues),
+        new Vector<String>(),
+        false);
+  }
+
+  /**
+   * Recursivelly vists the nodes in order to find the ones that almost match 
a given key.
+   *
+   * @param currentNode The current node.
+   * @param charIndex The current char.
+   * @param d The number of differences so far.
+   * @param matchAlmostNumReturnValues The maximum number of values in the 
result <code>List</code>.
+   * @param matchAlmostResult2 The results so far.
+   * @param upTo If true all keys having up to and including matchAlmostDiff 
mismatched letters will
+   *     be included in the result (including a key that is exactly the same 
as the target string)
+   *     otherwise keys will be included in the result only if they have 
exactly matchAlmostDiff
+   *     number of mismatched letters.
+   * @param matchAlmostKey The key being searched.
+   * @return A <code>List</code> with the results.
+   */
+  private List<String> matchAlmostRecursion(
+      TSTNode currentNode,
+      int charIndex,
+      int d,
+      CharSequence matchAlmostKey,
+      int matchAlmostNumReturnValues,
+      List<String> matchAlmostResult2,
+      boolean upTo) {
+    if ((currentNode == null)
+        || (matchAlmostNumReturnValues != -1
+            && matchAlmostResult2.size() >= matchAlmostNumReturnValues)
+        || (d < 0)
+        || (charIndex >= matchAlmostKey.length())) {
+      return matchAlmostResult2;
+    }
+    int charComp =
+        compareCharsAlphabetically(matchAlmostKey.charAt(charIndex), 
currentNode.splitchar);
+    List<String> matchAlmostResult = matchAlmostResult2;
+    if ((d > 0) || (charComp < 0)) {
+      matchAlmostResult =
+          matchAlmostRecursion(
+              currentNode.relatives[TSTNode.LOKID],
+              charIndex,
+              d,
+              matchAlmostKey,
+              matchAlmostNumReturnValues,
+              matchAlmostResult,
+              upTo);
+    }
+    int nextD = (charComp == 0) ? d : d - 1;
+    boolean cond = (upTo) ? (nextD >= 0) : (nextD == 0);
+    if ((matchAlmostKey.length() == charIndex + 1) && cond && 
(currentNode.data != null)) {
+      matchAlmostResult.add(getKey(currentNode));
+    }
+    matchAlmostResult =
+        matchAlmostRecursion(
+            currentNode.relatives[TSTNode.EQKID],
+            charIndex + 1,
+            nextD,
+            matchAlmostKey,
+            matchAlmostNumReturnValues,
+            matchAlmostResult,
+            upTo);
+    if ((d > 0) || (charComp > 0)) {
+      matchAlmostResult =
+          matchAlmostRecursion(
+              currentNode.relatives[TSTNode.HIKID],
+              charIndex,
+              d,
+              matchAlmostKey,
+              matchAlmostNumReturnValues,
+              matchAlmostResult,
+              upTo);
+    }
+    return matchAlmostResult;
+  }
+
+  /**
+   * Returns an alphabetical <code>List</code> of all keys in the trie that 
begin with a given
+   * prefix. Only keys for nodes having non-null data are included in the 
<code>List</code>.
+   *
+   * @param prefix Each key returned from this method will begin with the 
characters in prefix.
+   * @return A <code>List</code> with the results.
+   */
+  public List<String> matchPrefix(String prefix) {
+    return matchPrefix(prefix, defaultNumReturnValues);
+  }
+
+  /**
+   * Returns an alphabetical <code>List</code> of all keys in the trie that 
begin with a given
+   * prefix. Only keys for nodes having non-null data are included in the 
<code>List</code>.
+   *
+   * @param prefix Each key returned from this method will begin with the 
characters in prefix.
+   * @param numReturnValues The maximum number of values returned from this 
method.
+   * @return A <code>List</code> with the results
+   */
+  public List<String> matchPrefix(CharSequence prefix, int numReturnValues) {
+    Vector<String> sortKeysResult = new Vector<>();
+    TSTNode startNode = getNode(prefix);
+    if (startNode == null) {
+      return sortKeysResult;
+    }
+    if (startNode.data != null) {
+      sortKeysResult.addElement(getKey(startNode));
+    }
+    return sortKeysRecursion(
+        startNode.relatives[TSTNode.EQKID],
+        ((numReturnValues < 0) ? -1 : numReturnValues),
+        sortKeysResult);
+  }
+
+  /**
+   * Returns the number of nodes in the trie that have non-null data.
+   *
+   * @return The number of nodes in the trie that have non-null data.
+   */
+  public int numDataNodes() {
+    return numDataNodes(rootNode);
+  }
+
+  /**
+   * Returns the number of nodes in the subtrie below and including the 
starting node. The method
+   * counts only nodes that have non-null data.
+   *
+   * @param startingNode The top node of the subtrie. the node that defines 
the subtrie.
+   * @return The total number of nodes in the subtrie.
+   */
+  protected int numDataNodes(TSTNode startingNode) {
+    return recursiveNodeCalculator(startingNode, true, 0);
+  }
+
+  /**
+   * Returns the total number of nodes in the trie. The method counts nodes 
whether or not they have
+   * data.
+   *
+   * @return The total number of nodes in the trie.
+   */
+  public int numNodes() {
+    return numNodes(rootNode);
+  }
+
+  /**
+   * Returns the total number of nodes in the subtrie below and including the 
starting Node. The
+   * method counts nodes whether or not they have data.
+   *
+   * @param startingNode The top node of the subtrie. The node that defines 
the subtrie.
+   * @return The total number of nodes in the subtrie.
+   */
+  protected int numNodes(TSTNode startingNode) {
+    return recursiveNodeCalculator(startingNode, false, 0);
+  }
+
+  /**
+   * Stores a value in the trie. The value may be retrieved using the key.
+   *
+   * @param key A <code>String</code> that indexes the object to be stored.
+   * @param value The object to be stored in the Trie.
+   */
+  public void put(CharSequence key, Object value) {
+    getOrCreateNode(key).data = value;
+  }
+
+  /**
+   * Recursivelly visists each node to calculate the number of nodes.
+   *
+   * @param currentNode The current node.
+   * @param checkData If true we check the data to be different of 
<code>null</code>.
+   * @param numNodes2 The number of nodes so far.
+   * @return The number of nodes accounted.
+   */
+  private int recursiveNodeCalculator(TSTNode currentNode, boolean checkData, 
int numNodes2) {
+    if (currentNode == null) {
+      return numNodes2;
+    }
+    int numNodes =
+        recursiveNodeCalculator(currentNode.relatives[TSTNode.LOKID], 
checkData, numNodes2);
+    numNodes = recursiveNodeCalculator(currentNode.relatives[TSTNode.EQKID], 
checkData, numNodes);
+    numNodes = recursiveNodeCalculator(currentNode.relatives[TSTNode.HIKID], 
checkData, numNodes);
+    if (checkData) {
+      if (currentNode.data != null) {
+        numNodes++;
+      }
+    } else {
+      numNodes++;
+    }
+    return numNodes;
+  }
+
+  /**
+   * Removes the value indexed by key. Also removes all nodes that are 
rendered unnecessary by the
+   * removal of this data.
+   *
+   * @param key A <code>string</code> that indexes the object to be removed 
from the Trie.
+   */
+  public void remove(String key) {
+    deleteNode(getNode(key.trim().toLowerCase(locale)));
+  }
+
+  /**
+   * Sets the number of characters by which words can differ from target word 
when calling the
+   * <code>matchAlmost</code> method.
+   *
+   * <p>Arguments less than 0 will set the char difference to 0, and arguments 
greater than 3 will
+   * set the char difference to 3.
+   *
+   * @param diff The number of characters by which words can differ from 
target word.
+   */
+  public void setMatchAlmostDiff(int diff) {
+    if (diff < 0) {
+      matchAlmostDiff = 0;
+    } else if (diff > 3) {
+      matchAlmostDiff = 3;
+    } else {
+      matchAlmostDiff = diff;
+    }
+  }
+
+  /**
+   * Sets the default maximum number of values returned from the 
<code>matchPrefix</code> and <code>
+   * matchAlmost</code> methods.
+   *
+   * <p>The value should be set this to -1 to get an unlimited number of 
return values. note that
+   * the methods mentioned above provide overloaded versions that allow you to 
specify the maximum
+   * number of return values, in which case this value is temporarily 
overridden.
+   *
+   * <p>*@param num The number of values that will be returned when calling 
the methods above.
+   */
+  public void setNumReturnValues(int num) {
+    defaultNumReturnValues = (num < 0) ? -1 : num;
+  }
+
+  /**
+   * Returns keys sorted in alphabetical order. This includes the start Node 
and all nodes connected
+   * to the start Node.
+   *
+   * <p>The number of keys returned is limited to numReturnValues. To get a 
list that isn't limited
+   * in size, set numReturnValues to -1.
+   *
+   * @param startNode The top node defining the subtrie to be searched.
+   * @param numReturnValues The maximum number of values returned from this 
method.
+   * @return A <code>List</code> with the results.
+   */
+  protected List<String> sortKeys(TSTNode startNode, int numReturnValues) {
+    return sortKeysRecursion(
+        startNode, ((numReturnValues < 0) ? -1 : numReturnValues), new 
Vector<String>());
+  }
+
+  /**
+   * Returns keys sorted in alphabetical order. This includes the current Node 
and all nodes
+   * connected to the current Node.
+   *
+   * <p>Sorted keys will be appended to the end of the resulting 
<code>List</code>. The result may
+   * be empty when this method is invoked, but may not be <code>null</code>.
+   *
+   * @param currentNode The current node.
+   * @param sortKeysNumReturnValues The maximum number of values in the result.
+   * @param sortKeysResult2 The results so far.
+   * @return A <code>List</code> with the results.
+   */
+  private List<String> sortKeysRecursion(
+      TSTNode currentNode, int sortKeysNumReturnValues, List<String> 
sortKeysResult2) {
+    if (currentNode == null) {
+      return sortKeysResult2;
+    }
+    List<String> sortKeysResult =
+        sortKeysRecursion(
+            currentNode.relatives[TSTNode.LOKID], sortKeysNumReturnValues, 
sortKeysResult2);
+    if (sortKeysNumReturnValues != -1 && sortKeysResult.size() >= 
sortKeysNumReturnValues) {
+      return sortKeysResult;
+    }
+    if (currentNode.data != null) {
+      sortKeysResult.add(getKey(currentNode));
+    }
+    sortKeysResult =
+        sortKeysRecursion(
+            currentNode.relatives[TSTNode.EQKID], sortKeysNumReturnValues, 
sortKeysResult);
+    return sortKeysRecursion(
+        currentNode.relatives[TSTNode.HIKID], sortKeysNumReturnValues, 
sortKeysResult);
+  }
+
+  @Override
+  public long ramBytesUsed() {
+    long mem = RamUsageEstimator.shallowSizeOf(this);
+    final TSTNode root = getRoot();
+    if (root != null) {
+      mem += root.ramBytesUsed();
+    }
+    return mem;
+  }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/package-info.java 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/package-info.java
index 569fe8e..f8d3b77 100644
--- 
a/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/package-info.java
+++ 
b/solr/core/src/java/org/apache/solr/spelling/suggest/jaspell/package-info.java
@@ -16,7 +16,7 @@
  */
  
 /** 
- * Factories for {@linkplain org.apache.lucene.search.suggest.jaspell JaSpell} 
based {@link org.apache.solr.spelling.suggest.Suggester}s
+ * Factories for {@linkplain org.apache.solr.spelling.suggest.jaspell JaSpell} 
based {@link org.apache.solr.spelling.suggest.Suggester}s
  */
 package org.apache.solr.spelling.suggest.jaspell;
 
diff --git a/solr/core/src/java/org/apache/solr/util/PayloadUtils.java 
b/solr/core/src/java/org/apache/solr/util/PayloadUtils.java
index 7bcfd73..7db4562 100644
--- a/solr/core/src/java/org/apache/solr/util/PayloadUtils.java
+++ b/solr/core/src/java/org/apache/solr/util/PayloadUtils.java
@@ -35,10 +35,11 @@ import 
org.apache.lucene.queries.payloads.MinPayloadFunction;
 import org.apache.lucene.queries.payloads.PayloadDecoder;
 import org.apache.lucene.queries.payloads.PayloadFunction;
 import org.apache.lucene.queries.payloads.SumPayloadFunction;
-import org.apache.lucene.search.spans.SpanNearQuery;
-import org.apache.lucene.search.spans.SpanOrQuery;
-import org.apache.lucene.search.spans.SpanQuery;
-import org.apache.lucene.search.spans.SpanTermQuery;
+
+import org.apache.lucene.queries.spans.SpanNearQuery;
+import org.apache.lucene.queries.spans.SpanOrQuery;
+import org.apache.lucene.queries.spans.SpanQuery;
+import org.apache.lucene.queries.spans.SpanTermQuery;
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.analysis.TokenizerChain;
 import org.apache.solr.schema.FieldType;
diff --git a/solr/core/src/test-files/solr/collection1/conf/schema-bm25.xml 
b/solr/core/src/test-files/solr/collection1/conf/schema-bm25.xml
index 02a0d08..a9c2a6a 100644
--- a/solr/core/src/test-files/solr/collection1/conf/schema-bm25.xml
+++ b/solr/core/src/test-files/solr/collection1/conf/schema-bm25.xml
@@ -35,6 +35,7 @@
       <float name="b">0.76</float>
     </similarity>
   </fieldType>
+  
 
   <field name="id" type="string" indexed="true" stored="true" 
multiValued="false" required="false"/>
   <field name="text" type="text" indexed="true" stored="false"/>
diff --git 
a/solr/core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicyfactory.xml
 
b/solr/core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicyfactory.xml
index 4a58100..3494db0 100644
--- 
a/solr/core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicyfactory.xml
+++ 
b/solr/core/src/test-files/solr/collection1/conf/solrconfig-tieredmergepolicyfactory.xml
@@ -25,7 +25,7 @@
   <indexConfig>
     <useCompoundFile>${useCompoundFile:false}</useCompoundFile>
     <mergePolicyFactory class="org.apache.solr.index.TieredMergePolicyFactory">
-      <int name="maxMergeAtOnceExplicit">19</int>
+      <int name="maxMergeAtOnce">19</int>
       <int name="maxMergeAtOnce">7</int>
       <int name="segmentsPerTier">9</int>
       <double name="noCFSRatio">0.1</double>
diff --git 
a/solr/core/src/test/org/apache/solr/analysis/TestLuceneMatchVersion.java 
b/solr/core/src/test/org/apache/solr/analysis/TestLuceneMatchVersion.java
index 859f141..2f6f856 100644
--- a/solr/core/src/test/org/apache/solr/analysis/TestLuceneMatchVersion.java
+++ b/solr/core/src/test/org/apache/solr/analysis/TestLuceneMatchVersion.java
@@ -52,6 +52,5 @@ public class TestLuceneMatchVersion extends SolrTestCaseJ4 {
     type = schema.getFieldType("textTurkishAnalyzerDefault");
     Analyzer ana1 = type.getIndexAnalyzer();
     assertTrue(ana1 instanceof TurkishAnalyzer);
-    assertEquals(DEFAULT_VERSION, ana1.getVersion());
   }
 }
diff --git 
a/solr/core/src/test/org/apache/solr/analysis/TestReversedWildcardFilterFactory.java
 
b/solr/core/src/test/org/apache/solr/analysis/TestReversedWildcardFilterFactory.java
index e442055..19ac6fc 100644
--- 
a/solr/core/src/test/org/apache/solr/analysis/TestReversedWildcardFilterFactory.java
+++ 
b/solr/core/src/test/org/apache/solr/analysis/TestReversedWildcardFilterFactory.java
@@ -170,7 +170,7 @@ public class TestReversedWildcardFilterFactory extends 
SolrTestCaseJ4 {
     }
     Automaton automaton = ((AutomatonQuery) q).getAutomaton();
     String prefix = 
Operations.getCommonPrefix(Operations.determinize(automaton,
-      Operations.DEFAULT_MAX_DETERMINIZED_STATES));
+      Operations.DEFAULT_DETERMINIZE_WORK_LIMIT));
     return prefix.length() > 0 && prefix.charAt(0) == '\u0001';
   }
 
diff --git a/solr/core/src/test/org/apache/solr/core/TestMergePolicyConfig.java 
b/solr/core/src/test/org/apache/solr/core/TestMergePolicyConfig.java
index 5f4eb95..bf004af 100644
--- a/solr/core/src/test/org/apache/solr/core/TestMergePolicyConfig.java
+++ b/solr/core/src/test/org/apache/solr/core/TestMergePolicyConfig.java
@@ -110,7 +110,6 @@ public class TestMergePolicyConfig extends SolrTestCaseJ4 {
     assertEquals(7, tieredMP.getMaxMergeAtOnce());
     
     // mp-specific setters
-    assertEquals(19, tieredMP.getMaxMergeAtOnceExplicit());
     assertEquals(0.1D, tieredMP.getNoCFSRatio(), 0.0D);
     // make sure we overrode segmentsPerTier 
     // (split from maxMergeAtOnce out of mergeFactor)
diff --git 
a/solr/core/src/test/org/apache/solr/handler/TestSnapshotCoreBackup.java 
b/solr/core/src/test/org/apache/solr/handler/TestSnapshotCoreBackup.java
index c096dd1..81f5a1b 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestSnapshotCoreBackup.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestSnapshotCoreBackup.java
@@ -379,7 +379,7 @@ public class TestSnapshotCoreBackup extends SolrTestCaseJ4 {
                  new File(backup, expectedSegmentsFileName).exists());
     }
     try (Directory dir = FSDirectory.open(backup.toPath())) {
-      TestUtil.checkIndex(dir, true, true, null);
+      TestUtil.checkIndex(dir, true, true, true, null);
       try (DirectoryReader r = DirectoryReader.open(dir)) {
         assertEquals("numDocs in " + backup.toString(),
                      numDocs, r.numDocs());
diff --git 
a/solr/core/src/test/org/apache/solr/handler/TestStressThreadBackup.java 
b/solr/core/src/test/org/apache/solr/handler/TestStressThreadBackup.java
index 2d760e6..43b2436 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestStressThreadBackup.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestStressThreadBackup.java
@@ -316,7 +316,7 @@ public class TestStressThreadBackup extends 
SolrCloudTestCase {
     final int numRealDocsExpected = Integer.parseInt(m.group());
     
     try (Directory dir = FSDirectory.open(backup.toPath())) {
-      TestUtil.checkIndex(dir, true, true, null);
+      TestUtil.checkIndex(dir, true, true, true, null);
       try (DirectoryReader r = DirectoryReader.open(dir)) {
         assertEquals("num real docs in " + backup.toString(),
                      numRealDocsExpected, r.docFreq(new 
Term("type_s","real")));
diff --git a/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java 
b/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
index 0deb6a2..0513fd9 100644
--- a/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
+++ b/solr/core/src/test/org/apache/solr/highlight/HighlighterTest.java
@@ -28,9 +28,9 @@ import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.spans.SpanTermQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.queries.payloads.SpanPayloadCheckQuery;
-import org.apache.lucene.search.spans.SpanTermQuery;
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.params.HighlightParams;
diff --git 
a/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java 
b/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
index 32795f4..aa0b868 100644
--- a/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
+++ b/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
@@ -38,7 +38,6 @@ import 
org.apache.solr.client.solrj.request.schema.SchemaRequest;
 import org.apache.solr.common.SolrDocumentList;
 import org.apache.solr.core.CoreContainer;
 import org.apache.solr.core.SolrCore;
-import org.apache.solr.schema.IndexSchema;
 import org.apache.solr.schema.SimilarityFactory;
 import org.apache.solr.search.similarities.SchemaSimilarityFactory;
 import org.apache.solr.util.RESTfulServerProvider;
@@ -203,7 +202,7 @@ public class TestBulkSchemaAPI extends RestTestBase {
     @SuppressWarnings({"rawtypes"})
     Map analyzer = (Map)map.get("analyzer");
     assertEquals("org.apache.lucene.analysis.core.WhitespaceAnalyzer", 
String.valueOf(analyzer.get("class")));
-    assertEquals("5.0.0", 
String.valueOf(analyzer.get(IndexSchema.LUCENE_MATCH_VERSION_PARAM)));
+
   }
 
   public void testAnalyzerByName() throws Exception {
diff --git 
a/solr/core/src/test/org/apache/solr/search/ApacheLuceneSolrNearQueryBuilder.java
 
b/solr/core/src/test/org/apache/solr/search/ApacheLuceneSolrNearQueryBuilder.java
index 574a736..01c1e63 100644
--- 
a/solr/core/src/test/org/apache/solr/search/ApacheLuceneSolrNearQueryBuilder.java
+++ 
b/solr/core/src/test/org/apache/solr/search/ApacheLuceneSolrNearQueryBuilder.java
@@ -18,13 +18,13 @@ package org.apache.solr.search;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.spans.SpanNearQuery;
+import org.apache.lucene.queries.spans.SpanQuery;
+import org.apache.lucene.queries.spans.SpanTermQuery;
 import org.apache.lucene.queryparser.xml.DOMUtils;
 import org.apache.lucene.queryparser.xml.ParserException;
 import org.apache.lucene.queryparser.xml.builders.SpanQueryBuilder;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanNearQuery;
-import org.apache.lucene.search.spans.SpanQuery;
-import org.apache.lucene.search.spans.SpanTermQuery;
 import org.apache.solr.request.SolrQueryRequest;
 import org.w3c.dom.Element;
 
diff --git 
a/solr/core/src/test/org/apache/solr/search/ChooseOneWordQueryBuilder.java 
b/solr/core/src/test/org/apache/solr/search/ChooseOneWordQueryBuilder.java
index 6e2112e..3fd29ed 100644
--- a/solr/core/src/test/org/apache/solr/search/ChooseOneWordQueryBuilder.java
+++ b/solr/core/src/test/org/apache/solr/search/ChooseOneWordQueryBuilder.java
@@ -18,13 +18,13 @@ package org.apache.solr.search;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.spans.SpanQuery;
+import org.apache.lucene.queries.spans.SpanTermQuery;
 import org.apache.lucene.queryparser.xml.DOMUtils;
 import org.apache.lucene.queryparser.xml.ParserException;
 import org.apache.lucene.queryparser.xml.builders.SpanQueryBuilder;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.spans.SpanQuery;
-import org.apache.lucene.search.spans.SpanTermQuery;
 import org.apache.solr.request.SolrQueryRequest;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
diff --git a/solr/core/src/test/org/apache/solr/search/FuzzySearchTest.java 
b/solr/core/src/test/org/apache/solr/search/FuzzySearchTest.java
deleted file mode 100644
index f84cf10..0000000
--- a/solr/core/src/test/org/apache/solr/search/FuzzySearchTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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.
- */
-
-package org.apache.solr.search;
-
-import java.io.IOException;
-
-import org.apache.lucene.util.LuceneTestCase;
-import org.apache.solr.client.solrj.SolrQuery;
-import org.apache.solr.client.solrj.SolrServerException;
-import org.apache.solr.client.solrj.impl.BaseHttpSolrClient;
-import org.apache.solr.client.solrj.impl.CloudSolrClient;
-import org.apache.solr.client.solrj.request.CollectionAdminRequest;
-import org.apache.solr.cloud.SolrCloudTestCase;
-import org.apache.solr.common.SolrInputDocument;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
[email protected]
-public class FuzzySearchTest extends SolrCloudTestCase {
-  private final static String COLLECTION = "c1";
-  private CloudSolrClient client;
-
-  @BeforeClass
-  public static void setupCluster() throws Exception {
-    configureCluster(1).addConfig(COLLECTION, 
configset("cloud-minimal")).configure();
-  }
-
-  @Before
-  public void setupCollection() throws Exception {
-    client = cluster.getSolrClient();
-    client.setDefaultCollection(COLLECTION);
-
-    CollectionAdminRequest.createCollection(COLLECTION, 1, 1).process(client);
-    cluster.waitForActiveCollection(COLLECTION, 1, 1);
-  }
-
-  @Test
-  public void testTooComplex() throws IOException, SolrServerException {
-    SolrInputDocument doc = new SolrInputDocument();
-
-    doc.setField("id", "1");
-    doc.setField("text", "foo");
-    client.add(doc);
-    client.commit(); // Must have index files written, but the contents don't 
matter
-
-    SolrQuery query = new 
SolrQuery("text:headquarters\\(在日米海軍横須賀基地司令部庁舎\\/旧横須賀鎮守府会議所・横須賀海軍艦船部\\)~");
-
-    BaseHttpSolrClient.RemoteSolrException e = 
expectThrows(BaseHttpSolrClient.RemoteSolrException.class, () -> 
client.query(query));
-    assertTrue("Should be client error, not server error", e.code() >= 400 && 
e.code() < 500);
-  }
-}
diff --git a/solr/core/src/test/org/apache/solr/search/HandyQueryBuilder.java 
b/solr/core/src/test/org/apache/solr/search/HandyQueryBuilder.java
index f76015f..ae6c620 100644
--- a/solr/core/src/test/org/apache/solr/search/HandyQueryBuilder.java
+++ b/solr/core/src/test/org/apache/solr/search/HandyQueryBuilder.java
@@ -17,14 +17,14 @@
 package org.apache.solr.search;
 
 import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.queries.spans.SpanOrQuery;
+import org.apache.lucene.queries.spans.SpanQuery;
 import org.apache.lucene.queryparser.xml.DOMUtils;
 import org.apache.lucene.queryparser.xml.ParserException;
 import org.apache.lucene.queryparser.xml.builders.SpanQueryBuilder;
 import org.apache.lucene.search.BooleanClause;
 import org.apache.lucene.search.BooleanQuery;
 import org.apache.lucene.search.Query;
-import org.apache.lucene.search.spans.SpanOrQuery;
-import org.apache.lucene.search.spans.SpanQuery;
 import org.apache.solr.request.SolrQueryRequest;
 import org.w3c.dom.Element;
 
diff --git a/solr/core/src/test/org/apache/solr/search/TestDocSet.java 
b/solr/core/src/test/org/apache/solr/search/TestDocSet.java
index 8a84f2e..47f481a 100644
--- a/solr/core/src/test/org/apache/solr/search/TestDocSet.java
+++ b/solr/core/src/test/org/apache/solr/search/TestDocSet.java
@@ -288,6 +288,11 @@ public class TestDocSet extends SolrTestCase {
       }
 
       @Override
+      public Fields getTermVectors(int docID) {
+        return null;
+      }
+
+      @Override
       public int numDocs() {
         return maxDoc;
       }
@@ -308,11 +313,6 @@ public class TestDocSet extends SolrTestCase {
       }
 
       @Override
-      public Fields getTermVectors(int doc) {
-        return null;
-      }
-
-      @Override
       public NumericDocValues getNumericDocValues(String field) {
         return null;
       }
@@ -353,7 +353,8 @@ public class TestDocSet extends SolrTestCase {
       }
 
       @Override
-      public TopDocs searchNearestVectors(String field, float[] target, int k, 
int fanout) {
+      public TopDocs searchNearestVectors(String field, float[] target, int k, 
Bits acceptDocs)
+          throws IOException {
         return null;
       }
 
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolrCoreParser.java 
b/solr/core/src/test/org/apache/solr/search/TestSolrCoreParser.java
index d82abdb..def7a21 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolrCoreParser.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolrCoreParser.java
@@ -25,6 +25,9 @@ import org.apache.lucene.analysis.MockAnalyzer;
 import org.apache.lucene.analysis.MockTokenFilter;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.queries.spans.SpanNearQuery;
+import org.apache.lucene.queries.spans.SpanOrQuery;
+import org.apache.lucene.queries.spans.SpanTermQuery;
 import org.apache.lucene.queryparser.xml.CoreParser;
 import org.apache.lucene.queryparser.xml.ParserException;
 import org.apache.lucene.search.BooleanQuery;
@@ -32,11 +35,6 @@ import org.apache.lucene.search.MatchAllDocsQuery;
 import org.apache.lucene.search.MatchNoDocsQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.spans.SpanBoostQuery;
-import org.apache.lucene.search.spans.SpanNearQuery;
-import org.apache.lucene.search.spans.SpanOrQuery;
-import org.apache.lucene.search.spans.SpanQuery;
-import org.apache.lucene.search.spans.SpanTermQuery;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.util.NamedList;
 import org.junit.BeforeClass;
@@ -122,12 +120,6 @@ public class TestSolrCoreParser extends SolrTestCaseJ4 {
     assertTrue(bq.clauses().get(1).getQuery() instanceof MatchNoDocsQuery);
   }
 
-  private static SpanQuery unwrapSpanBoostQuery(Query query) {
-    assertTrue(query instanceof SpanBoostQuery);
-    final SpanBoostQuery spanBoostQuery = (SpanBoostQuery)query;
-    return spanBoostQuery.getQuery();
-  }
-
   // test custom query (HandyQueryBuilder) wrapping a SpanQuery
   public void testHandySpanQuery() throws IOException, ParserException {
     final String lhsXml = "<SpanOr fieldName='contents'>"
@@ -146,10 +138,10 @@ public class TestSolrCoreParser extends SolrTestCaseJ4 {
       final Query clauseQuery = bq.clauses().get(ii).getQuery();
       switch (ii) {
         case 0:
-          assertTrue(unwrapSpanBoostQuery(clauseQuery) instanceof SpanOrQuery);
+          assertTrue(clauseQuery instanceof SpanOrQuery);
           break;
         case 1:
-          assertTrue(unwrapSpanBoostQuery(clauseQuery) instanceof 
SpanNearQuery);
+          assertTrue(clauseQuery instanceof SpanNearQuery);
           break;
         default:
           fail("unexpected clause index "+ii);
@@ -185,8 +177,8 @@ public class TestSolrCoreParser extends SolrTestCaseJ4 {
     // the test
     final Query query = parseXmlString(xml);
     if (span) {
-      assertTrue(unwrapSpanBoostQuery(query) instanceof SpanOrQuery);
-      final SpanOrQuery soq = (SpanOrQuery)unwrapSpanBoostQuery(query);
+      assertTrue(query instanceof SpanOrQuery);
+      final SpanOrQuery soq = (SpanOrQuery) query;
       assertEquals(2, soq.getClauses().length);
       checkChooseOneWordQuery(span, soq.getClauses()[0], fieldName, 
randomTerms);
       checkApacheLuceneSolr(soq.getClauses()[1], fieldName);
diff --git a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java 
b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
index 4f43b10..63a25ac 100644
--- a/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
+++ b/solr/core/src/test/org/apache/solr/update/SolrIndexConfigTest.java
@@ -92,9 +92,10 @@ public class SolrIndexConfigTest extends SolrTestCaseJ4 {
     assertNotNull("null mp", iwc.getMergePolicy());
     assertTrue("mp is not TieredMergePolicy", iwc.getMergePolicy() instanceof 
TieredMergePolicy);
     TieredMergePolicy mp = (TieredMergePolicy) iwc.getMergePolicy();
-    assertEquals("mp.maxMergeAtOnceExplicit", 19, 
mp.getMaxMergeAtOnceExplicit());
+    assertEquals("mp.maxMergeAtOnce", 7, mp.getMaxMergeAtOnce());
     assertEquals("mp.segmentsPerTier",9,(int)mp.getSegmentsPerTier());
 
+
     assertNotNull("null ms", iwc.getMergeScheduler());
     assertTrue("ms is not CMS", iwc.getMergeScheduler() instanceof 
ConcurrentMergeScheduler);
     ConcurrentMergeScheduler ms = (ConcurrentMergeScheduler)  
iwc.getMergeScheduler();
diff --git 
a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java 
b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
index 78f0eab..24ca22f 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/request/SchemaTest.java
@@ -625,8 +625,6 @@ public class SchemaTest extends RestTestBase {
     assertThat(fieldTypeName, 
is(equalTo(newFieldTypeRepresentation.getAttributes().get("name"))));
     assertThat(analyzerAttributes.get("class"),
         
is(equalTo(newFieldTypeRepresentation.getAnalyzer().getAttributes().get("class"))));
-    assertThat(analyzerAttributes.get("luceneMatchVersion"),
-        
is(equalTo(newFieldTypeRepresentation.getAnalyzer().getAttributes().get("luceneMatchVersion"))));
   }
 
   @Test
diff --git a/versions.lock b/versions.lock
index 6960cb0..d3e4025 100644
--- a/versions.lock
+++ b/versions.lock
@@ -132,32 +132,32 @@ org.apache.kerby:kerby-util:1.0.1 (2 constraints: 
6518bdb6)
 org.apache.logging.log4j:log4j-api:2.14.1 (4 constraints: d033fab0)
 org.apache.logging.log4j:log4j-core:2.14.1 (2 constraints: 0d16b624)
 org.apache.logging.log4j:log4j-slf4j-impl:2.14.1 (1 constraints: 3a053c3b)
-org.apache.lucene:lucene-analysis-common:9.0.0-prerelease5 (10 constraints: 
10cca63a)
-org.apache.lucene:lucene-analysis-icu:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-kuromoji:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-morfologik:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-nori:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-opennlp:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-phonetic:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-smartcn:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-analysis-stempel:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-backward-codecs:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-classification:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-codecs:9.0.0-prerelease5 (3 constraints: 313301b7)
-org.apache.lucene:lucene-core:9.0.0-prerelease5 (26 constraints: a6054f0d)
-org.apache.lucene:lucene-expressions:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-grouping:9.0.0-prerelease5 (2 constraints: f01ea971)
-org.apache.lucene:lucene-highlighter:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-join:9.0.0-prerelease5 (1 constraints: 95093990)
-org.apache.lucene:lucene-memory:9.0.0-prerelease5 (1 constraints: 1f14475c)
-org.apache.lucene:lucene-misc:9.0.0-prerelease5 (1 constraints: 95093990)
-org.apache.lucene:lucene-queries:9.0.0-prerelease5 (5 constraints: 5a5a7a89)
-org.apache.lucene:lucene-queryparser:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-sandbox:9.0.0-prerelease5 (2 constraints: e71d8a14)
-org.apache.lucene:lucene-spatial-extras:9.0.0-prerelease5 (1 constraints: 
95093990)
-org.apache.lucene:lucene-spatial3d:9.0.0-prerelease5 (1 constraints: 4215f39f)
-org.apache.lucene:lucene-suggest:9.0.0-prerelease5 (1 constraints: 95093990)
-org.apache.lucene:lucene-test-framework:9.0.0-prerelease5 (1 constraints: 
95093990)
+org.apache.lucene:lucene-analysis-common:9.0.0-prerelease9 (10 constraints: 
38cc2665)
+org.apache.lucene:lucene-analysis-icu:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-kuromoji:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-morfologik:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-nori:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-opennlp:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-phonetic:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-smartcn:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-analysis-stempel:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-backward-codecs:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-classification:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-codecs:9.0.0-prerelease9 (3 constraints: 3d33d1b9)
+org.apache.lucene:lucene-core:9.0.0-prerelease9 (26 constraints: 0e06b22a)
+org.apache.lucene:lucene-expressions:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-grouping:9.0.0-prerelease9 (2 constraints: f81ea172)
+org.apache.lucene:lucene-highlighter:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-join:9.0.0-prerelease9 (1 constraints: 99093d90)
+org.apache.lucene:lucene-memory:9.0.0-prerelease9 (1 constraints: 23144b5c)
+org.apache.lucene:lucene-misc:9.0.0-prerelease9 (1 constraints: 99093d90)
+org.apache.lucene:lucene-queries:9.0.0-prerelease9 (6 constraints: f06c3251)
+org.apache.lucene:lucene-queryparser:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-sandbox:9.0.0-prerelease9 (2 constraints: ef1d7615)
+org.apache.lucene:lucene-spatial-extras:9.0.0-prerelease9 (1 constraints: 
99093d90)
+org.apache.lucene:lucene-spatial3d:9.0.0-prerelease9 (1 constraints: 4615f79f)
+org.apache.lucene:lucene-suggest:9.0.0-prerelease9 (1 constraints: 99093d90)
+org.apache.lucene:lucene-test-framework:9.0.0-prerelease9 (1 constraints: 
99093d90)
 org.apache.opennlp:opennlp-tools:1.9.1 (2 constraints: a1164d13)
 org.apache.pdfbox:fontbox:2.0.17 (1 constraints: 3c05323b)
 org.apache.pdfbox:jempbox:1.8.16 (1 constraints: 42054b3b)
@@ -227,8 +227,8 @@ org.locationtech.spatial4j:spatial4j:0.7 (1 constraints: 
58105398)
 org.openjdk.jmh:jmh-core:1.32 (1 constraints: da04f730)
 org.ow2.asm:asm:7.2 (3 constraints: a325a35c)
 org.ow2.asm:asm-commons:7.2 (1 constraints: 6b0f7267)
-org.reactivestreams:reactive-streams:1.0.3 (3 constraints: 3c2b02fd)
 org.quicktheories:quicktheories:0.26 (1 constraints: dc04f530)
+org.reactivestreams:reactive-streams:1.0.3 (3 constraints: 3c2b02fd)
 org.slf4j:jcl-over-slf4j:1.7.24 (1 constraints: 4005473b)
 org.slf4j:slf4j-api:1.7.24 (19 constraints: 97f04fc1)
 org.tallison:jmatio:1.5 (1 constraints: aa041f2c)
diff --git a/versions.props b/versions.props
index 2c71a28..aac56cf 100644
--- a/versions.props
+++ b/versions.props
@@ -90,7 +90,7 @@ org.apache.httpcomponents:httpmime=4.5.10
 org.apache.james:apache-mime4j*=0.8.3
 org.apache.kerby:*=1.0.1
 org.apache.logging.log4j:*=2.14.1
-org.apache.lucene:*=9.0.0-prerelease5
+org.apache.lucene:*=9.0.0-prerelease9
 org.apache.opennlp:opennlp-tools=1.9.1
 org.apache.pdfbox:*=2.0.17
 org.apache.pdfbox:jempbox=1.8.16

Reply via email to