 build.xml                                          |  31 +--
 dev-tools/eclipse/dot.classpath.xsl                |   2 +-
 .../dot.settings/org.eclipse.jdt.core.prefs        |   6 +-
 dev-tools/idea/.idea/misc.xml                      |   2 +-
 dev-tools/maven/pom.xml.template                   |  47 ++--
 dev-tools/scripts/checkJavaDocs.py                 |  11 +-
 dev-tools/scripts/checkJavadocLinks.py             |  11 +-
 dev-tools/scripts/smokeTestRelease.py              | 130 ++++-----
 .../lucene/analysis/snowball/SnowballFilter.java   |   2 +-
 .../snowball/SnowballPorterFilterFactory.java      |   2 +-
 .../analysis/util/ClasspathResourceLoader.java     |   2 +-
 .../lucene/analysis/core/TestRandomChains.java     |   2 +-
 .../analysis/util/StringMockResourceLoader.java    |   2 +-
 .../analysis/ja/StringMockResourceLoader.java      |   2 +-
 .../analysis/ko/StringMockResourceLoader.java      |   2 +-
 .../analysis/phonetic/PhoneticFilterFactory.java   |   2 +-
 .../lucene/benchmark/byTask/PerfRunData.java       |   8 +-
 .../byTask/feeds/EnwikiContentSource.java          |  26 +-
 .../benchmark/byTask/feeds/TrecContentSource.java  |   4 +-
 .../benchmark/byTask/tasks/CreateIndexTask.java    |   9 +-
 .../benchmark/byTask/tasks/NewAnalyzerTask.java    |   2 +-
 .../byTask/tasks/SearchWithCollectorTask.java      |   2 +-
 lucene/build.xml                                   |   2 +-
 .../codecs/simpletext/SimpleTextBKDWriter.java     |  21 +-
 .../simpletext/SimpleTextStoredFieldsReader.java   |   4 +-
 lucene/common-build.xml                            | 152 +++-------
 lucene/core/build.xml                              |   9 -
 .../tokenattributes/CharTermAttributeImpl.java     |  10 +-
 .../org/apache/lucene/codecs/compressing/LZ4.java  |   3 +-
 .../org/apache/lucene/document/BinaryPoint.java    |   3 +-
 .../org/apache/lucene/document/DoubleRange.java    |   7 +-
 .../org/apache/lucene/document/FloatRange.java     |   7 +-
 .../java/org/apache/lucene/document/IntRange.java  |   7 +-
 .../document/LatLonPointDistanceFeatureQuery.java  |  38 +--
 .../lucene/document/LatLonPointDistanceQuery.java  |  42 +--
 .../lucene/document/LatLonPointInPolygonQuery.java |   9 +-
 .../lucene/document/LongDistanceFeatureQuery.java  |  14 +-
 .../java/org/apache/lucene/document/LongRange.java |   7 +-
 .../apache/lucene/document/RangeFieldQuery.java    |  37 ++-
 .../java/org/apache/lucene/index/BitsSlice.java    |   5 +-
 .../java/org/apache/lucene/index/CheckIndex.java   |  17 +-
 .../java/org/apache/lucene/index/CodecReader.java  |   4 +-
 .../apache/lucene/index/MergeReaderWrapper.java    |   4 +-
 .../java/org/apache/lucene/index/PointValues.java  |   6 +-
 .../org/apache/lucene/index/PrefixCodedTerms.java  |   6 +
 .../org/apache/lucene/search/BooleanScorer.java    |   4 +-
 .../org/apache/lucene/search/PointInSetQuery.java  |   5 +-
 .../org/apache/lucene/search/PointRangeQuery.java  |  29 +-
 .../apache/lucene/search/TopFieldCollector.java    |   4 +-
 .../apache/lucene/store/ByteBuffersDataOutput.java |   4 +-
 .../org/apache/lucene/store/LockStressTest.java    |   2 +-
 .../org/apache/lucene/store/MMapDirectory.java     |  54 +---
 .../src/java/org/apache/lucene/util/BytesRef.java  |   6 +-
 .../java/org/apache/lucene/util/BytesRefArray.java |   5 +-
 .../src/java/org/apache/lucene/util/CharsRef.java  |  12 +-
 .../java/org/apache/lucene/util/FutureArrays.java  | 268 ------------------
 .../java/org/apache/lucene/util/FutureObjects.java |  70 -----
 .../src/java/org/apache/lucene/util/IntsRef.java   |   5 +-
 .../src/java/org/apache/lucene/util/LongsRef.java  |   5 +-
 .../org/apache/lucene/util/NamedSPILoader.java     |   2 +-
 .../java/org/apache/lucene/util/StringHelper.java  |   8 +-
 .../apache/lucene/util/automaton/Automaton.java    |  10 +-
 .../apache/lucene/util/bkd/BKDRadixSelector.java   |  13 +-
 .../java/org/apache/lucene/util/bkd/BKDReader.java |  12 +-
 .../java/org/apache/lucene/util/bkd/BKDWriter.java |  37 ++-
 .../lucene/util/bkd/MutablePointsReaderUtils.java  |   9 +-
 .../tokenattributes/TestBytesRefAttImpl.java       |   2 +-
 .../tokenattributes/TestCharTermAttributeImpl.java |   2 +-
 .../codecs/lucene60/TestLucene60PointsFormat.java  |   9 +-
 .../org/apache/lucene/search/TestPointQueries.java |   9 +-
 .../org/apache/lucene/util/TestFutureArrays.java   | 305 ---------------------
 .../org/apache/lucene/util/TestFutureObjects.java  | 102 -------
 .../org/apache/lucene/util/TestUnicodeUtil.java    |   4 +-
 .../test/org/apache/lucene/util/bkd/TestBKD.java   |  23 +-
 .../lucene/util/bkd/TestBKDRadixSelector.java      |  13 +-
 .../util/bkd/TestMutablePointsReaderUtils.java     |   5 +-
 .../directory/DirectoryTaxonomyWriter.java         |   4 +-
 .../dialog/menubar/CheckIndexDialogFactory.java    |   7 -
 .../dialog/menubar/OptimizeIndexDialogFactory.java |   3 -
 .../luke/app/desktop/util/TextAreaPrintStream.java |   9 +-
 .../lucene/luke/models/analysis/AnalysisImpl.java  |   2 +-
 .../luke/models/analysis/AnalysisImplTest.java     |   2 +-
 .../apache/lucene/index/memory/MemoryIndex.java    |   5 +-
 .../apache/lucene/document/InetAddressPoint.java   |   3 +-
 .../apache/lucene/document/InetAddressRange.java   |   4 +-
 .../lucene/search/TestInetAddressRangeQueries.java |  19 +-
 lucene/module-build.xml                            |  23 +-
 .../java/org/apache/lucene/geo/Rectangle2D.java    |  17 +-
 .../apache/lucene/document/TestHalfFloatPoint.java |   3 +-
 .../prefix/tree/SpatialPrefixTreeFactory.java      |   2 +-
 .../apache/lucene/spatial3d/TestGeo3DPoint.java    |   5 +-
 .../lucene/search/suggest/LookupBenchmarkTest.java |   2 +-
 .../lucene/search/suggest/PersistenceTest.java     |   4 +-
 .../apache/lucene/index/AssertingLeafReader.java   |  10 +-
 .../lucene/index/BasePointsFormatTestCase.java     |  27 +-
 .../apache/lucene/index/PointsStackTracker.java    |   6 +-
 .../org/apache/lucene/util/LuceneTestCase.java     |   2 +-
 lucene/tools/javadoc/java11/package-list           | 282 +++++++++++++++++++
 lucene/tools/javadoc/java8/package-list            | 217 ---------------
 lucene/tools/src/groovy/patch-mrjar-classes.groovy |  83 ------
 lucene/tools/src/groovy/run-maven-build.groovy     |   1 +
 .../lucene/validation/LibVersionsCheckTask.java    |  21 +-
 solr/CHANGES.txt                                   |   6 +
 solr/common-build.xml                              |   9 +-
 .../carrot2/LuceneCarrot2StemmerFactory.java       |   2 +-
 .../handler/dataimport/MailEntityProcessor.java    |   4 +-
 .../solr/handler/dataimport/DataImporter.java      |   6 +-
 .../apache/solr/handler/dataimport/DocBuilder.java |   4 +-
 .../handler/dataimport/EntityProcessorWrapper.java |   4 +-
 .../solr/handler/dataimport/JdbcDataSource.java    |  14 +-
 .../dataimport/AbstractDIHJdbcTestCase.java        |   4 +-
 .../dataimport/TestEntityProcessorBase.java        |   6 +-
 .../apache/solr/cloud/rule/ReplicaAssigner.java    |   4 +-
 .../java/org/apache/solr/core/CoreContainer.java   |  11 -
 .../java/org/apache/solr/core/MemClassLoader.java  |   2 +-
 .../src/java/org/apache/solr/core/SolrCore.java    |  13 +-
 .../apache/solr/core/SolrCoreCloseListener.java    |  42 +++
 .../src/java/org/apache/solr/core/SolrCores.java   |  10 +-
 .../apache/solr/core/TransientSolrCoreCache.java   |  30 +-
 .../solr/core/TransientSolrCoreCacheDefault.java   |  12 +-
 .../solr/core/TransientSolrCoreCacheFactory.java   |   2 +-
 .../handler/component/ShardHandlerFactory.java     |   2 +-
 .../org/apache/solr/schema/CurrencyFieldType.java  |   2 +-
 .../apache/solr/schema/FieldTypePluginLoader.java  |   2 +-
 .../java/org/apache/solr/search/CacheConfig.java   |   2 +-
 .../solr/search/GraphTermsQParserPlugin.java       |   5 +-
 .../org/apache/solr/update/SolrIndexWriter.java    |  13 -
 .../org/apache/solr/util/ConcurrentLFUCache.java   |  15 -
 .../org/apache/solr/util/ConcurrentLRUCache.java   |  16 --
 .../src/java/org/apache/solr/util/SolrCLI.java     |   4 +-
 .../src/test/org/apache/solr/SolrInfoBeanTest.java |   4 +-
 .../analysis/ThrowingMockTokenFilterFactory.java   |   5 +-
 .../org/apache/solr/core/DirectoryFactoryTest.java |   6 +-
 .../org/apache/solr/core/TestDirectoryFactory.java |   2 +-
 .../apache/solr/legacy/TestNumericTokenStream.java |   2 +-
 .../apache/solr/schema/PrimitiveFieldTypeTest.java |   4 +-
 .../org/apache/solr/search/TestSolr4Spatial2.java  |   5 +-
 .../spelling/ConjunctionSolrSpellCheckerTest.java  |   4 +-
 .../client/solrj/beans/DocumentObjectBinder.java   |   2 +-
 .../solr/client/solrj/impl/HttpClientUtil.java     |   5 +-
 .../client/solrj/io/stream/JDBCStreamTest.java     |   2 +-
 .../analysis/StringMockSolrResourceLoader.java     |   2 +-
 142 files changed, 961 insertions(+), 1850 deletions(-)

diff --git a/build.xml b/build.xml
index 96fc565..c45f7ce 100755
--- a/build.xml
+++ b/build.xml
@@ -25,7 +25,7 @@
   <property name="tests.heap-dump-dir" location="heapdumps"/>
   
   <property name="maven-build-dir" value="maven-build"/>
-  <property name="maven-version" value="2.2.1"/>
+  <property name="maven-version" value="3.5.0"/>
   <property name="maven.dependencies.filters.file" location="lucene/build/maven.dependencies.filters.properties"/>
 
   <property name="smokeTestRelease.dir" location="lucene/build/smokeTestRelease/dist"/>
@@ -332,7 +332,7 @@
 
     <echo>
       SUCCESS: You must right-click your project and choose Refresh.
-               Your project must use a Java 8 JRE.
+               Your project must use a Java 11 JRE.
     </echo>
   </target>
 
@@ -379,7 +379,7 @@ following two XML attributes/values (adjust values according to
 JDKs you have defined locally - see 
 File | Project Structure | Platform Settings | SDKs):
 
-    idea.jdk = project-jdk-name="1.8" project-jdk-type="JavaSDK"
+    idea.jdk = project-jdk-name="11" project-jdk-type="JavaSDK"
     </echo>
   </target>
 
@@ -423,23 +423,23 @@ File | Project Structure | Platform Settings | SDKs):
       <propertyset refid="uptodate.and.compiled.properties"/>
     </subant>
   </target>
-  
-  <target name="-nightly-smoke-java9params" if="smokeTestRelease.java9">
+
+  <target name="-nightly-smoke-java12params" if="smokeTestRelease.java12">
     <!-- convert path to UNIX style, so windows backslashes don't hurt escaping: -->
-    <pathconvert targetos="unix" property="-smokeTestRelease.java9params">
-      <regexpmapper from="^(.*)$" to="--test-java9 '\1'"/>
-      <path location="${smokeTestRelease.java9}"/>
+    <pathconvert targetos="unix" property="-smokeTestRelease.java12params">
+      <regexpmapper from="^(.*)$" to="--test-java12 '\1'"/>
+      <path location="${smokeTestRelease.java12}"/>
     </pathconvert>
   </target>
-
-  <target name="nightly-smoke" description="Builds an unsigned release and smoke tests it (pass '-DsmokeTestRelease.java9=/path/to/jdk-9' to additionally test with Java 9 or later)"
-    depends="clean,resolve-groovy,resolve-markdown,install-maven-tasks,-nightly-smoke-java9params">
-    <fail message="To run nightly smoke, the JDK must be exactly Java 1.8, was: ${java.specification.version}">
+  
+  <target name="nightly-smoke" description="Builds an unsigned release and smoke tests it  (pass '-DsmokeTestRelease.java12=/path/to/jdk-12' to additionally test with Java 12 or later)"
+    depends="clean,resolve-groovy,resolve-markdown,install-maven-tasks,-nightly-smoke-java12params">
+    <fail message="To run nightly smoke, the JDK must be exactly Java 11, was: ${java.specification.version}">
       <condition>
-        <not><equals arg1="${java.specification.version}" arg2="1.8"/></not>
+        <not><equals arg1="${java.specification.version}" arg2="11"/></not>
       </condition>
     </fail>
-    <property name="-smokeTestRelease.java9params" value=""/><!-- (if not yet defined) -->
+    <property name="-smokeTestRelease.java12params" value=""/><!-- (if not yet defined) -->
     <exec executable="${python32.exe}" failonerror="true" taskname="python32">
       <arg value="-V"/>
     </exec>
@@ -464,7 +464,7 @@ File | Project Structure | Platform Settings | SDKs):
       <!-- Tell Python not to write any bytecode cache into the filesystem: -->
       <arg value="-B"/>
       <arg file="dev-tools/scripts/smokeTestRelease.py"/>
-      <arg line="${-smokeTestRelease.java9params}"/>
+      <arg line="${-smokeTestRelease.java12params}"/>
       <arg value="--revision"/>
       <arg value="skip"/>
       <!-- pass ${version.base} here to emulate a real release, without appendix like "-SNAPSHOT": -->
@@ -692,5 +692,4 @@ Test args: [${args}]</echo>
 
   <!-- useless targets (override common-build.xml): -->
   <target name="generate-test-reports"/>
-  <target name="patch-mrjar-classes"/>
 </project>
diff --git a/dev-tools/eclipse/dot.classpath.xsl b/dev-tools/eclipse/dot.classpath.xsl
index 40bca21..8d48c5d 100644
--- a/dev-tools/eclipse/dot.classpath.xsl
+++ b/dev-tools/eclipse/dot.classpath.xsl
@@ -74,7 +74,7 @@
 
       <!-- the main resources folder is here (see above), so it's listed after the test-framework resources, making preflex-override work: -->
       <classpathentry kind="output" path="eclipse-build/main"/>
-      <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+      <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"/>
 
       <xsl:for-each select="str:split($eclipse.fileset.libs,'|')">
         <!-- sort the jars by path name: -->
diff --git a/dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs b/dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs
index 6014c22..8dba526 100644
--- a/dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs
+++ b/dev-tools/eclipse/dot.settings/org.eclipse.jdt.core.prefs
@@ -1,7 +1,7 @@
 #Sun Sep 23 13:02:27 EDT 2012
 eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
-org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
 org.eclipse.jdt.core.compiler.doc.comment.support=enabled
 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=error
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
@@ -34,7 +34,7 @@ org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
 org.eclipse.jdt.core.compiler.problem.unusedImport=error
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=error
 org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
-org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.compiler.source=11
 org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
 org.eclipse.jdt.core.compiler.taskPriorities=HIGH
 org.eclipse.jdt.core.compiler.taskTags=nocommit
diff --git a/dev-tools/idea/.idea/misc.xml b/dev-tools/idea/.idea/misc.xml
index 0fe2e6d..8414ae3 100755
--- a/dev-tools/idea/.idea/misc.xml
+++ b/dev-tools/idea/.idea/misc.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" subst.="idea.jdk" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_11" subst.="idea.jdk" />
 </project>
 
diff --git a/dev-tools/maven/pom.xml.template b/dev-tools/maven/pom.xml.template
index bcf5c4b..0b90eed 100644
--- a/dev-tools/maven/pom.xml.template
+++ b/dev-tools/maven/pom.xml.template
@@ -43,9 +43,7 @@
     <vc-browse-base-url>https://git1-us-west.apache.org/repos/asf?p=lucene-solr.git;a=tree</vc-browse-base-url>
     <specification.version>@spec.version@</specification.version>
     <maven.build.timestamp.format>yyyy-MM-dd HH:mm:ss</maven.build.timestamp.format>
-    <java.compat.version>8</java.compat.version>
-    <!-- HACK: the enforce plugin does not like new versioning: -->
-    <java.legacy-compat.version>1.${java.compat.version}</java.legacy-compat.version>
+    <java.compat.version>11</java.compat.version>
     <jetty.version>9.3.8.v20160314</jetty.version>
 
     <!-- RandomizedTesting library system properties -->
@@ -177,17 +175,17 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-antrun-plugin</artifactId>
-          <version>1.7</version>
+          <version>1.8</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-clean-plugin</artifactId>
-          <version>2.5</version>
+          <version>3.1.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
-          <version>3.1</version>
+          <version>3.8.0</version>
           <configuration>
             <source>${java.compat.version}</source>
             <target>${java.compat.version}</target>
@@ -200,27 +198,27 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-dependency-plugin</artifactId>
-          <version>2.8</version>
+          <version>3.1.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-deploy-plugin</artifactId>
-          <version>2.7</version>
+          <version>3.0.0-M1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-enforcer-plugin</artifactId>
-          <version>1.3</version>
+          <version>3.0.0-M2</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-install-plugin</artifactId>
-          <version>2.4</version>
+          <version>3.0.0-M1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-jar-plugin</artifactId>
-          <version>2.4</version>
+          <version>3.1.1</version>
           <configuration>
             <archive>
               <manifest>
@@ -233,7 +231,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-javadoc-plugin</artifactId>
-          <version>2.9.1</version>
+          <version>3.1.0</version>
           <configuration>
             <quiet>true</quiet>
             <additionalparam>-Xdoclint:all</additionalparam>
@@ -243,12 +241,17 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-resources-plugin</artifactId>
-          <version>2.6</version>
+          <version>3.1.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-remote-resources-plugin</artifactId>
+          <version>1.6.0</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-site-plugin</artifactId>
-          <version>3.3</version>
+          <version>3.7.1</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
@@ -293,7 +296,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-war-plugin</artifactId>
-          <version>2.3</version>
+          <version>3.2.2</version>
           <configuration>
             <archive>
               <!-- This section should be *exactly* the same under -->
@@ -319,12 +322,12 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>build-helper-maven-plugin</artifactId>
-          <version>1.8</version>
+          <version>3.0.0</version>
         </plugin>
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>buildnumber-maven-plugin</artifactId>
-          <version>1.2</version>
+          <version>1.4</version>
         </plugin>
         <plugin>
           <groupId>org.mortbay.jetty</groupId>
@@ -385,7 +388,7 @@
         <artifactId>maven-enforcer-plugin</artifactId>
         <executions>
           <execution>
-            <id>enforce-java-compat-version-and-maven-2.2.1</id>
+            <id>enforce-java-compat-version-and-maven-3.0.0</id>
             <goals>
               <goal>enforce</goal>
             </goals>
@@ -393,11 +396,11 @@
               <rules>
                 <requireJavaVersion>
                   <message>Java ${java.compat.version}+ is required.</message>
-                  <version>[${java.legacy-compat.version},)</version>
+                  <version>[${java.compat.version},)</version>
                 </requireJavaVersion>
                 <requireMavenVersion>
-                  <message>Maven 2.2.1+ is required.</message>
-                  <version>[2.2.1,)</version>
+                  <message>Maven 3.5.0+ is required.</message>
+                  <version>[3.5.0,)</version>
                 </requireMavenVersion>
                 <requirePluginVersions/>
               </rules>
@@ -418,7 +421,7 @@
       <plugin>
         <groupId>org.apache.felix</groupId>
         <artifactId>maven-bundle-plugin</artifactId>
-        <version>2.5.3</version>
+        <version>4.2.0</version>
         <configuration>
           <instructions>
             <Export-Package>*;-split-package:=merge-first</Export-Package>
diff --git a/dev-tools/scripts/checkJavaDocs.py b/dev-tools/scripts/checkJavaDocs.py
index 355bbdd..b43fcfb 100644
--- a/dev-tools/scripts/checkJavaDocs.py
+++ b/dev-tools/scripts/checkJavaDocs.py
@@ -24,7 +24,7 @@ reDivBlock = re.compile('<div class="block">(.*?)</div>', re.IGNORECASE)
 reCaption = re.compile('<caption><span>(.*?)</span>', re.IGNORECASE)
 reJ8Caption = re.compile('<h3>(.*?) Summary</h3>')
 reTDLastNested = re.compile('^<td class="colLast"><code><strong><a href="[^>]*\.([^>]*?)\.html" title="class in[^>]*">', re.IGNORECASE)
