diff --git a/dev/core/src/com/google/gwt/util/tools/ToolBase.java b/dev/core/src/com/google/gwt/util/tools/ToolBase.java
index f1f5376..d5bb18f 100644
--- a/dev/core/src/com/google/gwt/util/tools/ToolBase.java
+++ b/dev/core/src/com/google/gwt/util/tools/ToolBase.java
@@ -70,6 +70,10 @@
   //
   private final List orderedArgHandlers = new ArrayList();
 
+  protected String getDescription() {
+    return null;
+  }
+
   protected void printHelp() {
     System.err.println(About.GWT_VERSION);
 
@@ -139,6 +143,11 @@
     }
 
     System.err.println();
+    String description = getDescription();
+    if (description != null) {
+      System.err.println(description);
+      System.err.println();
+    }
 
     System.err.println("where ");
 
diff --git a/user/src/com/google/gwt/junit/remote/BrowserManagerProcess.java b/user/src/com/google/gwt/junit/remote/BrowserManagerProcess.java
new file mode 100644
index 0000000..781c9b3
--- /dev/null
+++ b/user/src/com/google/gwt/junit/remote/BrowserManagerProcess.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright 2008 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.remote;
+
+import java.text.NumberFormat;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Manages one web browser child process. This class contains a TimerTask which
+ * tries to kill the managed process. A thread is created for each task to wait
+ * for the process to exit and give a callback.
+ * 
+ * Invariants:
+ * <ul>
+ * <li> Most of this code executes in a separate thread per process. Thus, the
+ * API entry points lock <code>this</code></li>
+ * <li> The lock on this is removed before calling the <code>childExited</code>
+ * callback. This prevents potential deadlock.
+ * </ul>
+ */
+class BrowserManagerProcess {
+
+  /**
+   * Used to notify the caller of the constructor when a process exits. Note
+   * that the childExited() method is called from a different thread than the
+   * one that created the process.
+   */
+  public interface ProcessExitCb {
+    void childExited(int key, int exitValue);
+  }
+
+  /**
+   * Kills the child process when fired, unless it is no longer the active
+   * {@link BrowserManagerProcess#killTask} in its outer ProcessManager.
+   */
+  private final class KillTask extends TimerTask {
+    @Override
+    public void run() {
+      synchronized (BrowserManagerProcess.this) {
+        /*
+         * CORNER CASE: Verify we're still the active KillTask, because it's
+         * possible we were bumped out by a keepAlive call after our execution
+         * started but before we could grab the lock.
+         */
+        if (killTask == this) {
+          logger.info("Timeout expired for task: " + token);
+          doKill();
+        }
+      }
+    }
+  }
+
+  private static final Logger logger = Logger.getLogger(BrowserManagerProcess.class.getName());
+
+  /**
+   * Exit callback when the process exits.
+   */
+  private final ProcessExitCb cb;
+
+  /**
+   * Set to 'true' when the process exits.
+   */
+  private boolean exited = false;
+
+  /**
+   * Set to the exitValue() of the process when it actually exits.
+   */
+  private int exitValue = -1;
+
+  /**
+   * The key associated with <code>process</code>.
+   */
+  private final int token;
+
+  /**
+   * If non-null, the active TimerTask which will kill <code>process</code>
+   * when it fires.
+   */
+  private KillTask killTask;
+
+  /**
+   * The managed child process.
+   */
+  private final Process process;
+
+  /**
+   * Time the exec'ed child actually started.
+   */
+  private final long startTime;
+
+  /**
+   * Timer instance passed in from BrowserManagerServer.
+   */
+  private final Timer timer;
+
+  /**
+   * Constructs a new ProcessManager for the specified process.
+   * 
+   * @param timer timer passed in from BrowserManagerServer instance.
+   * @param token the key to be used to identify this process.
+   * @param process the process being managed
+   * @param initKeepAliveMs the initial time to wait before killing
+   *          <code>process</code>
+   */
+  BrowserManagerProcess(ProcessExitCb cb, Timer timer, final int token,
+      final Process process, long initKeepAliveMs) {
+    this.cb = cb;
+    this.timer = timer;
+    this.process = process;
+    this.token = token;
+    schedule(initKeepAliveMs);
+    startTime = System.currentTimeMillis();
+
+    Thread cleanupThread = new Thread() {
+      @Override
+      public void run() {
+        try {
+          exitValue = process.waitFor();
+          if (cleanupBrowser() != 0) {
+            logger.warning("Browser " + token + "exited with bad status: "
+                + exitValue);
+          } else {
+            logger.info("Browser " + token + " process exited normally. "
+                + getElapsed() + " milliseconds.");
+          }
+        } catch (InterruptedException e) {
+          logger.log(Level.WARNING, "Couldn't wait for process exit. token: "
+              + token, e);
+        }
+      }
+    };
+
+    cleanupThread.setDaemon(true);
+    cleanupThread.setName("Browser-" + token + "-Wait");
+    cleanupThread.start();
+  }
+
+  /**
+   * Kills the managed process.
+   * 
+   * @return the exit value of the task.
+   */
+  public int doKill() {
+
+    boolean doCleanup = false;
+    synchronized (this) {
+      if (!exited) {
+        logger.info("Killing browser process for " + this.token);
+        process.destroy();
+
+        // Wait for the process to exit.
+        try {
+          exitValue = process.waitFor();
+          doCleanup = true;
+        } catch (InterruptedException ie) {
+          logger.severe("Interrupted waiting for browser " + token
+              + " exit during kill.");
+        }
+      }
+    }
+
+    // Run cleanupBrowser() outside the critical section.
+    if (doCleanup) {
+      if (cleanupBrowser() != 0) {
+        logger.warning("Kill Browser " + token + "exited with bad status: "
+            + exitValue);
+
+      } else {
+        logger.info("Kill Browser " + token + " process exited normally. "
+            + getElapsed() + " milliseconds.");
+      }
+    }
+
+    return exitValue;
+  }
+
+  /**
+   * Keeps the underlying process alive for <code>keepAliveMs</code> starting
+   * now. If the managed process is already dead, cleanup is performed and the
+   * method return false.
+   * 
+   * @param keepAliveMs the time to wait before killing the underlying process
+   * @return <code>true</code> if the process was successfully kept alive,
+   *         <code>false</code> if the process is already dead.
+   */
+  public boolean keepAlive(long keepAliveMs) {
+    synchronized (this) {
+      try {
+        /*
+         * See if the managed process is still alive. WEIRD: The only way to
+         * check the process's liveness appears to be asking for its exit status
+         * and seeing whether it throws an IllegalThreadStateException.
+         */
+        process.exitValue();
+      } catch (IllegalThreadStateException e) {
+        // The process is still alive.
+        schedule(keepAliveMs);
+        return true;
+      }
+    }
+
+    // The process is dead already; perform cleanup.
+    cleanupBrowser();
+    return false;
+  }
+
+  /**
+   * Routine that informs the BrowserManagerServer of the exit status once and
+   * only once.
+   * 
+   * This should be called WITHOUT the lock on BrowserManagerProcess.this being
+   * held.
+   * 
+   * @return The exit value returned by the process when it exited.
+   */
+  private int cleanupBrowser() {
+    boolean doCb = false;
+    synchronized (this) {
+      if (!exited) {
+        exited = true;
+        exitValue = process.exitValue();
+        // Stop the timer for this thread.
+        schedule(0);
+        doCb = true;
+      }
+    }
+
+    /*
+     * Callback must occur without holding my own lock. This is because the
+     * callee will try to acquire the lock on
+     * BrowserManagerServer.processByToken. If another thread already has that
+     * lock and is tries to lock me at the same time, a deadlock would ensure.
+     */
+    if (doCb) {
+      cb.childExited(token, exitValue);
+    }
+
+    return exitValue;
+  }
+
+  /**
+   * Compute elapsed time.
+   * 
+   * @return returns a string representing the number of seconds elapsed since
+   *         the process started.
+   */
+  private synchronized String getElapsed() {
+    NumberFormat nf = NumberFormat.getNumberInstance();
+    nf.setMaximumFractionDigits(3);
+    return nf.format((System.currentTimeMillis() - startTime) / 1000.0);
+  }
+
+  /**
+   * Cancels any existing kill task and optionally schedules a new one to run
+   * <code>keepAliveMs</code> from now.
+   * 
+   * @param keepAliveMs if > 0, schedules a new kill task to run in keepAliveMs
+   *          milliseconds; if <= 0, a new kill task is not scheduled.
+   */
+  private void schedule(long keepAliveMs) {
+    if (killTask != null) {
+      killTask.cancel();
+      killTask = null;
+    }
+    if (keepAliveMs > 0) {
+      killTask = new KillTask();
+      timer.schedule(killTask, keepAliveMs);
+    }
+  }
+}
diff --git a/user/src/com/google/gwt/junit/remote/BrowserManagerServer.java b/user/src/com/google/gwt/junit/remote/BrowserManagerServer.java
index befb97d..9a39822 100644
--- a/user/src/com/google/gwt/junit/remote/BrowserManagerServer.java
+++ b/user/src/com/google/gwt/junit/remote/BrowserManagerServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 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
@@ -15,22 +15,25 @@
  */
 package com.google.gwt.junit.remote;
 
