Merged /lucene/dev/trunk:r1446984-1447123

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene4765@1447125 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/dev-tools/maven/lucene/analysis/common/pom.xml.template b/dev-tools/maven/lucene/analysis/common/pom.xml.template
index 2ea7940..9010336 100644
--- a/dev-tools/maven/lucene/analysis/common/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/common/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Additional Analyzers</description>
   <properties>
     <module-directory>lucene/analysis/common</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/icu/pom.xml.template b/dev-tools/maven/lucene/analysis/icu/pom.xml.template
index c1281c7..a9a5350 100644
--- a/dev-tools/maven/lucene/analysis/icu/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/icu/pom.xml.template
@@ -36,8 +36,8 @@
   </description>
   <properties>
     <module-directory>lucene/analysis/icu</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template b/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template
index 1447a91..e6b5834 100644
--- a/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/kuromoji/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/analysis/kuromoji</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template b/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template
index b520b3e..63a6e20 100644
--- a/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/morfologik/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/analysis/morfologik</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template b/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template
index b7498af..c5fa9a6 100644
--- a/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/phonetic/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/analysis/phonetic</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template b/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template
index e045921..6adc15f 100644
--- a/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/smartcn/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Smart Chinese Analyzer</description>
   <properties>
     <module-directory>lucene/analysis/smartcn</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/analysis/stempel/pom.xml.template b/dev-tools/maven/lucene/analysis/stempel/pom.xml.template
index d10c093..51d34e9 100644
--- a/dev-tools/maven/lucene/analysis/stempel/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/stempel/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Stempel Analyzer</description>
   <properties>
     <module-directory>lucene/analysis/stempel</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -76,5 +76,50 @@
         </excludes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>check-system-out</id> <!-- separate execution to specify excludes -->
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <excludes>
+                <!-- exclude command line tools -->
+                <exclude>org/egothor/stemmer/Compile.class</exclude>
+                <exclude>org/egothor/stemmer/DiffIt.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/analysis/uima/pom.xml.template b/dev-tools/maven/lucene/analysis/uima/pom.xml.template
index 81dbac3..ab07352 100644
--- a/dev-tools/maven/lucene/analysis/uima/pom.xml.template
+++ b/dev-tools/maven/lucene/analysis/uima/pom.xml.template
@@ -37,8 +37,8 @@
   </description>
   <properties>
     <module-directory>lucene/analysis/uima</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/benchmark/pom.xml.template b/dev-tools/maven/lucene/benchmark/pom.xml.template
index 93f9c65..8962866 100755
--- a/dev-tools/maven/lucene/benchmark/pom.xml.template
+++ b/dev-tools/maven/lucene/benchmark/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Benchmarking Module</description>
   <properties>
     <module-directory>lucene/benchmark</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -120,5 +120,36 @@
         </includes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <!-- Skip jdk-system-out  -->
+                <!-- <bundledSignature>jdk-system-out</bundledSignature> -->
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/classification/pom.xml.template b/dev-tools/maven/lucene/classification/pom.xml.template
index ec572ed..d5f2d55 100644
--- a/dev-tools/maven/lucene/classification/pom.xml.template
+++ b/dev-tools/maven/lucene/classification/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Classification</description>
   <properties>
     <module-directory>lucene/classification</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/codecs/src/java/pom.xml.template b/dev-tools/maven/lucene/codecs/src/java/pom.xml.template
index 4f7172f..459c45d 100644
--- a/dev-tools/maven/lucene/codecs/src/java/pom.xml.template
+++ b/dev-tools/maven/lucene/codecs/src/java/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/codecs</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/java</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -73,6 +73,16 @@
           <skip>true</skip> <!-- This skips test compilation - tests are run from lucene-codecs-tests module -->
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase>  <!-- Block inherited execution -->
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/codecs/src/test/pom.xml.template b/dev-tools/maven/lucene/codecs/src/test/pom.xml.template
index fc7adc3..b6cf898 100644
--- a/dev-tools/maven/lucene/codecs/src/test/pom.xml.template
+++ b/dev-tools/maven/lucene/codecs/src/test/pom.xml.template
@@ -32,8 +32,8 @@
   <packaging>jar</packaging>
   <properties>
     <module-directory>lucene/codecs</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/test</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
   </properties>
   <dependencies>
     <dependency>
@@ -69,6 +69,16 @@
           <skip>true</skip>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/core/src/java/pom.xml.template b/dev-tools/maven/lucene/core/src/java/pom.xml.template
index 0579ace..db0fee6 100644
--- a/dev-tools/maven/lucene/core/src/java/pom.xml.template
+++ b/dev-tools/maven/lucene/core/src/java/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Lucene Java Core</description>
   <properties>
     <module-directory>lucene/core</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/java</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -64,6 +64,57 @@
           <skip>true</skip> <!-- This skips test compilation - tests are run from lucene-codecs-tests module -->
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>lucene-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase>  <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>check-system-out</id> <!-- separate execution to specify excludes -->
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <excludes>
+                <!-- exclude command line tools -->
+                <exclude>org/apache/lucene/index/CheckIndex.class</exclude>
+                <exclude>org/apache/lucene/index/IndexUpgrader.class</exclude>
+                <exclude>org/apache/lucene/store/LockVerifyServer.class</exclude>
+                <exclude>org/apache/lucene/store/LockStressTest.class</exclude>
+                <!-- not printing, just checking if it's a system stream -->
+                <exclude>org/apache/lucene/util/PrintStreamInfoStream.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/core/src/test/pom.xml.template b/dev-tools/maven/lucene/core/src/test/pom.xml.template
index db1c0cc..6f59c36 100644
--- a/dev-tools/maven/lucene/core/src/test/pom.xml.template
+++ b/dev-tools/maven/lucene/core/src/test/pom.xml.template
@@ -32,8 +32,8 @@
   <packaging>jar</packaging>
   <properties>
     <module-directory>lucene/core</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/test</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
   </properties>
   <dependencies>
     <dependency>
@@ -88,6 +88,16 @@
           </systemPropertyVariables>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/demo/pom.xml.template b/dev-tools/maven/lucene/demo/pom.xml.template
index 7d9387f..741cf53 100644
--- a/dev-tools/maven/lucene/demo/pom.xml.template
+++ b/dev-tools/maven/lucene/demo/pom.xml.template
@@ -33,8 +33,8 @@
   <description>This is the demo for Apache Lucene Java</description>
   <properties>
     <module-directory>lucene/demo</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -91,5 +91,36 @@
         </excludes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <!-- demo has mostly command-line programs, so don't do the jdk-system-out check -->
+                <!-- <bundledSignature>jdk-system-out</bundledSignature> -->
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/facet/pom.xml.template b/dev-tools/maven/lucene/facet/pom.xml.template
index 85ed80c..0b56933 100755
--- a/dev-tools/maven/lucene/facet/pom.xml.template
+++ b/dev-tools/maven/lucene/facet/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/facet</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -78,5 +78,49 @@
         </excludes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>check-system-out</id> <!-- separate execution to specify excludes -->
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <excludes>
+                <!-- exclude command line tools -->
+                <exclude>org/apache/lucene/facet/util/PrintTaxonomyStats.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/grouping/pom.xml.template b/dev-tools/maven/lucene/grouping/pom.xml.template
index 2b004bf..868d3d5 100644
--- a/dev-tools/maven/lucene/grouping/pom.xml.template
+++ b/dev-tools/maven/lucene/grouping/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Grouping Module</description>
   <properties>
     <module-directory>lucene/grouping</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/highlighter/pom.xml.template b/dev-tools/maven/lucene/highlighter/pom.xml.template
index f739538..7964b7d 100644
--- a/dev-tools/maven/lucene/highlighter/pom.xml.template
+++ b/dev-tools/maven/lucene/highlighter/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/highlighter</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/join/pom.xml.template b/dev-tools/maven/lucene/join/pom.xml.template
index 4ff18bd..f072b9c 100644
--- a/dev-tools/maven/lucene/join/pom.xml.template
+++ b/dev-tools/maven/lucene/join/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Join Module</description>
   <properties>
     <module-directory>lucene/join</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/memory/pom.xml.template b/dev-tools/maven/lucene/memory/pom.xml.template