-reTDLast = re.compile('^<td class="colLast"><code><strong><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
+reMethod = re.compile('^<th class="colSecond" scope="row"><code><span class="memberNameLink"><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
 reColOne = re.compile('^<td class="colOne"><code><strong><a href="[^>]*#([^>]*?)">', re.IGNORECASE)
 reMemberNameLink = re.compile('^<td class="colLast"><code><span class="memberNameLink"><a href="[^>]*#([^>]*?)"', re.IGNORECASE)
 reNestedClassMemberNameLink = re.compile('^<td class="colLast"><code><span class="memberNameLink"><a href="[^>]*?".*?>(.*?)</a>', re.IGNORECASE)
@@ -32,8 +32,7 @@ reMemberNameOneLink = re.compile('^<td class="colOne"><code><span class="memberN
 
 # the Method detail section at the end
 reMethodDetail = re.compile('^<h3>Method Detail</h3>$', re.IGNORECASE)
-reMethodDetailAnchor = re.compile('^(?:</a>)?<a name="([^>]*?)">$', re.IGNORECASE)
-reMethodOverridden = re.compile('^<dt><strong>(Specified by:|Overrides:)</strong></dt>$', re.IGNORECASE)
+reMethodDetailAnchor = re.compile('^(?:</a>)?<a id="([^>]*?)">$', re.IGNORECASE)
 
 reTag = re.compile("(?i)<(\/?\w+)((\s+\w+(\s*=\s*(?:\".*?\"|'.*?'|[^'\">\s]+))?)+\s*|\s*)\/?>")
 
@@ -201,7 +200,7 @@ def checkClassSummaries(fullPath):
 
     # Try to find the item in question (method/member name):
     for matcher in (reTDLastNested, # nested classes
-                    reTDLast, # methods etc.
+                    reMethod, # methods etc.
                     reColOne, # ctors etc.
                     reMemberNameLink, # java 8
                     reNestedClassMemberNameLink, # java 8, nested class
@@ -276,7 +275,7 @@ def checkSummary(fullPath):
       if lineLower.startswith('package ') or lineLower.startswith('<h1 title="package" '):
         sawPackage = True
       elif sawPackage:
-        if lineLower.startswith('<table ') or lineLower.startswith('<b>see: ') or lineLower.startswith('<p>see:'):
+        if lineLower.startswith('<table ') or lineLower.startswith('<b>see: ') or lineLower.startswith('<p>see:') or lineLower.startswith('</main>'):
           desc = ' '.join(desc)
           desc = reMarkup.sub(' ', desc)
           desc = desc.strip()
@@ -316,6 +315,8 @@ def checkSummary(fullPath):
 def unEscapeURL(s):
   # Not exhaustive!!
   s = s.replace('%20', ' ')
+  s = s.replace('%5B', '[')
+  s = s.replace('%5D', ']')
   return s
 
 def unescapeHTML(s):
diff --git a/dev-tools/scripts/checkJavadocLinks.py b/dev-tools/scripts/checkJavadocLinks.py
index 8ae0f4c..5d07e27 100644
--- a/dev-tools/scripts/checkJavadocLinks.py
+++ b/dev-tools/scripts/checkJavadocLinks.py
@@ -44,6 +44,7 @@ class FindHyperlinks(HTMLParser):
     if tag not in ('link', 'meta', 'frame', 'br', 'hr', 'p', 'li', 'img', 'col', 'a'):
       self.stack.append(tag)
     if tag == 'a':
+      id = None
       name = None
       href = None
       for attName, attValue in attrs:
@@ -51,6 +52,8 @@ class FindHyperlinks(HTMLParser):
           name = attValue
         elif attName == 'href':
           href = attValue
+        elif attName == 'id':
+          id = attValue
 
       if name is not None:
         assert href is None
@@ -72,12 +75,8 @@ class FindHyperlinks(HTMLParser):
         assert name is None
         href = href.strip()
         self.links.append(urlparse.urljoin(self.baseURL, href))
-      else:
-        if self.baseURL.endswith('/AttributeSource.html'):
-          # LUCENE-4010: AttributeSource's javadocs has an unescaped <A> generics!!  Seems to be a javadocs bug... (fixed in Java 7)
-          pass
-        else:
-          raise RuntimeError('couldn\'t find an href nor name in link in %s: only got these attrs: %s' % (self.baseURL, attrs))
+      elif id is None:
+        raise RuntimeError('couldn\'t find an href nor name in link in %s: only got these attrs: %s' % (self.baseURL, attrs))
 
   def handle_endtag(self, tag):
     if tag in ('link', 'meta', 'frame', 'br', 'hr', 'p', 'li', 'img', 'col', 'a'):
diff --git a/dev-tools/scripts/smokeTestRelease.py b/dev-tools/scripts/smokeTestRelease.py
index a6f0990..6f3d0fc 100644
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -189,14 +189,14 @@ def checkJARMetaData(desc, jarFile, gitRevision, version):
       'Specification-Vendor: The Apache Software Foundation',
       'Implementation-Vendor: The Apache Software Foundation',
       # Make sure 1.8 compiler was used to build release bits:
-      'X-Compile-Source-JDK: 8',
+      'X-Compile-Source-JDK: 11',
       # Make sure 1.8, 1.9 or 1.10 ant was used to build release bits: (this will match 1.8.x, 1.9.x, 1.10.x)
       ('Ant-Version: Apache Ant 1.8', 'Ant-Version: Apache Ant 1.9', 'Ant-Version: Apache Ant 1.10'),
       # Make sure .class files are 1.8 format:
-      'X-Compile-Target-JDK: 8',
+      'X-Compile-Target-JDK: 11',
       'Specification-Version: %s' % version,
       # Make sure the release was compiled with 1.8:
-      'Created-By: 1.8'):
+      'Created-By: 11'):
       if type(verify) is not tuple:
         verify = (verify,)
       for x in verify:
@@ -696,54 +696,54 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
     # Can't run documentation-lint in lucene src, because dev-tools is missing
     validateCmd = 'ant validate' if project == 'lucene' else 'ant validate documentation-lint';
     print('    run "%s"' % validateCmd)
-    java.run_java8(validateCmd, '%s/validate.log' % unpackPath)
+    java.run_java11(validateCmd, '%s/validate.log' % unpackPath)
 
     if project == 'lucene':
-      print("    run tests w/ Java 8 and testArgs='%s'..." % testArgs)
-      java.run_java8('ant clean test %s' % testArgs, '%s/test.log' % unpackPath)
-      java.run_java8('ant jar', '%s/compile.log' % unpackPath)
-      testDemo(java.run_java8, isSrc, version, '1.8')
+      print("    run tests w/ Java 11 and testArgs='%s'..." % testArgs)
+      java.run_java11('ant clean test %s' % testArgs, '%s/test.log' % unpackPath)
+      java.run_java11('ant jar', '%s/compile.log' % unpackPath)
+      testDemo(java.run_java11, isSrc, version, '11')
 
-      print('    generate javadocs w/ Java 8...')
-      java.run_java8('ant javadocs', '%s/javadocs.log' % unpackPath)
+      print('    generate javadocs w/ Java 11...')
+      java.run_java11('ant javadocs', '%s/javadocs.log' % unpackPath)
       checkJavadocpathFull('%s/build/docs' % unpackPath)
 
-      if java.run_java9:
-        print("    run tests w/ Java 9 and testArgs='%s'..." % testArgs)
-        java.run_java9('ant clean test %s' % testArgs, '%s/test.log' % unpackPath)
-        java.run_java9('ant jar', '%s/compile.log' % unpackPath)
-        testDemo(java.run_java9, isSrc, version, '9')
+      if java.run_java12:
+        print("    run tests w/ Java 12 and testArgs='%s'..." % testArgs)
+        java.run_java12('ant clean test %s' % testArgs, '%s/test.log' % unpackPath)
+        java.run_java12('ant jar', '%s/compile.log' % unpackPath)
+        testDemo(java.run_java12, isSrc, version, '12')
 
-        #print('    generate javadocs w/ Java 9...')
-        #java.run_java9('ant javadocs', '%s/javadocs.log' % unpackPath)
+        #print('    generate javadocs w/ Java 12...')
+        #java.run_java12('ant javadocs', '%s/javadocs.log' % unpackPath)
         #checkJavadocpathFull('%s/build/docs' % unpackPath)
 
     else:
       os.chdir('solr')
 
-      print("    run tests w/ Java 8 and testArgs='%s'..." % testArgs)
-      java.run_java8('ant clean test -Dtests.slow=false %s' % testArgs, '%s/test.log' % unpackPath)
+      print("    run tests w/ Java 11 and testArgs='%s'..." % testArgs)
+      java.run_java11('ant clean test -Dtests.slow=false %s' % testArgs, '%s/test.log' % unpackPath)
 
       # test javadocs
-      print('    generate javadocs w/ Java 8...')
-      java.run_java8('ant clean javadocs', '%s/javadocs.log' % unpackPath)
+      print('    generate javadocs w/ Java 11...')
+      java.run_java11('ant clean javadocs', '%s/javadocs.log' % unpackPath)
       checkJavadocpathFull('%s/solr/build/docs' % unpackPath, False)
 
-      print('    test solr example w/ Java 8...')
-      java.run_java8('ant clean server', '%s/antexample.log' % unpackPath)
-      testSolrExample(unpackPath, java.java8_home, True)
+      print('    test solr example w/ Java 11...')
+      java.run_java11('ant clean server', '%s/antexample.log' % unpackPath)
+      testSolrExample(unpackPath, java.java11_home, True)
 
-      if java.run_java9:
-        print("    run tests w/ Java 9 and testArgs='%s'..." % testArgs)
-        java.run_java9('ant clean test -Dtests.slow=false %s' % testArgs, '%s/test.log' % unpackPath)
+      if java.run_java12:
+        print("    run tests w/ Java 12 and testArgs='%s'..." % testArgs)
+        java.run_java12('ant clean test -Dtests.slow=false %s' % testArgs, '%s/test.log' % unpackPath)
 
-        #print('    generate javadocs w/ Java 9...')
-        #java.run_java9('ant clean javadocs', '%s/javadocs.log' % unpackPath)
+        #print('    generate javadocs w/ Java 12...')
+        #java.run_java12('ant clean javadocs', '%s/javadocs.log' % unpackPath)
         #checkJavadocpathFull('%s/solr/build/docs' % unpackPath, False)
 
-        print('    test solr example w/ Java 9...')
-        java.run_java9('ant clean server', '%s/antexample.log' % unpackPath)
-        testSolrExample(unpackPath, java.java9_home, True)
+        print('    test solr example w/ Java 12...')
+        java.run_java12('ant clean server', '%s/antexample.log' % unpackPath)
+        testSolrExample(unpackPath, java.java12_home, True)
 
       os.chdir('..')
       print('    check NOTICE')
@@ -754,32 +754,32 @@ def verifyUnpacked(java, project, artifact, unpackPath, gitRevision, version, te
     checkAllJARs(os.getcwd(), project, gitRevision, version, tmpDir, baseURL)
 
     if project == 'lucene':
-      testDemo(java.run_java8, isSrc, version, '1.8')
-      if java.run_java9:
-        testDemo(java.run_java9, isSrc, version, '9')
+      testDemo(java.run_java11, isSrc, version, '11')
+      if java.run_java12:
+        testDemo(java.run_java12, isSrc, version, '12')
 
       print('    check Lucene\'s javadoc JAR')
       checkJavadocpath('%s/docs' % unpackPath)
 
     else:
-      print('    copying unpacked distribution for Java 8 ...')
-      java8UnpackPath = '%s-java8' % unpackPath
-      if os.path.exists(java8UnpackPath):
-        shutil.rmtree(java8UnpackPath)
-      shutil.copytree(unpackPath, java8UnpackPath)
-      os.chdir(java8UnpackPath)
-      print('    test solr example w/ Java 8...')
-      testSolrExample(java8UnpackPath, java.java8_home, False)
-
-      if java.run_java9:
-        print('    copying unpacked distribution for Java 9 ...')
-        java9UnpackPath = '%s-java9' % unpackPath
-        if os.path.exists(java9UnpackPath):
-          shutil.rmtree(java9UnpackPath)
-        shutil.copytree(unpackPath, java9UnpackPath)
-        os.chdir(java9UnpackPath)
-        print('    test solr example w/ Java 9...')
-        testSolrExample(java9UnpackPath, java.java9_home, False)
+      print('    copying unpacked distribution for Java 11 ...')
+      java11UnpackPath = '%s-java11' % unpackPath
+      if os.path.exists(java11UnpackPath):
+        shutil.rmtree(java11UnpackPath)
+      shutil.copytree(unpackPath, java11UnpackPath)
+      os.chdir(java11UnpackPath)
+      print('    test solr example w/ Java 11...')
+      testSolrExample(java11UnpackPath, java.java11_home, False)
+
+      if java.run_java12:
+        print('    copying unpacked distribution for Java 12 ...')
+        java12UnpackPath = '%s-java12' % unpackPath
+        if os.path.exists(java12UnpackPath):
+          shutil.rmtree(java12UnpackPath)
+        shutil.copytree(unpackPath, java12UnpackPath)
+        os.chdir(java12UnpackPath)
+        print('    test solr example w/ Java 12...')
+        testSolrExample(java12UnpackPath, java.java12_home, False)
 
       os.chdir(unpackPath)
 
@@ -1230,7 +1230,7 @@ def crawl(downloadedFiles, urlString, targetDir, exclusions=set()):
         downloadedFiles.append(path)
         sys.stdout.write('.')
 
-def make_java_config(parser, java9_home):
+def make_java_config(parser, java12_home):
   def _make_runner(java_home, version):
     print('Java %s JAVA_HOME=%s' % (version, java_home))
     if cygwin:
@@ -1244,16 +1244,16 @@ def make_java_config(parser, java9_home):
     def run_java(cmd, logfile):
       run('%s; %s' % (cmd_prefix, cmd), logfile)
     return run_java
-  java8_home =  os.environ.get('JAVA_HOME')
-  if java8_home is None:
+  java11_home =  os.environ.get('JAVA_HOME')
+  if java11_home is None:
     parser.error('JAVA_HOME must be set')
-  run_java8 = _make_runner(java8_home, '1.8')
-  run_java9 = None
-  if java9_home is not None:
-    run_java9 = _make_runner(java9_home, '9')
+  run_java11 = _make_runner(java11_home, '11')
+  run_java12 = None
+  if java12_home is not None:
+    run_java12 = _make_runner(java12_home, '12')
 
-  jc = namedtuple('JavaConfig', 'run_java8 java8_home run_java9 java9_home')
-  return jc(run_java8, java8_home, run_java9, java9_home)
+  jc = namedtuple('JavaConfig', 'run_java11 java11_home run_java12 java12_home')
+  return jc(run_java11, java11_home, run_java12, java12_home)
 
 version_re = re.compile(r'(\d+\.\d+\.\d+(-ALPHA|-BETA)?)')
 revision_re = re.compile(r'rev([a-f\d]+)')
@@ -1275,8 +1275,8 @@ def parse_config():
                       help='GIT revision number that release was built with, defaults to that in URL')
   parser.add_argument('--version', metavar='X.Y.Z(-ALPHA|-BETA)?',
                       help='Version of the release, defaults to that in URL')
-  parser.add_argument('--test-java9', metavar='JAVA9_HOME',
-                      help='Path to Java9 home directory, to run tests with if specified')
+  parser.add_argument('--test-java12', metavar='JAVA12_HOME',
+                      help='Path to Java12 home directory, to run tests with if specified')
   parser.add_argument('url', help='Url pointing to release to test')
   parser.add_argument('test_args', nargs=argparse.REMAINDER,
                       help='Arguments to pass to ant for testing, e.g. -Dwhat=ever.')
@@ -1301,7 +1301,7 @@ def parse_config():
   if c.local_keys is not None and not os.path.exists(c.local_keys):
     parser.error('Local KEYS file "%s" not found' % c.local_keys)
 
-  c.java = make_java_config(parser, c.test_java9)
+  c.java = make_java_config(parser, c.test_java12)
 
   if c.tmp_dir:
     c.tmp_dir = os.path.abspath(c.tmp_dir)
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
index 06aed49..ceec615 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
@@ -78,7 +78,7 @@ public final class SnowballFilter extends TokenFilter {
     try {
       Class<? extends SnowballProgram> stemClass =
         Class.forName("org.tartarus.snowball.ext." + name + "Stemmer").asSubclass(SnowballProgram.class);
-      stemmer = stemClass.newInstance();
+      stemmer = stemClass.getConstructor().newInstance();
     } catch (Exception e) {
       throw new IllegalArgumentException("Invalid stemmer class specified: " + name, e);
     }
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
index ee3876d..181f7ad 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
@@ -76,7 +76,7 @@ public class SnowballPorterFilterFactory extends TokenFilterFactory implements R
   public TokenFilter create(TokenStream input) {
     SnowballProgram program;
     try {
-      program = stemClass.newInstance();
+      program = stemClass.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Error instantiating stemmer for language " + language + "from class " + stemClass, e);
     }
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java
index 4ee9212..e746347 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java
@@ -91,7 +91,7 @@ public final class ClasspathResourceLoader implements ResourceLoader {
   public <T> T newInstance(String cname, Class<T> expectedType) {
     Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Cannot create instance: " + cname, e);
     }
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java
index ddaa984..10358c7 100644
--- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestRandomChains.java
@@ -408,7 +408,7 @@ public class TestRandomChains extends BaseTokenStreamTestCase {
         try {
           String lang = TestSnowball.SNOWBALL_LANGS[random.nextInt(TestSnowball.SNOWBALL_LANGS.length)];
           Class<? extends SnowballProgram> clazz = Class.forName("org.tartarus.snowball.ext." + lang + "Stemmer").asSubclass(SnowballProgram.class);
-          return clazz.newInstance();
+          return clazz.getConstructor().newInstance();
         } catch (Exception ex) {
           Rethrow.rethrow(ex);
           return null; // unreachable code
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java
index 883671d..f5384f4 100644
--- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java
@@ -43,7 +43,7 @@ public class StringMockResourceLoader implements ResourceLoader {
   public <T> T newInstance(String cname, Class<T> expectedType) {
     Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Cannot create instance: " + cname, e);
     }
diff --git a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/StringMockResourceLoader.java b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/StringMockResourceLoader.java
index 61a8a85..887098f 100644
--- a/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/StringMockResourceLoader.java
+++ b/lucene/analysis/kuromoji/src/test/org/apache/lucene/analysis/ja/StringMockResourceLoader.java
@@ -45,7 +45,7 @@ class StringMockResourceLoader implements ResourceLoader {
   public <T> T newInstance(String cname, Class<T> expectedType) {
     Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Cannot create instance: " + cname, e);
     }
diff --git a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/StringMockResourceLoader.java b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/StringMockResourceLoader.java
index cc1ee00..db9ff89 100644
--- a/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/StringMockResourceLoader.java
+++ b/lucene/analysis/nori/src/test/org/apache/lucene/analysis/ko/StringMockResourceLoader.java
@@ -45,7 +45,7 @@ class StringMockResourceLoader implements ResourceLoader {
   public <T> T newInstance(String cname, Class<T> expectedType) {
     Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Cannot create instance: " + cname, e);
     }
diff --git a/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java b/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
index d5d3b0e..e580d6e 100644
--- a/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
+++ b/lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
@@ -144,7 +144,7 @@ public class PhoneticFilterFactory extends TokenFilterFactory implements Resourc
     // Unfortunately, Commons-Codec doesn't offer any thread-safe guarantees so we must play it safe and instantiate
     // every time.  A simple benchmark showed this as negligible.
     try {
-      Encoder encoder = clazz.newInstance();
+      Encoder encoder = clazz.getConstructor().newInstance();
       // Try to set the maxCodeLength
       if(maxCodeLength != null && setMaxCodeLenMethod != null) {
         setMaxCodeLenMethod.invoke(encoder, maxCodeLength);
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java
index 1304d4b..8ad4755 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java
@@ -115,16 +115,16 @@ public class PerfRunData implements Closeable {
 
     // content source
     String sourceClass = config.get("content.source", "org.apache.lucene.benchmark.byTask.feeds.SingleDocSource");
-    contentSource = Class.forName(sourceClass).asSubclass(ContentSource.class).newInstance();
+    contentSource = Class.forName(sourceClass).asSubclass(ContentSource.class).getConstructor().newInstance();
     contentSource.setConfig(config);
 
     // doc maker
     docMaker = Class.forName(config.get("doc.maker",
-        "org.apache.lucene.benchmark.byTask.feeds.DocMaker")).asSubclass(DocMaker.class).newInstance();
+        "org.apache.lucene.benchmark.byTask.feeds.DocMaker")).asSubclass(DocMaker.class).getConstructor().newInstance();
     docMaker.setConfig(config, contentSource);
     // facet source
     facetSource = Class.forName(config.get("facet.source",
-        "org.apache.lucene.benchmark.byTask.feeds.RandomFacetSource")).asSubclass(FacetSource.class).newInstance();
+        "org.apache.lucene.benchmark.byTask.feeds.RandomFacetSource")).asSubclass(FacetSource.class).getConstructor().newInstance();
     facetSource.setConfig(config);
     // query makers
     readTaskQueryMaker = new HashMap<>();
@@ -453,7 +453,7 @@ public class PerfRunData implements Closeable {
     QueryMaker qm = readTaskQueryMaker.get(readTaskClass);
     if (qm == null) {
       try {
-        qm = qmkrClass.newInstance();
+        qm = qmkrClass.getConstructor().newInstance();
         qm.setConfig(config);
       } catch (Exception e) {
         throw new RuntimeException(e);
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/EnwikiContentSource.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/EnwikiContentSource.java
index 7258476..0f63155 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/EnwikiContentSource.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/EnwikiContentSource.java
@@ -26,6 +26,11 @@ import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
+import javax.xml.XMLConstants;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
 import org.apache.lucene.benchmark.byTask.utils.Config;
 import org.apache.lucene.benchmark.byTask.utils.StreamUtils;
 import org.apache.lucene.util.IOUtils;
@@ -33,9 +38,9 @@ import org.apache.lucene.util.ThreadInterruptedException;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
 import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
 
 /**
  * A {@link ContentSource} which reads the English Wikipedia dump. You can read
@@ -48,6 +53,15 @@ import org.xml.sax.helpers.XMLReaderFactory;
  */
 public class EnwikiContentSource extends ContentSource {
 
+  private static final SAXParserFactory SAX_PARSER_FACTORY = SAXParserFactory.newDefaultInstance();
+  static {
+    try {
+      SAX_PARSER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+    } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+      throw new Error(e);
+    }
+  }
+
   private class Parser extends DefaultHandler implements Runnable {
     private Thread t;
     private boolean threadDone;
@@ -172,15 +186,13 @@ public class EnwikiContentSource extends ContentSource {
     public void run() {
 
       try {
-        XMLReader reader = XMLReaderFactory.createXMLReader();
-        reader.setContentHandler(this);
-        reader.setErrorHandler(this);
+        SAXParser reader = SAX_PARSER_FACTORY.newSAXParser();
         while(!stopped){
           final InputStream localFileIS = is;
           if (localFileIS != null) { // null means fileIS was closed on us 
             try {
               // To work around a bug in XERCES (XERCESJ-1257), we assume the XML is always UTF8, so we simply provide reader.
-              reader.parse(new InputSource(IOUtils.getDecodingReader(localFileIS, StandardCharsets.UTF_8)));
+              reader.parse(new InputSource(IOUtils.getDecodingReader(localFileIS, StandardCharsets.UTF_8)), this);
             } catch (IOException ioe) {
               synchronized(EnwikiContentSource.this) {
                 if (localFileIS != is) {
@@ -202,7 +214,7 @@ public class EnwikiContentSource extends ContentSource {
             }
           }
         }
-      } catch (SAXException | IOException sae) {
+      } catch (SAXException | IOException | ParserConfigurationException sae) {
         throw new RuntimeException(sae);
       } finally {
         synchronized(this) {
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/TrecContentSource.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/TrecContentSource.java
index 6ceb922..55c6b63 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/TrecContentSource.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/feeds/TrecContentSource.java
@@ -309,7 +309,7 @@ public class TrecContentSource extends ContentSource {
     // trec doc parser
     try {
       String trecDocParserClassName = config.get("trec.doc.parser", "org.apache.lucene.benchmark.byTask.feeds.TrecGov2Parser");
-      trecDocParser = Class.forName(trecDocParserClassName).asSubclass(TrecDocParser.class).newInstance();
+      trecDocParser = Class.forName(trecDocParserClassName).asSubclass(TrecDocParser.class).getConstructor().newInstance();
     } catch (Exception e) {
       // Should not get here. Throw runtime exception.
       throw new RuntimeException(e);
@@ -318,7 +318,7 @@ public class TrecContentSource extends ContentSource {
     try {
       String htmlParserClassName = config.get("html.parser",
           "org.apache.lucene.benchmark.byTask.feeds.DemoHTMLParser");
-      htmlParser = Class.forName(htmlParserClassName).asSubclass(HTMLParser.class).newInstance();
+      htmlParser = Class.forName(htmlParserClassName).asSubclass(HTMLParser.class).getConstructor().newInstance();
     } catch (Exception e) {
       // Should not get here. Throw runtime exception.
       throw new RuntimeException(e);
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
index d4d68d6..30076e9 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
@@ -80,7 +80,7 @@ public class CreateIndexTask extends PerfTask {
       return NoDeletionPolicy.INSTANCE;
     } else {
       try {
-        return Class.forName(deletionPolicyName).asSubclass(IndexDeletionPolicy.class).newInstance();
+        return Class.forName(deletionPolicyName).asSubclass(IndexDeletionPolicy.class).getConstructor().newInstance();
       } catch (Exception e) {
         throw new RuntimeException("unable to instantiate class '" + deletionPolicyName + "' as IndexDeletionPolicy", e);
       }
@@ -96,7 +96,6 @@ public class CreateIndexTask extends PerfTask {
   }
   
   public static IndexWriterConfig createWriterConfig(Config config, PerfRunData runData, OpenMode mode, IndexCommit commit) {
-    @SuppressWarnings("deprecation")
     IndexWriterConfig iwConf = new IndexWriterConfig(runData.getAnalyzer());
     iwConf.setOpenMode(mode);
     IndexDeletionPolicy indexDeletionPolicy = getIndexDeletionPolicy(config);
@@ -112,7 +111,7 @@ public class CreateIndexTask extends PerfTask {
       iwConf.setMergeScheduler(NoMergeScheduler.INSTANCE);
     } else {
       try {
-        iwConf.setMergeScheduler(Class.forName(mergeScheduler).asSubclass(MergeScheduler.class).newInstance());
+        iwConf.setMergeScheduler(Class.forName(mergeScheduler).asSubclass(MergeScheduler.class).getConstructor().newInstance());
       } catch (Exception e) {
         throw new RuntimeException("unable to instantiate class '" + mergeScheduler + "' as merge scheduler", e);
       }
@@ -129,7 +128,7 @@ public class CreateIndexTask extends PerfTask {
     if (defaultCodec != null) {
       try {
         Class<? extends Codec> clazz = Class.forName(defaultCodec).asSubclass(Codec.class);
-        iwConf.setCodec(clazz.newInstance());
+        iwConf.setCodec(clazz.getConstructor().newInstance());
       } catch (Exception e) {
         throw new RuntimeException("Couldn't instantiate Codec: " + defaultCodec, e);
       }
@@ -158,7 +157,7 @@ public class CreateIndexTask extends PerfTask {
       iwConf.setMergePolicy(NoMergePolicy.INSTANCE);
     } else {
       try {
-        iwConf.setMergePolicy(Class.forName(mergePolicy).asSubclass(MergePolicy.class).newInstance());
+        iwConf.setMergePolicy(Class.forName(mergePolicy).asSubclass(MergePolicy.class).getConstructor().newInstance());
       } catch (Exception e) {
         throw new RuntimeException("unable to instantiate class '" + mergePolicy + "' as merge policy", e);
       }
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NewAnalyzerTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NewAnalyzerTask.java
index 1673d34..53f5b10 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NewAnalyzerTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NewAnalyzerTask.java
@@ -48,7 +48,7 @@ public class NewAnalyzerTask extends PerfTask {
       return cnstr.newInstance(Version.LATEST);
     } catch (NoSuchMethodException nsme) {
       // otherwise use default ctor
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     }
   }
 
diff --git a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
index f557f93..e3343fe 100644
--- a/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
+++ b/lucene/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/SearchWithCollectorTask.java
@@ -55,7 +55,7 @@ public class SearchWithCollectorTask extends SearchTask {
     if (clnName.equalsIgnoreCase("topScoreDoc") == true) {
       collector = TopScoreDocCollector.create(numHits(), Integer.MAX_VALUE);
     } else if (clnName.length() > 0){
-      collector = Class.forName(clnName).asSubclass(Collector.class).newInstance();
+      collector = Class.forName(clnName).asSubclass(Collector.class).getConstructor().newInstance();
 
     } else {
       collector = super.createCollector();
diff --git a/lucene/build.xml b/lucene/build.xml
index e3cf905..d4eb59e 100644
--- a/lucene/build.xml
+++ b/lucene/build.xml
@@ -543,7 +543,7 @@
   </target>
 
   <!-- Override common-build.xml definition to check for the jar already being up-to-date -->
-  <target name="jar-core" depends="resolve-groovy,check-lucene-core-uptodate,compile-lucene-core" unless="lucene-core.uptodate">
+  <target name="jar-core" depends="check-lucene-core-uptodate,compile-lucene-core" unless="lucene-core.uptodate">
     <ant dir="${common.dir}/core" target="jar-core" inheritAll="false">
       <propertyset refid="uptodate.and.compiled.properties"/>
     </ant>
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDWriter.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDWriter.java
index ff6cbaa..aefa00c 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDWriter.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextBKDWriter.java
@@ -36,7 +36,6 @@ import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.bkd.BKDRadixSelector;
@@ -233,10 +232,10 @@ final class SimpleTextBKDWriter implements Closeable {
     } else {
       for(int dim=0;dim<numIndexDims;dim++) {
         int offset = dim*bytesPerDim;
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
           System.arraycopy(packedValue, offset, minPackedValue, offset, bytesPerDim);
         }
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           System.arraycopy(packedValue, offset, maxPackedValue, offset, bytesPerDim);
         }
       }
@@ -302,10 +301,10 @@ final class SimpleTextBKDWriter implements Closeable {
       values.getValue(i, scratchBytesRef1);
       for(int dim=0;dim<numIndexDims;dim++) {
         int offset = dim*bytesPerDim;
-        if (FutureArrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
           System.arraycopy(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, minPackedValue, offset, bytesPerDim);
         }
-        if (FutureArrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           System.arraycopy(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, maxPackedValue, offset, bytesPerDim);
         }
       }
@@ -777,10 +776,10 @@ final class SimpleTextBKDWriter implements Closeable {
   private boolean valueInBounds(BytesRef packedValue, byte[] minPackedValue, byte[] maxPackedValue) {
     for(int dim=0;dim<numIndexDims;dim++) {
       int offset = bytesPerDim*dim;
-      if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+      if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
         return false;
       }
-      if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+      if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
         return false;
       }
     }
@@ -793,7 +792,7 @@ final class SimpleTextBKDWriter implements Closeable {
     int splitDim = -1;
     for(int dim=0;dim<numIndexDims;dim++) {
       NumericUtils.subtract(bytesPerDim, dim, maxPackedValue, minPackedValue, scratchDiff);
-      if (splitDim == -1 || FutureArrays.compareUnsigned(scratchDiff, 0, bytesPerDim, scratch1, 0, bytesPerDim) > 0) {
+      if (splitDim == -1 || Arrays.compareUnsigned(scratchDiff, 0, bytesPerDim, scratch1, 0, bytesPerDim) > 0) {
         System.arraycopy(scratchDiff, 0, scratch1, 0, bytesPerDim);
         splitDim = dim;
       }
@@ -1049,7 +1048,7 @@ final class SimpleTextBKDWriter implements Closeable {
       long rightCount = points.count / 2;
       long leftCount = points.count - rightCount;
 
-      int commonPrefixLen = FutureArrays.mismatch(minPackedValue, splitDim * bytesPerDim,
+      int commonPrefixLen = Arrays.mismatch(minPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim, maxPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim);
       if (commonPrefixLen == -1) {
@@ -1096,7 +1095,7 @@ final class SimpleTextBKDWriter implements Closeable {
       packedValue = value.packedValue();
       for (int dim = 0; dim < numDataDims; dim++) {
         if (commonPrefixLengths[dim] != 0) {
-          int j = FutureArrays.mismatch(commonPrefix, dim * bytesPerDim, dim * bytesPerDim + commonPrefixLengths[dim], packedValue.bytes, packedValue.offset + dim * bytesPerDim, packedValue.offset + dim * bytesPerDim + commonPrefixLengths[dim]);
+          int j = Arrays.mismatch(commonPrefix, dim * bytesPerDim, dim * bytesPerDim + commonPrefixLengths[dim], packedValue.bytes, packedValue.offset + dim * bytesPerDim, packedValue.offset + dim * bytesPerDim + commonPrefixLengths[dim]);
           if (j != -1) {
             commonPrefixLengths[dim] = j;
           }
@@ -1128,7 +1127,7 @@ final class SimpleTextBKDWriter implements Closeable {
       int doc, int lastDoc) {
     int dimOffset = sortedDim * bytesPerDim;
     if (ord > 0) {
-      int cmp = FutureArrays.compareUnsigned(lastPackedValue, dimOffset, dimOffset + bytesPerDim, packedValue, packedValueOffset + dimOffset, packedValueOffset + dimOffset + bytesPerDim);
+      int cmp = Arrays.compareUnsigned(lastPackedValue, dimOffset, dimOffset + bytesPerDim, packedValue, packedValueOffset + dimOffset, packedValueOffset + dimOffset + bytesPerDim);
       if (cmp > 0) {
         throw new AssertionError("values out of order: last value=" + new BytesRef(lastPackedValue) + " current value=" + new BytesRef(packedValue, packedValueOffset, packedBytesLength) + " ord=" + ord + " sortedDim=" + sortedDim);
       }
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
index b457ca5..2078378 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/simpletext/SimpleTextStoredFieldsReader.java
@@ -18,6 +18,7 @@ package org.apache.lucene.codecs.simpletext;
 
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import org.apache.lucene.codecs.StoredFieldsReader;
 import org.apache.lucene.index.FieldInfo;
@@ -36,7 +37,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.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.lucene.util.StringHelper;
@@ -204,7 +204,7 @@ public class SimpleTextStoredFieldsReader extends StoredFieldsReader {
   
   private boolean equalsAt(BytesRef a, BytesRef b, int bOffset) {
     return a.length == b.length - bOffset &&
-        FutureArrays.equals(a.bytes, a.offset, a.offset + a.length, b.bytes, b.offset + bOffset, b.offset + b.length);
+        Arrays.equals(a.bytes, a.offset, a.offset + a.length, b.bytes, b.offset + bOffset, b.offset + b.length);
   }
 
   @Override
diff --git a/lucene/common-build.xml b/lucene/common-build.xml
index e9405a6..c61eee2 100644
--- a/lucene/common-build.xml
+++ b/lucene/common-build.xml
@@ -166,20 +166,15 @@
 
   <!-- Display at most this many failures as a summary at the end of junit4 run. -->
   <property name="tests.showNumFailures" value="10" />
-  
-  <!-- If we detect Java 9+, should we test the patched classes of the
-   multi-release JAR or still run with our own classes? -->
-  <property name="tests.withJava9Patches" value="true" />
 
   <property name="javac.deprecation" value="off"/>
   <property name="javac.debug" value="on"/>
-  <property name="javac.release" value="8"/>
+  <property name="javac.release" value="11"/>
   <property name="javac.args" value="-Xlint -Xlint:-deprecation -Xlint:-serial"/>
-  <property name="javac.profile.args" value="-profile compact2"/>
-  <property name="javadoc.link" value="https://docs.oracle.com/javase/8/docs/api/"/>
+  <property name="javadoc.link" value="https://docs.oracle.com/en/java/javase/11/docs/api/"/>
   <property name="javadoc.link.junit" value="http://junit.sourceforge.net/javadoc/"/>
   <property name="javadoc.packagelist.dir" location="${common.dir}/tools/javadoc"/>
-  <available file="${javadoc.packagelist.dir}/java8/package-list" property="javadoc.java8.packagelist.exists"/>
+  <available file="${javadoc.packagelist.dir}/java11/package-list" property="javadoc.java11.packagelist.exists"/>
   <property name="javadoc.access" value="protected"/>
   <property name="javadoc.charset" value="utf-8"/>
   <property name="javadoc.dir" location="${common.dir}/build/docs"/>
@@ -267,7 +262,7 @@
   </propertyset>
 
   <patternset id="lucene.local.src.package.patterns"
-              excludes="**/pom.xml,**/*.iml,**/*.jar,build/**,dist/**,benchmark/work/**,benchmark/temp/**,tools/javadoc/java8/**"
+              excludes="**/pom.xml,**/*.iml,**/*.jar,build/**,dist/**,benchmark/work/**,benchmark/temp/**,tools/javadoc/java11/**"
   />
 
   <!-- Default exclude sources and javadoc jars from Ivy fetch to save time and bandwidth -->
@@ -297,48 +292,12 @@
     </condition>
   </fail>
 
-  <fail message="Minimum supported Java version is 1.8.">
+  <fail message="Minimum supported Java version is 11.">
     <condition>
-      <not><hasmethod classname="java.util.Arrays" method="parallelSort"/></not>
+      <not><hasmethod classname="java.lang.String" method="repeat"/></not>
     </condition>
   </fail>
 
-  <!-- temporary for cleanup of java.specification.version, to be in format "x.y" -->
-  <loadresource property="-cleaned.specification.version">
-    <propertyresource name="java.specification.version"/>
-    <filterchain>
-      <tokenfilter>
-        <filetokenizer/>
-        <replaceregex pattern="^(\d+\.\d+)(|\..*)$" replace="\1" flags="s"/>
-      </tokenfilter>
-    </filterchain>
-  </loadresource>
-
-  <!-- 
-    the propery "ant.java.version" is not always correct, depending on used ANT version.
-    E.g. Java 8 is only detected in ANT 1.8.3+.
-    
-    We want to detect here only a limited set of versions and placed in normalized form in ${build.java.runtime},
-    every other version is normalized to "unknown":
-    - To define a target to be only run on a specific version, add <equals/> condition to one of the supplied versions.
-    - To explicitely exclude specific versions (and unknown ones), add a condition to disallow "unknown" and some versions like "1.9"/"9"!
-    - For Java 9, be sure to exclude both in custom checks: "9" and "1.9"
-    
-    TODO: Find a better solution in Ant without scripting to check supported Java versions!
-   -->
-  <condition property="build.java.runtime" value="${-cleaned.specification.version}" else="unknown">
-    <or>
-      <equals arg1="${-cleaned.specification.version}" arg2="1.8"/>
-      <equals arg1="${-cleaned.specification.version}" arg2="1.9"/>
-      <equals arg1="${-cleaned.specification.version}" arg2="9"/>
-    </or>
-  </condition>
-  
-  <!--
-  <echo message="DEBUG: Cleaned java.specification.version=${-cleaned.specification.version}"/>
-  <echo message="DEBUG: Detected runtime: ${build.java.runtime}"/>
-  -->
-  
   <condition property="documentation-lint.supported">
     <and>
       <or>
@@ -346,9 +305,9 @@
         <contains string="${java.vm.name}" substring="openjdk" casesensitive="false"/>
         <contains string="${java.vm.name}" substring="jrockit" casesensitive="false"/>
       </or>
-      <equals arg1="${build.java.runtime}" arg2="1.8"/>
+      <equals arg1="${java.specification.version}" arg2="11"/>
       <!-- TODO: Fix this! For now only run this on 64bit, because jTIDY OOMs with default heap size: -->
-      <contains string="${os.arch}" substring="64"/>
+      <!--<contains string="${os.arch}" substring="64"/>-->
     </and>
   </condition>
 
@@ -361,12 +320,12 @@
   </condition>
 
   <target name="-documentation-lint-unsupported" unless="documentation-lint.supported">
-    <fail message="Linting documentation HTML is not supported on this Java version (${build.java.runtime}) / JVM (${java.vm.name}).">
+    <fail message="Linting documentation HTML is not supported on this Java version (JVM (${java.vm.name}).">
       <condition>
         <not><isset property="is.jenkins.build"/></not>
       </condition>
     </fail>
-    <echo level="warning" message="WARN: Linting documentation HTML is not supported on this Java version (${build.java.runtime}) / JVM (${java.vm.name}). NOTHING DONE!"/>
+    <echo level="warning" message="WARN: Linting documentation HTML is not supported on this Java version (JVM (${java.vm.name}). NOTHING DONE!"/>
   </target>
 
   <!-- Import custom ANT tasks. -->
@@ -570,48 +529,10 @@
     <!-- convenience target to compile core -->
   </target>
 
-  <!-- Special targets to patch all class files by replacing some method calls with new Java 9 methods: -->
-  <target name="-mrjar-classes-uptodate">
-    <uptodate property="mrjar-classes-uptodate" targetfile="${build.dir}/patch-mrjar.stamp">
-      <srcfiles dir= "${build.dir}/classes/java" includes="**/*.class"/>
-    </uptodate>
-  </target>
-  
-  <target xmlns:ivy="antlib:org.apache.ivy.ant" name="patch-mrjar-classes" depends="-mrjar-classes-uptodate,ivy-availability-check,ivy-configure,resolve-groovy,compile-core"
-    unless="mrjar-classes-uptodate" description="Patches compiled class files for usage with Java 9 in MR-JAR">
-    <loadproperties prefix="ivyversions" srcFile="${common.dir}/ivy-versions.properties"/>
-    <ivy:cachepath organisation="org.ow2.asm" module="asm-commons" revision="${ivyversions./org.ow2.asm/asm-commons}"
-      inline="true" conf="default" transitive="true" log="download-only" pathid="asm.classpath"/>
-    <groovy taskname="patch-cls" classpathref="asm.classpath" src="${common.dir}/tools/src/groovy/patch-mrjar-classes.groovy"/>
-    <touch file="${build.dir}/patch-mrjar.stamp"/>
-  </target>
-  
-  <target name="-mrjar-check" depends="patch-mrjar-classes">
-    <zipfileset id="mrjar-patched-files" prefix="META-INF/versions/9" dir="${build.dir}/classes/java9" erroronmissingdir="false"/>
-    <condition property="has-mrjar-patched-files">
-      <resourcecount refid="mrjar-patched-files" when="greater" count="0" />
-    </condition>
-  </target>
-  
-  <target name="-mrjar-core" depends="-mrjar-check" if="has-mrjar-patched-files">
-    <jarify>
-      <filesets>
-        <zipfileset refid="mrjar-patched-files"/>
-      </filesets>
-      <jarify-additional-manifest-attributes>
-        <attribute name="Multi-Release" value="true"/>
-      </jarify-additional-manifest-attributes>
-    </jarify>
-  </target>
-  
-  <target name="-jar-core" depends="-mrjar-check" unless="has-mrjar-patched-files">
+  <target name="jar-core" depends="compile-core">
     <jarify/>
   </target>
-  
-  <target name="jar-core" depends="-mrjar-core,-jar-core"/>
 
-  <!-- Packaging targets: -->
-  
   <property name="lucene.tgz.file" location="${common.dir}/dist/lucene-${version}.tgz"/>
   <available file="${lucene.tgz.file}" property="lucene.tgz.exists"/>
   <property name="lucene.tgz.unpack.dir" location="${common.build.dir}/lucene.tgz.unpacked"/>
@@ -1022,11 +943,8 @@
           <istrue value="${tests.useSecurityManager}"/>
         </condition>
         
-        <!-- additional arguments for Java 9+ -->
-        <local name="tests.runtimespecific.args"/>
-        <condition property="tests.runtimespecific.args" value="" else="--illegal-access=deny">
-          <equals arg1="${build.java.runtime}" arg2="1.8"/>
-        </condition>
+        <!-- additional arguments -->
+        <property name="tests.runtimespecific.args" value="--illegal-access=deny"/>
 
         <!-- create a fileset pattern that matches ${tests.class}. -->
         <loadresource property="tests.explicitclass" quiet="true">
@@ -1513,15 +1431,15 @@ ${tests-output}/junit4-*.suites     - per-JVM executed suites
     </taskdef>
   </target>
 
-  <target name="test" depends="clover,compile-test,patch-mrjar-classes,install-junit4-taskdef,validate,-init-totals,-test,-check-totals" description="Runs unit tests"/>
-  <target name="beast" depends="install-ant-contrib,clover,compile-test,patch-mrjar-classes,install-junit4-taskdef,validate,-init-totals,-beast,-check-totals" description="Runs unit tests in a loop (-Dbeast.iters=n)"/>
+  <target name="test" depends="clover,compile-test,install-junit4-taskdef,validate,-init-totals,-test,-check-totals" description="Runs unit tests"/>
+  <target name="beast" depends="install-ant-contrib,clover,compile-test,install-junit4-taskdef,validate,-init-totals,-beast,-check-totals" description="Runs unit tests in a loop (-Dbeast.iters=n)"/>
 
   <target name="test-nocompile" depends="-clover.disable,install-junit4-taskdef,-init-totals,-test,-check-totals"
           description="Only runs unit tests.  Jars are not downloaded; compilation is not updated; and Clover is not enabled."/>
 
   <target name="-jacoco-install">
     <!-- download jacoco from ivy if needed -->
-    <ivy:cachepath organisation="org.jacoco" module="org.jacoco.ant" type="jar" inline="true" revision="0.7.4.201502262128"
+    <ivy:cachepath organisation="org.jacoco" module="org.jacoco.ant" type="jar" inline="true" revision="0.8.3"
                    log="download-only" pathid="jacoco.classpath" />
 
     <!-- install jacoco ant tasks -->
@@ -1626,6 +1544,7 @@ ${tests-output}/junit4-*.suites     - per-JVM executed suites
   <target name="clover" depends="-clover.disable,-clover.load,-clover.classpath,-clover.setup"/>
   
   <target name="-clover.load" depends="ivy-availability-check,ivy-configure" if="run.clover" unless="clover.loaded">
+    <fail>TODO: Code coverage with OpenClover does not yet work with Java 11 - see https://issues.apache.org/jira/browse/LUCENE-8763</fail>
     <echo>Code coverage with OpenClover enabled.</echo>
     <ivy:cachepath organisation="org.openclover" module="clover" revision="4.2.1"
       inline="true" conf="master" pathid="clover.classpath"/>
@@ -2043,10 +1962,6 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
     <element name="nested" implicit="yes" optional="yes"/>
 
     <sequential>
-      <local name="javac.release.args"/>
-      <condition property="javac.release.args" value="-source @{javac.release} -target @{javac.release}" else="--release @{javac.release}">
-        <equals arg1="${build.java.runtime}" arg2="1.8"/>
-      </condition>
       <mkdir dir="@{destdir}"/>
       <javac
         includeAntRuntime="@{includeantruntime}"
@@ -2059,8 +1974,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
         <!-- <compilerarg line="-Xmaxwarns 10000000"/>
         <compilerarg line="-Xmaxerrs 10000000"/> -->
         <compilerarg line="${javac.args}"/>
-        <compilerarg line="${javac.profile.args}"/>
-        <compilerarg line="${javac.release.args}"/>
+        <compilerarg line="--release @{javac.release}"/>
         <compilerarg line="${javac.doclint.args}"/>
       </javac>
     </sequential>
@@ -2069,7 +1983,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
   <!-- ECJ Javadoc linting: -->
   
   <condition property="ecj-javadoc-lint.supported">
-    <equals arg1="${build.java.runtime}" arg2="1.8"/>
+    <equals arg1="${java.specification.version}" arg2="11"/>
   </condition>
 
   <condition property="ecj-javadoc-lint-tests.supported">
@@ -2080,12 +1994,12 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
   </condition>
 
   <target name="-ecj-javadoc-lint-unsupported" unless="ecj-javadoc-lint.supported">
-    <fail message="Linting documentation with ECJ is not supported on this Java version (${build.java.runtime}).">
+    <fail message="Linting documentation with ECJ is not supported on this Java version (${java.specification.version}).">
       <condition>
         <not><isset property="is.jenkins.build"/></not>
       </condition>
     </fail>
-    <echo level="warning" message="WARN: Linting documentation with ECJ is not supported on this Java version (${build.java.runtime}). NOTHING DONE!"/>
+    <echo level="warning" message="WARN: Linting documentation with ECJ is not supported on this Java version (${java.specification.version}). NOTHING DONE!"/>
   </target>
 
   <target name="-ecj-javadoc-lint" depends="-ecj-javadoc-lint-unsupported,-ecj-javadoc-lint-src,-ecj-javadoc-lint-tests"/>
@@ -2103,7 +2017,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
   </target>
   
   <target name="-ecj-resolve" unless="ecj.loaded" depends="ivy-availability-check,ivy-configure" if="ecj-javadoc-lint.supported">
-    <ivy:cachepath organisation="org.eclipse.jdt.core.compiler" module="ecj" revision="4.6.1"
+    <ivy:cachepath organisation="org.eclipse.jdt" module="ecj" revision="3.17.0"
      inline="true" conf="master" type="jar" pathid="ecj.classpath" />
     <componentdef classname="org.eclipse.jdt.core.JDTCompilerAdapter"
      classpathref="ecj.classpath" name="ecj-component"/>
@@ -2150,6 +2064,8 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
   <macrodef name="jtidy-macro">
     <element name="nested" implicit="yes" optional="yes"/>
     <sequential>
+      <!--
+      TODO: find a better replacement for jTIDY that can handle HTML5
       <ivy:cachepath organisation="net.sf.jtidy" module="jtidy" revision="r938"
           log="download-only" inline="true" conf="master" type="jar" pathid="jtidy.classpath" />
       <taskdef name="tidy" classname="org.w3c.tidy.ant.JTidyTask" classpathref="jtidy.classpath"/>
@@ -2162,6 +2078,8 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
          <parameter name="show-warnings" value="false" />
       </tidy>
       <delete dir="${common.dir}/build/jtidy_tmp" quiet="true"/>
+      -->
+      <echo message="FIXME: Broken HTML checks were disabled, as jtidy can't handle HTML5." taskname="jtidy"/>
     </sequential>
   </macrodef>
 
@@ -2173,11 +2091,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
     <attribute name="overview" default="${src.dir}/overview.html"/>
     <attribute name="linksource" default="no"/>
     <sequential>
-      <local name="javadoc.release.args"/>
-      <condition property="javadoc.release.args" value="-source ${javac.release}" else="--release ${javac.release}">
-        <equals arg1="${build.java.runtime}" arg2="1.8"/>
-      </condition>
-      <antcall target="download-java8-javadoc-packagelist"/>
+      <antcall target="download-java11-javadoc-packagelist"/>
       <delete file="@{destdir}/stylesheet.css" failonerror="false"/>
       <delete file="@{destdir}/script.js" failonerror="false"/>
       <record name="@{destdir}/log_javadoc.txt" action="start" append="no"/>
@@ -2205,7 +2119,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
         <tag name="lucene.internal"
         description="NOTE: This API is for internal purposes only and might change in incompatible ways in the next release."/>
         <link offline="true" packagelistLoc="${javadoc.dir}"/>
-        <link offline="true" href="${javadoc.link}" packagelistLoc="${javadoc.packagelist.dir}/java8"/>
+        <link offline="true" href="${javadoc.link}" packagelistLoc="${javadoc.packagelist.dir}/java11"/>
         <bottom><![CDATA[
           <i>Copyright &copy; ${year} Apache Software Foundation.  All Rights Reserved.</i>
         ]]></bottom>
@@ -2213,7 +2127,7 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
         <sources />
                 
         <classpath refid="javadoc.classpath"/>
-        <arg line="${javadoc.release.args}"/>
+        <arg line="--release ${javac.release}"/>
         <arg line="${javadoc.doclint.args}"/>
       </javadoc>
       <record name="@{destdir}/log_javadoc.txt" action="stop"/>
@@ -2273,10 +2187,10 @@ ${ant.project.name}.test.dependencies=${test.classpath.list}
     </sequential>
   </macrodef>
 
-  <target name="download-java8-javadoc-packagelist" unless="javadoc.java8.packagelist.exists">
-    <mkdir dir="${javadoc.packagelist.dir}/java8"/>
-    <get src="${javadoc.link}/package-list"
-         dest="${javadoc.packagelist.dir}/java8/package-list" ignoreerrors="true"/>
+  <target name="download-java11-javadoc-packagelist" unless="javadoc.java11.packagelist.exists">
+    <mkdir dir="${javadoc.packagelist.dir}/java11"/>
+    <get src="${javadoc.link}/element-list"
+         dest="${javadoc.packagelist.dir}/java11/package-list" ignoreerrors="true"/>
   </target>
 
   <!-- VALIDATION work -->
diff --git a/lucene/core/build.xml b/lucene/core/build.xml
index 46183b0..d968798 100644
--- a/lucene/core/build.xml
+++ b/lucene/core/build.xml
@@ -31,19 +31,10 @@
 
   <path id="classpath"/>
   
-  <!-- if we run with Java 9+, we refer to the java9 classes directory and insert this before the main classpath (to "emulate" a MR-JAR): -->
-  <condition property="-test.classpath.java9.addon" value="${build.dir}/classes/java9" else="${build.dir}/classes/java">
-    <and>
-      <not><equals arg1="${build.java.runtime}" arg2="1.8"/></not>
-      <istrue value="${tests.withJava9Patches}"/>
-    </and>
-  </condition>
-
   <path id="test.classpath">
     <pathelement location="${common.dir}/build/codecs/classes/java"/>
     <pathelement location="${common.dir}/build/test-framework/classes/java"/>
     <path refid="junit-path"/>
-    <pathelement location="${-test.classpath.java9.addon}"/><!-- if it's a duplicate it gets removed by Ant! -->
     <pathelement location="${build.dir}/classes/java"/>
     <pathelement location="${build.dir}/classes/test"/>
   </path>
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
index f28cc78..9d6166d 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/CharTermAttributeImpl.java
@@ -17,13 +17,13 @@
 package org.apache.lucene.analysis.tokenattributes;
 
 import java.nio.CharBuffer;
+import java.util.Objects;
 
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.AttributeImpl;
 import org.apache.lucene.util.AttributeReflector;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
-import org.apache.lucene.util.FutureObjects;
 
 /** Default implementation of {@link CharTermAttribute}. */
 public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttribute, TermToBytesRefAttribute, Cloneable {
@@ -72,7 +72,7 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
 
   @Override
   public final CharTermAttribute setLength(int length) {
-    FutureObjects.checkFromIndexSize(0, length, termBuffer.length);
+    Objects.checkFromIndexSize(0, length, termBuffer.length);
     termLength = length;
     return this;
   }
@@ -99,13 +99,13 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
   
   @Override
   public final char charAt(int index) {
-    FutureObjects.checkIndex(index, termLength);
+    Objects.checkIndex(index, termLength);
     return termBuffer[index];
   }
   
   @Override
   public final CharSequence subSequence(final int start, final int end) {
-    FutureObjects.checkFromToIndex(start, end, termLength);
+    Objects.checkFromToIndex(start, end, termLength);
     return new String(termBuffer, start, end - start);
   }
   
@@ -123,7 +123,7 @@ public class CharTermAttributeImpl extends AttributeImpl implements CharTermAttr
     if (csq == null) // needed for Appendable compliance
       csq = "null";
     // TODO: the optimized cases (jdk methods) will already do such checks, maybe re-organize this?
-    FutureObjects.checkFromToIndex(start, end, csq.length());
+    Objects.checkFromToIndex(start, end, csq.length());
     final int len = end - start;
     if (len == 0)
       return this;
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java b/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
index cba625f..51ac89f 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/compressing/LZ4.java
@@ -22,7 +22,6 @@ import java.util.Arrays;
 
 import org.apache.lucene.store.DataInput;
 import org.apache.lucene.store.DataOutput;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.packed.PackedInts;
 
 /**
@@ -63,7 +62,7 @@ final class LZ4 {
   private static int commonBytes(byte[] b, int o1, int o2, int limit) {
     assert o1 < o2;
     // never -1 because lengths always differ
-    return FutureArrays.mismatch(b, o1, limit, b, o2, limit);
+    return Arrays.mismatch(b, o1, limit, b, o2, limit);
   }
 
   private static int commonBytesBackward(byte[] b, int o1, int o2, int l1, int l2) {
diff --git a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
index f4b625e..aa62f22 100644
--- a/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
+++ b/lucene/core/src/java/org/apache/lucene/document/BinaryPoint.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.PointInSetQuery;
 import org.apache.lucene.search.PointRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 
 /** 
  * An indexed binary field for fast range filters.  If you also
@@ -222,7 +221,7 @@ public final class BinaryPoint extends Field {
                 new Comparator<byte[]>() {
                   @Override
                   public int compare(byte[] a, byte[] b) {
-                    return FutureArrays.compareUnsigned(a, 0, a.length, b, 0, b.length);
+                    return Arrays.compareUnsigned(a, 0, a.length, b, 0, b.length);
                   }
                 });
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java b/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
index 726d0a1..f798205 100644
--- a/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/DoubleRange.java
@@ -16,10 +16,11 @@
  */
 package org.apache.lucene.document;
 
+import java.util.Objects;
+
 import org.apache.lucene.document.RangeFieldQuery.QueryType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.NumericUtils;
 
 /**
@@ -148,7 +149,7 @@ public class DoubleRange extends Field {
    * @return the decoded min value
    */
   public double getMin(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMin(((BytesRef)fieldsData).bytes, dimension);
   }
 
@@ -158,7 +159,7 @@ public class DoubleRange extends Field {
    * @return the decoded max value
    */
   public double getMax(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMax(((BytesRef)fieldsData).bytes, dimension);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/FloatRange.java b/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
index 191631b..bf23118 100644
--- a/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/FloatRange.java
@@ -16,10 +16,11 @@
  */
 package org.apache.lucene.document;
 
+import java.util.Objects;
+
 import org.apache.lucene.document.RangeFieldQuery.QueryType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.NumericUtils;
 
 /**
@@ -148,7 +149,7 @@ public class FloatRange extends Field {
    * @return the decoded min value
    */
   public float getMin(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMin(((BytesRef)fieldsData).bytes, dimension);
   }
 
@@ -158,7 +159,7 @@ public class FloatRange extends Field {
    * @return the decoded max value
    */
   public float getMax(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMax(((BytesRef)fieldsData).bytes, dimension);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/IntRange.java b/lucene/core/src/java/org/apache/lucene/document/IntRange.java
index b24e80a..170e62b 100644
--- a/lucene/core/src/java/org/apache/lucene/document/IntRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/IntRange.java
@@ -16,10 +16,11 @@
  */
 package org.apache.lucene.document;
 
+import java.util.Objects;
+
 import org.apache.lucene.document.RangeFieldQuery.QueryType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.NumericUtils;
 
 /**
@@ -148,7 +149,7 @@ public class IntRange extends Field {
    * @return the decoded min value
    */
   public int getMin(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMin(((BytesRef)fieldsData).bytes, dimension);
   }
 
@@ -158,7 +159,7 @@ public class IntRange extends Field {
    * @return the decoded max value
    */
   public int getMax(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMax(((BytesRef)fieldsData).bytes, dimension);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
index 3a34cae..846b353 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceFeatureQuery.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.document;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Objects;
 
 import org.apache.lucene.geo.GeoEncodingUtils;
@@ -39,7 +40,6 @@ import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.ScorerSupplier;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.SloppyMath;
 
@@ -411,21 +411,21 @@ final class LatLonPointDistanceFeatureQuery extends Query {
             // Already visited or skipped
             return;
           }
-          if (FutureArrays.compareUnsigned(packedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0 ||
-              FutureArrays.compareUnsigned(packedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0) {
+          if (Arrays.compareUnsigned(packedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0 ||
+              Arrays.compareUnsigned(packedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0) {
             //Latitude out of range
             return;
           }
           if (crossDateLine) {
-            if (FutureArrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0 &&
-                FutureArrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES)  > 0) {
+            if (Arrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0 &&
+                Arrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES)  > 0) {
               //Longitude out of range
               return;
             }
 
           } else {
-            if (FutureArrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
+            if (Arrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 ||
+                Arrays.compareUnsigned(packedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
               //Longitude out of range
               return;
             }
@@ -436,28 +436,28 @@ final class LatLonPointDistanceFeatureQuery extends Query {
         @Override
         public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
 
-          if (FutureArrays.compareUnsigned(minPackedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0 ||
-              FutureArrays.compareUnsigned(maxPackedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0) {
+          if (Arrays.compareUnsigned(minPackedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0 ||
+              Arrays.compareUnsigned(maxPackedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0) {
             return Relation.CELL_OUTSIDE_QUERY;
           }
-          boolean crosses = FutureArrays.compareUnsigned(minPackedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0 ||
-              FutureArrays.compareUnsigned(maxPackedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0;
+          boolean crosses = Arrays.compareUnsigned(minPackedValue, 0, LatLonPoint.BYTES, minLat, 0, LatLonPoint.BYTES) < 0 ||
+              Arrays.compareUnsigned(maxPackedValue, 0, LatLonPoint.BYTES, maxLat, 0, LatLonPoint.BYTES) > 0;
 
           if (crossDateLine) {
-            if (FutureArrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 &&
-                FutureArrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
+            if (Arrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 &&
+                Arrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
               return Relation.CELL_OUTSIDE_QUERY;
             }
-            crosses |= FutureArrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) < 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) > 0;
+            crosses |= Arrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) < 0 ||
+                Arrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) > 0;
 
           } else {
-            if (FutureArrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
+            if (Arrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0 ||
+                Arrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0) {
               return Relation.CELL_OUTSIDE_QUERY;
             }
-            crosses |= FutureArrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0;
+            crosses |= Arrays.compareUnsigned(minPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, minLon, 0, LatLonPoint.BYTES) < 0 ||
+                Arrays.compareUnsigned(maxPackedValue, LatLonPoint.BYTES, 2 * LatLonPoint.BYTES, maxLon, 0, LatLonPoint.BYTES) > 0;
           }
           if (crosses) {
             return Relation.CELL_CROSSES_QUERY;
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
index 969a133..750124a 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointDistanceQuery.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.document;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import org.apache.lucene.geo.GeoEncodingUtils;
 import org.apache.lucene.geo.GeoUtils;
@@ -40,7 +41,6 @@ import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.BitSetIterator;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.NumericUtils;
 
 import static org.apache.lucene.geo.GeoEncodingUtils.decodeLatitude;
@@ -207,15 +207,15 @@ final class LatLonPointDistanceQuery extends Query {
           @Override
           public void visit(int docID, byte[] packedValue) {
             // bounding box check
-            if (FutureArrays.compareUnsigned(packedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(packedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
+            if (Arrays.compareUnsigned(packedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(packedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
               // latitude out of bounding box range
               return;
             }
 
-            if ((FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
-                && FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
+            if ((Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
+                && Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
               // longitude out of bounding box range
               return;
             }
@@ -234,15 +234,15 @@ final class LatLonPointDistanceQuery extends Query {
           // 4. recurse naively (subtrees crossing over circle edge)
           @Override
           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-            if (FutureArrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
+            if (Arrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
               // latitude out of bounding box range
               return Relation.CELL_OUTSIDE_QUERY;
             }
 
-            if ((FutureArrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
-                && FutureArrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
+            if ((Arrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
+                && Arrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
               // longitude out of bounding box range
               return Relation.CELL_OUTSIDE_QUERY;
             }
@@ -272,17 +272,17 @@ final class LatLonPointDistanceQuery extends Query {
           @Override
           public void visit(int docID, byte[] packedValue) {
             // bounding box check
-            if (FutureArrays.compareUnsigned(packedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(packedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
+            if (Arrays.compareUnsigned(packedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(packedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
               // latitude out of bounding box range
               result.clear(docID);
               cost[0]--;
               return;
             }
 
-            if ((FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
-                && FutureArrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
+            if ((Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
+                && Arrays.compareUnsigned(packedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
               // longitude out of bounding box range
               result.clear(docID);
               cost[0]--;
@@ -299,15 +299,15 @@ final class LatLonPointDistanceQuery extends Query {
 
           @Override
           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-            if (FutureArrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
+            if (Arrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0) {
               // latitude out of bounding box range
               return Relation.CELL_INSIDE_QUERY;
             }
 
-            if ((FutureArrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
-                FutureArrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
-                && FutureArrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
+            if ((Arrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
+                Arrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0)
+                && Arrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon2, 0, Integer.BYTES) < 0) {
               // latitude out of bounding box range
               return Relation.CELL_INSIDE_QUERY;
             }
diff --git a/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java b/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
index e425d16..6907b1d 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LatLonPointInPolygonQuery.java
@@ -38,7 +38,6 @@ import org.apache.lucene.search.ScoreMode;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.NumericUtils;
 
 import static org.apache.lucene.geo.GeoEncodingUtils.decodeLatitude;
@@ -149,10 +148,10 @@ final class LatLonPointInPolygonQuery extends Query {
 
                            @Override
                            public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-                             if (FutureArrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
-                                 FutureArrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0 ||
-                                 FutureArrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
-                                 FutureArrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0) {
+                             if (Arrays.compareUnsigned(minPackedValue, 0, Integer.BYTES, maxLat, 0, Integer.BYTES) > 0 ||
+                                 Arrays.compareUnsigned(maxPackedValue, 0, Integer.BYTES, minLat, 0, Integer.BYTES) < 0 ||
+                                 Arrays.compareUnsigned(minPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, maxLon, 0, Integer.BYTES) > 0 ||
+                                 Arrays.compareUnsigned(maxPackedValue, Integer.BYTES, Integer.BYTES + Integer.BYTES, minLon, 0, Integer.BYTES) < 0) {
                                // outside of global bounding box range
                                return Relation.CELL_OUTSIDE_QUERY;
                              }
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
index a2b793b..0b4c365 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongDistanceFeatureQuery.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.document;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Objects;
 
 import org.apache.lucene.index.DocValues;
@@ -36,7 +37,6 @@ import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.ScorerSupplier;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.FutureArrays;
 
 final class LongDistanceFeatureQuery extends Query {
 
@@ -396,11 +396,11 @@ final class LongDistanceFeatureQuery extends Query {
             // Already visited or skipped
             return;
           }
-          if (FutureArrays.compareUnsigned(packedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
+          if (Arrays.compareUnsigned(packedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
             // Doc's value is too low, in this dimension
             return;
           }
-          if (FutureArrays.compareUnsigned(packedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
+          if (Arrays.compareUnsigned(packedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
             // Doc's value is too high, in this dimension
             return;
           }
@@ -411,13 +411,13 @@ final class LongDistanceFeatureQuery extends Query {
 
         @Override
         public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-          if (FutureArrays.compareUnsigned(minPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0 ||
-              FutureArrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
+          if (Arrays.compareUnsigned(minPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0 ||
+              Arrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0) {
             return Relation.CELL_OUTSIDE_QUERY;
           }
 
-          if (FutureArrays.compareUnsigned(minPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0 ||
-              FutureArrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
+          if (Arrays.compareUnsigned(minPackedValue, 0, Long.BYTES, minValueAsBytes, 0, Long.BYTES) < 0 ||
+              Arrays.compareUnsigned(maxPackedValue, 0, Long.BYTES, maxValueAsBytes, 0, Long.BYTES) > 0) {
             return Relation.CELL_CROSSES_QUERY;
           }
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/LongRange.java b/lucene/core/src/java/org/apache/lucene/document/LongRange.java
index 9056d2d..642f562 100644
--- a/lucene/core/src/java/org/apache/lucene/document/LongRange.java
+++ b/lucene/core/src/java/org/apache/lucene/document/LongRange.java
@@ -16,10 +16,11 @@
  */
 package org.apache.lucene.document;
 
+import java.util.Objects;
+
 import org.apache.lucene.document.RangeFieldQuery.QueryType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.NumericUtils;
 
 /**
@@ -146,7 +147,7 @@ public class LongRange extends Field {
    * @return the decoded min value
    */
   public long getMin(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMin(((BytesRef)fieldsData).bytes, dimension);
   }
 
@@ -156,7 +157,7 @@ public class LongRange extends Field {
    * @return the decoded max value
    */
   public long getMax(int dimension) {
-    FutureObjects.checkIndex(dimension, type.pointDataDimensionCount()/2);
+    Objects.checkIndex(dimension, type.pointDataDimensionCount()/2);
     return decodeMax(((BytesRef)fieldsData).bytes, dimension);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java b/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
index ac21a43..37f30ed 100644
--- a/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/document/RangeFieldQuery.java
@@ -37,7 +37,6 @@ import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.ScorerSupplier;
 import org.apache.lucene.search.Weight;
 import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.FutureArrays;
 
 /**
  * Query class for searching {@code RangeField} types by a defined {@link Relation}.
@@ -68,14 +67,14 @@ abstract class RangeFieldQuery extends Query {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) < 0
-            || FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) < 0
+            || Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) > 0) {
           // disjoint
           return Relation.CELL_OUTSIDE_QUERY;
         }
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) >= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) <= 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) >= 0
+            && Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) <= 0) {
           return Relation.CELL_INSIDE_QUERY;
         }
 
@@ -86,8 +85,8 @@ abstract class RangeFieldQuery extends Query {
       boolean matches(byte[] queryPackedValue, byte[] packedValue, int numDims, int bytesPerDim, int dim) {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
-        return FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) >= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) <= 0;
+        return Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) >= 0
+            && Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) <= 0;
       }
 
     },
@@ -100,14 +99,14 @@ abstract class RangeFieldQuery extends Query {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) < 0
-            || FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) < 0
+            || Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) > 0) {
           // all ranges have at least one point outside of the query
           return Relation.CELL_OUTSIDE_QUERY;
         }
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) >= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) <= 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) >= 0
+            && Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) <= 0) {
           return Relation.CELL_INSIDE_QUERY;
         }
 
@@ -118,8 +117,8 @@ abstract class RangeFieldQuery extends Query {
       boolean matches(byte[] queryPackedValue, byte[] packedValue, int numDims, int bytesPerDim, int dim) {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
-        return FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) <= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) >= 0;
+        return Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) <= 0
+            && Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) >= 0;
       }
 
     },
@@ -132,14 +131,14 @@ abstract class RangeFieldQuery extends Query {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) > 0
-            || FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, maxPackedValue, maxOffset, maxOffset + bytesPerDim) > 0
+            || Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, minPackedValue, minOffset, minOffset + bytesPerDim) < 0) {
           // all ranges are either less than the query max or greater than the query min
           return Relation.CELL_OUTSIDE_QUERY;
         }
 
-        if (FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) <= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) >= 0) {
+        if (Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, minPackedValue, maxOffset, maxOffset + bytesPerDim) <= 0
+            && Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, maxPackedValue, minOffset, minOffset + bytesPerDim) >= 0) {
           return Relation.CELL_INSIDE_QUERY;
         }
 
@@ -150,8 +149,8 @@ abstract class RangeFieldQuery extends Query {
       boolean matches(byte[] queryPackedValue, byte[] packedValue, int numDims, int bytesPerDim, int dim) {
         int minOffset = dim * bytesPerDim;
         int maxOffset = minOffset + bytesPerDim * numDims;
-        return FutureArrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) >= 0
-            && FutureArrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) <= 0;
+        return Arrays.compareUnsigned(queryPackedValue, minOffset, minOffset + bytesPerDim, packedValue, minOffset, minOffset + bytesPerDim) >= 0
+            && Arrays.compareUnsigned(queryPackedValue, maxOffset, maxOffset + bytesPerDim, packedValue, maxOffset, maxOffset + bytesPerDim) <= 0;
       }
 
     },
diff --git a/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java b/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
index 19bf9c1..800f20f 100644
--- a/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
+++ b/lucene/core/src/java/org/apache/lucene/index/BitsSlice.java
@@ -16,8 +16,9 @@
  */
 package org.apache.lucene.index;
 
+import java.util.Objects;
+
 import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.FutureObjects;
 
 
 /**
@@ -40,7 +41,7 @@ final class BitsSlice implements Bits {
     
   @Override
   public boolean get(int doc) {
-    FutureObjects.checkIndex(doc, length);
+    Objects.checkIndex(doc, length);
     return parent.get(doc+start);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
index fcda464..9fc612b 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CheckIndex.java
@@ -59,7 +59,6 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.CommandLineUtil;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LongBitSet;
 import org.apache.lucene.util.StringHelper;
@@ -2041,12 +2040,12 @@ public final class CheckIndex implements Closeable {
         int offset = bytesPerDim * dim;
 
         // Compare to last cell:
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lastMinPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lastMinPackedValue, offset, offset + bytesPerDim) < 0) {
           // This doc's point, in this dimension, is lower than the minimum value of the last cell checked:
           throw new RuntimeException("packed points value " + Arrays.toString(packedValue) + " for field=\"" + fieldName + "\", docID=" + docID + " is out-of-bounds of the last cell min=" + Arrays.toString(lastMinPackedValue) + " max=" + Arrays.toString(lastMaxPackedValue) + " dim=" + dim);
         }
 
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lastMaxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lastMaxPackedValue, offset, offset + bytesPerDim) > 0) {
           // This doc's point, in this dimension, is greater than the maximum value of the last cell checked:
           throw new RuntimeException("packed points value " + Arrays.toString(packedValue) + " for field=\"" + fieldName + "\", docID=" + docID + " is out-of-bounds of the last cell min=" + Arrays.toString(lastMinPackedValue) + " max=" + Arrays.toString(lastMaxPackedValue) + " dim=" + dim);
         }
@@ -2056,7 +2055,7 @@ public final class CheckIndex implements Closeable {
       // increasing docID:
       // for data dimension > 1, leaves are sorted by the dimension with the lowest cardinality to improve block compression
       if (numDataDims == 1) {
-        int cmp = FutureArrays.compareUnsigned(lastPackedValue, 0, bytesPerDim, packedValue, 0, bytesPerDim);
+        int cmp = Arrays.compareUnsigned(lastPackedValue, 0, bytesPerDim, packedValue, 0, bytesPerDim);
         if (cmp > 0) {
           throw new RuntimeException("packed points value " + Arrays.toString(packedValue) + " for field=\"" + fieldName + "\", for docID=" + docID + " is out-of-order vs the previous document's value " + Arrays.toString(lastPackedValue));
         } else if (cmp == 0) {
@@ -2079,27 +2078,27 @@ public final class CheckIndex implements Closeable {
       for(int dim=0;dim<numIndexDims;dim++) {
         int offset = bytesPerDim * dim;
 
-        if (FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           throw new RuntimeException("packed points cell minPackedValue " + Arrays.toString(minPackedValue) +
                                      " is out-of-bounds of the cell's maxPackedValue " + Arrays.toString(maxPackedValue) + " dim=" + dim + " field=\"" + fieldName + "\"");
         }
 
         // Make sure this cell is not outside of the global min/max:
-        if (FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, globalMinPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, globalMinPackedValue, offset, offset + bytesPerDim) < 0) {
           throw new RuntimeException("packed points cell minPackedValue " + Arrays.toString(minPackedValue) +
                                      " is out-of-bounds of the global minimum " + Arrays.toString(globalMinPackedValue) + " dim=" + dim + " field=\"" + fieldName + "\"");
         }
 
-        if (FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, globalMinPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, globalMinPackedValue, offset, offset + bytesPerDim) < 0) {
           throw new RuntimeException("packed points cell maxPackedValue " + Arrays.toString(maxPackedValue) +
                                      " is out-of-bounds of the global minimum " + Arrays.toString(globalMinPackedValue) + " dim=" + dim + " field=\"" + fieldName + "\"");
         }
 
-        if (FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, globalMaxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, globalMaxPackedValue, offset, offset + bytesPerDim) > 0) {
           throw new RuntimeException("packed points cell minPackedValue " + Arrays.toString(minPackedValue) +
                                      " is out-of-bounds of the global maximum " + Arrays.toString(globalMaxPackedValue) + " dim=" + dim + " field=\"" + fieldName + "\"");
         }
-        if (FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, globalMaxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, globalMaxPackedValue, offset, offset + bytesPerDim) > 0) {
           throw new RuntimeException("packed points cell maxPackedValue " + Arrays.toString(maxPackedValue) +
                                      " is out-of-bounds of the global maximum " + Arrays.toString(globalMaxPackedValue) + " dim=" + dim + " field=\"" + fieldName + "\"");
         }
diff --git a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
index ca6ac7d..af90c7b 100644
--- a/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
+++ b/lucene/core/src/java/org/apache/lucene/index/CodecReader.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 
 import org.apache.lucene.codecs.DocValuesProducer;
 import org.apache.lucene.codecs.FieldsProducer;
@@ -31,7 +32,6 @@ import org.apache.lucene.codecs.StoredFieldsReader;
 import org.apache.lucene.codecs.TermVectorsReader;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.Accountables;
-import org.apache.lucene.util.FutureObjects;
 
 /**
  * LeafReader implemented by codec APIs.
@@ -95,7 +95,7 @@ public abstract class CodecReader extends LeafReader implements Accountable {
   }
   
   private void checkBounds(int docID) {
-    FutureObjects.checkIndex(docID, maxDoc());
+    Objects.checkIndex(docID, maxDoc());
   }
 
   @Override
diff --git a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
index 1f35e45..afa2612 100644
--- a/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
+++ b/lucene/core/src/java/org/apache/lucene/index/MergeReaderWrapper.java
@@ -18,6 +18,7 @@
 package org.apache.lucene.index;
 
 import java.io.IOException;
+import java.util.Objects;
 
 import org.apache.lucene.codecs.DocValuesProducer;
 import org.apache.lucene.codecs.FieldsProducer;
@@ -25,7 +26,6 @@ import org.apache.lucene.codecs.NormsProducer;
 import org.apache.lucene.codecs.StoredFieldsReader;
 import org.apache.lucene.codecs.TermVectorsReader;
 import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.FutureObjects;
 
 /** This is a hack to make index sorting fast, with a {@link LeafReader} that always returns merge instances when you ask for the codec readers. */
 class MergeReaderWrapper extends LeafReader {
@@ -227,7 +227,7 @@ class MergeReaderWrapper extends LeafReader {
   }
 
   private void checkBounds(int docID) {
-    FutureObjects.checkIndex(docID, maxDoc());
+    Objects.checkIndex(docID, maxDoc());
   }
 
   @Override
diff --git a/lucene/core/src/java/org/apache/lucene/index/PointValues.java b/lucene/core/src/java/org/apache/lucene/index/PointValues.java
index 51b12d1..8690cce 100644
--- a/lucene/core/src/java/org/apache/lucene/index/PointValues.java
+++ b/lucene/core/src/java/org/apache/lucene/index/PointValues.java
@@ -19,6 +19,7 @@ package org.apache.lucene.index;
 import java.io.IOException;
 import java.math.BigInteger;
 import java.net.InetAddress;
+import java.util.Arrays;
 
 import org.apache.lucene.document.BinaryPoint;
 import org.apache.lucene.document.DoublePoint;
@@ -28,7 +29,6 @@ import org.apache.lucene.document.IntPoint;
 import org.apache.lucene.document.LatLonPoint;
 import org.apache.lucene.document.LongPoint;
 import org.apache.lucene.search.DocIdSetIterator;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.bkd.BKDWriter;
 
 /** 
@@ -140,7 +140,7 @@ public abstract class PointValues {
         final int numBytesPerDimension = values.getBytesPerDimension();
         for (int i = 0; i < numDimensions; ++i) {
           int offset = i * numBytesPerDimension;
-          if (FutureArrays.compareUnsigned(leafMinValue, offset, offset + numBytesPerDimension, minValue, offset, offset + numBytesPerDimension) < 0) {
+          if (Arrays.compareUnsigned(leafMinValue, offset, offset + numBytesPerDimension, minValue, offset, offset + numBytesPerDimension) < 0) {
             System.arraycopy(leafMinValue, offset, minValue, offset, numBytesPerDimension);
           }
         }
@@ -171,7 +171,7 @@ public abstract class PointValues {
         final int numBytesPerDimension = values.getBytesPerDimension();
         for (int i = 0; i < numDimensions; ++i) {
           int offset = i * numBytesPerDimension;
-          if (FutureArrays.compareUnsigned(leafMaxValue, offset, offset + numBytesPerDimension, maxValue, offset, offset + numBytesPerDimension) > 0) {
+          if (Arrays.compareUnsigned(leafMaxValue, offset, offset + numBytesPerDimension, maxValue, offset, offset + numBytesPerDimension) > 0) {
             System.arraycopy(leafMaxValue, offset, maxValue, offset, numBytesPerDimension);
           }
         }
diff --git a/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java b/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
index 6820561..e687091 100644
--- a/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
+++ b/lucene/core/src/java/org/apache/lucene/index/PrefixCodedTerms.java
@@ -149,11 +149,17 @@ public class PrefixCodedTerms implements Accountable {
       builder.setLength(prefix + suffix);
     }
 
+    // Copied from parent-class because javadoc doesn't do it for some reason
+    /** Returns current field.  This method should not be called
+     *  after iteration is done.  Note that you may use == to
+     *  detect a change in field. */
     @Override
     public String field() {
       return field;
     }
 
+    // Copied from parent-class because javadoc doesn't do it for some reason
+    /** Del gen of the current term. */
     @Override
     public long delGen() {
       return delGen;
diff --git a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
index 6ec17ba..e1b0399 100644
--- a/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
+++ b/lucene/core/src/java/org/apache/lucene/search/BooleanScorer.java
@@ -20,9 +20,9 @@ package org.apache.lucene.search;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Objects;
 
 import org.apache.lucene.util.Bits;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.PriorityQueue;
 
 /**
@@ -106,7 +106,7 @@ final class BooleanScorer extends BulkScorer {
     }
 
     public BulkScorerAndDoc get(int i) {
-      FutureObjects.checkIndex(i, size());
+      Objects.checkIndex(i, size());
       return (BulkScorerAndDoc) getHeapArray()[1 + i];
     }
 
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
index ad9e258..1bb5e43 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointInSetQuery.java
@@ -35,7 +35,6 @@ import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.BytesRefIterator;
 import org.apache.lucene.util.DocIdSetBuilder;
-import org.apache.lucene.util.FutureArrays;
 
 /**
  * Abstract query class to find all documents whose single or multi-dimensional point values, previously indexed with e.g. {@link IntPoint},
@@ -291,12 +290,12 @@ public abstract class PointInSetQuery extends Query {
       for(int dim=0;dim<numDims;dim++) {
         int offset = dim*bytesPerDim;
 
-        int cmpMin = FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
+        int cmpMin = Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
         if (cmpMin > 0) {
           return Relation.CELL_OUTSIDE_QUERY;
         }
 
-        int cmpMax = FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
+        int cmpMax = Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
         if (cmpMax < 0) {
           return Relation.CELL_OUTSIDE_QUERY;
         }
diff --git a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
index 57c8708..c51b255 100644
--- a/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
+++ b/lucene/core/src/java/org/apache/lucene/search/PointRangeQuery.java
@@ -30,7 +30,6 @@ import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BitSetIterator;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 
 /** 
  * Abstract class for range queries against single or multidimensional points such as
@@ -133,11 +132,11 @@ public abstract class PointRangeQuery extends Query {
           public void visit(int docID, byte[] packedValue) {
             for(int dim=0;dim<numDims;dim++) {
               int offset = dim*bytesPerDim;
-              if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
+              if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
                 // Doc's value is too low, in this dimension
                 return;
               }
-              if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0) {
+              if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0) {
                 // Doc's value is too high, in this dimension
                 return;
               }
@@ -155,13 +154,13 @@ public abstract class PointRangeQuery extends Query {
             for(int dim=0;dim<numDims;dim++) {
               int offset = dim*bytesPerDim;
 
-              if (FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0 ||
-                  FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
+              if (Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0 ||
+                  Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
                 return Relation.CELL_OUTSIDE_QUERY;
               }
 
-              crosses |= FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0 ||
-                  FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0;
+              crosses |= Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0 ||
+                  Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0;
             }
 
             if (crosses) {
@@ -189,13 +188,13 @@ public abstract class PointRangeQuery extends Query {
           public void visit(int docID, byte[] packedValue) {
             for(int dim=0;dim<numDims;dim++) {
               int offset = dim*bytesPerDim;
-              if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
+              if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
                 // Doc's value is too low, in this dimension
                 result.clear(docID);
                 cost[0]--;
                 return;
               }
-              if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0) {
+              if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0) {
                 // Doc's value is too high, in this dimension
                 result.clear(docID);
                 cost[0]--;
@@ -212,14 +211,14 @@ public abstract class PointRangeQuery extends Query {
             for(int dim=0;dim<numDims;dim++) {
               int offset = dim*bytesPerDim;
 
-              if (FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0 ||
-                  FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
+              if (Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0 ||
+                  Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0) {
                 // This dim is not in the range
                 return Relation.CELL_INSIDE_QUERY;
               }
 
-              crosses |= FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0 ||
-                  FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0;
+              crosses |= Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, lowerPoint, offset, offset + bytesPerDim) < 0 ||
+                  Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, upperPoint, offset, offset + bytesPerDim) > 0;
             }
 
             if (crosses) {
@@ -255,8 +254,8 @@ public abstract class PointRangeQuery extends Query {
           allDocsMatch = true;
           for (int i = 0; i < numDims; ++i) {
             int offset = i * bytesPerDim;
-            if (FutureArrays.compareUnsigned(lowerPoint, offset, offset + bytesPerDim, fieldPackedLower, offset, offset + bytesPerDim) > 0
-                || FutureArrays.compareUnsigned(upperPoint, offset, offset + bytesPerDim, fieldPackedUpper, offset, offset + bytesPerDim) < 0) {
+            if (Arrays.compareUnsigned(lowerPoint, offset, offset + bytesPerDim, fieldPackedLower, offset, offset + bytesPerDim) > 0
+                || Arrays.compareUnsigned(upperPoint, offset, offset + bytesPerDim, fieldPackedUpper, offset, offset + bytesPerDim) < 0) {
               allDocsMatch = false;
               break;
             }
diff --git a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
index 5981659..8ba42ab 100644
--- a/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
+++ b/lucene/core/src/java/org/apache/lucene/search/TopFieldCollector.java
@@ -21,12 +21,12 @@ import java.io.IOException;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 
 import org.apache.lucene.index.LeafReaderContext;
 import org.apache.lucene.index.ReaderUtil;
 import org.apache.lucene.search.FieldValueHitQueue.Entry;
 import org.apache.lucene.search.TotalHits.Relation;
-import org.apache.lucene.util.FutureObjects;
 
 /**
  * A {@link Collector} that sorts by {@link SortField} using
@@ -434,7 +434,7 @@ public abstract class TopFieldCollector extends TopDocsCollector<Entry> {
     Scorer currentScorer = null;
     for (ScoreDoc scoreDoc : topDocs) {
       if (currentContext == null || scoreDoc.doc >= currentContext.docBase + currentContext.reader().maxDoc()) {
-        FutureObjects.checkIndex(scoreDoc.doc, searcher.getIndexReader().maxDoc());
+        Objects.checkIndex(scoreDoc.doc, searcher.getIndexReader().maxDoc());
         int newContextIndex = ReaderUtil.subIndex(scoreDoc.doc, contexts);
         currentContext = contexts.get(newContextIndex);
         final ScorerSupplier scorerSupplier = weight.scorerSupplier(currentContext);
diff --git a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
index 9bdddd8..e2bb097 100644
--- a/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
+++ b/lucene/core/src/java/org/apache/lucene/store/ByteBuffersDataOutput.java
@@ -206,7 +206,7 @@ public final class ByteBuffersDataOutput extends DataOutput implements Accountab
       result.add(EMPTY);
     } else {
       for (ByteBuffer bb : blocks) {
-        bb = (ByteBuffer) bb.asReadOnlyBuffer().flip(); // cast for jdk8 (covariant in jdk9+) 
+        bb = bb.asReadOnlyBuffer().flip();
         result.add(bb);
       }
     }
@@ -231,7 +231,7 @@ public final class ByteBuffersDataOutput extends DataOutput implements Accountab
       result.add(EMPTY);
     } else {
       for (ByteBuffer bb : blocks) {
-        bb = (ByteBuffer) bb.duplicate().flip(); // cast for jdk8 (covariant in jdk9+) 
+        bb = bb.duplicate().flip();
         result.add(bb);
       }
     }
diff --git a/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java b/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
index 2008f91..8d8c042 100644
--- a/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
+++ b/lucene/core/src/java/org/apache/lucene/store/LockStressTest.java
@@ -139,7 +139,7 @@ public class LockStressTest {
     
     // try to create a new instance
     try {
-      return Class.forName(lockFactoryClassName).asSubclass(FSLockFactory.class).newInstance();
+      return Class.forName(lockFactoryClassName).asSubclass(FSLockFactory.class).getConstructor().newInstance();
     } catch (ReflectiveOperationException | ClassCastException e) {
       // fall-through
     }
diff --git a/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java b/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
index b994d0d..416e395 100644
--- a/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
+++ b/lucene/core/src/java/org/apache/lucene/store/MMapDirectory.java
@@ -35,7 +35,6 @@ import java.util.Objects;
 import java.util.concurrent.Future;
 import java.lang.invoke.MethodHandle;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 
 import org.apache.lucene.store.ByteBufferGuard.BufferCleaner;
 import org.apache.lucene.util.Constants;
@@ -339,48 +338,17 @@ public class MMapDirectory extends FSDirectory {
   private static Object unmapHackImpl() {
     final Lookup lookup = lookup();
     try {
-      try {
-        // *** sun.misc.Unsafe unmapping (Java 9+) ***
-        final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
-        // first check if Unsafe has the right method, otherwise we can give up
-        // without doing any security critical stuff:
-        final MethodHandle unmapper = lookup.findVirtual(unsafeClass, "invokeCleaner",
-            methodType(void.class, ByteBuffer.class));
-        // fetch the unsafe instance and bind it to the virtual MH:
-        final Field f = unsafeClass.getDeclaredField("theUnsafe");
-        f.setAccessible(true);
-        final Object theUnsafe = f.get(null);
-        return newBufferCleaner(ByteBuffer.class, unmapper.bindTo(theUnsafe));
-      } catch (SecurityException se) {
-        // rethrow to report errors correctly (we need to catch it here, as we also catch RuntimeException below!):
-        throw se;
-      } catch (ReflectiveOperationException | RuntimeException e) {
-        // *** sun.misc.Cleaner unmapping (Java 8) ***
-        final Class<?> directBufferClass = Class.forName("java.nio.DirectByteBuffer");
-        
-        final Method m = directBufferClass.getMethod("cleaner");
-        m.setAccessible(true);
-        final MethodHandle directBufferCleanerMethod = lookup.unreflect(m);
-        final Class<?> cleanerClass = directBufferCleanerMethod.type().returnType();
-        
-        /* "Compile" a MH that basically is equivalent to the following code:
-         * void unmapper(ByteBuffer byteBuffer) {
-         *   sun.misc.Cleaner cleaner = ((java.nio.DirectByteBuffer) byteBuffer).cleaner();
-         *   if (Objects.nonNull(cleaner)) {
-         *     cleaner.clean();
-         *   } else {
-         *     noop(cleaner); // the noop is needed because MethodHandles#guardWithTest always needs ELSE
-         *   }
-         * }
-         */
-        final MethodHandle cleanMethod = lookup.findVirtual(cleanerClass, "clean", methodType(void.class));
-        final MethodHandle nonNullTest = lookup.findStatic(Objects.class, "nonNull", methodType(boolean.class, Object.class))
-            .asType(methodType(boolean.class, cleanerClass));
-        final MethodHandle noop = dropArguments(constant(Void.class, null).asType(methodType(void.class)), 0, cleanerClass);
-        final MethodHandle unmapper = filterReturnValue(directBufferCleanerMethod, guardWithTest(nonNullTest, cleanMethod, noop))
-            .asType(methodType(void.class, ByteBuffer.class));
-        return newBufferCleaner(directBufferClass, unmapper);
-      }
+      // *** sun.misc.Unsafe unmapping (Java 9+) ***
+      final Class<?> unsafeClass = Class.forName("sun.misc.Unsafe");
+      // first check if Unsafe has the right method, otherwise we can give up
+      // without doing any security critical stuff:
+      final MethodHandle unmapper = lookup.findVirtual(unsafeClass, "invokeCleaner",
+          methodType(void.class, ByteBuffer.class));
+      // fetch the unsafe instance and bind it to the virtual MH:
+      final Field f = unsafeClass.getDeclaredField("theUnsafe");
+      f.setAccessible(true);
+      final Object theUnsafe = f.get(null);
+      return newBufferCleaner(ByteBuffer.class, unmapper.bindTo(theUnsafe));
     } catch (SecurityException se) {
       return "Unmapping is not supported, because not all required permissions are given to the Lucene JAR file: " + se +
           " [Please grant at least the following permissions: RuntimePermission(\"accessClassInPackage.sun.misc\") " +
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRef.java b/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
index a9a05e6..eb42b15 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRef.java
@@ -16,6 +16,8 @@
  */
 package org.apache.lucene.util;
 
+import java.util.Arrays;
+
 /** Represents byte[], as a slice (offset + length) into an
  *  existing byte[].  The {@link #bytes} member should never be null;
  *  use {@link #EMPTY_BYTES} if necessary.
@@ -93,7 +95,7 @@ public final class BytesRef implements Comparable<BytesRef>,Cloneable {
    * @lucene.internal
    */
   public boolean bytesEquals(BytesRef other) {
-    return FutureArrays.equals(this.bytes, this.offset, this.offset + this.length, 
+    return Arrays.equals(this.bytes, this.offset, this.offset + this.length, 
                                other.bytes, other.offset, other.offset + other.length);
   }
 
@@ -157,7 +159,7 @@ public final class BytesRef implements Comparable<BytesRef>,Cloneable {
   /** Unsigned byte order comparison */
   @Override
   public int compareTo(BytesRef other) {
-    return FutureArrays.compareUnsigned(this.bytes, this.offset, this.offset + this.length, 
+    return Arrays.compareUnsigned(this.bytes, this.offset, this.offset + this.length, 
                                         other.bytes, other.offset, other.offset + other.length);
   }
     
diff --git a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
index f169d1a..cb0b3e3 100644
--- a/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
+++ b/lucene/core/src/java/org/apache/lucene/util/BytesRefArray.java
@@ -18,6 +18,7 @@ package org.apache.lucene.util;
 
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Objects;
 
 /**
  * A simple append only random-access {@link BytesRef} array that stores full
@@ -93,7 +94,7 @@ public final class BytesRefArray implements SortableBytesRefArray {
    * @return the <i>n'th</i> element of this {@link BytesRefArray}
    */
   public BytesRef get(BytesRefBuilder spare, int index) {
-    FutureObjects.checkIndex(index, lastElement);
+    Objects.checkIndex(index, lastElement);
     int offset = offsets[index];
     int length = index == lastElement - 1 ? currentOffset - offset
         : offsets[index + 1] - offset;
@@ -106,7 +107,7 @@ public final class BytesRefArray implements SortableBytesRefArray {
   /** Used only by sort below, to set a {@link BytesRef} with the specified slice, avoiding copying bytes in the common case when the slice
    *  is contained in a single block in the byte block pool. */
   private void setBytesRef(BytesRefBuilder spare, BytesRef result, int index) {
-    FutureObjects.checkIndex(index, lastElement);
+    Objects.checkIndex(index, lastElement);
     int offset = offsets[index];
     int length;
     if (index == lastElement - 1) {
diff --git a/lucene/core/src/java/org/apache/lucene/util/CharsRef.java b/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
index 7cb8ce9..80be7cc 100644
--- a/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/CharsRef.java
@@ -17,7 +17,9 @@
 package org.apache.lucene.util;
 
 
+import java.util.Arrays;
 import java.util.Comparator;
+import java.util.Objects;
 
 /**
  * Represents char[], as a slice (offset + length) into an existing char[].
@@ -106,14 +108,14 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
   }
 
   public boolean charsEquals(CharsRef other) {
-    return FutureArrays.equals(this.chars, this.offset, this.offset + this.length, 
+    return Arrays.equals(this.chars, this.offset, this.offset + this.length, 
                                other.chars, other.offset, other.offset + other.length);
   }
 
   /** Signed int order comparison */
   @Override
   public int compareTo(CharsRef other) {
-    return FutureArrays.compare(this.chars, this.offset, this.offset + this.length, 
+    return Arrays.compare(this.chars, this.offset, this.offset + this.length, 
                                 other.chars, other.offset, other.offset + other.length);
   }
 
@@ -130,14 +132,14 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
   @Override
   public char charAt(int index) {
     // NOTE: must do a real check here to meet the specs of CharSequence
-    FutureObjects.checkIndex(index, length);
+    Objects.checkIndex(index, length);
     return chars[offset + index];
   }
 
   @Override
   public CharSequence subSequence(int start, int end) {
     // NOTE: must do a real check here to meet the specs of CharSequence
-    FutureObjects.checkFromToIndex(start, end, length);
+    Objects.checkFromToIndex(start, end, length);
     return new CharsRef(chars, offset + start, end - start);
   }
   
@@ -161,7 +163,7 @@ public final class CharsRef implements Comparable<CharsRef>, CharSequence, Clone
     public int compare(CharsRef a, CharsRef b) {
       int aEnd = a.offset + a.length;
       int bEnd = b.offset + b.length;
-      int i = FutureArrays.mismatch(a.chars, a.offset, aEnd, 
+      int i = Arrays.mismatch(a.chars, a.offset, aEnd, 
                                     b.chars, b.offset, bEnd);
 
       if (i >= 0 && i < Math.min(a.length, b.length)) {
diff --git a/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java b/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java
deleted file mode 100644
index 0154053..0000000
--- a/lucene/core/src/java/org/apache/lucene/util/FutureArrays.java
+++ /dev/null
@@ -1,268 +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.lucene.util;
-
-/**
- * Additional methods from Java 9's <a href="https://docs.oracle.com/javase/9/docs/api/java/util/Arrays.html">
- * {@code java.util.Arrays}</a>.
- * <p>
- * This class will be removed when Java 9 is minimum requirement.
- * Currently any bytecode is patched to use the Java 9 native
- * classes through MR-JAR (Multi-Release JAR) mechanism.
- * In Java 8 it will use THIS implementation.
- * Because of patching, inside the Java source files we always
- * refer to the Lucene implementations, but the final Lucene
- * JAR files will use the native Java 9 class names when executed
- * with Java 9.
- * @lucene.internal
- */
-public final class FutureArrays {
-  
-  private FutureArrays() {} // no instance
-  
-  // methods in Arrays are defined stupid: they cannot use Objects.checkFromToIndex
-  // they throw IAE (vs IOOBE) in the case of fromIndex > toIndex.
-  // so this method works just like checkFromToIndex, but with that stupidity added.
-  private static void checkFromToIndex(int fromIndex, int toIndex, int length) {
-    if (fromIndex > toIndex) {
-      throw new IllegalArgumentException("fromIndex " + fromIndex + " > toIndex " + toIndex);
-    }
-    if (fromIndex < 0 || toIndex > length) {
-      throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + toIndex + ") out-of-bounds for length " + length);
-    }
-  }
-
-  // byte[]
-
-  /**
-   * Behaves like Java 9's Arrays.mismatch
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#mismatch-byte:A-int-int-byte:A-int-int-">Arrays.mismatch</a>
-   */
-  public static int mismatch(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++)
-      if (a[i+aFromIndex] != b[i+bFromIndex])
-        return i;
-    return aLen == bLen ? -1 : len;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.compareUnsigned
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compareUnsigned-byte:A-int-int-byte:A-int-int-">Arrays.compareUnsigned</a>
-   */
-  public static int compareUnsigned(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++) {
-      int aByte = a[i+aFromIndex] & 0xFF;
-      int bByte = b[i+bFromIndex] & 0xFF;
-      int diff = aByte - bByte;
-      if (diff != 0) {
-        return diff;
-      }
-    }
-
-    // One is a prefix of the other, or, they are equal:
-    return aLen - bLen;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.equals
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-byte:A-int-int-byte:A-int-int-">Arrays.equals</a>
-   */
-  public static boolean equals(byte[] a, int aFromIndex, int aToIndex, byte[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    // lengths differ: cannot be equal
-    if (aLen != bLen) {
-      return false;
-    }
-    for (int i = 0; i < aLen; i++) {
-      if (a[i+aFromIndex] != b[i+bFromIndex]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  // char[]
-
-  /**
-   * Behaves like Java 9's Arrays.mismatch
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#mismatch-char:A-int-int-char:A-int-int-">Arrays.mismatch</a>
-   */
-  public static int mismatch(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++)
-      if (a[i+aFromIndex] != b[i+bFromIndex])
-        return i;
-    return aLen == bLen ? -1 : len;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.compare
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-char:A-int-int-char:A-int-int-">Arrays.compare</a>
-   */
-  public static int compare(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++) {
-      int aInt = a[i+aFromIndex];
-      int bInt = b[i+bFromIndex];
-      if (aInt > bInt) {
-        return 1;
-      } else if (aInt < bInt) {
-        return -1;
-      }
-    }
-
-    // One is a prefix of the other, or, they are equal:
-    return aLen - bLen;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.equals
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-char:A-int-int-char:A-int-int-">Arrays.equals</a>
-   */
-  public static boolean equals(char[] a, int aFromIndex, int aToIndex, char[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    // lengths differ: cannot be equal
-    if (aLen != bLen) {
-      return false;
-    }
-    for (int i = 0; i < aLen; i++) {
-      if (a[i+aFromIndex] != b[i+bFromIndex]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  // int[]
-  
-  /**
-   * Behaves like Java 9's Arrays.compare
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-int:A-int-int-int:A-int-int-">Arrays.compare</a>
-   */
-  public static int compare(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++) {
-      int aInt = a[i+aFromIndex];
-      int bInt = b[i+bFromIndex];
-      if (aInt > bInt) {
-        return 1;
-      } else if (aInt < bInt) {
-        return -1;
-      }
-    }
-
-    // One is a prefix of the other, or, they are equal:
-    return aLen - bLen;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.equals
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-int:A-int-int-int:A-int-int-">Arrays.equals</a>
-   */
-  public static boolean equals(int[] a, int aFromIndex, int aToIndex, int[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    // lengths differ: cannot be equal
-    if (aLen != bLen) {
-      return false;
-    }
-    for (int i = 0; i < aLen; i++) {
-      if (a[i+aFromIndex] != b[i+bFromIndex]) {
-        return false;
-      }
-    }
-    return true;
-  }
-  
-  // long[]
-  
-  /**
-   * Behaves like Java 9's Arrays.compare
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#compare-long:A-int-int-long:A-int-int-">Arrays.compare</a>
-   */
-  public static int compare(long[] a, int aFromIndex, int aToIndex, long[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    int len = Math.min(aLen, bLen);
-    for (int i = 0; i < len; i++) {
-      long aInt = a[i+aFromIndex];
-      long bInt = b[i+bFromIndex];
-      if (aInt > bInt) {
-        return 1;
-      } else if (aInt < bInt) {
-        return -1;
-      }
-    }
-
-    // One is a prefix of the other, or, they are equal:
-    return aLen - bLen;
-  }
-  
-  /**
-   * Behaves like Java 9's Arrays.equals
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Arrays.html#equals-long:A-int-int-long:A-int-int-">Arrays.equals</a>
-   */
-  public static boolean equals(long[] a, int aFromIndex, int aToIndex, long[] b, int bFromIndex, int bToIndex) {
-    checkFromToIndex(aFromIndex, aToIndex, a.length);
-    checkFromToIndex(bFromIndex, bToIndex, b.length);
-    int aLen = aToIndex - aFromIndex;
-    int bLen = bToIndex - bFromIndex;
-    // lengths differ: cannot be equal
-    if (aLen != bLen) {
-      return false;
-    }
-    for (int i = 0; i < aLen; i++) {
-      if (a[i+aFromIndex] != b[i+bFromIndex]) {
-        return false;
-      }
-    }
-    return true;
-  }
-  
-}
diff --git a/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java b/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java
deleted file mode 100644
index b8ad4d3..0000000
--- a/lucene/core/src/java/org/apache/lucene/util/FutureObjects.java
+++ /dev/null
@@ -1,70 +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.lucene.util;
-
-/**
- * Additional methods from Java 9's <a href="https://docs.oracle.com/javase/9/docs/api/java/util/Objects.html">
- * {@code java.util.Objects}</a>.
- * <p>
- * This class will be removed when Java 9 is minimum requirement.
- * Currently any bytecode is patched to use the Java 9 native
- * classes through MR-JAR (Multi-Release JAR) mechanism.
- * In Java 8 it will use THIS implementation.
- * Because of patching, inside the Java source files we always
- * refer to the Lucene implementations, but the final Lucene
- * JAR files will use the native Java 9 class names when executed
- * with Java 9.
- * @lucene.internal
- */
-public final class FutureObjects {
-  
-  private FutureObjects() {} // no instance
-
-  /**
-   * Behaves like Java 9's Objects.checkIndex
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkIndex-int-int-">Objects.checkIndex</a>
-   */
-  public static int checkIndex(int index, int length) {
-    if (index < 0 || index >= length) {
-      throw new IndexOutOfBoundsException("Index " + index + " out-of-bounds for length " + length);
-    }
-    return index;
-  }
-  
-  /**
-   * Behaves like Java 9's Objects.checkFromToIndex
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkFromToIndex-int-int-int-">Objects.checkFromToIndex</a>
-   */
-  public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
-    if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
-      throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + toIndex + ") out-of-bounds for length " + length);
-    }
-    return fromIndex;
-  }
-  
-  /**
-   * Behaves like Java 9's Objects.checkFromIndexSize
-   * @see <a href="http://download.java.net/java/jdk9/docs/api/java/util/Objects.html#checkFromIndexSize-int-int-int-">Objects.checkFromIndexSize</a>
-   */
-  public static int checkFromIndexSize(int fromIndex, int size, int length) {
-    int end = fromIndex + size;
-    if (fromIndex < 0 || fromIndex > end || end > length) {
-      throw new IndexOutOfBoundsException("Range [" + fromIndex + ", " + fromIndex + " + " + size + ") out-of-bounds for length " + length);
-    }
-    return fromIndex;
-  }
-}
diff --git a/lucene/core/src/java/org/apache/lucene/util/IntsRef.java b/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
index 0c6cfa5..95cd999 100644
--- a/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/IntsRef.java
@@ -16,6 +16,7 @@
  */
 package org.apache.lucene.util;
 
+import java.util.Arrays;
 
 /** Represents int[], as a slice (offset + length) into an
  *  existing int[].  The {@link #ints} member should never be null; use
@@ -91,14 +92,14 @@ public final class IntsRef implements Comparable<IntsRef>, Cloneable {
   }
 
   public boolean intsEquals(IntsRef other) {
-    return FutureArrays.equals(this.ints, this.offset, this.offset + this.length, 
+    return Arrays.equals(this.ints, this.offset, this.offset + this.length, 
                                other.ints, other.offset, other.offset + other.length);
   }
 
   /** Signed int order comparison */
   @Override
   public int compareTo(IntsRef other) {
-    return FutureArrays.compare(this.ints, this.offset, this.offset + this.length, 
+    return Arrays.compare(this.ints, this.offset, this.offset + this.length, 
                                 other.ints, other.offset, other.offset + other.length);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/util/LongsRef.java b/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
index e4ca3ef..4a0deda 100644
--- a/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
+++ b/lucene/core/src/java/org/apache/lucene/util/LongsRef.java
@@ -16,6 +16,7 @@
  */
 package org.apache.lucene.util;
 
+import java.util.Arrays;
 
 /** Represents long[], as a slice (offset + length) into an
  *  existing long[].  The {@link #longs} member should never be null; use
@@ -90,14 +91,14 @@ public final class LongsRef implements Comparable<LongsRef>, Cloneable {
   }
 
   public boolean longsEquals(LongsRef other) {
-    return FutureArrays.equals(this.longs, this.offset, this.offset + this.length, 
+    return Arrays.equals(this.longs, this.offset, this.offset + this.length, 
                                other.longs, other.offset, other.offset + other.length);
   }
 
   /** Signed int order comparison */
   @Override
   public int compareTo(LongsRef other) {
-    return FutureArrays.compare(this.longs, this.offset, this.offset + this.length, 
+    return Arrays.compare(this.longs, this.offset, this.offset + this.length, 
                                 other.longs, other.offset, other.offset + other.length);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java b/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java
index 56ef574..c8d4002 100644
--- a/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java
+++ b/lucene/core/src/java/org/apache/lucene/util/NamedSPILoader.java
@@ -69,7 +69,7 @@ public final class NamedSPILoader<S extends NamedSPILoader.NamedSPI> implements
     while (loader.hasNext()) {
       final Class<? extends S> c = loader.next();
       try {
-        final S service = c.newInstance();
+        final S service = c.getConstructor().newInstance();
         final String name = service.getName();
         // only add the first one for each name, later services will be ignored
         // this allows to place services before others in classpath to make 
diff --git a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
index 130b0e0..2a36c39 100644
--- a/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
+++ b/lucene/core/src/java/org/apache/lucene/util/StringHelper.java
@@ -41,7 +41,7 @@ public abstract class StringHelper {
    * @return The number of common elements (from the start of each).
    */
   public static int bytesDifference(BytesRef priorTerm, BytesRef currentTerm) {
-    int mismatch = FutureArrays.mismatch(priorTerm.bytes, priorTerm.offset, priorTerm.offset + priorTerm.length, 
+    int mismatch = Arrays.mismatch(priorTerm.bytes, priorTerm.offset, priorTerm.offset + priorTerm.length, 
                                          currentTerm.bytes, currentTerm.offset, currentTerm.offset + currentTerm.length);
     if (mismatch < 0) {
       throw new IllegalArgumentException("terms out of order: priorTerm=" + priorTerm + ",currentTerm=" + currentTerm);
@@ -77,7 +77,7 @@ public abstract class StringHelper {
     if (ref.length < prefix.length) {
       return false;
     }
-    return FutureArrays.equals(ref, 0, prefix.length,
+    return Arrays.equals(ref, 0, prefix.length,
                                prefix.bytes, prefix.offset, prefix.offset + prefix.length);
   }
 
@@ -97,7 +97,7 @@ public abstract class StringHelper {
     if (ref.length < prefix.length) {
       return false;
     }
-    return FutureArrays.equals(ref.bytes, ref.offset, ref.offset + prefix.length, 
+    return Arrays.equals(ref.bytes, ref.offset, ref.offset + prefix.length, 
                                prefix.bytes, prefix.offset, prefix.offset + prefix.length);
   }
 
@@ -118,7 +118,7 @@ public abstract class StringHelper {
     if (startAt < 0) {
       return false;
     }
-    return FutureArrays.equals(ref.bytes, ref.offset + startAt, ref.offset + startAt + suffix.length,
+    return Arrays.equals(ref.bytes, ref.offset + startAt, ref.offset + startAt + suffix.length,
                                suffix.bytes, suffix.offset, suffix.offset + suffix.length);
   }
 
diff --git a/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java b/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
index 9ef31e8..807ef8f 100644
--- a/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
+++ b/lucene/core/src/java/org/apache/lucene/util/automaton/Automaton.java
@@ -23,11 +23,11 @@ package org.apache.lucene.util.automaton;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
 
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.ArrayUtil;
-import org.apache.lucene.util.FutureObjects;
 import org.apache.lucene.util.InPlaceMergeSorter;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.lucene.util.Sorter;
@@ -115,7 +115,7 @@ public class Automaton implements Accountable {
 
   /** Set or clear this state as an accept state. */
   public void setAccept(int state, boolean accept) {
-    FutureObjects.checkIndex(state, getNumStates());
+    Objects.checkIndex(state, getNumStates());
     isAccept.set(state, accept);
   }
 
@@ -157,8 +157,8 @@ public class Automaton implements Accountable {
     assert nextTransition%3 == 0;
 
     int bounds = nextState/2;
-    FutureObjects.checkIndex(source, bounds);
-    FutureObjects.checkIndex(dest, bounds);
+    Objects.checkIndex(source, bounds);
+    Objects.checkIndex(dest, bounds);
 
     growTransitions();
     if (curState != source) {
@@ -834,7 +834,7 @@ public class Automaton implements Accountable {
 
     /** Set or clear this state as an accept state. */
     public void setAccept(int state, boolean accept) {
-      FutureObjects.checkIndex(state, getNumStates());      
+      Objects.checkIndex(state, getNumStates());      
       this.isAccept.set(state, accept);
     }
 
diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDRadixSelector.java b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDRadixSelector.java
index 6a212d8..84fce3f 100644
--- a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDRadixSelector.java
+++ b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDRadixSelector.java
@@ -21,7 +21,6 @@ import java.util.Arrays;
 
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IntroSelector;
 import org.apache.lucene.util.IntroSorter;
 import org.apache.lucene.util.MSBRadixSorter;
@@ -158,12 +157,12 @@ public final class BKDRadixSelector {
           final int startIndex = (dimCommonPrefix > bytesPerDim) ? bytesPerDim : dimCommonPrefix;
           final int endIndex = (commonPrefixPosition > bytesPerDim) ? bytesPerDim : commonPrefixPosition;
           packedValue = pointValue.packedValue();
-          int j = FutureArrays.mismatch(scratch, startIndex, endIndex, packedValue.bytes, packedValue.offset + offset + startIndex, packedValue.offset + offset + endIndex);
+          int j = Arrays.mismatch(scratch, startIndex, endIndex, packedValue.bytes, packedValue.offset + offset + startIndex, packedValue.offset + offset + endIndex);
           if (j == -1) {
             if (commonPrefixPosition > bytesPerDim) {
               //tie-break on docID
               docIDBytes = pointValue.docIDBytes();
-              int k = FutureArrays.mismatch(scratch, bytesPerDim, commonPrefixPosition, docIDBytes.bytes, docIDBytes.offset, docIDBytes.offset + commonPrefixPosition - bytesPerDim);
+              int k = Arrays.mismatch(scratch, bytesPerDim, commonPrefixPosition, docIDBytes.bytes, docIDBytes.offset, docIDBytes.offset + commonPrefixPosition - bytesPerDim);
               if (k != -1) {
                 commonPrefixPosition = bytesPerDim + k;
                 Arrays.fill(histogram, 0);
@@ -360,7 +359,7 @@ public final class BKDRadixSelector {
             if (skypedBytes < bytesPerDim) {
               int iOffset = i * packedBytesLength;
               int jOffset = j * packedBytesLength;
-              int cmp = FutureArrays.compareUnsigned(points.block, iOffset + start, iOffset + end,
+              int cmp = Arrays.compareUnsigned(points.block, iOffset + start, iOffset + end,
                   points.block, jOffset + start, jOffset + end);
               if (cmp != 0) {
                 return cmp;
@@ -373,7 +372,7 @@ public final class BKDRadixSelector {
           protected int comparePivot(int j) {
             if (skypedBytes < bytesPerDim) {
               int jOffset = j * packedBytesLength;
-              int cmp = FutureArrays.compareUnsigned(scratch, skypedBytes, bytesPerDim,
+              int cmp = Arrays.compareUnsigned(scratch, skypedBytes, bytesPerDim,
                   points.block, jOffset + start, jOffset + end);
               if (cmp != 0) {
                 return cmp;
@@ -443,7 +442,7 @@ public final class BKDRadixSelector {
             if (skypedBytes < bytesPerDim) {
               int iOffset = i * packedBytesLength;
               int jOffset = j * packedBytesLength;
-              int cmp = FutureArrays.compareUnsigned(points.block, iOffset + start, iOffset + end,
+              int cmp = Arrays.compareUnsigned(points.block, iOffset + start, iOffset + end,
                   points.block, jOffset + start, jOffset + end);
               if (cmp != 0) {
                 return cmp;
@@ -456,7 +455,7 @@ public final class BKDRadixSelector {
           protected int comparePivot(int j) {
             if (skypedBytes < bytesPerDim) {
               int jOffset = j * packedBytesLength;
-              int cmp = FutureArrays.compareUnsigned(scratch, skypedBytes, bytesPerDim,
+              int cmp = Arrays.compareUnsigned(scratch, skypedBytes, bytesPerDim,
                   points.block, jOffset + start, jOffset + end);
               if (cmp != 0) {
                 return cmp;
diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDReader.java b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDReader.java
index 3cbb054..c1f5a63 100644
--- a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDReader.java
+++ b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDReader.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.util.bkd;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import org.apache.lucene.codecs.CodecUtil;
 import org.apache.lucene.index.CorruptIndexException;
@@ -25,7 +26,6 @@ import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.util.Accountable;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.MathUtil;
 
 /** Handles intersection of an multi-dimensional shape in byte[] space with a block KD-tree previously written with {@link BKDWriter}.
@@ -77,7 +77,7 @@ public final class BKDReader extends PointValues implements Accountable {
     in.readBytes(maxPackedValue, 0, packedIndexBytesLength);
 
     for(int dim=0;dim<numIndexDims;dim++) {
-      if (FutureArrays.compareUnsigned(minPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, maxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) > 0) {
+      if (Arrays.compareUnsigned(minPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, maxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) > 0) {
         throw new CorruptIndexException("minPackedValue " + new BytesRef(minPackedValue) + " is > maxPackedValue " + new BytesRef(maxPackedValue) + " for dim=" + dim, in);
       }
     }
@@ -590,8 +590,8 @@ public final class BKDReader extends PointValues implements Accountable {
       //System.out.println("  splitDimValue=" + splitDimValue + " splitDim=" + splitDim);
 
       // make sure cellMin <= splitValue <= cellMax:
-      assert FutureArrays.compareUnsigned(cellMinPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) <= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
-      assert FutureArrays.compareUnsigned(cellMaxPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) >= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
+      assert Arrays.compareUnsigned(cellMinPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) <= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
+      assert Arrays.compareUnsigned(cellMaxPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) >= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
 
       // Recurse on left sub-tree:
       System.arraycopy(cellMaxPacked, 0, splitPackedValue, 0, packedIndexBytesLength);
@@ -644,8 +644,8 @@ public final class BKDReader extends PointValues implements Accountable {
       //System.out.println("  splitDimValue=" + splitDimValue + " splitDim=" + splitDim);
 
       // make sure cellMin <= splitValue <= cellMax:
-      assert FutureArrays.compareUnsigned(cellMinPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) <= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
-      assert FutureArrays.compareUnsigned(cellMaxPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) >= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
+      assert Arrays.compareUnsigned(cellMinPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) <= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
+      assert Arrays.compareUnsigned(cellMaxPacked, splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim, splitDimValue.bytes, splitDimValue.offset, splitDimValue.offset + bytesPerDim) >= 0: "bytesPerDim=" + bytesPerDim + " splitDim=" + splitDim + " numIndexDims=" + numIndexDims + " numDataDims=" + numDataDims;
 
       // Recurse on left sub-tree:
       System.arraycopy(cellMaxPacked, 0, splitPackedValue, 0, packedIndexBytesLength);
diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
index 5e92126..7a1aec4 100644
--- a/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
+++ b/lucene/core/src/java/org/apache/lucene/util/bkd/BKDWriter.java
@@ -39,7 +39,6 @@ import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.PriorityQueue;
@@ -231,10 +230,10 @@ public class BKDWriter implements Closeable {
     } else {
       for(int dim=0;dim<numIndexDims;dim++) {
         int offset = dim*bytesPerDim;
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
           System.arraycopy(packedValue, offset, minPackedValue, offset, bytesPerDim);
         }
-        if (FutureArrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(packedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           System.arraycopy(packedValue, offset, maxPackedValue, offset, bytesPerDim);
         }
       }
@@ -351,7 +350,7 @@ public class BKDWriter implements Closeable {
     public boolean lessThan(MergeReader a, MergeReader b) {
       assert a != b;
 
-      int cmp = FutureArrays.compareUnsigned(a.state.scratchDataPackedValue, 0, bytesPerDim, b.state.scratchDataPackedValue, 0, bytesPerDim);
+      int cmp = Arrays.compareUnsigned(a.state.scratchDataPackedValue, 0, bytesPerDim, b.state.scratchDataPackedValue, 0, bytesPerDim);
       if (cmp < 0) {
         return true;
       } else if (cmp > 0) {
@@ -413,10 +412,10 @@ public class BKDWriter implements Closeable {
       values.getValue(i, scratchBytesRef1);
       for(int dim=0;dim<numIndexDims;dim++) {
         int offset = dim*bytesPerDim;
-        if (FutureArrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
           System.arraycopy(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, minPackedValue, offset, bytesPerDim);
         }
-        if (FutureArrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, scratchBytesRef1.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           System.arraycopy(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset, maxPackedValue, offset, bytesPerDim);
         }
       }
@@ -612,7 +611,7 @@ public class BKDWriter implements Closeable {
 
       // Find per-dim common prefix:
       int offset = (leafCount - 1) * packedBytesLength;
-      int prefix = FutureArrays.mismatch(leafValues, 0, bytesPerDim, leafValues, offset, offset + bytesPerDim);
+      int prefix = Arrays.mismatch(leafValues, 0, bytesPerDim, leafValues, offset, offset + bytesPerDim);
       if (prefix == -1) {
           prefix = bytesPerDim;
       }
@@ -901,7 +900,7 @@ public class BKDWriter implements Closeable {
       //System.out.println("recursePack inner nodeID=" + nodeID + " splitDim=" + splitDim + " splitValue=" + new BytesRef(splitPackedValues, address, bytesPerDim));
 
       // find common prefix with last split value in this dim:
-      int prefix = FutureArrays.mismatch(splitPackedValues, address, address + bytesPerDim, lastSplitValues,
+      int prefix = Arrays.mismatch(splitPackedValues, address, address + bytesPerDim, lastSplitValues,
           splitDim * bytesPerDim, splitDim * bytesPerDim + bytesPerDim);
       if (prefix == -1) {
         prefix = bytesPerDim;
@@ -1082,9 +1081,9 @@ public class BKDWriter implements Closeable {
     max.copyBytes(first.bytes, first.offset + offset, length);
     for (int i = 1; i < count; ++i) {
       BytesRef candidate = packedValues.apply(i);
-      if (FutureArrays.compareUnsigned(min.bytes(), 0, length, candidate.bytes, candidate.offset + offset, candidate.offset + offset + length) > 0) {
+      if (Arrays.compareUnsigned(min.bytes(), 0, length, candidate.bytes, candidate.offset + offset, candidate.offset + offset + length) > 0) {
         min.copyBytes(candidate.bytes, candidate.offset + offset, length);
-      } else if (FutureArrays.compareUnsigned(max.bytes(), 0, length, candidate.bytes, candidate.offset + offset, candidate.offset + offset + length) < 0) {
+      } else if (Arrays.compareUnsigned(max.bytes(), 0, length, candidate.bytes, candidate.offset + offset, candidate.offset + offset + length) < 0) {
         max.copyBytes(candidate.bytes, candidate.offset + offset, length);
       }
     }
@@ -1166,10 +1165,10 @@ public class BKDWriter implements Closeable {
   private boolean valueInBounds(BytesRef packedValue, byte[] minPackedValue, byte[] maxPackedValue) {
     for(int dim=0;dim<numIndexDims;dim++) {
       int offset = bytesPerDim*dim;
-      if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+      if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
         return false;
       }
-      if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+      if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
         return false;
       }
     }
@@ -1195,7 +1194,7 @@ public class BKDWriter implements Closeable {
     for (int dim = 0; dim < numIndexDims; ++dim) {
       final int offset = dim * bytesPerDim;
       if (parentSplits[dim] < maxNumSplits / 2 &&
-          FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) != 0) {
+          Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) != 0) {
         return dim;
       }
     }
@@ -1204,7 +1203,7 @@ public class BKDWriter implements Closeable {
     int splitDim = -1;
     for(int dim=0;dim<numIndexDims;dim++) {
       NumericUtils.subtract(bytesPerDim, dim, maxPackedValue, minPackedValue, scratchDiff);
-      if (splitDim == -1 || FutureArrays.compareUnsigned(scratchDiff, 0, bytesPerDim, scratch1, 0, bytesPerDim) > 0) {
+      if (splitDim == -1 || Arrays.compareUnsigned(scratchDiff, 0, bytesPerDim, scratch1, 0, bytesPerDim) > 0) {
         System.arraycopy(scratchDiff, 0, scratch1, 0, bytesPerDim);
         splitDim = dim;
       }
@@ -1255,7 +1254,7 @@ public class BKDWriter implements Closeable {
         for (int dim=0;dim<numDataDims;dim++) {
           final int offset = dim * bytesPerDim;
           int dimensionPrefixLength = commonPrefixLengths[dim];
-          commonPrefixLengths[dim] = FutureArrays.mismatch(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset,
+          commonPrefixLengths[dim] = Arrays.mismatch(scratchBytesRef1.bytes, scratchBytesRef1.offset + offset,
               scratchBytesRef1.offset + offset + dimensionPrefixLength,
               scratchBytesRef2.bytes, scratchBytesRef2.offset + offset,
               scratchBytesRef2.offset + offset + dimensionPrefixLength);
@@ -1334,7 +1333,7 @@ public class BKDWriter implements Closeable {
       final int splitDim = split(minPackedValue, maxPackedValue, parentSplits);
       final int mid = (from + to + 1) >>> 1;
 
-      int commonPrefixLen = FutureArrays.mismatch(minPackedValue, splitDim * bytesPerDim,
+      int commonPrefixLen = Arrays.mismatch(minPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim, maxPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim);
       if (commonPrefixLen == -1) {
@@ -1480,7 +1479,7 @@ public class BKDWriter implements Closeable {
 
       BKDRadixSelector.PathSlice[] slices = new BKDRadixSelector.PathSlice[2];
 
-      int commonPrefixLen = FutureArrays.mismatch(minPackedValue, splitDim * bytesPerDim,
+      int commonPrefixLen = Arrays.mismatch(minPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim, maxPackedValue, splitDim * bytesPerDim,
           splitDim * bytesPerDim + bytesPerDim);
       if (commonPrefixLen == -1) {
@@ -1529,7 +1528,7 @@ public class BKDWriter implements Closeable {
       packedValue = value.packedValue();
       for (int dim = 0; dim < numDataDims; dim++) {
         if (commonPrefixLengths[dim] != 0) {
-          int j = FutureArrays.mismatch(commonPrefix, dim * bytesPerDim, dim * bytesPerDim + commonPrefixLengths[dim], packedValue.bytes, packedValue.offset + dim * bytesPerDim, packedValue.offset + dim * bytesPerDim + commonPrefixLengths[dim]);
+          int j = Arrays.mismatch(commonPrefix, dim * bytesPerDim, dim * bytesPerDim + commonPrefixLengths[dim], packedValue.bytes, packedValue.offset + dim * bytesPerDim, packedValue.offset + dim * bytesPerDim + commonPrefixLengths[dim]);
           if (j != -1) {
             commonPrefixLengths[dim] = j;
           }
@@ -1561,7 +1560,7 @@ public class BKDWriter implements Closeable {
       int doc, int lastDoc) {
     int dimOffset = sortedDim * bytesPerDim;
     if (ord > 0) {
-      int cmp = FutureArrays.compareUnsigned(lastPackedValue, dimOffset, dimOffset + bytesPerDim, packedValue, packedValueOffset + dimOffset, packedValueOffset + dimOffset + bytesPerDim);
+      int cmp = Arrays.compareUnsigned(lastPackedValue, dimOffset, dimOffset + bytesPerDim, packedValue, packedValueOffset + dimOffset, packedValueOffset + dimOffset + bytesPerDim);
       if (cmp > 0) {
         throw new AssertionError("values out of order: last value=" + new BytesRef(lastPackedValue) + " current value=" + new BytesRef(packedValue, packedValueOffset, packedBytesLength) + " ord=" + ord);
       }
diff --git a/lucene/core/src/java/org/apache/lucene/util/bkd/MutablePointsReaderUtils.java b/lucene/core/src/java/org/apache/lucene/util/bkd/MutablePointsReaderUtils.java
index c56ed71..5323476 100644
--- a/lucene/core/src/java/org/apache/lucene/util/bkd/MutablePointsReaderUtils.java
+++ b/lucene/core/src/java/org/apache/lucene/util/bkd/MutablePointsReaderUtils.java
@@ -16,9 +16,10 @@
  */
 package org.apache.lucene.util.bkd;
 
+import java.util.Arrays;
+
 import org.apache.lucene.codecs.MutablePointValues;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IntroSelector;
 import org.apache.lucene.util.IntroSorter;
 import org.apache.lucene.util.MSBRadixSorter;
@@ -77,7 +78,7 @@ public final class MutablePointsReaderUtils {
           protected int comparePivot(int j) {
             if (k < packedBytesLength) {
               reader.getValue(j, scratch);
-              int cmp = FutureArrays.compareUnsigned(pivot.bytes, pivot.offset + k, pivot.offset + k + packedBytesLength - k, scratch.bytes, scratch.offset + k, scratch.offset + k + packedBytesLength - k);
+              int cmp = Arrays.compareUnsigned(pivot.bytes, pivot.offset + k, pivot.offset + k + packedBytesLength - k, scratch.bytes, scratch.offset + k, scratch.offset + k + packedBytesLength - k);
               if (cmp != 0) {
                 return cmp;
               }
@@ -118,7 +119,7 @@ public final class MutablePointsReaderUtils {
       @Override
       protected int comparePivot(int j) {
         reader.getValue(j, scratch2);
-        int cmp = FutureArrays.compareUnsigned(pivot.bytes, pivot.offset + offset, pivot.offset + offset + numBytesToCompare, scratch2.bytes, scratch2.offset + offset, scratch2.offset + offset + numBytesToCompare);
+        int cmp = Arrays.compareUnsigned(pivot.bytes, pivot.offset + offset, pivot.offset + offset + numBytesToCompare, scratch2.bytes, scratch2.offset + offset, scratch2.offset + offset + numBytesToCompare);
         if (cmp == 0) {
           cmp = pivotDoc - reader.getDocID(j);
         }
@@ -160,7 +161,7 @@ public final class MutablePointsReaderUtils {
           protected int comparePivot(int j) {
             if (k < cmpBytes) {
               reader.getValue(j, scratch2);
-              int cmp = FutureArrays.compareUnsigned(pivot.bytes, pivot.offset + offset + k, pivot.offset + offset + k + cmpBytes - k, scratch2.bytes, scratch2.offset + offset + k, scratch2.offset + offset + k + cmpBytes - k);
+              int cmp = Arrays.compareUnsigned(pivot.bytes, pivot.offset + offset + k, pivot.offset + offset + k + cmpBytes - k, scratch2.bytes, scratch2.offset + offset + k, scratch2.offset + offset + k + cmpBytes - k);
               if (cmp != 0) {
                 return cmp;
               }
diff --git a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestBytesRefAttImpl.java b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestBytesRefAttImpl.java
index 49e1c22..6c01d5c 100644
--- a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestBytesRefAttImpl.java
+++ b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestBytesRefAttImpl.java
@@ -39,7 +39,7 @@ public class TestBytesRefAttImpl extends LuceneTestCase {
 
   public static <T extends AttributeImpl> T assertCopyIsEqual(T att) throws Exception {
     @SuppressWarnings("unchecked")
-    T copy = (T) att.getClass().newInstance();
+    T copy = (T) att.getClass().getConstructor().newInstance();
     att.copyTo(copy);
     assertEquals("Copied instance must be equal", att, copy);
     assertEquals("Copied instance's hashcode must be equal", att.hashCode(), copy.hashCode());
diff --git a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
index 9bf3621..a889e4d 100644
--- a/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
+++ b/lucene/core/src/test/org/apache/lucene/analysis/tokenattributes/TestCharTermAttributeImpl.java
@@ -291,7 +291,7 @@ public class TestCharTermAttributeImpl extends LuceneTestCase {
 
   public static <T extends AttributeImpl> T assertCopyIsEqual(T att) throws Exception {
     @SuppressWarnings("unchecked")
-    T copy = (T) att.getClass().newInstance();
+    T copy = (T) att.getClass().getConstructor().newInstance();
     att.copyTo(copy);
     assertEquals("Copied instance must be equal", att, copy);
     assertEquals("Copied instance's hashcode must be equal", att.hashCode(), copy.hashCode());
diff --git a/lucene/core/src/test/org/apache/lucene/codecs/lucene60/TestLucene60PointsFormat.java b/lucene/core/src/test/org/apache/lucene/codecs/lucene60/TestLucene60PointsFormat.java
index 87fc5e2..7275f65 100644
--- a/lucene/core/src/test/org/apache/lucene/codecs/lucene60/TestLucene60PointsFormat.java
+++ b/lucene/core/src/test/org/apache/lucene/codecs/lucene60/TestLucene60PointsFormat.java
@@ -40,7 +40,6 @@ import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.PointValues.IntersectVisitor;
 import org.apache.lucene.index.PointValues.Relation;
 import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.TestUtil;
 import org.apache.lucene.util.bkd.BKDWriter;
 
@@ -170,8 +169,8 @@ public class TestLucene60PointsFormat extends BasePointsFormatTestCase {
           
           @Override
           public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-            if (FutureArrays.compareUnsigned(uniquePointValue, 0, 3, maxPackedValue, 0, 3) > 0 ||
-                FutureArrays.compareUnsigned(uniquePointValue, 0, 3, minPackedValue, 0, 3) < 0) {
+            if (Arrays.compareUnsigned(uniquePointValue, 0, 3, maxPackedValue, 0, 3) > 0 ||
+                Arrays.compareUnsigned(uniquePointValue, 0, 3, minPackedValue, 0, 3) < 0) {
               return Relation.CELL_OUTSIDE_QUERY;
             }
             return Relation.CELL_CROSSES_QUERY;
@@ -267,8 +266,8 @@ public class TestLucene60PointsFormat extends BasePointsFormatTestCase {
         @Override
         public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
           for (int dim = 0; dim < 2; ++dim) {
-            if (FutureArrays.compareUnsigned(uniquePointValue[dim], 0, 3, maxPackedValue, dim * 3, dim * 3 + 3) > 0 ||
-                FutureArrays.compareUnsigned(uniquePointValue[dim], 0, 3, minPackedValue, dim * 3, dim * 3 + 3) < 0) {
+            if (Arrays.compareUnsigned(uniquePointValue[dim], 0, 3, maxPackedValue, dim * 3, dim * 3 + 3) > 0 ||
+                Arrays.compareUnsigned(uniquePointValue[dim], 0, 3, minPackedValue, dim * 3, dim * 3 + 3) < 0) {
               return Relation.CELL_OUTSIDE_QUERY;
             }
           }
diff --git a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
index 7e322f4..092dd7d 100644
--- a/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
+++ b/lucene/core/src/test/org/apache/lucene/search/TestPointQueries.java
@@ -64,7 +64,6 @@ import org.apache.lucene.index.SegmentWriteState;
 import org.apache.lucene.index.Term;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NumericUtils;
@@ -783,7 +782,7 @@ public class TestPointQueries extends LuceneTestCase {
                 upper[dim] = new byte[bytesPerDim];
                 random().nextBytes(upper[dim]);
 
-                if (FutureArrays.compareUnsigned(lower[dim], 0, bytesPerDim, upper[dim], 0, bytesPerDim) > 0) {
+                if (Arrays.compareUnsigned(lower[dim], 0, bytesPerDim, upper[dim], 0, bytesPerDim) > 0) {
                   byte[] x = lower[dim];
                   lower[dim] = upper[dim];
                   upper[dim] = x;
@@ -883,12 +882,12 @@ public class TestPointQueries extends LuceneTestCase {
     int numDims = lower.length;
     for(int dim=0;dim<numDims;dim++) {
 
-      if (FutureArrays.compareUnsigned(value[dim], 0, bytesPerDim, lower[dim], 0, bytesPerDim) < 0) {
+      if (Arrays.compareUnsigned(value[dim], 0, bytesPerDim, lower[dim], 0, bytesPerDim) < 0) {
         // Value is below the lower bound, on this dim
         return false;
       }
 
-      if (FutureArrays.compareUnsigned(value[dim], 0, bytesPerDim, upper[dim], 0, bytesPerDim) > 0) {
+      if (Arrays.compareUnsigned(value[dim], 0, bytesPerDim, upper[dim], 0, bytesPerDim) > 0) {
         // Value is above the upper bound, on this dim
         return false;
       }
@@ -1418,7 +1417,7 @@ public class TestPointQueries extends LuceneTestCase {
                 new Comparator<byte[]>() {
                   @Override
                   public int compare(byte[] a, byte[] b) {
-                    return FutureArrays.compareUnsigned(a, 0, a.length, b, 0, a.length);
+                    return Arrays.compareUnsigned(a, 0, a.length, b, 0, a.length);
                   }
                 });
 
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestFutureArrays.java b/lucene/core/src/test/org/apache/lucene/util/TestFutureArrays.java
deleted file mode 100644
index 1c128ed..0000000
--- a/lucene/core/src/test/org/apache/lucene/util/TestFutureArrays.java
+++ /dev/null
@@ -1,305 +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.lucene.util;
-
-import java.nio.charset.StandardCharsets;
-
-/** Test java 8-compatible implementations of {@code java.util.Arrays} methods */
-public class TestFutureArrays extends LuceneTestCase {
-  
-  public void testByteMismatch() {
-    assertEquals(1, FutureArrays.mismatch(bytes("ab"), 0, 2, bytes("ac"), 0, 2));
-    assertEquals(0, FutureArrays.mismatch(bytes("ab"), 0, 2, bytes("b"), 0, 1));
-    assertEquals(-1, FutureArrays.mismatch(bytes("ab"), 0, 2, bytes("ab"), 0, 2));
-    assertEquals(1, FutureArrays.mismatch(bytes("ab"), 0, 2, bytes("a"), 0, 1));
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.mismatch(bytes("ab"), 2, 1, bytes("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.mismatch(bytes("ab"), 2, 1, bytes("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.mismatch(null, 0, 2, bytes("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.mismatch(bytes("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.mismatch(bytes("ab"), 0, 3, bytes("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.mismatch(bytes("ab"), 0, 2, bytes("a"), 0, 2);
-    });
-  }
-  
-  public void testCharMismatch() {
-    assertEquals(1, FutureArrays.mismatch(chars("ab"), 0, 2, chars("ac"), 0, 2));
-    assertEquals(0, FutureArrays.mismatch(chars("ab"), 0, 2, chars("b"), 0, 1));
-    assertEquals(-1, FutureArrays.mismatch(chars("ab"), 0, 2, chars("ab"), 0, 2));
-    assertEquals(1, FutureArrays.mismatch(chars("ab"), 0, 2, chars("a"), 0, 1));
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.mismatch(chars("ab"), 2, 1, chars("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.mismatch(chars("ab"), 2, 1, chars("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.mismatch(null, 0, 2, chars("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.mismatch(chars("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.mismatch(chars("ab"), 0, 3, chars("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.mismatch(chars("ab"), 0, 2, chars("a"), 0, 2);
-    });
-  }
-  
-  public void testByteCompareUnsigned() {
-    assertEquals(1, Integer.signum(FutureArrays.compareUnsigned(bytes("ab"), 0, 2, bytes("a"), 0, 1)));
-    assertEquals(1, Integer.signum(FutureArrays.compareUnsigned(bytes("ab"), 0, 2, bytes("aa"), 0, 2)));
-    assertEquals(0, Integer.signum(FutureArrays.compareUnsigned(bytes("ab"), 0, 2, bytes("ab"), 0, 2)));
-    assertEquals(-1, Integer.signum(FutureArrays.compareUnsigned(bytes("a"), 0, 1, bytes("ab"), 0, 2)));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compareUnsigned(bytes("ab"), 2, 1, bytes("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compareUnsigned(bytes("ab"), 2, 1, bytes("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compareUnsigned(null, 0, 2, bytes("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compareUnsigned(bytes("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compareUnsigned(bytes("ab"), 0, 3, bytes("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compareUnsigned(bytes("ab"), 0, 2, bytes("a"), 0, 2);
-    });
-  }
-  
-  public void testCharCompare() {
-    assertEquals(1, Integer.signum(FutureArrays.compare(chars("ab"), 0, 2, chars("a"), 0, 1)));
-    assertEquals(1, Integer.signum(FutureArrays.compare(chars("ab"), 0, 2, chars("aa"), 0, 2)));
-    assertEquals(0, Integer.signum(FutureArrays.compare(chars("ab"), 0, 2, chars("ab"), 0, 2)));
-    assertEquals(-1, Integer.signum(FutureArrays.compare(chars("a"), 0, 1, chars("ab"), 0, 2)));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(chars("ab"), 2, 1, chars("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(chars("ab"), 2, 1, chars("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(null, 0, 2, chars("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(chars("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(chars("ab"), 0, 3, chars("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(chars("ab"), 0, 2, chars("a"), 0, 2);
-    });
-  }
-  
-  public void testIntCompare() {
-    assertEquals(1, Integer.signum(FutureArrays.compare(ints("ab"), 0, 2, ints("a"), 0, 1)));
-    assertEquals(1, Integer.signum(FutureArrays.compare(ints("ab"), 0, 2, ints("aa"), 0, 2)));
-    assertEquals(0, Integer.signum(FutureArrays.compare(ints("ab"), 0, 2, ints("ab"), 0, 2)));
-    assertEquals(-1, Integer.signum(FutureArrays.compare(ints("a"), 0, 1, ints("ab"), 0, 2)));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(ints("ab"), 2, 1, ints("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(ints("ab"), 2, 1, ints("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(null, 0, 2, ints("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(ints("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(ints("ab"), 0, 3, ints("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(ints("ab"), 0, 2, ints("a"), 0, 2);
-    });
-  }
-  
-  public void testLongCompare() {
-    assertEquals(1, Integer.signum(FutureArrays.compare(longs("ab"), 0, 2, longs("a"), 0, 1)));
-    assertEquals(1, Integer.signum(FutureArrays.compare(longs("ab"), 0, 2, longs("aa"), 0, 2)));
-    assertEquals(0, Integer.signum(FutureArrays.compare(longs("ab"), 0, 2, longs("ab"), 0, 2)));
-    assertEquals(-1, Integer.signum(FutureArrays.compare(longs("a"), 0, 1, longs("ab"), 0, 2)));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(longs("ab"), 2, 1, longs("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.compare(longs("ab"), 2, 1, longs("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(null, 0, 2, longs("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.compare(longs("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(longs("ab"), 0, 3, longs("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.compare(longs("ab"), 0, 2, longs("a"), 0, 2);
-    });
-  }
-  
-  public void testByteEquals() {
-    assertFalse(FutureArrays.equals(bytes("ab"), 0, 2, bytes("a"), 0, 1));
-    assertFalse(FutureArrays.equals(bytes("ab"), 0, 2, bytes("aa"), 0, 2));
-    assertTrue(FutureArrays.equals(bytes("ab"), 0, 2, bytes("ab"), 0, 2));
-    assertFalse(FutureArrays.equals(bytes("a"), 0, 1, bytes("ab"), 0, 2));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(bytes("ab"), 2, 1, bytes("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(bytes("ab"), 2, 1, bytes("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(null, 0, 2, bytes("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(bytes("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(bytes("ab"), 0, 3, bytes("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(bytes("ab"), 0, 2, bytes("a"), 0, 2);
-    });
-  }
-  
-  public void testCharEquals() {
-    assertFalse(FutureArrays.equals(chars("ab"), 0, 2, chars("a"), 0, 1));
-    assertFalse(FutureArrays.equals(chars("ab"), 0, 2, chars("aa"), 0, 2));
-    assertTrue(FutureArrays.equals(chars("ab"), 0, 2, chars("ab"), 0, 2));
-    assertFalse(FutureArrays.equals(chars("a"), 0, 1, chars("ab"), 0, 2));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(chars("ab"), 2, 1, chars("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(chars("ab"), 2, 1, chars("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(null, 0, 2, chars("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(chars("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(chars("ab"), 0, 3, chars("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(chars("ab"), 0, 2, chars("a"), 0, 2);
-    });
-  }
-  
-  public void testIntEquals() {
-    assertFalse(FutureArrays.equals(ints("ab"), 0, 2, ints("a"), 0, 1));
-    assertFalse(FutureArrays.equals(ints("ab"), 0, 2, ints("aa"), 0, 2));
-    assertTrue(FutureArrays.equals(ints("ab"), 0, 2, ints("ab"), 0, 2));
-    assertFalse(FutureArrays.equals(ints("a"), 0, 1, ints("ab"), 0, 2));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(ints("ab"), 2, 1, ints("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(ints("ab"), 2, 1, ints("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(null, 0, 2, ints("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(ints("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(ints("ab"), 0, 3, ints("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(ints("ab"), 0, 2, ints("a"), 0, 2);
-    });
-  }
-  
-  public void testLongEquals() {
-    assertFalse(FutureArrays.equals(longs("ab"), 0, 2, longs("a"), 0, 1));
-    assertFalse(FutureArrays.equals(longs("ab"), 0, 2, longs("aa"), 0, 2));
-    assertTrue(FutureArrays.equals(longs("ab"), 0, 2, longs("ab"), 0, 2));
-    assertFalse(FutureArrays.equals(longs("a"), 0, 1, longs("ab"), 0, 2));
-
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(longs("ab"), 2, 1, longs("a"), 0, 1);
-    });
-    expectThrows(IllegalArgumentException.class, () -> {
-      FutureArrays.equals(longs("ab"), 2, 1, longs("a"), 1, 0);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(null, 0, 2, longs("a"), 0, 1);
-    });
-    expectThrows(NullPointerException.class, () -> {
-      FutureArrays.equals(longs("ab"), 0, 2, null, 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(longs("ab"), 0, 3, longs("a"), 0, 1);
-    });
-    expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureArrays.equals(longs("ab"), 0, 2, longs("a"), 0, 2);
-    });
-  }
-  
-  private byte[] bytes(String s) {
-    return s.getBytes(StandardCharsets.UTF_8);
-  }
-  
-  private char[] chars(String s) {
-    return s.toCharArray();
-  }
-  
-  private int[] ints(String s) {
-    int ints[] = new int[s.length()];
-    for (int i = 0; i < s.length(); i++) {
-      ints[i] = s.charAt(i);
-    }
-    return ints;
-  }
-  
-  private long[] longs(String s) {
-    long longs[] = new long[s.length()];
-    for (int i = 0; i < s.length(); i++) {
-      longs[i] = s.charAt(i);
-    }
-    return longs;
-  }
-}
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestFutureObjects.java b/lucene/core/src/test/org/apache/lucene/util/TestFutureObjects.java
deleted file mode 100644
index ed1ad36..0000000
--- a/lucene/core/src/test/org/apache/lucene/util/TestFutureObjects.java
+++ /dev/null
@@ -1,102 +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.lucene.util;
-
-/** Test java 8-compatible implementations of {@code java.util.Objects} methods */
-public class TestFutureObjects extends LuceneTestCase {
-
-  public void testCheckIndex() {
-    assertEquals(0, FutureObjects.checkIndex(0, 1));
-    assertEquals(1, FutureObjects.checkIndex(1, 2));
-
-    Exception e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkIndex(-1, 0);
-    });
-    assertEquals("Index -1 out-of-bounds for length 0", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkIndex(0, 0);
-    });
-    assertEquals("Index 0 out-of-bounds for length 0", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkIndex(1, 0);
-    });
-    assertEquals("Index 1 out-of-bounds for length 0", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkIndex(0, -1);
-    });
-    assertEquals("Index 0 out-of-bounds for length -1", e.getMessage());
-  }
-  
-  public void testCheckFromToIndex() {
-    assertEquals(0, FutureObjects.checkFromToIndex(0, 0, 0));
-    assertEquals(1, FutureObjects.checkFromToIndex(1, 2, 2));
-    
-    Exception e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromToIndex(-1, 0, 0);
-    });
-    assertEquals("Range [-1, 0) out-of-bounds for length 0", e.getMessage());
-
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromToIndex(1, 0, 2);
-    });
-    assertEquals("Range [1, 0) out-of-bounds for length 2", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromToIndex(1, 3, 2);
-    });
-    assertEquals("Range [1, 3) out-of-bounds for length 2", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromToIndex(0, 0, -1);
-    });
-    assertEquals("Range [0, 0) out-of-bounds for length -1", e.getMessage());
-  }
-  
-  public void testCheckFromIndexSize() {
-    assertEquals(0, FutureObjects.checkFromIndexSize(0, 0, 0));
-    assertEquals(1, FutureObjects.checkFromIndexSize(1, 2, 3));
-    
-    Exception e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromIndexSize(-1, 0, 1);
-    });
-    assertEquals("Range [-1, -1 + 0) out-of-bounds for length 1", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromIndexSize(0, -1, 1);
-    });
-    assertEquals("Range [0, 0 + -1) out-of-bounds for length 1", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromIndexSize(0, 2, 1);
-    });
-    assertEquals("Range [0, 0 + 2) out-of-bounds for length 1", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromIndexSize(1, Integer.MAX_VALUE, Integer.MAX_VALUE);
-    });
-    assertEquals("Range [1, 1 + 2147483647) out-of-bounds for length 2147483647", e.getMessage());
-    
-    e = expectThrows(IndexOutOfBoundsException.class, () -> {
-      FutureObjects.checkFromIndexSize(0, 0, -1);
-    });
-    assertEquals("Range [0, 0 + 0) out-of-bounds for length -1", e.getMessage());
-  }
-
-}
diff --git a/lucene/core/src/test/org/apache/lucene/util/TestUnicodeUtil.java b/lucene/core/src/test/org/apache/lucene/util/TestUnicodeUtil.java
index 9e20cb5..b273900 100644
--- a/lucene/core/src/test/org/apache/lucene/util/TestUnicodeUtil.java
+++ b/lucene/core/src/test/org/apache/lucene/util/TestUnicodeUtil.java
@@ -16,6 +16,8 @@
  */
 package org.apache.lucene.util;
 
+import java.util.Arrays;
+
 /*
  * Some of this code came from the excellent Unicode
  * conversion examples from:
@@ -142,7 +144,7 @@ public class TestUnicodeUtil extends LuceneTestCase {
       final int utf32Len = UnicodeUtil.UTF8toUTF32(new BytesRef(utf8, 0, utf8Len), utf32);
       
       int[] codePoints = s.codePoints().toArray();
-      if (!FutureArrays.equals(codePoints, 0, codePoints.length, utf32, 0, codePoints.length)) {
+      if (!Arrays.equals(codePoints, 0, codePoints.length, utf32, 0, codePoints.length)) {
         System.out.println("FAILED");
         for(int j=0;j<s.length();j++) {
           System.out.println("  char[" + j + "]=" + Integer.toHexString(s.charAt(j)));
diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
index b651b53..98449ad 100644
--- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
+++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKD.java
@@ -38,7 +38,6 @@ import org.apache.lucene.store.IndexInput;
 import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NumericUtils;
@@ -791,7 +790,7 @@ public class TestBKD extends LuceneTestCase {
           random().nextBytes(queryMin[dim]);
           queryMax[dim] = new byte[numBytesPerDim];
           random().nextBytes(queryMax[dim]);
-          if (FutureArrays.compareUnsigned(queryMin[dim], 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+          if (Arrays.compareUnsigned(queryMin[dim], 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
             byte[] x = queryMin[dim];
             queryMin[dim] = queryMax[dim];
             queryMax[dim] = x;
@@ -810,8 +809,8 @@ public class TestBKD extends LuceneTestCase {
             public void visit(int docID, byte[] packedValue) {
               //System.out.println("visit check docID=" + docID);
               for(int dim=0;dim<numIndexDims;dim++) {
-                if (FutureArrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                    FutureArrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                if (Arrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                    Arrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                   //System.out.println("  no");
                   return;
                 }
@@ -825,11 +824,11 @@ public class TestBKD extends LuceneTestCase {
             public Relation compare(byte[] minPacked, byte[] maxPacked) {
               boolean crosses = false;
               for(int dim=0;dim<numIndexDims;dim++) {
-                if (FutureArrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                    FutureArrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                if (Arrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                    Arrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                   return Relation.CELL_OUTSIDE_QUERY;
-                } else if (FutureArrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                           FutureArrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                } else if (Arrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                           Arrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                   crosses = true;
                 }
               }
@@ -847,8 +846,8 @@ public class TestBKD extends LuceneTestCase {
           boolean matches = true;
           for(int dim=0;dim<numIndexDims;dim++) {
             byte[] x = docValues[ord][dim];
-            if (FutureArrays.compareUnsigned(x, 0, numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                FutureArrays.compareUnsigned(x, 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+            if (Arrays.compareUnsigned(x, 0, numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                Arrays.compareUnsigned(x, 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
               matches = false;
               break;
             }
@@ -1231,8 +1230,8 @@ public class TestBKD extends LuceneTestCase {
 
       @Override
       public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
-        if (FutureArrays.compareUnsigned(uniquePointValue, 0, numBytesPerDim, maxPackedValue, 0, numBytesPerDim) > 0 ||
-            FutureArrays.compareUnsigned(uniquePointValue, 0, numBytesPerDim, minPackedValue, 0, numBytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(uniquePointValue, 0, numBytesPerDim, maxPackedValue, 0, numBytesPerDim) > 0 ||
+            Arrays.compareUnsigned(uniquePointValue, 0, numBytesPerDim, minPackedValue, 0, numBytesPerDim) < 0) {
           return Relation.CELL_OUTSIDE_QUERY;
         }
         return Relation.CELL_CROSSES_QUERY;
diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKDRadixSelector.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKDRadixSelector.java
index c290825..dfe654b 100644
--- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKDRadixSelector.java
+++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestBKDRadixSelector.java
@@ -23,7 +23,6 @@ import java.util.Arrays;
 
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.TestUtil;
@@ -195,7 +194,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
       //check that left and right slices contain the correct points
       byte[] max = getMax(slices[0], bytesPerDimensions, splitDim);
       byte[] min = getMin(slices[1], bytesPerDimensions, splitDim);
-      int cmp = FutureArrays.compareUnsigned(max, 0, bytesPerDimensions, min, 0, bytesPerDimensions);
+      int cmp = Arrays.compareUnsigned(max, 0, bytesPerDimensions, min, 0, bytesPerDimensions);
       assertTrue(cmp <= 0);
       if (cmp == 0) {
         int maxDocID = getMaxDocId(slices[0], bytesPerDimensions, splitDim, partitionPoint);
@@ -224,7 +223,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
   private int getRandomCommonPrefix(BKDRadixSelector.PathSlice inputSlice, int bytesPerDimension, int splitDim) throws IOException {
     byte[] pointsMax = getMax(inputSlice, bytesPerDimension, splitDim);
     byte[] pointsMin = getMin(inputSlice, bytesPerDimension, splitDim);
-    int commonPrefixLength = FutureArrays.mismatch(pointsMin, 0, bytesPerDimension, pointsMax, 0, bytesPerDimension);
+    int commonPrefixLength = Arrays.mismatch(pointsMin, 0, bytesPerDimension, pointsMax, 0, bytesPerDimension);
     if (commonPrefixLength == -1) {
       commonPrefixLength = bytesPerDimension;
     }
@@ -259,7 +258,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
         PointValue pointValue = reader.pointValue();
         BytesRef packedValue = pointValue.packedValue();
         System.arraycopy(packedValue.bytes, packedValue.offset + dimension * bytesPerDimension, value, 0, bytesPerDimension);
-        if (FutureArrays.compareUnsigned(min, 0, bytesPerDimension, value, 0, bytesPerDimension) > 0) {
+        if (Arrays.compareUnsigned(min, 0, bytesPerDimension, value, 0, bytesPerDimension) > 0) {
           System.arraycopy(value, 0, min, 0, bytesPerDimension);
         }
       }
@@ -274,7 +273,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
         PointValue pointValue = reader.pointValue();
         BytesRef packedValue = pointValue.packedValue();
         int offset = dimension * bytesPerDimension;
-        if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDimension, partitionPoint, 0, bytesPerDimension) == 0) {
+        if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDimension, partitionPoint, 0, bytesPerDimension) == 0) {
           int newDocID = pointValue.docID();
           if (newDocID < docID) {
             docID = newDocID;
@@ -294,7 +293,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
         PointValue pointValue = reader.pointValue();
         BytesRef packedValue = pointValue.packedValue();
         System.arraycopy(packedValue.bytes, packedValue.offset + dimension * bytesPerDimension, value, 0, bytesPerDimension);
-        if (FutureArrays.compareUnsigned(max, 0, bytesPerDimension, value, 0, bytesPerDimension) < 0) {
+        if (Arrays.compareUnsigned(max, 0, bytesPerDimension, value, 0, bytesPerDimension) < 0) {
           System.arraycopy(value, 0, max, 0, bytesPerDimension);
         }
       }
@@ -309,7 +308,7 @@ public class TestBKDRadixSelector extends LuceneTestCase {
         PointValue pointValue = reader.pointValue();
         BytesRef packedValue = pointValue.packedValue();
         int offset = dimension * bytesPerDimension;
-        if (FutureArrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDimension, partitionPoint, 0, bytesPerDimension) == 0) {
+        if (Arrays.compareUnsigned(packedValue.bytes, packedValue.offset + offset, packedValue.offset + offset + bytesPerDimension, partitionPoint, 0, bytesPerDimension) == 0) {
           int newDocID = pointValue.docID();
           if (newDocID > docID) {
             docID = newDocID;
diff --git a/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java b/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java
index da75b12..a78b898 100644
--- a/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java
+++ b/lucene/core/src/test/org/apache/lucene/util/bkd/TestMutablePointsReaderUtils.java
@@ -23,7 +23,6 @@ import java.util.Comparator;
 import org.apache.lucene.codecs.MutablePointValues;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 
@@ -86,7 +85,7 @@ public class TestMutablePointsReaderUtils extends LuceneTestCase {
       final int offset = sortedDim * bytesPerDim;
       BytesRef previousValue = reader.points[i-1].packedValue;
       BytesRef currentValue = reader.points[i].packedValue;
-      int cmp = FutureArrays.compareUnsigned(previousValue.bytes, previousValue.offset + offset, previousValue.offset + offset + bytesPerDim, currentValue.bytes, currentValue.offset + offset, currentValue.offset + offset + bytesPerDim);
+      int cmp = Arrays.compareUnsigned(previousValue.bytes, previousValue.offset + offset, previousValue.offset + offset + bytesPerDim, currentValue.bytes, currentValue.offset + offset, currentValue.offset + offset + bytesPerDim);
       if (cmp == 0) {
         cmp = reader.points[i - 1].doc - reader.points[i].doc;
       }
@@ -121,7 +120,7 @@ public class TestMutablePointsReaderUtils extends LuceneTestCase {
     int offset = splitDim * bytesPerDim;
     for (int i = 0; i < points.length; ++i) {
       BytesRef value = reader.points[i].packedValue;
-      int cmp = FutureArrays.compareUnsigned(value.bytes, value.offset + offset, value.offset + offset + bytesPerDim, pivotValue.bytes, pivotValue.offset + offset, pivotValue.offset + offset + bytesPerDim);
+      int cmp = Arrays.compareUnsigned(value.bytes, value.offset + offset, value.offset + offset + bytesPerDim, pivotValue.bytes, pivotValue.offset + offset, pivotValue.offset + offset + bytesPerDim);
       if (cmp == 0) {
         cmp = reader.points[i].doc - reader.points[pivot].doc;
       }
diff --git a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java
index b36bf39..f8374a3 100644
--- a/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java
+++ b/lucene/facet/src/java/org/apache/lucene/facet/taxonomy/directory/DirectoryTaxonomyWriter.java
@@ -25,6 +25,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.lucene.analysis.TokenStream;
@@ -61,7 +62,6 @@ import org.apache.lucene.store.AlreadyClosedException;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.LockObtainFailedException;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureObjects;
 
 /**
  * {@link TaxonomyWriter} which uses a {@link Directory} to store the taxonomy
@@ -769,7 +769,7 @@ public class DirectoryTaxonomyWriter implements TaxonomyWriter {
     // Note: the following if() just enforces that a user can never ask
     // for the parent of a nonexistant category - even if the parent array
     // was allocated bigger than it really needs to be.
-    FutureObjects.checkIndex(ordinal, nextID);
+    Objects.checkIndex(ordinal, nextID);
     
     int[] parents = getTaxoArrays().parents();
     assert ordinal < parents.length : "requested ordinal (" + ordinal + "); parents.length (" + parents.length + ") !";
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
index 3928ba6..0c9ad37 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/CheckIndexDialogFactory.java
@@ -36,7 +36,6 @@ import java.awt.Insets;
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.lang.invoke.MethodHandles;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -277,15 +276,12 @@ public final class CheckIndexDialogFactory implements DialogOpener.DialogFactory
             CheckIndex.Status status = toolsModel.checkIndex(ps);
             ps.flush();
             return status;
-          } catch (UnsupportedEncodingException e) {
-            // will not reach
           } catch (Exception e) {
             statusLbl.setText(MessageUtils.getLocalizedMessage("message.error.unknown"));
             throw e;
           } finally {
             setProgress(100);
           }
-          return null;
         }
 
         @Override
@@ -358,15 +354,12 @@ public final class CheckIndexDialogFactory implements DialogOpener.DialogFactory
             statusLbl.setText("Done");
             ps.flush();
             return status;
-          } catch (UnsupportedEncodingException e) {
-            // will not occur
           } catch (Exception e) {
             statusLbl.setText(MessageUtils.getLocalizedMessage("message.error.unknown"));
             throw e;
           } finally {
             setProgress(100);
           }
-          return null;
         }
 
         @Override
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OptimizeIndexDialogFactory.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OptimizeIndexDialogFactory.java
index e5543d8..947525c 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OptimizeIndexDialogFactory.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/components/dialog/menubar/OptimizeIndexDialogFactory.java
@@ -39,7 +39,6 @@ import java.awt.Insets;
 import java.awt.Window;
 import java.awt.event.ActionEvent;
 import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.lang.invoke.MethodHandles;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -221,8 +220,6 @@ public final class OptimizeIndexDialogFactory implements DialogOpener.DialogFact
             ps = new TextAreaPrintStream(logArea);
             toolsModel.optimize(expungeCB.isSelected(), (int) maxSegSpnr.getValue(), ps);
             ps.flush();
-          } catch (UnsupportedEncodingException e) {
-            // will not reach
           } catch (Exception e) {
             statusLbl.setText(MessageUtils.getLocalizedMessage("message.error.unknown"));
             throw e;
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaPrintStream.java b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaPrintStream.java
index 7c1f7ca..d826b65 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaPrintStream.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/app/desktop/util/TextAreaPrintStream.java
@@ -20,7 +20,6 @@ package org.apache.lucene.luke.app.desktop.util;
 import javax.swing.JTextArea;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
 import java.nio.charset.StandardCharsets;
 
 /** PrintStream for text areas */
@@ -30,8 +29,8 @@ public final class TextAreaPrintStream extends PrintStream {
 
   private final JTextArea textArea;
 
-  public TextAreaPrintStream(JTextArea textArea) throws UnsupportedEncodingException {
-    super(new ByteArrayOutputStream(), false, StandardCharsets.UTF_8.name()); // TODO: replace by Charset in Java 11
+  public TextAreaPrintStream(JTextArea textArea) {
+    super(new ByteArrayOutputStream(), false, StandardCharsets.UTF_8);
     this.baos = (ByteArrayOutputStream) out;
     this.textArea = textArea;
     baos.reset();
@@ -40,9 +39,7 @@ public final class TextAreaPrintStream extends PrintStream {
   @Override
   public void flush() {
     try {
-      textArea.append(baos.toString(StandardCharsets.UTF_8.name())); // TODO: replace by Charset in Java 11
-    } catch (UnsupportedEncodingException e) {
-      setError();
+      textArea.append(baos.toString(StandardCharsets.UTF_8));
     } finally {
       baos.reset();
     }
diff --git a/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java b/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java
index 7d76b8f..6743a93 100644
--- a/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java
+++ b/lucene/luke/src/java/org/apache/lucene/luke/models/analysis/AnalysisImpl.java
@@ -169,7 +169,7 @@ public final class AnalysisImpl implements Analysis {
 
     try {
       Class<? extends Analyzer> clazz = Class.forName(analyzerType).asSubclass(Analyzer.class);
-      this.analyzer = clazz.newInstance();
+      this.analyzer = clazz.getConstructor().newInstance();
       return analyzer;
     } catch (ReflectiveOperationException e) {
       throw new LukeException(String.format(Locale.ENGLISH, "Failed to instantiate class: %s", analyzerType), e);
diff --git a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/AnalysisImplTest.java b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/AnalysisImplTest.java
index 39e8eca..2ce1084 100644
--- a/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/AnalysisImplTest.java
+++ b/lucene/luke/src/test/org/apache/lucene/luke/models/analysis/AnalysisImplTest.java
@@ -41,7 +41,7 @@ public class AnalysisImplTest extends LuceneTestCase {
     Collection<Class<? extends Analyzer>> analyerTypes = analysis.getPresetAnalyzerTypes();
     assertNotNull(analyerTypes);
     for (Class<? extends Analyzer> clazz : analyerTypes) {
-      clazz.newInstance();
+      clazz.getConstructor().newInstance();
     }
   }
 
diff --git a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
index 4337276..b061d51 100644
--- a/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
+++ b/lucene/memory/src/java/org/apache/lucene/index/memory/MemoryIndex.java
@@ -52,7 +52,6 @@ import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.BytesRefHash;
 import org.apache.lucene.util.BytesRefHash.DirectBytesStartArray;
 import org.apache.lucene.util.Counter;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IntBlockPool;
 import org.apache.lucene.util.IntBlockPool.SliceReader;
 import org.apache.lucene.util.IntBlockPool.SliceWriter;
@@ -889,10 +888,10 @@ public class MemoryIndex {
               assert pointValue.bytes.length == pointValue.length : "BytesRef should wrap a precise byte[], BytesRef.deepCopyOf() should take care of this";
               for (int dim = 0; dim < numDimensions; ++dim) {
                 int offset = dim * numBytesPerDimension;
-                if (FutureArrays.compareUnsigned(pointValue.bytes, offset, offset + numBytesPerDimension, minPackedValue, offset, offset + numBytesPerDimension) < 0) {
+                if (Arrays.compareUnsigned(pointValue.bytes, offset, offset + numBytesPerDimension, minPackedValue, offset, offset + numBytesPerDimension) < 0) {
                   System.arraycopy(pointValue.bytes, offset, minPackedValue, offset, numBytesPerDimension);
                 }
-                if (FutureArrays.compareUnsigned(pointValue.bytes, offset, offset + numBytesPerDimension, maxPackedValue, offset, offset + numBytesPerDimension) > 0) {
+                if (Arrays.compareUnsigned(pointValue.bytes, offset, offset + numBytesPerDimension, maxPackedValue, offset, offset + numBytesPerDimension) > 0) {
                   System.arraycopy(pointValue.bytes, offset, maxPackedValue, offset, numBytesPerDimension);
                 }
               }
diff --git a/lucene/misc/src/java/org/apache/lucene/document/InetAddressPoint.java b/lucene/misc/src/java/org/apache/lucene/document/InetAddressPoint.java
index e3d27a9..7316835 100644
--- a/lucene/misc/src/java/org/apache/lucene/document/InetAddressPoint.java
+++ b/lucene/misc/src/java/org/apache/lucene/document/InetAddressPoint.java
@@ -26,7 +26,6 @@ import org.apache.lucene.search.PointInSetQuery;
 import org.apache.lucene.search.PointRangeQuery;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.NumericUtils;
 
 /** 
@@ -280,7 +279,7 @@ public class InetAddressPoint extends Field {
                 new Comparator<byte[]>() {
                   @Override
                   public int compare(byte[] a, byte[] b) {
-                    return FutureArrays.compareUnsigned(a, 0, BYTES, b, 0, BYTES);
+                    return Arrays.compareUnsigned(a, 0, BYTES, b, 0, BYTES);
                   }
                 });
 
diff --git a/lucene/misc/src/java/org/apache/lucene/document/InetAddressRange.java b/lucene/misc/src/java/org/apache/lucene/document/InetAddressRange.java
index 8bde4b3..b530f99 100644
--- a/lucene/misc/src/java/org/apache/lucene/document/InetAddressRange.java
+++ b/lucene/misc/src/java/org/apache/lucene/document/InetAddressRange.java
@@ -17,11 +17,11 @@
 package org.apache.lucene.document;
 
 import java.net.InetAddress;
+import java.util.Arrays;
 
 import org.apache.lucene.document.RangeFieldQuery.QueryType;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 
 /**
  * An indexed InetAddress Range Field
@@ -84,7 +84,7 @@ public class InetAddressRange extends Field {
     final byte[] minEncoded = InetAddressPoint.encode(min);
     final byte[] maxEncoded = InetAddressPoint.encode(max);
     // ensure min is lt max
-    if (FutureArrays.compareUnsigned(minEncoded, 0, BYTES, maxEncoded, 0, BYTES) > 0) {
+    if (Arrays.compareUnsigned(minEncoded, 0, BYTES, maxEncoded, 0, BYTES) > 0) {
       throw new IllegalArgumentException("min value cannot be greater than max value for InetAddressRange field");
     }
     System.arraycopy(minEncoded, 0, bytes, 0, BYTES);
diff --git a/lucene/misc/src/test/org/apache/lucene/search/TestInetAddressRangeQueries.java b/lucene/misc/src/test/org/apache/lucene/search/TestInetAddressRangeQueries.java
index 557ab90..6b301ff 100644
--- a/lucene/misc/src/test/org/apache/lucene/search/TestInetAddressRangeQueries.java
+++ b/lucene/misc/src/test/org/apache/lucene/search/TestInetAddressRangeQueries.java
@@ -22,7 +22,6 @@ import java.util.Arrays;
 
 import org.apache.lucene.document.InetAddressPoint;
 import org.apache.lucene.document.InetAddressRange;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.LuceneTestCase.SuppressCodecs;
 
 /**
@@ -38,7 +37,7 @@ public class TestInetAddressRangeQueries extends BaseRangeFieldQueryTestCase {
     byte[] bMin = InetAddressPoint.encode(min);
     InetAddress max = nextInetaddress();
     byte[] bMax = InetAddressPoint.encode(max);
-    if (FutureArrays.compareUnsigned(bMin, 0, bMin.length, bMax, 0, bMin.length) > 0) {
+    if (Arrays.compareUnsigned(bMin, 0, bMin.length, bMax, 0, bMin.length) > 0) {
       return new IpRange(max, min);
     }
     return new IpRange(min, max);
@@ -142,7 +141,7 @@ public class TestInetAddressRangeQueries extends BaseRangeFieldQueryTestCase {
       InetAddress v = (InetAddress)val;
       byte[] e = InetAddressPoint.encode(v);
 
-      if (FutureArrays.compareUnsigned(min, 0, e.length, e, 0, e.length) < 0) {
+      if (Arrays.compareUnsigned(min, 0, e.length, e, 0, e.length) < 0) {
         max = e;
         maxAddress = v;
       } else {
@@ -161,7 +160,7 @@ public class TestInetAddressRangeQueries extends BaseRangeFieldQueryTestCase {
       InetAddress v = (InetAddress)val;
       byte[] e = InetAddressPoint.encode(v);
 
-      if (FutureArrays.compareUnsigned(max, 0, e.length, e, 0, e.length) > 0) {
+      if (Arrays.compareUnsigned(max, 0, e.length, e, 0, e.length) > 0) {
         min = e;
         minAddress = v;
       } else {
@@ -179,22 +178,22 @@ public class TestInetAddressRangeQueries extends BaseRangeFieldQueryTestCase {
     @Override
     protected boolean isDisjoint(Range o) {
       IpRange other = (IpRange)o;
-      return FutureArrays.compareUnsigned(min, 0, min.length, other.max, 0, min.length) > 0 ||
-          FutureArrays.compareUnsigned(max, 0, max.length, other.min, 0, max.length) < 0;
+      return Arrays.compareUnsigned(min, 0, min.length, other.max, 0, min.length) > 0 ||
+          Arrays.compareUnsigned(max, 0, max.length, other.min, 0, max.length) < 0;
     }
 
     @Override
     protected boolean isWithin(Range o) {
       IpRange other = (IpRange)o;
-      return FutureArrays.compareUnsigned(min, 0, min.length, other.min, 0, min.length) >= 0 &&
-          FutureArrays.compareUnsigned(max, 0, max.length, other.max, 0, max.length) <= 0;
+      return Arrays.compareUnsigned(min, 0, min.length, other.min, 0, min.length) >= 0 &&
+          Arrays.compareUnsigned(max, 0, max.length, other.max, 0, max.length) <= 0;
     }
 
     @Override
     protected boolean contains(Range o) {
       IpRange other = (IpRange)o;
-      return FutureArrays.compareUnsigned(min, 0, min.length, other.min, 0, min.length) <= 0 &&
-          FutureArrays.compareUnsigned(max, 0, max.length, other.max, 0, max.length) >= 0;
+      return Arrays.compareUnsigned(min, 0, min.length, other.min, 0, min.length) <= 0 &&
+          Arrays.compareUnsigned(max, 0, max.length, other.max, 0, max.length) >= 0;
     }
 
     @Override
diff --git a/lucene/module-build.xml b/lucene/module-build.xml
index 0e6e693..e73f0fc 100644
--- a/lucene/module-build.xml
+++ b/lucene/module-build.xml
@@ -34,20 +34,11 @@
   <!-- default classpath refid, can be overridden by contrib's build.xml (use the above base.classpath as basis): -->
   <path id="classpath" refid="base.classpath"/>
   
-  <!-- if we run with Java 9+, we refer to the java9 classes directory and insert this before the main classpath (to "emulate" a MR-JAR): -->
-  <condition property="-test.classpath.java9.addon" value="${build.dir}/classes/java9" else="${build.dir}/classes/java">
-    <and>
-      <not><equals arg1="${build.java.runtime}" arg2="1.8"/></not>
-      <istrue value="${tests.withJava9Patches}"/>
-    </and>
-  </condition>
-  
   <path id="test.base.classpath">
     <pathelement location="${common.dir}/build/test-framework/classes/java"/>
     <pathelement location="${common.dir}/build/codecs/classes/java"/>
     <path refid="classpath"/>
     <path refid="junit-path"/>
-    <pathelement location="${-test.classpath.java9.addon}"/><!-- if it's a duplicate it gets removed by Ant! -->
     <pathelement location="${build.dir}/classes/java"/>
   </path>
 
@@ -92,6 +83,20 @@
            <packageset dir="${src.dir}"/>
         </sources>
       </invoke-javadoc>
+      
+      <!-- fix for Java 11 Javadoc tool that cannot handle split packages between modules correctly (by removing all the packages which are part of lucene-core): -->
+      <!-- problem description: [https://issues.apache.org/jira/browse/LUCENE-8738?focusedCommentId=16818106&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-16818106] -->
+      <local name="element-list-regex"/><!-- contains a regex for all package names which are in lucene-core's javadoc! -->
+      <loadfile property="element-list-regex" srcFile="${javadoc.dir}/core/element-list" encoding="utf-8">
+        <filterchain>
+          <tokenfilter delimoutput="|">
+            <replacestring from="." to="\."/>
+          </tokenfilter>
+        </filterchain>
+      </loadfile>
+      <!--<echo>Regex: ^(${element-list-regex})$</echo>-->
+      <replaceregexp encoding="utf-8" file="${javadoc.dir}/${name}/element-list" byline="true" match="^(${element-list-regex})$" replace=""/>
+      
       <jarify basedir="${javadoc.dir}/${name}" destfile="${build.dir}/${final.name}-javadoc.jar"/>
     </sequential>
   </macrodef>
diff --git a/lucene/sandbox/src/java/org/apache/lucene/geo/Rectangle2D.java b/lucene/sandbox/src/java/org/apache/lucene/geo/Rectangle2D.java
index 3f64608..4e59383 100644
--- a/lucene/sandbox/src/java/org/apache/lucene/geo/Rectangle2D.java
+++ b/lucene/sandbox/src/java/org/apache/lucene/geo/Rectangle2D.java
@@ -20,7 +20,6 @@ package org.apache.lucene.geo;
 import java.util.Arrays;
 
 import org.apache.lucene.index.PointValues;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.NumericUtils;
 
 import static java.lang.Integer.BYTES;
@@ -162,17 +161,17 @@ public class Rectangle2D {
                                                             int minXOffset, int minYOffset, byte[] minTriangle,
                                                             int maxXOffset, int maxYOffset, byte[] maxTriangle) {
     // check bounding box (DISJOINT)
-    if (FutureArrays.compareUnsigned(minTriangle, minXOffset, minXOffset + BYTES, bbox, 3 * BYTES, 4 * BYTES) > 0 ||
-        FutureArrays.compareUnsigned(maxTriangle, maxXOffset, maxXOffset + BYTES, bbox, BYTES, 2 * BYTES) < 0 ||
-        FutureArrays.compareUnsigned(minTriangle, minYOffset, minYOffset + BYTES, bbox, 2 * BYTES, 3 * BYTES) > 0 ||
-        FutureArrays.compareUnsigned(maxTriangle, maxYOffset, maxYOffset + BYTES, bbox, 0, BYTES) < 0) {
+    if (Arrays.compareUnsigned(minTriangle, minXOffset, minXOffset + BYTES, bbox, 3 * BYTES, 4 * BYTES) > 0 ||
+        Arrays.compareUnsigned(maxTriangle, maxXOffset, maxXOffset + BYTES, bbox, BYTES, 2 * BYTES) < 0 ||
+        Arrays.compareUnsigned(minTriangle, minYOffset, minYOffset + BYTES, bbox, 2 * BYTES, 3 * BYTES) > 0 ||
+        Arrays.compareUnsigned(maxTriangle, maxYOffset, maxYOffset + BYTES, bbox, 0, BYTES) < 0) {
       return PointValues.Relation.CELL_OUTSIDE_QUERY;
     }
 
-    if (FutureArrays.compareUnsigned(minTriangle, minXOffset, minXOffset + BYTES, bbox, BYTES, 2 * BYTES) >= 0 &&
-        FutureArrays.compareUnsigned(maxTriangle, maxXOffset, maxXOffset + BYTES, bbox, 3 * BYTES, 4 * BYTES) <= 0 &&
-        FutureArrays.compareUnsigned(minTriangle, minYOffset, minYOffset + BYTES, bbox, 0, BYTES) >= 0 &&
-        FutureArrays.compareUnsigned(maxTriangle, maxYOffset, maxYOffset + BYTES, bbox, 2 * BYTES, 3 * BYTES) <= 0) {
+    if (Arrays.compareUnsigned(minTriangle, minXOffset, minXOffset + BYTES, bbox, BYTES, 2 * BYTES) >= 0 &&
+        Arrays.compareUnsigned(maxTriangle, maxXOffset, maxXOffset + BYTES, bbox, 3 * BYTES, 4 * BYTES) <= 0 &&
+        Arrays.compareUnsigned(minTriangle, minYOffset, minYOffset + BYTES, bbox, 0, BYTES) >= 0 &&
+        Arrays.compareUnsigned(maxTriangle, maxYOffset, maxYOffset + BYTES, bbox, 2 * BYTES, 3 * BYTES) <= 0) {
       return PointValues.Relation.CELL_INSIDE_QUERY;
     }
     return PointValues.Relation.CELL_CROSSES_QUERY;
diff --git a/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java b/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
index 5a03141..710a982 100644
--- a/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
+++ b/lucene/sandbox/src/test/org/apache/lucene/document/TestHalfFloatPoint.java
@@ -23,7 +23,6 @@ import org.apache.lucene.index.RandomIndexWriter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.ArrayUtil;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.TestUtil;
 
@@ -161,7 +160,7 @@ public class TestHalfFloatPoint extends LuceneTestCase {
       HalfFloatPoint.shortToSortableBytes((short) (i - 1), previous, 0);
       byte[] current = new byte[HalfFloatPoint.BYTES];
       HalfFloatPoint.shortToSortableBytes((short) i, current, 0);
-      assertTrue(FutureArrays.compareUnsigned(previous, 0, HalfFloatPoint.BYTES, current, 0, HalfFloatPoint.BYTES) < 0);
+      assertTrue(Arrays.compareUnsigned(previous, 0, HalfFloatPoint.BYTES, current, 0, HalfFloatPoint.BYTES) < 0);
       assertEquals(i, HalfFloatPoint.sortableBytesToShort(current, 0));
     }
   }
diff --git a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
index d88e41a..424e482 100644
--- a/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
+++ b/lucene/spatial-extras/src/java/org/apache/lucene/spatial/prefix/tree/SpatialPrefixTreeFactory.java
@@ -59,7 +59,7 @@ public abstract class SpatialPrefixTreeFactory {
     else {
       try {
         Class<?> c = classLoader.loadClass(cname);
-        instance = (SpatialPrefixTreeFactory) c.newInstance();
+        instance = (SpatialPrefixTreeFactory) c.getConstructor().newInstance();
       } catch (Exception e) {
         throw new RuntimeException(e);
       }
diff --git a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
index 66fa3cd..95bfc8a 100644
--- a/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
+++ b/lucene/spatial3d/src/test/org/apache/lucene/spatial3d/TestGeo3DPoint.java
@@ -75,7 +75,6 @@ import org.apache.lucene.spatial3d.geom.XYZSolidFactory;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.NumericUtils;
@@ -1437,11 +1436,11 @@ public class TestGeo3DPoint extends LuceneTestCase {
         for(int dim=0;dim<numDims;dim++) {
           int offset = bytesPerDim * dim;
           // other.min < this.min?
-          if (FutureArrays.compareUnsigned(other.minPackedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+          if (Arrays.compareUnsigned(other.minPackedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
             return false;
           }
           // other.max < this.max?
-          if (FutureArrays.compareUnsigned(other.maxPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+          if (Arrays.compareUnsigned(other.maxPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
             return false;
           }
         }
diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/LookupBenchmarkTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/LookupBenchmarkTest.java
index 12c6416..7e01256 100644
--- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/LookupBenchmarkTest.java
+++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/LookupBenchmarkTest.java
@@ -163,7 +163,7 @@ public class LookupBenchmarkTest extends LuceneTestCase {
   private Lookup buildLookup(Class<? extends Lookup> cls, Input[] input) throws Exception {
     Lookup lookup = null;
     try {
-      lookup = cls.newInstance();
+      lookup = cls.getConstructor().newInstance();
     } catch (InstantiationException e) {
       Analyzer a = new MockAnalyzer(random, MockTokenizer.KEYWORD, false);
       if (cls == AnalyzingInfixSuggester.class || cls == BlendedInfixSuggester.class) {
diff --git a/lucene/suggest/src/test/org/apache/lucene/search/suggest/PersistenceTest.java b/lucene/suggest/src/test/org/apache/lucene/search/suggest/PersistenceTest.java
index a4a9d21..fd5b558 100644
--- a/lucene/suggest/src/test/org/apache/lucene/search/suggest/PersistenceTest.java
+++ b/lucene/suggest/src/test/org/apache/lucene/search/suggest/PersistenceTest.java
@@ -73,7 +73,7 @@ public class PersistenceTest extends LuceneTestCase {
     } else if (lookupClass == FSTCompletionLookup.class) {
       lookup = new FSTCompletionLookup(tempDir, "suggest");
     } else {
-      lookup = lookupClass.newInstance();
+      lookup = lookupClass.getConstructor().newInstance();
     }
     Input[] keys = new Input[this.keys.length];
     for (int i = 0; i < keys.length; i++)
@@ -85,7 +85,7 @@ public class PersistenceTest extends LuceneTestCase {
     lookup.store(Files.newOutputStream(storeDir.resolve("lookup.dat")));
 
     // Re-read it from disk.
-    lookup = lookupClass.newInstance();
+    lookup = lookupClass.getConstructor().newInstance();
     lookup.load(Files.newInputStream(storeDir.resolve("lookup.dat")));
 
     // Assert validity.
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java b/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
index 96c5ee2..fe6024c 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/AssertingLeafReader.java
@@ -17,6 +17,7 @@
 package org.apache.lucene.index;
 
 import java.io.IOException;
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
@@ -26,7 +27,6 @@ import org.apache.lucene.index.PointValues.Relation;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.VirtualMethod;
 import org.apache.lucene.util.automaton.CompiledAutomaton;
 
@@ -1149,14 +1149,14 @@ public class AssertingLeafReader extends FilterLeafReader {
 
       // This doc's packed value should be contained in the last cell passed to compare:
       for(int dim=0;dim<numIndexDims;dim++) {
-        assert FutureArrays.compareUnsigned(lastMinPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, packedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) <= 0: "dim=" + dim + " of " +  numDataDims + " value=" + new BytesRef(packedValue);
-        assert FutureArrays.compareUnsigned(lastMaxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, packedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) >= 0: "dim=" + dim + " of " +  numDataDims + " value=" + new BytesRef(packedValue);
+        assert Arrays.compareUnsigned(lastMinPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, packedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) <= 0: "dim=" + dim + " of " +  numDataDims + " value=" + new BytesRef(packedValue);
+        assert Arrays.compareUnsigned(lastMaxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, packedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) >= 0: "dim=" + dim + " of " +  numDataDims + " value=" + new BytesRef(packedValue);
       }
 
       // TODO: we should assert that this "matches" whatever relation the last call to compare had returned
       assert packedValue.length == numDataDims * bytesPerDim;
       if (numDataDims == 1) {
-        int cmp = FutureArrays.compareUnsigned(lastDocValue, 0, bytesPerDim, packedValue, 0, bytesPerDim);
+        int cmp = Arrays.compareUnsigned(lastDocValue, 0, bytesPerDim, packedValue, 0, bytesPerDim);
         if (cmp < 0) {
           // ok
         } else if (cmp == 0) {
@@ -1180,7 +1180,7 @@ public class AssertingLeafReader extends FilterLeafReader {
     @Override
     public Relation compare(byte[] minPackedValue, byte[] maxPackedValue) {
       for(int dim=0;dim<numIndexDims;dim++) {
-        assert FutureArrays.compareUnsigned(minPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, maxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) <= 0;
+        assert Arrays.compareUnsigned(minPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim, maxPackedValue, dim * bytesPerDim, dim * bytesPerDim + bytesPerDim) <= 0;
       }
       System.arraycopy(maxPackedValue, 0, lastMaxPackedValue, 0, numIndexDims*bytesPerDim);
       System.arraycopy(minPackedValue, 0, lastMinPackedValue, 0, numIndexDims*bytesPerDim);
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/BasePointsFormatTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/index/BasePointsFormatTestCase.java
index 49ada73..c5798df 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/BasePointsFormatTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/BasePointsFormatTestCase.java
@@ -39,7 +39,6 @@ import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.util.Bits;
 import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.lucene.util.IOUtils;
 import org.apache.lucene.util.NumericUtils;
 import org.apache.lucene.util.Rethrow;
@@ -609,10 +608,10 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
           System.arraycopy(docValues[ord][dim], 0, expectedMaxValues[dim], 0, numBytesPerDim);
         } else {
           // TODO: it's cheating that we use StringHelper.compare for "truth": what if it's buggy?
-          if (FutureArrays.compareUnsigned(docValues[ord][dim], 0, numBytesPerDim, expectedMinValues[dim], 0, numBytesPerDim) < 0) {
+          if (Arrays.compareUnsigned(docValues[ord][dim], 0, numBytesPerDim, expectedMinValues[dim], 0, numBytesPerDim) < 0) {
             System.arraycopy(docValues[ord][dim], 0, expectedMinValues[dim], 0, numBytesPerDim);
           }
-          if (FutureArrays.compareUnsigned(docValues[ord][dim], 0, numBytesPerDim, expectedMaxValues[dim], 0, numBytesPerDim) > 0) {
+          if (Arrays.compareUnsigned(docValues[ord][dim], 0, numBytesPerDim, expectedMaxValues[dim], 0, numBytesPerDim) > 0) {
             System.arraycopy(docValues[ord][dim], 0, expectedMaxValues[dim], 0, numBytesPerDim);
           }
         }
@@ -773,10 +772,10 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
         byte[] leafMinValues = dimValues.getMinPackedValue();
         byte[] leafMaxValues = dimValues.getMaxPackedValue();
         for(int dim=0;dim<numIndexDims;dim++) {
-          if (FutureArrays.compareUnsigned(leafMinValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, minValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim) < 0) {
+          if (Arrays.compareUnsigned(leafMinValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, minValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim) < 0) {
             System.arraycopy(leafMinValues, dim*numBytesPerDim, minValues, dim*numBytesPerDim, numBytesPerDim);
           }
-          if (FutureArrays.compareUnsigned(leafMaxValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, maxValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim) > 0) {
+          if (Arrays.compareUnsigned(leafMaxValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, maxValues, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim) > 0) {
             System.arraycopy(leafMaxValues, dim*numBytesPerDim, maxValues, dim*numBytesPerDim, numBytesPerDim);
           }
         }
@@ -806,7 +805,7 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
           random().nextBytes(queryMin[dim]);
           queryMax[dim] = new byte[numBytesPerDim];
           random().nextBytes(queryMax[dim]);
-          if (FutureArrays.compareUnsigned(queryMin[dim], 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+          if (Arrays.compareUnsigned(queryMin[dim], 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
             byte[] x = queryMin[dim];
             queryMin[dim] = queryMax[dim];
             queryMax[dim] = x;
@@ -846,8 +845,8 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
 
                 for(int dim=0;dim<numIndexDims;dim++) {
                   //System.out.println("  dim=" + dim + " value=" + new BytesRef(packedValue, dim*numBytesPerDim, numBytesPerDim));
-                  if (FutureArrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                      FutureArrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                  if (Arrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                      Arrays.compareUnsigned(packedValue, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                     //System.out.println("  no");
                     return;
                   }
@@ -862,12 +861,12 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
                 boolean crosses = false;
                 //System.out.println("compare");
                 for(int dim=0;dim<numIndexDims;dim++) {
-                  if (FutureArrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                      FutureArrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                  if (Arrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                      Arrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                     //System.out.println("  query_outside_cell");
                     return Relation.CELL_OUTSIDE_QUERY;
-                  } else if (FutureArrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                             FutureArrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+                  } else if (Arrays.compareUnsigned(minPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                             Arrays.compareUnsigned(maxPacked, dim * numBytesPerDim, dim * numBytesPerDim + numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
                     crosses = true;
                   }
                 }
@@ -888,8 +887,8 @@ public abstract class BasePointsFormatTestCase extends BaseIndexFileFormatTestCa
           boolean matches = true;
           for(int dim=0;dim<numIndexDims;dim++) {
             byte[] x = docValues[ord][dim];
-            if (FutureArrays.compareUnsigned(x, 0, numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
-                FutureArrays.compareUnsigned(x, 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
+            if (Arrays.compareUnsigned(x, 0, numBytesPerDim, queryMin[dim], 0, numBytesPerDim) < 0 ||
+                Arrays.compareUnsigned(x, 0, numBytesPerDim, queryMax[dim], 0, numBytesPerDim) > 0) {
               matches = false;
               break;
             }
diff --git a/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java b/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
index af11219..5f3535d 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/index/PointsStackTracker.java
@@ -18,10 +18,10 @@
 package org.apache.lucene.index;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import org.apache.lucene.index.PointValues.IntersectVisitor;
-import org.apache.lucene.util.FutureArrays;
 
 /** Simple utility class to track the current BKD stack based solely on calls to {@link IntersectVisitor#compare}. */
 public class PointsStackTracker {
@@ -44,11 +44,11 @@ public class PointsStackTracker {
       for(int dim=0;dim<numDims;dim++) {
         int offset = dim * bytesPerDim;
         // other.min < min?
-        if (FutureArrays.compareUnsigned(other.minPackedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
+        if (Arrays.compareUnsigned(other.minPackedValue, offset, offset + bytesPerDim, minPackedValue, offset, offset + bytesPerDim) < 0) {
           return false;
         }
         // other.max > max?
-        if (FutureArrays.compareUnsigned(other.maxPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
+        if (Arrays.compareUnsigned(other.maxPackedValue, offset, offset + bytesPerDim, maxPackedValue, offset, offset + bytesPerDim) > 0) {
           return false;
         }
       }
diff --git a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
index eeb0906..6aa6f03 100644
--- a/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
+++ b/lucene/test-framework/src/java/org/apache/lucene/util/LuceneTestCase.java
@@ -1658,7 +1658,7 @@ public abstract class LuceneTestCase extends Assert {
       }
 
       // try empty ctor
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       Rethrow.rethrow(e);
       throw null; // dummy to prevent compiler failure
diff --git a/lucene/tools/javadoc/java11/package-list b/lucene/tools/javadoc/java11/package-list
new file mode 100644
index 0000000..4cfabf8
--- /dev/null
+++ b/lucene/tools/javadoc/java11/package-list
@@ -0,0 +1,282 @@
+module:java.base
+java.io
+java.lang
+java.lang.annotation
+java.lang.invoke
+java.lang.module
+java.lang.ref
+java.lang.reflect
+java.math
+java.net
+java.net.spi
+java.nio
+java.nio.channels
+java.nio.channels.spi
+java.nio.charset
+java.nio.charset.spi
+java.nio.file
+java.nio.file.attribute
+java.nio.file.spi
+java.security
+java.security.acl
+java.security.cert
+java.security.interfaces
+java.security.spec
+java.text
+java.text.spi
+java.time
+java.time.chrono
+java.time.format
+java.time.temporal
+java.time.zone
+java.util
+java.util.concurrent
+java.util.concurrent.atomic
+java.util.concurrent.locks
+java.util.function
+java.util.jar
+java.util.regex
+java.util.spi
+java.util.stream
+java.util.zip
+javax.crypto
+javax.crypto.interfaces
+javax.crypto.spec
+javax.net
+javax.net.ssl
+javax.security.auth
+javax.security.auth.callback
+javax.security.auth.login
+javax.security.auth.spi
+javax.security.auth.x500
+javax.security.cert
+module:java.compiler
+javax.annotation.processing
+javax.lang.model
+javax.lang.model.element
+javax.lang.model.type
+javax.lang.model.util
+javax.tools
+module:java.datatransfer
+java.awt.datatransfer
+module:java.desktop
+java.applet
+java.awt
+java.awt.color
+java.awt.desktop
+java.awt.dnd
+java.awt.event
+java.awt.font
+java.awt.geom
+java.awt.im
+java.awt.im.spi
+java.awt.image
+java.awt.image.renderable
+java.awt.print
+java.beans
+java.beans.beancontext
+javax.accessibility
+javax.imageio
+javax.imageio.event
+javax.imageio.metadata
+javax.imageio.plugins.bmp
+javax.imageio.plugins.jpeg
+javax.imageio.plugins.tiff
+javax.imageio.spi
+javax.imageio.stream
+javax.print
+javax.print.attribute
+javax.print.attribute.standard
+javax.print.event
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.swing
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.metal
+javax.swing.plaf.multi
+javax.swing.plaf.nimbus
+javax.swing.plaf.synth
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.tree
+javax.swing.undo
+module:java.instrument
+java.lang.instrument
+module:java.logging
+java.util.logging
+module:java.management
+java.lang.management
+javax.management
+javax.management.loading
+javax.management.modelmbean
+javax.management.monitor
+javax.management.openmbean
+javax.management.relation
+javax.management.remote
+javax.management.timer
+module:java.management.rmi
+javax.management.remote.rmi
+module:java.naming
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+module:java.net.http
+java.net.http
+module:java.prefs
+java.util.prefs
+module:java.rmi
+java.rmi
+java.rmi.activation
+java.rmi.dgc
+java.rmi.registry
+java.rmi.server
+javax.rmi.ssl
+module:java.scripting
+javax.script
+module:java.se
+module:java.security.jgss
+javax.security.auth.kerberos
+org.ietf.jgss
+module:java.security.sasl
+javax.security.sasl
+module:java.smartcardio
+javax.smartcardio
+module:java.sql
+java.sql
+javax.sql
+module:java.sql.rowset
+javax.sql.rowset
+javax.sql.rowset.serial
+javax.sql.rowset.spi
+module:java.transaction.xa
+javax.transaction.xa
+module:java.xml
+javax.xml
+javax.xml.catalog
+javax.xml.datatype
+javax.xml.namespace
+javax.xml.parsers
+javax.xml.stream
+javax.xml.stream.events
+javax.xml.stream.util
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stax
+javax.xml.transform.stream
+javax.xml.validation
+javax.xml.xpath
+org.w3c.dom
+org.w3c.dom.bootstrap
+org.w3c.dom.events
+org.w3c.dom.ls
+org.w3c.dom.ranges
+org.w3c.dom.traversal
+org.w3c.dom.views
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
+module:java.xml.crypto
+javax.xml.crypto
+javax.xml.crypto.dom
+javax.xml.crypto.dsig
+javax.xml.crypto.dsig.dom
+javax.xml.crypto.dsig.keyinfo
+javax.xml.crypto.dsig.spec
+module:jdk.accessibility
+com.sun.java.accessibility.util
+module:jdk.attach
+com.sun.tools.attach
+com.sun.tools.attach.spi
+module:jdk.charsets
+module:jdk.compiler
+com.sun.source.doctree
+com.sun.source.tree
+com.sun.source.util
+com.sun.tools.javac
+module:jdk.crypto.cryptoki
+module:jdk.crypto.ec
+module:jdk.dynalink
+jdk.dynalink
+jdk.dynalink.beans
+jdk.dynalink.linker
+jdk.dynalink.linker.support
+jdk.dynalink.support
+module:jdk.editpad
+module:jdk.hotspot.agent
+module:jdk.httpserver
+com.sun.net.httpserver
+com.sun.net.httpserver.spi
+module:jdk.jartool
+com.sun.jarsigner
+jdk.security.jarsigner
+module:jdk.javadoc
+com.sun.javadoc
+com.sun.tools.javadoc
+jdk.javadoc.doclet
+module:jdk.jcmd
+module:jdk.jconsole
+com.sun.tools.jconsole
+module:jdk.jdeps
+module:jdk.jdi
+com.sun.jdi
+com.sun.jdi.connect
+com.sun.jdi.connect.spi
+com.sun.jdi.event
+com.sun.jdi.request
+module:jdk.jdwp.agent
+module:jdk.jfr
+jdk.jfr
+jdk.jfr.consumer
+module:jdk.jlink
+module:jdk.jshell
+jdk.jshell
+jdk.jshell.execution
+jdk.jshell.spi
+jdk.jshell.tool
+module:jdk.jsobject
+netscape.javascript
+module:jdk.jstatd
+module:jdk.localedata
+module:jdk.management
+com.sun.management
+module:jdk.management.agent
+module:jdk.management.jfr
+jdk.management.jfr
+module:jdk.naming.dns
+module:jdk.naming.rmi
+module:jdk.net
+jdk.net
+jdk.nio
+module:jdk.pack
+module:jdk.rmic
+module:jdk.scripting.nashorn
+jdk.nashorn.api.scripting
+jdk.nashorn.api.tree
+module:jdk.sctp
+com.sun.nio.sctp
+module:jdk.security.auth
+com.sun.security.auth
+com.sun.security.auth.callback
+com.sun.security.auth.login
+com.sun.security.auth.module
+module:jdk.security.jgss
+com.sun.security.jgss
+module:jdk.xml.dom
+org.w3c.dom.css
+org.w3c.dom.html
+org.w3c.dom.stylesheets
+org.w3c.dom.xpath
+module:jdk.zipfs
diff --git a/lucene/tools/javadoc/java8/package-list b/lucene/tools/javadoc/java8/package-list
deleted file mode 100644
index 351c186..0000000
--- a/lucene/tools/javadoc/java8/package-list
+++ /dev/null
@@ -1,217 +0,0 @@
-java.applet
-java.awt
-java.awt.color
-java.awt.datatransfer
-java.awt.dnd
-java.awt.event
-java.awt.font
-java.awt.geom
-java.awt.im
-java.awt.im.spi
-java.awt.image
-java.awt.image.renderable
-java.awt.print
-java.beans
-java.beans.beancontext
-java.io
-java.lang
-java.lang.annotation
-java.lang.instrument
-java.lang.invoke
-java.lang.management
-java.lang.ref
-java.lang.reflect
-java.math
-java.net
-java.nio
-java.nio.channels
-java.nio.channels.spi
-java.nio.charset
-java.nio.charset.spi
-java.nio.file
-java.nio.file.attribute
-java.nio.file.spi
-java.rmi
-java.rmi.activation
-java.rmi.dgc
-java.rmi.registry
-java.rmi.server
-java.security
-java.security.acl
-java.security.cert
-java.security.interfaces
-java.security.spec
-java.sql
-java.text
-java.text.spi
-java.time
-java.time.chrono
-java.time.format
-java.time.temporal
-java.time.zone
-java.util
-java.util.concurrent
-java.util.concurrent.atomic
-java.util.concurrent.locks
-java.util.function
-java.util.jar
-java.util.logging
-java.util.prefs
-java.util.regex
-java.util.spi
-java.util.stream
-java.util.zip
-javax.accessibility
-javax.activation
-javax.activity
-javax.annotation
-javax.annotation.processing
-javax.crypto
-javax.crypto.interfaces
-javax.crypto.spec
-javax.imageio
-javax.imageio.event
-javax.imageio.metadata
-javax.imageio.plugins.bmp
-javax.imageio.plugins.jpeg
-javax.imageio.spi
-javax.imageio.stream
-javax.jws
-javax.jws.soap
-javax.lang.model
-javax.lang.model.element
-javax.lang.model.type
-javax.lang.model.util
-javax.management
-javax.management.loading
-javax.management.modelmbean
-javax.management.monitor
-javax.management.openmbean
-javax.management.relation
-javax.management.remote
-javax.management.remote.rmi
-javax.management.timer
-javax.naming
-javax.naming.directory
-javax.naming.event
-javax.naming.ldap
-javax.naming.spi
-javax.net
-javax.net.ssl
-javax.print
-javax.print.attribute
-javax.print.attribute.standard
-javax.print.event
-javax.rmi
-javax.rmi.CORBA
-javax.rmi.ssl
-javax.script
-javax.security.auth
-javax.security.auth.callback
-javax.security.auth.kerberos
-javax.security.auth.login
-javax.security.auth.spi
-javax.security.auth.x500
-javax.security.cert
-javax.security.sasl
-javax.sound.midi
-javax.sound.midi.spi
-javax.sound.sampled
-javax.sound.sampled.spi
-javax.sql
-javax.sql.rowset
-javax.sql.rowset.serial
-javax.sql.rowset.spi
-javax.swing
-javax.swing.border
-javax.swing.colorchooser
-javax.swing.event
-javax.swing.filechooser
-javax.swing.plaf
-javax.swing.plaf.basic
-javax.swing.plaf.metal
-javax.swing.plaf.multi
-javax.swing.plaf.nimbus
-javax.swing.plaf.synth
-javax.swing.table
-javax.swing.text
-javax.swing.text.html
-javax.swing.text.html.parser
-javax.swing.text.rtf
-javax.swing.tree
-javax.swing.undo
-javax.tools
-javax.transaction
-javax.transaction.xa
-javax.xml
-javax.xml.bind
-javax.xml.bind.annotation
-javax.xml.bind.annotation.adapters
-javax.xml.bind.attachment
-javax.xml.bind.helpers
-javax.xml.bind.util
-javax.xml.crypto
-javax.xml.crypto.dom
-javax.xml.crypto.dsig
-javax.xml.crypto.dsig.dom
-javax.xml.crypto.dsig.keyinfo
-javax.xml.crypto.dsig.spec
-javax.xml.datatype
-javax.xml.namespace
-javax.xml.parsers
-javax.xml.soap
-javax.xml.stream
-javax.xml.stream.events
-javax.xml.stream.util
-javax.xml.transform
-javax.xml.transform.dom
-javax.xml.transform.sax
-javax.xml.transform.stax
-javax.xml.transform.stream
-javax.xml.validation
-javax.xml.ws
-javax.xml.ws.handler
-javax.xml.ws.handler.soap
-javax.xml.ws.http
-javax.xml.ws.soap
-javax.xml.ws.spi
-javax.xml.ws.spi.http
-javax.xml.ws.wsaddressing
-javax.xml.xpath
-org.ietf.jgss
-org.omg.CORBA
-org.omg.CORBA.DynAnyPackage
-org.omg.CORBA.ORBPackage
-org.omg.CORBA.TypeCodePackage
-org.omg.CORBA.portable
-org.omg.CORBA_2_3
-org.omg.CORBA_2_3.portable
-org.omg.CosNaming
-org.omg.CosNaming.NamingContextExtPackage
-org.omg.CosNaming.NamingContextPackage
-org.omg.Dynamic
-org.omg.DynamicAny
-org.omg.DynamicAny.DynAnyFactoryPackage
-org.omg.DynamicAny.DynAnyPackage
-org.omg.IOP
-org.omg.IOP.CodecFactoryPackage
-org.omg.IOP.CodecPackage
-org.omg.Messaging
-org.omg.PortableInterceptor
-org.omg.PortableInterceptor.ORBInitInfoPackage
-org.omg.PortableServer
-org.omg.PortableServer.CurrentPackage
-org.omg.PortableServer.POAManagerPackage
-org.omg.PortableServer.POAPackage
-org.omg.PortableServer.ServantLocatorPackage
-org.omg.PortableServer.portable
-org.omg.SendingContext
-org.omg.stub.java.rmi
-org.w3c.dom
-org.w3c.dom.bootstrap
-org.w3c.dom.events
-org.w3c.dom.ls
-org.w3c.dom.views
-org.xml.sax
-org.xml.sax.ext
-org.xml.sax.helpers
diff --git a/lucene/tools/src/groovy/patch-mrjar-classes.groovy b/lucene/tools/src/groovy/patch-mrjar-classes.groovy
deleted file mode 100644
index 1ba6a98..0000000
--- a/lucene/tools/src/groovy/patch-mrjar-classes.groovy
+++ /dev/null
@@ -1,83 +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.
- */
-
-/** Task script that is called by Ant's common-build.xml file:
- * Patches Java 8 class files to replace method signatures by
- * native Java 9 optimized ones (to be placed in MR-JAR).
- */
-
-import org.apache.tools.ant.Project;
-
-import org.objectweb.asm.ClassReader;
-import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.commons.ClassRemapper;
-import org.objectweb.asm.commons.Remapper;
-
-def mappings = [
-  'org/apache/lucene/util/FutureObjects': 'java/util/Objects',
-  'org/apache/lucene/util/FutureArrays': 'java/util/Arrays',
-];
-
-if (properties['run.clover'] != null) {
-  task.log("Disabled class file remapping for Java 9, because Clover code coverage is enabled.", Project.MSG_INFO);
-  return;
-}
-
-File inputDir = new File(properties['build.dir'], 'classes/java');
-File outputDir = new File(properties['build.dir'], 'classes/java9');
-
-outputDir.mkdirs();
-
-def scanner = ant.fileScanner {
-  fileset(dir:inputDir) {
-    include(name:"**/*.class")
-  }
-}
-
-int count = 0;
-for (f in scanner) {
-  ClassReader reader = new ClassReader(f.getBytes());
-  if (mappings.containsKey(reader.className)) {
-    // we do not remap our replacements! :-)
-    continue;
-  }
-
-  ClassWriter writer = new ClassWriter(0 /* no recalculations needed */);  
-  boolean remapped = false;
-  ClassRemapper remapper = new ClassRemapper(writer, new Remapper() {
-    @Override
-    public String map(String typeName) {
-      if (mappings.containsKey(typeName)) {
-        remapped = true;
-        return mappings.get(typeName);
-      }
-      return typeName;
-    }
-  });
-  
-  reader.accept(remapper, 0 /* keep everything as-is*/);
-  
-  if (remapped) {
-    task.log("Remapped: "+reader.className, Project.MSG_INFO);
-    File output = new File(outputDir, reader.className + '.class');
-    output.parentFile.mkdirs();
-    output.setBytes(writer.toByteArray());
-    count++;
-  }
-}
-
-task.log("Remapped $count class files for Java 9 to: $outputDir", Project.MSG_INFO);
diff --git a/lucene/tools/src/groovy/run-maven-build.groovy b/lucene/tools/src/groovy/run-maven-build.groovy
index c26c7bf..e241837 100644
--- a/lucene/tools/src/groovy/run-maven-build.groovy
+++ b/lucene/tools/src/groovy/run-maven-build.groovy
@@ -43,6 +43,7 @@ def artifact = NamespaceBuilder.newInstance(ant, 'antlib:org.apache.maven.artifa
 
 task.log('Running Maven with props: ' + cmdlineProps.toString(), Project.MSG_INFO);
 artifact.mvn(pom: properties['maven-build-dir']+'/pom.xml', mavenVersion: properties['maven-version'], failonerror: true, fork: true) {
+  sysproperty(key: 'maven.multiModuleProjectDirectory', file: properties['maven-build-dir'])
   cmdlineProps.each{ k, v -> arg(value: '-D' + k + '=' + v) };
   arg(value: '-fae');
   arg(value: 'install');
diff --git a/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java b/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java
index 02c9e9d..2b89703 100644
--- a/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java
+++ b/lucene/tools/src/java/org/apache/lucene/validation/LibVersionsCheckTask.java
@@ -35,11 +35,14 @@ import org.apache.tools.ant.types.resources.Resources;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
 import org.xml.sax.helpers.DefaultHandler;
-import org.xml.sax.helpers.XMLReaderFactory;
 
+import javax.xml.XMLConstants;
 import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
@@ -92,6 +95,14 @@ public class LibVersionsCheckTask extends Task {
   private static final Pattern MODULE_NAME_PATTERN = Pattern.compile("\\smodule\\s*=\\s*[\"']([^\"']+)[\"']");
   private static final Pattern MODULE_DIRECTORY_PATTERN 
       = Pattern.compile(".*[/\\\\]((?:lucene|solr)[/\\\\].*)[/\\\\].*");
+  private static final SAXParserFactory SAX_PARSER_FACTORY = SAXParserFactory.newDefaultInstance();
+  static {
+    try {
+      SAX_PARSER_FACTORY.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+    } catch (SAXNotRecognizedException | SAXNotSupportedException | ParserConfigurationException e) {
+      throw new Error(e);
+    }
+  }
   private Ivy ivy;
 
   /**
@@ -825,11 +836,9 @@ public class LibVersionsCheckTask extends Task {
   private boolean checkIvyXmlFile(File ivyXmlFile)
       throws ParserConfigurationException, SAXException, IOException {
     log("Scanning: " + ivyXmlFile.getPath(), verboseLevel);
-    XMLReader xmlReader = XMLReaderFactory.createXMLReader();
+    SAXParser xmlReader = SAX_PARSER_FACTORY.newSAXParser();
     DependencyRevChecker revChecker = new DependencyRevChecker(ivyXmlFile); 
-    xmlReader.setContentHandler(revChecker);
-    xmlReader.setErrorHandler(revChecker);
-    xmlReader.parse(new InputSource(ivyXmlFile.getAbsolutePath()));
+    xmlReader.parse(new InputSource(ivyXmlFile.getAbsolutePath()), revChecker);
     return ! revChecker.fail;
   }
 
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 16f0432..3871b18 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -48,6 +48,12 @@ Upgrade Notes
 * SOLR-13323: The unused package org.apache.solr.internal.csv.writer and associated classes/tests that were easily
   confused with but not used by org.apache.solr.response.CSVWriter (or any other code) have been removed (Gus Heck)
 
+* LUCENE-8738: Du to the change to Java 11 as a minimum version, TransientSolrCoreCache no longer extends
+  the java.util.Observable, which was deprecated in Java 9. The implementation was therefore replaced by a more
+  type-safe implementation. If a plugin implemented its own TransientSolrCoreCache, the implementation needs
+  to be changed to call the new methods for registering/deregistering listener and notify them.
+  (Uwe Schindler, Erick Erickson, Adrien Grand)
+
 New Features
 ----------------------
 * SOLR-13131: Category Routed Aliases are now available for data driven assignment of documents to collections based on
diff --git a/solr/common-build.xml b/solr/common-build.xml
index 3dfafdc..d6a4827 100644
--- a/solr/common-build.xml
+++ b/solr/common-build.xml
@@ -24,9 +24,9 @@
   <dirname file="${ant.file.common-solr}" property="common-solr.dir"/>
 
   <property name="Name" value="Solr" />
-
-  <!-- solr uses Java 8 -->
-  <property name="javac.release" value="8"/>
+  
+  <!-- solr uses Java 11 -->
+  <property name="javac.release" value="11"/>
   <property name="javac.args" value="-Xlint:-deprecation"/>
   <property name="javac.profile.args" value=""/>
 
@@ -556,7 +556,4 @@
   <target name="test" unless="tests.disable-solr">
     <antcall target="common.test" inheritrefs="true" inheritall="true"/>
   </target>
-
-  <!-- In Solr we do not generate MR-JARs yet; disable completely so we do not accidentally patch -->
-  <target name="patch-mrjar-classes"/>
 </project>
diff --git a/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/LuceneCarrot2StemmerFactory.java b/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/LuceneCarrot2StemmerFactory.java
index 4065e41..1ebd1fc 100644
--- a/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/LuceneCarrot2StemmerFactory.java
+++ b/solr/contrib/clustering/src/java/org/apache/solr/handler/clustering/carrot2/LuceneCarrot2StemmerFactory.java
@@ -143,7 +143,7 @@ public class LuceneCarrot2StemmerFactory implements IStemmerFactory {
       }
 
       try {
-        return new SnowballStemmerAdapter(stemmerClazz.newInstance());
+        return new SnowballStemmerAdapter(stemmerClazz.getConstructor().newInstance());
       } catch (Exception e) {
         log.warn("Could not instantiate snowball stemmer"
             + " for language: " + language.name()
diff --git a/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java b/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java
index 91847d4..f19a4ca 100644
--- a/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java
+++ b/solr/contrib/dataimporthandler-extras/src/java/org/apache/solr/handler/dataimport/MailEntityProcessor.java
@@ -418,8 +418,8 @@ public class MailEntityProcessor extends EntityProcessorBase {
     }
     if (customFilter != null && !customFilter.equals("")) {
       try {
-        Class cf = Class.forName(customFilter);
-        Object obj = cf.newInstance();
+        Class<?> cf = Class.forName(customFilter);
+        Object obj = cf.getConstructor().newInstance();
         if (obj instanceof CustomFilter) {
           filters.add((CustomFilter) obj);
         }
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImporter.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImporter.java
index d610d66..932849b 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImporter.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DataImporter.java
@@ -333,7 +333,7 @@ public class DataImporter {
     PropertyWriter configPw = config.getPropertyWriter();
     try {
       Class<DIHProperties> writerClass = DocBuilder.loadClass(configPw.getType(), this.core);
-      propWriter = writerClass.newInstance();
+      propWriter = writerClass.getConstructor().newInstance();
       propWriter.init(this, configPw.getParameters());
     } catch (Exception e) {
       throw new DataImportHandlerException(DataImportHandlerException.SEVERE, "Unable to PropertyWriter implementation:" + configPw.getType(), e);
@@ -378,7 +378,7 @@ public class DataImporter {
       dataSrc = new JdbcDataSource();
     } else {
       try {
-        dataSrc = (DataSource) DocBuilder.loadClass(type, getCore()).newInstance();
+        dataSrc = (DataSource) DocBuilder.loadClass(type, getCore()).getConstructor().newInstance();
       } catch (Exception e) {
         wrapAndThrow(SEVERE, e, "Invalid type for data source: " + type);
       }
@@ -533,7 +533,7 @@ public class DataImporter {
     SolrCore core = docBuilder == null ? null : docBuilder.dataImporter.getCore();
     for (Map<String, String> map : fn) {
       try {
-        evaluators.put(map.get(NAME), (Evaluator) loadClass(map.get(CLASS), core).newInstance());
+        evaluators.put(map.get(NAME), (Evaluator) loadClass(map.get(CLASS), core).getConstructor().newInstance());
       } catch (Exception e) {
         wrapAndThrow(SEVERE, e, "Unable to instantiate evaluator: " + map.get(CLASS));
       }
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java
index 164cf70..285b135 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/DocBuilder.java
@@ -157,7 +157,7 @@ public class DocBuilder {
 
   private void invokeEventListener(String className, Exception lastException) {
     try {
-      EventListener listener = (EventListener) loadClass(className, dataImporter.getCore()).newInstance();
+      EventListener listener = (EventListener) loadClass(className, dataImporter.getCore()).getConstructor().newInstance();
       notifyListener(listener, lastException);
     } catch (Exception e) {
       wrapAndThrow(SEVERE, e, "Unable to load class : " + className);
@@ -721,7 +721,7 @@ public class DocBuilder {
     } else {
       try {
         entityProcessor = (EntityProcessor) loadClass(entity.getProcessorName(), dataImporter.getCore())
-                .newInstance();
+            .getConstructor().newInstance();
       } catch (Exception e) {
         wrapAndThrow (SEVERE,e,
                 "Unable to load EntityProcessor implementation for entity:" + entity.getName());
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorWrapper.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorWrapper.java
index 8a76e11..984f030 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorWrapper.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/EntityProcessorWrapper.java
@@ -112,7 +112,7 @@ public class EntityProcessorWrapper extends EntityProcessor {
       try {
         Class clazz = DocBuilder.loadClass(trans, context.getSolrCore());
         if (Transformer.class.isAssignableFrom(clazz)) {
-          transformers.add((Transformer) clazz.newInstance());
+          transformers.add((Transformer) clazz.getConstructor().newInstance());
         } else {
           Method meth = clazz.getMethod(TRANSFORM_ROW, Map.class);
           transformers.add(new ReflectionTransformer(meth, clazz, trans));
@@ -164,7 +164,7 @@ public class EntityProcessorWrapper extends EntityProcessor {
       this.meth = meth;
       this.clazz = clazz;
       this.trans = trans;
-      o = clazz.newInstance();
+      o = clazz.getConstructor().newInstance();
     }
 
     @Override
diff --git a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java
index a8eed55..5eb3517 100644
--- a/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java
+++ b/solr/contrib/dataimporthandler/src/java/org/apache/solr/handler/dataimport/JdbcDataSource.java
@@ -188,7 +188,7 @@ public class JdbcDataSource extends
             // the class loader of the class which is trying to make the connection.
             // This is a workaround for cases where the user puts the driver jar in the
             // solr.home/lib or solr.home/core/lib directories.
-            Driver d = (Driver) DocBuilder.loadClass(driver, context.getSolrCore()).newInstance();
+            Driver d = (Driver) DocBuilder.loadClass(driver, context.getSolrCore()).getConstructor().newInstance();
             c = d.connect(url, initProps);
           }
         }
@@ -537,18 +537,6 @@ public class JdbcDataSource extends
     }
   }
 
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      if(!isClosed){
-        log.error("JdbcDataSource was not closed prior to finalize(), indicates a bug -- POSSIBLE RESOURCE LEAK!!!");
-        close();
-      }
-    } finally {
-      super.finalize();
-    }
-  }
-
   private boolean isClosed = false;
 
   @Override
diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDIHJdbcTestCase.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDIHJdbcTestCase.java
index 1a0d888..5428e18 100644
--- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDIHJdbcTestCase.java
+++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/AbstractDIHJdbcTestCase.java
@@ -52,12 +52,12 @@ public abstract class AbstractDIHJdbcTestCase extends
   @BeforeClass
   public static void beforeClassDihJdbcTest() throws Exception {
     try {
-      Class.forName("org.hsqldb.jdbcDriver").newInstance();
+      Class.forName("org.hsqldb.jdbcDriver").getConstructor().newInstance();
       String oldProp = System.getProperty("derby.stream.error.field");
       System
           .setProperty("derby.stream.error.field",
               "org.apache.solr.handler.dataimport.AbstractDIHJdbcTestCase$DerbyUtil.DEV_NULL");
-      Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
+      Class.forName("org.apache.derby.jdbc.EmbeddedDriver").getConstructor().newInstance();
       if (oldProp != null) {
         System.setProperty("derby.stream.error.field", oldProp);
       }
diff --git a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestEntityProcessorBase.java b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestEntityProcessorBase.java
index 623e49e..75ec2f5 100644
--- a/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestEntityProcessorBase.java
+++ b/solr/contrib/dataimporthandler/src/test/org/apache/solr/handler/dataimport/TestEntityProcessorBase.java
@@ -55,7 +55,7 @@ public class TestEntityProcessorBase extends AbstractDataImportHandlerTestCase {
     assertNotNull(res.get("T3"));
   }
 
-  static class T1 extends Transformer {
+  public static class T1 extends Transformer {
 
     @Override
     public Object transformRow(Map<String, Object> aRow, Context context) {
@@ -65,7 +65,7 @@ public class TestEntityProcessorBase extends AbstractDataImportHandlerTestCase {
     }
   }
 
-  static class T2 extends Transformer {
+  public static class T2 extends Transformer {
 
     @Override
     public Object transformRow(Map<String, Object> aRow, Context context) {
@@ -74,7 +74,7 @@ public class TestEntityProcessorBase extends AbstractDataImportHandlerTestCase {
     }
   }
 
-  static class T3 {
+  public static class T3 {
 
     public Object transformRow(Map<String, Object> aRow) {
       aRow.put("T3", "T3 called");
diff --git a/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java b/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
index d40f342..3d04fff 100644
--- a/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
+++ b/solr/core/src/java/org/apache/solr/cloud/rule/ReplicaAssigner.java
@@ -338,7 +338,7 @@ public class ReplicaAssigner {
     for (Class c : Snitch.WELL_KNOWN_SNITCHES) {
       if (snitches.containsKey(c)) continue;// it is already specified explicitly , ignore
       try {
-        snitches.put(c, new SnitchInfoImpl(Collections.EMPTY_MAP, (Snitch) c.newInstance(), cloudManager));
+        snitches.put(c, new SnitchInfoImpl(Collections.EMPTY_MAP, (Snitch) c.getConstructor().newInstance(), cloudManager));
       } catch (Exception e) {
         throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "Error instantiating Snitch " + c.getName());
       }
@@ -433,7 +433,7 @@ public class ReplicaAssigner {
       try {
         if (klas.indexOf('.') == -1) klas = Snitch.class.getPackage().getName() + "." + klas;
         Snitch inst =
-            (Snitch) Snitch.class.getClassLoader().loadClass(klas).newInstance() ;
+            (Snitch) Snitch.class.getClassLoader().loadClass(klas).getConstructor().newInstance() ;
         snitches.put(inst.getClass(), new SnitchInfoImpl(map, inst, cloudManager));
       } catch (Exception e) {
         throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e);
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 3cdccd0..da260c7 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -1032,17 +1032,6 @@ public class CoreContainer {
     }
   }
 
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      if(!isShutDown){
-        log.error("CoreContainer was not close prior to finalize(), indicates a bug -- POSSIBLE RESOURCE LEAK!!!  instance=" + System.identityHashCode(this));
-      }
-    } finally {
-      super.finalize();
-    }
-  }
-
   public CoresLocator getCoresLocator() {
     return coresLocator;
   }
diff --git a/solr/core/src/java/org/apache/solr/core/MemClassLoader.java b/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
index e4f561f..a249dc8 100644
--- a/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
+++ b/solr/core/src/java/org/apache/solr/core/MemClassLoader.java
@@ -169,7 +169,7 @@ public class MemClassLoader extends ClassLoader implements AutoCloseable, Resour
   @Override
   public <T> T newInstance(String cname, Class<T> expectedType) {
     try {
-      return findClass(cname, expectedType).newInstance();
+      return findClass(cname, expectedType).getConstructor().newInstance();
     } catch (SolrException e) {
       throw e;
     } catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCore.java b/solr/core/src/java/org/apache/solr/core/SolrCore.java
index c86ceb4..d850aa1 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -1699,17 +1699,6 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
       return refCount.get() <= 0;
   }
 
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      if (getOpenCount() != 0) {
-        log.error("REFCOUNT ERROR: unreferenced {} ({}) has a reference count of {}", this, getName(), getOpenCount());
-      }
-    } finally {
-      super.finalize();
-    }
-  }
-
   private Collection<CloseHook> closeHooks = null;
 
    /**
@@ -2698,7 +2687,7 @@ public final class SolrCore implements SolrInfoBean, SolrMetricProducer, Closeab
     DEFAULT_RESPONSE_WRITERS = Collections.unmodifiableMap(m);
     try {
       m.put("xlsx",
-          (QueryResponseWriter) Class.forName("org.apache.solr.handler.extraction.XLSXResponseWriter").newInstance());
+          (QueryResponseWriter) Class.forName("org.apache.solr.handler.extraction.XLSXResponseWriter").getConstructor().newInstance());
     } catch (Exception e) {
       //don't worry; solrcell contrib not in class path
     }
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java b/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java
new file mode 100644
index 0000000..4a5b41c
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java
@@ -0,0 +1,42 @@
+/*
+ * 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.core;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * Notifies observers implementing this class about cores that need to be closed.
+ */
+public interface SolrCoreCloseListener extends PropertyChangeListener {
+
+  /**
+   * Called by TransientSolrCoreCache to notify the CoreContainer / SolrCores about cores that need to be closed.
+   * @param core Core that need to be queued for close
+   */
+  void queueCoreClose(SolrCore core);
+
+  @Override
+  default void propertyChange(PropertyChangeEvent evt) {
+    queueCoreClose((SolrCore) evt.getOldValue());
+  }
+
+}
+
+
+  
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCores.java b/solr/core/src/java/org/apache/solr/core/SolrCores.java
index 546686e..43034a5 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCores.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCores.java
@@ -33,8 +33,6 @@ import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Observable;
-import java.util.Observer;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
@@ -42,7 +40,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 
 
-class SolrCores implements Observer {
+class SolrCores implements SolrCoreCloseListener {
 
   private static Object modifyLock = new Object(); // for locking around manipulating any of the core maps.
   private final Map<String, SolrCore> cores = new LinkedHashMap<>(); // For "permanent" cores
@@ -536,10 +534,9 @@ class SolrCores implements Observer {
 
   // Let transient cache implementation tell us when it ages out a core
   @Override
-  public void update(Observable o, Object arg) {
+  public void queueCoreClose(SolrCore core) {
     synchronized (modifyLock) {
       // Erick Erickson debugging TestLazyCores. With this un-commented, we get no testLazyCores failures.
-//      SolrCore core = (SolrCore) arg;
 //      SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams());
 //      CommitUpdateCommand cmd = new CommitUpdateCommand(req, false);
 //      cmd.openSearcher = false;
@@ -549,7 +546,7 @@ class SolrCores implements Observer {
 //      } catch (IOException e) {
 //        log.warn("Caught exception trying to close a transient core, ignoring as it should be benign");
 //      }
-      pendingCloses.add((SolrCore) arg); // Essentially just queue this core up for closing.
+      pendingCloses.add(core); // Essentially just queue this core up for closing.
       modifyLock.notifyAll(); // Wakes up closer thread too
     }
   }
@@ -564,5 +561,4 @@ class SolrCores implements Observer {
     return transientCoreCache.getTransientSolrCoreCache();
   }
 
-
 }
diff --git a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
index 63df02b..3af7e23 100644
--- a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
+++ b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
@@ -18,10 +18,10 @@
 package org.apache.solr.core;
 
 
+import java.beans.PropertyChangeSupport;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Observable;
 import java.util.Set;
 
 import org.apache.http.annotation.Experimental;
@@ -45,7 +45,7 @@ import org.apache.http.annotation.Experimental;
  *          necessary and to coordinate shutting down cores, manipulating the internal structures and the like..
  *          
  *          The only real action you should _initiate_ is to close a core for whatever reason, and do that by 
- *          calling notifyObservers(coreToClose); The observer will call back to removeCore(name) at the appropriate 
+ *          calling notifyCoreCloseListener(coreToClose); The observer will call back to removeCore(name) at the appropriate 
  *          time. There is no need to directly remove the core _at that time_ from the transientCores list, a call
  *          will come back to this class when CoreContainer is closing this core.
  *          
@@ -65,7 +65,7 @@ import org.apache.http.annotation.Experimental;
  *  In particular, DO NOT reach into the transientCores structure from a method called to manipulate core descriptors
  *  or vice-versa.
  */
-public abstract class TransientSolrCoreCache extends Observable {
+public abstract class TransientSolrCoreCache {
 
   // Gets the core container that encloses this cache.
   public abstract CoreContainer getContainer();
@@ -121,6 +121,30 @@ public abstract class TransientSolrCoreCache extends Observable {
   // These two methods allow custom implementations to communicate arbitrary information as necessary.
   public abstract int getStatus(String coreName);
   public abstract void setStatus(String coreName, int status);
+  
+  
+  /**
+   * Registers a listener to be notified when a core should close
+   */
+  protected final void registerCoreCloseListener(SolrCoreCloseListener listener) {
+    pcs.addPropertyChangeListener(listener);
+  }
+  
+  /**
+   * Removes a listener registered by {@link #registerCoreCloseListener(SolrCoreCloseListener)}
+   */
+  protected final void removeCoreCloseListener(SolrCoreCloseListener listener) {
+    pcs.removePropertyChangeListener(listener);
+  }
+  
+  /**
+   * Notifies all listeners to close a core that were previously registered using {@link #registerCoreCloseListener(SolrCoreCloseListener)}
+   */
+  protected final void notifyCoreCloseListeners(SolrCore core) {
+    pcs.firePropertyChange("core", core, null);
+  }
+  
+  private final PropertyChangeSupport pcs = new  PropertyChangeSupport(this);
 }
 
 
diff --git a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
index e1fd748..0b3db4b 100644
--- a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
+++ b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
@@ -23,7 +23,6 @@ import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Observer;
 import java.util.Set;
 
 import org.apache.solr.common.util.NamedList;
@@ -36,7 +35,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
 
   private int cacheSize = NodeConfig.NodeConfigBuilder.DEFAULT_TRANSIENT_CACHE_SIZE;
 
-  protected Observer observer;
+  protected SolrCoreCloseListener coreCloseListener;
   protected CoreContainer coreContainer;
 
   protected final Map<String, CoreDescriptor> transientDescriptors = new LinkedHashMap<>();
@@ -49,7 +48,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
    */
   public TransientSolrCoreCacheDefault(final CoreContainer container) {
     this.coreContainer = container;
-    this.observer= coreContainer.solrCores;
+    this.coreCloseListener = coreContainer.solrCores;
     
     NodeConfig cfg = container.getNodeConfig();
     if (cfg.getTransientCachePluginInfo() == null) {
@@ -80,7 +79,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
     }
 
     log.info("Allocating transient cache for {} transient cores", cacheSize);
-    addObserver(this.observer);
+    this.registerCoreCloseListener(this.coreCloseListener);
     // it's possible for cache
     if (cacheSize < 0) { // Trap old flag
       cacheSize = Integer.MAX_VALUE;
@@ -92,9 +91,8 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
       protected boolean removeEldestEntry(Map.Entry<String, SolrCore> eldest) {
         if (size() > cacheSize) {
           SolrCore coreToClose = eldest.getValue();
-          setChanged();
-          notifyObservers(coreToClose);
           log.info("Closing transient core [{}]", coreToClose.getName());
+          notifyCoreCloseListeners(coreToClose);
           return true;
         }
         return false;
@@ -184,7 +182,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
    */
   @Override
   public void close() {
-    deleteObserver(this.observer);
+    this.removeCoreCloseListener(this.coreCloseListener);
   }
 
 
diff --git a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheFactory.java b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheFactory.java
index 7c83ec8..6d0646e 100644
--- a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheFactory.java
+++ b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheFactory.java
@@ -50,7 +50,7 @@ public abstract class TransientSolrCoreCacheFactory {
 
     try {
       // According to the docs, this returns a TransientSolrCoreCacheFactory with the default c'tor
-      TransientSolrCoreCacheFactory tccf = loader.findClass(info.className, TransientSolrCoreCacheFactory.class).newInstance(); 
+      TransientSolrCoreCacheFactory tccf = loader.findClass(info.className, TransientSolrCoreCacheFactory.class).getConstructor().newInstance(); 
       
       // OK, now we call it's init method.
       if (PluginInfoInitialized.class.isAssignableFrom(tccf.getClass()))
diff --git a/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java
index 8395769..a7712c3 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/ShardHandlerFactory.java
@@ -46,7 +46,7 @@ public abstract class ShardHandlerFactory {
       info = DEFAULT_SHARDHANDLER_INFO;
 
     try {
-      ShardHandlerFactory shf = loader.findClass(info.className, ShardHandlerFactory.class).newInstance();
+      ShardHandlerFactory shf = loader.findClass(info.className, ShardHandlerFactory.class).getConstructor().newInstance();
       if (PluginInfoInitialized.class.isAssignableFrom(shf.getClass()))
         PluginInfoInitialized.class.cast(shf).init(info);
       return shf;
diff --git a/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java b/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
index 2b3b555..4e59212 100644
--- a/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
+++ b/solr/core/src/java/org/apache/solr/schema/CurrencyFieldType.java
@@ -122,7 +122,7 @@ public class CurrencyFieldType extends FieldType implements SchemaAware, Resourc
     try {
       Class<? extends ExchangeRateProvider> c
           = schema.getResourceLoader().findClass(exchangeRateProviderClass, ExchangeRateProvider.class);
-      provider = c.newInstance();
+      provider = c.getConstructor().newInstance();
       provider.init(args);
     } catch (Exception e) {
       throw new SolrException(ErrorCode.SERVER_ERROR,
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 158d569..36be446 100644
--- a/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
+++ b/solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
@@ -226,7 +226,7 @@ public final class FieldTypePluginLoader
       try {
         // No need to be core-aware as Analyzers are not in the core-aware list
         final Class<? extends Analyzer> clazz = loader.findClass(analyzerName, Analyzer.class);
-        Analyzer analyzer = clazz.newInstance();
+        Analyzer analyzer = clazz.getConstructor().newInstance();
 
         final String matchVersionStr = DOMUtil.getAttr(attrs, LUCENE_MATCH_VERSION_PARAM);
         final Version luceneMatchVersion = (matchVersionStr == null) ?
diff --git a/solr/core/src/java/org/apache/solr/search/CacheConfig.java b/solr/core/src/java/org/apache/solr/search/CacheConfig.java
index 648fe38..16a9d57 100644
--- a/solr/core/src/java/org/apache/solr/search/CacheConfig.java
+++ b/solr/core/src/java/org/apache/solr/search/CacheConfig.java
@@ -136,7 +136,7 @@ public class CacheConfig implements MapSerializable{
 
   public SolrCache newInstance() {
     try {
-      SolrCache cache = clazz.newInstance();
+      SolrCache cache = clazz.getConstructor().newInstance();
       persistence[0] = cache.init(args, persistence[0], regenerator);
       return cache;
     } catch (Exception e) {
diff --git a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
index 4ced113..b4aa44d 100644
--- a/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
+++ b/solr/core/src/java/org/apache/solr/search/GraphTermsQParserPlugin.java
@@ -61,7 +61,6 @@ import org.apache.lucene.util.BytesRefBuilder;
 import org.apache.lucene.util.BytesRefIterator;
 import org.apache.lucene.util.DocIdSetBuilder;
 import org.apache.lucene.util.FixedBitSet;
-import org.apache.lucene.util.FutureArrays;
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.schema.FieldType;
@@ -690,12 +689,12 @@ abstract class PointSetQuery extends Query implements DocSetProducer {
       for(int dim=0;dim<numDims;dim++) {
         int offset = dim*bytesPerDim;
 
-        int cmpMin = FutureArrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
+        int cmpMin = Arrays.compareUnsigned(minPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
         if (cmpMin > 0) {
           return PointValues.Relation.CELL_OUTSIDE_QUERY;
         }
 
-        int cmpMax = FutureArrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
+        int cmpMax = Arrays.compareUnsigned(maxPackedValue, offset, offset + bytesPerDim, pointBytes, offset, offset + bytesPerDim);
         if (cmpMax < 0) {
           return PointValues.Relation.CELL_OUTSIDE_QUERY;
         }
diff --git a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
index 27e0198..538a983 100644
--- a/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
+++ b/solr/core/src/java/org/apache/solr/update/SolrIndexWriter.java
@@ -348,17 +348,4 @@ public class SolrIndexWriter extends IndexWriter {
     }
   }
 
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      if(!isClosed){
-        assert false : "SolrIndexWriter was not closed prior to finalize()";
-        log.error("SolrIndexWriter was not closed prior to finalize(), indicates a bug -- POSSIBLE RESOURCE LEAK!!!");
-        close();
-      }
-    } finally { 
-      super.finalize();
-    }
-    
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java b/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java
index 6f2ff2d..d3d32f0 100644
--- a/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java
+++ b/solr/core/src/java/org/apache/solr/util/ConcurrentLFUCache.java
@@ -16,7 +16,6 @@
  */
 package org.apache.solr.util;
 
-import java.lang.invoke.MethodHandles;
 import java.lang.ref.WeakReference;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -27,8 +26,6 @@ import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantLock;
 
 import org.apache.solr.common.util.Cache;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * A LFU cache implementation based upon ConcurrentHashMap.
@@ -42,7 +39,6 @@ import org.slf4j.LoggerFactory;
  * @since solr 1.6
  */
 public class ConcurrentLFUCache<K, V> implements Cache<K,V> {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   private final ConcurrentHashMap<Object, CacheEntry<K, V>> map;
   private final int upperWaterMark, lowerWaterMark;
@@ -469,15 +465,4 @@ public class ConcurrentLFUCache<K, V> implements Cache<K,V> {
     }
   }
 
-  @Override
-  protected void finalize() throws Throwable {
-    try {
-      if (!isDestroyed) {
-        log.error("ConcurrentLFUCache was not destroyed prior to finalize(), indicates a bug -- POSSIBLE RESOURCE LEAK!!!");
-        destroy();
-      }
-    } finally {
-      super.finalize();
-    }
-  }
 }
diff --git a/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java b/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java
index e875828..2d01cce 100644
--- a/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java
+++ b/solr/core/src/java/org/apache/solr/util/ConcurrentLRUCache.java
@@ -20,8 +20,6 @@ import org.apache.lucene.util.PriorityQueue;
 import org.apache.lucene.util.RamUsageEstimator;
 import org.apache.solr.common.util.Cache;
 import org.apache.solr.search.LRUCache;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -36,7 +34,6 @@ import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.LongAdder;
 import java.util.concurrent.locks.ReentrantLock;
-import java.lang.invoke.MethodHandles;
 import java.lang.ref.WeakReference;
 
 /**
@@ -52,7 +49,6 @@ import java.lang.ref.WeakReference;
  * @since solr 1.4
  */
 public class ConcurrentLRUCache<K,V> implements Cache<K,V>, Accountable {
-  private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
   static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(ConcurrentLRUCache.class);
 
@@ -731,18 +727,6 @@ public class ConcurrentLRUCache<K,V> implements Cache<K,V>, Accountable {
   }
 
   @Override
-  protected void finalize() throws Throwable {
-    try {
-      if(!isDestroyed && (cleanupThread != null)){
-        log.error("ConcurrentLRUCache created with a thread and was not destroyed prior to finalize(), indicates a bug -- POSSIBLE RESOURCE LEAK!!!");
-        destroy();
-      }
-    } finally {
-      super.finalize();
-    }
-  }
-
-  @Override
   public long ramBytesUsed() {
     return BASE_RAM_BYTES_USED + ramBytes.get();
   }
diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
index 7eddc76..791a9d5 100755
--- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java
+++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java
@@ -416,7 +416,7 @@ public class SolrCLI implements CLIO {
     // classpath scanning
 
     for (Class<Tool> next : findToolClassesInPackage("org.apache.solr.util")) {
-      Tool tool = next.newInstance();
+      Tool tool = next.getConstructor().newInstance();
       if (toolType.equals(tool.getName()))
         return tool;
     }
@@ -445,7 +445,7 @@ public class SolrCLI implements CLIO {
 
     List<Class<Tool>> toolClasses = findToolClassesInPackage("org.apache.solr.util");
     for (Class<Tool> next : toolClasses) {
-      Tool tool = next.newInstance();
+      Tool tool = next.getConstructor().newInstance();
       formatter.printHelp(tool.getName(), getToolOptions(tool));
     }
   }
diff --git a/solr/core/src/test/org/apache/solr/SolrInfoBeanTest.java b/solr/core/src/test/org/apache/solr/SolrInfoBeanTest.java
index 8220fd1..e44414d 100644
--- a/solr/core/src/test/org/apache/solr/SolrInfoBeanTest.java
+++ b/solr/core/src/test/org/apache/solr/SolrInfoBeanTest.java
@@ -63,7 +63,7 @@ public class SolrInfoBeanTest extends SolrTestCaseJ4
     for( Class clazz : classes ) {
       if( SolrInfoBean.class.isAssignableFrom( clazz ) ) {
         try {
-          SolrInfoBean info = (SolrInfoBean)clazz.newInstance();
+          SolrInfoBean info = (SolrInfoBean)clazz.getConstructor().newInstance();
           if (info instanceof SolrMetricProducer) {
             ((SolrMetricProducer)info).initializeMetrics(metricManager, registry, "foo", scope);
           }
@@ -80,7 +80,7 @@ public class SolrInfoBeanTest extends SolrTestCaseJ4
           assertNotNull( info.toString() );
           checked++;
         }
-        catch( InstantiationException ex ) {
+        catch( ReflectiveOperationException ex ) {
           // expected...
           //System.out.println( "unable to initialize: "+clazz );
         }
diff --git a/solr/core/src/test/org/apache/solr/analysis/ThrowingMockTokenFilterFactory.java b/solr/core/src/test/org/apache/solr/analysis/ThrowingMockTokenFilterFactory.java
index 47f80ed..19b52c2 100644
--- a/solr/core/src/test/org/apache/solr/analysis/ThrowingMockTokenFilterFactory.java
+++ b/solr/core/src/test/org/apache/solr/analysis/ThrowingMockTokenFilterFactory.java
@@ -21,6 +21,7 @@ import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Map;
 
 /**
@@ -57,8 +58,8 @@ public class ThrowingMockTokenFilterFactory extends TokenFilterFactory {
       public boolean incrementToken() throws IOException {
         if (input.incrementToken()) {
           try {
-            throw exceptionClass.newInstance();
-          } catch (IllegalAccessException | InstantiationException iae) {
+            throw exceptionClass.getConstructor().newInstance();
+          } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException iae) {
             throw new RuntimeException(iae);
           }
         }
diff --git a/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java b/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java
index dada632..7936ef1 100755
--- a/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java
+++ b/solr/core/src/test/org/apache/solr/core/DirectoryFactoryTest.java
@@ -80,7 +80,7 @@ public class DirectoryFactoryTest extends SolrTestCase {
     NodeConfig config = loadNodeConfig("/solr/solr-solrDataHome.xml");
     CoreContainer cc = new CoreContainer(config);
     Properties cp = cc.getContainerProperties();
-    DirectoryFactory df = directoryFactoryClass.newInstance();
+    DirectoryFactory df = directoryFactoryClass.getConstructor().newInstance();
     df.initCoreContainer(cc);
     df.init(new NamedList());
 
@@ -97,7 +97,7 @@ public class DirectoryFactoryTest extends SolrTestCase {
     System.setProperty("solr.data.home", "solrdata");
     config = loadNodeConfig("/solr/solr-solrDataHome.xml");
     cc = new CoreContainer(config);
-    df = directoryFactoryClass.newInstance();
+    df = directoryFactoryClass.getConstructor().newInstance();
     df.initCoreContainer(cc);
     df.init(new NamedList());
     assertDataHome(solrHome.resolve("solrdata/inst_dir/data").toAbsolutePath().toString(), "inst_dir", df, cc);
@@ -107,7 +107,7 @@ public class DirectoryFactoryTest extends SolrTestCase {
     System.setProperty("test.solr.data.home", "/foo");
     config = loadNodeConfig("/solr/solr-solrDataHome.xml");
     cc = new CoreContainer(config);
-    df = directoryFactoryClass.newInstance();
+    df = directoryFactoryClass.getConstructor().newInstance();
     df.initCoreContainer(cc);
     df.init(new NamedList());
     assertDataHome("/foo/inst_dir/data", "inst_dir", df, cc);
diff --git a/solr/core/src/test/org/apache/solr/core/TestDirectoryFactory.java b/solr/core/src/test/org/apache/solr/core/TestDirectoryFactory.java
index 0eccb6a..72b02b3 100644
--- a/solr/core/src/test/org/apache/solr/core/TestDirectoryFactory.java
+++ b/solr/core/src/test/org/apache/solr/core/TestDirectoryFactory.java
@@ -62,7 +62,7 @@ public class TestDirectoryFactory extends SolrTestCaseJ4 {
     final String path = createTempDir().toString() + "/" + clazz + "_somedir";
     DirectoryFactory dirFac = null;
     try {
-      dirFac = clazz.newInstance();
+      dirFac = clazz.getConstructor().newInstance();
       dirFac.initCoreContainer(null); // greybox testing directly against path
       dirFac.init(new NamedList());
 
diff --git a/solr/core/src/test/org/apache/solr/legacy/TestNumericTokenStream.java b/solr/core/src/test/org/apache/solr/legacy/TestNumericTokenStream.java
index 4e75820..4cdabba 100644
--- a/solr/core/src/test/org/apache/solr/legacy/TestNumericTokenStream.java
+++ b/solr/core/src/test/org/apache/solr/legacy/TestNumericTokenStream.java
@@ -176,7 +176,7 @@ public class TestNumericTokenStream extends BaseTokenStreamTestCase {
 
   public static <T extends AttributeImpl> T assertCopyIsEqual(T att) throws Exception {
     @SuppressWarnings("unchecked")
-    T copy = (T) att.getClass().newInstance();
+    T copy = (T) att.getClass().getConstructor().newInstance();
     att.copyTo(copy);
     assertEquals("Copied instance must be equal", att, copy);
     assertEquals("Copied instance's hashcode must be equal", att.hashCode(), copy.hashCode());
diff --git a/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java b/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java
index 013ff0e..544b2d4 100644
--- a/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java
+++ b/solr/core/src/test/org/apache/solr/schema/PrimitiveFieldTypeTest.java
@@ -76,7 +76,7 @@ public class PrimitiveFieldTypeTest extends SolrTestCaseJ4 {
 
 
     for (Class<? extends FieldType> clazz : types) {
-      FieldType ft = clazz.newInstance();
+      FieldType ft = clazz.getConstructor().newInstance();
       ft.init(schema, initMap);
       assertFalse(ft.getClass().getName(), ft.hasProperty(FieldType.OMIT_NORMS));
     }
@@ -87,7 +87,7 @@ public class PrimitiveFieldTypeTest extends SolrTestCaseJ4 {
     schema = IndexSchemaFactory.buildIndexSchema(testConfHome + "schema15.xml", config);
 
     for (Class<? extends FieldType> clazz : types) {
-      FieldType ft = clazz.newInstance();
+      FieldType ft = clazz.getConstructor().newInstance();
       ft.init(schema, initMap);
       assertEquals(ft.getClass().getName(),
                    ft instanceof PrimitiveFieldType,
diff --git a/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial2.java b/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial2.java
index 0291f7a..8f654d5 100644
--- a/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial2.java
+++ b/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial2.java
@@ -17,6 +17,7 @@
 package org.apache.solr.search;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -183,8 +184,8 @@ public class TestSolr4Spatial2 extends SolrTestCaseJ4 {
 
     // a random point using the number of decimal places we support for round-tripping.
     String randPointStr =
-        new BigDecimal(GeoTestUtil.nextLatitude()).setScale(7, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString() +
-        "," + new BigDecimal(GeoTestUtil.nextLongitude()).setScale(7, BigDecimal.ROUND_HALF_UP).stripTrailingZeros().toPlainString();
+        new BigDecimal(GeoTestUtil.nextLatitude()).setScale(7, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString() +
+        "," + new BigDecimal(GeoTestUtil.nextLongitude()).setScale(7, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
 
     List<RetrievalCombo> combos = Arrays.asList(
         new RetrievalCombo("llp_1_dv_st", ptHighPrecision),
diff --git a/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java b/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
index 98ec2e7..c531d49 100644
--- a/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
+++ b/solr/core/src/test/org/apache/solr/spelling/ConjunctionSolrSpellCheckerTest.java
@@ -40,8 +40,8 @@ public class ConjunctionSolrSpellCheckerTest extends SolrTestCase {
     @SuppressWarnings("unchecked")
     Class<StringDistance> sameDistance = (Class<StringDistance>) AVAILABLE_DISTANCES[random().nextInt(AVAILABLE_DISTANCES.length)];
     
-    StringDistance sameDistance1 = sameDistance.newInstance();
-    StringDistance sameDistance2 = sameDistance.newInstance();
+    StringDistance sameDistance1 = sameDistance.getConstructor().newInstance();
+    StringDistance sameDistance2 = sameDistance.getConstructor().newInstance();
     
     //NGramDistance defaults to 2, so we'll try 3 or 4 to ensure we have one that is not-equal.
     StringDistance differentDistance = new NGramDistance(3);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/beans/DocumentObjectBinder.java b/solr/solrj/src/java/org/apache/solr/client/solrj/beans/DocumentObjectBinder.java
index 2e78093..0e06615 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/beans/DocumentObjectBinder.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/beans/DocumentObjectBinder.java
@@ -62,7 +62,7 @@ public class DocumentObjectBinder {
     }
 
     try {
-      T obj = clazz.newInstance();
+      T obj = clazz.getConstructor().newInstance();
       for (DocField docField : fields) {
         docField.inject(obj, solrDoc);
       }
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
index d415f21..21177af 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientUtil.java
@@ -19,6 +19,7 @@ package org.apache.solr.client.solrj.impl;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.invoke.MethodHandles;
+import java.lang.reflect.InvocationTargetException;
 import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -151,9 +152,9 @@ public class HttpClientUtil {
     if (factoryClassName != null) {
       log.debug ("Using " + factoryClassName);
       try {
-        HttpClientBuilderFactory factory = (HttpClientBuilderFactory)Class.forName(factoryClassName).newInstance();
+        HttpClientBuilderFactory factory = (HttpClientBuilderFactory)Class.forName(factoryClassName).getConstructor().newInstance();
         httpClientBuilder = factory.getHttpClientBuilder(Optional.of(SolrHttpClientBuilder.create()));
-      } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+      } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException | NoSuchMethodException e) {
         throw new RuntimeException("Unable to instantiate Solr HttpClientBuilderFactory", e);
       }
     }
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/JDBCStreamTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/JDBCStreamTest.java
index d6ac88d..2fbe101 100644
--- a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/JDBCStreamTest.java
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/JDBCStreamTest.java
@@ -93,7 +93,7 @@ public class JDBCStreamTest extends SolrCloudTestCase {
     // So, for this reason and to simplify writing these tests I've decided that in all statements all table and column names 
     // will be in UPPERCASE. This is to ensure things look and behave consistently. Note that this is not a requirement of the 
     // JDBCStream and is only a carryover from the driver we are testing with.
-    Class.forName("org.hsqldb.jdbcDriver").newInstance();
+    Class.forName("org.hsqldb.jdbcDriver").getConstructor().newInstance();
     Connection connection = DriverManager.getConnection("jdbc:hsqldb:mem:.");
     Statement statement  = connection.createStatement();
     statement.executeUpdate("create table COUNTRIES(CODE varchar(3) not null primary key, COUNTRY_NAME varchar(50), DELETED char(1) default 'N')");
diff --git a/solr/test-framework/src/java/org/apache/solr/analysis/StringMockSolrResourceLoader.java b/solr/test-framework/src/java/org/apache/solr/analysis/StringMockSolrResourceLoader.java
index b00e979..4b79cf0 100644
--- a/solr/test-framework/src/java/org/apache/solr/analysis/StringMockSolrResourceLoader.java
+++ b/solr/test-framework/src/java/org/apache/solr/analysis/StringMockSolrResourceLoader.java
@@ -43,7 +43,7 @@ class StringMockSolrResourceLoader implements ResourceLoader {
   public <T> T newInstance(String cname, Class<T> expectedType) {
     Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      return clazz.newInstance();
+      return clazz.getConstructor().newInstance();
     } catch (Exception e) {
       throw new RuntimeException("Cannot create instance: " + cname, e);
     }