+import com.google.gwt.junit.remote.BrowserManagerProcess.ProcessExitCb;
+
 import java.io.IOException;
-import java.rmi.Naming;
 import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-import java.rmi.registry.Registry;
 import java.rmi.server.UnicastRemoteObject;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.Map;
+import java.util.Queue;
+import java.util.StringTokenizer;
 import java.util.Timer;
-import java.util.TimerTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * Manages instances of a web browser as child processes. This class is
  * experimental and unsupported. An instance of this class can create browser
  * windows using one specific shell-level command. It performs process
- * managagement (babysitting) on behalf of a remote client. This can be useful
+ * management (baby sitting) on behalf of a remote client. This can be useful
  * for running a GWTTestCase on a browser that cannot be run on the native
  * platform. For example, a GWTTestCase test running on Linux could use a remote
  * call to a Windows machine to test with Internet Explorer.
@@ -41,18 +44,21 @@
  * </p>
  * 
  * <p>
- * This system has been tested on Internet Explorer 6. Firefox does not work in
- * the general case; if an existing Firefox process is already running, new
+ * This system has been tested on Internet Explorer 6 & 7. Firefox does not work
+ * in the general case; if an existing Firefox process is already running, new
  * processes simply delegate to the existing process and terminate, which breaks
- * the model. Safari on MacOS requires very special treatment given Safari's
- * poor command line support, but that is beyond the scope of this
- * documentation.
+ * the model. A shell script that sets MOZNOREMOTE=1 and cleans up
+ * locks/sessions is needed. Safari on MacOS requires very special treatment
+ * given Safari's poor command line support, but that is beyond the scope of
+ * this documentation.
  * </p>
  * 
  * <p>
  * TODO(scottb): We technically need a watchdog thread to slurp up stdout and
  * stderr from the child processes, or they might block. However, most browsers
