trunk c6943-c6949 were merged into this branch
  Sort & format some junit files.
  Cleanup of CompileStrategy which no longer cares about RunStyle at all.
  RunStyleHtmlUnit was not setting the number of clients.
  UnitShell should never refresh modules; it's not necesary and can lead to race conditions.
  Cleanup of ModuleDef loading.
  GWTShell now reuses dev mode linking code to populate its generated resources directory.
    svn merge --ignore-ancestry -r6942:6949 https://google-web-toolkit.googlecode.com/svn/trunk/ .



git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/2.0@6953 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/branch-info.txt b/branch-info.txt
index e3eb63b..0aeaeb8 100644
--- a/branch-info.txt
+++ b/branch-info.txt
@@ -714,3 +714,13 @@
  Update MissingPlugin app version.
     svn merge --ignore-ancestry -c6939 \
       https://google-web-toolkit.googlecode.com/svn/trunk/ .
+
+trunk c6943-c6949 were merged into this branch
+  Sort & format some junit files.
+  Cleanup of CompileStrategy which no longer cares about RunStyle at all.
+  RunStyleHtmlUnit was not setting the number of clients.
+  UnitShell should never refresh modules; it's not necesary and can lead to race conditions.
+  Cleanup of ModuleDef loading.
+  GWTShell now reuses dev mode linking code to populate its generated resources directory.
+    svn merge --ignore-ancestry -r6942:6949 https://google-web-toolkit.googlecode.com/svn/trunk/ .
+
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index 54380b6..3c39cd0 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -22,7 +22,6 @@
 import com.google.gwt.core.ext.linker.ArtifactSet;
 import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
 import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.shell.ArtifactAcceptor;
 import com.google.gwt.dev.shell.jetty.JettyLauncher;
 import com.google.gwt.dev.ui.RestartServerCallback;
 import com.google.gwt.dev.ui.RestartServerEvent;
@@ -282,18 +281,6 @@
   }
 
   @Override