index 53de599..053c613 100644
--- a/dev-tools/maven/lucene/memory/pom.xml.template
+++ b/dev-tools/maven/lucene/memory/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/memory</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/misc/pom.xml.template b/dev-tools/maven/lucene/misc/pom.xml.template
index 12a60f0..f8fcacd 100644
--- a/dev-tools/maven/lucene/misc/pom.xml.template
+++ b/dev-tools/maven/lucene/misc/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Miscellaneous Lucene extensions</description>
   <properties>
     <module-directory>lucene/misc</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -66,5 +66,54 @@
         </excludes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>check-system-out</id>
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <excludes>
+                <!-- exclude command line tools -->
+                <exclude>org/apache/lucene/index/CompoundFileExtractor.class</exclude>
+                <exclude>org/apache/lucene/index/IndexSplitter.class</exclude>
+                <exclude>org/apache/lucene/index/MultiPassIndexSplitter.class</exclude>
+                <exclude>org/apache/lucene/misc/GetTermInfo.class</exclude>
+                <exclude>org/apache/lucene/misc/HighFreqTerms.class</exclude>
+                <exclude>org/apache/lucene/misc/IndexMergeTool.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/pom.xml.template b/dev-tools/maven/lucene/pom.xml.template
index c902eb0..87bdbcd 100644
--- a/dev-tools/maven/lucene/pom.xml.template
+++ b/dev-tools/maven/lucene/pom.xml.template
@@ -59,4 +59,47 @@
     <module>spatial</module>
     <module>suggest</module>
   </modules>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>lucene-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
 </project>
diff --git a/dev-tools/maven/lucene/queries/pom.xml.template b/dev-tools/maven/lucene/queries/pom.xml.template
index 864c0b9..6d5168f 100644
--- a/dev-tools/maven/lucene/queries/pom.xml.template
+++ b/dev-tools/maven/lucene/queries/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Queries Module</description>
   <properties>
     <module-directory>lucene/queries</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/queryparser/pom.xml.template b/dev-tools/maven/lucene/queryparser/pom.xml.template
index b14ffce..ba414aa 100644
--- a/dev-tools/maven/lucene/queryparser/pom.xml.template
+++ b/dev-tools/maven/lucene/queryparser/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene QueryParsers module</description>
   <properties>
     <module-directory>lucene/queryparser</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -81,5 +81,51 @@
         </excludes>
       </testResource>
     </testResources>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>check-system-out</id>
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-system-out</bundledSignature>
+              </bundledSignatures>
+              <excludes>
+                <!-- not printing, just generated code from javacc -->
+                <exclude>org/apache/lucene/queryparser/classic/QueryParserTokenManager.class</exclude>
+                <exclude>org/apache/lucene/queryparser/flexible/standard/parser/StandardSyntaxParserTokenManager.class</exclude>
+                <exclude>org/apache/lucene/queryparser/surround/parser/QueryParserTokenManager.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/lucene/sandbox/pom.xml.template b/dev-tools/maven/lucene/sandbox/pom.xml.template
index 508975f..95d200e3 100644
--- a/dev-tools/maven/lucene/sandbox/pom.xml.template
+++ b/dev-tools/maven/lucene/sandbox/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Sandbox</description>
   <properties>
     <module-directory>lucene/sandbox</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/spatial/pom.xml.template b/dev-tools/maven/lucene/spatial/pom.xml.template
index b3a0fde..f51dce0 100644
--- a/dev-tools/maven/lucene/spatial/pom.xml.template
+++ b/dev-tools/maven/lucene/spatial/pom.xml.template
@@ -35,8 +35,8 @@
   </description>
   <properties>
     <module-directory>lucene/spatial</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <dependencies>
     <dependency> 
diff --git a/dev-tools/maven/lucene/suggest/pom.xml.template b/dev-tools/maven/lucene/suggest/pom.xml.template
index 42ecf7d..44eadf6 100644
--- a/dev-tools/maven/lucene/suggest/pom.xml.template
+++ b/dev-tools/maven/lucene/suggest/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Lucene Suggest Module</description>
   <properties>
     <module-directory>lucene/suggest</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
diff --git a/dev-tools/maven/lucene/test-framework/pom.xml.template b/dev-tools/maven/lucene/test-framework/pom.xml.template
index ad8c6ed..c3cd82f 100644
--- a/dev-tools/maven/lucene/test-framework/pom.xml.template
+++ b/dev-tools/maven/lucene/test-framework/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Lucene Java Test Framework</description>
   <properties>
     <module-directory>lucene/test-framework</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -82,6 +82,35 @@
           <skip>true</skip>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>lucene-check-forbidden-executors-and-jdk-unsafe-deprecated-and-system-out</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>lucene-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal> <!-- NOT testCheck -->
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
   <repositories>
diff --git a/dev-tools/maven/pom.xml.template b/dev-tools/maven/pom.xml.template
index 5742a30..7fcf4ae 100644
--- a/dev-tools/maven/pom.xml.template
+++ b/dev-tools/maven/pom.xml.template
@@ -38,7 +38,6 @@
     <module>solr</module>
   </modules>
   <properties>
-    <top-level>..</top-level>
     <vc-anonymous-base-url>http://svn.apache.org/repos/asf/lucene/dev/trunk</vc-anonymous-base-url>
     <vc-dev-base-url>https://svn.apache.org/repos/asf/lucene/dev/trunk</vc-dev-base-url>
     <vc-browse-base-url>http://svn.apache.org/viewvc/lucene/dev/trunk</vc-browse-base-url>
@@ -49,6 +48,7 @@
     <slf4j.version>1.6.4</slf4j.version>
     <tika.version>1.2</tika.version>
     <httpcomponents.version>4.2.3</httpcomponents.version>
+    <commons-io.version>2.1</commons-io.version>
 
     <!-- RandomizedTesting library system properties -->
     <tests.iters>1</tests.iters>
@@ -178,7 +178,7 @@
       <dependency>
         <groupId>commons-io</groupId>
         <artifactId>commons-io</artifactId>
-        <version>2.1</version>
+        <version>${commons-io.version}</version>
       </dependency>
       <dependency>
         <groupId>org.apache.httpcomponents</groupId>
@@ -459,6 +459,19 @@
     <pluginManagement>
       <plugins>
         <plugin>
+          <groupId>de.thetaphi</groupId>
+          <artifactId>forbiddenapis</artifactId>
+          <version>1.2</version>
+          <configuration>
+            <!--
+              This is the default setting, we don't support Java 8 at the moment.
+              The checker simply passes by default and only prints a warning.
+             -->
+            <failOnUnsupportedJava>false</failOnUnsupportedJava>
+            <targetVersion>${java.compat.version}</targetVersion>
+          </configuration>
+        </plugin>
+        <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-antrun-plugin</artifactId>
           <version>1.7</version>
@@ -626,7 +639,7 @@
         <artifactId>gmaven-plugin</artifactId>
         <executions>
           <execution>
-            <id>generate-timestamps</id>
+            <id>generate-timestamps-and-get-top-level-basedir</id>
             <phase>validate</phase>
             <goals>
               <goal>execute</goal>
@@ -636,6 +649,7 @@
                 project.properties['now.timestamp'] = "${maven.build.timestamp}"
                 project.properties['now.version'] = ("${maven.build.timestamp}" =~ /[- :]/).replaceAll(".")
                 project.properties['now.year'] = "${maven.build.timestamp}".substring(0, 4)
+                project.properties['top-level'] = (project.basedir.getAbsolutePath() =~ /[\\\\\/]maven-build.*/).replaceAll("")
               </source>
             </configuration>
           </execution>
@@ -680,8 +694,8 @@
                   <message>Maven 2.2.1+ is required.</message>
                   <version>[2.2.1,)</version>
                 </requireMavenVersion>
-                <requirePluginVersions/>           
-              </rules>    
+                <requirePluginVersions/>
+              </rules>
             </configuration>
           </execution>
         </executions>
diff --git a/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template b/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template
index afbab45..86864e2 100644
--- a/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/analysis-extras/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr Analysis Extras</description>
   <properties>
     <module-directory>solr/contrib/analysis-extras</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -99,16 +98,5 @@
         </includes>
       </testResource>
     </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/contrib/clustering/pom.xml.template b/dev-tools/maven/solr/contrib/clustering/pom.xml.template
index 2048272..bbeb03d 100644
--- a/dev-tools/maven/solr/contrib/clustering/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/clustering/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr Clustering</description>
   <properties>
     <module-directory>solr/contrib/clustering</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -140,16 +139,5 @@
         </includes>
       </testResource>
     </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template b/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template
index e068752..b568910 100644
--- a/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/dataimporthandler-extras/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr DataImportHandler Extras</description>
   <properties>
     <module-directory>solr/contrib/dataimporthandler-extras</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -102,16 +101,5 @@
         </includes>
       </testResource>
     </testResources>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
-    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template b/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template
index 8edb991..9e605ce 100644
--- a/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/dataimporthandler/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr DataImportHandler</description>
   <properties>
     <module-directory>solr/contrib/dataimporthandler</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -105,15 +104,6 @@
           </execution>
         </executions>
       </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