- * never write to stdout and stderr, so this is low priority.
+ * never write to stdout and stderr, so this is low priority. (There is now a
+ * thread that is spawned for each task to wait for an exit value - this might
+ * be adapted for that purpose one day.)
  * </p>
  * 
  * see http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=4062587
@@ -66,188 +72,86 @@
    */
 
   /**
-   * Manages one web browser child process. This class contains a TimerTask
-   * which tries to kill the managed process.
-   * 
-   * Invariants:
-   * <ul>
-   * <li> If process is alive, this manager is in <code>processByToken</code>.
-   * </li>
-   * <li> If process is dead, this manager <i>might</i> be in
-   * <code>processByToken</code>. It will be observed to be dead next time
-   * {@link #keepAlive(long)} or {@link #doKill()} are called. </li>
-   * <li> Calling {@link #keepAlive(long)} and {@link #doKill()} require the
-   * lock on <code>processByToken</code> to be held, so they cannot be called
-   * at the same time. </li>
-   * </ul>
+   * Entry in the launchCommandQueue to use when tasks are serialized.
    */
-  private final class ProcessManager {
+  private class LaunchCommand {
+    long keepAliveMsecs;
+    int token;
+    String url;
 
-    /**
-     * Kills the child process when fired, unless it is no longer the active
-     * {@link ProcessManager#killTask} in its outer ProcessManager.
-     */
-    private final class KillTask extends TimerTask {
-      /*
-       * @see java.lang.Runnable#run()
-       */
-      @Override
-      public void run() {
-        synchronized (processByToken) {
-          /*
-           * CORNER CASE: Verify we're still the active KillTask, because it's
-           * possible we were bumped out by a keepAlive call after our execution
-           * started but before we could grab the lock on processByToken.
-           */
-          if (killTask == this) {
-            doKill();
-          }
-        }
-      }
+    LaunchCommand(int tokenIn) {
+      this(tokenIn, null, 0);
     }
 
-    /**
-     * The key associated with <code>process</code> in
-     * <code>processByToken</code>.
-     */
-    private Integer key;
-
-    /**
-     * If non-null, the active TimerTask which will kill <code>process</code>
-     * when it fires.
-     */
-    private KillTask killTask;
-
-    /**
-     * The managed child process.
-     */
-    private final Process process;
-
-    /**
-     * Constructs a new ProcessManager for the specified process, and adds
-     * itself to <code>processByToken</code> using the supplied key. You must
-     * hold the lock on <code>processByToken</code> to call this method.
-     * 
-     * @param key the key to be used when adding the new object to
-     *          <code>processByToken</code>
-     * @param process the process being managed
-     * @param initKeepAliveMs the initial time to wait before killing
-     *          <code>process</code>
-     */
-    ProcessManager(Integer key, Process process, long initKeepAliveMs) {
-      this.process = process;
-      this.key = key;
-      schedule(initKeepAliveMs);
-      processByToken.put(key, this);
+    LaunchCommand(int tokenIn, String urlIn, long keepAliveMsecsIn) {
+      token = tokenIn;
+      url = urlIn;
+      keepAliveMsecs = keepAliveMsecsIn;
     }
 
-    /**
-     * Kills the managed process. You must hold the lock on
-     * <code>processByToken</code> to call this method.
-     */
-    public void doKill() {
-      ProcessManager removed = processByToken.remove(key);
-      assert (removed == this);
-      process.destroy();
-      schedule(0);
-    }
-
-    /**
-     * Keeps the underlying process alive for <code>keepAliveMs</code>
-     * starting now. If the managed process is already dead, cleanup is
-     * performed and the method return false. You must hold the lock on
-     * <code>processByToken</code> to call this method.
-     * 
-     * @param keepAliveMs the time to wait before killing the underlying process
-     * @return <code>true</code> if the process was successfully kept alive,
-     *         <code>false</code> if the process is already dead.
-     */
-    public boolean keepAlive(long keepAliveMs) {
-      try {
-        /*
-         * See if the managed process is still alive. WEIRD: The only way to
-         * check the process's liveness appears to be asking for its exit status
-         * and seeing whether it throws an IllegalThreadStateException.
-         */
-        process.exitValue();
-      } catch (IllegalThreadStateException e) {
-        // The process is still alive.
-        schedule(keepAliveMs);
+    @Override
+    public boolean equals(Object obj) {
+      if (obj instanceof LaunchCommand && ((LaunchCommand) obj).token == token) {
         return true;
       }
-
-      // The process is dead already; perform cleanup.
-      doKill();
       return false;
     }
 
-    /**
-     * Cancels any existing kill task and optionally schedules a new one to run
-     * <code>keepAliveMs</code> from now. You must hold the lock on
-     * <code>processByToken</code> to call this method.
-     * 
-     * @param keepAliveMs if > 0, schedules a new kill task to run in
-     *          keepAliveMs milliseconds; if <= 0, a new kill task is not
-     *          scheduled.
-     */
-    private void schedule(long keepAliveMs) {
-      if (killTask != null) {
-        killTask.cancel();
-        killTask = null;
-      }
-      if (keepAliveMs > 0) {
-        killTask = new KillTask();
-        timer.schedule(killTask, keepAliveMs);
-      }
+    @Override
+    public int hashCode() {
+      return token;
     }
   }
 
+  private static final Logger logger = Logger.getLogger(BrowserManagerServer.class.getName());
+
   /**
    * Starts up and registers one or more browser servers. Command-line entry
    * point.
    */
   public static void main(String[] args) throws Exception {
-    if (args.length == 0) {
-      System.err.println(""
-          + "Manages local browser windows for a remote client using RMI.\n"
-          + "\n"
-          + "Pass in an even number of args, at least 2. The first argument\n"
-          + "is a short registration name, and the second argument is the\n"
-          + "executable to run when that name is used; for example,\n" + "\n"
-          + "\tie6 \"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE\"\n"
-          + "\n"
-          + "would register Internet Explorer to \"rmi://localhost/ie6\".\n"
-          + "The third and fourth arguments make another pair, and so on.\n");
-      System.exit(1);
-    }
 
-    if (args.length < 2) {
-      throw new IllegalArgumentException("Need at least 2 arguments");
-    }
-
-    if (args.length % 2 != 0) {
-      throw new IllegalArgumentException("Need an even number of arguments");
-    }
-
-    // Create an RMI registry so we don't need an external process.
-    // Uses the default RMI port.
-    // TODO(scottb): allow user to override the port via command line option.
-    LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
-    System.out.println("RMI registry ready.");
-
-    for (int i = 0; i < args.length; i += 2) {
-      BrowserManagerServer bms = new BrowserManagerServer(args[i + 1]);
-      Naming.rebind(args[i], bms);
-      System.out.println(args[i] + " started and awaiting connections");
+    // Startup logic has been delegated to BrowserManagerServerLauncher
+    // class to facilitate use of the ToolBase class for
+    // argument handling.
+    BrowserManagerServerLauncher serverMain = new BrowserManagerServerLauncher();
+    if (serverMain.doProcessArgs(args)) {
+      serverMain.run();
     }
   }
 
   /**
+   * Receives an event when a child process exits.
+   */
+  private final ProcessExitCb childExitCallback = new ProcessExitCb() {
+    /**
+     * Called back from BrowserManagerProcess in a DIFFERENT THREAD than the
+     * main thread.
+     * 
+     * @param token token value of browser that exited.
+     * @param exitValue exit status of the browser.
+     */
+    public void childExited(int token, int exitValue) {
+      synchronized (processByToken) {
+        processByToken.remove(token);
+        // Start up any commands that were delayed.
+        launchDelayedCommand();
+      }
+    }
+  };
+
+  /**
    * The shell command to launch when a new browser is requested.
    */
   private final String launchCmd;
 
   /**
+   * A queue of delayed commands. This is used if the serialized option is
+   * turned on.
+   */
+  private Queue<LaunchCommand> launchCommandQueue = new LinkedList<LaunchCommand>();
+
+  /**
    * The next token that will be returned from
    * {@link #launchNewBrowser(String, long)}.
    */
@@ -258,27 +162,40 @@
    * serves as a lock that must be held before any state-changing operations on
    * this class may be performed.
    */
-  private final Map<Integer, ProcessManager> processByToken =
-      new HashMap<Integer, ProcessManager>();
+  private final Map<Integer, BrowserManagerProcess> processByToken = new HashMap<Integer, BrowserManagerProcess>();
+
+  /**
+   * Flag that is set if the serialized option is turned on.
+   */
+  private final boolean serializeFlag;
 
   /**
    * A single shared Timer used by all instances of
-   * {@link ProcessManager.KillTask}.
+   * {@link BrowserManagerProcess}.
    */
   private final Timer timer = new Timer();
 
   /**
-   * Constructs a manager for a particular shell command.
+   * Constructs a manager for a particular shell command. The specified launch
+   * command should be a path to a browser's executable, suitable for passing to
+   * {@link Runtime#exec(java.lang.String)}. It may also include newline
+   * delimited arguments to pass to that executable. The invoked process must
+   * accept a URL as the final command line argument.
    * 
-   * @param launchCmd the path to a browser's executable, suitable for passing
-   *          to {@link Runtime#exec(java.lang.String)}. The invoked process
-   *          must accept a URL as a command line argument.
+   * @param launchCmd a command to launch a browser executable
+   * @param serializeFlag if <code>true</code>, serialize instance of browser
+   *          processes to only run one at a time
    */
-  public BrowserManagerServer(String launchCmd) throws RemoteException {
+  BrowserManagerServer(String launchCmd, boolean serializeFlag)
+      throws RemoteException {
+    // TODO: It would be nice to test to see if this file exists, but
+    // currently this mechanism allows you to pass in command line arguments
+    // and it will be a pain to accommodate this.
     this.launchCmd = launchCmd;
+    this.serializeFlag = serializeFlag;
   }
 
-  /*
+  /**
    * @see BrowserManager#keepAlive(int, long)
    */
   public void keepAlive(int token, long keepAliveMs) {
@@ -292,56 +209,166 @@
       if (token < 0 || token >= nextToken) {
         throw new IllegalArgumentException();
       }
-      ProcessManager process = processByToken.get(token);
+      BrowserManagerProcess process = processByToken.get(token);
       if (process != null) {
         if (process.keepAlive(keepAliveMs)) {
           // The process was successfully kept alive.
           return;
-        } else {
-          // The process is already dead. Fall through to failure.
         }
+      } else if (launchCommandQueue.contains(new LaunchCommand(token))) {
+        // Nothing to do, the command hasn't started yet.
+        return;
       }
+
+      // The process is already dead. Fall through to failure.
     }
 
     throw new IllegalStateException("Process " + token + " already dead");
   }
 
-  /*
+  /**
    * @see BrowserManager#killBrowser(int)
    */
   public void killBrowser(int token) {
+
     synchronized (processByToken) {
       // Is the token one we've issued?
       if (token < 0 || token >= nextToken) {
         throw new IllegalArgumentException();
       }
-      ProcessManager process = processByToken.get(token);
+      BrowserManagerProcess process = processByToken.get(token);
       if (process != null) {
+        logger.fine("Killing browser. token=" + token);
         process.doKill();
+      } else if (launchCommandQueue.contains(new LaunchCommand(token))) {
+        launchCommandQueue.remove(new LaunchCommand(token));
+        logger.info(token + " removed from delayed launch queue.");
+      } else {
+        logger.fine("No action taken. Browser not active for token " + token
+            + ".");
       }
     }
   }
 
-  /*
+  /**
    * @see BrowserManager#launchNewBrowser(java.lang.String, long)
    */
   public int launchNewBrowser(String url, long keepAliveMs) {
-
+    logger.info("Launching browser for url: " + url + " keepAliveMs: "
+        + keepAliveMs);
     if (url == null || keepAliveMs <= 0) {
       throw new IllegalArgumentException();
     }
 
     try {
-      Process child = Runtime.getRuntime().exec(new String[] {launchCmd, url});
       synchronized (processByToken) {
         int myToken = nextToken++;
         // Adds self to processByToken.
-        new ProcessManager(myToken, child, keepAliveMs);
+
+        if (serializeFlag && !processByToken.isEmpty()) {
+          // Queue up a launch request if one is already running.
+          launchCommandQueue.add(new LaunchCommand(myToken, url, keepAliveMs));
+          logger.info("Queuing up request token: " + myToken + " for url: "
+              + url + ".  Another launch command is active.");
+        } else {
+          execChild(myToken, url, keepAliveMs);
+        }
         return myToken;
       }
     } catch (IOException e) {
+      logger.log(Level.SEVERE, "Error launching browser" + launchCmd
+          + "' for '" + url + "'", e);
       throw new RuntimeException("Error launching browser '" + launchCmd
           + "' for '" + url + "'", e);
     }
   }
+
+  /**
+   * This method is mainly in place for writing assertions in the unit test.
+   * 
+   * @return number of tasks waiting to run if serialized option is enabled
+   */
+  int numQueued() {
+    synchronized (processByToken) {
+      return launchCommandQueue.size();
+    }
+  }
+
+  /**
+   * This method is mainly in place for writing assertions in the unit test.
+   * 
+   * @return number of launch commands running that have not yet exited.
+   */
+  int numRunning() {
+    synchronized (processByToken) {
+      return processByToken.size();
+    }
+  }
+
+  /**
+   * Actually create a process and run a browser.
+   * 
+   * (Assumes that code is already synchronized by processBytoken)
+   * 
+   * @param token token value of browser that exited.
+   * @param url command line arguments to pass to the browser
+   * @param keepAliveMs inital keep alive interval in milliseconds
+   */
+  private void execChild(int token, String url, long keepAliveMs)
+      throws IOException {
+    // Tokenize the launchCmd by carriage returns (used for unit testing).
+    StringTokenizer st = new StringTokenizer(launchCmd, "\n");
+    int userTokens = st.countTokens();
+    String[] cmdarray = new String[userTokens + 1];
+    for (int i = 0; st.hasMoreTokens(); i++) {
+      cmdarray[i] = st.nextToken();
+    }
+    // Append the user-specified URL.
+    cmdarray[userTokens] = url;
+
+    // Start the task.
+    Process child = Runtime.getRuntime().exec(cmdarray);
+
+    BrowserManagerProcess bmp = new BrowserManagerProcess(childExitCallback,
+        timer, token, child, keepAliveMs);
+    processByToken.put(token, bmp);
+  }
+
+  /**
+   * If serialization is enabled on the server, kicks off the next queued
+   * command on the delayed command queue.
+   * 
+   * (Assumes that code is already synchronized by processBytoken)
+   */
+  private void launchDelayedCommand() {
+
+    if (!serializeFlag || !processByToken.isEmpty()) {
+      // No need to launch if serialization is off or
+      // something is already running
+      return;
+    }
+
+    // Loop through the commands until we can launch one
+    // successfully.
+    while (!launchCommandQueue.isEmpty()) {
+      LaunchCommand lc = launchCommandQueue.remove();
+
+      try {
+        execChild(lc.token, lc.url, lc.keepAliveMsecs);
+        // No exception? Great!
+        logger.info("Started delayed browser " + lc.token);
+        return;
+
+      } catch (IOException e) {
+
+        logger.log(Level.SEVERE, "Error launching browser" + launchCmd
+            + "' for '" + lc.url + "'", e);
+
+        throw new RuntimeException("Error launching browser '" + launchCmd
+            + "' for '" + lc.url + "'", e);
+      }
+
+      // If an exception occurred, keep pulling cmds off the queue.
+    }
+  }
 }
diff --git a/user/src/com/google/gwt/junit/remote/BrowserManagerServerLauncher.java b/user/src/com/google/gwt/junit/remote/BrowserManagerServerLauncher.java
new file mode 100644
index 0000000..b383b62
--- /dev/null
+++ b/user/src/com/google/gwt/junit/remote/BrowserManagerServerLauncher.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2008 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.remote;
+
+import com.google.gwt.util.tools.ArgHandler;
+import com.google.gwt.util.tools.ArgHandlerFlag;
+import com.google.gwt.util.tools.ArgHandlerString;
+import com.google.gwt.util.tools.ToolBase;
+
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * 
+ * Used to process arguments and start up instances of BrowserManagerServer.
+ * Some of this logic used to be in BrowserManagerServer.main() and was moved
+ * here so we could inherit argument parsing from the ToolBase class.
+ */
+class BrowserManagerServerLauncher extends ToolBase {
+
+  private final class ArgHandlerPort extends ArgHandlerString {
+
+    @Override
+    public String getPurpose() {
+      return "Controls the port for the RMI invocation (defaults to "
+          + Registry.REGISTRY_PORT + ")";
+    }
+
+    @Override
+    public String getTag() {
+      return "-port";
+    }
+
+    @Override
+    public String[] getTagArgs() {
+      return new String[] {"port-number"};
+    }
+
+    @Override
+    public boolean isRequired() {
+      return false;
+    }
+
+    @Override
+    public boolean setString(String value) {
+      try {
+        portArg = Integer.parseInt(value);
+      } catch (NumberFormatException e) {
+        logger.severe("The -port argument must be an integer value.  Got: "
+            + value);
+        return false;
+      }
+      return true;
+    }
+  }
+
+  /**
+   * Handles the list of registration ids / machine names passed on the command
+   * line.
+   */
+  private class ArgHandlerRegistration extends ArgHandler {
+
+    @Override
+    public String[] getDefaultArgs() {
+      return null;
+    }
+
+    @Override
+    public String getPurpose() {
+      return "Specify two arguments: a registration id used for the "
+          + "RMI call and the browser launch command";
+    }
+
+    @Override
+    public String getTag() {
+      return null;
+    }
+
+    @Override
+    public String[] getTagArgs() {
+      return new String[] {"registration-id", "path-to-browser-executable"};
+    }
+
+    @Override
+    public int handle(String[] args, int startIndex) {
+      // Consume 2 arguments
+      if (args.length >= startIndex + 2) {
+        BMSEntry entry = new BMSEntry(args[startIndex], args[startIndex + 1]);
+        bmsList.add(entry);
+        return 1;
+      }
+      return -1;
+    }
+
+    @Override
+    public boolean isRequired() {
+      return true;
+    }
+  }
+
+  private class BMSEntry {
+    final String browserPath;
+    final String registrationKey;
+
+    BMSEntry(String registrationKeyIn, String browserPathIn) {
+      registrationKey = registrationKeyIn;
+      browserPath = browserPathIn;
+    }
+  }
+
+  private static final Logger logger = Logger.getLogger(BrowserManagerServerLauncher.class.getName());
+
+  private static final String USAGE = ""
+      + "Manages local browser windows for a remote client using RMI.\n" + "\n"
+      + "Pass in an even number of args, at least 2. The first argument\n"
+      + "is a short registration name, and the second argument is the\n"
+      + "executable to run when that name is used; for example,\n" + "\n"
+      + "\tie6 \"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE\"\n" + "\n"
+      + "would register Internet Explorer to \"rmi://localhost/ie6\".\n"
+      + "The third and fourth arguments make another pair, and so on.\n";
+
+  private List<BMSEntry> bmsList = new ArrayList<BMSEntry>();
+  private int portArg = Registry.REGISTRY_PORT;
+  private boolean serializeArg = false;
+
+  /**
+   * Creates a new BrowserServerLauncher and registers argument handling
+   * instances.
+   */
+  BrowserManagerServerLauncher() {
+    registerHandler(new ArgHandlerPort());
+    registerHandler(new ArgHandlerRegistration());
+    registerHandler(new ArgHandlerFlag() {
+
+      @Override
+      public String getPurpose() {
+        return "Queue up requests to a single server so that only a single "
+            + "test runs at a time (Usefule for a simple Firefox setup.)\n";
+      }
+
+      @Override
+      public String getTag() {
+        return "-serialize";
+      }
+
+      @Override
+      public boolean setFlag() {
+        serializeArg = true;
+        return true;
+      }
+
+    });
+  }
+
+  public boolean doProcessArgs(String[] args) {
+    if (args.length == 0) {
+      System.err.println(USAGE);
+      return false;
+    }
+    return processArgs(args);
+  }
+
+  /**
+   * This method should be invoked after argument parsing completes.
+   */
+  public void run() {
+    Registry rmiRegistry = null;
+
+    try {
+      // Create an RMI registry so we don't need an external process.
+      // Uses the default RMI port if no port is specified with the -port arg.
+      rmiRegistry = LocateRegistry.createRegistry(portArg);
+    } catch (RemoteException e) {
+      logger.log(Level.SEVERE, "Couldn't bind RMI Registry to port " + portArg,
+          e);
+      System.exit(1);
+    }
+
+    logger.log(Level.ALL, "RMI registry ready on port " + portArg + ".");
+
+    // Startup each of the registered servers on this machine.
+    for (BMSEntry entry : bmsList) {
+      BrowserManagerServer server = null;
+      try {
+        server = new BrowserManagerServer(entry.browserPath, serializeArg);
+      } catch (RemoteException re) {
+        logger.log(Level.SEVERE, entry.registrationKey
+            + ": Error starting new BrowserManagerServer.", re);
+        System.exit(2);
+      }
+
+      try {
+        rmiRegistry.rebind(entry.registrationKey, server);
+      } catch (RemoteException re) {
+        logger.log(Level.SEVERE, entry.registrationKey + " server: " + server
+            + " port: " + portArg + " Error on rebind to "
+            + entry.registrationKey, re);
+        System.exit(3);
+      }
+      logger.log(Level.INFO, "Server: " + entry.registrationKey
+          + " started and awaiting connections.");
+    }
+
+    logger.log(Level.INFO, "All servers started.");
+  }
+
+  @Override
+  protected String getDescription() {
+    return USAGE;
+  }
+
+}
diff --git a/user/test/com/google/gwt/junit/remote/BrowserManagerServerTest.java b/user/test/com/google/gwt/junit/remote/BrowserManagerServerTest.java
new file mode 100644
index 0000000..a6628d6
--- /dev/null
+++ b/user/test/com/google/gwt/junit/remote/BrowserManagerServerTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2008 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.remote;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.Properties;
+
+/**
+ * Exercise the BrowserManagerServer with the serialized option turned on and
+ * off.
+ */
+public class BrowserManagerServerTest extends TestCase {
+  /**
+   * Seconds for simulated browser to hang.
+   */
+  static final int TIMEOUT_MS = 2000;
+  /**
+   * Time to wait between keepAlive calls to all browsers.
+   */
+  static final int PING_INTERVAL_MS = 100;
+  static final boolean LOG = false;
+
+  private static final String REGISTRATION_KEY = "sleep-" + (TIMEOUT_MS / 1000)
+      + "-seconds";
+  private static Registry rmiRegistry = null;
+
+  private int portArg = Registry.REGISTRY_PORT;
+  private BrowserManagerServer server = null;
+
+  /**
+   * Run a test with the 'serialized' flag on.
+   */
+  public void testSerializedServer() throws Exception {
+    BrowserManager browserManager = startBrowserManagerServer(true);
+
+    // Launch some browsers all at once.
+    final int NUM_BROWSERS = 4;
+    int tokens[] = new int[NUM_BROWSERS];
+
+    for (int i = 0; i < NUM_BROWSERS; i++) {
+      tokens[i] = launchBrowser(browserManager, i);
+    }
+
+    // Give them a chance to startup.
+    Thread.sleep(TIMEOUT_MS / 4);
+
+    int numQueued = server.numQueued();
+    int numRunning = server.numRunning();
+    assertEquals("Did not find the number of expected browsers queued up",
+        NUM_BROWSERS - 1, numQueued);
+    assertEquals("Expected only one running at a time for serialized.", 1,
+        numRunning);
+
+    outer : for (int runningBrowser = 0; runningBrowser < NUM_BROWSERS; ++runningBrowser) {
+      // The current browser should be dead within twice the expected timeout.
+      long shouldBeDeadBy = System.currentTimeMillis() + (TIMEOUT_MS * 2);
+      while (System.currentTimeMillis() < shouldBeDeadBy) {
+        assertTrue(server.numRunning() <= 1);
+
+        // Ping every alive browser.
+        for (int i = runningBrowser; i < NUM_BROWSERS; ++i) {
+          // Keep the browser alive with a margin of safety until the next ping.
+          try {
+            browserManager.keepAlive(tokens[runningBrowser], TIMEOUT_MS);
+          } catch (IllegalStateException ise) {
+            // Expected.
+            assertEquals("The wrong browser is dead", runningBrowser, i);
+            if (LOG) {
+              System.out.println("Browser token: " + tokens[i]
+                  + " exited sucessfully");
+            }
+            // Ensure it's legal to kill the dead browser.
+            browserManager.killBrowser(tokens[i]);
+            // Continue with the next active browser.
+            continue outer;
+          }
+        }
+        Thread.sleep(PING_INTERVAL_MS);
+      }
+      // Error case
+      fail("Browser " + runningBrowser + " failed to exit in a timely manner");
+    }
+  }
+
+  /**
+   * Run a test with the 'serialized' flag on.
+   */
+  public void testUnserializedServer() throws Exception {
+    BrowserManager browserManager = startBrowserManagerServer(false);
+
+    // Launch some browsers all at once.
+    final int NUM_BROWSERS = 6;
+    int tokens[] = new int[NUM_BROWSERS];
+
+    for (int i = 0; i < NUM_BROWSERS; i++) {
+      tokens[i] = launchBrowser(browserManager, i);
+    }
+
+    // Give them a chance to startup.
+    Thread.sleep(TIMEOUT_MS / 4);
+
+    int numQueued = server.numQueued();
+    int numRunning = server.numRunning();
+    assertEquals("No queuing should occur", 0, numQueued);
+    assertEquals("All browers should be running", NUM_BROWSERS, numRunning);
+
+    // The current browser should be dead within twice the expected timeout.
+    long shouldBeDeadBy = System.currentTimeMillis() + (TIMEOUT_MS * 2);
+    int liveBrowsers = NUM_BROWSERS;
+    while (System.currentTimeMillis() < shouldBeDeadBy) {
+      // Ping every alive browser.
+      for (int i = 0; i < NUM_BROWSERS; ++i) {
+        if (tokens[i] == 0) {
+          // This one's already dead.
+          continue;
+        }
+        // Keep the browser alive with a margin of safety until the next ping.
+        try {
+          browserManager.keepAlive(tokens[i], TIMEOUT_MS);
+        } catch (IllegalStateException ise) {
+          // Expected.
+          if (LOG) {
+            System.out.println("Browser token: " + tokens[i]
+                + " exited sucessfully");
+          }
+          // Ensure it's legal to kill the dead browser.
+          browserManager.killBrowser(tokens[i]);
+
+          tokens[i] = 0;
+          --liveBrowsers;
+
+          if (liveBrowsers == 0) {
+            // All done;
+            return;
+          }
+        }
+      }
+      Thread.sleep(PING_INTERVAL_MS);
+    }
+    // Error case
+    fail(liveBrowsers + " browsers failed to exit in a timely manner");
+  }
+
+  /**
+   * Start up the RMI registry and create a shell script that just sleeps for
+   * 'timeout' seconds.
+   */
+  @Override
+  protected void setUp() throws Exception {
+    if (rmiRegistry == null) {
+      rmiRegistry = LocateRegistry.createRegistry(portArg);
+    }
+  }
+
+  /**
+   * Clean up temporary files.
+   */
+  @Override
+  protected void tearDown() throws Exception {
+    // De-register the server.
+    if (rmiRegistry != null) {
+      rmiRegistry.unbind(REGISTRATION_KEY);
+    }
+  }
+
+  /**
+   * Start a browser task on the server.
+   * 
+   * @param browserManager handle to the browser manager instance
+   * @param token browser ident number
+   */
+  private int launchBrowser(BrowserManager browserManager, int token)
+      throws RemoteException {
+    return browserManager.launchNewBrowser("# client" + token, TIMEOUT_MS);
+  }
+
+  /**
+   * Starts up an instance of BrowserManagerServer.
+   * 
+   * @param isSerialized true to enable the serialized mode (run one browser
+   *          instance at a time, queue any others.)
+   * @return the newly created instance of BrowserManagerServer on success
+   */
+  private BrowserManager startBrowserManagerServer(boolean isSerialized)
+      throws RemoteException, MalformedURLException, NotBoundException {
+    // Construct a launch command for relaunching the JVM out of process,
+    // running DummyProcess.
+    StringBuilder sb = new StringBuilder();
+    Properties properties = System.getProperties();
+    sb.append(properties.getProperty("java.home"));
+    sb.append(File.separatorChar);
+    sb.append("bin");
+    sb.append(File.separatorChar);
+    sb.append("java");
+    sb.append('\n');
+
+    sb.append("-classpath");
+    sb.append('\n');
+
+    sb.append(properties.getProperty("java.class.path"));
+    sb.append('\n');
+
+    sb.append(DummyProcess.class.getName());
+
+    server = new BrowserManagerServer(sb.toString(), isSerialized);
+    rmiRegistry.rebind(REGISTRATION_KEY, server);
+
+    // Server started. Now, create a client and send some commands to it
+    String url = "rmi://localhost/" + REGISTRATION_KEY;
+    BrowserManager browserManager = (BrowserManager) Naming.lookup(url);
+    return browserManager;
+  }
+}
diff --git a/user/test/com/google/gwt/junit/remote/DummyProcess.java b/user/test/com/google/gwt/junit/remote/DummyProcess.java
new file mode 100644
index 0000000..9e32bfa
--- /dev/null
+++ b/user/test/com/google/gwt/junit/remote/DummyProcess.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2008 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.remote;
+
+/**
+ * A dummy process to simulate a server-side browser process.
+ */
+public class DummyProcess {
+
+  public static void main(String[] args) throws InterruptedException {
+    Thread.sleep(BrowserManagerServerTest.TIMEOUT_MS);
+  }
+
+}
