- Moved benchmarks out of the junit package and into its own
- Mucho refactoring


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1928 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java
index 208e52a..4e0d683 100644
--- a/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java
+++ b/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.examples.benchmarks;
 
-import com.google.gwt.junit.client.Benchmark;
+import com.google.gwt.benchmarks.client.Benchmark;
 
 /**
  * Provides profile statistics on allocation times for different kinds of
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java
index 9a34662..5ed5465 100644
--- a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java
+++ b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2007 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
@@ -15,22 +15,22 @@
  */
 package com.google.gwt.examples.benchmarks;
 
-import com.google.gwt.junit.client.IntRange;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.Operator;
-import com.google.gwt.junit.client.Range;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
+import com.google.gwt.benchmarks.client.Range;
 
-import java.util.Vector;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Vector;
 
 /**
- * Benchmarks common operations on both ArrayLists and Vectors.
- * This test covers appends, inserts, and removes for various sizes
- * and positions on both ArrayLists and Vectors.
- *
+ * Benchmarks common operations on both ArrayLists and Vectors. This test covers
+ * appends, inserts, and removes for various sizes and positions on both
+ * ArrayLists and Vectors.
+ * 
  */
 public class ArrayListAndVectorBenchmark extends Benchmark {
 
@@ -48,13 +48,13 @@
 
     public static final Range positions = new Range() {
       public Iterator iterator() {
-        return Arrays.asList( new Position[] {BEGIN, END, NONE, VARIED } ).iterator();
+        return Arrays.asList(new Position[] {BEGIN, END, NONE, VARIED}).iterator();
       }
     };
 
     public static final Range positions2 = new Range() {
       public Iterator iterator() {
-        return Arrays.asList( new Position[] {BEGIN, END, VARIED } ).iterator();
+        return Arrays.asList(new Position[] {BEGIN, END, VARIED}).iterator();
       }
     };
 
@@ -90,9 +90,10 @@
 
   /**
    * Appends <code>size</code> items to an empty ArrayList.
+   * 
    * @gwt.benchmark.param size -limit = baseRange
    */
-  public void testArrayListAdds( Integer size ) {
+  public void testArrayListAdds(Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       list.add("hello");
@@ -104,10 +105,12 @@
   }
 
   /**
-   * Performs <code>size</code> gets on an ArrayList of size, <code>size</code>.
+   * Performs <code>size</code> gets on an ArrayList of size,
+   * <code>size</code>.
+   * 
    * @gwt.benchmark.param size -limit = baseRange
    */
-  public void testArrayListGets( Integer size ) {
+  public void testArrayListGets(Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       list.get(i);
@@ -119,12 +122,13 @@
   }
 
   /**
-   * Performs <code>size</code> inserts at position, <code>where</code>, on an
-   * empty ArrayList.
+   * Performs <code>size</code> inserts at position, <code>where</code>, on
+   * an empty ArrayList.
+   * 
    * @gwt.benchmark.param where = Position.positions
    * @gwt.benchmark.param size -limit = insertRemoveRange
    */
-  public void testArrayListInserts( Position where, Integer size ) {
+  public void testArrayListInserts(Position where, Integer size) {
     insertIntoCollection(size, where, list);
   }
 
@@ -133,8 +137,9 @@
   }
 
   /**
-   * Performs <code>size</code> removes at position, <code>where</code>, on an
-   * ArrayList of size, <code>size</code>.
+   * Performs <code>size</code> removes at position, <code>where</code>, on
+   * an ArrayList of size, <code>size</code>.
+   * 
    * @gwt.benchmark.param where = Position.positions2
    * @gwt.benchmark.param size -limit = insertRemoveRange
    */
@@ -148,9 +153,10 @@
 
   /**
    * Appends <code>size</code> items to an empty Vector.
+   * 
    * @gwt.benchmark.param size -limit = baseRange
    */
-  public void testVectorAdds( Integer size ) {
+  public void testVectorAdds(Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       vector.add("hello");
@@ -163,9 +169,10 @@
 
   /**
    * Performs <code>size</code> gets on a Vector of size, <code>size</code>.
+   * 
    * @gwt.benchmark.param size -limit = baseRange
    */
-  public void testVectorGets( Integer size ) {
+  public void testVectorGets(Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       vector.get(i);
@@ -177,13 +184,14 @@
   }
 
   /**
-   * Performs <code>size</code> inserts at position, <code>where</code>, on an
-   * empty Vector.
+   * Performs <code>size</code> inserts at position, <code>where</code>, on
+   * an empty Vector.
+   * 
    * @gwt.benchmark.param where = Position.positions
    * @gwt.benchmark.param size -limit = insertRemoveRange
    */
   public void testVectorInserts(Position where, Integer size) {
-    insertIntoCollection( size, where, vector );
+    insertIntoCollection(size, where, vector);
   }
 
   // Required for JUnit
@@ -191,25 +199,26 @@
   }
 
   /**
-   * Performs <code>size</code> removes at position, <code>where</code>, on a
-   * Vector of size, <code>size</code>.
+   * Performs <code>size</code> removes at position, <code>where</code>, on
+   * a Vector of size, <code>size</code>.
+   * 
    * @gwt.benchmark.param where = Position.positions2
    * @gwt.benchmark.param size -limit = insertRemoveRange
    */
-  public void testVectorRemoves( Position where, Integer size ) {
-    removeFromCollection( size, where, vector );
+  public void testVectorRemoves(Position where, Integer size) {
+    removeFromCollection(size, where, vector);
   }
 
   // Required for JUnit
   public void testVectorRemoves() {
   }
 
-  void beginArrayListAdds( Integer size ) {
+  void beginArrayListAdds(Integer size) {
     list = new ArrayList();
   }
 
-  void beginArrayListGets( Integer size ) {
-    createArrayList( size );
+  void beginArrayListGets(Integer size) {
+    createArrayList(size);
   }
 
   void beginArrayListInserts(Position where, Integer size) {
@@ -226,32 +235,34 @@
     vector = new Vector();
   }
 
-  void beginVectorGets( Integer size ) {
-    createVector( size );
+  void beginVectorGets(Integer size) {
+    createVector(size);
   }
 
   void beginVectorInserts(Position where, Integer size) {
-    vector = new Vector(); index = 0;
+    vector = new Vector();
+    index = 0;
   }
 
   void beginVectorRemoves(Position where, Integer size) {
-    beginVectorInserts(where,size); testVectorInserts(where,size);
+    beginVectorInserts(where, size);
+    testVectorInserts(where, size);
   }
 
-  private void createArrayList( Integer size ) {
-    beginArrayListAdds( size );
-    testArrayListAdds( size );
+  private void createArrayList(Integer size) {
+    beginArrayListAdds(size);
+    testArrayListAdds(size);
   }
 
-  private void createVector( Integer size ) {
-    beginVectorAdds( size );
-    testVectorAdds( size );
+  private void createVector(Integer size) {
+    beginVectorAdds(size);
+    testVectorAdds(size);
   }
 
   private void insertIntoCollection(Integer size, Position where, List v) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
-      if (where == Position.NONE ) {
+      if (where == Position.NONE) {
         v.add("hello");
       } else if (where == Position.BEGIN) {
         v.add(0, "hello");
@@ -278,7 +289,7 @@
         v.remove(index);
         index += PRIME;
         int currentSize = v.size();
-        if ( currentSize > 0 ) {
+        if (currentSize > 0) {
           index %= v.size();
         }
       }
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java
index c9609ff..ffa9ada 100644
--- a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java
+++ b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -14,16 +14,17 @@
  * the License.
  */
 package com.google.gwt.examples.benchmarks;
-import com.google.gwt.junit.client.IntRange;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.Operator;
-import com.google.gwt.junit.client.annotations.RangeField;
-import com.google.gwt.junit.client.annotations.RangeEnum;
-import com.google.gwt.junit.client.annotations.Setup;
 
-import java.util.List;
-import java.util.Arrays;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
+import com.google.gwt.benchmarks.client.RangeEnum;
+import com.google.gwt.benchmarks.client.RangeField;
+import com.google.gwt.benchmarks.client.Setup;
+
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Benchmarks common operations on {@link List Lists}. This test covers
@@ -38,18 +39,16 @@
    */
   protected enum Position {
 
-    BEGIN("at the beginning"),
-    EXPLICIT_END("explicitly at the end"),
-    IMPLICIT_END("implicitly at the end"),
-    VARIED("in varied locations");
+    BEGIN("at the beginning"), EXPLICIT_END("explicitly at the end"), IMPLICIT_END(
+        "implicitly at the end"), VARIED("in varied locations");
 
     private String label;
 
     /**
      * Constructor for <code>Position</code>.
-     *
+     * 
      * @param label a not <code>null</code> label describing this
-     * <code>Position</code>.
+     *          <code>Position</code>.
      */
     Position(String label) {
       this.label = label;
@@ -57,7 +56,7 @@
 
     /**
      * Returns the textual description for the position.
-     *
+     * 
      * @return a not <code>null</code> description.
      */
     public String toString() {
@@ -65,8 +64,8 @@
     }
   }
 
-  protected final List<Position> explicitPositions = Arrays
-      .asList(Position.BEGIN, Position.EXPLICIT_END, Position.VARIED);
+  protected final List<Position> explicitPositions = Arrays.asList(
+      Position.BEGIN, Position.EXPLICIT_END, Position.VARIED);
 
   protected final IntRange insertRemoveRange = new IntRange(64,
       Integer.MAX_VALUE, Operator.MULTIPLY, 2);
@@ -84,11 +83,12 @@
 
   /**
    * Appends <code>size</code> items to an empty {@code List}.
-   *
+   * 
    * @param size the size of the {@code List}
    */
   @Setup("beginListAdds")
-  public void testListAdds(@RangeField("baseRange") Integer size) {
+  public void testListAdds(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       list.add("hello");
@@ -102,11 +102,12 @@
   /**
    * Performs <code>size</code> gets on a {@code List} of size,
    * <code>size</code>.
-   *
+   * 
    * @param size the size of the {@code List}
    */
   @Setup("beginListGets")
-  public void testListGets(@RangeField("baseRange") Integer size) {
+  public void testListGets(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       list.get(i);
@@ -118,17 +119,17 @@
   }
 
   /**
-   * Performs <code>size</code> inserts at position, <code>where</code>, on an
-   * empty <code>List</code>.
-   *
+   * Performs <code>size</code> inserts at position, <code>where</code>, on
+   * an empty <code>List</code>.
+   * 
    * @param where Where the inserts happen
    * @param size The size of the <code>List</code>
-   *
+   * 
    */
   @Setup("beginListInserts")
-  public void testListInserts(
-      @RangeEnum(Position.class)Position where,
-      @RangeField("insertRemoveRange")Integer size) {
+  public void testListInserts(@RangeEnum(Position.class)
+  Position where, @RangeField("insertRemoveRange")
+  Integer size) {
     insertIntoCollection(size, where, list);
   }
 
@@ -137,16 +138,16 @@
   }
 
   /**
-   * Performs <code>size</code> removes at position, <code>where</code>, on an
-   * ArrayList of size, <code>size</code>.
-   *
+   * Performs <code>size</code> removes at position, <code>where</code>, on
+   * an ArrayList of size, <code>size</code>.
+   * 
    * @param where Where the inserts happen
    * @param size The size of the <code>List</code>
    */
   @Setup("beginListRemoves")
-  public void testListRemoves(
-      @RangeField("explicitPositions")Position where,
-      @RangeField("insertRemoveRange")Integer size) {
+  public void testListRemoves(@RangeField("explicitPositions")
+  Position where, @RangeField("insertRemoveRange")
+  Integer size) {
     removeFromCollection(size, where, list);
   }
 
@@ -156,7 +157,7 @@
 
   /**
    * Creates a new empty List.
-   *
+   * 
    * @return a not <code>null</code>, empty List
    */
   protected List<String> newList() {
diff --git a/user/src/com/google/gwt/junit/benchmarks/BenchmarkReport.java b/user/src/com/google/gwt/benchmarks/BenchmarkReport.java
similarity index 94%
rename from user/src/com/google/gwt/junit/benchmarks/BenchmarkReport.java
rename to user/src/com/google/gwt/benchmarks/BenchmarkReport.java
index aa6b05f..07ea13a 100644
--- a/user/src/com/google/gwt/junit/benchmarks/BenchmarkReport.java
+++ b/user/src/com/google/gwt/benchmarks/BenchmarkReport.java
@@ -13,8 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.benchmarks;
+package com.google.gwt.benchmarks;
 
+import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
+import com.google.gwt.benchmarks.client.impl.Trial;
+import com.google.gwt.benchmarks.rebind.BenchmarkGenerator;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.typeinfo.HasAnnotations;
 import com.google.gwt.core.ext.typeinfo.HasMetaData;
@@ -22,9 +25,6 @@
 import com.google.gwt.core.ext.typeinfo.JMethod;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.util.Util;
-import com.google.gwt.junit.client.TestResults;
-import com.google.gwt.junit.client.Trial;
-import com.google.gwt.junit.rebind.BenchmarkGenerator;
 import com.google.gwt.util.tools.Utility;
 
 import junit.framework.TestCase;
@@ -65,11 +65,11 @@
 
     private MetaData metaData;
 
-    private List<TestResults> results;
+    private List<BenchmarkResults> results;
 
     private TestCase test;
 
-    BenchmarkXml(TestCase test, List<TestResults> results) {
+    BenchmarkXml(TestCase test, List<BenchmarkResults> results) {
       this.test = test;
       this.results = results;
       Map<String, MetaData> methodMetaData = testMetaData.get(test.getClass().toString());
@@ -91,18 +91,26 @@
 
       // TODO(tobyr): create target_code element
 
-      for (TestResults result : results) {
+      for (BenchmarkResults result : results) {
         benchmark.appendChild(toElement(doc, result));
       }
 
       return benchmark;
     }
 
-    private Element toElement(Document doc, TestResults result) {
+    private Element toElement(Document doc, BenchmarkResults result) {
       Element resultElement = doc.createElement("result");
       resultElement.setAttribute("host", result.getHost());
       resultElement.setAttribute("agent", result.getAgent());
 
+      Throwable exception = result.getException();
+
+      if (exception != null) {
+        Element exceptionElement = doc.createElement("exception");
+        exceptionElement.appendChild(doc.createTextNode(exception.toString()));
+        resultElement.appendChild(exceptionElement);
+      }
+
       List<Trial> trials = result.getTrials();
 
       for (Trial trial : trials) {
@@ -130,14 +138,6 @@
       trialElement.setAttribute("timing",
           String.valueOf(trial.getRunTimeMillis()));
 
-      Throwable exception = trial.getException();
-
-      if (exception != null) {
-        Element exceptionElement = doc.createElement("exception");
-        exceptionElement.appendChild(doc.createTextNode(exception.toString()));
-        trialElement.appendChild(exceptionElement);
-      }
-
       return trialElement;
     }
   }
@@ -225,9 +225,9 @@
 
       // Add each test result into the report.
       // Add the category for the test result, if necessary.
-      for (Map.Entry<TestCase, List<TestResults>> entry : testResults.entrySet()) {
+      for (Map.Entry<TestCase, List<BenchmarkResults>> entry : testResults.entrySet()) {
         TestCase test = entry.getKey();
-        List<TestResults> results = entry.getValue();
+        List<BenchmarkResults> results = entry.getValue();
         BenchmarkXml xml = new BenchmarkXml(test, results);
         Element categoryElement = getCategoryElement(doc, report,
             xml.metaData.getCategory().getClassName());
@@ -320,7 +320,7 @@
 
   private Map<String, Map<String, MetaData>> testMetaData = new HashMap<String, Map<String, MetaData>>();
 
-  private Map<TestCase, List<TestResults>> testResults = new HashMap<TestCase, List<TestResults>>();
+  private Map<TestCase, List<BenchmarkResults>> testResults = new HashMap<TestCase, List<BenchmarkResults>>();
 
   private TypeOracle typeOracle;
 
@@ -384,10 +384,10 @@
     }
   }
 
-  public void addBenchmarkResults(TestCase test, TestResults results) {
-    List<TestResults> currentResults = testResults.get(test);
+  public void addBenchmarkResults(TestCase test, BenchmarkResults results) {
+    List<BenchmarkResults> currentResults = testResults.get(test);
     if (currentResults == null) {
-      currentResults = new ArrayList<TestResults>();
+      currentResults = new ArrayList<BenchmarkResults>();
       testResults.put(test, currentResults);
     }
     currentResults.add(results);
diff --git a/user/src/com/google/gwt/benchmarks/BenchmarkShell.java b/user/src/com/google/gwt/benchmarks/BenchmarkShell.java
new file mode 100644
index 0000000..d556134
--- /dev/null
+++ b/user/src/com/google/gwt/benchmarks/BenchmarkShell.java
@@ -0,0 +1,107 @@
+/*
+ * 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.benchmarks;
+
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
+import com.google.gwt.core.ext.UnableToCompleteException;
+import com.google.gwt.junit.JUnitShell;
+import com.google.gwt.junit.JUnitShell.Strategy;
+import com.google.gwt.junit.client.impl.JUnitResult;
+
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+
+import java.io.File;
+import java.util.Date;
+
+/**
+ * This class is responsible for hosting BenchMarks test case execution.
+ * 
+ * @see JUnitShell
+ */
+public class BenchmarkShell {
+
+  private static class BenchmarkStrategy implements Strategy {
+    public String getModuleInherit() {
+      return "com.google.gwt.benchmarks.Benchmarks";
+    }
+
+    public String getSyntheticModuleExtension() {
+      return "Benchmarks";
+    }
+
+    public void processResult(TestCase testCase, JUnitResult result) {
+      report.addBenchmarkResults(testCase, (BenchmarkResults) result);
+    }
+  }
+
+  /**
+   * Executes shutdown logic for JUnitShell
+   * 
+   * Sadly, there's no simple way to know when all unit tests have finished
+   * executing. So this class is registered as a VM shutdown hook so that work
+   * can be done at the end of testing - for example, writing out the reports.
+   */
+  private static class Shutdown implements Runnable {
+
+    public void run() {
+      try {
+        String reportPath = System.getProperty(Benchmark.REPORT_PATH);
+        if (reportPath == null || reportPath.trim().equals("")) {
+          reportPath = System.getProperty("user.dir");
+        }
+        report.generate(reportPath + File.separator + "report-"
+            + new Date().getTime() + ".xml");
+      } catch (Exception e) {
+        // It really doesn't matter how we got here.
+        // Regardless of the failure, the VM is shutting down.
+        e.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * The result of benchmark runs.
+   */
+  private static BenchmarkReport report = new BenchmarkReport();
+
+  private static boolean shutdownHookSet = false;
+
+  /**
+   * Called by {@link com.google.gwt.benchmarks.rebind.BenchmarkGenerator} to
+   * add test meta data to the test report.
+   * 
+   * @return The {@link BenchmarkReport} that belongs to the singleton {@link
+   *         JUnitShell}, or <code>null</code> if no such singleton exists.
+   */
+  public static BenchmarkReport getReport() {
+    return report;
+  }
+
+  public static void runTest(String moduleName, TestCase testCase,
+      TestResult testResult) throws UnableToCompleteException {
+    if (!shutdownHookSet) {
+      shutdownHookSet = true;
+      Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown()));
+    }
+    JUnitShell.runTest(moduleName, testCase, testResult,
+        new BenchmarkStrategy());
+  }
+
+  private BenchmarkShell() {
+  }
+}
diff --git a/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml b/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml
new file mode 100644
index 0000000..94af64f
--- /dev/null
+++ b/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml
@@ -0,0 +1,30 @@
+<!--                                                                        -->
+<!-- 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   -->
+<!-- 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. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<!-- Deferred binding rules for browser selection.                          -->
+<!--                                                                        -->
+<!-- Do not inherit this module directly.  Running GWTTestCase under JUnit  -->
+<!-- will inherit this module automatically.                                -->
+<module>
+  <inherits name="com.google.gwt.junit.JUnit"/>
+
+  <super-source path="translatable"/>
+
+  <source path="client"/>
+
+  <generate-with class="com.google.gwt.benchmarks.rebind.BenchmarkGenerator">
+    <when-type-assignable class="com.google.gwt.benchmarks.client.Benchmark"/>
+  </generate-with>
+
+</module>
diff --git a/user/src/com/google/gwt/junit/benchmarks/CategoryImpl.java b/user/src/com/google/gwt/benchmarks/CategoryImpl.java
similarity index 96%
rename from user/src/com/google/gwt/junit/benchmarks/CategoryImpl.java
rename to user/src/com/google/gwt/benchmarks/CategoryImpl.java
index 9d621ad..b1bf1de 100644
--- a/user/src/com/google/gwt/junit/benchmarks/CategoryImpl.java
+++ b/user/src/com/google/gwt/benchmarks/CategoryImpl.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.benchmarks;
+package com.google.gwt.benchmarks;
 
 /**
  * Benchmark Category information. Part of the overall MetaData for a Benchmark.
diff --git a/user/src/com/google/gwt/junit/benchmarks/MetaData.java b/user/src/com/google/gwt/benchmarks/MetaData.java
similarity index 97%
rename from user/src/com/google/gwt/junit/benchmarks/MetaData.java
rename to user/src/com/google/gwt/benchmarks/MetaData.java
index 043f7de..7e57c9b 100644
--- a/user/src/com/google/gwt/junit/benchmarks/MetaData.java
+++ b/user/src/com/google/gwt/benchmarks/MetaData.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.benchmarks;
+package com.google.gwt.benchmarks;
 
 /**
  * The benchmark metadata for a single benchmark method.
diff --git a/user/src/com/google/gwt/junit/client/Benchmark.java b/user/src/com/google/gwt/benchmarks/client/Benchmark.java
similarity index 73%
rename from user/src/com/google/gwt/junit/client/Benchmark.java
rename to user/src/com/google/gwt/benchmarks/client/Benchmark.java
index f5e9b6c..32d69b7 100644
--- a/user/src/com/google/gwt/junit/client/Benchmark.java
+++ b/user/src/com/google/gwt/benchmarks/client/Benchmark.java
@@ -13,7 +13,10 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client;
+
+import com.google.gwt.benchmarks.BenchmarkShell;
+import com.google.gwt.junit.client.GWTTestCase;
 
 /**
  * A type of {@link com.google.gwt.junit.client.GWTTestCase} which specifically
@@ -32,9 +35,8 @@
  * GWT supports test methods that have parameters. GWT will execute each
  * benchmark method multiple times in order to exhaustively test all the
  * possible combinations of parameter values. All of your test method parameters
- * must be annotated with a {@code Range} annotation such as
- * {@link com.google.gwt.junit.client.annotations.RangeField RangeField} or
- * {@link com.google.gwt.junit.client.annotations.RangeEnum RangeEnum}.
+ * must be annotated with a {@code Range} annotation such as {@link RangeField}
+ * or {@link RangeEnum}.
  * 
  * For example,
  * 
@@ -51,17 +53,14 @@
  * <li>GWT automatically removes jitter from your benchmark methods by running
  * them for a minimum period of time (150ms).</li>
  * 
- * <li>GWT supports
- * {@link com.google.gwt.junit.client.annotations.IterationTimeLimit time
- * limits} on the maximum duration of each permutation of a benchmark method.
- * With this feature, you can supply very high upper bounds on your ranges (such
- * as Integer.MAX_VALUE), which future-proofs your benchmarks against faster
- * hardware. </li>
+ * <li>GWT supports {@link IterationTimeLimit time limits} on the maximum
+ * duration of each permutation of a benchmark method. With this feature, you
+ * can supply very high upper bounds on your ranges (such as Integer.MAX_VALUE),
+ * which future-proofs your benchmarks against faster hardware. </li>
  * 
- * <li>GWT supports {@link com.google.gwt.junit.client.annotations.Setup Setup}
- * and {@link com.google.gwt.junit.client.annotations.Teardown Teardown} methods
- * which separate test overhead from the actual work being benchmarked. The
- * timings of these lifecycle methods are excluded from test results. </li>
+ * <li>GWT supports {@link Setup} and {@link Teardown} methods which separate
+ * test overhead from the actual work being benchmarked. The timings of these
+ * lifecycle methods are excluded from test results. </li>
  * </ul>
  * 
  * <h2>Notes</h2>
@@ -101,4 +100,21 @@
    * working directory.
    */
   public static final String REPORT_PATH = "com.google.gwt.junit.reportPath";
+
+  /**
+   * Runs the test via the {@link com.google.gwt.benchmarks.BenchmarkShell}
+   * environment. Do not override or call this method.
+   */
+  @Override
+  protected final void runTest() throws Throwable {
+    BenchmarkShell.runTest(getModuleName(), this, testResult);
+  }
+
+  /**
+   * Benchmarks do not support asynchronous mode.
+   */
+  protected final boolean supportsAsync() {
+    return false;
+  }
+
 }
diff --git a/user/src/com/google/gwt/junit/client/Category.java b/user/src/com/google/gwt/benchmarks/client/Category.java
similarity index 94%
rename from user/src/com/google/gwt/junit/client/Category.java
rename to user/src/com/google/gwt/benchmarks/client/Category.java
index ff9c233..22d537b 100644
--- a/user/src/com/google/gwt/junit/client/Category.java
+++ b/user/src/com/google/gwt/benchmarks/client/Category.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client;
 
 /**
  * A named category that provides classification for
diff --git a/user/src/com/google/gwt/junit/client/IntRange.java b/user/src/com/google/gwt/benchmarks/client/IntRange.java
similarity index 88%
rename from user/src/com/google/gwt/junit/client/IntRange.java
rename to user/src/com/google/gwt/benchmarks/client/IntRange.java
index ef81343..0daf451 100644
--- a/user/src/com/google/gwt/junit/client/IntRange.java
+++ b/user/src/com/google/gwt/benchmarks/client/IntRange.java
@@ -1,10 +1,10 @@
 /*
  * Copyright 2007 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
@@ -13,19 +13,18 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client;
 
 /**
- * A {@link com.google.gwt.junit.client.Range} that iterates over a start and
- * end value by a stepping function. Typically used by benchmarks to supply a
- * range of values over an integral parameter, such as size or length.
- *
+ * Iterates over a start and end value by a stepping function. Typically used by
+ * benchmarks to supply a range of values over an integral parameter, such as
+ * size or length.
  */
 public class IntRange implements Range<Integer> {
 
   /**
    * Implementation of the Iterator.
-   *
+   * 
    */
   private static class IntRangeIterator extends RangeIterator<Integer> {
 
@@ -81,7 +80,7 @@
    * <code>start</code>, end at <code>end</code> and increment by the
    * stepping function described by <code>operator</code> and
    * <code>step</code>.
-   *
+   * 
    * @param start Initial starting value, inclusive.
    * @param end Ending value, inclusive.
    * @param operator The function used to step.
diff --git a/user/src/com/google/gwt/junit/client/annotations/IterationTimeLimit.java b/user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java
similarity index 84%
rename from user/src/com/google/gwt/junit/client/annotations/IterationTimeLimit.java
rename to user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java
index 275aae1..e24276b 100644
--- a/user/src/com/google/gwt/junit/client/annotations/IterationTimeLimit.java
+++ b/user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.annotations;
+package com.google.gwt.benchmarks.client;
 
 import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
@@ -21,9 +21,8 @@
 
 /**
  * Specifies a custom time limit for iterations on the decorated
- * {@link com.google.gwt.junit.client.Benchmark Benchmark} method. Methods that
- * aren't explicitly decorated with an IterationTimeLimit, receive the default
- * value.
+ * {@link Benchmark} method. Methods that aren't explicitly decorated with an
+ * IterationTimeLimit, receive the default value.
  */
 @Target(ElementType.METHOD)
 @Documented
diff --git a/user/src/com/google/gwt/junit/client/Operator.java b/user/src/com/google/gwt/benchmarks/client/Operator.java
similarity index 87%
rename from user/src/com/google/gwt/junit/client/Operator.java
rename to user/src/com/google/gwt/benchmarks/client/Operator.java
index 59f8fad..a4d30b4 100644
--- a/user/src/com/google/gwt/junit/client/Operator.java
+++ b/user/src/com/google/gwt/benchmarks/client/Operator.java
@@ -13,11 +13,11 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client;
 
 /**
- * A mathematical operator used in {@link com.google.gwt.junit.client.Range}s
- * to indicate the stepping function.
+ * A mathematical operator used in {@link Range}s to indicate the stepping
+ * function.
  */
 public final class Operator {
 
diff --git a/user/src/com/google/gwt/junit/client/Range.java b/user/src/com/google/gwt/benchmarks/client/Range.java
similarity index 80%
rename from user/src/com/google/gwt/junit/client/Range.java
rename to user/src/com/google/gwt/benchmarks/client/Range.java
index db00c8a..b4d21fd 100644
--- a/user/src/com/google/gwt/junit/client/Range.java
+++ b/user/src/com/google/gwt/benchmarks/client/Range.java
@@ -1,31 +1,29 @@
 /*
  * 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.client;
+package com.google.gwt.benchmarks.client;
 
 /**
  * A range of values for a Benchmark parameter.
- *
+ * 
  * A Range produces an Iterator that contains all of the values that a Benchmark
  * parameter should be tested over.
- *
- * Range is unlikely to provide any extra semantics above what you would get
- * with java.util.Iterable, but it was introduced before GWT's JDK 1.5 support.
- *
- * @param <T> the type that this range contains
  * 
+ * @param <T> the type that this range contains
+ * @deprecated This class was introduced before JDK 1.5 support. Just use
+ *             {@link Iterable}.
  */
 public interface Range<T> extends Iterable<T> {
 }
diff --git a/user/src/com/google/gwt/junit/client/annotations/RangeEnum.java b/user/src/com/google/gwt/benchmarks/client/RangeEnum.java
similarity index 90%
rename from user/src/com/google/gwt/junit/client/annotations/RangeEnum.java
rename to user/src/com/google/gwt/benchmarks/client/RangeEnum.java
index a828d39..da69913 100644
--- a/user/src/com/google/gwt/junit/client/annotations/RangeEnum.java
+++ b/user/src/com/google/gwt/benchmarks/client/RangeEnum.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.annotations;
+package com.google.gwt.benchmarks.client;
 
 import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
@@ -21,7 +21,7 @@
 
 /**
  * Specifies an Enum containing the entire range of values for a parameter to a
- * {@link com.google.gwt.junit.client.Benchmark} method.
+ * {@link Benchmark} method.
  */
 @Target(ElementType.PARAMETER)
 @Documented
diff --git a/user/src/com/google/gwt/junit/client/annotations/RangeField.java b/user/src/com/google/gwt/benchmarks/client/RangeField.java
similarity index 77%
rename from user/src/com/google/gwt/junit/client/annotations/RangeField.java
rename to user/src/com/google/gwt/benchmarks/client/RangeField.java
index 70d40db..e05b885 100644
--- a/user/src/com/google/gwt/junit/client/annotations/RangeField.java
+++ b/user/src/com/google/gwt/benchmarks/client/RangeField.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.annotations;
+package com.google.gwt.benchmarks.client;
 
 import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
@@ -21,10 +21,9 @@
 
 /**
  * Specifies a field containing the entire range of values for a parameter to a
- * {@link com.google.gwt.junit.client.Benchmark} method. The field must belong
- * to the same class being decorated by this annotation. The field must be
- * either an Iterable, Enum, or array whose type matches the parameter being
- * annotated.
+ * {@link Benchmark} method. The field must belong to the same class being
+ * decorated by this annotation. The field must be either an Iterable, Enum, or
+ * array whose type matches the parameter being annotated.
  * 
  * @see RangeEnum
  */
diff --git a/user/src/com/google/gwt/junit/client/RangeIterator.java b/user/src/com/google/gwt/benchmarks/client/RangeIterator.java
similarity index 95%
rename from user/src/com/google/gwt/junit/client/RangeIterator.java
rename to user/src/com/google/gwt/benchmarks/client/RangeIterator.java
index 738ed5a..9f345cc 100644
--- a/user/src/com/google/gwt/junit/client/RangeIterator.java
+++ b/user/src/com/google/gwt/benchmarks/client/RangeIterator.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client;
 
 import java.util.Iterator;
 
diff --git a/user/src/com/google/gwt/junit/client/annotations/Setup.java b/user/src/com/google/gwt/benchmarks/client/Setup.java
similarity index 81%
rename from user/src/com/google/gwt/junit/client/annotations/Setup.java
rename to user/src/com/google/gwt/benchmarks/client/Setup.java
index 12b37b6..6cc1d0f 100644
--- a/user/src/com/google/gwt/junit/client/annotations/Setup.java
+++ b/user/src/com/google/gwt/benchmarks/client/Setup.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.annotations;
+package com.google.gwt.benchmarks.client;
 
 import java.lang.annotation.Target;
 import java.lang.annotation.ElementType;
@@ -21,9 +21,9 @@
 
 /**
  * Specifies a setup method that will be executed before the annotated
- * {@link com.google.gwt.junit.client.Benchmark} test method. Setup methods are
- * automatically executed by the benchmarking framework before their matching
- * test methods. Setup measurements are excluded from final benchmark reports.
+ * {@link Benchmark} test method. Setup methods are automatically executed by
+ * the benchmarking framework before their matching test methods. Setup
+ * measurements are excluded from final benchmark reports.
  * 
  * <p>
  * For example, you might annotate a {@code Benchmark} method named
diff --git a/user/src/com/google/gwt/junit/client/annotations/Teardown.java b/user/src/com/google/gwt/benchmarks/client/Teardown.java
similarity index 80%
rename from user/src/com/google/gwt/junit/client/annotations/Teardown.java
rename to user/src/com/google/gwt/benchmarks/client/Teardown.java
index 36971b8..22bd302 100644
--- a/user/src/com/google/gwt/junit/client/annotations/Teardown.java
+++ b/user/src/com/google/gwt/benchmarks/client/Teardown.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.annotations;
+package com.google.gwt.benchmarks.client;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -21,10 +21,9 @@
 
 /**
  * Specifies a teardown method that will be executed after the annotated
- * {@link com.google.gwt.junit.client.Benchmark} test method. Teardown methods
- * are automatically executed by the benchmarking framework after their matching
- * test methods. Teardown measurements are excluded from final benchmark
- * reports.
+ * {@link Benchmark} test method. Teardown methods are automatically executed by
+ * the benchmarking framework after their matching test methods. Teardown
+ * measurements are excluded from final benchmark reports.
  * 
  * <p>
  * For example, you might annotate a {@code Benchmark} method named
diff --git a/user/src/com/google/gwt/junit/client/TestResults.java b/user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java
similarity index 62%
rename from user/src/com/google/gwt/junit/client/TestResults.java
rename to user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java
index 74ebccb..fe4c4f4 100644
--- a/user/src/com/google/gwt/junit/client/TestResults.java
+++ b/user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java
@@ -13,31 +13,28 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client;
+package com.google.gwt.benchmarks.client.impl;
 
+import com.google.gwt.junit.client.impl.JUnitResult;
 import com.google.gwt.user.client.rpc.IsSerializable;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 /**
- * Encapsulates the results of the execution of a single benchmark. A TestResult
- * is constructed transparently within a benchmark and reported back to the
- * JUnit RPC server, JUnitHost. It's then shared (via JUnitMessageQueue) with
- * JUnitShell and aggregated in BenchmarkReport with other TestResults.
+ * Encapsulates the results of the execution of a single benchmark. A
+ * BenchmarkResults is constructed transparently within a benchmark and reported
+ * back to the JUnit RPC server, JUnitHost. It's then shared (via
+ * JUnitMessageQueue) with JUnitShell and aggregated in BenchmarkReport with
+ * other BenchmarkResults.
  * 
  * @skip
  * @see com.google.gwt.junit.client.impl.JUnitHost
  * @see com.google.gwt.junit.JUnitMessageQueue
  * @see com.google.gwt.junit.JUnitShell
- * @see com.google.gwt.junit.benchmarks.BenchmarkReport
+ * @see com.google.gwt.benchmarks.BenchmarkReport
  */
-public class TestResults implements IsSerializable {
-
-  // Computed at the server, via HTTP header.
-  private String agent;
-
-  private String host;
+public class BenchmarkResults extends JUnitResult implements IsSerializable {
 
   /**
    * The URL of the document on the browser (document.location). This is used to
@@ -51,19 +48,7 @@
    */
   private String sourceRef;
 
-  private List<Trial> trials;
-
-  public TestResults() {
-    trials = new ArrayList<Trial>();
-  }
-
-  public String getAgent() {
-    return agent;
-  }
-
-  public String getHost() {
-    return host;
-  }
+  private List<Trial> trials = new ArrayList<Trial>();
 
   public String getSourceRef() {
     return sourceRef;
@@ -73,25 +58,18 @@
     return trials;
   }
 
-  public void setAgent(String agent) {
-    this.agent = agent;
-  }
-
-  public void setHost(String host) {
-    this.host = host;
-  }
-
   public void setSourceRef(String sourceRef) {
     this.sourceRef = sourceRef;
   }
 
-  public void setTrials(List<Trial> trials) {
-    this.trials = trials;
-  }
-
   @Override
   public String toString() {
-    return "trials: " + trials + ", sourceRef: " + sourceRef + ", agent: "
-        + agent + ", host: " + host;
+    return "BenchmarkResults {" + toStringInner() + "}";
   }
+
+  protected String toStringInner() {
+    return super.toStringInner() + ", trials: " + trials + ", sourceRef: "
+        + sourceRef;
+  }
+
 }
\ No newline at end of file
diff --git a/user/src/com/google/gwt/junit/client/impl/IterableAdapter.java b/user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java
similarity index 96%
rename from user/src/com/google/gwt/junit/client/impl/IterableAdapter.java
rename to user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java
index 140c6a5..87ecd6e 100644
--- a/user/src/com/google/gwt/junit/client/impl/IterableAdapter.java
+++ b/user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.impl;
+package com.google.gwt.benchmarks.client.impl;
 
 import java.util.Arrays;
 
diff --git a/user/src/com/google/gwt/junit/client/impl/PermutationIterator.java b/user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java
similarity index 99%
rename from user/src/com/google/gwt/junit/client/impl/PermutationIterator.java
rename to user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java
index 9f3ce45..2269b71 100644
--- a/user/src/com/google/gwt/junit/client/impl/PermutationIterator.java
+++ b/user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java
@@ -13,7 +13,7 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.client.impl;
+package com.google.gwt.benchmarks.client.impl;
 
 import java.util.Iterator;
 import java.util.List;
diff --git a/user/src/com/google/gwt/benchmarks/client/impl/Trial.java b/user/src/com/google/gwt/benchmarks/client/impl/Trial.java
new file mode 100644
index 0000000..e89e297
--- /dev/null
+++ b/user/src/com/google/gwt/benchmarks/client/impl/Trial.java
@@ -0,0 +1,58 @@
+/*
+ * 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.benchmarks.client.impl;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The result of a single trial-run of a single benchmark method. Each Trial
+ * contains the results of running a benchmark method with one set of values for
+ * its parameters. TestResults for a method will contain Trials for all
+ * permutations of the parameter values. For test methods without parameters,
+ * there is only 1 trial result.
+ * 
+ * @skip
+ */
+public class Trial implements IsSerializable {
+
+  private double runTimeMillis;
+
+  private Map<String, String> variables = new HashMap<String, String>();
+
+  public double getRunTimeMillis() {
+    return runTimeMillis;
+  }
+
+  /**
+   * Returns the names and values of the variables used in the test. If there
+   * were no variables, the map is empty.
+   */
+  public Map<String, String> getVariables() {
+    return variables;
+  }
+
+  public void setRunTimeMillis(double runTimeMillis) {
+    this.runTimeMillis = runTimeMillis;
+  }
+
+  @Override
+  public String toString() {
+    return "variables: " + variables + ", runTimeMillis: " + runTimeMillis;
+  }
+}
diff --git a/user/src/com/google/gwt/benchmarks/client/package.html b/user/src/com/google/gwt/benchmarks/client/package.html
new file mode 100644
index 0000000..ee7bb32
--- /dev/null
+++ b/user/src/com/google/gwt/benchmarks/client/package.html
@@ -0,0 +1,5 @@
+<html>
+<body>
+Classes and modules used in building benchmarks.
+</body>
+</html>
diff --git a/user/src/com/google/gwt/junit/rebind/BenchmarkGenerator.java b/user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java
similarity index 88%
rename from user/src/com/google/gwt/junit/rebind/BenchmarkGenerator.java
rename to user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java
index 9fb05f8..6413c5d 100644
--- a/user/src/com/google/gwt/junit/rebind/BenchmarkGenerator.java
+++ b/user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java
@@ -13,8 +13,19 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package com.google.gwt.junit.rebind;
+package com.google.gwt.benchmarks.rebind;
 
+import com.google.gwt.benchmarks.BenchmarkShell;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IterationTimeLimit;
+import com.google.gwt.benchmarks.client.RangeEnum;
+import com.google.gwt.benchmarks.client.RangeField;
+import com.google.gwt.benchmarks.client.Setup;
+import com.google.gwt.benchmarks.client.Teardown;
+import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
+import com.google.gwt.benchmarks.client.impl.IterableAdapter;
+import com.google.gwt.benchmarks.client.impl.PermutationIterator;
+import com.google.gwt.benchmarks.client.impl.Trial;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
@@ -26,13 +37,9 @@
 import com.google.gwt.dev.generator.ast.Statement;
 import com.google.gwt.dev.generator.ast.Statements;
 import com.google.gwt.dev.generator.ast.StatementsList;
-import com.google.gwt.junit.JUnitShell;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.annotations.IterationTimeLimit;
-import com.google.gwt.junit.client.annotations.RangeEnum;
-import com.google.gwt.junit.client.annotations.RangeField;
-import com.google.gwt.junit.client.annotations.Setup;
-import com.google.gwt.junit.client.annotations.Teardown;
+import com.google.gwt.junit.rebind.JUnitTestCaseStubGenerator;
+import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.IncrementalCommand;
 import com.google.gwt.user.rebind.SourceWriter;
 
 import java.lang.reflect.Method;
@@ -50,21 +57,30 @@
 public class BenchmarkGenerator extends JUnitTestCaseStubGenerator {
 
   private static class MutableLong {
-
     long value;
   }
 
   private static final String BEGIN_PREFIX = "begin";
 
+  private static final String BENCHMARK_CLASS = Benchmark.class.getName();
+
   private static final String BENCHMARK_PARAM_META = "gwt.benchmark.param";
 
+  private static final String BENCHMARK_RESULTS_CLASS = BenchmarkResults.class.getName();
+
+  private static long defaultTimeout = -1;
+
   private static final String EMPTY_FUNC = "__emptyFunc";
 
   private static final String END_PREFIX = "end";
 
   private static final String ESCAPE_LOOP = "__escapeLoop";
 
-  private static long defaultTimeout = -1;
+  private static final String ITERABLE_ADAPTER_CLASS = IterableAdapter.class.getName();
+
+  private static final String PERMUTATION_ITERATOR_CLASS = PermutationIterator.class.getName();
+
+  private static final String TRIAL_CLASS = Trial.class.getName();
 
   /**
    * Returns all the zero-argument JUnit test methods that do not have
@@ -118,8 +134,8 @@
 
       if (methods.size() > 2) {
         String msg = requestedClass + "." + name
-            + " has more than one overloaded version.\n"
-            + "It will not be included in the test case execution.";
+            + " has more than one overloaded version"
+            + "; it will not be included in the test case execution";
         logger.log(TreeLogger.WARN, msg, null);
         continue;
       }
@@ -134,8 +150,8 @@
            * test to make the benchmarks run correctly (JUnit artifact).
            */
           String msg = requestedClass + "." + name
-              + " does not have a zero-argument overload.\n"
-              + "It will not be included in the test case execution.";
+              + " does not have a zero-argument overload"
+              + "; it will not be included in the test case execution";
           logger.log(TreeLogger.WARN, msg, null);
         }
         // Only a zero-argument version, we don't need to process it.
@@ -161,8 +177,8 @@
 
       if (noArgMethod == null) {
         String msg = requestedClass + "." + name
-            + " does not have a zero-argument overload.\n"
-            + "It will not be included in the test case execution.";
+            + " does not have a zero-argument overload"
+            + "; it will not be included in the test case execution";
         logger.log(TreeLogger.WARN, msg, null);
         continue;
       }
@@ -222,14 +238,14 @@
     super.writeSource();
 
     deprecationBranch = logger.branch(TreeLogger.TRACE,
-        "Scanning Benchmarks for deprecated annotations; " + "Please see "
-            + Benchmark.class.getName() + " for more information.", null);
+        "Scanning Benchmarks for deprecated annotations; please see "
+            + BENCHMARK_CLASS + " for more information", null);
 
     generateEmptyFunc(getSourceWriter());
     implementZeroArgTestMethods();
     implementParameterizedTestMethods();
     generateAsyncCode();
-    JUnitShell.getReport().addBenchmark(logger, deprecationBranch,
+    BenchmarkShell.getReport().addBenchmark(logger, deprecationBranch,
         getRequestedClass(), getTypeOracle());
   }
 
@@ -372,7 +388,7 @@
    * making it a JSNI call. This works as of 1.3 RC 2, but smarter versions of
    * the compiler may be able to inline JSNI.
    * 
-   * Things actually get pretty squirrely in general when benchmarking function
+   * Things actually get pretty squirrelly in general when benchmarking function
    * call overhead, because, depending upon the benchmark, the compiler may
    * inline the benchmark into our benchmark loop, negating the cost we thought
    * we were measuring.
@@ -380,7 +396,7 @@
    * The best way to deal with this is for users to write micro-benchmarks such
    * that the micro-benchmark does significantly more work than a function call.
    * For example, if micro-benchmarking a function call, perform the function
-   * call 100K times within the microbenchmark itself.
+   * call 100K times within the micro-benchmark itself.
    */
   private void generateEmptyFunc(SourceWriter writer) {
     writer.println("private native void " + EMPTY_FUNC + "() /*-{");
@@ -474,8 +490,8 @@
 
     deprecationBranch.log(TreeLogger.WARN, "Deprecated use of "
         + BENCHMARK_PARAM_META + " at " + method.getEnclosingType() + " in "
-        + method + "; Please use the new Benchmark JDK 1.5 annotations in "
-        + "com.google.gwt.junit.client.annotations.", null);
+        + method + "; please use the new Benchmark JDK 1.5 annotations in "
+        + "com.google.gwt.benchmark.client", null);
 
     Map<String, String> params = new HashMap<String, String>();
 
@@ -500,8 +516,7 @@
               + cls
               + "."
               + method.getName()
-              + "\n"
-              + "Only the last parameter of a method can be marked with the -limit flag.";
+              + ": only the last parameter of a method can be marked with the -limit flag";
           logger.log(TreeLogger.ERROR, msg, null);
           throw new UnableToCompleteException();
         }
@@ -552,7 +567,7 @@
 
       for (int i = 0; i < paramNames.size(); ++i) {
         String paramName = paramNames.get(i);
-        sw.print("com.google.gwt.junit.client.impl.IterableAdapter.toIterable("
+        sw.print(ITERABLE_ADAPTER_CLASS + ".toIterable("
             + metaDataByParams.get(paramName) + ")");
         if (i != paramNames.size() - 1) {
           sw.print(",");
@@ -562,12 +577,15 @@
         sw.print(" ");
       }
 
-      sw.println("final com.google.gwt.junit.client.impl.PermutationIterator permutationIt = new com.google.gwt.junit.client.impl.PermutationIterator(iterables);\n"
-          + "com.google.gwt.user.client.DeferredCommand.addCommand( new com.google.gwt.user.client.IncrementalCommand() {\n"
+      sw.println("final " + PERMUTATION_ITERATOR_CLASS
+          + " permutationIt = new " + PERMUTATION_ITERATOR_CLASS
+          + "(iterables);\n" + DeferredCommand.class.getName()
+          + ".addCommand( new " + IncrementalCommand.class.getName() + "() {\n"
           + "  public boolean execute() {\n"
           + "    privateDelayTestFinish( 10000 );\n"
-          + "    if ( permutationIt.hasNext() ) {\n"
-          + "      com.google.gwt.junit.client.impl.PermutationIterator.Permutation permutation = permutationIt.next();\n");
+          + "    if ( permutationIt.hasNext() ) {\n" + "      "
+          + PERMUTATION_ITERATOR_CLASS
+          + ".Permutation permutation = permutationIt.next();\n");
 
       for (int i = 0; i < methodParams.length; ++i) {
         JParameter methodParam = methodParams[i];
@@ -589,8 +607,12 @@
           new Statement(new MethodCall(method.getName(), paramNames)));
 
       StringBuffer recordResultsCode = new StringBuffer(
-          "com.google.gwt.junit.client.TestResults results = impl.getTestResults();\n"
-              + "com.google.gwt.junit.client.Trial trial = new com.google.gwt.junit.client.Trial();\n"
+          BENCHMARK_RESULTS_CLASS
+              + " results = __getOrCreateTestResult();\n"
+              + TRIAL_CLASS
+              + " trial = new "
+              + TRIAL_CLASS
+              + "();\n"
               + "trial.setRunTimeMillis( "
               + testTimingName
               + " - "
@@ -664,11 +686,10 @@
       Statements testBench = genBenchTarget(beginMethod, endMethod,
           Collections.<String> emptyList(), testStatements);
 
-      String recordResultsCode = "com.google.gwt.junit.client.TestResults results = impl.getTestResults();\n"
-          + "com.google.gwt.junit.client.Trial trial = new com.google.gwt.junit.client.Trial();\n"
-          + "trial.setRunTimeMillis( "
-          + testTimingName
-          + " - "
+      String recordResultsCode = BENCHMARK_RESULTS_CLASS
+          + " results = __getOrCreateTestResult();\n" + TRIAL_CLASS
+          + " trial = new " + TRIAL_CLASS + "();\n"
+          + "trial.setRunTimeMillis( " + testTimingName + " - "
           + setupTimingName + " );\n" + "results.getTrials().add( trial )";
 
       Statements breakCode = new Statement("  break " + ESCAPE_LOOP);
diff --git a/user/src/com/google/gwt/junit/COPYING b/user/src/com/google/gwt/junit/COPYING
deleted file mode 100644
index d9a10c0..0000000
--- a/user/src/com/google/gwt/junit/COPYING
+++ /dev/null
@@ -1,176 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
diff --git a/user/src/com/google/gwt/junit/JUnit.gwt.xml b/user/src/com/google/gwt/junit/JUnit.gwt.xml
index f03417d..f351246 100644
--- a/user/src/com/google/gwt/junit/JUnit.gwt.xml
+++ b/user/src/com/google/gwt/junit/JUnit.gwt.xml
@@ -31,10 +31,8 @@
     <when-type-assignable class="com.google.gwt.junit.client.GWTTestCase"/>
   </generate-with>
 
-  <generate-with class="com.google.gwt.junit.rebind.BenchmarkGenerator">
-    <when-type-assignable class="com.google.gwt.junit.client.Benchmark"/>
-  </generate-with>
-
   <servlet path='/junithost' class='com.google.gwt.junit.server.JUnitHostImpl'/>
 
+  <inherits name="com.google.gwt.benchmarks.Benchmarks"/>
+
 </module>
diff --git a/user/src/com/google/gwt/junit/JUnitMessageQueue.java b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
index bbd3a51..51dfe31 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.junit;
 
-import com.google.gwt.junit.client.TestResults;
+import com.google.gwt.junit.client.impl.JUnitResult;
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 
 import java.util.ArrayList;
@@ -65,7 +65,7 @@
   private Object readTestLock = new Object();
 
   /**
-   * The lock used to synchronize access around testResults.
+   * The lock used to synchronize access around testResult.
    */
   private Object resultsLock = new Object();
 
@@ -87,7 +87,7 @@
   /**
    * The results for the current test method.
    */
-  private List<TestResults> testResults = new ArrayList<TestResults>();
+  private List<JUnitResult> testResult = new ArrayList<JUnitResult>();
 
   /**
    * Creates a message queue with one client.
@@ -149,13 +149,13 @@
    * @param moduleName the name of the test module
    * @param results the result of running the test
    */
-  public void reportResults(String moduleName, TestResults results) {
+  public void reportResults(String moduleName, JUnitResult results) {
     synchronized (resultsLock) {
       if (!moduleName.equals(testModule)) {
         // an old client is trying to report results, do nothing
         return;
       }
-      testResults.add(results);
+      testResult.add(results);
     }
   }
 
@@ -166,9 +166,9 @@
    * @return An getException thrown from a failed test, or <code>null</code>
    *         if the test completed without error.
    */
-  List<TestResults> getResults(String moduleName) {
+  List<JUnitResult> getResults(String moduleName) {
     assert (moduleName.equals(testModule));
-    return testResults;
+    return testResult;
   }
 
   /**
@@ -181,7 +181,7 @@
   boolean hasResult(String moduleName) {
     synchronized (resultsLock) {
       assert (moduleName.equals(testModule));
-      return testResults.size() == numClients;
+      return testResult.size() == numClients;
     }
   }
 
@@ -219,7 +219,7 @@
       this.testClass = testClass;
       this.testMethod = testMethod;
       ++currentTestIndex;
-      testResults = new ArrayList<TestResults>(numClients);
+      testResult = new ArrayList<JUnitResult>(numClients);
       readTestLock.notifyAll();
     }
   }
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 41c11d3..35e3c53 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -26,12 +26,9 @@
 import com.google.gwt.dev.cfg.Property;
 import com.google.gwt.dev.shell.BrowserWidgetHost;
 import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
-import com.google.gwt.junit.benchmarks.BenchmarkReport;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.TestResults;
 import com.google.gwt.junit.client.TimeoutException;
-import com.google.gwt.junit.client.Trial;
 import com.google.gwt.junit.client.impl.GWTRunner;
+import com.google.gwt.junit.client.impl.JUnitResult;
 import com.google.gwt.junit.remote.BrowserManager;
 import com.google.gwt.util.tools.ArgHandlerFlag;
 import com.google.gwt.util.tools.ArgHandlerString;
@@ -40,10 +37,8 @@
 import junit.framework.TestCase;
 import junit.framework.TestResult;
 
-import java.io.File;
 import java.rmi.Naming;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -80,27 +75,26 @@
 public class JUnitShell extends GWTShell {
 
   /**
-   * Executes shutdown logic for JUnitShell
-   * 
-   * Sadly, there's no simple way to know when all unit tests have finished
-   * executing. So this class is registered as a VM shutdown hook so that work
-   * can be done at the end of testing - for example, writing out the reports.
+   * A strategy for running the test.
    */
-  private class Shutdown implements Runnable {
+  public interface Strategy {
+    String getModuleInherit();
 
-    public void run() {
-      try {
-        String reportPath = System.getProperty(Benchmark.REPORT_PATH);
-        if (reportPath == null || reportPath.trim().equals("")) {
-          reportPath = System.getProperty("user.dir");
-        }
-        report.generate(reportPath + File.separator + "report-"
-            + new Date().getTime() + ".xml");
-      } catch (Exception e) {
-        // It really doesn't matter how we got here.
-        // Regardless of the failure, the VM is shutting down.
-        e.printStackTrace();
-      }
+    String getSyntheticModuleExtension();
+
+    void processResult(TestCase testCase, JUnitResult result);
+  }
+
+  private static class JUnitStrategy implements Strategy {
+    public String getModuleInherit() {
+      return "com.google.gwt.junit.JUnit";
+    }
+
+    public String getSyntheticModuleExtension() {
+      return "JUnit";
+    }
+
+    public void processResult(TestCase testCase, JUnitResult result) {
     }
   }
 
@@ -143,27 +137,20 @@
   }
 
   /**
-   * Called by {@link com.google.gwt.junit.rebind.JUnitTestCaseStubGenerator} to
-   * add test meta data to the test report.
-   * 
-   * @return The {@link BenchmarkReport} that belongs to the singleton {@link
-   *         JUnitShell}, or <code>null</code> if no such singleton exists.
-   */
-  public static BenchmarkReport getReport() {
-    if (unitTestShell == null) {
-      return null;
-    }
-    return unitTestShell.report;
-  }
-
-  /**
    * Entry point for {@link com.google.gwt.junit.client.GWTTestCase}. Gets or
    * creates the singleton {@link JUnitShell} and invokes its {@link
    * #runTestImpl(String, TestCase, TestResult)}.
    */
   public static void runTest(String moduleName, TestCase testCase,
       TestResult testResult) throws UnableToCompleteException {
-    getUnitTestShell().runTestImpl(moduleName, testCase, testResult);
+    getUnitTestShell().runTestImpl(moduleName, testCase, testResult,
+        new JUnitStrategy());
+  }
+
+  public static void runTest(String moduleName, TestCase testCase,
+      TestResult testResult, Strategy strategy)
+      throws UnableToCompleteException {
+    getUnitTestShell().runTestImpl(moduleName, testCase, testResult, strategy);
   }
 
   /**
@@ -184,11 +171,7 @@
       if (!shell.startUp()) {
         throw new RuntimeException("Shell failed to start");
       }
-
-      shell.report = new BenchmarkReport();
       unitTestShell = shell;
-
-      Runtime.getRuntime().addShutdownHook(new Thread(shell.new Shutdown()));
     }
 
     return unitTestShell;
@@ -222,11 +205,6 @@
   private int numClients = 1;
 
   /**
-   * The result of benchmark runs.
-   */
-  private BenchmarkReport report;
-
-  /**
    * What type of test we're running; Local hosted, local web, or remote web.
    */
   private RunStyle runStyle = new RunStyleLocalHosted(this);
@@ -415,9 +393,11 @@
    * Runs a particular test case.
    */
   private void runTestImpl(String moduleName, TestCase testCase,
-      TestResult testResult) throws UnableToCompleteException {
+      TestResult testResult, Strategy strategy)
+      throws UnableToCompleteException {
 
-    String syntheticModuleName = moduleName + ".JUnit";
+    String syntheticModuleName = moduleName + "."
+        + strategy.getSyntheticModuleExtension();
     boolean sameTest = syntheticModuleName.equals(currentModuleName);
     if (sameTest && lastLaunchFailed) {
       throw new UnableToCompleteException();
@@ -431,7 +411,7 @@
        */
       ModuleDef synthetic = ModuleDefLoader.createSyntheticModule(
           getTopLogger(), currentModuleName, new String[] {
-              moduleName, "com.google.gwt.junit.JUnit"}, true);
+              moduleName, strategy.getModuleInherit()}, true);
       // Replace any user entry points with our test runner.
       synthetic.clearEntryPoints();
       synthetic.addEntryPointTypeName(GWTRunner.class.getName());
@@ -466,7 +446,7 @@
       return;
     }
 
-    List<TestResults> results = messageQueue.getResults(currentModuleName);
+    List<JUnitResult> results = messageQueue.getResults(currentModuleName);
 
     if (results == null) {
       return;
@@ -474,9 +454,8 @@
 
     boolean parallelTesting = numClients > 1;
 
-    for (TestResults result : results) {
-      Trial firstTrial = result.getTrials().get(0);
-      Throwable exception = firstTrial.getException();
+    for (JUnitResult result : results) {
+      Throwable exception = result.getException();
 
       // In the case that we're running multiple clients at once, we need to
       // let the user know the browser in which the failure happened
@@ -504,9 +483,7 @@
         testResult.addError(testCase, exception);
       }
 
-      if (testCase instanceof Benchmark) {
-        report.addBenchmarkResults(testCase, result);
-      }
+      strategy.processResult(testCase, result);
     }
   }
 
diff --git a/user/src/com/google/gwt/junit/client/GWTTestCase.java b/user/src/com/google/gwt/junit/client/GWTTestCase.java
index 8a90ee8..d5d0feb 100644
--- a/user/src/com/google/gwt/junit/client/GWTTestCase.java
+++ b/user/src/com/google/gwt/junit/client/GWTTestCase.java
@@ -39,12 +39,12 @@
   /*
    * Object that collects the results of this test case execution.
    */
-  private TestResult testResult = null;
+  protected TestResult testResult = null;
 
   /**
    * Add a checkpoint message to the current test. If this test fails, all
-   * checkpoint messages will be appended to the getException description. This can
-   * be useful in web mode for determining how far test execution progressed
+   * checkpoint messages will be appended to the getException description. This
+   * can be useful in web mode for determining how far test execution progressed
    * before a failure occurs.
    * 
    * @param msg the checkpoint message to add
@@ -142,9 +142,8 @@
    * @param timeoutMillis how long to wait before the current test will time out
    * @tip Subsequent calls to this method reset the timeout.
    * @see #finishTest()
-   *
-   * @throws UnsupportedOperationException if this test case is a
-   *         {@link Benchmark}
+   * 
+   * @throws UnsupportedOperationException if {@link #supportsAsync()} is false
    */
   protected final void delayTestFinish(int timeoutMillis) {
     // implemented in the translatable version of this class
@@ -167,10 +166,9 @@
    * {@example com.google.gwt.examples.AsyncJUnitExample#testTimer()}
    * </p>
    * 
-   * @throws IllegalStateException if this test is not in asynchronous mode.
-   * @throws UnsupportedOperationException if this test case is a
-   *         {@link Benchmark}
-   *
+   * @throws IllegalStateException if this test is not in asynchronous mode
+   * @throws UnsupportedOperationException if {@link #supportsAsync()} is false
+   * 
    * @see #delayTestFinish(int)
    */
   protected final void finishTest() {
@@ -178,10 +176,20 @@
   }
 
   /**
-   * Runs the test via the {@link JUnitShell} environment.
+   * Runs the test via the {@link JUnitShell} environment. Do not override or
+   * call this method.
    */
   @Override
-  protected final void runTest() throws Throwable {
+  protected void runTest() throws Throwable {
     JUnitShell.runTest(getModuleName(), this, testResult);
   }
+
+  /**
+   * Returns true if this test case supports asynchronous mode. By default, this
+   * is set to true.
+   */
+  protected boolean supportsAsync() {
+    return true;
+  }
+
 }
diff --git a/user/src/com/google/gwt/junit/client/Trial.java b/user/src/com/google/gwt/junit/client/Trial.java
deleted file mode 100644
index d30bb3d..0000000
--- a/user/src/com/google/gwt/junit/client/Trial.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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.client;
-
-import com.google.gwt.junit.client.impl.ExceptionWrapper;
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * The result of a single trial-run of a single benchmark method. Each Trial
- * contains the results of running a benchmark method with one set of values for
- * its parameters. TestResults for a method will contain Trials for all
- * permutations of the parameter values. For test methods without parameters,
- * there is only 1 trial result.
- * 
- * @skip
- */
-public class Trial implements IsSerializable {
-
-  // Deserialized from exceptionWrapper on the server-side
-  private transient Throwable exception;
-
-  private ExceptionWrapper exceptionWrapper;
-
-  private double runTimeMillis;
-
-  private Map<String, String> variables;
-
-  public Trial() {
-    this.variables = new HashMap<String, String>();
-  }
-
-  /**
-   * Creates a new Trial.
-   * 
-   * @param runTimeMillis The amount of time spent executing the test
-   * @param exceptionWrapper The wrapped getException thrown by the the last
-   *          test, or <code>null</code> if the last test completed
-   *          successfully.
-   */
-  public Trial(Map<String, String> variables, double runTimeMillis,
-      ExceptionWrapper exceptionWrapper) {
-    this.variables = variables;
-    this.runTimeMillis = runTimeMillis;
-    this.exceptionWrapper = exceptionWrapper;
-  }
-
-  public Throwable getException() {
-    return exception;
-  }
-
-  public ExceptionWrapper getExceptionWrapper() {
-    return exceptionWrapper;
-  }
-
-  public double getRunTimeMillis() {
-    return runTimeMillis;
-  }
-
-  /**
-   * Returns the names and values of the variables used in the test. If there
-   * were no variables, the map is empty.
-   */
-  public Map<String, String> getVariables() {
-    return variables;
-  }
-
-  public void setException(Throwable exception) {
-    this.exception = exception;
-  }
-
-  public void setExceptionWrapper(ExceptionWrapper exceptionWrapper) {
-    this.exceptionWrapper = exceptionWrapper;
-  }
-
-  public void setRunTimeMillis(double runTimeMillis) {
-    this.runTimeMillis = runTimeMillis;
-  }
-
-  @Override
-  public String toString() {
-    return "variables: " + variables + ", exceptionWrapper: "
-        + exceptionWrapper + ", runTimeMillis: " + runTimeMillis;
-  }
-}
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
index 7e92793..e461ed9 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHost.java
@@ -17,7 +17,6 @@
 
 import com.google.gwt.user.client.rpc.IsSerializable;
 import com.google.gwt.user.client.rpc.RemoteService;
-import com.google.gwt.junit.client.TestResults;
 
 /**
  * An interface for {@link com.google.gwt.junit.client.GWTTestCase} to
@@ -50,6 +49,11 @@
     public String getTestMethod() {
       return testMethod;
     }
+    
+    @Override
+    public String toString() {
+      return testClass + "." + testMethod;
+    }
   }
 
   /**
@@ -65,8 +69,8 @@
    * run.
    * 
    * @param moduleName the module name of this client
-   * @param results The results of executing the test
+   * @param result the results of executing the test
    * @return the next test to run
    */
-  TestInfo reportResultsAndGetNextMethod(String moduleName, TestResults results);
+  TestInfo reportResultsAndGetNextMethod(String moduleName, JUnitResult result);
 }
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
index e27baaf..c900a18 100644
--- a/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitHostAsync.java
@@ -15,7 +15,6 @@
  */
 package com.google.gwt.junit.client.impl;
 
-import com.google.gwt.junit.client.TestResults;
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 
@@ -28,8 +27,8 @@
    * Gets the name of next method to run.
    * 
    * @param moduleName the module name of this client
-   * @param callBack The object that will receive the name of the next method to
-   *          run.
+   * @param callBack the object that will receive the name of the next method to
+   *          run
    */
   void getFirstMethod(String moduleName, AsyncCallback<TestInfo> callBack);
 
@@ -38,10 +37,10 @@
    * run.
    * 
    * @param moduleName the module name of this client
-   * @param results The results of the test.
-   * @param callBack The object that will receive the name of the next method to
-   *          run.
+   * @param result the result of the test
+   * @param callBack the object that will receive the name of the next method to
+   *          run
    */
-  void reportResultsAndGetNextMethod(String moduleName, TestResults results,
+  void reportResultsAndGetNextMethod(String moduleName, JUnitResult result,
       AsyncCallback<TestInfo> callBack);
 }
diff --git a/user/src/com/google/gwt/junit/client/impl/JUnitResult.java b/user/src/com/google/gwt/junit/client/impl/JUnitResult.java
new file mode 100644
index 0000000..2f63e26
--- /dev/null
+++ b/user/src/com/google/gwt/junit/client/impl/JUnitResult.java
@@ -0,0 +1,85 @@
+/*
+ * 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.client.impl;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+/**
+ * Encapsulates the results of the execution of a single benchmark. A TestResult
+ * is constructed transparently within a benchmark and reported back to the
+ * JUnit RPC server, JUnitHost. It's then shared (via JUnitMessageQueue) with
+ * JUnitShell and aggregated in BenchmarkReport with other TestResults.
+ * 
+ * @skip
+ * @see com.google.gwt.junit.client.impl.JUnitHost
+ * @see com.google.gwt.junit.JUnitMessageQueue
+ * @see com.google.gwt.junit.JUnitShell
+ */
+public class JUnitResult implements IsSerializable {
+
+  // Computed at the server, via HTTP header.
+  private transient String agent;
+
+  // Deserialized from exceptionWrapper on the server-side
+  private transient Throwable exception;
+
+  private ExceptionWrapper exceptionWrapper;
+
+  // Computed at the server, via HTTP header.
+  private transient String host;
+
+  public String getAgent() {
+    return agent;
+  }
+
+  public Throwable getException() {
+    return exception;
+  }
+
+  public ExceptionWrapper getExceptionWrapper() {
+    return exceptionWrapper;
+  }
+
+  public String getHost() {
+    return host;
+  }
+
+  public void setAgent(String agent) {
+    this.agent = agent;
+  }
+
+  public void setException(Throwable exception) {
+    this.exception = exception;
+  }
+
+  public void setExceptionWrapper(ExceptionWrapper exceptionWrapper) {
+    this.exceptionWrapper = exceptionWrapper;
+  }
+
+  public void setHost(String host) {
+    this.host = host;
+  }
+
+  @Override
+  public String toString() {
+    return "TestResult {" + toStringInner() + "}";
+  }
+
+  protected String toStringInner() {
+    return "exceptionWrapper: " + exceptionWrapper + ", agent: " + agent
+        + ", host: " + host;
+  }
+}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/junit/rebind/JUnitTestCaseStubGenerator.java b/user/src/com/google/gwt/junit/rebind/JUnitTestCaseStubGenerator.java
index 96613f8..87c1ea6 100644
--- a/user/src/com/google/gwt/junit/rebind/JUnitTestCaseStubGenerator.java
+++ b/user/src/com/google/gwt/junit/rebind/JUnitTestCaseStubGenerator.java
@@ -40,22 +40,11 @@
  */
 public class JUnitTestCaseStubGenerator extends Generator {
 
-  interface MethodFilter {
-    boolean accept(JMethod method);
-  }
-
   /**
-   * Returns the method names for the set of methods that are strictly JUnit
-   * test methods (have no arguments).
-   * 
-   * @param requestedClass
+   * An interface for filtering out methods.
    */
-  public static String[] getTestMethodNames(JClassType requestedClass) {
-    return getAllMethods(requestedClass, new MethodFilter() {
-      public boolean accept(JMethod method) {
-        return isJUnitTestMethod(method, false);
-      }
-    }).keySet().toArray(new String[] {});
+  protected interface MethodFilter {
+    boolean accept(JMethod method);
   }
 
   /**
@@ -70,7 +59,7 @@
    * @param type the type to search (non-null)
    * @return the set of matching methods (non-null)
    */
-  static Map<String, List<JMethod>> getAllMethods(JClassType type,
+  protected static Map<String, List<JMethod>> getAllMethods(JClassType type,
       MethodFilter filter) {
     Map<String, List<JMethod>> methods = new HashMap<String, List<JMethod>>();
     JClassType cls = type;
@@ -119,7 +108,7 @@
    * access. The method may be static. You must choose to include or exclude
    * methods which have arguments.
    */
-  static boolean isJUnitTestMethod(JMethod method, boolean acceptArgs) {
+  protected static boolean isJUnitTestMethod(JMethod method, boolean acceptArgs) {
     if (!method.getName().startsWith("test")) {
       return false;
     }
@@ -150,12 +139,25 @@
     return true;
   }
 
+  /**
+   * Returns the method names for the set of methods that are strictly JUnit
+   * test methods (have no arguments).
+   * 
+   * @param requestedClass
+   */
+  private static String[] getTestMethodNames(JClassType requestedClass) {
+    return getAllMethods(requestedClass, new MethodFilter() {
+      public boolean accept(JMethod method) {
+        return isJUnitTestMethod(method, false);
+      }
+    }).keySet().toArray(new String[] {});
+  }
+
   protected TreeLogger logger;
   private String packageName;
   private String qualifiedStubClassName;
-  private String simpleStubClassName;
-
   private JClassType requestedClass;
+  private String simpleStubClassName;
   private SourceWriter sourceWriter;
   private TypeOracle typeOracle;
 
diff --git a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
index e9103a3..f30d477 100644
--- a/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
+++ b/user/src/com/google/gwt/junit/server/JUnitHostImpl.java
@@ -18,10 +18,9 @@
 import com.google.gwt.junit.JUnitFatalLaunchException;
 import com.google.gwt.junit.JUnitMessageQueue;
 import com.google.gwt.junit.JUnitShell;
-import com.google.gwt.junit.client.TestResults;
-import com.google.gwt.junit.client.Trial;
 import com.google.gwt.junit.client.impl.ExceptionWrapper;
 import com.google.gwt.junit.client.impl.JUnitHost;
+import com.google.gwt.junit.client.impl.JUnitResult;
 import com.google.gwt.junit.client.impl.StackTraceWrapper;
 import com.google.gwt.user.client.rpc.InvocationException;
 import com.google.gwt.user.server.rpc.RPCServletUtils;
@@ -32,7 +31,6 @@
 import java.io.PrintWriter;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.util.List;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
@@ -89,19 +87,12 @@
   }
 
   public TestInfo reportResultsAndGetNextMethod(String moduleName,
-      TestResults results) {
+      JUnitResult result) {
+    initResult(getThreadLocalRequest(), result);
+    ExceptionWrapper ew = result.getExceptionWrapper();
+    result.setException(deserialize(ew));
     JUnitMessageQueue host = getHost();
-    HttpServletRequest request = getThreadLocalRequest();
-    String agent = request.getHeader("User-Agent");
-    results.setAgent(agent);
-    String machine = request.getRemoteHost();
-    results.setHost(machine);
-    List<Trial> trials = results.getTrials();
-    for (Trial trial : trials) {
-      ExceptionWrapper ew = trial.getExceptionWrapper();
-      trial.setException(deserialize(ew));
-    }
-    host.reportResults(moduleName, results);
+    host.reportResults(moduleName, result);
     return host.getNextTestInfo(getClientId(), moduleName,
         TIME_TO_WAIT_FOR_TESTNAME);
   }
@@ -131,11 +122,10 @@
     if (requestURI.endsWith("/junithost/loadError")) {
       String moduleName = getModuleName(getPrefix(requestURI));
       String requestPayload = RPCServletUtils.readContentAsUtf8(request);
-      TestResults results = new TestResults();
-      Trial trial = new Trial();
-      trial.setException(new JUnitFatalLaunchException(requestPayload));
-      results.getTrials().add(trial);
-      getHost().reportResults(moduleName, results);
+      JUnitResult result = new JUnitResult();
+      initResult(request, result);
+      result.setException(new JUnitFatalLaunchException(requestPayload));
+      getHost().reportResults(moduleName, result);
     } else {
       super.service(request, response);
     }
@@ -268,4 +258,11 @@
     String prefix = requestURI.substring(0, pos);
     return prefix;
   }
+
+  private void initResult(HttpServletRequest request, JUnitResult result) {
+    String agent = request.getHeader("User-Agent");
+    result.setAgent(agent);
+    String machine = request.getRemoteHost();
+    result.setHost(machine);
+  }
 }
diff --git a/user/src/com/google/gwt/junit/client/Category.java b/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java
similarity index 67%
copy from user/src/com/google/gwt/junit/client/Category.java
copy to user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java
index ff9c233..d5a4636 100644
--- a/user/src/com/google/gwt/junit/client/Category.java
+++ b/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java
@@ -1,25 +1,25 @@
 /*
  * 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.client;
+package com.google.gwt.benchmarks.client;
+
+import com.google.gwt.benchmarks.client.impl.BenchmarkImpl;
 
 /**
- * A named category that provides classification for
- * {@link Benchmark Benchmarks}. Categories are now deprecated.
- * 
+ * This class is the translatable version of {@link Benchmark}; it is an empty
+ * shell to make debugging easier.
  */
-@Deprecated
-public interface Category {
+public abstract class Benchmark extends BenchmarkImpl {
 }
diff --git a/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/impl/BenchmarkImpl.java b/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/impl/BenchmarkImpl.java
new file mode 100644
index 0000000..f134ce9
--- /dev/null
+++ b/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/impl/BenchmarkImpl.java
@@ -0,0 +1,49 @@
+/*
+ * 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.benchmarks.client.impl;
+
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * The implementation class for the translatable {@link GWTTestCase}.
+ * 
+ * This class is split out of {@link GWTTestCase} to make debugging work. Trying
+ * to debug the translatable {@link GWTTestCase} confuses the debugger, which
+ * tends to use the non-translatable version.
+ */
+public abstract class BenchmarkImpl extends GWTTestCase {
+
+  private static native String getDocumentLocation() /*-{
+    return $doc.location.toString();
+  }-*/;
+
+  /**
+   * Collective test results.
+   */
+  private BenchmarkResults results;
+  
+  // CHECKSTYLE_OFF
+  @Override
+  protected BenchmarkResults __getOrCreateTestResult() {
+    if (results == null) {
+      results = new BenchmarkResults();
+      results.setSourceRef(getDocumentLocation());
+    }
+    return results;
+  }
+  // CHECKSTYLE_ON
+  
+}
diff --git a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/GWTTestCase.java b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/GWTTestCase.java
index 511943c..d877e1c 100644
--- a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/GWTTestCase.java
+++ b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/GWTTestCase.java
@@ -17,68 +17,9 @@
 
 import com.google.gwt.junit.client.impl.GWTTestCaseImpl;
 
-import junit.framework.TestCase;
-
 /**
- * This class is the translatable version of {@link GWTTestCase}. It uses RPC
- * to communicate test progress back to the GWT environment, where the real test
- * test is running.
+ * This class is the translatable version of {@link GWTTestCase}; it is an
+ * empty shell to make debugging easier.
  */
-public abstract class GWTTestCase extends TestCase {
-
-  /**
-   * A reference to my implementation class. All substantive methods simply
-   * delegate to the implementation class, to make debugging easier.
-   */
-  public GWTTestCaseImpl impl;
-
-  public final void addCheckpoint(String msg) {
-    impl.addCheckpoint(msg);
-  }
-
-  public boolean catchExceptions() {
-    return true;
-  }
-
-  public final void clearCheckpoints() {
-    impl.clearCheckpoints();
-  }
-
-  public final String[] getCheckpoints() {
-    return impl.getCheckpoints();
-  }
-
-  public abstract String getModuleName();
-
-  protected final void delayTestFinish(int timeoutMillis) {
-    if (supportsAsync()) {
-      impl.delayTestFinish(timeoutMillis);
-    } else {
-      throw new UnsupportedOperationException(
-          "This test case does not support asynchronous mode.");
-    }
-  }
-
-  protected final void finishTest() {
-    if (supportsAsync()) {
-      impl.finishTest();
-    } else {
-      throw new UnsupportedOperationException(
-          "This test case does not support asynchronous mode.");
-    }
-  }
-
-  /**
-   * Returns true if this test case supports asynchronous mode. By default, this
-   * is set to true. Originally introduced for Benchmarks which don't currently
-   * support asynchronous mode.
-   * 
-   * <p>
-   * Note that an overrider of this method may report different answers for the
-   * same test case during the same run, so it is not safe to cache the results.
-   * </p>
-   */
-  protected boolean supportsAsync() {
-    return true;
-  }
+public abstract class GWTTestCase extends GWTTestCaseImpl {
 }
diff --git a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
index 43704ee..e6a5bbc 100644
--- a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
+++ b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java
@@ -18,7 +18,6 @@
 import com.google.gwt.core.client.EntryPoint;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.junit.client.TestResults;
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.rpc.ServiceDefTarget;
@@ -148,12 +147,12 @@
    */
   protected abstract GWTTestCase createNewTestCase(String testClass);
 
-  void reportResultsAndGetNextMethod(TestResults results) {
+  void reportResultsAndGetNextMethod(JUnitResult result) {
     if (serverless) {
       // That's it, we're done
       return;
     }
-    junitHost.reportResultsAndGetNextMethod(GWT.getModuleName(), results,
+    junitHost.reportResultsAndGetNextMethod(GWT.getModuleName(), result,
         junitHostListener);
   }
 
@@ -169,12 +168,17 @@
 
   private void runTest(TestInfo testToRun) {
     // Dynamically create a new test case.
-    GWTTestCase testCase = createNewTestCase(testToRun.getTestClass());
-    if (testCase != null) {
-      testCase.setName(testToRun.getTestMethod());
+    GWTTestCaseImpl testCase = createNewTestCase(testToRun.getTestClass());
+    if (testCase == null) {
+      RuntimeException ex = new RuntimeException(testToRun
+          + ": could not instantiate the requested class");
+      JUnitResult result = new JUnitResult();
+      result.setExceptionWrapper(new ExceptionWrapper(ex));
+      reportResultsAndGetNextMethod(result);
     }
-    GWTTestCaseImpl impl = new GWTTestCaseImpl(testCase);
-    impl.runTest();
+
+    testCase.setName(testToRun.getTestMethod());
+    testCase.__doRunTest();
   }
 
 }
diff --git a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTTestCaseImpl.java b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTTestCaseImpl.java
index 50b4fbf..942a1e3 100644
--- a/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTTestCaseImpl.java
+++ b/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTTestCaseImpl.java
@@ -17,13 +17,11 @@
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.junit.client.TestResults;
 import com.google.gwt.junit.client.TimeoutException;
-import com.google.gwt.junit.client.Trial;
 import com.google.gwt.user.client.Timer;
 
+import junit.framework.TestCase;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -34,11 +32,7 @@
  * to debug the translatable {@link GWTTestCase} confuses the debugger, which
  * tends to use the non-translatable version.
  */
-public class GWTTestCaseImpl implements UncaughtExceptionHandler {
-
-  private static native String getDocumentLocation() /*-{
-    return $doc.location.toString();
-  }-*/;
+public abstract class GWTTestCaseImpl extends TestCase {
 
   /**
    * A watchdog class for use with asynchronous mode. On construction,
@@ -80,19 +74,9 @@
   private boolean mainTestHasRun = false;
 
   /**
-   * Collective test results.
+   * Test result.
    */
-  private TestResults results = new TestResults();
-
-  /**
-   * The time the test began execution.
-   */
-  private long testBeginMillis;
-
-  /**
-   * My paired {@link GWTTestCase}.
-   */
-  private final GWTTestCase testCase;
+  private JUnitResult result;
 
   /**
    * Tracks whether this test is completely done.
@@ -104,19 +88,21 @@
    */
   private KillTimer timer;
 
-  /**
-   * Constructs a new GWTTestCaseImpl that is paired one-to-one with a
-   * {@link GWTTestCase}.
-   * 
-   * @param outer The paired (enclosing) GWTTestCase.
-   */
-  public GWTTestCaseImpl(GWTTestCase testCase) {
-    this.testCase = testCase;
-    if (testCase != null) {
-      // Initialize the back reference from the test case to myself.
-      testCase.impl = this;
+  private final UncaughtExceptionHandler uncaughtHandler = new UncaughtExceptionHandler() {
+    /**
+     * An uncaught exception escaped to the browser; what we should do depends
+     * on what state we're in.
+     */
+    public void onUncaughtException(Throwable ex) {
+      if (mainTestHasRun && timer != null) {
+        // Asynchronous mode; uncaught exceptions cause an immediate failure.
+        assert (!testIsFinished);
+        reportResultsAndRunNextMethod(ex);
+      } else {
+        // just ignore it
+      }
     }
-  }
+  };
 
   /**
    * Implementation of {@link GWTTestCase#addCheckpoint(String)}.
@@ -128,98 +114,95 @@
     checkPoints.add(msg);
   }
 
+  public boolean catchExceptions() {
+    return true;
+  }
+
   public void clearCheckpoints() {
     checkPoints = null;
   }
 
-  /**
-   * Implementation of {@link GWTTestCase#delayTestFinish(int)}.
-   */
-  public void delayTestFinish(int timeoutMillis) {
-    if (timer != null) {
-      // Cancel the pending timer
-      timer.cancel();
-    }
-
-    // Set a new timer for the specified new timeout
-    timer = new KillTimer(timeoutMillis);
-  }
-
-  /**
-   * Implementation of {@link GWTTestCase#finishTest()}.
-   */
-  public void finishTest() {
-    if (testIsFinished) {
-      // This test is totally done already, just ignore the call.
-      return;
-    }
-
-    if (timer == null) {
-      throw new IllegalStateException(
-          "This test is not in asynchronous mode; call delayTestFinish() first");
-    }
-
-    if (mainTestHasRun) {
-      // This is a correct, successful async finish.
-      reportResultsAndRunNextMethod(null);
-    } else {
-      // The user tried to finish the test before the main body returned!
-      // Just let the test continue running normally.
-      resetAsyncState();
-    }
-  }
-
   public String[] getCheckpoints() {
     if (checkPoints == null) {
       return new String[0];
     } else {
       int len = checkPoints.size();
-      String[] result = new String[len];
+      String[] retval = new String[len];
       for (int i = 0; i < len; ++i) {
-        result[i] = checkPoints.get(i);
+        retval[i] = checkPoints.get(i);
       }
-      return result;
+      return retval;
     }
   }
 
-  public TestResults getTestResults() {
-    return results;
-  }
+  public abstract String getModuleName();
 
-  /**
-   * An uncaught exception escaped to the browser; what we should do depends on
-   * what state we're in.
-   */
-  public void onUncaughtException(Throwable ex) {
-    if (mainTestHasRun && timer != null) {
-      // Asynchronous mode; uncaught exceptions cause an immediate failure.
-      assert (!testIsFinished);
-      reportResultsAndRunNextMethod(ex);
+  // CHECKSTYLE_OFF
+  protected JUnitResult __getOrCreateTestResult() {
+    if (result == null) {
+      result = new JUnitResult();
+    }
+    return result;
+  }
+  // CHECKSTYLE_ON
+
+  protected final void delayTestFinish(int timeoutMillis) {
+    if (supportsAsync()) {
+      if (timer != null) {
+        // Cancel the pending timer
+        timer.cancel();
+      }
+
+      // Set a new timer for the specified new timeout
+      timer = new KillTimer(timeoutMillis);
     } else {
-      // just ignore it
+      throw new UnsupportedOperationException(
+          "This test case does not support asynchronous mode.");
     }
   }
 
+  protected final void finishTest() {
+    if (supportsAsync()) {
+      if (testIsFinished) {
+        // This test is totally done already, just ignore the call.
+        return;
+      }
+
+      if (timer == null) {
+        throw new IllegalStateException(
+            "This test is not in asynchronous mode; call delayTestFinish() first");
+      }
+
+      if (mainTestHasRun) {
+        // This is a correct, successful async finish.
+        reportResultsAndRunNextMethod(null);
+      } else {
+        // The user tried to finish the test before the main body returned!
+        // Just let the test continue running normally.
+        resetAsyncState();
+      }
+    } else {
+      throw new UnsupportedOperationException(
+          "This test case does not support asynchronous mode.");
+    }
+  }
+
+  protected boolean supportsAsync() {
+    return false;
+  }
+  
+  // CHECKSTYLE_OFF
   /**
    * Actually run the user's test. Called from {@link GWTRunner}.
    */
-  void runTest() {
+  void __doRunTest() {
     Throwable caught = null;
 
-    testBeginMillis = System.currentTimeMillis();
-    results = new TestResults();
-
-    if (testCase == null) {
-      reportResultsAndRunNextMethod(new RuntimeException(
-          "Could not instantiate the requested class"));
-      return;
-    }
-
     if (shouldCatchExceptions()) {
       // Make sure no exceptions escape
-      GWT.setUncaughtExceptionHandler(this);
+      GWT.setUncaughtExceptionHandler(uncaughtHandler);
       try {
-        testCase.runBare();
+        runBare();
       } catch (Throwable e) {
         caught = e;
       }
@@ -243,6 +226,7 @@
       reportResultsAndRunNextMethod(null);
     }
   }
+  // CHECKSTYLE_ON
 
   /**
    * Cleans up any outstanding state, reports ex to the remote runner, and kicks
@@ -251,55 +235,20 @@
    * @param ex The results of this test.
    */
   private void reportResultsAndRunNextMethod(Throwable ex) {
-    List<Trial> trials = results.getTrials();
-
-    /*
-     * TODO(tobyr) - Consider making this logic polymorphic which will remove
-     * instanceof test. But testCase might be null.
-     * 
-     * If this is not a benchmark, we have to create a fake trial run
-     */
-    if (!(testCase instanceof Benchmark)) {
-      Trial trial = new Trial();
-      long testDurationMillis = System.currentTimeMillis() - testBeginMillis;
-      trial.setRunTimeMillis(testDurationMillis);
-
-      if (ex != null) {
-        ExceptionWrapper ew = new ExceptionWrapper(ex);
-        if (checkPoints != null) {
-          for (int i = 0, c = checkPoints.size(); i < c; ++i) {
-            ew.message += "\n" + checkPoints.get(i);
-          }
+    JUnitResult myResult = __getOrCreateTestResult();
+    if (ex != null) {
+      ExceptionWrapper ew = new ExceptionWrapper(ex);
+      if (checkPoints != null) {
+        for (int i = 0, c = checkPoints.size(); i < c; ++i) {
+          ew.message += "\n" + checkPoints.get(i);
         }
-        trial.setExceptionWrapper(ew);
       }
-
-      trials.add(trial);
-    } else {
-      /*
-       * If this was a benchmark, we need to handle exceptions specially. If an
-       * exception occurred, it happened without the trial being recorded. We,
-       * unfortunately, don't know the trial parameters at this point. We should
-       * consider putting the exception handling code directly into the
-       * generated Benchmark subclasses.
-       */
-      if (ex != null) {
-        ExceptionWrapper ew = new ExceptionWrapper(ex);
-        if (checkPoints != null) {
-          for (int i = 0, c = checkPoints.size(); i < c; ++i) {
-            ew.message += "\n" + checkPoints.get(i);
-          }
-        }
-        Trial trial = new Trial();
-        trial.setExceptionWrapper(ew);
-        trials.add(trial);
-      }
+      myResult.setExceptionWrapper(ew);
     }
 
-    results.setSourceRef(getDocumentLocation());
     testIsFinished = true;
     resetAsyncState();
-    GWTRunner.get().reportResultsAndGetNextMethod(results);
+    GWTRunner.get().reportResultsAndGetNextMethod(myResult);
   }
 
   /**
@@ -318,8 +267,7 @@
    * this method serves as a hack to avoid "throws" clause problems.
    */
   private native void runBareTestCaseAvoidingExceptionDecl() /*-{
-    this.@com.google.gwt.junit.client.impl.GWTTestCaseImpl::testCase
-        .@junit.framework.TestCase::runBare()();
+    this.@junit.framework.TestCase::runBare()();
   }-*/;
 
   /**
@@ -332,7 +280,7 @@
    */
   private boolean shouldCatchExceptions() {
     try {
-      return testCase.catchExceptions();
+      return catchExceptions();
     } catch (Throwable e) {
       return true;
     }
diff --git a/user/test/com/google/gwt/emultest/java/util/ArraySortBenchmark.java b/user/test/com/google/gwt/emultest/java/util/ArraySortBenchmark.java
index 9dbf683..abc1495 100644
--- a/user/test/com/google/gwt/emultest/java/util/ArraySortBenchmark.java
+++ b/user/test/com/google/gwt/emultest/java/util/ArraySortBenchmark.java
@@ -15,9 +15,9 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.IntRange;
-import com.google.gwt.junit.client.Operator;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
 
 import java.util.Arrays;
 
diff --git a/user/test/com/google/gwt/emultest/java/util/HashMapBenchmark.java b/user/test/com/google/gwt/emultest/java/util/HashMapBenchmark.java
index f35e371..50653ea 100644
--- a/user/test/com/google/gwt/emultest/java/util/HashMapBenchmark.java
+++ b/user/test/com/google/gwt/emultest/java/util/HashMapBenchmark.java
@@ -1,12 +1,12 @@
 /*
  * 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
@@ -15,12 +15,12 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import com.google.gwt.junit.client.Range;
-import com.google.gwt.junit.client.IntRange;
-import com.google.gwt.junit.client.Operator;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.annotations.RangeField;
-import com.google.gwt.junit.client.annotations.Setup;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
+import com.google.gwt.benchmarks.client.Range;
+import com.google.gwt.benchmarks.client.RangeField;
+import com.google.gwt.benchmarks.client.Setup;
 
 import java.util.HashMap;
 
@@ -48,8 +48,8 @@
    * Integers, and contain duplicate values.
    */
   @Setup("beginHashMapContainsValueInt")
-  public void testHashMapContainsValueInt(
-      @RangeField("containsRange")Integer size) {
+  public void testHashMapContainsValueInt(@RangeField("containsRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       Integer intVal = new Integer(i);
@@ -65,8 +65,8 @@
    * Strings, and contain duplicate values.
    */
   @Setup("beginHashMapContainsValueString")
-  public void testHashMapContainsValueString(
-      @RangeField("containsRange")Integer size) {
+  public void testHashMapContainsValueString(@RangeField("containsRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       String strVal = Integer.toString(i);
@@ -82,8 +82,8 @@
    * Integers, and contain duplicate values.
    */
   @Setup("initMap")
-  public void testHashMapDuplicateIntAdds(
-      @RangeField("baseRange")Integer size) {
+  public void testHashMapDuplicateIntAdds(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       Integer intVal = new Integer(i / 10);
@@ -95,12 +95,12 @@
   }
 
   /**
-   * Appends <code>size</code> items to an empty HashMap. All items are Strings,
-   * and contain duplicate values.
+   * Appends <code>size</code> items to an empty HashMap. All items are
+   * Strings, and contain duplicate values.
    */
   @Setup("initMap")
-  public void testHashMapDuplicateStringAdds(
-      @RangeField("baseRange")Integer size) {
+  public void testHashMapDuplicateStringAdds(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       String strVal = Integer.toString(i / 10);
@@ -116,7 +116,8 @@
    * Integers, and do not contain duplicate values.
    */
   @Setup("initMap")
-  public void testHashMapIntAdds(@RangeField("baseRange")Integer size) {
+  public void testHashMapIntAdds(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       Integer intVal = new Integer(i);
@@ -132,7 +133,8 @@
    * Integers, and contain duplicate values.
    */
   @Setup("beginHashMapIntGets")
-  public void testHashMapIntGets(@RangeField("baseRange")Integer size) {
+  public void testHashMapIntGets(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       Integer intVal = new Integer(i);
@@ -144,11 +146,12 @@
   }
 
   /**
-   * Appends <code>size</code> items to an empty HashMap. All items are Strings,
-   * and do not contain duplicate values.
+   * Appends <code>size</code> items to an empty HashMap. All items are
+   * Strings, and do not contain duplicate values.
    */
   @Setup("initMap")
-  public void testHashMapStringAdds(@RangeField("baseRange")Integer size) {
+  public void testHashMapStringAdds(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       String strVal = Integer.toString(i);
@@ -164,7 +167,8 @@
    * contain duplicate values.
    */
   @Setup("beginHashMapStringGets")
-  public void testHashMapStringGets(@RangeField("baseRange")Integer size) {
+  public void testHashMapStringGets(@RangeField("baseRange")
+  Integer size) {
     int num = size.intValue();
     for (int i = 0; i < num; i++) {
       String strVal = Integer.toString(i);
diff --git a/user/test/com/google/gwt/emultest/java/util/ListBenchmark.java b/user/test/com/google/gwt/emultest/java/util/ListBenchmark.java
index a61a9f6..c58675e 100644
--- a/user/test/com/google/gwt/emultest/java/util/ListBenchmark.java
+++ b/user/test/com/google/gwt/emultest/java/util/ListBenchmark.java
@@ -15,15 +15,15 @@
  */
 package com.google.gwt.emultest.java.util;
 
-import com.google.gwt.junit.client.IntRange;
-import com.google.gwt.junit.client.Benchmark;
-import com.google.gwt.junit.client.Operator;
-import com.google.gwt.junit.client.annotations.RangeField;
-import com.google.gwt.junit.client.annotations.RangeEnum;
-import com.google.gwt.junit.client.annotations.Setup;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
+import com.google.gwt.benchmarks.client.RangeEnum;
+import com.google.gwt.benchmarks.client.RangeField;
+import com.google.gwt.benchmarks.client.Setup;
 
-import java.util.List;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Benchmarks common operations on {@link List Lists}. This test covers
diff --git a/user/test/com/google/gwt/junit/client/BenchmarkTest.java b/user/test/com/google/gwt/junit/client/BenchmarkTest.java
index 54cb922..7540ec9 100644
--- a/user/test/com/google/gwt/junit/client/BenchmarkTest.java
+++ b/user/test/com/google/gwt/junit/client/BenchmarkTest.java
@@ -16,10 +16,13 @@
 
 package com.google.gwt.junit.client;
 
-import com.google.gwt.junit.client.annotations.RangeField;
-import com.google.gwt.junit.client.annotations.RangeEnum;
-import com.google.gwt.junit.client.annotations.Setup;
-import com.google.gwt.junit.client.annotations.Teardown;
+import com.google.gwt.benchmarks.client.Benchmark;
+import com.google.gwt.benchmarks.client.IntRange;
+import com.google.gwt.benchmarks.client.Operator;
+import com.google.gwt.benchmarks.client.RangeEnum;
+import com.google.gwt.benchmarks.client.RangeField;
+import com.google.gwt.benchmarks.client.Setup;
+import com.google.gwt.benchmarks.client.Teardown;
 
 /**
  * Basic Benchmark testing.