diff --git a/lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java b/lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java
index 1dea2be..dad1b3e 100644
--- a/lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java
+++ b/lucene/src/test-framework/org/apache/lucene/util/LuceneTestCase.java
@@ -64,9 +64,11 @@ import org.apache.lucene.store.MockDirectoryWrapper;
 import org.apache.lucene.store.MockDirectoryWrapper.Throttling;
 import org.apache.lucene.util.FieldCacheSanityChecker.Insanity;
 import org.junit.*;
+import org.junit.rules.MethodRule;
 import org.junit.rules.TestWatchman;
 import org.junit.runner.RunWith;
 import org.junit.runners.model.FrameworkMethod;
+import org.junit.runners.model.Statement;
 
 /**
  * Base class for all Lucene unit tests, Junit3 or Junit4 variant.
@@ -591,6 +593,29 @@ public abstract class LuceneTestCase extends Assert {
       super.starting(method);
     }
   };
+  
+  /** 
+   * The thread executing the current test case.
+   * @see #isTestThread()
+   */
+  volatile Thread testCaseThread;
+
+  /** @see #testCaseThread */
+  @Rule
+  public final MethodRule setTestThread = new MethodRule() {
+    public Statement apply(final Statement s, FrameworkMethod fm, Object target) {
+      return new Statement() {
+        public void evaluate() throws Throwable {
+          try {
+            LuceneTestCase.this.testCaseThread = Thread.currentThread();
+            s.evaluate();
+          } finally {
+            LuceneTestCase.this.testCaseThread = null;
+          }
+        }
+      };
+    }
+  };
 
   @Before
   public void setUp() throws Exception {
@@ -635,6 +660,15 @@ public abstract class LuceneTestCase extends Assert {
     return getClass().getName() + "." + getName();
   }
 
+  /**
+   * Returns true if and only if the calling thread is the primary thread 
+   * executing the test case. 
+   */
+  protected boolean isTestThread() {
+    assertNotNull("Test case thread not set?", testCaseThread);
+    return Thread.currentThread() == testCaseThread;
+  }
+
   @After
   public void tearDown() throws Exception {
     State oldState = state; // capture test execution state
@@ -1373,7 +1407,7 @@ public abstract class LuceneTestCase extends Assert {
 
   static final Random seedRand = new Random();
   protected static final SmartRandom random = new SmartRandom(0);
-  
+
   private String name = "<unknown>";
 
   /**
diff --git a/lucene/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java b/lucene/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
index 2f41d4e..bd22d5b 100644
--- a/lucene/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
+++ b/lucene/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
@@ -30,7 +30,7 @@ import org.apache.lucene.util.LuceneTestCase;
 
 public class TestConcurrentMergeScheduler extends LuceneTestCase {
   
-  private static class FailOnlyOnFlush extends MockDirectoryWrapper.Failure {
+  private class FailOnlyOnFlush extends MockDirectoryWrapper.Failure {
     boolean doFail;
     boolean hitExc;
 
@@ -46,8 +46,7 @@ public class TestConcurrentMergeScheduler extends LuceneTestCase {
 
     @Override
     public void eval(MockDirectoryWrapper dir)  throws IOException {
-      if (doFail && (Thread.currentThread().getName().equals("main") 
-          || Thread.currentThread().getName().equals("Main Thread"))) {
+      if (doFail && isTestThread()) {
         boolean isDoFlush = false;
         boolean isClose = false;
         StackTraceElement[] trace = new Exception().getStackTrace();