-      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/contrib/extraction/pom.xml.template b/dev-tools/maven/solr/contrib/extraction/pom.xml.template
index adf0755..acd529e 100644
--- a/dev-tools/maven/solr/contrib/extraction/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/extraction/pom.xml.template
@@ -36,9 +36,8 @@
   </description>
   <properties>
     <module-directory>solr/contrib/extraction</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -101,13 +100,21 @@
     </testResources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>test-check-forbidden-servlet-api</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/contrib/langid/pom.xml.template b/dev-tools/maven/solr/contrib/langid/pom.xml.template
index 19ff593..75506ab 100644
--- a/dev-tools/maven/solr/contrib/langid/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/langid/pom.xml.template
@@ -37,9 +37,8 @@
   </description>
   <properties>
     <module-directory>solr/contrib/langid</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -107,13 +106,21 @@
     </testResources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>test-check-forbidden-servlet-api</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/contrib/uima/pom.xml.template b/dev-tools/maven/solr/contrib/uima/pom.xml.template
index 5fb861d..d1eae03 100644
--- a/dev-tools/maven/solr/contrib/uima/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/uima/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr - UIMA integration</description>
   <properties>
     <module-directory>solr/contrib/uima</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -126,13 +125,21 @@
     </testResources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>test-check-forbidden-servlet-api</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/contrib/velocity/pom.xml.template b/dev-tools/maven/solr/contrib/velocity/pom.xml.template
index 9e8b726..ac5a843 100644
--- a/dev-tools/maven/solr/contrib/velocity/pom.xml.template
+++ b/dev-tools/maven/solr/contrib/velocity/pom.xml.template
@@ -33,9 +33,8 @@
   <description>Apache Solr Velocity</description>
   <properties>
     <module-directory>solr/contrib/velocity</module-directory>
-    <top-level>../../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -142,13 +141,21 @@
     </testResources>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>test-check-forbidden-servlet-api</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/core/src/java/pom.xml.template b/dev-tools/maven/solr/core/src/java/pom.xml.template
index 70554fc..91b4e3b 100644
--- a/dev-tools/maven/solr/core/src/java/pom.xml.template
+++ b/dev-tools/maven/solr/core/src/java/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Solr Core</description>
   <properties>
     <module-directory>solr/core</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/java</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -216,6 +216,39 @@
           <skip>true</skip> <!-- This skips test compilation - tests are run from solr-core-tests module -->
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-servlet-api-and-jdk-unsafe-and-deprecated-and-commons-io-unsafe</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <bundledSignature>commons-io-unsafe-${commons-io.version}</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/core/src/test/pom.xml.template b/dev-tools/maven/solr/core/src/test/pom.xml.template
index 17d77d5..ad2f623 100644
--- a/dev-tools/maven/solr/core/src/test/pom.xml.template
+++ b/dev-tools/maven/solr/core/src/test/pom.xml.template
@@ -32,9 +32,8 @@
   <packaging>jar</packaging>
   <properties>
     <module-directory>solr/core</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/test</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
   </properties>
   <dependencies>
     <dependency>
@@ -115,13 +114,53 @@
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>test-check-forbidden-servlet-api-and-jdk-unsafe-and-deprecated-and-commons-io-unsafe</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <bundledSignature>commons-io-unsafe-${commons-io.version}</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>test-check-forbidden-test-apis</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+              <excludes>
+                <!-- not actually a test -->
+                <exclude>org/apache/solr/search/DocSetPerf.class</exclude>
+                <!-- imported code -->
+                <exclude>org/apache/solr/internal/**/*.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/pom.xml.template b/dev-tools/maven/solr/pom.xml.template
index 7feaa2d..9f9eeed 100644
--- a/dev-tools/maven/solr/pom.xml.template
+++ b/dev-tools/maven/solr/pom.xml.template
@@ -110,5 +110,54 @@
         </plugin>
       </plugins>
     </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <java.util.logging.config.file>${top-level}/solr/testlogging.properties</java.util.logging.config.file>
+          </systemPropertyVariables>
+        </configuration>
+      </plugin>
+    </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/solrj/src/java/pom.xml.template b/dev-tools/maven/solr/solrj/src/java/pom.xml.template
index 2ef6014..f659cdf 100644
--- a/dev-tools/maven/solr/solrj/src/java/pom.xml.template
+++ b/dev-tools/maven/solr/solrj/src/java/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Solr Solrj</description>
   <properties>
     <module-directory>solr/solrj</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/java</module-path>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/java</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -132,6 +132,40 @@
           <skip>true</skip> <!-- This skips test compilation - tests are run from solr-solrj-tests module -->
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-executors-and-jdk-unsafe-and-deprecated-and-commons-io-unsafe</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <bundledSignature>commons-io-unsafe-${commons-io.version}</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/executors.txt</signaturesFile>
+                <!-- Solr-J does NOT depend on servlet-api -->
+                <!-- <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile> -->
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/solrj/src/test/pom.xml.template b/dev-tools/maven/solr/solrj/src/test/pom.xml.template
index de0a101..f981e58 100644
--- a/dev-tools/maven/solr/solrj/src/test/pom.xml.template
+++ b/dev-tools/maven/solr/solrj/src/test/pom.xml.template
@@ -32,9 +32,8 @@
   <packaging>jar</packaging>
   <properties>
     <module-directory>solr/solrj</module-directory>
-    <top-level>../../../../..</top-level>
-    <module-path>${top-level}/${module-directory}/src/test</module-path>
-    <surefire-solr-directory>${top-level}/../../solr</surefire-solr-directory>
+    <relative-top-level>../../../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}/src/test</module-path>
   </properties>
   <dependencies>
     <dependency>
@@ -104,13 +103,51 @@
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <configuration>
-          <systemPropertyVariables>
-            <java.util.logging.config.file>${surefire-solr-directory}/testlogging.properties</java.util.logging.config.file>
-          </systemPropertyVariables>
-        </configuration>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>test-check-forbidden-servlet-api</id>
+            <configuration>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+              </signaturesFiles>
+              <excludes>
+                <!-- violates the servlet-api restrictions, but it is safe to do so in this test: -->
+                <exclude>org/apache/solr/client/solrj/impl/BasicHttpSolrServerTest$DebugServlet.class</exclude>
+              </excludes>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated-and-commons-io-unsafe</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+                <bundledSignature>commons-io-unsafe-${commons-io.version}</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>testCheck</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
     </plugins>
   </build>
diff --git a/dev-tools/maven/solr/test-framework/pom.xml.template b/dev-tools/maven/solr/test-framework/pom.xml.template
index c5842ec..82aa1d5 100644
--- a/dev-tools/maven/solr/test-framework/pom.xml.template
+++ b/dev-tools/maven/solr/test-framework/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Solr Test Framework</description>
   <properties>
     <module-directory>solr/test-framework</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -104,6 +104,38 @@
           <skip>true</skip>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>check-forbidden-test-apis-and-servlet-api-and-jdk-unsafe-and-deprecated</id>
+            <configuration>
+              <!-- disallow undocumented classes like sun.misc.Unsafe: -->
+              <internalRuntimeForbidden>true</internalRuntimeForbidden>
+              <bundledSignatures>
+                <bundledSignature>jdk-unsafe</bundledSignature>
+                <bundledSignature>jdk-deprecated</bundledSignature>
+              </bundledSignatures>
+              <signaturesFiles>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/servlet-api.txt</signaturesFile>
+                <signaturesFile>${top-level}/lucene/tools/forbiddenApis/tests.txt</signaturesFile>
+              </signaturesFiles>
+            </configuration>
+            <goals>
+              <goal>check</goal>  <!-- NOT testcheck -->
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/dev-tools/maven/solr/webapp/pom.xml.template b/dev-tools/maven/solr/webapp/pom.xml.template
index 7d886b1..32aec1a 100644
--- a/dev-tools/maven/solr/webapp/pom.xml.template
+++ b/dev-tools/maven/solr/webapp/pom.xml.template
@@ -33,8 +33,8 @@
   <description>Apache Solr Search Server</description>
   <properties>
     <module-directory>solr/webapp</module-directory>
-    <top-level>../../..</top-level>
-    <module-path>${top-level}/${module-directory}</module-path>
+    <relative-top-level>../../..</relative-top-level>
+    <module-path>${relative-top-level}/${module-directory}</module-path>
   </properties>
   <scm>
     <connection>scm:svn:${vc-anonymous-base-url}/${module-directory}</connection>
@@ -114,6 +114,20 @@
           </systemProperties>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>de.thetaphi</groupId>