-  protected ArtifactAcceptor doCreateArtifactAcceptor(TreeLogger logger,
-      final ModuleDef module) throws UnableToCompleteException {
-    final StandardLinkerContext linkerContext = link(logger, module);
-    return new ArtifactAcceptor() {
-      public void accept(TreeLogger relinkLogger, ArtifactSet newArtifacts)
-          throws UnableToCompleteException {
-        relink(relinkLogger, linkerContext, module, newArtifacts);
-      }
-    };
-  }
-
-  @Override
   protected void doShutDownServer() {
     if (server != null) {
       try {
@@ -387,28 +374,7 @@
     return options.getServletContainerLauncher().getName();
   }
 
-  /**
-   * Perform an initial hosted mode link, without overwriting newer or
-   * unmodified files in the output folder.
-   * 
-   * @param logger the logger to use
-   * @param module the module to link
-   * @throws UnableToCompleteException
-   */
-  private StandardLinkerContext link(TreeLogger logger, ModuleDef module)
-      throws UnableToCompleteException {
-    TreeLogger linkLogger = logger.branch(TreeLogger.DEBUG, "Linking module '"
-        + module.getName() + "'");
-
-    // Create a new active linker stack for the fresh link.
-    StandardLinkerContext linkerStack = new StandardLinkerContext(linkLogger,
-        module, options);
-    ArtifactSet artifacts = linkerStack.invokeLink(linkLogger);
-    produceOutput(linkLogger, linkerStack, artifacts, module);
-    return linkerStack;
-  }
-
-  private synchronized void produceOutput(TreeLogger logger,
+  protected synchronized void produceOutput(TreeLogger logger,
       StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef module)
       throws UnableToCompleteException {
     File moduleOutDir = new File(options.getWarDir(), module.getName());
@@ -419,26 +385,6 @@
     }
   }
 
-  /**
-   * Perform hosted mode relink when new artifacts are generated, without
-   * overwriting newer or unmodified files in the output folder.
-   * 
-   * @param logger the logger to use
-   * @param module the module to link
-   * @param newlyGeneratedArtifacts the set of new artifacts
-   * @throws UnableToCompleteException
-   */
-  private void relink(TreeLogger logger, StandardLinkerContext linkerContext,
-      ModuleDef module, ArtifactSet newlyGeneratedArtifacts)
-      throws UnableToCompleteException {
-    TreeLogger linkLogger = logger.branch(TreeLogger.DEBUG,
-        "Relinking module '" + module.getName() + "'");
-
-    ArtifactSet artifacts = linkerContext.invokeRelink(linkLogger,
-        newlyGeneratedArtifacts);
-    produceOutput(linkLogger, linkerContext, artifacts, module);
-  }
-
   private void validateServletTags(TreeLogger logger,
       ServletValidator servletValidator, ModuleDef module, File webXml) {
     TreeLogger servletLogger = logger.branch(TreeLogger.DEBUG,
diff --git a/dev/core/src/com/google/gwt/dev/DevModeBase.java b/dev/core/src/com/google/gwt/dev/DevModeBase.java
index 971ef98..faa78b7 100644
--- a/dev/core/src/com/google/gwt/dev/DevModeBase.java
+++ b/dev/core/src/com/google/gwt/dev/DevModeBase.java
@@ -18,6 +18,8 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.TreeLogger.HelpInfo;
+import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
 import com.google.gwt.dev.Precompile.PrecompileOptionsImpl;
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.cfg.ModuleDefLoader;
@@ -756,9 +758,6 @@
 
   protected abstract HostedModeBaseOptions createOptions();
 
-  protected abstract ArtifactAcceptor doCreateArtifactAcceptor(
-      TreeLogger logger, ModuleDef module) throws UnableToCompleteException;
-
   /**
    * Creates an instance of ShellModuleSpaceHost (or a derived class) using the
    * specified constituent parts. This method is made to be overridden for
@@ -776,10 +775,11 @@
     File shellBaseWorkDir = options.getShellBaseWorkDir(moduleDef);
     File sessionWorkDir = new File(shellBaseWorkDir,
         String.valueOf(uniqueId.getAndIncrement()));
-    Util.recursiveDelete(sessionWorkDir, true);
+    Util.recursiveDelete(sessionWorkDir, false);
+    ArtifactAcceptor artifactAcceptor = createArtifactAcceptor(logger,
+        moduleDef);
     return new ShellModuleSpaceHost(logger, compilationState, moduleDef,
-        options.getGenDir(), new File(sessionWorkDir, "gen"),
-        doCreateArtifactAcceptor(logger, moduleDef));
+        options.getGenDir(), new File(sessionWorkDir, "gen"), artifactAcceptor);
   }
 
   protected abstract void doShutDownServer();
@@ -905,6 +905,27 @@
   }
 
   /**
+   * Perform an initial hosted mode link, without overwriting newer or
+   * unmodified files in the output folder.
+   * 
+   * @param logger the logger to use
+   * @param module the module to link
+   * @throws UnableToCompleteException
+   */
+  protected final StandardLinkerContext link(TreeLogger logger, ModuleDef module)
+      throws UnableToCompleteException {
+    TreeLogger linkLogger = logger.branch(TreeLogger.DEBUG, "Linking module '"
+        + module.getName() + "'");
+
+    // Create a new active linker stack for the fresh link.
+    StandardLinkerContext linkerStack = new StandardLinkerContext(linkLogger,
+        module, options);
+    ArtifactSet artifacts = linkerStack.invokeLink(linkLogger);
+    produceOutput(linkLogger, linkerStack, artifacts, module);
+    return linkerStack;
+  }
+
+  /**
    * Load a module.
    * 
    * @param moduleName name of the module to load
@@ -923,6 +944,10 @@
     return moduleDef;
   }
 
+  protected abstract void produceOutput(TreeLogger logger,
+      StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef module)
+      throws UnableToCompleteException;
+
   protected final void setDone() {
     blockUntilDone.release();
   }
@@ -965,6 +990,17 @@
     return true;
   }
 
+  private ArtifactAcceptor createArtifactAcceptor(TreeLogger logger,
+      final ModuleDef module) throws UnableToCompleteException {
+    final StandardLinkerContext linkerContext = link(logger, module);
+    return new ArtifactAcceptor() {
+      public void accept(TreeLogger relinkLogger, ArtifactSet newArtifacts)
+          throws UnableToCompleteException {
+        relink(relinkLogger, linkerContext, module, newArtifacts);
+      }
+    };
+  }
+
   private DevModeUI createUI() {
     if (headlessMode) {
       return new HeadlessUI(options);
@@ -978,4 +1014,24 @@
 
     return new SwingUI(options);
   }
+
+  /**
+   * Perform hosted mode relink when new artifacts are generated, without
+   * overwriting newer or unmodified files in the output folder.
+   * 
+   * @param logger the logger to use
+   * @param module the module to link
+   * @param newlyGeneratedArtifacts the set of new artifacts
+   * @throws UnableToCompleteException
+   */
+  private void relink(TreeLogger logger, StandardLinkerContext linkerContext,
+      ModuleDef module, ArtifactSet newlyGeneratedArtifacts)
+      throws UnableToCompleteException {
+    TreeLogger linkLogger = logger.branch(TreeLogger.DEBUG,
+        "Relinking module '" + module.getName() + "'");
+
+    ArtifactSet artifacts = linkerContext.invokeRelink(linkLogger,
+        newlyGeneratedArtifacts);
+    produceOutput(linkLogger, linkerContext, artifacts, module);
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/GWTShell.java b/dev/core/src/com/google/gwt/dev/GWTShell.java
index 3bf1332..b7d5c61 100644
--- a/dev/core/src/com/google/gwt/dev/GWTShell.java
+++ b/dev/core/src/com/google/gwt/dev/GWTShell.java
@@ -18,12 +18,10 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.linker.ArtifactSet;
-import com.google.gwt.core.ext.linker.EmittedArtifact;
+import com.google.gwt.core.ext.linker.impl.StandardLinkerContext;
 import com.google.gwt.dev.cfg.ModuleDef;
-import com.google.gwt.dev.shell.ArtifactAcceptor;
 import com.google.gwt.dev.shell.WorkDirs;
 import com.google.gwt.dev.shell.tomcat.EmbeddedTomcatServer;
-import com.google.gwt.dev.util.Util;
 import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
 import com.google.gwt.util.tools.ArgHandlerExtra;
 
@@ -123,9 +121,6 @@
     }
   }
 
-  public static final String GWT_SHELL_PATH = ".gwt-tmp" + File.separator
-      + "shell";
-
   public static String checkHost(String hostUnderConsideration,
       Set<String> hosts) {
     hostUnderConsideration = hostUnderConsideration.toLowerCase(Locale.ENGLISH);
@@ -192,28 +187,6 @@
   }
 
   @Override
-  protected ArtifactAcceptor doCreateArtifactAcceptor(TreeLogger logger,
-      final ModuleDef module) {
-    return new ArtifactAcceptor() {
-      public void accept(TreeLogger logger, ArtifactSet artifacts)
-          throws UnableToCompleteException {
-
-        /*
-         * Copied from StandardLinkerContext.produceOutputDirectory() for legacy
-         * GWTShellServlet support.
-         */
-        for (EmittedArtifact artifact : artifacts.find(EmittedArtifact.class)) {
-          if (!artifact.isPrivate()) {
-            File outFile = new File(options.getShellPublicGenDir(module),
-                artifact.getPartialPath());
-            Util.copy(logger, artifact.getContents(logger), outFile);
-          }
-        }
-      }
-    };
-  }
-
-  @Override
   protected void doShutDownServer() {
     // Stop the HTTP server.
     //
@@ -234,4 +207,11 @@
     }
     return EmbeddedTomcatServer.getPort();
   }
+
+  protected synchronized void produceOutput(TreeLogger logger,
+      StandardLinkerContext linkerStack, ArtifactSet artifacts, ModuleDef module)
+      throws UnableToCompleteException {
+    File moduleOutDir = options.getShellPublicGenDir(module);
+    linkerStack.produceOutputDirectory(logger, artifacts, moduleOutDir);
+  }
 }
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
index b1b7294..8455bff 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefLoader.java
@@ -128,7 +128,7 @@
   }
 
   private static ModuleDef tryGetLoadedModule(TreeLogger logger,
-      String moduleName, boolean refresh) throws UnableToCompleteException {
+      String moduleName, boolean refresh) {
     ModuleDef moduleDef = loadedModules.get(moduleName);
     if (moduleDef == null || moduleDef.isGwtXmlFileStale()) {
       return null;
diff --git a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
index 336bf7c..ac39d73 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/ModuleDefSchema.java
@@ -38,7 +38,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 // CHECKSTYLE_NAMING_OFF
@@ -358,12 +357,12 @@
 
     @SuppressWarnings("unused")
     protected Schema __property_provider_begin(BindingProperty property) {
-      return fChild = new PropertyProviderBodySchema();
+      return fChild = new ScriptSchema();
     }
 
     protected void __property_provider_end(BindingProperty property)
         throws UnableToCompleteException {
-      PropertyProviderBodySchema childSchema = ((PropertyProviderBodySchema) fChild);
+      ScriptSchema childSchema = ((ScriptSchema) fChild);
       String script = childSchema.getScript();
       if (script == null) {
         // This is a problem.
@@ -415,30 +414,21 @@
      * @param src a partial or full url to a script file to inject
      * @return <code>null</code> since there can be no children
      */
+    @SuppressWarnings("unused")
     protected Schema __script_begin(String src) {
-      return fChild = new ScriptReadyBodySchema();
+      return fChild = new ScriptSchema();
     }
 
-    protected void __script_end(String src) throws UnableToCompleteException {
-      ScriptReadyBodySchema childSchema = (ScriptReadyBodySchema) fChild;
-      String js = childSchema.getScriptReadyBlock();
+    protected void __script_end(String src) {
+      ScriptSchema childSchema = (ScriptSchema) fChild;
+      String js = childSchema.getScript();
       if (js != null) {
         logger.log(
             TreeLogger.WARN,
             "Injected scripts no longer require an associated JavaScript block.",
             null);
       }
-
-      // For consistency, we allow the ready functions to use $wnd even though
-      // they'll be running in the context of the host html window anyway.
-      // We make up the difference by injecting a local variable into the
-      // function we wrap around their code.
-      js = "var $wnd = window; " + js;
-
-      int lineNumber = childSchema.getStartLineNumber();
-      JsFunction fn = parseJsBlock(lineNumber, js);
-      Script script = new Script(src, fn);
-      moduleDef.getScripts().append(script);
+      moduleDef.getScripts().append(new Script(src));
     }
 
     protected Schema __servlet_begin(String path, String servletClass)
@@ -852,56 +842,6 @@
   }
 
   /**
-   * Creates singleton instances of objects based on an attribute containing a
-   * class name.
-   */
-  private final class ObjAttrCvt<T> extends AttributeConverter {
-
-    private final Class<T> fReqdSuperclass;
-
-    public ObjAttrCvt(Class<T> reqdSuperclass) {
-      fReqdSuperclass = reqdSuperclass;
-    }
-
-    public Object convertToArg(Schema schema, int lineNumber, String elemName,
-        String attrName, String attrValue) throws UnableToCompleteException {
-
-      Object found = singletonsByName.get(attrValue);
-      if (found != null) {
-        // Found in the cache.
-        //
-        return found;
-      }
-
-      Class<?> foundClass = null;
-      try {
-        // Load the class.
-        //
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        foundClass = cl.loadClass(attrValue);
-        Class<? extends T> clazz = foundClass.asSubclass(fReqdSuperclass);
-
-        T object = clazz.newInstance();
-        singletonsByName.put(attrValue, object);
-        return object;
-      } catch (ClassCastException e) {
-        Messages.INVALID_CLASS_DERIVATION.log(logger, foundClass,
-            fReqdSuperclass, null);
-        throw new UnableToCompleteException();
-      } catch (ClassNotFoundException e) {
-        Messages.UNABLE_TO_LOAD_CLASS.log(logger, attrValue, e);
-        throw new UnableToCompleteException();
-      } catch (InstantiationException e) {
-        Messages.UNABLE_TO_CREATE_OBJECT.log(logger, attrValue, e);
-        throw new UnableToCompleteException();
-      } catch (IllegalAccessException e) {
-        Messages.UNABLE_TO_CREATE_OBJECT.log(logger, attrValue, e);
-        throw new UnableToCompleteException();
-      }
-    }
-  }
-
-  /**
    * Converts property names into their corresponding property objects.
    */
   private final class PropertyAttrCvt extends AttributeConverter {
@@ -1019,32 +959,6 @@
     }
   }
 
-  private static class PropertyProviderBodySchema extends Schema {
-
-    private StringBuffer script;
-
-    private int startLineNumber = -1;
-
-    public PropertyProviderBodySchema() {
-    }
-
-    public void __text(String text) {
-      if (script == null) {
-        script = new StringBuffer();
-        startLineNumber = getLineNumber();
-      }
-      script.append(text);
-    }
-
-    public String getScript() {
-      return script != null ? script.toString() : null;
-    }
-
-    public int getStartLineNumber() {
-      return startLineNumber;
-    }
-  }
-
   private static class PropertyValue {
     public final String token;
 
@@ -1090,13 +1004,13 @@
     }
   }
 
-  private static class ScriptReadyBodySchema extends Schema {
+  private static class ScriptSchema extends Schema {
 
     private StringBuffer script;
 
     private int startLineNumber = -1;
 
-    public ScriptReadyBodySchema() {
+    public ScriptSchema() {
     }
 
     public void __text(String text) {
@@ -1107,7 +1021,7 @@
       script.append(text);
     }
 
-    public String getScriptReadyBlock() {
+    public String getScript() {
       return script != null ? script.toString() : null;
     }
 
@@ -1128,8 +1042,6 @@
    */
   private static final HashMap<String, String> propertySettings = new HashMap<String, String>();
 
-  private static final Map<String, Object> singletonsByName = new HashMap<String, Object>();
-
   private static void addPrefix(String[] strings, String prefix) {
     for (int i = 0; i < strings.length; ++i) {
       strings[i] = prefix + strings[i];
@@ -1137,8 +1049,8 @@
   }
 
   /**
-   * Returns <code>true</code> if the string equals "true" or "yes" using a case
-   * insensitive comparison.
+   * Returns <code>true</code> if the string equals "true" or "yes" using a
+   * case insensitive comparison.
    */
   private static boolean toPrimitiveBoolean(String s) {
     return "yes".equalsIgnoreCase(s) || "true".equalsIgnoreCase(s);
diff --git a/dev/core/src/com/google/gwt/dev/cfg/Script.java b/dev/core/src/com/google/gwt/dev/cfg/Script.java
index 9d2c73b..21d4d8b 100644
--- a/dev/core/src/com/google/gwt/dev/cfg/Script.java
+++ b/dev/core/src/com/google/gwt/dev/cfg/Script.java
@@ -15,8 +15,6 @@
  */
 package com.google.gwt.dev.cfg;
 
-import com.google.gwt.dev.js.ast.JsFunction;
-
 /**
  * Represents configuration for a dynamically-injected script.
  */
@@ -24,15 +22,8 @@
 
   private final String src;
 
-  private final JsFunction jsReadyFn;
-
-  public Script(String src, JsFunction jsReadyFn) {
+  public Script(String src) {
     this.src = src;
-    this.jsReadyFn = jsReadyFn;
-  }
-
-  public JsFunction getJsReadyFunction() {
-    return jsReadyFn;
   }
 
   public String getSrc() {
diff --git a/user/src/com/google/gwt/junit/CompileStrategy.java b/user/src/com/google/gwt/junit/CompileStrategy.java
index b1417e9..e1db74d 100644
--- a/user/src/com/google/gwt/junit/CompileStrategy.java
+++ b/user/src/com/google/gwt/junit/CompileStrategy.java
@@ -78,6 +78,7 @@
    * 
    * @throws UnableToCompleteException if the compilation fails
    */
+  @SuppressWarnings("unused")
   public void maybeCompileAhead() throws UnableToCompleteException {
   }
 
@@ -87,14 +88,13 @@
    * @param moduleName the module name
    * @param syntheticModuleName the synthetic module name
    * @param strategy the strategy
-   * @param runStyle the run style
    * @param batchingStrategy the batching strategy
    * @param treeLogger the logger
    * @return the {@link ModuleDef} describing the synthetic module
    * @throws UnableToCompleteException
    */
   public abstract ModuleDef maybeCompileModule(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException;
 
@@ -104,19 +104,17 @@
    * @param moduleName the module name
    * @param syntheticModuleName the synthetic module name
    * @param strategy the strategy
-   * @param runStyle the run style
    * @param batchingStrategy the batching strategy
    * @param treeLogger the logger
    * @return the {@link ModuleDef} describing the synthetic module
    */
   protected ModuleDef maybeCompileModuleImpl(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException {
 
-    // Let the runstyle compile the module.
     ModuleDef moduleDef = maybeCompileModuleImpl2(moduleName,
-        syntheticModuleName, strategy, runStyle, treeLogger);
+        syntheticModuleName, strategy, treeLogger);
 
     // Add all test blocks for the module if we haven't seen this module before.
     if (!compiledModuleNames.contains(syntheticModuleName)) {
@@ -151,27 +149,26 @@
   }
 
   /**
-   * Let the {@link RunStyle} compile the module if needed
+   * Compile the module if needed.
    * 
    * Visible for testing and mocking.
    * 
    * @param moduleName the module name
    * @param syntheticModuleName the synthetic module name
    * @param strategy the strategy
-   * @param runStyle the run style
    * @param treeLogger the logger
    * @return the {@link ModuleDef} describing the synthetic module
    */
   ModuleDef maybeCompileModuleImpl2(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
-      TreeLogger treeLogger) throws UnableToCompleteException {
+      String syntheticModuleName, Strategy strategy, TreeLogger treeLogger)
+      throws UnableToCompleteException {
     /*
      * Synthesize a synthetic module that derives from the user-specified module
      * but also includes JUnit support.
      */
     ModuleDef moduleDef = ModuleDefLoader.createSyntheticModule(treeLogger,
         syntheticModuleName, new String[] {
-            moduleName, strategy.getModuleInherit()}, true);
+            moduleName, strategy.getModuleInherit()}, false);
 
     // Replace any user entry points with our test runner.
     moduleDef.clearEntryPoints();
@@ -197,23 +194,17 @@
 class ParallelCompileStrategy extends PreCompileStrategy {
 
   /**
-   * The list of all synthetic module names to be compiled.
-   */
-  private List<String> modulesToCompile = new ArrayList<String>();
-
-  /**
-   * The {@link RunStyle} used to compile, which is set on the first compilation
-   * and is the same across all compilations.
-   */
-  private RunStyle runStyle;
-
-  /**
    * The {@link BatchingStrategy} used to compile, which is set on the first
    * compilation and is the same across all compilations.
    */
   private BatchingStrategy batchingStrategy;
 
   /**
+   * The list of all synthetic module names to be compiled.
+   */
+  private List<String> modulesToCompile = new ArrayList<String>();
+
+  /**
    * The {@link TreeLogger} used to compile, which is set on the first
    * compilation and is the same across all compilations.
    */
@@ -230,19 +221,18 @@
       TestModuleInfo moduleInfo = GWTTestCase.getTestsForModule(nextModule);
       String syntheticModuleName = moduleInfo.getSyntheticModuleName();
       maybeCompileModuleImpl(moduleInfo.getModuleName(), syntheticModuleName,
-          moduleInfo.getStrategy(), runStyle, batchingStrategy, treeLogger);
+          moduleInfo.getStrategy(), batchingStrategy, treeLogger);
     }
   }
 
   @Override
   public ModuleDef maybeCompileModule(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException {
 
     // Initialize the map of modules.
     if (preCompiledModuleDefs == null) {
-      this.runStyle = runStyle;
       this.batchingStrategy = batchingStrategy;
       this.treeLogger = treeLogger;
       preCompiledModuleDefs = new HashMap<String, ModuleDef>();
@@ -256,19 +246,19 @@
     ModuleDef moduleDef = preCompiledModuleDefs.get(syntheticModuleName);
     if (moduleDef == null) {
       moduleDef = maybeCompileModuleImpl(moduleName, syntheticModuleName,
-          strategy, runStyle, batchingStrategy, treeLogger);
+          strategy, batchingStrategy, treeLogger);
     }
     return moduleDef;
   }
 
   @Override
   protected ModuleDef maybeCompileModuleImpl(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException {
     modulesToCompile.remove(syntheticModuleName);
     ModuleDef moduleDef = super.maybeCompileModuleImpl(moduleName,
-        syntheticModuleName, strategy, runStyle, batchingStrategy, treeLogger);
+        syntheticModuleName, strategy, batchingStrategy, treeLogger);
     preCompiledModuleDefs.put(syntheticModuleName, moduleDef);
     return moduleDef;
   }
@@ -291,10 +281,10 @@
 
   @Override
   public ModuleDef maybeCompileModule(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException {
-    maybePrecompileModules(runStyle, batchingStrategy, treeLogger);
+    maybePrecompileModules(batchingStrategy, treeLogger);
 
     // Since all test blocks from a module are added to the queue at the
     // same time, we can safely take the module out of the hash map at
@@ -305,9 +295,8 @@
   /**
    * Precompile all modules if needed.
    */
-  private void maybePrecompileModules(RunStyle runStyle,
-      BatchingStrategy batchingStrategy, TreeLogger treeLogger)
-      throws UnableToCompleteException {
+  private void maybePrecompileModules(BatchingStrategy batchingStrategy,
+      TreeLogger treeLogger) throws UnableToCompleteException {
     if (preCompiledModuleDefs == null) {
       preCompiledModuleDefs = new HashMap<String, ModuleDef>();
       for (String moduleName : GWTTestCase.getAllTestModuleNames()) {
@@ -315,7 +304,7 @@
         String syntheticModuleName = moduleInfo.getSyntheticModuleName();
         ModuleDef moduleDef = maybeCompileModuleImpl(
             moduleInfo.getModuleName(), syntheticModuleName,
-            moduleInfo.getStrategy(), runStyle, batchingStrategy, treeLogger);
+            moduleInfo.getStrategy(), batchingStrategy, treeLogger);
         preCompiledModuleDefs.put(syntheticModuleName, moduleDef);
       }
     }
@@ -333,10 +322,10 @@
 
   @Override
   public ModuleDef maybeCompileModule(String moduleName,
-      String syntheticModuleName, Strategy strategy, RunStyle runStyle,
+      String syntheticModuleName, Strategy strategy,
       BatchingStrategy batchingStrategy, TreeLogger treeLogger)
       throws UnableToCompleteException {
     return maybeCompileModuleImpl(moduleName, syntheticModuleName, strategy,
-        runStyle, batchingStrategy, treeLogger);
+        batchingStrategy, treeLogger);
   }
 }
diff --git a/user/src/com/google/gwt/junit/JUnitMessageQueue.java b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
index ddc8550..b8f671a 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -48,9 +48,9 @@
    * Holds the state of an individual client.
    */
   public static class ClientStatus {
+    public int blockIndex = 0;
     public final String clientId;
     public boolean isNew = true;
-    public int blockIndex = 0;
 
     public ClientStatus(String clientId) {
       this.clientId = clientId;
@@ -70,11 +70,6 @@
    * Records results for each client; must lock before accessing.
    */
   private final Map<String, ClientStatus> clientStatuses = new HashMap<String, ClientStatus>();
-  
-  /**
-   * A set of the GWT user agents (eg. ie6, gecko) that have connected. 
-   */
-  private final Set<String> userAgents = new HashSet<String>();
 
   /**
    * The lock used to synchronize access to clientStatuses.
@@ -82,11 +77,22 @@
   private final Object clientStatusesLock = new Object();
 
   /**
+   * Set to true when the last test block has been added. This is used to tell
+   * clients that all tests are complete.
+   */
+  private boolean isLastTestBlockAvailable;
+
+  /**
    * The number of TestCase clients executing in parallel.
    */
   private int numClients = 1;
 
   /**
+   * The list of test blocks to run.
+   */
+  private final List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
+
+  /**
    * Maps the TestInfo to the results from each clientId. If JUnitResult is
    * null, it means that the client requested the test but did not report the
    * results yet.
@@ -94,22 +100,17 @@
   private final Map<TestInfo, Map<String, JUnitResult>> testResults = new HashMap<TestInfo, Map<String, JUnitResult>>();
 
   /**
-   * The list of test blocks to run.
+   * A set of the GWT user agents (eg. ie6, gecko) that have connected.
    */
-  private final List<TestInfo[]> testBlocks = new ArrayList<TestInfo[]>();
-
-  /**
-   * Set to true when the last test block has been added. This is used to tell
-   * clients that all tests are complete.
-   */
-  private boolean isLastTestBlockAvailable;
+  private final Set<String> userAgents = new HashSet<String>();
 
   /**
    * Only instantiable within this package.
    */
-  JUnitMessageQueue() {
+  JUnitMessageQueue(int numClients) {
+    this.numClients = numClients;
   }
-  
+
   /**
    * Called by the servlet to query for for the next block to test.
    * 
@@ -117,8 +118,8 @@
    * @param userAgent the user agent property of the client
    * @param blockIndex the index of the test block to get
    * @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 TestBlock getTestBlock(String clientId, String userAgent,
@@ -246,6 +247,10 @@
     }
   }
 
+  int getNumClients() {
+    return numClients;
+  }
+
   /**
    * Returns how many clients have requested the currently-running test.
    * 
@@ -431,22 +436,6 @@
     }
   }
 
-  /**
-   * Set the number of clients. This must be called before adding any tests.
-   * 
-   * @param numClients The number of parallel clients being served by this
-   *          queue.
-   */
-  void setNumClients(int numClients) {
-    synchronized (clientStatusesLock) {
-      if (testBlocks.size() > 0) {
-        throw new IllegalStateException(
-            "Cannot change number of clients after adding tests");
-      }
-      this.numClients = numClients;
-    }
-  }
-
   void waitForResults(int millis) {
     synchronized (clientStatusesLock) {
       try {
@@ -457,7 +446,7 @@
   }
 
   /**
-   * Ensure that a {@link ClientStatus} for the clientId exists. 
+   * Ensure that a {@link ClientStatus} for the clientId exists.
    * 
    * @param clientId the id of the client
    * @return the {@link ClientStatus} for the client
@@ -487,7 +476,8 @@
     return results;
   }
 
-  private boolean isMember(Throwable exception, Set<Class<? extends Throwable>> throwableSet) {
+  private boolean isMember(Throwable exception,
+      Set<Class<? extends Throwable>> throwableSet) {
     for (Class<? extends Throwable> throwable : throwableSet) {
       if (throwable.isInstance(exception)) {
         return true;
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 7c23420..d564ae5 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -356,7 +356,7 @@
           return true;
         }
       });
-      
+
       registerHandler(new ArgHandlerInt() {
         @Override
         public String getPurpose() {
@@ -372,12 +372,12 @@
         public String[] getTagArgs() {
           return new String[] {"1"};
         }
-        
+
         @Override
         public boolean isRequired() {
           return false;
         }
-        
+
         @Override
         public boolean isUndocumented() {
           return false;
@@ -603,8 +603,6 @@
       if (!argProcessor.processArgs(args)) {
         throw new JUnitFatalLaunchException("Error processing shell arguments");
       }
-      unitTestShell.messageQueue = new JUnitMessageQueue();
-
       if (!unitTestShell.startUp()) {
         throw new JUnitFatalLaunchException("Shell failed to start");
       }
@@ -616,44 +614,35 @@
   }
 
   /**
-   * Determines how to batch up tests for execution.
-   */
-  private BatchingStrategy batchingStrategy = new NoBatchingStrategy();
-
-  /**
    * 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). Set by the -testMethodTimeout argument.
+   * method, in milliseconds, measured from when the <i>last</i> client
+   * connects (and thus starts the test). Set by the -testMethodTimeout
+   * argument.
    */
   private long baseTestMethodTimeoutMillis;
 
   /**
-   * Test method timeout as modified by the batching strategy.
+   * Determines how to batch up tests for execution.
    */
-  private long testBatchingMethodTimeoutMillis;
+  private BatchingStrategy batchingStrategy = new NoBatchingStrategy();
 
   /**
-   * Max number of times a test method must be tried. 
-   */
-  private int tries;
-  
-  /**
    * Determines how modules are compiled.
    */
   private CompileStrategy compileStrategy = new SimpleCompileStrategy(
       JUnitShell.this);
 
   /**
-   * Name of the module containing the current/last module to run.
-   */
-  private ModuleDef currentModule;
-
-  /**
    * A type oracle for the current module, used to validate class existence.
    */
   private CompilationState currentCompilationState;
 
   /**
+   * Name of the module containing the current/last module to run.
+   */
+  private ModuleDef currentModule;
+
+  /**
    * The name of the current test case being run.
    */
   private TestInfo currentTestInfo;
@@ -689,13 +678,6 @@
   private JUnitMessageQueue messageQueue;
 
   /**
-   * The number of test clients executing in parallel. With -remoteweb, users
-   * can specify a number of parallel test clients, but by default we only have
-   * 1.
-   */
-  private int numClients = 1;
-
-  /**
    * An exception that should by fired the next time runTestImpl runs.
    */
   private UnableToCompleteException pendingException;
@@ -712,8 +694,8 @@
   private RunStyle runStyle = null;
 
   /**
-   * The argument passed to -runStyle.  This is parsed later so we can pass in
-   * a logger.
+   * The argument passed to -runStyle. This is parsed later so we can pass in a
+   * logger.
    */
   private String runStyleName = "HtmlUnit";
 
@@ -722,6 +704,11 @@
   private boolean standardsMode = false;
 
   /**
+   * Test method timeout as modified by the batching strategy.
+   */
+  private long testBatchingMethodTimeoutMillis;
+
+  /**
    * The time the test actually began.
    */
   private long testBeginTime;
@@ -741,6 +728,11 @@
   private long testMethodTimeout;
 
   /**
+   * Max number of times a test method must be tried.
+   */
+  private int tries;
+
+  /**
    * Enforce the singleton pattern. The call to {@link GWTShell}'s ctor forces
    * server mode and disables processing extra arguments as URLs to be shown.
    */
@@ -774,18 +766,22 @@
     if (!super.doStartup()) {
       return false;
     }
-    if (!createRunStyle(runStyleName)) {
+    int numClients = createRunStyle(runStyleName);
+    if (numClients < 0) {
       // RunStyle already logged reasons for its failure
       return false;
     }
-    
+    messageQueue = new JUnitMessageQueue(numClients);
+
     if (tries >= 1) {
       runStyle.setTries(tries);
     }
-    
+
     if (!runStyle.setupMode(getTopLogger(), developmentMode)) {
-      getTopLogger().log(TreeLogger.ERROR, "Run style does not support "
-          + (developmentMode ? "development" : "production") + " mode");
+      getTopLogger().log(
+          TreeLogger.ERROR,
+          "Run style does not support "
+              + (developmentMode ? "development" : "production") + " mode");
       return false;
     }
     return true;
@@ -799,11 +795,19 @@
     }
   }
 
+  @Override
+  protected ModuleDef loadModule(TreeLogger logger, String moduleName,
+      boolean refresh) throws UnableToCompleteException {
+    // Never refresh modules in JUnit.
+    return super.loadModule(logger, moduleName, false);
+  }
+
   /**
    * Checks to see if this test run is complete.
    */
   protected boolean notDone() {
     int activeClients = messageQueue.getNumClientsRetrievedTest(currentTestInfo);
+    int expectedClients = messageQueue.getNumClients();
     if (firstLaunch && runStyle instanceof RunStyleManual) {
       String[] newClients = messageQueue.getNewClients();
       int printIndex = activeClients - newClients.length + 1;
@@ -811,7 +815,7 @@
         System.out.println(printIndex + " - " + newClient);
         ++printIndex;
       }
-      if (activeClients != this.numClients) {
+      if (activeClients != expectedClients) {
         // Wait forever for first contact; user-driven.
         return true;
       }
@@ -819,7 +823,7 @@
 
     // Limit permutations after all clients have connected.
     if (remoteUserAgents == null
-        && messageQueue.getNumConnectedClients() == numClients) {
+        && messageQueue.getNumConnectedClients() == expectedClients) {
       remoteUserAgents = messageQueue.getUserAgents();
       String userAgentList = "";
       for (int i = 0; i < remoteUserAgents.length; i++) {
@@ -828,16 +832,19 @@
         }
         userAgentList += remoteUserAgents[i];
       }
-      getTopLogger().log(TreeLogger.INFO,
+      getTopLogger().log(
+          TreeLogger.INFO,
           "All clients connected (Limiting future permutations to: "
-          + userAgentList + ")");
+              + userAgentList + ")");
     }
 
     long currentTimeMillis = System.currentTimeMillis();
-    if (activeClients >= numClients) {
-      if (activeClients > numClients) {
-        getTopLogger().log(TreeLogger.WARN, "Too many clients: expected "
-            + numClients + ", found " + activeClients);
+    if (activeClients >= expectedClients) {
+      if (activeClients > expectedClients) {
+        getTopLogger().log(
+            TreeLogger.WARN,
+            "Too many clients: expected " + expectedClients + ", found "
+                + activeClients);
       }
       firstLaunch = false;
 
@@ -927,7 +934,7 @@
   /**
    * Accessor method to HostedModeBase.setHeadless -- without this, we get
    * IllegalAccessError from the -notHeadless arg handler. Compiler bug?
-   *
+   * 
    * @param headlessMode
    */
   void setHeadlessAccessor(boolean headlessMode) {
@@ -935,15 +942,12 @@
   }
 
   /**
-   * Set the expected number of clients.
-   * 
-   * <p>Should only be called by RunStyle subtypes.
-   * 
-   * @param numClients
+   * @deprecated TODO(fabbott) delete me
    */
+  @Deprecated
+  @SuppressWarnings("unused")
   void setNumClients(int numClients) {
-    this.numClients = numClients;
-    messageQueue.setNumClients(numClients);
+    throw new UnsupportedOperationException("This method should be deleted.");
   }
 
   void setStandardsMode(boolean standardsMode) {
@@ -951,8 +955,10 @@
   }
 
   private void checkArgs() {
-    if (runStyle.getTries() > 1 && !(batchingStrategy instanceof NoBatchingStrategy)) {
-      throw new JUnitFatalLaunchException("Batching does not work with tries > 1");
+    if (runStyle.getTries() > 1
+        && !(batchingStrategy instanceof NoBatchingStrategy)) {
+      throw new JUnitFatalLaunchException(
+          "Batching does not work with tries > 1");
     }
   }
 
@@ -960,9 +966,9 @@
    * Create the specified (or default) runStyle.
    * 
    * @param runStyleName the argument passed to -runStyle
-   * @return true if the runStyle was successfully created/initialized
+   * @return the number of clients, or -1 if initialization was unsuccessful
    */
-  private boolean createRunStyle(String runStyleName) {
+  private int createRunStyle(String runStyleName) {
     String args = null;
     String name = runStyleName;
     int colon = name.indexOf(':');
@@ -1025,7 +1031,8 @@
 
     Map<String, JUnitResult> results = messageQueue.getResults(currentTestInfo);
     assert results != null;
-    assert results.size() == numClients : results.size() + " != " + numClients;
+    assert results.size() == messageQueue.getNumClients() : results.size()
+        + " != " + messageQueue.getNumClients();
 
     for (Entry<String, JUnitResult> entry : results.entrySet()) {
       String clientId = entry.getKey();
@@ -1073,8 +1080,8 @@
   /**
    * Runs a particular test case.
    */
-  private void runTestImpl(GWTTestCase testCase, TestResult testResult, int numTries)
-      throws UnableToCompleteException {
+  private void runTestImpl(GWTTestCase testCase, TestResult testResult,
+      int numTries) throws UnableToCompleteException {
 
     testBatchingMethodTimeoutMillis = batchingStrategy.getTimeoutMultiplier()
         * baseTestMethodTimeoutMillis;
@@ -1099,8 +1106,7 @@
     // Get the module definition for the current test.
     if (!sameTest) {
       currentModule = compileStrategy.maybeCompileModule(moduleName,
-          syntheticModuleName, strategy, runStyle, batchingStrategy,
-          getTopLogger());
+          syntheticModuleName, strategy, batchingStrategy, getTopLogger());
       currentCompilationState = currentModule.getCompilationState(getTopLogger());
     }
     assert (currentModule != null);
diff --git a/user/src/com/google/gwt/junit/RunStyle.java b/user/src/com/google/gwt/junit/RunStyle.java
index e1cd227..bed70d2 100644
--- a/user/src/com/google/gwt/junit/RunStyle.java
+++ b/user/src/com/google/gwt/junit/RunStyle.java
@@ -26,16 +26,16 @@
  */
 abstract class RunStyle {
 
-  protected int tries = 1;
-  
   /**
    * The containing shell.
    */
   protected final JUnitShell shell;
 
+  private int tries = 1;
+
   /**
-   * Constructor for RunStyle.  Any subclass must provide a constructor with
-   * the same signature since this will be how the RunStyle is created via
+   * Constructor for RunStyle. Any subclass must provide a constructor with the
+   * same signature since this will be how the RunStyle is created via
    * reflection.
    * 
    * @param shell the containing shell
@@ -57,7 +57,7 @@
    * Get the host name of the local system to use in URLs. This method returns
    * the host address instead of the host name in case the test target cannot
    * resolve the host name.
-   *  
+   * 
    * @return the host name of the local system
    */
   public String getLocalHostName() {
@@ -77,15 +77,13 @@
   }
 
   /**
-   * Initialize the runstyle with any supplied arguments.
+   * Initialize the runstyle with any supplied arguments, and return the number
+   * of clients this runstyle controls.
    * 
    * @param args arguments passed in -runStyle option, null if none supplied
-   * @return true if this runstyle is initialized successfully, false if it
-   *     was unsuccessful
+   * @return the number of clients, or -1 if initialization was unsuccessful
    */
-  public boolean initialize(String args) {
-    return true;
-  }
+  public abstract int initialize(String args);
 
   /**
    * Requests initial launch of the browser. This should only be called once per
@@ -102,22 +100,22 @@
   }
 
   /**
-   * Setup this RunStyle for the selected mode. 
+   * Setup this RunStyle for the selected mode.
    * 
-   * @param logger TreeLogger to use for any messages 
-   * @param developmentMode true if we are running in development mode
-   *     rather that web/production mode
-   * @return false if we should abort processing due to an unsupported mode
-   *     or an error setting up for that mode
+   * @param logger TreeLogger to use for any messages
+   * @param developmentMode true if we are running in development mode rather
+   *          that web/production mode
+   * @return false if we should abort processing due to an unsupported mode or
+   *         an error setting up for that mode
    */
   public boolean setupMode(TreeLogger logger, boolean developmentMode) {
     return true;
   }
 
   /**
-   * Whether the embedded server should ever generate resources.  Hosted mode
-   * needs this, but not noserver hosted.  TODO(spoon) does web mode get
-   * simpler if this is turned on?
+   * Whether the embedded server should ever generate resources. Hosted mode
+   * needs this, but not noserver hosted. TODO(spoon) does web mode get simpler
+   * if this is turned on?
    */
   public boolean shouldAutoGenerateResources() {
     return true;
diff --git a/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java b/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java
index 12239ca..adf4af8 100644
--- a/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java
+++ b/user/src/com/google/gwt/junit/RunStyleExternalBrowser.java
@@ -68,7 +68,7 @@
   }
 
   private ExternalBrowser[] externalBrowsers;
-  
+
   /**
    * @param shell the containing shell
    */
@@ -97,15 +97,16 @@
   }
 
   @Override
-  public boolean initialize(String args) {
+  public int initialize(String args) {
     if (args == null || args.length() == 0) {
-      getLogger().log(TreeLogger.ERROR, "ExternalBrowser runstyle requires an "
-          + "argument listing one or more executables of external browsers to "
-          + "launch");
-      return false;
+      getLogger().log(
+          TreeLogger.ERROR,
+          "ExternalBrowser runstyle requires an "
+              + "argument listing one or more executables of external browsers to "
+              + "launch");
+      return -1;
     }
     String browsers[] = args.split(",");
-    shell.setNumClients(browsers.length);
     synchronized (this) {
       this.externalBrowsers = new ExternalBrowser[browsers.length];
       for (int i = 0; i < browsers.length; ++i) {
@@ -113,7 +114,7 @@
       }
     }
     Runtime.getRuntime().addShutdownHook(new ShutdownCb());
-    return true;
+    return browsers.length;
   }
 
   @Override
diff --git a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
index e4eff2c..f5519e3 100644
--- a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
+++ b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
@@ -54,10 +54,10 @@
       IncorrectnessListener, OnbeforeunloadHandler {
 
     private final BrowserVersion browser;
+    private final boolean developmentMode;
+    private final TreeLogger treeLogger;
     private final String url;
     private Object waitForUnload = new Object();
-    private final TreeLogger treeLogger;
-    private final boolean developmentMode;
 
     public HtmlUnitThread(BrowserVersion browser, String url,
         TreeLogger treeLogger, boolean developmentMode) {
@@ -148,7 +148,7 @@
   }
 
   private static final Map<String, BrowserVersion> BROWSER_MAP = createBrowserMap();
-  
+
   /*
    * as long as this number is greater than 1, GWTTestCaseTest::testRetry will
    * pass
@@ -181,8 +181,8 @@
   }
 
   private Set<BrowserVersion> browsers = new HashSet<BrowserVersion>();
-  private final List<Thread> threads = new ArrayList<Thread>();
   private boolean developmentMode;
+  private final List<Thread> threads = new ArrayList<Thread>();
 
   /**
    * Create a RunStyle instance with the passed-in browser targets.
@@ -192,12 +192,7 @@
   }
 
   @Override
-  public int getTries() {
-    return tries;
-  }
-
-  @Override
-  public boolean initialize(String args) {
+  public int initialize(String args) {
     if (args == null || args.length() == 0) {
       // If no browsers specified, default to Firefox 3.
       args = "FF3";
@@ -206,17 +201,18 @@
     for (String browserName : args.split(",")) {
       BrowserVersion browser = BROWSER_MAP.get(browserName);
       if (browser == null) {
-        getLogger().log(TreeLogger.ERROR, "RunStyleHtmlUnit: Unknown browser "
-            + "name " + browserName + ", expected browser name: one of "
-            + BROWSER_MAP.keySet());
-        return false;
+        getLogger().log(
+            TreeLogger.ERROR,
+            "RunStyleHtmlUnit: Unknown browser " + "name " + browserName
+                + ", expected browser name: one of " + BROWSER_MAP.keySet());
+        return -1;
       }
       browserSet.add(browser);
     }
     browsers = Collections.unmodifiableSet(browserSet);
-   
-    setTries(DEFAULT_TRIES); // set to the default value for this RunStyle 
-    return true;
+
+    setTries(DEFAULT_TRIES); // set to the default value for this RunStyle
+    return browsers.size();
   }
 
   @Override
diff --git a/user/src/com/google/gwt/junit/RunStyleManual.java b/user/src/com/google/gwt/junit/RunStyleManual.java
index 07e974a..668e1a9 100644
--- a/user/src/com/google/gwt/junit/RunStyleManual.java
+++ b/user/src/com/google/gwt/junit/RunStyleManual.java
@@ -31,19 +31,18 @@
   }
 
   @Override
-  public boolean initialize(String args) {
+  public int initialize(String args) {
     numClients = 1;
     if (args != null) {
       try {
         numClients = Integer.parseInt(args);
       } catch (NumberFormatException e) {
-        getLogger().log(TreeLogger.ERROR, "Error parsing argument \""
-            + args + "\"", e);
-        return false;
+        getLogger().log(TreeLogger.ERROR,
+            "Error parsing argument \"" + args + "\"", e);
+        return -1;
       }
     }
-    shell.setNumClients(numClients);
-    return true;
+    return numClients;
   }
 
   @Override
diff --git a/user/src/com/google/gwt/junit/RunStyleRemoteWeb.java b/user/src/com/google/gwt/junit/RunStyleRemoteWeb.java
index e870a3a..e1a1968 100644
--- a/user/src/com/google/gwt/junit/RunStyleRemoteWeb.java
+++ b/user/src/com/google/gwt/junit/RunStyleRemoteWeb.java
@@ -133,13 +133,13 @@
 
   private static final int RESPONSE_TIMEOUT_MS = 10000;
 
-  private RemoteBrowser[] remoteBrowsers;
-
   /**
    * The list of hosts that were interrupted.
    */
   private Set<String> interruptedHosts;
 
+  private RemoteBrowser[] remoteBrowsers;
+
   /**
    * A separate lock to control access to {@link #interruptedHosts}. This keeps
    * the main thread calls into {@link #getInterruptedHosts()} from having to
@@ -168,11 +168,11 @@
   }
 
   @Override
-  public boolean initialize(String args) {
+  public int initialize(String args) {
     if (args == null || args.length() == 0) {
       getLogger().log(TreeLogger.ERROR,
           "RemoteWeb runstyle requires comma-separated RMI URLs");
-      return false;
+      return -1;
     }
     String[] urls = args.split(",");
     try {
@@ -180,10 +180,9 @@
     } catch (IOException e) {
       getLogger().log(TreeLogger.ERROR,
           "RemoteWeb: Error initializing RMISocketFactory", e);
-      return false;
+      return -1;
     }
     int numClients = urls.length;
-    shell.setNumClients(numClients);
     BrowserManager[] browserManagers = new BrowserManager[numClients];
     for (int i = 0; i < numClients; ++i) {
       long callStart = System.currentTimeMillis();
@@ -200,7 +199,7 @@
           cause = e.getCause();
         }
         getLogger().log(TreeLogger.ERROR, message, cause);
-        return false;
+        return -1;
       }
     }
     synchronized (this) {
@@ -210,7 +209,7 @@
       }
     }
     Runtime.getRuntime().addShutdownHook(new ShutdownCb());
-    return true;
+    return numClients;
   }
 
   @Override
diff --git a/user/src/com/google/gwt/junit/RunStyleSelenium.java b/user/src/com/google/gwt/junit/RunStyleSelenium.java
index 31be8d7..d3259b7 100644
--- a/user/src/com/google/gwt/junit/RunStyleSelenium.java
+++ b/user/src/com/google/gwt/junit/RunStyleSelenium.java
@@ -35,7 +35,9 @@
    */
   protected static interface SeleniumWrapper {
     void createSelenium(String domain);
+
     Selenium getSelenium();
+
     String getSpecifier();
   }
 
@@ -44,8 +46,7 @@
    */
   static class RCSelenium implements SeleniumWrapper {
 
-    private static final Pattern PATTERN =
-        Pattern.compile("([\\w\\.-]+):([\\d]+)/(.+)");
+    private static final Pattern PATTERN = Pattern.compile("([\\w\\.-]+):([\\d]+)/(.+)");
 
     /*
      * Visible for testing.
@@ -86,13 +87,13 @@
     }
   }
 
-  private SeleniumWrapper remotes[];
-
   /**
    * The list of hosts that were interrupted.
    */
   private Set<String> interruptedHosts;
 
+  private SeleniumWrapper remotes[];
+
   /**
    * A separate lock to control access to {@link #interruptedHosts}. This keeps
    * the main thread calls into {@link #getInterruptedHosts()} from having to be
@@ -118,11 +119,11 @@
   }
 
   @Override
-  public boolean initialize(String args) {
+  public int initialize(String args) {
     if (args == null || args.length() == 0) {
       getLogger().log(TreeLogger.ERROR,
           "Selenium runstyle requires comma-separated Selenium-RC targets");
-      return false;
+      return -1;
     }
     String[] targetsIn = args.split(",");
     SeleniumWrapper targets[] = new SeleniumWrapper[targetsIn.length];
@@ -132,12 +133,11 @@
         targets[i] = createSeleniumWrapper(targetsIn[i]);
       } catch (IllegalArgumentException e) {
         getLogger().log(TreeLogger.ERROR, e.getMessage());
-        return false;
+        return -1;
       }
     }
 
     this.remotes = targets;
-    shell.setNumClients(targets.length);
 
     // Install a shutdown hook that will close all of our outstanding Selenium
     // sessions.
@@ -157,7 +157,7 @@
       }
     });
     start();
-    return true;
+    return targets.length;
   }
 
   @Override
@@ -186,7 +186,7 @@
 
   /**
    * Factory method for {@link SeleniumWrapper}.
-   *
+   * 
    * @param seleniumSpecifier Specifies the Selenium instance to create
    * @return an instance of {@link SeleniumWrapper}
    */
diff --git a/user/test/com/google/gwt/junit/CompileStrategyTest.java b/user/test/com/google/gwt/junit/CompileStrategyTest.java
index df25b4a..8792940 100644
--- a/user/test/com/google/gwt/junit/CompileStrategyTest.java
+++ b/user/test/com/google/gwt/junit/CompileStrategyTest.java
@@ -34,16 +34,73 @@
 public class CompileStrategyTest extends TestCase {
 
   /**
-   * A mock {@link RunStyle} used for testing.
+   * A mock {@link CompileStrategy} used for testing.
    */
-  private static class MockRunStyle extends RunStyle {
+  private static class MockCompileStrategy extends CompileStrategy {
 
-    public MockRunStyle() {
+    private MockJUnitMessageQueue messageQueue = new MockJUnitMessageQueue();
+
+    /**
+     * The number of modules to mock.
+     */
+    private int mockModuleCount;
+
+    /**
+     * Construct a new {@link MockCompileStrategy}.
+     * 
+     * @param mockModuleCount the number of modules
+     */
+    public MockCompileStrategy(int mockModuleCount) {
       super(null);
+      this.mockModuleCount = mockModuleCount;
     }
 
     @Override
-    public void launchModule(String moduleName) {
+    public ModuleDef maybeCompileModule(String moduleName,
+        String syntheticModuleName, Strategy strategy,
+        BatchingStrategy batchingStrategy, TreeLogger treeLogger) {
+      fail("This method should not be called.");
+      return null;
+    }
+
+    @Override
+    MockJUnitMessageQueue getMessageQueue() {
+      return messageQueue;
+    }
+
+    @Override
+    int getModuleCount() {
+      return mockModuleCount;
+    }
+
+    @Override
+    ModuleDef maybeCompileModuleImpl2(String moduleName,
+        String syntheticModuleName, Strategy strategy, TreeLogger treeLogger) {
+      return null;
+    }
+  }
+
+  /**
+   * A mock test case used for testing.
+   */
+  private static class MockGWTTestCase extends GWTTestCase {
+    @Override
+    public String getModuleName() {
+      return "com.google.gwt.junit.JUnit";
+    }
+
+    @Override
+    public String getName() {
+      return "testMethod1";
+    }
+
+    public void testMethod0() {
+    }
+
+    public void testMethod1() {
+    }
+
+    public void testMethod2() {
     }
   }
 
@@ -53,17 +110,17 @@
   private static class MockJUnitMessageQueue extends JUnitMessageQueue {
 
     /**
-     * The test blocks added to the queue.
-     */
-    private List<TestInfo[]> testBlocks;
-
-    /**
      * Indicates that this is the last test block.
      */
     private boolean isLastBlock;
 
+    /**
+     * The test blocks added to the queue.
+     */
+    private List<TestInfo[]> testBlocks;
+
     public MockJUnitMessageQueue() {
-      super();
+      super(1);
     }
 
     @Override
@@ -95,76 +152,17 @@
     }
   }
 
-  /**
-   * A mock {@link CompileStrategy} used for testing.
-   */
-  private static class MockCompileStrategy extends CompileStrategy {
+  public void testMaybeAddTestBlockForCurrentTestWithBatching() {
+    BatchingStrategy batchingStrategy = new ModuleBatchingStrategy();
+    assertFalse(batchingStrategy.isSingleTestOnly());
 
-    /**
-     * The number of modules to mock.
-     */
-    private int mockModuleCount;
+    // Maybe add the current test.
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    strategy.maybeAddTestBlockForCurrentTest(testCase, batchingStrategy);
 
-    private MockJUnitMessageQueue messageQueue = new MockJUnitMessageQueue();
-
-    /**
-     * Construct a new {@link MockCompileStrategy}.
-     * 
-     * @param mockModuleCount the number of modules
-     */
-    public MockCompileStrategy(int mockModuleCount) {
-      super(null);
-      this.mockModuleCount = mockModuleCount;
-    }
-
-    @Override
-    public ModuleDef maybeCompileModule(String moduleName,
-        String syntheticModuleName, Strategy strategy, RunStyle runStyle,
-        BatchingStrategy batchingStrategy, TreeLogger treeLogger) {
-      fail("This method should not be called.");
-      return null;
-    }
-
-    @Override
-    MockJUnitMessageQueue getMessageQueue() {
-      return messageQueue;
-    }
-
-    @Override
-    int getModuleCount() {
-      return mockModuleCount;
-    }
-
-    @Override
-    ModuleDef maybeCompileModuleImpl2(String moduleName,
-        String syntheticModuleName, Strategy strategy, RunStyle runStyle,
-        TreeLogger treeLogger) {
-      return null;
-    }
-  }
-
-  /**
-   * A mock test case used for testing.
-   */
-  private static class MockGWTTestCase extends GWTTestCase {
-    @Override
-    public String getModuleName() {
-      return "com.google.gwt.junit.JUnit";
-    }
-
-    @Override
-    public String getName() {
-      return "testMethod1";
-    }
-
-    public void testMethod0() {
-    }
-
-    public void testMethod1() {
-    }
-
-    public void testMethod2() {
-    }
+    // Verify the test is not added to the queue.
+    strategy.getMessageQueue().assertTestBlocks(null);
   }
 
   public void testMaybeAddTestBlockForCurrentTestWithoutBatching() {
@@ -187,50 +185,16 @@
     strategy.getMessageQueue().assertTestBlocks(testBlocks);
   }
 
-  public void testMaybeAddTestBlockForCurrentTestWithBatching() {
-    BatchingStrategy batchingStrategy = new ModuleBatchingStrategy();
-    assertFalse(batchingStrategy.isSingleTestOnly());
-
-    // Maybe add the current test.
-    GWTTestCase testCase = new MockGWTTestCase();
-    MockCompileStrategy strategy = new MockCompileStrategy(-1);
-    strategy.maybeAddTestBlockForCurrentTest(testCase, batchingStrategy);
-
-    // Verify the test is not added to the queue.
-    strategy.getMessageQueue().assertTestBlocks(null);
-  }
-
-  public void testMaybeCompileModuleImplWithoutBatching() {
-    BatchingStrategy batchingStrategy = new NoBatchingStrategy();
-    assertTrue(batchingStrategy.isSingleTestOnly());
-
-    // Maybe add the current test.
-    RunStyle runStyle = new MockRunStyle();
-    GWTTestCase testCase = new MockGWTTestCase();
-    MockCompileStrategy strategy = new MockCompileStrategy(-1);
-    try {
-      strategy.maybeCompileModuleImpl(testCase.getModuleName(),
-          testCase.getSyntheticModuleName(), testCase.getStrategy(), runStyle,
-          batchingStrategy, TreeLogger.NULL);
-    } catch (UnableToCompleteException e) {
-      fail("Unexpected UnableToCompleteException: " + e.getMessage());
-    }
-
-    // Verify the test block is not added to the queue.
-    strategy.getMessageQueue().assertTestBlocks(null);
-  }
-
   public void testMaybeCompileModuleImplWithBatchingLastModule() {
     BatchingStrategy batchingStrategy = new ModuleBatchingStrategy();
     assertFalse(batchingStrategy.isSingleTestOnly());
 
     // Maybe add the current test.
-    RunStyle runStyle = new MockRunStyle();
     GWTTestCase testCase = new MockGWTTestCase();
     MockCompileStrategy strategy = new MockCompileStrategy(-1);
     try {
       strategy.maybeCompileModuleImpl(testCase.getModuleName(),
-          testCase.getSyntheticModuleName(), testCase.getStrategy(), runStyle,
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),
           batchingStrategy, TreeLogger.NULL);
     } catch (UnableToCompleteException e) {
       fail("Unexpected UnableToCompleteException: " + e.getMessage());
@@ -247,12 +211,11 @@
     assertFalse(batchingStrategy.isSingleTestOnly());
 
     // Maybe add the current test.
-    RunStyle runStyle = new MockRunStyle();
     GWTTestCase testCase = new MockGWTTestCase();
     MockCompileStrategy strategy = new MockCompileStrategy(1000);
     try {
       strategy.maybeCompileModuleImpl(testCase.getModuleName(),
-          testCase.getSyntheticModuleName(), testCase.getStrategy(), runStyle,
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),
           batchingStrategy, TreeLogger.NULL);
     } catch (UnableToCompleteException e) {
       fail("Unexpected UnableToCompleteException: " + e.getMessage());
@@ -263,4 +226,23 @@
     strategy.getMessageQueue().assertTestBlocks(
         batchingStrategy.getTestBlocks(testCase.getSyntheticModuleName()));
   }
+
+  public void testMaybeCompileModuleImplWithoutBatching() {
+    BatchingStrategy batchingStrategy = new NoBatchingStrategy();
+    assertTrue(batchingStrategy.isSingleTestOnly());
+
+    // Maybe add the current test.
+    GWTTestCase testCase = new MockGWTTestCase();
+    MockCompileStrategy strategy = new MockCompileStrategy(-1);
+    try {
+      strategy.maybeCompileModuleImpl(testCase.getModuleName(),
+          testCase.getSyntheticModuleName(), testCase.getStrategy(),
+          batchingStrategy, TreeLogger.NULL);
+    } catch (UnableToCompleteException e) {
+      fail("Unexpected UnableToCompleteException: " + e.getMessage());
+    }
+
+    // Verify the test block is not added to the queue.
+    strategy.getMessageQueue().assertTestBlocks(null);
+  }
 }
diff --git a/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java b/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
index 96dd50b..0f5a525 100644
--- a/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
+++ b/user/test/com/google/gwt/junit/JUnitMessageQueueTest.java
@@ -37,8 +37,7 @@
   private final static int ONE_TEST_PER_BLOCK = 1;
 
   public void testAddTestBlocks() {
-    JUnitMessageQueue queue = new JUnitMessageQueue();
-    queue.setNumClients(10);
+    JUnitMessageQueue queue = new JUnitMessageQueue(10);
     assertEquals(0, queue.getTestBlocks().size());
     List<TestInfo[]> expectedBlocks = new ArrayList<TestInfo[]>();
 
@@ -460,17 +459,6 @@
     assertTrue(queue.getResults(testInfo).get("client0").getException() == null);
   }
 
-  public void testSetNumClients() {
-    JUnitMessageQueue queue = new JUnitMessageQueue();
-    queue.addTestBlocks(createTestBlocks(ONE_BLOCK, ONE_TEST_PER_BLOCK), true);
-    try {
-      queue.setNumClients(2);
-      fail("Expected IllegalStateException");
-    } catch (IllegalStateException e) {
-      // expected.
-    }
-  }
-
   /**
    * Assert that two arrays are the same size and contain the same elements.
    * Ordering does not matter.
@@ -502,8 +490,7 @@
    */
   private JUnitMessageQueue createQueue(int numClients, int numBlocks,
       int testsPerBlock) {
-    JUnitMessageQueue queue = new JUnitMessageQueue();
-    queue.setNumClients(numClients);
+    JUnitMessageQueue queue = new JUnitMessageQueue(numClients);
     queue.addTestBlocks(createTestBlocks(numBlocks, testsPerBlock), true);
     return queue;
   }