Rolling back c5720 because it broke the build. 



git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@5722 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/common.ant.xml b/common.ant.xml
index e6ccd23..37cfcce 100755
--- a/common.ant.xml
+++ b/common.ant.xml
@@ -160,7 +160,7 @@
 
   <macrodef name="gwt.junit">
     <!-- TODO: make this more generic / refactor so it can be used from dev/core -->
-    <attribute name="test.args" default="-batch module" />
+    <attribute name="test.args" default="" />
     <attribute name="test.out" default="" />
     <attribute name="test.reports" default="@{test.out}/reports" />
     <attribute name="test.cases" default="" />
diff --git a/user/src/com/google/gwt/junit/BatchingStrategy.java b/user/src/com/google/gwt/junit/BatchingStrategy.java
deleted file mode 100644
index 8536d57..0000000
--- a/user/src/com/google/gwt/junit/BatchingStrategy.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.junit;
-
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
-
-import java.util.Set;
-
-/**
- * An interface that specifies how tests should be batched.
- */
-public interface BatchingStrategy {
-
-  /**
-   * Returns the list of tests that should be executed along with this test.
-   */
-  TestInfo[] getTestBlock(TestInfo currentTest);
-}
-
-/**
- * 
- * Strategy that does not batch tests.
- */
-class NoBatchingStrategy implements BatchingStrategy {
-  public TestInfo[] getTestBlock(TestInfo currentTest) {
-    return new TestInfo[] {currentTest};
-  }
-}
-
-/**
- * Strategy that batches all tests belonging to one module.
- */
-class ModuleBatchingStrategy implements BatchingStrategy {
-
-  /**
-   * Returns the list of all tests belonging to the module of
-   * <code>currentTest</code>.
-   */
-  public TestInfo[] getTestBlock(TestInfo currentTest) {
-    String moduleName = currentTest.getTestModule();
-    if (moduleName.endsWith(".JUnit")) {
-      moduleName = moduleName.substring(0, moduleName.length()
-          - ".JUnit".length());
-    }
-    Set<TestInfo> allTestsInModule = GWTTestCase.ALL_GWT_TESTS.get(moduleName);
-    if (allTestsInModule != null) {
-      return allTestsInModule.toArray(new TestInfo[allTestsInModule.size()]);
-    }
-    // No data, default to just this test.
-    return new TestInfo[] {currentTest};
-  }
-}
diff --git a/user/src/com/google/gwt/junit/JUnitMessageQueue.java b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
index 4cec301..169391c 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -23,11 +23,10 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
 
 /**
- * A message queue to pass data between {@link JUnitShell} and
- * {@link com.google.gwt.junit.server.JUnitHostImpl} in a thread-safe manner.
+ * A message queue to pass data between {@link JUnitShell} and {@link
+ * com.google.gwt.junit.server.JUnitHostImpl} in a thread-safe manner.
  * 
  * <p>
  * The public methods are called by the servlet to find out what test to execute
@@ -46,10 +45,8 @@
    */
   public static class ClientStatus {
     public final String clientId;
-    /**
-     * Stores the testResults for the current block of tests.
-     */
-    public Map<TestInfo, JUnitResult> currentTestBlockResults = null;
+
+    public JUnitResult currentTestResults = null;
     public boolean hasRequestedCurrentTest = false;
     public boolean isNew = true;
 
@@ -71,7 +68,7 @@
   /**
    * The current test to execute.
    */
-  private TestInfo[] currentBlock;
+  private TestInfo currentTest;
 
   /**
    * The number of TestCase clients executing in parallel.
@@ -91,14 +88,14 @@
   }
 
   /**
-   * Called by the servlet to query for for the next block to test.
+   * Called by the servlet to query for for the next method to test.
    * 
    * @param timeout how long to wait for an answer
-   * @return the next test to run, or <code>null</code> if <code>timeout</code>
-   *         is exceeded or the next test does not match
+   * @return the next test to run, or <code>null</code> if
+   *         <code>timeout</code> is exceeded or the next test does not match
    *         <code>testClassName</code>
    */
-  public TestInfo[] getNextTestBlock(String clientId, long timeout)
+  public TestInfo getNextTestInfo(String clientId, long timeout)
       throws TimeoutException {
     synchronized (clientStatusesLock) {
       ClientStatus clientStatus = clientStatuses.get(clientId);
@@ -109,7 +106,7 @@
 
       long startTime = System.currentTimeMillis();
       long stopTime = startTime + timeout;
-      while (clientStatus.currentTestBlockResults != null) {
+      while (clientStatus.currentTestResults != null) {
         long timeToWait = stopTime - System.currentTimeMillis();
         if (timeToWait < 1) {
           double elapsed = (System.currentTimeMillis() - startTime) / 1000.0;
@@ -133,27 +130,20 @@
 
       // Record that this client has retrieved the current test.
       clientStatus.hasRequestedCurrentTest = true;
-      return currentBlock;
+      return currentTest;
     }
   }
 
-  public void reportFatalLaunch(String clientId, JUnitResult result) {
-    // Fatal launch error, cause this client to fail the whole block.
-    Map<TestInfo, JUnitResult> results = new HashMap<TestInfo, JUnitResult>();
-    for (TestInfo testInfo : currentBlock) {
-      results.put(testInfo, result);
-    }
-    reportResults(clientId, results);
-  }
-
   /**
    * Called by the servlet to report the results of the last test to run.
    * 
-   * @param results the result of running the test block
+   * @param testInfo the testInfo the result is for
+   * @param results the result of running the test
    */
-  public void reportResults(String clientId, Map<TestInfo, JUnitResult> results) {
+  public void reportResults(String clientId, TestInfo testInfo,
+      JUnitResult results) {
     synchronized (clientStatusesLock) {
-      if (results != null && !resultsMatchCurrentBlock(results)) {
+      if (testInfo != null && !testInfo.equals(currentTest)) {
         // A client is reporting results for the wrong test.
         return;
       }
@@ -167,7 +157,7 @@
         clientStatus = new ClientStatus(clientId);
         clientStatuses.put(clientId, clientStatus);
       }
-      clientStatus.currentTestBlockResults = results;
+      clientStatus.currentTestResults = results;
       clientStatusesLock.notifyAll();
     }
   }
@@ -178,10 +168,10 @@
    * @return Fetches a human-readable representation of the current test object
    */
   String getCurrentTestName() {
-    if (currentBlock == null) {
+    if (currentTest == null) {
       return "(no test)";
     }
-    return currentBlock[0].toString();
+    return currentTest.toString();
   }
 
   /**
@@ -222,24 +212,11 @@
    * 
    * @return A map of results from all clients.
    */
-  Map<TestInfo, Map<String, JUnitResult>> getResults() {
+  Map<String, JUnitResult> getResults() {
     synchronized (clientStatusesLock) {
-      /*
-       * All this overly complicated piece of code does is transform mappings
-       * keyed by clientId into mappings keyed by TestInfo.
-       */
-      Map<TestInfo, Map<String, JUnitResult>> result = new HashMap<TestInfo, Map<String, JUnitResult>>();
+      Map<String, JUnitResult> result = new HashMap<String, JUnitResult>();
       for (ClientStatus clientStatus : clientStatuses.values()) {
-        for (Entry<TestInfo, JUnitResult> entry : clientStatus.currentTestBlockResults.entrySet()) {
-          TestInfo testInfo = entry.getKey();
-          JUnitResult clientResultForThisTest = entry.getValue();
-          Map<String, JUnitResult> targetMap = result.get(testInfo);
-          if (targetMap == null) {
-            targetMap = new HashMap<String, JUnitResult>();
-            result.put(testInfo, targetMap);
-          }
-          targetMap.put(clientStatus.clientId, clientResultForThisTest);
-        }
+        result.put(clientStatus.clientId, clientStatus.currentTestResults);
       }
       return result;
     }
@@ -295,7 +272,7 @@
       int itemCount = 0;
       for (ClientStatus clientStatus : clientStatuses.values()) {
         if (clientStatus.hasRequestedCurrentTest
-            && clientStatus.currentTestBlockResults == null) {
+            && clientStatus.currentTestResults == null) {
           if (itemCount > 0) {
             buf.append(", ");
           }
@@ -327,7 +304,7 @@
         return false;
       }
       for (ClientStatus clientStatus : clientStatuses.values()) {
-        if (clientStatus.currentTestBlockResults == null) {
+        if (clientStatus.currentTestResults == null) {
           return false;
         }
       }
@@ -338,12 +315,12 @@
   /**
    * Called by the shell to set the next test to run.
    */
-  void setNextTestBlock(TestInfo[] testBlock) {
+  void setNextTest(TestInfo testInfo) {
     synchronized (clientStatusesLock) {
-      this.currentBlock = testBlock;
+      this.currentTest = testInfo;
       for (ClientStatus clientStatus : clientStatuses.values()) {
         clientStatus.hasRequestedCurrentTest = false;
-        clientStatus.currentTestBlockResults = null;
+        clientStatus.currentTestResults = null;
       }
       clientStatusesLock.notifyAll();
     }
@@ -357,14 +334,4 @@
       }
     }
   }
-
-  private boolean resultsMatchCurrentBlock(Map<TestInfo, JUnitResult> results) {
-    assert results.size() == currentBlock.length;
-    for (TestInfo testInfo : currentBlock) {
-      if (!results.containsKey(testInfo)) {
-        return false;
-      }
-    }
-    return true;
-  }
 }
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 862b6d1..82cc08a 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -44,7 +44,6 @@
 import junit.framework.TestResult;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.regex.Matcher;
@@ -67,10 +66,10 @@
  * </p>
  * 
  * <p>
- * The client classes consist of the translatable version of
- * {@link com.google.gwt.junit.client.GWTTestCase}, translatable JUnit classes,
- * and the user's own {@link com.google.gwt.junit.client.GWTTestCase}-derived
- * class. The client communicates to the server via RPC.
+ * The client classes consist of the translatable version of {@link
+ * com.google.gwt.junit.client.GWTTestCase}, translatable JUnit classes, and the
+ * user's own {@link com.google.gwt.junit.client.GWTTestCase}-derived class.
+ * The client communicates to the server via RPC.
  * </p>
  * 
  * <p>
@@ -239,37 +238,6 @@
         }
       });
 
-      // TODO: currently, only two values but soon may have multiple values.
-      registerHandler(new ArgHandlerString() {
-        @Override
-        public String getPurpose() {
-          return "Configure batch execution of tests";
-        }
-
-        @Override
-        public String getTag() {
-          return "-batch";
-        }
-
-        @Override
-        public String[] getTagArgs() {
-          return new String[] {"module"};
-        }
-
-        @Override
-        public boolean isUndocumented() {
-          return true;
-        }
-
-        @Override
-        public boolean setString(String str) {
-          if (str.equals("module")) {
-            batchingStrategy = new ModuleBatchingStrategy();
-          }
-          return true;
-        }
-      });
-
       registerHandler(new ArgHandler() {
         @Override
         public String[] getDefaultArgs() {
@@ -369,8 +337,8 @@
 
   /**
    * The amount of time to wait for all clients to complete a single test
-   * method, in milliseconds, measured from when the <i>last</i> client connects
-   * (and thus starts the test). 5 minutes.
+   * method, in milliseconds, measured from when the <i>last</i> client
+   * connects (and thus starts the test). 5 minutes.
    */
   private static final long TEST_METHOD_TIMEOUT_MILLIS = 300000;
 
@@ -397,8 +365,8 @@
 
   /**
    * Entry point for {@link com.google.gwt.junit.client.GWTTestCase}. Gets or
-   * creates the singleton {@link JUnitShell} and invokes its
-   * {@link #runTestImpl(String, TestCase, TestResult, Strategy)}.
+   * creates the singleton {@link JUnitShell} and invokes its {@link
+   * #runTestImpl(String, TestCase, TestResult, Strategy)}.
    */
   public static void runTest(String moduleName, TestCase testCase,
       TestResult testResult) throws UnableToCompleteException {
@@ -477,11 +445,6 @@
   }
 
   /**
-   * Determines how to batch up tests for execution.
-   */
-  private BatchingStrategy batchingStrategy = new NoBatchingStrategy();
-
-  /**
    * When headless, all logging goes to the console.
    */
   private PrintWriterTreeLogger consoleLogger;
@@ -547,8 +510,6 @@
    */
   private long testMethodTimeout;
 
-  private Map<TestInfo, Map<String, JUnitResult>> cachedResults = new HashMap<TestInfo, Map<String, JUnitResult>>();
-
   /**
    * Enforce the singleton pattern. The call to {@link GWTShell}'s ctor forces
    * server mode and disables processing extra arguments as URLs to be shown.
@@ -677,49 +638,6 @@
     super.compile(getTopLogger(), module);
   }
 
-  private void processTestResult(TestInfo testInfo, TestCase testCase,
-      TestResult testResult, Strategy strategy) {
-
-    Map<String, JUnitResult> results = cachedResults.get(testInfo);
-    assert results != null;
-
-    boolean parallelTesting = numClients > 1;
-
-    for (Entry<String, JUnitResult> entry : results.entrySet()) {
-      String clientId = entry.getKey();
-      JUnitResult result = entry.getValue();
-      assert (result != null);
-      Throwable exception = result.getException();
-      // In the case that we're running multiple clients at once, we need to
-      // let the user know the browser in which the failure happened
-      if (parallelTesting && exception != null) {
-        String msg = "Remote test failed at " + clientId;
-        if (exception instanceof AssertionFailedError) {
-          AssertionFailedError newException = new AssertionFailedError(msg
-              + "\n" + exception.getMessage());
-          newException.setStackTrace(exception.getStackTrace());
-          newException.initCause(exception.getCause());
-          exception = newException;
-        } else {
-          exception = new RuntimeException(msg, exception);
-        }
-      }
-
-      // A "successful" failure.
-      if (exception instanceof AssertionFailedError) {
-        testResult.addFailure(testCase, (AssertionFailedError) exception);
-      } else if (exception != null) {
-        // A real failure
-        if (exception instanceof JUnitFatalLaunchException) {
-          lastLaunchFailed = true;
-        }
-        testResult.addError(testCase, exception);
-      }
-
-      strategy.processResult(testCase, result);
-    }
-  }
-
   /**
    * Runs a particular test case.
    */
@@ -764,19 +682,8 @@
       return;
     }
 
-    TestInfo testInfo = new TestInfo(currentModule.getName(),
-        testCase.getClass().getName(), testCase.getName());
-    if (cachedResults.containsKey(testInfo)) {
-      // Already have a result.
-      processTestResult(testInfo, testCase, testResult, strategy);
-      return;
-    }
-
-    /*
-     * Need to process test. Set up synchronization.
-     */
-    TestInfo[] testBlock = batchingStrategy.getTestBlock(testInfo);
-    messageQueue.setNextTestBlock(testBlock);
+    messageQueue.setNextTest(new TestInfo(currentModule.getName(),
+        testCase.getClass().getName(), testCase.getName()));
 
     try {
       if (firstLaunch) {
@@ -803,9 +710,43 @@
     }
 
     assert (messageQueue.hasResult());
-    cachedResults = messageQueue.getResults();
-    assert cachedResults.containsKey(testInfo);
-    processTestResult(testInfo, testCase, testResult, strategy);
+    Map<String, JUnitResult> results = messageQueue.getResults();
+
+    boolean parallelTesting = numClients > 1;
+
+    for (Entry<String, JUnitResult> entry : results.entrySet()) {
+      String clientId = entry.getKey();
+      JUnitResult result = entry.getValue();
+      assert (result != null);
+      Throwable exception = result.getException();
+      // In the case that we're running multiple clients at once, we need to
+      // let the user know the browser in which the failure happened
+      if (parallelTesting && exception != null) {
+        String msg = "Remote test failed at " + clientId;
+        if (exception instanceof AssertionFailedError) {
+          AssertionFailedError newException = new AssertionFailedError(msg
+              + "\n" + exception.getMessage());
+          newException.setStackTrace(exception.getStackTrace());
+          newException.initCause(exception.getCause());
+          exception = newException;
+        } else {
+          exception = new RuntimeException(msg, exception);
+        }
+      }
+
+      // A "successful" failure
+      if (exception instanceof AssertionFailedError) {
+        testResult.addFailure(testCase, (AssertionFailedError) exception);
+      } else if (exception != null) {
+        // A real failure
+        if (exception instanceof JUnitFatalLaunchException) {
+          lastLaunchFailed = true;
+        }
+        testResult.addError(testCase, exception);
+      }
+
+      strategy.processResult(testCase, result);
+    }
   }
 
   /**
diff --git a/user/src/com/google/gwt/junit/client/GWTTestCase.java b/user/src/com/google/gwt/junit/client/GWTTestCase.java
index d2fe917..256e153 100644
--- a/user/src/com/google/gwt/junit/client/GWTTestCase.java
+++ b/user/src/com/google/gwt/junit/client/GWTTestCase.java
@@ -16,16 +16,10 @@
 package com.google.gwt.junit.client;
 
 import com.google.gwt.junit.JUnitShell;
-import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 
 import junit.framework.TestCase;
 import junit.framework.TestResult;
 
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.Map;
-import java.util.Set;
-
 /**
  * Acts as a bridge between the JUnit environment and the GWT environment. We
  * hook the run method and stash the TestResult object for later communication
@@ -42,12 +36,6 @@
  */
 public abstract class GWTTestCase extends TestCase {
 
-  /**
-   * Records all live GWTTestCases by module name so we can optimize run they
-   * are compiled and run.
-   */
-  public static final Map<String, Set<TestInfo>> ALL_GWT_TESTS = new HashMap<String, Set<TestInfo>>();
-
   /*
    * Object that collects the results of this test case execution.
    */
@@ -145,22 +133,6 @@
     super.run(result);
   }
 
-  @Override
-  public void setName(String name) {
-    super.setName(name);
-
-    // Once the name is set, we can add ourselves to the global set.
-    String moduleName = getModuleName();
-    Set<TestInfo> testsInThisModule = ALL_GWT_TESTS.get(moduleName);
-    if (testsInThisModule == null) {
-      // Preserve the order.
-      testsInThisModule = new LinkedHashSet<TestInfo>();
-      ALL_GWT_TESTS.put(moduleName, testsInThisModule);
-    }
-    testsInThisModule.add(new TestInfo(moduleName + ".JUnit",
-        getClass().getName(), getName()));
-  }
-
   /**
    * Put the current test in asynchronous mode. If the test method completes
    * normally, this test will not immediately succeed. Instead, a <i>delay
@@ -246,10 +218,8 @@
   @Override
   protected void runTest() throws Throwable {
     if (this.getName() == null) {
-      throw new IllegalArgumentException(
-          "GWTTestCases require a name; \""
-              + this.toString()
-              + "\" has none.  Perhaps you used TestSuite.addTest() instead of addTestClass()?");
+      throw new IllegalArgumentException("GWTTestCases require a name; \"" + this.toString() 
+          + "\" has none.  Perhaps you used TestSuite.addTest() instead of addTestClass()?");
     }
 
     String moduleName = getModuleName();
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
index 18bf8cf..a968fd1 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
@@ -19,8 +19,6 @@
 import com.google.gwt.user.client.rpc.IsSerializable;
 import com.google.gwt.user.client.rpc.RemoteService;
 
-import java.util.HashMap;
-
 /**
  * An interface for {@link com.google.gwt.junit.client.GWTTestCase} to
  * communicate with the test process through RPC.
@@ -87,16 +85,17 @@
    * @return the next test to run
    * @throws TimeoutException if the wait for the next method times out.
    */
-  TestInfo[] getFirstMethod() throws TimeoutException;
+  TestInfo getFirstMethod() throws TimeoutException;
 
   /**
    * Reports results for the last method run and gets the name of next method to
    * run.
    * 
-   * @param results the results of executing the test
+   * @param testInfo the testInfo the result is for
+   * @param result the results of executing the test
    * @return the next test to run
    * @throws TimeoutException if the wait for the next method times out.
    */
-  TestInfo[] reportResultsAndGetNextMethod(
-      HashMap<TestInfo, JUnitResult> results) throws TimeoutException;
+  TestInfo reportResultsAndGetNextMethod(TestInfo testInfo, JUnitResult result)
+      throws TimeoutException;
 }
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
index 7c25d06..b26a588 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
@@ -18,8 +18,6 @@
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
-import java.util.HashMap;
-
 /**
  * The asynchronous version of {@link JUnitHost}.
  */
@@ -31,16 +29,17 @@
    * @param callBack the object that will receive the name of the next method to
    *          run
    */
-  void getFirstMethod(AsyncCallback<TestInfo[]> callBack);
+  void getFirstMethod(AsyncCallback<TestInfo> callBack);
 
   /**
    * Reports results for the last method run and gets the name of next method to
    * run.
    * 
-   * @param results the results of the tests
+   * @param testInfo the testInfo the result is for
+   * @param result the result of the test
    * @param callBack the object that will receive the name of the next method to
    *          run
    */
-  void reportResultsAndGetNextMethod(HashMap<TestInfo, JUnitResult> results,
-      AsyncCallback<TestInfo[]> callBack);
+  void reportResultsAndGetNextMethod(TestInfo testInfo, JUnitResult result,
+      AsyncCallback<TestInfo> callBack);
 }
diff --git a/user/src/com/google/gwt/junit/rebind/GWTRunnerGenerator.java b/user/src/com/google/gwt/junit/rebind/GWTRunnerGenerator.java
index f9c16e8..9e34312 100644
--- a/user/src/com/google/gwt/junit/rebind/GWTRunnerGenerator.java
+++ b/user/src/com/google/gwt/junit/rebind/GWTRunnerGenerator.java
@@ -27,7 +27,6 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.junit.client.impl.GWTRunner;
-import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 
@@ -39,6 +38,7 @@
  * This class generates a stub class for classes that derive from GWTTestCase.
  * This stub class provides the necessary bridge between our Hosted or Hybrid
  * mode classes and the JUnit system.
+ * 
  */
 public class GWTRunnerGenerator extends Generator {
 
@@ -77,8 +77,9 @@
 
     String moduleName;
     try {
-      ConfigurationProperty prop = context.getPropertyOracle().getConfigurationProperty(
-          "junit.moduleName");
+      ConfigurationProperty prop
+          = context.getPropertyOracle().getConfigurationProperty(
+              "junit.moduleName");
       moduleName = prop.getValues().get(0);
     } catch (BadPropertyValueException e) {
       logger.log(TreeLogger.ERROR,
@@ -96,20 +97,9 @@
         generatedClass, GWT_RUNNER_NAME);
 
     if (sourceWriter != null) {
-      // Check the global set of active tests for this module.
-      Set<TestInfo> moduleTests = GWTTestCase.ALL_GWT_TESTS.get(moduleName);
-      Set<String> testClasses;
-      if (moduleTests == null || moduleTests.isEmpty()) {
-        // Fall back to pulling in all types in the module.
-        JClassType[] allTestTypes = getAllPossibleTestTypes(context.getTypeOracle());
-        testClasses = getTestTypesForModule(logger, moduleName, allTestTypes);
-      } else {
-        // Must use sorted set to prevent nondeterminism.
-        testClasses = new TreeSet<String>();
-        for (TestInfo testInfo : moduleTests) {
-          testClasses.add(testInfo.getTestClass());
-        }
-      }
+      JClassType[] allTestTypes = getAllPossibleTestTypes(context.getTypeOracle());
+      Set<String> testClasses = getTestTypesForModule(logger, moduleName,
+          allTestTypes);
       writeCreateNewTestCaseMethod(testClasses, sourceWriter);
       sourceWriter.commit(logger);
     }
diff --git a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
index a249549..5da715e 100644
--- a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
+++ b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
@@ -30,7 +30,6 @@
 import java.io.IOException;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.util.HashMap;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -81,22 +80,20 @@
     fld.set(obj, value);
   }
 
-  public TestInfo[] getFirstMethod() throws TimeoutException {
-    return getHost().getNextTestBlock(getClientId(getThreadLocalRequest()),
+  public TestInfo getFirstMethod() throws TimeoutException {
+    return getHost().getNextTestInfo(getClientId(getThreadLocalRequest()),
         TIME_TO_WAIT_FOR_TESTNAME);
   }
 
-  public TestInfo[] reportResultsAndGetNextMethod(
-      HashMap<TestInfo, JUnitResult> results) throws TimeoutException {
-    for (JUnitResult result : results.values()) {
-      initResult(getThreadLocalRequest(), result);
-      ExceptionWrapper ew = result.getExceptionWrapper();
-      result.setException(deserialize(ew));
-    }
+  public TestInfo reportResultsAndGetNextMethod(TestInfo testInfo,
+      JUnitResult result) throws TimeoutException {
+    initResult(getThreadLocalRequest(), result);
+    ExceptionWrapper ew = result.getExceptionWrapper();
+    result.setException(deserialize(ew));
     JUnitMessageQueue host = getHost();
     String clientId = getClientId(getThreadLocalRequest());
-    host.reportResults(clientId, results);
-    return host.getNextTestBlock(clientId, TIME_TO_WAIT_FOR_TESTNAME);
+    host.reportResults(clientId, testInfo, result);
+    return host.getNextTestInfo(clientId, TIME_TO_WAIT_FOR_TESTNAME);
   }
 
   @Override
@@ -108,7 +105,7 @@
       JUnitResult result = new JUnitResult();
       initResult(request, result);
       result.setException(new JUnitFatalLaunchException(requestPayload));
-      getHost().reportFatalLaunch(getClientId(request), result);
+      getHost().reportResults(getClientId(request), null, result);
     } else {
       super.service(request, response);
     }
diff --git a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
index 4072e26..2a679a9 100644
--- a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
+++ b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
@@ -19,15 +19,11 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.DeferredCommand;
 import com.google.gwt.user.client.Timer;
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.rpc.ServiceDefTarget;
 
-import java.util.HashMap;
-
 /**
  * The entry point class for GWTTestCases.
  * 
@@ -41,7 +37,7 @@
    * The RPC callback object for {@link GWTRunner#junitHost}. When
    * {@link #onSuccess(Object)} is called, it's time to run the next test case.
    */
-  private final class JUnitHostListener implements AsyncCallback<TestInfo[]> {
+  private final class JUnitHostListener implements AsyncCallback<TestInfo> {
 
     /**
      * A call to junitHost failed.
@@ -59,11 +55,9 @@
     /**
      * A call to junitHost succeeded; run the next test case.
      */
-    public void onSuccess(TestInfo[] nextTestBlock) {
-      currentBlock = nextTestBlock;
-      currentBlockIndex = 0;
-      currentResults.clear();
-      if (currentBlock != null) {
+    public void onSuccess(TestInfo nextTest) {
+      currentTest = nextTest;
+      if (currentTest != null) {
         doRunTest();
       }
     }
@@ -88,20 +82,9 @@
     return sInstance;
   }
 
-  /**
-   * The current block of tests to execute.
-   */
-  private TestInfo currentBlock[];
+  private JUnitResult currentResult;
 
-  /**
-   * Active test within current block of tests.
-   */
-  private int currentBlockIndex = 0;
-
-  /**
-   * Results for all test cases in the current block.
-   */
-  private HashMap<TestInfo, JUnitResult> currentResults = new HashMap<TestInfo, JUnitResult>();
+  private TestInfo currentTest;
 
   /**
    * The remote service to communicate with.
@@ -133,8 +116,8 @@
   }
 
   public void onModuleLoad() {
-    currentBlock = checkForQueryParamTestToRun();
-    if (currentBlock != null) {
+    currentTest = checkForQueryParamTestToRun();
+    if (currentTest != null) {
       /*
        * Just run a single test with no server-side interaction.
        */
@@ -154,19 +137,8 @@
       // That's it, we're done
       return;
     }
-    TestInfo currentTest = getCurrentTest();
-    currentResults.put(currentTest, result);
-    ++currentBlockIndex;
-    if (currentBlockIndex < currentBlock.length) {
-      // Run the next test after a short delay.
-      DeferredCommand.addCommand(new Command() {
-        public void execute() {
-          doRunTest();
-        }
-      });
-    } else {
-      syncToServer();
-    }
+    currentResult = result;
+    syncToServer();
   }
 
   /**
@@ -175,21 +147,19 @@
    */
   protected abstract GWTTestCase createNewTestCase(String testClass);
 
-  private TestInfo[] checkForQueryParamTestToRun() {
+  private TestInfo checkForQueryParamTestToRun() {
     String testClass = Window.Location.getParameter(TESTCLASS_QUERY_PARAM);
     String testMethod = Window.Location.getParameter(TESTFUNC_QUERY_PARAM);
     if (testClass == null || testMethod == null) {
       return null;
     }
-    // TODO: support blocks of tests?
-    return new TestInfo[] {new TestInfo(GWT.getModuleName(), testClass,
-        testMethod)};
+    return new TestInfo(GWT.getModuleName(), testClass, testMethod);
   }
 
   private void doRunTest() {
     // Make sure the module matches.
     String currentModule = GWT.getModuleName();
-    String newModule = getCurrentTest().getTestModule();
+    String newModule = currentTest.getTestModule();
     if (currentModule.equals(newModule)) {
       // The module is correct.
       runTest();
@@ -204,13 +174,8 @@
     }
   }
 
-  private TestInfo getCurrentTest() {
-    return currentBlock[currentBlockIndex];
-  }
-
   private void runTest() {
     // Dynamically create a new test case.
-    TestInfo currentTest = getCurrentTest();
     GWTTestCase testCase = null;
     Throwable caught = null;
     try {
@@ -232,10 +197,11 @@
   }
 
   private void syncToServer() {
-    if (currentBlock == null) {
+    if (currentTest == null) {
       junitHost.getFirstMethod(junitHostListener);
     } else {
-      junitHost.reportResultsAndGetNextMethod(currentResults, junitHostListener);
+      junitHost.reportResultsAndGetNextMethod(currentTest, currentResult,
+          junitHostListener);
     }
   }