+        <artifactId>forbiddenapis</artifactId>
+        <executions>
+          <execution>
+            <id>solr-check-forbidden-executors-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+          <execution>
+            <id>solr-test-check-forbidden-test-apis-and-jdk-unsafe-and-deprecated</id>
+            <phase>none</phase> <!-- Block inherited execution -->
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
index 7bd91c1..e85ec16 100644
--- a/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
+++ b/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
@@ -24,8 +24,10 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.lucene41.Lucene41PostingsFormat;
 import org.apache.lucene.document.Document;
 import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StringField;
 import org.apache.lucene.document.TextField;
 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
 import org.apache.lucene.store.Directory;
@@ -343,14 +345,20 @@
 
   public void testTotalBytesSize() throws Exception {
     Directory d = newDirectory();
+    if (d instanceof MockDirectoryWrapper) {
+      ((MockDirectoryWrapper)d).setThrottling(MockDirectoryWrapper.Throttling.NEVER);
+    }
     IndexWriterConfig iwc = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random()));
     iwc.setMaxBufferedDocs(5);
     iwc.setMergeScheduler(new TrackingCMS());
-    RandomIndexWriter w = new RandomIndexWriter(random(), d);
-    for(int i=0;i<100000;i++) {
+    if (_TestUtil.getPostingsFormat("id").equals("SimpleText")) {
+      // no
+      iwc.setCodec(_TestUtil.alwaysPostingsFormat(new Lucene41PostingsFormat()));
+    }
+    RandomIndexWriter w = new RandomIndexWriter(random(), d, iwc);
+    for(int i=0;i<1000;i++) {
       Document doc = new Document();
-      doc.add(newStringField("id", ""+i, Field.Store.NO));
-      doc.add(newTextField("field", "here is some text", Field.Store.NO));
+      doc.add(new StringField("id", ""+i, Field.Store.NO));
       w.addDocument(doc);
 
       if (random().nextBoolean()) {
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 695aa0b..1b674cf 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
@@ -1247,8 +1247,10 @@
       if (maybeWrap) {
         r = maybeWrapReader(r);
       }
-      if (r instanceof AtomicReader) {
-        _TestUtil.checkReader((AtomicReader)r);
+      if (rarely() && r instanceof AtomicReader) {
+        // TODO: not useful to check DirectoryReader (redundant with checkindex)
+        // but maybe sometimes run this on the other crazy readers maybeWrapReader creates?
+        _TestUtil.checkReader(r);
       }
       IndexSearcher ret = random.nextBoolean() ? new AssertingIndexSearcher(random, r) : new AssertingIndexSearcher(random, r.getContext());
       ret.setSimilarity(classEnvRule.similarity);
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 88e6d8b..af113b8 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -79,6 +79,8 @@
 
 * SOLR-3855: Doc values support. (Adrien Grand)
 
+* SOLR-4417: Reopen the IndexWriter on SolrCore reload. (Mark Miller)
+
 Bug Fixes
 ----------------------
 
@@ -137,6 +139,13 @@
 * SOLR-4467: Ephemeral directory implementations may not recover correctly 
   because the code to clear the tlog files on startup is off. (Mark Miller)
 
+* SOLR-4413: Fix SolrCore#getIndexDir() to return the current index directory.
+  (Gregg Donovan, Mark Miller)
+  
+* SOLR-4469: A new IndexWriter must be opened on SolrCore reload when the index
+  directory has changed and the previous SolrCore's state should not be 
+  propagated. (Mark Miller, Gregg Donovan)
+
 Optimizations
 ----------------------
 
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 4abdb68..98f71b1 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCore.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCore.java
@@ -218,8 +218,13 @@
     return dataDir;
   }
 
-  public String getIndexDir() {  
-    return dataDir + "index/";
+  public String getIndexDir() {
+    synchronized (searcherLock) {
+      if (_searcher == null) return getNewIndexDir();
+      SolrIndexSearcher searcher = _searcher.get();
+      return searcher.getPath() == null ? dataDir + "index/" : searcher
+          .getPath();
+    }
   }
 
 
@@ -386,7 +391,6 @@
   
   public SolrCore reload(SolrResourceLoader resourceLoader, SolrCore prev) throws IOException,
       ParserConfigurationException, SAXException {
-    // TODO - what if indexwriter settings have changed
     
     SolrConfig config = new SolrConfig(resourceLoader,
         getSolrConfig().getName(), null);
@@ -396,9 +400,19 @@
     
     solrCoreState.increfSolrCoreState();
     
+    if (!getNewIndexDir().equals(getIndexDir())) {
+      // the directory is changing, don't pass on state
+      prev = null;
+    }
+    
     SolrCore core = new SolrCore(getName(), getDataDir(), config,
         schema, coreDescriptor, updateHandler, prev);
     core.solrDelPolicy = this.solrDelPolicy;
+    
+    core.getUpdateHandler().getSolrCoreState().newIndexWriter(core, false, false);
+    
+    core.getSearcher(true, false, null, true);
+    
     return core;
   }
 
@@ -1360,7 +1374,7 @@
         }
 
        // for now, turn off caches if this is for a realtime reader (caches take a little while to instantiate)
-        tmp = new SolrIndexSearcher(this, schema, (realtime ? "realtime":"main"), newReader, true, !realtime, true, directoryFactory);
+        tmp = new SolrIndexSearcher(this, newIndexDir, schema, (realtime ? "realtime":"main"), newReader, true, !realtime, true, directoryFactory);
 
       } else {
         // newestSearcher == null at this point
@@ -1370,7 +1384,7 @@
           // so that we pick up any uncommitted changes and so we don't go backwards
           // in time on a core reload
           DirectoryReader newReader = newReaderCreator.call();
-          tmp = new SolrIndexSearcher(this, schema, (realtime ? "realtime":"main"), newReader, true, !realtime, true, directoryFactory);
+          tmp = new SolrIndexSearcher(this, newIndexDir, schema, (realtime ? "realtime":"main"), newReader, true, !realtime, true, directoryFactory);
         } else {
          // normal open that happens at startup
         // verbose("non-reopen START:");
diff --git a/solr/core/src/java/org/apache/solr/handler/SnapShooter.java b/solr/core/src/java/org/apache/solr/handler/SnapShooter.java
index 4df241d..ecd074a 100644
--- a/solr/core/src/java/org/apache/solr/handler/SnapShooter.java
+++ b/solr/core/src/java/org/apache/solr/handler/SnapShooter.java
@@ -103,7 +103,7 @@
       Collection<String> files = indexCommit.getFileNames();
       FileCopier fileCopier = new FileCopier();
       
-      Directory dir = solrCore.getDirectoryFactory().get(solrCore.getNewIndexDir(), DirContext.DEFAULT, solrCore.getSolrConfig().indexConfig.lockType);
+      Directory dir = solrCore.getDirectoryFactory().get(solrCore.getIndexDir(), DirContext.DEFAULT, solrCore.getSolrConfig().indexConfig.lockType);
       try {
         fileCopier.copyFiles(dir, files, snapShotDir);
       } finally {
diff --git a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
index fbcaf27..3c70213 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
@@ -610,13 +610,17 @@
       }
       if (params.getBool(CoreAdminParams.DELETE_INDEX, false)) {
         core.addCloseHook(new CloseHook() {
+          private String indexDir;
+          
           @Override
-          public void preClose(SolrCore core) {}
+          public void preClose(SolrCore core) {
+            indexDir = core.getIndexDir();
+          }
           
           @Override
           public void postClose(SolrCore core) {
             try {
-              core.getDirectoryFactory().remove(core.getIndexDir());
+              core.getDirectoryFactory().remove(indexDir);
             } catch (IOException e) {
               throw new RuntimeException(e);
             }
@@ -1026,11 +1030,8 @@
     Directory dir;
     long size = 0;
     try {
-      if (!core.getDirectoryFactory().exists(core.getIndexDir())) {
-        dir = core.getDirectoryFactory().get(core.getNewIndexDir(), DirContext.DEFAULT, core.getSolrConfig().indexConfig.lockType);
-      } else {
-        dir = core.getDirectoryFactory().get(core.getIndexDir(), DirContext.DEFAULT, core.getSolrConfig().indexConfig.lockType); 
-      }
+
+      dir = core.getDirectoryFactory().get(core.getIndexDir(), DirContext.DEFAULT, core.getSolrConfig().indexConfig.lockType); 
 
       try {
         size = DirectoryFactory.sizeOfDirectory(dir);
diff --git a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
index 0ebc453..396bf4d 100644
--- a/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
+++ b/solr/core/src/java/org/apache/solr/search/SolrIndexSearcher.java
@@ -116,27 +116,17 @@
   private Collection<String> storedHighlightFieldNames;
   private DirectoryFactory directoryFactory;
   
-  private final AtomicReader atomicReader; 
+  private final AtomicReader atomicReader;
+  private String path; 
 
   public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, SolrIndexConfig config, String name, boolean enableCache, DirectoryFactory directoryFactory) throws IOException {
     // we don't need to reserve the directory because we get it from the factory
-    this(core, schema,name, core.getIndexReaderFactory().newReader(directoryFactory.get(path, DirContext.DEFAULT, config.lockType), core), true, enableCache, false, directoryFactory);
+    this(core, path, schema,name, core.getIndexReaderFactory().newReader(directoryFactory.get(path, DirContext.DEFAULT, config.lockType), core), true, enableCache, false, directoryFactory);
   }
 
-  private static String getIndexDir(Directory dir) {
-    if (dir instanceof FSDirectory) {
-      return ((FSDirectory)dir).getDirectory().getAbsolutePath();
-    } else if (dir instanceof NRTCachingDirectory) {
-      // recurse on the delegate
-      return getIndexDir(((NRTCachingDirectory) dir).getDelegate());
-    } else {
-      log.warn("WARNING: Directory impl does not support setting indexDir: " + dir.getClass().getName());
-      return null;
-    }
-  }
-
-  public SolrIndexSearcher(SolrCore core, IndexSchema schema, String name, DirectoryReader r, boolean closeReader, boolean enableCache, boolean reserveDirectory, DirectoryFactory directoryFactory) throws IOException {
+  public SolrIndexSearcher(SolrCore core, String path, IndexSchema schema, String name, DirectoryReader r, boolean closeReader, boolean enableCache, boolean reserveDirectory, DirectoryFactory directoryFactory) throws IOException {
     super(r);
+    this.path = path;
     this.directoryFactory = directoryFactory;
     this.reader = r;
     this.atomicReader = SlowCompositeReaderWrapper.wrap(r);
@@ -210,6 +200,10 @@
     // do this at the end since an exception in the constructor means we won't close    
     numOpens.incrementAndGet();
   }
+  
+  public String getPath() {
+    return path;
+  }
 
   @Override
   public String toString() {
diff --git a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
index 83b1b5e..fed183d 100644
--- a/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
+++ b/solr/core/src/test/org/apache/solr/cloud/BasicDistributedZkTest.java
@@ -25,7 +25,6 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CompletionService;
@@ -54,8 +53,6 @@
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrInputDocument;
 import org.apache.solr.common.cloud.ClusterState;
-import org.apache.solr.common.cloud.DocCollection;
-import org.apache.solr.common.cloud.Replica;
 import org.apache.solr.common.cloud.Slice;
 import org.apache.solr.common.cloud.ZkCoreNodeProps;
 import org.apache.solr.common.cloud.ZkNodeProps;
@@ -79,7 +76,7 @@
 public class BasicDistributedZkTest extends AbstractFullDistribZkTestBase {
   
   private static final String DEFAULT_COLLECTION = "collection1";
-  private static final boolean DEBUG = false;
+  protected static final boolean DEBUG = false;
   String t1="a_t";
   String i1="a_si";
   String nint = "n_i";
@@ -111,9 +108,6 @@
   
   @BeforeClass
   public static void beforeThisClass2() throws Exception {
-    // TODO: we use an fs based dir because something
-    // like a ram dir will not recover correctly right now
-    useFactory(null);
   }
   
   @Before
@@ -334,338 +328,12 @@
     testUpdateProcessorsRunOnlyOnce("distrib-dup-test-chain-explicit");
     testUpdateProcessorsRunOnlyOnce("distrib-dup-test-chain-implicit");
 
-    testCoreUnloadAndLeaders();
-    testUnloadLotsOfCores();
     testStopAndStartCoresInOneInstance();
-    testUnloadShardAndCollection();
     // Thread.sleep(10000000000L);
     if (DEBUG) {
       super.printLayout();
     }
   }
-
-  private void testUnloadShardAndCollection() throws Exception{
-    // create one leader and one replica
-    
-    Create createCmd = new Create();
-    createCmd.setCoreName("test_unload_shard_and_collection_1");
-    String collection = "test_unload_shard_and_collection";
-    createCmd.setCollection(collection);
-    String coreDataDir = dataDir.getAbsolutePath() + File.separator
-        + System.currentTimeMillis() + collection + "1";
-    createCmd.setDataDir(coreDataDir);
-    createCmd.setNumShards(2);
-    
-    SolrServer client = clients.get(0);
-    String url1 = getBaseUrl(client);
-    HttpSolrServer server = new HttpSolrServer(url1);
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    server.request(createCmd);
-    
-    createCmd = new Create();
-    createCmd.setCoreName("test_unload_shard_and_collection_2");
-    collection = "test_unload_shard_and_collection";
-    createCmd.setCollection(collection);
-    coreDataDir = dataDir.getAbsolutePath() + File.separator
-        + System.currentTimeMillis() + collection + "2";
-    createCmd.setDataDir(coreDataDir);
-    
-    server.request(createCmd);
-
-    // now unload one of the two
-    Unload unloadCmd = new Unload(false);
-    unloadCmd.setCoreName("test_unload_shard_and_collection_2");
-    server.request(unloadCmd);
-    
-    // there should be only one shard
-    Slice shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2");
-    long timeoutAt = System.currentTimeMillis() + 30000;
-    while (shard2 != null) {
-      if (System.currentTimeMillis() > timeoutAt) {
-        printLayout();
-        fail("Still found shard");
-      }
-      
-      Thread.sleep(50);
-      shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2");
-    }
-
-    Slice shard1 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard1");
-    assertNotNull(shard1);
-    assertTrue(getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collection));
-    
-    // now unload one of the other
-    unloadCmd = new Unload(false);
-    unloadCmd.setCoreName("test_unload_shard_and_collection_1");
-    server.request(unloadCmd);
-    
-    //printLayout();
-    // the collection should be gone
-    timeoutAt = System.currentTimeMillis() + 30000;
-    while (getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collection)) {
-      if (System.currentTimeMillis() > timeoutAt) {
-        printLayout();
-        fail("Still found collection");
-      }
-      
-      Thread.sleep(50);
-    }
-    
-  }
-
-  /**
-   * @throws Exception on any problem
-   */
-  private void testCoreUnloadAndLeaders() throws Exception {
-    // create a new collection collection
-    SolrServer client = clients.get(0);
-    String url1 = getBaseUrl(client);
-    HttpSolrServer server = new HttpSolrServer(url1);
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    
-    Create createCmd = new Create();
-    createCmd.setCoreName("unloadcollection1");
-    createCmd.setCollection("unloadcollection");
-    createCmd.setNumShards(1);
-    String core1DataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection1" + "_1n";
-    createCmd.setDataDir(core1DataDir);
-    server.request(createCmd);
-    
-    ZkStateReader zkStateReader = getCommonCloudSolrServer().getZkStateReader();
-    
-    zkStateReader.updateClusterState(true);
-
-    int slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size();
-    assertEquals(1, slices);
-    
-    client = clients.get(1);
-    String url2 = getBaseUrl(client);
-    server = new HttpSolrServer(url2);
-    
-    createCmd = new Create();
-    createCmd.setCoreName("unloadcollection2");
-    createCmd.setCollection("unloadcollection");
-    String core2dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection1" + "_2n";
-    createCmd.setDataDir(core2dataDir);
-    server.request(createCmd);
-    
-    zkStateReader.updateClusterState(true);
-    slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size();
-    assertEquals(1, slices);
-    
-    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
-    
-    ZkCoreNodeProps leaderProps = getLeaderUrlFromZk("unloadcollection", "shard1");
-    
-    Random random = random();
-    HttpSolrServer collectionClient;
-    if (random.nextBoolean()) {
-      collectionClient = new HttpSolrServer(leaderProps.getCoreUrl());
-      // lets try and use the solrj client to index and retrieve a couple
-      // documents
-      SolrInputDocument doc1 = getDoc(id, 6, i1, -600, tlong, 600, t1,
-          "humpty dumpy sat on a wall");
-      SolrInputDocument doc2 = getDoc(id, 7, i1, -600, tlong, 600, t1,
-          "humpty dumpy3 sat on a walls");
-      SolrInputDocument doc3 = getDoc(id, 8, i1, -600, tlong, 600, t1,
-          "humpty dumpy2 sat on a walled");
-      collectionClient.add(doc1);
-      collectionClient.add(doc2);
-      collectionClient.add(doc3);
-      collectionClient.commit();
-    }
-
-    // create another replica for our collection
-    client = clients.get(2);
-    String url3 = getBaseUrl(client);
-    server = new HttpSolrServer(url3);
-    
-    createCmd = new Create();
-    createCmd.setCoreName("unloadcollection3");
-    createCmd.setCollection("unloadcollection");
-    String core3dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection" + "_3n";
-    createCmd.setDataDir(core3dataDir);
-    server.request(createCmd);
-    
-    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
-    
-    // so that we start with some versions when we reload...
-    DirectUpdateHandler2.commitOnClose = false;
-    
-    HttpSolrServer addClient = new HttpSolrServer(url3 + "/unloadcollection3");
-    addClient.setConnectionTimeout(15000);
-    addClient.setSoTimeout(30000);
-    // add a few docs
-    for (int x = 20; x < 100; x++) {
-      SolrInputDocument doc1 = getDoc(id, x, i1, -600, tlong, 600, t1,
-          "humpty dumpy sat on a wall");
-      addClient.add(doc1);
-    }
-
-    // don't commit so they remain in the tran log
-    //collectionClient.commit();
-    
-    // unload the leader
-    collectionClient = new HttpSolrServer(leaderProps.getBaseUrl());
-    collectionClient.setConnectionTimeout(15000);
-    collectionClient.setSoTimeout(30000);
-    
-    Unload unloadCmd = new Unload(false);
-    unloadCmd.setCoreName(leaderProps.getCoreName());
-    ModifiableSolrParams p = (ModifiableSolrParams) unloadCmd.getParams();
-
-    collectionClient.request(unloadCmd);
-
-//    Thread.currentThread().sleep(500);
-//    printLayout();
-    
-    int tries = 50;
-    while (leaderProps.getCoreUrl().equals(zkStateReader.getLeaderUrl("unloadcollection", "shard1", 15000))) {
-      Thread.sleep(100);
-      if (tries-- == 0) {
-        fail("Leader never changed");
-      }
-    }
-    
-    // ensure there is a leader
-    zkStateReader.getLeaderRetry("unloadcollection", "shard1", 15000);
-    
-    addClient = new HttpSolrServer(url2 + "/unloadcollection2");
-    addClient.setConnectionTimeout(15000);
-    addClient.setSoTimeout(30000);
-    
-    // add a few docs while the leader is down
-    for (int x = 101; x < 200; x++) {
-      SolrInputDocument doc1 = getDoc(id, x, i1, -600, tlong, 600, t1,
-          "humpty dumpy sat on a wall");
-      addClient.add(doc1);
-    }
-    
-    
-    // create another replica for our collection
-    client = clients.get(3);
-    String url4 = getBaseUrl(client);
-    server = new HttpSolrServer(url4);
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    
-    createCmd = new Create();
-    createCmd.setCoreName("unloadcollection4");
-    createCmd.setCollection("unloadcollection");
-    String core4dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection" + "_4n";
-    createCmd.setDataDir(core4dataDir);
-    server.request(createCmd);
-    
-    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
-    
-    // unload the leader again
-    leaderProps = getLeaderUrlFromZk("unloadcollection", "shard1");
-    collectionClient = new HttpSolrServer(leaderProps.getBaseUrl());
-    collectionClient.setConnectionTimeout(15000);
-    collectionClient.setSoTimeout(30000);
-    
-    unloadCmd = new Unload(false);
-    unloadCmd.setCoreName(leaderProps.getCoreName());
-    p = (ModifiableSolrParams) unloadCmd.getParams();
-    collectionClient.request(unloadCmd);
-    
-    tries = 50;
-    while (leaderProps.getCoreUrl().equals(zkStateReader.getLeaderUrl("unloadcollection", "shard1", 15000))) {
-      Thread.sleep(100);
-      if (tries-- == 0) {
-        fail("Leader never changed");
-      }
-    }
-    
-    zkStateReader.getLeaderRetry("unloadcollection", "shard1", 15000);
-    
-    
-    // set this back
-    DirectUpdateHandler2.commitOnClose = true;
-    
-    // bring the downed leader back as replica
-    server = new HttpSolrServer(leaderProps.getBaseUrl());
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    
-    createCmd = new Create();
-    createCmd.setCoreName(leaderProps.getCoreName());
-    createCmd.setCollection("unloadcollection");
-    createCmd.setDataDir(core1DataDir);
-    server.request(createCmd);
-
-    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
-    
-    server = new HttpSolrServer(url2 + "/unloadcollection");
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    server.commit();
-    SolrQuery q = new SolrQuery("*:*");
-    q.set("distrib", false);
-    long found1 = server.query(q).getResults().getNumFound();
-    server = new HttpSolrServer(url3 + "/unloadcollection");
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    server.commit();
-    q = new SolrQuery("*:*");
-    q.set("distrib", false);
-    long found3 = server.query(q).getResults().getNumFound();
-    server = new HttpSolrServer(url4 + "/unloadcollection");
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(30000);
-    server.commit();
-    q = new SolrQuery("*:*");
-    q.set("distrib", false);
-    long found4 = server.query(q).getResults().getNumFound();
-    
-    // all 3 shards should now have the same number of docs
-    assertEquals(found1, found3);
-    assertEquals(found3, found4);
-    
-  }
-  
-  private void testUnloadLotsOfCores() throws Exception {
-    SolrServer client = clients.get(2);
-    String url3 = getBaseUrl(client);
-    final HttpSolrServer server = new HttpSolrServer(url3);
-    server.setConnectionTimeout(15000);
-    server.setSoTimeout(60000);
-    ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
-        5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
-        new DefaultSolrThreadFactory("testExecutor"));
-    int cnt = random().nextInt(12) + 1;
-    
-    // create the cores
-    createCores(server, executor, "multiunload", 2, cnt);
-    
-    executor.shutdown();
-    executor.awaitTermination(120, TimeUnit.SECONDS);
-    executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 5,
-        TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
-        new DefaultSolrThreadFactory("testExecutor"));
-    for (int j = 0; j < cnt; j++) {
-      final int freezeJ = j;
-      executor.execute(new Runnable() {
-        @Override
-        public void run() {
-          Unload unloadCmd = new Unload(true);
-          unloadCmd.setCoreName("multiunload" + freezeJ);
-          try {
-            server.request(unloadCmd);
-          } catch (SolrServerException e) {
-            throw new RuntimeException(e);
-          } catch (IOException e) {
-            throw new RuntimeException(e);
-          }
-        }
-      });
-      Thread.sleep(random().nextInt(50));
-    }
-    executor.shutdown();
-    executor.awaitTermination(120, TimeUnit.SECONDS);
-  }
   
   private void testStopAndStartCoresInOneInstance() throws Exception {
     SolrServer client = clients.get(0);
@@ -701,7 +369,7 @@
 
   }
 
-  private void createCores(final HttpSolrServer server,
+  protected void createCores(final HttpSolrServer server,
       ThreadPoolExecutor executor, final String collection, final int numShards, int cnt) {
     for (int i = 0; i < cnt; i++) {
       final int freezeI = i;
@@ -729,7 +397,7 @@
     }
   }
 
-  private String getBaseUrl(SolrServer client) {
+  protected String getBaseUrl(SolrServer client) {
     String url2 = ((HttpSolrServer) client).getBaseURL()
         .substring(
             0,
@@ -769,7 +437,7 @@
     }
   }
   
-  private ZkCoreNodeProps getLeaderUrlFromZk(String collection, String slice) {
+  protected ZkCoreNodeProps getLeaderUrlFromZk(String collection, String slice) {
     ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader().getClusterState();
     ZkNodeProps leader = clusterState.getLeader(collection, slice);
     if (leader == null) {
@@ -777,89 +445,7 @@
     }
     return new ZkCoreNodeProps(leader);
   }
-
-  private String checkCollectionExpectations(String collectionName, List<Integer> numShardsNumReplicaList, List<String> nodesAllowedToRunShards) {
-    ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader().getClusterState();
-    
-    int expectedSlices = numShardsNumReplicaList.get(0);
-    // The Math.min thing is here, because we expect replication-factor to be reduced to if there are not enough live nodes to spread all shards of a collection over different nodes
-    int expectedShardsPerSlice = numShardsNumReplicaList.get(1);
-    int expectedTotalShards = expectedSlices * expectedShardsPerSlice;
-    
-      Map<String,DocCollection> collections = clusterState
-          .getCollectionStates();
-      if (collections.containsKey(collectionName)) {
-        Map<String,Slice> slices = collections.get(collectionName).getSlicesMap();
-        // did we find expectedSlices slices/shards?
-      if (slices.size() != expectedSlices) {
-        return "Found new collection " + collectionName + ", but mismatch on number of slices. Expected: " + expectedSlices + ", actual: " + slices.size();
-      }
-      int totalShards = 0;
-      for (String sliceName : slices.keySet()) {
-        for (Replica replica : slices.get(sliceName).getReplicas()) {
-          if (nodesAllowedToRunShards != null && !nodesAllowedToRunShards.contains(replica.getStr(ZkStateReader.NODE_NAME_PROP))) {
-            return "Shard " + replica.getName() + " created on node " + replica.getStr(ZkStateReader.NODE_NAME_PROP) + " not allowed to run shards for the created collection " + collectionName;
-          }
-        }
-        totalShards += slices.get(sliceName).getReplicas().size();
-      }
-      if (totalShards != expectedTotalShards) {
-        return "Found new collection " + collectionName + " with correct number of slices, but mismatch on number of shards. Expected: " + expectedTotalShards + ", actual: " + totalShards; 
-        }
-      return null;
-    } else {
-      return "Could not find new collection " + collectionName;
-    }
-  }
   
-  private void checkForCollection(String collectionName, List<Integer> numShardsNumReplicaList, List<String> nodesAllowedToRunShards)
-      throws Exception {
-    // check for an expectedSlices new collection - we poll the state
-    long timeoutAt = System.currentTimeMillis() + 120000;
-    boolean success = false;
-    String checkResult = "Didnt get to perform a single check";
-    while (System.currentTimeMillis() < timeoutAt) {
-      checkResult = checkCollectionExpectations(collectionName, numShardsNumReplicaList, nodesAllowedToRunShards);
-      if (checkResult == null) {
-        success = true;
-        break;
-      }
-      Thread.sleep(500);
-    }
-    if (!success) {
-      super.printLayout();
-      fail(checkResult);
-      }
-    }
-
-  private void checkCollectionIsNotCreated(String collectionName)
-    throws Exception {
-    // TODO: REMOVE THIS SLEEP WHEN WE HAVE COLLECTION API RESPONSES
-    Thread.sleep(10000);
-    assertFalse(collectionName + " not supposed to exist", getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collectionName));
-  }
-  
-  private void checkForMissingCollection(String collectionName)
-      throws Exception {
-    // check for a  collection - we poll the state
-    long timeoutAt = System.currentTimeMillis() + 30000;
-    boolean found = true;
-    while (System.currentTimeMillis() < timeoutAt) {
-      getCommonCloudSolrServer().getZkStateReader().updateClusterState(true);
-      ClusterState clusterState = getCommonCloudSolrServer().getZkStateReader().getClusterState();
-      Map<String,DocCollection> collections = clusterState
-          .getCollectionStates();
-      if (!collections.containsKey(collectionName)) {
-        found = false;
-        break;
-      }
-      Thread.sleep(100);
-    }
-    if (found) {
-      fail("Found collection that should be gone " + collectionName);
-    }
-  }
-
   /**
    * Expects a RegexReplaceProcessorFactories in the chain which will
    * "double up" the values in two (stored) string fields.
@@ -1335,7 +921,7 @@
   }
 
   volatile CloudSolrServer commondCloudSolrServer;
-  private CloudSolrServer getCommonCloudSolrServer() {
+  protected CloudSolrServer getCommonCloudSolrServer() {
     if (commondCloudSolrServer == null) {
       synchronized(this) {
         try {
diff --git a/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java
new file mode 100644
index 0000000..7c55be1
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/cloud/UnloadDistributedZkTest.java
@@ -0,0 +1,411 @@
+package org.apache.solr.cloud;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Random;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.lucene.util.LuceneTestCase.Slow;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.SolrServerException;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.client.solrj.request.CoreAdminRequest.Create;
+import org.apache.solr.client.solrj.request.CoreAdminRequest.Unload;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.common.cloud.Slice;
+import org.apache.solr.common.cloud.ZkCoreNodeProps;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.update.DirectUpdateHandler2;
+import org.apache.solr.util.DefaultSolrThreadFactory;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+/**
+ * This test simply does a bunch of basic things in solrcloud mode and asserts things
+ * work as expected.
+ */
+@Slow
+public class UnloadDistributedZkTest extends BasicDistributedZkTest {
+  
+  @BeforeClass
+  public static void beforeThisClass3() throws Exception {
+
+  }
+  
+  @Before
+  @Override
+  public void setUp() throws Exception {
+    super.setUp();
+  }
+
+  
+  public UnloadDistributedZkTest() {
+    super();
+  }
+  
+  @Override
+  public void doTest() throws Exception {
+    
+    testCoreUnloadAndLeaders(); // long
+    testUnloadLotsOfCores(); // long
+    
+    testUnloadShardAndCollection();
+    
+    if (DEBUG) {
+      super.printLayout();
+    }
+  }
+
+  private void testUnloadShardAndCollection() throws Exception{
+    // create one leader and one replica
+    
+    Create createCmd = new Create();
+    createCmd.setCoreName("test_unload_shard_and_collection_1");
+    String collection = "test_unload_shard_and_collection";
+    createCmd.setCollection(collection);
+    String coreDataDir = dataDir.getAbsolutePath() + File.separator
+        + System.currentTimeMillis() + collection + "1";
+    createCmd.setDataDir(coreDataDir);
+    createCmd.setNumShards(2);
+    
+    SolrServer client = clients.get(0);
+    String url1 = getBaseUrl(client);
+    HttpSolrServer server = new HttpSolrServer(url1);
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    server.request(createCmd);
+    
+    createCmd = new Create();
+    createCmd.setCoreName("test_unload_shard_and_collection_2");
+    collection = "test_unload_shard_and_collection";
+    createCmd.setCollection(collection);
+    coreDataDir = dataDir.getAbsolutePath() + File.separator
+        + System.currentTimeMillis() + collection + "2";
+    createCmd.setDataDir(coreDataDir);
+    
+    server.request(createCmd);
+
+    // now unload one of the two
+    Unload unloadCmd = new Unload(false);
+    unloadCmd.setCoreName("test_unload_shard_and_collection_2");
+    server.request(unloadCmd);
+    
+    // there should be only one shard
+    Slice shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2");
+    long timeoutAt = System.currentTimeMillis() + 30000;
+    while (shard2 != null) {
+      if (System.currentTimeMillis() > timeoutAt) {
+        printLayout();
+        fail("Still found shard");
+      }
+      
+      Thread.sleep(50);
+      shard2 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard2");
+    }
+
+    Slice shard1 = getCommonCloudSolrServer().getZkStateReader().getClusterState().getSlice(collection, "shard1");
+    assertNotNull(shard1);
+    assertTrue(getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collection));
+    
+    // now unload one of the other
+    unloadCmd = new Unload(false);
+    unloadCmd.setCoreName("test_unload_shard_and_collection_1");
+    server.request(unloadCmd);
+    
+    //printLayout();
+    // the collection should be gone
+    timeoutAt = System.currentTimeMillis() + 30000;
+    while (getCommonCloudSolrServer().getZkStateReader().getClusterState().getCollections().contains(collection)) {
+      if (System.currentTimeMillis() > timeoutAt) {
+        printLayout();
+        fail("Still found collection");
+      }
+      
+      Thread.sleep(50);
+    }
+    
+  }
+
+  /**
+   * @throws Exception on any problem
+   */
+  private void testCoreUnloadAndLeaders() throws Exception {
+    // create a new collection collection
+    SolrServer client = clients.get(0);
+    String url1 = getBaseUrl(client);
+    HttpSolrServer server = new HttpSolrServer(url1);
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    
+    Create createCmd = new Create();
+    createCmd.setCoreName("unloadcollection1");
+    createCmd.setCollection("unloadcollection");
+    createCmd.setNumShards(1);
+    String core1DataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection1" + "_1n";
+    createCmd.setDataDir(core1DataDir);
+    server.request(createCmd);
+    
+    ZkStateReader zkStateReader = getCommonCloudSolrServer().getZkStateReader();
+    
+    zkStateReader.updateClusterState(true);
+
+    int slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size();
+    assertEquals(1, slices);
+    
+    client = clients.get(1);
+    String url2 = getBaseUrl(client);
+    server = new HttpSolrServer(url2);
+    
+    createCmd = new Create();
+    createCmd.setCoreName("unloadcollection2");
+    createCmd.setCollection("unloadcollection");
+    String core2dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection1" + "_2n";
+    createCmd.setDataDir(core2dataDir);
+    server.request(createCmd);
+    
+    zkStateReader.updateClusterState(true);
+    slices = zkStateReader.getClusterState().getCollectionStates().get("unloadcollection").getSlices().size();
+    assertEquals(1, slices);
+    
+    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
+    
+    ZkCoreNodeProps leaderProps = getLeaderUrlFromZk("unloadcollection", "shard1");
+    
+    Random random = random();
+    HttpSolrServer collectionClient;
+    if (random.nextBoolean()) {
+      collectionClient = new HttpSolrServer(leaderProps.getCoreUrl());
+      // lets try and use the solrj client to index and retrieve a couple
+      // documents
+      SolrInputDocument doc1 = getDoc(id, 6, i1, -600, tlong, 600, t1,
+          "humpty dumpy sat on a wall");
+      SolrInputDocument doc2 = getDoc(id, 7, i1, -600, tlong, 600, t1,
+          "humpty dumpy3 sat on a walls");
+      SolrInputDocument doc3 = getDoc(id, 8, i1, -600, tlong, 600, t1,
+          "humpty dumpy2 sat on a walled");
+      collectionClient.add(doc1);
+      collectionClient.add(doc2);
+      collectionClient.add(doc3);
+      collectionClient.commit();
+    }
+
+    // create another replica for our collection
+    client = clients.get(2);
+    String url3 = getBaseUrl(client);
+    server = new HttpSolrServer(url3);
+    
+    createCmd = new Create();
+    createCmd.setCoreName("unloadcollection3");
+    createCmd.setCollection("unloadcollection");
+    String core3dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection" + "_3n";
+    createCmd.setDataDir(core3dataDir);
+    server.request(createCmd);
+    
+    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
+    
+    // so that we start with some versions when we reload...
+    DirectUpdateHandler2.commitOnClose = false;
+    
+    HttpSolrServer addClient = new HttpSolrServer(url3 + "/unloadcollection3");
+    addClient.setConnectionTimeout(15000);
+    addClient.setSoTimeout(30000);
+    // add a few docs
+    for (int x = 20; x < 100; x++) {
+      SolrInputDocument doc1 = getDoc(id, x, i1, -600, tlong, 600, t1,
+          "humpty dumpy sat on a wall");
+      addClient.add(doc1);
+    }
+
+    // don't commit so they remain in the tran log
+    //collectionClient.commit();
+    
+    // unload the leader
+    collectionClient = new HttpSolrServer(leaderProps.getBaseUrl());
+    collectionClient.setConnectionTimeout(15000);
+    collectionClient.setSoTimeout(30000);
+    
+    Unload unloadCmd = new Unload(false);
+    unloadCmd.setCoreName(leaderProps.getCoreName());
+    ModifiableSolrParams p = (ModifiableSolrParams) unloadCmd.getParams();
+
+    collectionClient.request(unloadCmd);
+
+//    Thread.currentThread().sleep(500);
+//    printLayout();
+    
+    int tries = 50;
+    while (leaderProps.getCoreUrl().equals(zkStateReader.getLeaderUrl("unloadcollection", "shard1", 15000))) {
+      Thread.sleep(100);
+      if (tries-- == 0) {
+        fail("Leader never changed");
+      }
+    }
+    
+    // ensure there is a leader
+    zkStateReader.getLeaderRetry("unloadcollection", "shard1", 15000);
+    
+    addClient = new HttpSolrServer(url2 + "/unloadcollection2");
+    addClient.setConnectionTimeout(15000);
+    addClient.setSoTimeout(30000);
+    
+    // add a few docs while the leader is down
+    for (int x = 101; x < 200; x++) {
+      SolrInputDocument doc1 = getDoc(id, x, i1, -600, tlong, 600, t1,
+          "humpty dumpy sat on a wall");
+      addClient.add(doc1);
+    }
+    
+    
+    // create another replica for our collection
+    client = clients.get(3);
+    String url4 = getBaseUrl(client);
+    server = new HttpSolrServer(url4);
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    
+    createCmd = new Create();
+    createCmd.setCoreName("unloadcollection4");
+    createCmd.setCollection("unloadcollection");
+    String core4dataDir = dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "unloadcollection" + "_4n";
+    createCmd.setDataDir(core4dataDir);
+    server.request(createCmd);
+    
+    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
+    
+    // unload the leader again
+    leaderProps = getLeaderUrlFromZk("unloadcollection", "shard1");
+    collectionClient = new HttpSolrServer(leaderProps.getBaseUrl());
+    collectionClient.setConnectionTimeout(15000);
+    collectionClient.setSoTimeout(30000);
+    
+    unloadCmd = new Unload(false);
+    unloadCmd.setCoreName(leaderProps.getCoreName());
+    p = (ModifiableSolrParams) unloadCmd.getParams();
+    collectionClient.request(unloadCmd);
+    
+    tries = 50;
+    while (leaderProps.getCoreUrl().equals(zkStateReader.getLeaderUrl("unloadcollection", "shard1", 15000))) {
+      Thread.sleep(100);
+      if (tries-- == 0) {
+        fail("Leader never changed");
+      }
+    }
+    
+    zkStateReader.getLeaderRetry("unloadcollection", "shard1", 15000);
+    
+    
+    // set this back
+    DirectUpdateHandler2.commitOnClose = true;
+    
+    // bring the downed leader back as replica
+    server = new HttpSolrServer(leaderProps.getBaseUrl());
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    
+    createCmd = new Create();
+    createCmd.setCoreName(leaderProps.getCoreName());
+    createCmd.setCollection("unloadcollection");
+    createCmd.setDataDir(core1DataDir);
+    server.request(createCmd);
+
+    waitForRecoveriesToFinish("unloadcollection", zkStateReader, false);
+    
+    server = new HttpSolrServer(url2 + "/unloadcollection");
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    server.commit();
+    SolrQuery q = new SolrQuery("*:*");
+    q.set("distrib", false);
+    long found1 = server.query(q).getResults().getNumFound();
+    server = new HttpSolrServer(url3 + "/unloadcollection");
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    server.commit();
+    q = new SolrQuery("*:*");
+    q.set("distrib", false);
+    long found3 = server.query(q).getResults().getNumFound();
+    server = new HttpSolrServer(url4 + "/unloadcollection");
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(30000);
+    server.commit();
+    q = new SolrQuery("*:*");
+    q.set("distrib", false);
+    long found4 = server.query(q).getResults().getNumFound();
+    
+    // all 3 shards should now have the same number of docs
+    assertEquals(found1, found3);
+    assertEquals(found3, found4);
+    
+  }
+  
+  private void testUnloadLotsOfCores() throws Exception {
+    SolrServer client = clients.get(2);
+    String url3 = getBaseUrl(client);
+    final HttpSolrServer server = new HttpSolrServer(url3);
+    server.setConnectionTimeout(15000);
+    server.setSoTimeout(60000);
+    ThreadPoolExecutor executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+        5, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+        new DefaultSolrThreadFactory("testExecutor"));
+    int cnt = atLeast(3);
+    
+    // create the cores
+    createCores(server, executor, "multiunload", 2, cnt);
+    
+    executor.shutdown();
+    executor.awaitTermination(120, TimeUnit.SECONDS);
+    executor = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 5,
+        TimeUnit.SECONDS, new SynchronousQueue<Runnable>(),
+        new DefaultSolrThreadFactory("testExecutor"));
+    for (int j = 0; j < cnt; j++) {
+      final int freezeJ = j;
+      executor.execute(new Runnable() {
+        @Override
+        public void run() {
+          Unload unloadCmd = new Unload(true);
+          unloadCmd.setCoreName("multiunload" + freezeJ);
+          try {
+            server.request(unloadCmd);
+          } catch (SolrServerException e) {
+            throw new RuntimeException(e);
+          } catch (IOException e) {
+            throw new RuntimeException(e);
+          }
+        }
+      });
+      Thread.sleep(random().nextInt(50));
+    }
+    executor.shutdown();
+    executor.awaitTermination(120, TimeUnit.SECONDS);
+  }
+
+
+
+
+  
+  @Override
+  public void tearDown() throws Exception {
+    super.tearDown();
+  }
+}
diff --git a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
index 8e71a3f..6474ce8 100644
--- a/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
+++ b/solr/core/src/test/org/apache/solr/handler/TestReplicationHandler.java
@@ -84,7 +84,7 @@
 
 
   @Before
-  public void setup() throws Exception {
+  public void setUp() throws Exception {
     super.setUp();
     // For manual testing only
     // useFactory(null); // force an FS factory
diff --git a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
index 2212dcd..989632e 100644
--- a/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
+++ b/solr/test-framework/src/java/org/apache/solr/BaseDistributedSearchTestCase.java
@@ -100,7 +100,7 @@
         hostContext.append("_");
       }
       hostContext.append(_TestUtil.randomSimpleString(random(), 3));
-      if ( ! "/".equals(hostContext)) {
+      if ( ! "/".equals(hostContext.toString())) {
         // if our random string is empty, this might add a trailing slash, 
         // but our code should be ok with that
         hostContext.append("/").append(_TestUtil.randomSimpleString(random(), 2));