diff --git a/build.xml b/build.xml
index 15c364e..c783631 100755
--- a/build.xml
+++ b/build.xml
@@ -152,11 +152,6 @@
     <call-subproject subproject="requestfactory" subtarget="test" />
   </target>
 
-  <target name="benchmark" depends="dist-dev" 
-          description="[action] Runs all the GWT benchmarks">
-    <call-subproject subproject="user" subtarget="benchmark" />
-  </target>
-
   <path id="emma.classpath.src">
     <pathelement location="${gwt.root}/user/src" />
     <pathelement location="${gwt.root}/dev/**/src/com/google" />
diff --git a/common.ant.xml b/common.ant.xml
index dbb7514..654c118 100755
--- a/common.ant.xml
+++ b/common.ant.xml
@@ -111,9 +111,6 @@
   <property name="gwt.junit.port" value="8888" />
   <property name="gwt.junit.testcase.includes" value="**/*Suite.class"/>
 
-  <!-- Benchmark support -->
-  <property name="gwt.benchmark.testcase.includes" value="**/*SuiteBenchmark.class"/>
-
   <!-- Shared class paths -->
   <path id="project.classpath.class">
     <pathelement location="${javac.out}" />
diff --git a/distro-source/build.xml b/distro-source/build.xml
index 64e8e33..59d384e 100755
--- a/distro-source/build.xml
+++ b/distro-source/build.xml
@@ -32,7 +32,6 @@
       <zipfileset file="${gwt.build.lib}/gwt-servlet.jar" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/gwt-codeserver.jar" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/gwt-servlet-deps.jar" prefix="${project.distname}" />
-      <zipfileset file="${gwt.build.lib}/gwt-benchmark-viewer.war" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/gwt-soyc-vis.jar" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/gwt-api-checker.jar" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/requestfactory*.jar" prefix="${project.distname}" />
diff --git a/distro-source/common.ant.xml b/distro-source/common.ant.xml
index cef80ec..7bad06e 100755
--- a/distro-source/common.ant.xml
+++ b/distro-source/common.ant.xml
@@ -9,12 +9,10 @@
 
   <patternset id="chmod.executables">
     <include name="*Creator" />
-    <include name="benchmarkViewer" />
   </patternset>
 
   <patternset id="chmod.not.executables">
     <exclude name="*Creator" />
-    <exclude name="benchmarkViewer" />
   </patternset>
 
   <target name="filter" description="Filters distro files for versioning">
diff --git a/distro-source/core/src/COPYING b/distro-source/core/src/COPYING
index 95a65cf..11f016a 100644
--- a/distro-source/core/src/COPYING
+++ b/distro-source/core/src/COPYING
@@ -202,13 +202,6 @@
     http://asm.objectweb.org/license.html
   Source code availability: com/google/gwt/dev/asm/ within gwt-dev.jar
   
-* Browser Detect v2.1.6
-  License: Creative Commons Attribution 1.0
-    http://creativecommons.org/licenses/by/1.0/
-  Source code availability:
-    http://google-web-toolkit.googlecode.com/svn/trunk/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/BrowserInfo.java
-    (transliterated into Java source)
-
 * Eclipse Java Development Tools (JDT)
   License: Eclipse Public License v. 1.0 
     http://www.eclipse.org/legal/epl-v10.html
diff --git a/distro-source/core/src/COPYING.html b/distro-source/core/src/COPYING.html
index 2615334..b0c85e7 100755
--- a/distro-source/core/src/COPYING.html
+++ b/distro-source/core/src/COPYING.html
@@ -293,11 +293,6 @@
     <td class="license">(<a href="http://asm.objectweb.org/license.html">custom</a>)</td>
     <td class="location">com/google/gwt/dev/asm/ within gwt-dev.jar</td>
   </tr>
-  <tr class="even">
-    <td class="package">Browser Detect v2.1.6</td>
-    <td class="license"><a href="http://creativecommons.org/licenses/by/1.0/">Creative Commons Attribution 1.0</a></td>
-    <td class="location"><a href="http://google-web-toolkit.googlecode.com/svn/trunk/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/BrowserInfo.java">google-web-toolkit.googlecode.com</a>; transliterated into Java source</td>
-  </tr>
   <tr>
     <td class="package">Eclipse Java Development Tools (JDT)</td>
     <td class="license"><a href="http://www.eclipse.org/legal/epl-v10.html">Eclipse Public License v. 1.0</a></td>
diff --git a/distro-source/src/benchmarkViewer b/distro-source/src/benchmarkViewer
deleted file mode 100755
index 8672c6f..0000000
--- a/distro-source/src/benchmarkViewer
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-APPDIR=`dirname $0`;
-java -Dcom.google.gwt.junit.reportPath="$1" -cp "$APPDIR/gwt-dev.jar" com.google.gwt.dev.RunWebApp -port auto $APPDIR/gwt-benchmark-viewer.war;
diff --git a/distro-source/src/benchmarkViewer.cmd b/distro-source/src/benchmarkViewer.cmd
deleted file mode 100755
index beef709..0000000
--- a/distro-source/src/benchmarkViewer.cmd
+++ /dev/null
@@ -1 +0,0 @@
-@java -Dcom.google.gwt.junit.reportPath="%1" -cp "%~dp0/gwt-dev.jar" com.google.gwt.dev.RunWebApp -port auto %~dp0/gwt-benchmark-viewer.war
diff --git a/eclipse/lang/.classpath b/eclipse/lang/.classpath
index 4dc55c0..ec76856 100644
--- a/eclipse/lang/.classpath
+++ b/eclipse/lang/.classpath
@@ -4,7 +4,6 @@
 	<classpathentry kind="src" path="user/super/com/google/gwt/typedarrays/super"/>
 	<classpathentry kind="src" path="user/src/com/google/gwt/regexp/super"/>
 	<classpathentry kind="src" path="user/super/com/google/gwt/user/translatable"/>
-	<classpathentry kind="src" path="user/super/com/google/gwt/benchmarks/translatable"/>
 	<classpathentry kind="src" path="user/super/com/google/gwt/emul"/>
 	<classpathentry kind="src" path="user/super/com/google/gwt/junit/translatable"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
diff --git a/eclipse/servlet/.classpath b/eclipse/servlet/.classpath
index 081e590..f8db73c 100644
--- a/eclipse/servlet/.classpath
+++ b/eclipse/servlet/.classpath
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry excluding="**/rebind/|**/tools/|com/google/gwt/json/|com/google/gwt/junit/*.java|com/google/gwt/junit/benchmarks/|com/google/gwt/junit/client/Benchmark.java|com/google/gwt/junit/client/GWTTestCase.java|com/google/gwt/junit/remote/|com/google/gwt/junit/server/" kind="src" path="core/src"/>
+	<classpathentry excluding="**/rebind/|**/tools/|com/google/gwt/json/|com/google/gwt/junit/*.java|com/google/gwt/junit/client/GWTTestCase.java|com/google/gwt/junit/remote/|com/google/gwt/junit/server/" kind="src" path="core/src"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/junit/junit-4.8.2.jar" sourcepath="/GWT_TOOLS/lib/junit/junit-4.8.2-src.zip"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/tomcat/servlet-api-2.4.jar"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/gwt-user"/>
diff --git a/eclipse/tools/benchmark-viewer/.checkstyle b/eclipse/tools/benchmark-viewer/.checkstyle
deleted file mode 100644
index 0f1cbd9..0000000
--- a/eclipse/tools/benchmark-viewer/.checkstyle
+++ /dev/null
@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<fileset-config file-format-version="1.2.0" simple-config="true">
-    <fileset name="all" enabled="true" check-config-name="GWT Checks" local="false">
-        <file-match-pattern match-pattern="." include-pattern="true"/>
-    </fileset>
-    <filter name="NonSrcDirs" enabled="true"/>
-</fileset-config>
diff --git a/eclipse/tools/benchmark-viewer/.classpath b/eclipse/tools/benchmark-viewer/.classpath
deleted file mode 100644
index fc34c4f..0000000
--- a/eclipse/tools/benchmark-viewer/.classpath
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" path="core/src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/gwt-user"/>
-	<classpathentry kind="var" path="GWT_TOOLS/lib/jfreechart/jfreechart-1.0.3.jar"/>
-	<classpathentry kind="var" path="GWT_TOOLS/lib/jfreechart/jcommon-1.0.6.jar"/>
-	<classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/eclipse/tools/benchmark-viewer/.project b/eclipse/tools/benchmark-viewer/.project
deleted file mode 100644
index a5983bb..0000000
--- a/eclipse/tools/benchmark-viewer/.project
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>benchmark-viewer</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>com.atlassw.tools.eclipse.checkstyle.CheckstyleBuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>com.atlassw.tools.eclipse.checkstyle.CheckstyleNature</nature>
-	</natures>
-	<linkedResources>
-		<link>
-			<name>core</name>
-			<type>2</type>
-			<locationURI>GWT_ROOT/tools/benchmark-viewer</locationURI>
-		</link>
-	</linkedResources>
-</projectDescription>
diff --git a/tools/api-checker/config/gwt25_26userApi.conf b/tools/api-checker/config/gwt25_26userApi.conf
index ec9279c..e8c0fed 100644
--- a/tools/api-checker/config/gwt25_26userApi.conf
+++ b/tools/api-checker/config/gwt25_26userApi.conf
@@ -139,3 +139,9 @@
 #Api  whitelist
 # when adding to the white-list, include comments as to why the addition is
 # being made.
+
+# Removed an internal method of GWTTestCase
+com.google.gwt.junit.client.GWTTestCase::__getOrCreateTestResult() MISSING
+
+# Removed deprecated benchmark infra
+com.google.gwt.benchmarks.client MISSING
diff --git a/tools/benchmark-viewer/build.xml b/tools/benchmark-viewer/build.xml
deleted file mode 100755
index d243b06..0000000
--- a/tools/benchmark-viewer/build.xml
+++ /dev/null
@@ -1,93 +0,0 @@
-<project name="benchmark-viewer" default="build" basedir=".">
-
-  <!--
-    TODO(tobyr) 
-
-    Once we have more than a single tool, this build should be re-examined
-    to see if several of the targets should be lifted into common.ant.xml.
-    The simple targets, like tests*, clean, and checkstyle are good
-    candidates, while the other targets depend heavily on the actual
-    makeup of the future tools.
-  -->
-
-  <property name="gwt.root" location="../.." />
-  <property name="project.tail" value="tools/benchmark-viewer" />
-  <import file="${gwt.root}/common.ant.xml" />
-
-    <!-- Platform shouldn't matter here, just picking one -->
-  <property.ensure name="gwt.dev.jar" location="${gwt.build.lib}/gwt-dev.jar" />
-  <property.ensure name="gwt.user.jar" location="${gwt.build.lib}/gwt-user.jar" />
-  <property.ensure name="gwt.servlet.jar" location="${gwt.build.lib}/gwt-servlet.jar" />
-
-  <property name="war" location="${project.build}/war" />
-
-  <path id="project.class.path">
-    <pathelement location="war/WEB-INF/classes"/>
-    <pathelement location="${gwt.user.jar}"/>
-    <pathelement location="${gwt.dev.jar}"/>
-    <fileset dir="${war}/WEB-INF/lib" includes="**/*.jar"/>
-  </path>
-
-  <target name="wardir" description="Create the target war directory">
-    <copy todir="${war}">
-      <fileset dir="war" excludes="WEB-INF/classes/marker" />
-    </copy>
-    <mkdir dir="${war}/WEB-INF/lib" />
-    <copy todir="${war}/WEB-INF/lib" file="${gwt.servlet.jar}" />
-    <copy todir="${war}/WEB-INF/lib" file="${gwt.tools.lib}/jfreechart/jfreechart-1.0.3.jar" />
-    <copy todir="${war}/WEB-INF/lib" file="${gwt.tools.lib}/jfreechart/jcommon-1.0.6.jar" />
-  </target>
-
-  <target name="javac" depends="wardir" description="Compile java source">
-    <mkdir dir="${war}/WEB-INF/classes"/>
-    <gwt.javac destdir="${war}/WEB-INF/classes">
-      <classpath refid="project.class.path"/>
-    </gwt.javac>
-    <copy todir="${war}/WEB-INF/classes">
-      <fileset dir="src" excludes="**/*.java"/>
-    </copy>
-  </target>
-
-  <target name="gwtc" depends="javac" description="GWT compile to JavaScript">
-    <outofdate>
-      <sourcefiles>
-        <fileset dir="src"/>
-        <path refid="project.class.path"/>
-      </sourcefiles>
-      <targetfiles path="${war}/reportViewer/reportViewer.nocache.js" />
-      <sequential>
-        <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
-          <classpath>
-            <pathelement location="src"/>
-            <path refid="project.class.path"/>
-            <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA.jar"/>
-            <pathelement location="${gwt.tools.lib}/javax/validation/validation-api-1.0.0.GA-sources.jar"/>
-          </classpath>
-          <jvmarg value="-Xmx256M"/>
-          <arg value="-war"/>
-          <arg value="${war}"/>
-          <arg value="com.google.gwt.benchmarks.viewer.ReportViewer"/>
-        </java>
-      </sequential>
-    </outofdate>
-  </target>
-
-  <target name="war" depends="gwtc" description="Create a war file">
-    <zip destfile="${gwt.build.lib}/gwt-benchmark-viewer.war" basedir="${war}"/>
-  </target>
-
-  <target name="build" depends="war" description="Build this project" />
-
-  <target name="clean" description="Cleans this project">
-    <delete dir="${war}" failonerror="false" />
-    <delete file="${gwt.build.lib}/gwt-benchmark-viewer.war" failonerror="false" />
-  </target>
-
-  <target name="checkstyle" description="Static analysis of source">
-    <gwt.checkstyle>
-      <fileset dir="src"/>
-    </gwt.checkstyle>
-  </target>
-
-  <target name="test" depends="build" />
-</project>
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/ReportViewer.gwt.xml b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/ReportViewer.gwt.xml
deleted file mode 100644
index 0dd5d3e..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/ReportViewer.gwt.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<!--                                                                        -->
-<!-- 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   -->
-<!-- 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.                          -->
-<!--                                                                        -->
-<module rename-to="reportViewer">
-  <inherits name="com.google.gwt.user.User"/>
-  <inherits name="com.google.gwt.http.HTTP"/>
-
-  <source path="client"/>
-
-  <entry-point class="com.google.gwt.benchmarks.viewer.client.ReportViewer"/>
-
-  <servlet path='/test_reports' class='com.google.gwt.benchmarks.viewer.server.ReportServerImpl'/>
-  <servlet path='/test_images/*' class='com.google.gwt.benchmarks.viewer.server.ReportImageServer'/>
-</module>
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Benchmark.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Benchmark.java
deleted file mode 100644
index 421ad8a..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Benchmark.java
+++ /dev/null
@@ -1,76 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.List;
-
-/**
- * A data object for Benchmark.
- */
-public class Benchmark implements IsSerializable {
-
-  private String className;
-
-  private String description;
-
-  private String name;
-
-  private List<Result> results;
-
-  private String sourceCode;
-
-  public String getClassName() {
-    return className;
-  }
-
-  public String getDescription() {
-    return description;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public List<Result> getResults() {
-    return results;
-  }
-
-  public String getSourceCode() {
-    return sourceCode;
-  }
-
-  public void setClassName(String className) {
-    this.className = className;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-
-  public void setResults(List<Result> results) {
-    this.results = results;
-  }
-
-  public void setSourceCode(String sourceCode) {
-    this.sourceCode = sourceCode;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/BrowserInfo.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/BrowserInfo.java
deleted file mode 100644
index 63b5721..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/BrowserInfo.java
+++ /dev/null
@@ -1,170 +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.benchmarks.viewer.client;
-
-/**
- * Provides information about a browser (vendor,version,operating system,etc...)
- * based on user agent and other easily accessible information.
- * 
- * This is not meant to be a "detect script" to implement browser workarounds,
- * but rather a "pretty printer" for the browser information.
- * 
- * This code is a derivation of Browser Detect v2.1.6 documentation:
- * http://www.dithered.com/javascript/browser_detect/index.html license:
- * http://creativecommons.org/licenses/by/1.0/ code by Chris Nott
- * (chris[at]dithered[dot]com)
- * 
- * It has been transliterated from JavaScript to Java with additional changes
- * along the way.
- */
-public class BrowserInfo {
-
-  /**
-   * Retrieves a "pretty" version of the browser version information.
-   * 
-   * @param userAgent - The HTTP user agent string.
-   * @return A pretty-printed version of the browser including the a) vendor b)
-   *         version c) and operating system
-   */
-  @SuppressWarnings("unused")
-  public static String getBrowser(String userAgent) {
-
-    userAgent = userAgent.toLowerCase();
-
-    // browser engine name
-    boolean isGecko = userAgent.indexOf("gecko") != -1 && userAgent.indexOf("safari") == -1;
-    boolean isAppleWebKit = userAgent.indexOf("applewebkit") != -1;
-
-    // browser name
-    boolean isKonqueror = userAgent.indexOf("konqueror") != -1;
-    boolean isSafari = userAgent.indexOf("safari") != -1;
-    boolean isOmniweb = userAgent.indexOf("omniweb") != -1;
-    boolean isOpera = userAgent.indexOf("opera") != -1;
-    boolean isIcab = userAgent.indexOf("icab") != -1;
-    boolean isAol = userAgent.indexOf("aol") != -1;
-    boolean isIE =
-        userAgent.indexOf("msie") != -1 && !isOpera && (userAgent.indexOf("webtv") == -1);
-    boolean isMozilla = isGecko && userAgent.indexOf("gecko/") + 14 == userAgent.length();
-    boolean isFirefox = userAgent.indexOf("firefox/") != -1 || userAgent.indexOf("firebird/") != -1;
-    boolean isNS =
-        isGecko ? userAgent.indexOf("netscape") != -1 : userAgent.indexOf("mozilla") != -1
-            && !isOpera && !isSafari && userAgent.indexOf("spoofer") == -1
-            && userAgent.indexOf("compatible") == -1 && userAgent.indexOf("webtv") == -1
-            && userAgent.indexOf("hotjava") == -1;
-
-    // spoofing and compatible browsers
-    boolean isIECompatible = userAgent.indexOf("msie") != -1 && !isIE;
-    boolean isNSCompatible = userAgent.indexOf("mozilla") != -1 && !isNS && !isMozilla;
-
-    // rendering engine versions
-    String geckoVersion =
-        isGecko ? userAgent.substring(userAgent.lastIndexOf("gecko/") + 6, userAgent
-            .lastIndexOf("gecko/") + 14) : "-1";
-    String equivalentMozilla = isGecko ? userAgent.substring(userAgent.indexOf("rv:") + 3) : "-1";
-    String appleWebKitVersion =
-        isAppleWebKit ? userAgent.substring(userAgent.indexOf("applewebkit/") + 12) : "-1";
-
-    // float versionMinor = parseFloat(navigator.appVersion);
-    String versionMinor = "";
-
-    // correct version number
-    if (isGecko && !isMozilla) {
-      versionMinor =
-          userAgent.substring(userAgent.indexOf("/", userAgent.indexOf("gecko/") + 6) + 1);
-    } else if (isMozilla) {
-      versionMinor = userAgent.substring(userAgent.indexOf("rv:") + 3);
-    } else if (isIE) {
-      versionMinor = userAgent.substring(userAgent.indexOf("msie ") + 5);
-    } else if (isKonqueror) {
-      versionMinor = userAgent.substring(userAgent.indexOf("konqueror/") + 10);
-    } else if (isSafari) {
-      versionMinor = userAgent.substring(userAgent.lastIndexOf("safari/") + 7);
-    } else if (isOmniweb) {
-      versionMinor = userAgent.substring(userAgent.lastIndexOf("omniweb/") + 8);
-    } else if (isOpera) {
-      versionMinor = userAgent.substring(userAgent.indexOf("opera") + 6);
-    } else if (isIcab) {
-      versionMinor = userAgent.substring(userAgent.indexOf("icab") + 5);
-    }
-
-    String version = getVersion(versionMinor);
-
-    // dom support
-    // boolean isDOM1 = (document.getElementById);
-    // boolean isDOM2Event = (document.addEventListener &&
-    // document.removeEventListener);
-
-    // css compatibility mode
-    // this.mode = document.compatMode ? document.compatMode : "BackCompat";
-
-    // platform
-    boolean isWin = userAgent.indexOf("win") != -1;
-    boolean isWin32 =
-        isWin && userAgent.indexOf("95") != -1 || userAgent.indexOf("98") != -1
-            || userAgent.indexOf("nt") != -1 || userAgent.indexOf("win32") != -1
-            || userAgent.indexOf("32bit") != -1 || userAgent.indexOf("xp") != -1;
-
-    boolean isMac = userAgent.indexOf("mac") != -1;
-    boolean isUnix =
-        userAgent.indexOf("unix") != -1 || userAgent.indexOf("sunos") != -1
-            || userAgent.indexOf("bsd") != -1 || userAgent.indexOf("x11") != -1;
-
-    boolean isLinux = userAgent.indexOf("linux") != -1;
-
-    // specific browser shortcuts
-    /*
-     * this.isNS4x = (this.isNS && this.versionMajor == 4); this.isNS40x =
-     * (this.isNS4x && this.versionMinor < 4.5); this.isNS47x = (this.isNS4x &&
-     * this.versionMinor >= 4.7); this.isNS4up = (this.isNS && this.versionMinor
-     * >= 4); this.isNS6x = (this.isNS && this.versionMajor == 6); this.isNS6up
-     * = (this.isNS && this.versionMajor >= 6); this.isNS7x = (this.isNS &&
-     * this.versionMajor == 7); this.isNS7up = (this.isNS && this.versionMajor
-     * >= 7);
-     * 
-     * this.isIE4x = (this.isIE && this.versionMajor == 4); this.isIE4up =
-     * (this.isIE && this.versionMajor >= 4); this.isIE5x = (this.isIE &&
-     * this.versionMajor == 5); this.isIE55 = (this.isIE && this.versionMinor ==
-     * 5.5); this.isIE5up = (this.isIE && this.versionMajor >= 5); this.isIE6x =
-     * (this.isIE && this.versionMajor == 6); this.isIE6up = (this.isIE &&
-     * this.versionMajor >= 6);
-     * 
-     * this.isIE4xMac = (this.isIE4x && this.isMac);
-     */
-
-    String name =
-        isGecko ? "Gecko" : isAppleWebKit ? "Apple WebKit" : isKonqueror ? "Konqueror" : isSafari
-            ? "Safari" : isOpera ? "Opera" : isIE ? "IE" : isMozilla ? "Mozilla" : isFirefox
-                ? "Firefox" : isNS ? "Netscape" : "";
-
-    name +=
-        " " + version + " on "
-            + (isWin ? "Windows" : isMac ? "Mac" : isUnix ? "Unix" : isLinux ? "Linux" : "Unknown");
-
-    return name;
-  }
-
-  // Reads the version from a string which begins with a version number
-  // and contains additional character data
-  private static String getVersion(String versionPlusCruft) {
-    for (int index = 0; index < versionPlusCruft.length(); ++index) {
-      char c = versionPlusCruft.charAt(index);
-      if (c != '.' && !Character.isDigit(c)) {
-        return versionPlusCruft.substring(0, index);
-      }
-    }
-    return versionPlusCruft;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Category.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Category.java
deleted file mode 100644
index 2748aff..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Category.java
+++ /dev/null
@@ -1,56 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.List;
-
-/**
- * A data object for Category.
- */
-public class Category implements IsSerializable {
-
-  private List<Benchmark> benchmarks;
-
-  private String description;
-
-  private String name;
-
-  public List<Benchmark> getBenchmarks() {
-    return benchmarks;
-  }
-
-  public String getDescription() {
-    return description;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public void setBenchmarks(List<Benchmark> benchmarks) {
-    this.benchmarks = benchmarks;
-  }
-
-  public void setDescription(String description) {
-    this.description = description;
-  }
-
-  public void setName(String name) {
-    this.name = name;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Report.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Report.java
deleted file mode 100644
index b179ab4..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Report.java
+++ /dev/null
@@ -1,92 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * A data object for Report.
- */
-public class Report implements IsSerializable {
-
-  private List<Category> categories;
-
-  private Date date;
-
-  // Temporary addition until we get better date
-  private String dateString;
-
-  // formatting in GWT
-  private String gwtVersion;
-
-  private String id;
-
-  public List<Category> getCategories() {
-    return categories;
-  }
-
-  public Date getDate() {
-    return date;
-  }
-
-  public String getDateString() {
-    return dateString;
-  }
-
-  public String getGwtVersion() {
-    return gwtVersion;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public ReportSummary getSummary() {
-    int numTests = 0;
-    boolean testsPassed = true;
-
-    for (int i = 0; i < categories.size(); ++i) {
-      Category c = categories.get(i);
-      List<Benchmark> benchmarks = c.getBenchmarks();
-      numTests += benchmarks.size();
-    }
-
-    return new ReportSummary(id, date, dateString, numTests, testsPassed);
-  }
-
-  public void setCategories(List<Category> categories) {
-    this.categories = categories;
-  }
-
-  public void setDate(Date date) {
-    this.date = date;
-  }
-
-  public void setDateString(String dateString) {
-    this.dateString = dateString;
-  }
-
-  public void setGwtVersion(String gwtVersion) {
-    this.gwtVersion = gwtVersion;
-  }
-
-  public void setId(String id) {
-    this.id = id;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServer.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServer.java
deleted file mode 100644
index 07810ed..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServer.java
+++ /dev/null
@@ -1,47 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.RemoteService;
-import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
-
-import java.util.List;
-
-/**
- * Provides Benchmark report summaries and details. This service must be running
- * in order to view the reports via ReportViewer.
- * 
- * @see com.google.gwt.junit.viewer.server.ReportServerImpl
- * @see ReportViewer
- */
-@RemoteServiceRelativePath("test_reports")
-public interface ReportServer extends RemoteService {
-
-  /**
-   * Returns the full details of the specified report.
-   * 
-   * @param reportId The id of the report. Originates from the ReportSummary.
-   * @return the matching Report, or null if the Report could not be found.
-   */
-  Report getReport(String reportId);
-
-  /**
-   * Returns a list of summaries of all the Benchmark reports.
-   * 
-   * @return a non-null list of ReportSummary
-   */
-  List<ReportSummary> getReportSummaries();
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServerAsync.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServerAsync.java
deleted file mode 100644
index d128334..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportServerAsync.java
+++ /dev/null
@@ -1,32 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-import java.util.List;
-
-/**
- * The asynchronous interface for ReportServer.
- * 
- * @see ReportServer
- */
-public interface ReportServerAsync {
-
-  void getReport(String reportId, AsyncCallback<Report> callback);
-
-  void getReportSummaries(AsyncCallback<List<ReportSummary>> callback);
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportSummary.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportSummary.java
deleted file mode 100644
index 2d944ed..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportSummary.java
+++ /dev/null
@@ -1,70 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.Date;
-
-/**
- * A data object summarizing the results of a report.
- */
-public class ReportSummary implements IsSerializable {
-
-  private boolean allTestsSucceeded;
-
-  private Date date;
-
-  // A temporary addition until we get better date formatting in GWT user
-  private String dateString;
-
-  private String id;
-
-  // in GWT
-  private int numTests;
-
-  public ReportSummary() {
-  }
-
-  public ReportSummary(String id, Date date, String dateString, int numTests,
-      boolean allTestsSucceeded) {
-    this.id = id;
-    this.date = date;
-    this.dateString = dateString;
-    this.numTests = numTests;
-    this.allTestsSucceeded = allTestsSucceeded;
-  }
-
-  public boolean allTestsSucceeded() {
-    return allTestsSucceeded;
-  }
-
-  public Date getDate() {
-    return date;
-  }
-
-  public String getDateString() {
-    return dateString;
-  }
-
-  public String getId() {
-    return id;
-  }
-
-  public int getNumTests() {
-    return numTests;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportViewer.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportViewer.java
deleted file mode 100644
index 4e7c4df..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/ReportViewer.java
+++ /dev/null
@@ -1,499 +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.benchmarks.viewer.client;
-
-import com.google.gwt.core.client.EntryPoint;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.http.client.URL;
-import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Element;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.HistoryListener;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.CellPanel;
-import com.google.gwt.user.client.ui.ClickListener;
-import com.google.gwt.user.client.ui.FlexTable;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.HasHorizontalAlignment;
-import com.google.gwt.user.client.ui.HasVerticalAlignment;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Hyperlink;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.SourcesTableEvents;
-import com.google.gwt.user.client.ui.TableListener;
-import com.google.gwt.user.client.ui.VerticalPanel;
-import com.google.gwt.user.client.ui.Widget;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-/**
- * The application for viewing benchmark reports. In order for the ReportViewer
- * to operate correctly, you must have both the {@link ReportServer} RPC and
- * {@link com.google.gwt.junit.viewer.server.ReportImageServer} servlets up and
- * running within a servlet container.
- * 
- * <code>ReportViewer's</code> GWT XML module is configured to start these
- * servlets by default. Just start <code>ReportViewer</code> in hosted mode, and
- * GWT will run them within its own embedded servlet engine. For example,
- * 
- * <pre>java -cp &lt;classpath&gt; com.google.gwt.dev.GWTShell -out
- * ReportViewerShell/www
- * com.google.gwt.junit.viewer.ReportViewer/ReportViewer.html</pre>
- * 
- * You can configure the location where ReportServer reads the benchmark reports
- * from by setting the system property named in
- * {@link com.google.gwt.benchmarks.client.Benchmark#REPORT_PATH}.
- */
-@SuppressWarnings("deprecation")
-public class ReportViewer implements EntryPoint, HistoryListener {
-
-  private static class MutableBool {
-
-    boolean value;
-
-    MutableBool(boolean value) {
-      this.value = value;
-    }
-  }
-
-  private class SummariesTableListener implements TableListener {
-
-    public void onCellClicked(SourcesTableEvents sender, int row, int col) {
-      if (row > 0) {
-        ReportSummary summary = summaries.get(row - 1);
-        String token = summary.getId();
-        // Short circuit the history loop.
-        selectReport(row, token);
-        History.newItem(token);
-      }
-    }
-  }
-
-  private static final String imageServer = GWT.getModuleBaseURL() + "test_images/";
-
-  HTML detailsLabel;
-
-  Report report;
-
-  VerticalPanel reportPanel;
-
-  ReportServerAsync reportServer;
-
-  FlexTable reportTable;
-
-  HTML statusLabel;
-
-  List<ReportSummary> summaries;
-
-  VerticalPanel summariesPanel;
-
-  FlexTable summariesTable;
-
-  CellPanel topPanel;
-
-  private int currentSelectedRow;
-
-  private String currentToken;
-
-  public void onHistoryChanged(String token) {
-    assert (summaries != null);
-    int row = 1;
-    for (ReportSummary summary : summaries) {
-      if (summary.getId().equals(token)) {
-        selectReport(row, token);
-        return;
-      }
-      ++row;
-    }
-    selectReport(0, token);
-  }
-
-  public void onModuleLoad() {
-    init();
-
-    // Asynchronously load the summaries
-    reportServer = (ReportServerAsync) GWT.create(ReportServer.class);
-
-    reportServer.getReportSummaries(new AsyncCallback<List<ReportSummary>>() {
-      public void onFailure(Throwable caught) {
-        String msg =
-            "<p>" + caught.toString() + "</p>" + "<p>Is your path to the reports correct?</p>";
-        statusLabel.setHTML(msg);
-      }
-
-      public void onSuccess(List<ReportSummary> result) {
-        summaries = result;
-        if (summaries != null) {
-          if (summaries.size() == 0) {
-            statusLabel.setText("There are no benchmark reports available in this folder.");
-          }
-          Collections.sort(summaries, new Comparator<ReportSummary>() {
-            public int compare(ReportSummary r1, ReportSummary r2) {
-              return r2.getDate().compareTo(r1.getDate()); // most recent first
-            }
-          });
-          displaySummaries();
-
-          // If there's an initial URL, browse to it.
-          onHistoryChanged(History.getToken());
-          History.addHistoryListener(ReportViewer.this);
-        }
-      }
-    });
-  }
-
-  protected void selectReport(int row, String token) {
-    if (row == currentSelectedRow && token.equals(currentToken)) {
-      return;
-    }
-    if (currentSelectedRow != -1) {
-      summariesTable.getRowFormatter().removeStyleName(currentSelectedRow, "viewer-SelectedRow");
-    }
-    currentToken = token;
-    currentSelectedRow = row;
-
-    if (row < 1) {
-      clearReport();
-    } else {
-      fetchReport(row, token);
-    }
-  }
-
-  private void clearReport() {
-    statusLabel.setText("Select a report.");
-    detailsLabel.setHTML("<h3>Report Details</h3>");
-    reportPanel.remove(reportTable);
-  }
-
-  private FlexTable createReportTable() {
-    FlexTable topTable = new FlexTable();
-
-    FlexTable tempReportTable = new FlexTable();
-    tempReportTable.setBorderWidth(1);
-    tempReportTable.setCellPadding(5);
-    tempReportTable.setWidget(0, 0, new Label("Date Created"));
-    tempReportTable.setWidget(0, 1, new Label("GWT Version"));
-
-    if (report == null) {
-      tempReportTable.setWidget(1, 0, new Label("No currently selected report."));
-      tempReportTable.getFlexCellFormatter().setColSpan(1, 0, 3);
-      return tempReportTable;
-    }
-
-    detailsLabel.setHTML("<h3>" + report.getId() + " details </h3>");
-    tempReportTable.setWidget(1, 0, new Label(report.getDateString()));
-    tempReportTable.setWidget(1, 1, new Label(report.getGwtVersion()));
-
-    // topTable.setWidget( 0, 0, tempReportTable );
-    int currentRow = 1;
-
-    Collections.sort(report.getCategories(), new Comparator<Category>() {
-      public int compare(Category c1, Category c2) {
-        return c1.getName().compareTo(c2.getName());
-      }
-    }); // Should be done once in the RPC
-
-    for (int i = 0; i < report.getCategories().size(); ++i) {
-      Category c = report.getCategories().get(i);
-
-      if (!c.getName().equals("")) {
-        FlexTable categoryTable = new FlexTable();
-        categoryTable.setBorderWidth(0);
-        categoryTable.setCellPadding(5);
-        categoryTable.setText(0, 0, c.getName());
-        categoryTable.getFlexCellFormatter().setStyleName(0, 0, "benchmark-category");
-
-        categoryTable.setWidget(0, 1, new Label("Description"));
-        categoryTable.setWidget(1, 0, new Label(c.getName()));
-        categoryTable.setWidget(1, 1, new Label(c.getDescription()));
-
-        topTable.setWidget(currentRow++, 0, categoryTable);
-      }
-
-      Collections.sort(c.getBenchmarks(), new Comparator<Benchmark>() {
-        public int compare(Benchmark b1, Benchmark b2) {
-          return b1.getName().compareTo(b2.getName());
-        }
-      }); // Should be done once in the RPC
-
-      for (int j = 0; j < c.getBenchmarks().size(); ++j) {
-        Benchmark benchmark = c.getBenchmarks().get(j);
-
-        FlexTable benchmarkTable = new FlexTable();
-        benchmarkTable.setBorderWidth(0);
-        benchmarkTable.setCellPadding(5);
-        benchmarkTable.setText(0, 0, benchmark.getName());
-        // benchmarkTable.setText(0, 1, benchmark.getDescription());
-        String codeHtml;
-        String sourceText = benchmark.getSourceCode();
-        if (sourceText != null) {
-          Element tempElem = DOM.createDiv();
-          DOM.setInnerText(tempElem, sourceText);
-          String escapedCodeHtml = DOM.getInnerHTML(tempElem);
-          codeHtml = "<pre>" + escapedCodeHtml + "</pre>";
-        } else {
-          codeHtml = "<i>(source not available)</i>";
-        }
-        benchmarkTable.setWidget(1, 0, new HTML(codeHtml));
-        benchmarkTable.getFlexCellFormatter().setStyleName(0, 0, "benchmark-name");
-        // benchmarkTable.getFlexCellFormatter().setStyleName( 0, 1,
-        // "benchmark-description" );
-        benchmarkTable.getFlexCellFormatter().setStyleName(1, 0, "benchmark-code");
-
-        // TODO(tobyr) Provide detailed benchmark information.
-        // Following bits of commented code are steps in that direction.
-        /*
-         * benchmarkTable.setWidget( 0, 1, new Label( "Description"));
-         * benchmarkTable.setWidget( 0, 2, new Label( "Class Name"));
-         * benchmarkTable.setWidget( 0, 3, new Label( "Source Code"));
-         * benchmarkTable.setWidget( 1, 0, new Label( benchmark.getName()));
-         * benchmarkTable.setWidget( 1, 1, new Label(
-         * benchmark.getDescription())); benchmarkTable.setWidget( 1, 2, new
-         * Label( benchmark.getClassName())); benchmarkTable.setWidget( 1, 3,
-         * new HTML( "<pre>" + benchmark.getSourceCode() + "</pre>"));
-         */
-        topTable.setWidget(currentRow++, 0, benchmarkTable);
-
-        FlexTable resultsTable = new FlexTable();
-        resultsTable.setBorderWidth(0);
-        resultsTable.setCellPadding(5);
-        FlexTable.FlexCellFormatter resultsFormatter = resultsTable.getFlexCellFormatter();
-        topTable.setWidget(currentRow++, 0, resultsTable);
-
-        Collections.sort(benchmark.getResults(), new Comparator<Result>() {
-          public int compare(Result r1, Result r2) {
-            return r1.getAgent().compareTo(r2.getAgent());
-          }
-        }); // Should be done once in the RPC
-
-        final List<FlexTable> trialsTables = new ArrayList<FlexTable>();
-
-        int numVariables = 0;
-        List<String> variableNames = null;
-        if (benchmark.getResults().size() > 0) {
-          Result sampleResult = benchmark.getResults().get(0);
-          if (sampleResult.getTrials().size() > 0) {
-            Trial sampleTrial = sampleResult.getTrials().get(0);
-            numVariables = sampleTrial.getVariables().size();
-            Map<String, String> variables = sampleTrial.getVariables();
-            variableNames = new ArrayList<String>(variables.keySet());
-            Collections.sort(variableNames);
-          }
-        }
-        final MutableBool isVisible = new MutableBool(numVariables > 2);
-        String buttonName = isVisible.value ? "Hide Data" : "Show Data";
-
-        Button visibilityButton = new Button(buttonName, new ClickListener() {
-          public void onClick(Widget sender) {
-            isVisible.value = !isVisible.value;
-            for (int i = 0; i < trialsTables.size(); ++i) {
-              Widget w = trialsTables.get(i);
-              w.setVisible(isVisible.value);
-            }
-            String name = isVisible.value ? "Hide Data" : "Show Data";
-            ((Button) sender).setText(name);
-          }
-        });
-
-        for (int k = 0; k < benchmark.getResults().size(); ++k) {
-          Result result = benchmark.getResults().get(k);
-
-          // Currently only support graphs for results of 2 variables or less
-          if (numVariables <= 2) {
-            resultsTable.setWidget(0, k, new Image(getImageUrl(report.getId(), c.getName(),
-                benchmark.getClassName(), benchmark.getName(), result.getAgent())));
-          } else {
-            if (k == 0) {
-              resultsTable.setHTML(0, k, "<b>" + BrowserInfo.getBrowser(result.getAgent())
-                  + "</b><br><font size=\"-1\">(Graphs are not yet available "
-                  + "for benchmarks with more than two parameters)</font>");
-            }
-          }
-
-          /*
-           * FlexTable allTrialsTable = new FlexTable();
-           * allTrialsTable.setBorderWidth(1); allTrialsTable.setCellPadding(5);
-           * FlexTable.CellFormatter allTrialsFormatter = allTrialsTable
-           * .getFlexCellFormatter(); topTable.setWidget(currentRow++, 0,
-           * allTrialsTable); allTrialsTable.setWidget(0, k, trialsTable);
-           * allTrialsFormatter .setAlignment(0, k,
-           * HasHorizontalAlignment.ALIGN_CENTER,
-           * HasVerticalAlignment.ALIGN_TOP);
-           */
-
-          resultsFormatter.setAlignment(2, k, HasHorizontalAlignment.ALIGN_LEFT,
-              HasVerticalAlignment.ALIGN_TOP);
-
-          // A table of straight data for all trials for an agent
-          FlexTable trialsTable = new FlexTable();
-          trialsTable.setVisible(isVisible.value);
-          trialsTables.add(trialsTable);
-          trialsTable.setBorderWidth(1);
-          trialsTable.setCellPadding(5);
-
-          if (k == 0) {
-            resultsTable.setWidget(1, k, visibilityButton);
-            resultsFormatter.setColSpan(1, k, benchmark.getResults().size());
-            resultsFormatter.setAlignment(1, k, HasHorizontalAlignment.ALIGN_LEFT,
-                HasVerticalAlignment.ALIGN_MIDDLE);
-          }
-
-          resultsTable.setWidget(2, k, trialsTable);
-
-          // Write out the variable column headers
-          for (int varIndex = 0; varIndex < numVariables; ++varIndex) {
-            String varName = variableNames.get(varIndex);
-            trialsTable.setHTML(0, varIndex, varName);
-          }
-
-          // Timing header
-          trialsTable.setHTML(0, numVariables, "Timing (ms)");
-
-          // Write out all the trial data
-          int l = 0;
-          for (Trial trial : result.getTrials()) {
-            // Write the variable values
-            for (int varIndex = 0; varIndex < numVariables; ++varIndex) {
-              String varName = variableNames.get(varIndex);
-              String varValue = trial.getVariables().get(varName);
-              trialsTable.setHTML(l + 1, varIndex, varValue);
-            }
-
-            // Write out the timing data
-            String data = trial.getRunTimeMillis() + "";
-            trialsTable.setHTML(l + 1, numVariables, data);
-            ++l;
-          }
-
-          if (result.getException() != null) {
-            trialsTable.setHTML(l + 1, numVariables, result.getException());
-          }
-        }
-      }
-    }
-
-    return topTable;
-  }
-
-  private FlexTable createSummariesTable() {
-    FlexTable tempSummariesTable = new FlexTable();
-    tempSummariesTable.addStyleName("viewer-List");
-    tempSummariesTable.setCellPadding(5);
-    tempSummariesTable.setBorderWidth(1);
-    tempSummariesTable.setCellSpacing(0);
-    tempSummariesTable.setWidget(0, 0, new Label("Report"));
-    tempSummariesTable.setWidget(0, 1, new Label("Date Created"));
-    tempSummariesTable.setWidget(0, 2, new Label("Tests"));
-    tempSummariesTable.getRowFormatter().addStyleName(0, "viewer-ListHeader");
-
-    if (summaries == null) {
-      tempSummariesTable.setWidget(1, 0, new Label("Fetching reports..."));
-      tempSummariesTable.getFlexCellFormatter().setColSpan(1, 0, 4);
-      return tempSummariesTable;
-    }
-
-    for (int i = 0; i < summaries.size(); ++i) {
-      ReportSummary summary = summaries.get(i);
-      int index = i + 1;
-      tempSummariesTable.setWidget(index, 0, new Hyperlink(summary.getId(), summary.getId()));
-      tempSummariesTable.setWidget(index, 1, new Label(summary.getDateString()));
-      tempSummariesTable.setWidget(index, 2, new Label(String.valueOf(summary.getNumTests())));
-    }
-
-    tempSummariesTable.addTableListener(new SummariesTableListener());
-    return tempSummariesTable;
-  }
-
-  private void displayReport() {
-    FlexTable table = createReportTable();
-    reportPanel.remove(reportTable);
-    reportTable = table;
-    reportPanel.insert(reportTable, 1);
-  }
-
-  private void displaySummaries() {
-    FlexTable table = createSummariesTable();
-    summariesPanel.remove(summariesTable);
-    summariesTable = table;
-    summariesPanel.insert(summariesTable, 1);
-  }
-
-  private String encode(String str) {
-    if (str.equals("")) {
-      return str;
-    }
-    return URL.encodeComponent(str);
-  }
-
-  private void fetchReport(int row, String token) {
-    summariesTable.getRowFormatter().addStyleName(row, "viewer-SelectedRow");
-    statusLabel.setText("Retrieving the report...");
-    reportServer.getReport(token, new AsyncCallback<Report>() {
-      public void onFailure(Throwable caught) {
-        statusLabel.setText(caught.toString());
-      }
-
-      public void onSuccess(Report result) {
-        report = result;
-        statusLabel.setText("Finished fetching report details.");
-        displayReport();
-      }
-    });
-  }
-
-  private String getImageUrl(String report, String category, String testClass, String testMethod,
-      String agent) {
-    return imageServer + encode(report) + "/" + encode(category) + "/" + encode(testClass) + "/"
-        + encode(testMethod) + "/" + encode(agent);
-  }
-
-  private void init() {
-    topPanel = new VerticalPanel();
-
-    summariesPanel = new VerticalPanel();
-    summariesPanel.add(new HTML("<h3>Benchmark Reports</h3>"));
-    summariesTable = createSummariesTable();
-    summariesPanel.add(summariesTable);
-
-    reportPanel = new VerticalPanel();
-    detailsLabel = new HTML();
-    reportPanel.add(detailsLabel);
-    reportTable = createReportTable();
-    // reportPanel.add( reportTable );
-
-    topPanel.add(summariesPanel);
-    CellPanel spacerPanel = new HorizontalPanel();
-    spacerPanel.setSpacing(10);
-    spacerPanel.add(new Label());
-    topPanel.add(spacerPanel);
-    topPanel.add(reportPanel);
-    final RootPanel root = RootPanel.get();
-
-    root.add(topPanel);
-
-    statusLabel = new HTML();
-    root.add(statusLabel);
-
-    selectReport(0, "");
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Result.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Result.java
deleted file mode 100644
index d6add52..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Result.java
+++ /dev/null
@@ -1,69 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.List;
-
-/**
- * A data object for Benchmark results.
- */
-public class Result implements IsSerializable {
-
-  private String agent;
-
-  private String exception;
-
-  private String host;
-
-  private List<Trial> trials;
-
-  public Result() {
-  }
-
-  public String getAgent() {
-    return agent;
-  }
-
-  public String getException() {
-    return exception;
-  }
-
-  public String getHost() {
-    return host;
-  }
-
-  public List<Trial> getTrials() {
-    return trials;
-  }
-
-  public void setAgent(String agent) {
-    this.agent = agent;
-  }
-
-  public void setException(String exception) {
-    this.exception = exception;
-  }
-
-  public void setHost(String host) {
-    this.host = host;
-  }
-
-  public void setTrials(List<Trial> trials) {
-    this.trials = trials;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Trial.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Trial.java
deleted file mode 100644
index 604dfc1..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/client/Trial.java
+++ /dev/null
@@ -1,47 +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.benchmarks.viewer.client;
-
-import com.google.gwt.user.client.rpc.IsSerializable;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A data object for Trial.
- */
-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;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/BenchmarkXml.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/BenchmarkXml.java
deleted file mode 100644
index 933788a..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/BenchmarkXml.java
+++ /dev/null
@@ -1,51 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Benchmark;
-import com.google.gwt.benchmarks.viewer.client.Result;
-
-import org.w3c.dom.Element;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Converts an XML element to a Benchmark object.
- * 
- */
-class BenchmarkXml {
-
-  public static Benchmark fromXml(Element element) {
-    Benchmark benchmark = new Benchmark();
-    benchmark.setClassName(element.getAttribute("class"));
-    benchmark.setName(element.getAttribute("name"));
-    benchmark.setDescription(element.getAttribute("description"));
-
-    List<Element> children = ReportXml.getElementChildren(element, "result");
-    benchmark.setResults(new ArrayList<Result>(children.size()));
-    for (int i = 0; i < children.size(); ++i) {
-      benchmark.getResults().add(ResultXml.fromXml(children.get(i)));
-    }
-
-    Element code = ReportXml.getElementChild(element, "source_code");
-    if (code != null) {
-      benchmark.setSourceCode(ReportXml.getText(code));
-    }
-
-    return benchmark;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/CategoryXml.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/CategoryXml.java
deleted file mode 100644
index 1ca5ffa..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/CategoryXml.java
+++ /dev/null
@@ -1,44 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Benchmark;
-import com.google.gwt.benchmarks.viewer.client.Category;
-
-import org.w3c.dom.Element;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Converts an XML Element to a Category object.
- * 
- */
-class CategoryXml {
-  public static Category fromXml(Element element) {
-    Category category = new Category();
-    category.setName(element.getAttribute("name"));
-    category.setDescription(element.getAttribute("description"));
-
-    List<Element> children = ReportXml.getElementChildren(element, "benchmark");
-    category.setBenchmarks(new ArrayList<Benchmark>(children.size()));
-    for (int i = 0; i < children.size(); ++i) {
-      category.getBenchmarks().add(BenchmarkXml.fromXml(children.get(i)));
-    }
-
-    return category;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportDatabase.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportDatabase.java
deleted file mode 100644
index 5911fa9..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportDatabase.java
+++ /dev/null
@@ -1,257 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.benchmarks.viewer.client.Report;
-import com.google.gwt.benchmarks.viewer.client.ReportSummary;
-
-import org.w3c.dom.Document;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-/**
- * Serves up benchmark reports created during JUnit execution.
- * 
- * The benchmark reports are read from the path specified by the system property
- * named <code>Benchmark.REPORT_PATH</code>. In the case the property is not
- * set, they are read from the user's current working directory.
- */
-public class ReportDatabase {
-
-  /**
-   * Indicates that a supplied path was invalid.
-   * 
-   */
-  public static class BadPathException extends RuntimeException {
-    String path;
-
-    public BadPathException(String path) {
-      super("The path " + path + " does not exist.");
-      this.path = path;
-    }
-
-    public String getPath() {
-      return path;
-    }
-  }
-
-  private static class ReportEntry {
-    private long lastModified;
-    private Report report;
-    private ReportSummary summary;
-
-    public ReportEntry(Report report, ReportSummary summary, long lastModified) {
-      this.report = report;
-      this.summary = summary;
-      this.lastModified = lastModified;
-    }
-  }
-
-  private static class ReportFile {
-    File file;
-    long lastModified;
-
-    ReportFile(File f) {
-      this.file = f;
-      this.lastModified = f.lastModified();
-    }
-  }
-
-  private static ReportDatabase database = new ReportDatabase();
-
-  /**
-   * The amount of time to go between report updates.
-   */
-  private static final int UPDATE_DURATION_MILLIS = 30000;
-
-  public static ReportDatabase getInstance() {
-    return database;
-  }
-
-  private static String getReportId(File f) {
-    return f.getName();
-  }
-
-  /**
-   * The last time we updated our reports.
-   */
-  private long lastUpdateMillis = -1L;
-
-  /**
-   * The path to read benchmark reports from.
-   */
-  private final String reportPath;
-
-  /**
-   * A list of all reports by id.
-   */
-  private Map<String, ReportEntry> reports = new HashMap<String, ReportEntry>();
-
-  /**
-   * Lock for reports.
-   */
-  private Object reportsLock = new Object();
-
-  /**
-   * Lock for updating from file system. (Guarantees a single update while not
-   * holding reportsLock open).
-   */
-  private Object updateLock = new Object();
-
-  /**
-   * Are we currently undergoing updating?
-   */
-  private boolean updating = false;
-
-  private ReportDatabase() throws BadPathException {
-    String path = System.getProperty(Benchmark.REPORT_PATH);
-    if (path == null || path.trim().equals("")) {
-      path = System.getProperty("user.dir");
-    }
-    reportPath = path;
-
-    if (!new File(reportPath).exists()) {
-      throw new BadPathException(reportPath);
-    }
-  }
-
-  public Report getReport(String reportId) {
-    synchronized (reportsLock) {
-      ReportEntry entry = reports.get(reportId);
-      return entry == null ? null : entry.report;
-    }
-  }
-
-  public List<ReportSummary> getReportSummaries() {
-
-    /**
-     * There are probably ways to make this faster, but I've taken basic
-     * precautions to try to make this scale ok with multiple clients.
-     */
-
-    boolean update = false;
-
-    // See if we need to do an update
-    // Go ahead and let others continue reading, even if an update is required.
-    synchronized (updateLock) {
-      if (!updating) {
-        long currentTime = System.currentTimeMillis();
-
-        if (currentTime > lastUpdateMillis + UPDATE_DURATION_MILLIS) {
-          update = updating = true;
-        }
-      }
-    }
-
-    if (update) {
-      updateReports();
-    }
-
-    synchronized (reportsLock) {
-      List<ReportSummary> summaries = new ArrayList<ReportSummary>(reports.size());
-      for (ReportEntry entry : reports.values()) {
-        summaries.add(entry.summary);
-      }
-      return summaries;
-    }
-  }
-
-  private void updateReports() {
-
-    File path = new File(reportPath);
-
-    File[] files = path.listFiles(new FilenameFilter() {
-      public boolean accept(File f, String name) {
-        return name.startsWith("report-") && name.endsWith(".xml");
-      }
-    });
-
-    Map<String, ReportEntry> filesToUpdate = new HashMap<String, ReportEntry>();
-    Map<String, ReportFile> filesById = new HashMap<String, ReportFile>();
-    for (int i = 0; i < files.length; ++i) {
-      File f = files[i];
-      filesById.put(getReportId(f), new ReportFile(f));
-    }
-
-    // Lock temporarily so we can determine what needs updating
-    // (This could be a read-lock - not a general read-write lock,
-    // if we moved dead report removal outside of this critical section).
-    synchronized (reportsLock) {
-
-      // Add reports which need to be updated or are new
-      for (int i = 0; i < files.length; ++i) {
-        File file = files[i];
-        String reportId = getReportId(file);
-        ReportEntry entry = reports.get(reportId);
-        if (entry == null || entry.lastModified < file.lastModified()) {
-          filesToUpdate.put(reportId, null);
-        }
-      }
-
-      // Remove reports which no longer exist
-      for (Iterator<String> it = reports.keySet().iterator(); it.hasNext();) {
-        if (filesById.get(it.next()) == null) {
-          it.remove();
-        }
-      }
-    }
-
-    try {
-      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-      factory.setIgnoringElementContentWhitespace(true);
-      factory.setIgnoringComments(true);
-      DocumentBuilder builder = factory.newDocumentBuilder();
-
-      for (String id : filesToUpdate.keySet()) {
-        ReportFile reportFile = filesById.get(id);
-        String filePath = reportFile.file.getAbsolutePath();
-        Document doc = builder.parse(filePath);
-        Report report = ReportXml.fromXml(doc.getDocumentElement());
-        report.setId(id);
-        ReportSummary summary = report.getSummary();
-        long lastModified = new File(filePath).lastModified();
-        filesToUpdate.put(id, new ReportEntry(report, summary, lastModified));
-      }
-
-      // Update the reports
-      synchronized (reportsLock) {
-        for (String id : filesToUpdate.keySet()) {
-          reports.put(id, filesToUpdate.get(id));
-        }
-      }
-    } catch (Exception e) {
-      // Even if we got an error, we'll just try again on the next update
-      // This might happen if a report has only been partially written, for
-      // example.
-      e.printStackTrace();
-    }
-
-    synchronized (updateLock) {
-      updating = false;
-      lastUpdateMillis = System.currentTimeMillis();
-    }
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportImageServer.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportImageServer.java
deleted file mode 100644
index 673d20c..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportImageServer.java
+++ /dev/null
@@ -1,452 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Benchmark;
-import com.google.gwt.benchmarks.viewer.client.BrowserInfo;
-import com.google.gwt.benchmarks.viewer.client.Category;
-import com.google.gwt.benchmarks.viewer.client.Report;
-import com.google.gwt.benchmarks.viewer.client.Result;
-import com.google.gwt.benchmarks.viewer.client.Trial;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.ValueAxis;
-import org.jfree.chart.encoders.EncoderUtil;
-import org.jfree.chart.encoders.ImageFormat;
-import org.jfree.chart.plot.CategoryPlot;
-import org.jfree.chart.plot.DefaultDrawingSupplier;
-import org.jfree.chart.plot.DrawingSupplier;
-import org.jfree.chart.plot.Plot;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
-import org.jfree.data.category.DefaultCategoryDataset;
-import org.jfree.data.xy.XYSeries;
-import org.jfree.data.xy.XYSeriesCollection;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.GradientPaint;
-import java.awt.Polygon;
-import java.awt.Shape;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Serves up report images for the ReportViewer application. Generates the
- * charts/graphs which contain the benchmarking data for a report.
- * 
- * <p>
- * This servlet requires the name of the report file, the category, the
- * benchmark class, the test method, and the browser agent.
- * <p>
- * 
- * <p>
- * An Example URI:
- * 
- * <pre>
- * /com.google.gwt.junit.viewer.ReportViewer/test_images/
- *   report-12345.xml/
- *   RemoveCategory/
- *   com.google.gwt.junit.client.ArrayListAndVectorBenchmark/
- *   testArrayListRemoves/
- *   Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20050920/
- * </pre>
- * 
- * </p>
- */
-public class ReportImageServer extends HttpServlet {
-
-  private static final String charset = "UTF-8";
-
-  @Override
-  public void doGet(HttpServletRequest request, HttpServletResponse response) {
-    try {
-      handleRequest(request, response);
-    } catch (Exception e) {
-      if (e.getClass().getName().endsWith(".ClientAbortException")
-          || e.getClass().getName().endsWith(".EofException")) {
-        // No big deal, the client browser terminated a download.
-      } else {
-        logException("An error occured while trying to create the chart.", e, response);
-      }
-      return;
-    }
-  }
-
-  private JFreeChart createChart(String testName, Result result, String title,
-      List<Result> comparativeResults) {
-
-    // Find the maximum values across both axes for all of the results
-    // (this chart's own results, plus all comparative results).
-    //
-    // This is a stop-gap solution that helps us compare different charts for
-    // the same benchmark method (usually with different user agents) until we
-    // get real comparative functionality in version two.
-
-    double maxTime = 0;
-
-    for (Result r : comparativeResults) {
-      for (Trial t : r.getTrials()) {
-        maxTime = Math.max(maxTime, t.getRunTimeMillis());
-      }
-    }
-
-    // Determine the number of variables in this benchmark method
-    List<Trial> trials = result.getTrials();
-    Trial firstTrial = new Trial();
-    int numVariables = 0;
-    if (trials.size() > 0) {
-      firstTrial = trials.get(0);
-      numVariables = firstTrial.getVariables().size();
-    }
-
-    // Display the trial data.
-    //
-    // First, pick the domain and series variables for our graph.
-    // Right now we only handle up to two "user" variables.
-    // We set the domain variable to the be the one containing the most unique
-    // values.
-    // This might be easier if the results had meta information telling us
-    // how many total variables there are, what types they are of, etc....
-
-    String domainVariable = null;
-    String seriesVariable = null;
-
-    Map<String, Set<String>> variableValues = null;
-
-    if (numVariables == 1) {
-      domainVariable = firstTrial.getVariables().keySet().iterator().next();
-    } else {
-      // TODO(tobyr): Do something smarter, like allow the user to specify which
-      // variables are domain and series, along with the variables which are
-      // held constant.
-
-      variableValues = new HashMap<String, Set<String>>();
-
-      for (int i = 0; i < trials.size(); ++i) {
-        Trial trial = trials.get(i);
-        Map<String, String> variables = trial.getVariables();
-
-        for (Map.Entry<String, String> entry : variables.entrySet()) {
-          String variable = entry.getKey();
-          Set<String> set = variableValues.get(variable);
-          if (set == null) {
-            set = new TreeSet<String>();
-            variableValues.put(variable, set);
-          }
-          set.add(entry.getValue());
-        }
-      }
-
-      TreeMap<Integer, List<String>> numValuesMap = new TreeMap<Integer, List<String>>();
-
-      for (Map.Entry<String, Set<String>> entry : variableValues.entrySet()) {
-        Integer numValues = new Integer(entry.getValue().size());
-        List<String> variables = numValuesMap.get(numValues);
-        if (variables == null) {
-          variables = new ArrayList<String>();
-          numValuesMap.put(numValues, variables);
-        }
-        variables.add(entry.getKey());
-      }
-
-      if (numValuesMap.values().size() > 0) {
-        domainVariable = numValuesMap.get(numValuesMap.lastKey()).get(0);
-        seriesVariable = numValuesMap.get(numValuesMap.firstKey()).get(0);
-      }
-    }
-
-    String valueTitle = "time (ms)"; // This axis is time across all charts.
-
-    if (numVariables == 0) {
-      // Show a bar graph, with a single centered simple bar
-      // 0 variables means there is only 1 trial
-      DefaultCategoryDataset data = new DefaultCategoryDataset();
-      data.addValue(firstTrial.getRunTimeMillis(), "result", "result");
-
-      JFreeChart chart =
-          ChartFactory.createBarChart(title, testName, valueTitle, data, PlotOrientation.VERTICAL,
-              false, false, false);
-      CategoryPlot p = chart.getCategoryPlot();
-      ValueAxis axis = p.getRangeAxis();
-      axis.setUpperBound(maxTime + maxTime * 0.1);
-      return chart;
-    } else if (numVariables == 1) {
-
-      // Show a line graph with only 1 series
-      // Or.... choose between a line graph and a bar graph depending upon
-      // whether the type of the domain is numeric.
-
-      XYSeriesCollection data = new XYSeriesCollection();
-
-      XYSeries series = new XYSeries(domainVariable);
-
-      for (Trial trial : trials) {
-        double time = trial.getRunTimeMillis();
-        String domainValue = trial.getVariables().get(domainVariable);
-        series.add(Double.parseDouble(domainValue), time);
-      }
-
-      data.addSeries(series);
-
-      JFreeChart chart =
-          ChartFactory.createXYLineChart(title, domainVariable, valueTitle, data,
-              PlotOrientation.VERTICAL, false, false, false);
-      XYPlot plot = chart.getXYPlot();
-      plot.getRangeAxis().setUpperBound(maxTime + maxTime * 0.1);
-      double maxDomainValue = getMaxValue(comparativeResults, domainVariable);
-      plot.getDomainAxis().setUpperBound(maxDomainValue + maxDomainValue * 0.1);
-      return chart;
-    } else if (numVariables == 2) {
-      // Show a line graph with two series
-      XYSeriesCollection data = new XYSeriesCollection();
-
-      Set<String> seriesValues = variableValues.get(seriesVariable);
-
-      for (String seriesValue : seriesValues) {
-        XYSeries series = new XYSeries(seriesValue);
-
-        for (Trial trial : trials) {
-          Map<String, String> variables = trial.getVariables();
-          if (variables.get(seriesVariable).equals(seriesValue)) {
-            double time = trial.getRunTimeMillis();
-            String domainValue = trial.getVariables().get(domainVariable);
-            series.add(Double.parseDouble(domainValue), time);
-          }
-        }
-        data.addSeries(series);
-      }
-      // TODO(tobyr) - Handle graphs above 2 variables
-
-      JFreeChart chart =
-          ChartFactory.createXYLineChart(title, domainVariable, valueTitle, data,
-              PlotOrientation.VERTICAL, true, true, false);
-      XYPlot plot = chart.getXYPlot();
-      plot.getRangeAxis().setUpperBound(maxTime + maxTime * 0.1);
-      double maxDomainValue = getMaxValue(comparativeResults, domainVariable);
-      plot.getDomainAxis().setUpperBound(maxDomainValue + maxDomainValue * 0.1);
-      return chart;
-    }
-
-    throw new RuntimeException("The ReportImageServer is not yet able to "
-        + "create charts for benchmarks with more than two variables.");
-
-    // Sample JFreeChart code for creating certain charts:
-    // Leaving this around until we can handle multivariate charts in dimensions
-    // greater than two.
-
-    // Code for creating a category data set - probably better with a bar chart
-    // instead of line chart
-    /*
-     * DefaultCategoryDataset data = new DefaultCategoryDataset(); String series
-     * = domainVariable;
-     * 
-     * for ( Iterator it = trials.iterator(); it.hasNext(); ) { Trial trial =
-     * (Trial) it.next(); double time = trial.getRunTimeMillis(); String
-     * domainValue = (String) trial.getVariables().get( domainVariable );
-     * data.addValue( time, series, domainValue ); }
-     * 
-     * String title = ""; String categoryTitle = domainVariable; PlotOrientation
-     * orientation = PlotOrientation.VERTICAL;
-     * 
-     * chart = ChartFactory.createLineChart( title, categoryTitle, valueTitle,
-     * data, orientation, true, true, false );
-     */
-
-    /*
-     * DefaultCategoryDataset data = new DefaultCategoryDataset(); String
-     * series1 = "firefox"; String series2 = "ie";
-     * 
-     * data.addValue( 1.0, series1, "1024"); data.addValue( 2.0, series1,
-     * "2048"); data.addValue( 4.0, series1, "4096"); data.addValue( 8.0,
-     * series1, "8192");
-     * 
-     * data.addValue( 2.0, series2, "1024"); data.addValue( 4.0, series2,
-     * "2048"); data.addValue( 8.0, series2, "4096"); data.addValue( 16.0,
-     * series2,"8192");
-     * 
-     * String title = ""; String categoryTitle = "size"; PlotOrientation
-     * orientation = PlotOrientation.VERTICAL;
-     * 
-     * chart = ChartFactory.createLineChart( title, categoryTitle, valueTitle,
-     * data, orientation, true, true, false );
-     */
-  }
-
-  private Benchmark getBenchmarkByName(List<Benchmark> benchmarks, String name) {
-    for (Benchmark benchmark : benchmarks) {
-      if (benchmark.getName().equals(name)) {
-        return benchmark;
-      }
-    }
-    return null;
-  }
-
-  private Category getCategoryByName(List<Category> categories, String categoryName) {
-    for (Category category : categories) {
-      if (category.getName().equals(categoryName)) {
-        return category;
-      }
-    }
-    return null;
-  }
-
-  private DrawingSupplier getDrawingSupplier() {
-    Color[] colors = new Color[] {new Color(176, 29, 29, 175), // dark red
-        new Color(10, 130, 86, 175), // dark green
-        new Color(8, 26, 203, 175), // dark blue
-        new Color(145, 162, 66, 175), // light pea green
-        new Color(196, 140, 6, 175), // sienna
-    };
-
-    float size = 8;
-    float offset = size / 2;
-
-    int iOffset = (int) offset;
-
-    Shape square = new Rectangle2D.Double(-offset, -offset, size, size);
-    Shape circle = new Ellipse2D.Double(-offset, -offset, size, size);
-    Shape triangle =
-        new Polygon(new int[] {0, iOffset, -iOffset}, new int[] {-iOffset, iOffset, iOffset}, 3);
-    Shape diamond =
-        new Polygon(new int[] {0, iOffset, 0, -iOffset}, new int[] {-iOffset, 0, iOffset, 0}, 4);
-    Shape ellipse = new Ellipse2D.Double(-offset, -offset / 2, size, size / 2);
-
-    return new DefaultDrawingSupplier(colors,
-        DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE,
-        DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE,
-        DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, new Shape[] {
-            circle, square, triangle, diamond, ellipse});
-  }
-
-  private double getMaxValue(List<Result> results, String variable) {
-    double value = 0.0;
-
-    for (int i = 0; i < results.size(); ++i) {
-      Result r = results.get(i);
-      List<Trial> resultTrials = r.getTrials();
-
-      for (int j = 0; j < resultTrials.size(); ++j) {
-        Trial t = resultTrials.get(j);
-        Map<String, String> variables = t.getVariables();
-        value = Math.max(value, Double.parseDouble(variables.get(variable)));
-      }
-    }
-
-    return value;
-  }
-
-  private Result getResultsByAgent(List<Result> results, String agent) {
-    for (Object element : results) {
-      Result result = (Result) element;
-      if (result.getAgent().equals(agent)) {
-        return result;
-      }
-    }
-    return null;
-  }
-
-  private void handleRequest(HttpServletRequest request, HttpServletResponse response)
-      throws IOException {
-
-    String uri = request.getRequestURI();
-    String requestString = uri.split("test_images/")[1];
-    String[] requestParams = requestString.split("/");
-
-    String reportName = URLDecoder.decode(requestParams[0], charset);
-    String categoryName = URLDecoder.decode(requestParams[1], charset);
-    // String className = URLDecoder.decode(requestParams[2], charset);
-    String testName = URLDecoder.decode(requestParams[3], charset);
-    String agent = URLDecoder.decode(requestParams[4], charset);
-
-    ReportDatabase db = ReportDatabase.getInstance();
-    Report report = db.getReport(reportName);
-    List<Category> categories = report.getCategories();
-    Category category = getCategoryByName(categories, categoryName);
-    List<Benchmark> benchmarks = category.getBenchmarks();
-    Benchmark benchmark = getBenchmarkByName(benchmarks, testName);
-    List<Result> results = benchmark.getResults();
-    Result result = getResultsByAgent(results, agent);
-
-    String title = BrowserInfo.getBrowser(agent);
-    JFreeChart chart = createChart(testName, result, title, results);
-
-    chart.getTitle().setFont(Font.decode("Verdana BOLD 12"));
-    chart.setAntiAlias(true);
-    chart.setBorderVisible(true);
-    chart.setBackgroundPaint(new Color(241, 241, 241));
-
-    Plot plot = chart.getPlot();
-
-    plot.setDrawingSupplier(getDrawingSupplier());
-    plot.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 640, 480, new Color(200, 200, 200)));
-
-    if (plot instanceof XYPlot) {
-      XYPlot xyplot = (XYPlot) plot;
-      Font labelFont = Font.decode("Verdana PLAIN");
-      xyplot.getDomainAxis().setLabelFont(labelFont);
-      xyplot.getRangeAxis().setLabelFont(labelFont);
-      org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = xyplot.getRenderer();
-      xyitemrenderer.setStroke(new BasicStroke(4));
-      if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
-        XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
-        xylineandshaperenderer.setShapesVisible(true);
-        xylineandshaperenderer.setShapesFilled(true);
-      }
-    }
-
-    // Try to fit all the graphs into a 1024 window, with a min of 240 and a max
-    // of 480
-    final int graphWidth =
-        Math.max(240, Math.min(480, (1024 - 10 * results.size()) / results.size()));
-    BufferedImage img = chart.createBufferedImage(graphWidth, 240);
-    byte[] image = EncoderUtil.encode(img, ImageFormat.PNG);
-
-    // The images have unique URLs; might as well set them to never expire.
-    response.setHeader("Cache-Control", "max-age=0");
-    response.setHeader("Expires", "Fri, 2 Jan 1970 00:00:00 GMT");
-    response.setContentType("image/png");
-    response.setContentLength(image.length);
-
-    OutputStream output = response.getOutputStream();
-    output.write(image);
-  }
-
-  private void logException(String msg, Exception e, HttpServletResponse response) {
-    ServletContext servletContext = getServletContext();
-    servletContext.log(msg, e);
-    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportServerImpl.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportServerImpl.java
deleted file mode 100644
index f9657d1..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportServerImpl.java
+++ /dev/null
@@ -1,37 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Report;
-import com.google.gwt.benchmarks.viewer.client.ReportServer;
-import com.google.gwt.benchmarks.viewer.client.ReportSummary;
-import com.google.gwt.user.server.rpc.RemoteServiceServlet;
-
-import java.util.List;
-
-/**
- * Implements the ReportServer RPC interface.
- */
-public class ReportServerImpl extends RemoteServiceServlet implements ReportServer {
-
-  public Report getReport(String reportId) {
-    return ReportDatabase.getInstance().getReport(reportId);
-  }
-
-  public List<ReportSummary> getReportSummaries() {
-    return ReportDatabase.getInstance().getReportSummaries();
-  }
-}
\ No newline at end of file
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportXml.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportXml.java
deleted file mode 100644
index b908fdd..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ReportXml.java
+++ /dev/null
@@ -1,97 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Category;
-import com.google.gwt.benchmarks.viewer.client.Report;
-
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Hydrates a Report from its XML representation.
- */
-class ReportXml {
-
-  /**
-   * Hydrates a Report from its XML representation.
-   * 
-   * @param element The XML element to hydrate from.
-   * @return a new report (with null id)
-   */
-  public static Report fromXml(Element element) {
-
-    Report report = new Report();
-    String dateString = element.getAttribute("date");
-
-    try {
-      DateFormat format = DateFormat.getDateTimeInstance();
-      Date d = format.parse(dateString);
-      report.setDate(d);
-      report.setDateString(format.format(d));
-    } catch (ParseException e) {
-      // let date remain null if it doesn't parse correctly
-    }
-
-    report.setGwtVersion(element.getAttribute("gwt_version"));
-
-    List<Element> children = getElementChildren(element, "category");
-    Map<String, Category> categories = new HashMap<String, Category>();
-    for (Element child : children) {
-      Category newCategory = CategoryXml.fromXml(child);
-      Category oldCategory = categories.get(newCategory.getName());
-      if (oldCategory != null) {
-        // if a category with the same name exists, combine the benchmarks
-        oldCategory.getBenchmarks().addAll(newCategory.getBenchmarks());
-      } else {
-        categories.put(newCategory.getName(), newCategory);
-      }
-    }
-    report.setCategories(new ArrayList<Category>(categories.values()));
-
-    return report;
-  }
-
-  static Element getElementChild(Element e, String name) {
-    NodeList children = e.getElementsByTagName(name);
-    return children.getLength() == 0 ? null : (Element) children.item(0);
-  }
-
-  static List<Element> getElementChildren(Element e, String name) {
-    NodeList children = e.getElementsByTagName(name);
-    int numElements = children.getLength();
-    List<Element> elements = new ArrayList<Element>(numElements);
-    for (int i = 0; i < children.getLength(); ++i) {
-      Node n = children.item(i);
-      elements.add((Element) n);
-    }
-    return elements;
-  }
-
-  static String getText(Element e) {
-    Node n = e.getFirstChild();
-    return n == null ? null : n.getNodeValue();
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ResultXml.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ResultXml.java
deleted file mode 100644
index 4365cca..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/ResultXml.java
+++ /dev/null
@@ -1,52 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Result;
-import com.google.gwt.benchmarks.viewer.client.Trial;
-
-import org.w3c.dom.Element;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Hydrates a benchmark Result from an XML Element.
- */
-public class ResultXml {
-  public static Result fromXml(Element element) {
-    Result result = new Result();
-    result.setAgent(element.getAttribute("agent"));
-    result.setHost(element.getAttribute("host"));
-    Element exception = ReportXml.getElementChild(element, "exception");
-    if (exception != null) {
-      result.setException(ReportXml.getText(exception));
-    }
-
-    List<Element> children = ReportXml.getElementChildren(element, "trial");
-
-    ArrayList<Trial> trials = new ArrayList<Trial>(children.size());
-    result.setTrials(trials);
-
-    for (int i = 0; i < children.size(); ++i) {
-      trials.add(TrialXml.fromXml(children.get(i)));
-    }
-
-    // TODO(tobyr) Put some type information in here for the variables
-
-    return result;
-  }
-}
diff --git a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/TrialXml.java b/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/TrialXml.java
deleted file mode 100644
index d9ad3d0..0000000
--- a/tools/benchmark-viewer/src/com/google/gwt/benchmarks/viewer/server/TrialXml.java
+++ /dev/null
@@ -1,51 +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.benchmarks.viewer.server;
-
-import com.google.gwt.benchmarks.viewer.client.Trial;
-
-import org.w3c.dom.Element;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Hydrates a benchmark Trial from an XML Element.
- */
-class TrialXml {
-
-  public static Trial fromXml(Element element) {
-    Trial trial = new Trial();
-
-    String timing = element.getAttribute("timing");
-
-    if (timing != null) {
-      trial.setRunTimeMillis(Double.parseDouble(timing));
-    }
-
-    List<Element> elements = ReportXml.getElementChildren(element, "variable");
-
-    Map<String, String> variables = trial.getVariables();
-
-    for (Element e : elements) {
-      String name = e.getAttribute("name");
-      String value = e.getAttribute("value");
-      variables.put(name, value);
-    }
-
-    return trial;
-  }
-}
diff --git a/tools/benchmark-viewer/war/ReportViewer.css b/tools/benchmark-viewer/war/ReportViewer.css
deleted file mode 100644
index dd58e49..0000000
--- a/tools/benchmark-viewer/war/ReportViewer.css
+++ /dev/null
@@ -1,56 +0,0 @@
-body, html {
-  height: 100%;
-}
-
-body {
-	background: #fff;
-	color: black;
-	font-family: Helvetica, Arial, sans-serif;
-	font-size: small;
-	margin: 8px;
-	margin-top: 3px;
-}
-
-.viewer-List {
-  border-left: 1px solid #666;
-  border-right: 1px solid #666;
-  border-bottom: 1px solid #666;
-  font-size: 80%;
-  cursor: pointer;
-  cursor: hand;
-}
-
-.viewer-List td {
-  border-top: 1px solid #fff;
-  border-bottom: 1px solid #fff;
-  border-left: 1px solid #fff;
-  border-right: 1px solid #fff;
-  padding: 2px 0 2px 10px;
-}
-
-.viewer-ListHeader td {
-  border-top: 1px solid #999;
-  border-bottom: 1px solid #999;
-  border-left: 1px solid #999;
-  border-right: 1px solid #999;
-  padding: 5px 5px 5px 5px;
-}
-
-.viewer-ListHeader {
-  background: #c1eec8 url(gradient.gif) repeat-x 0px 0px;
-  font-weight: bold;
-}
-
-.viewer-SelectedRow td {
-  border-bottom: 1px solid #eee;
-  border-top: 1px solid #eee;
-  border-left: 1px solid #eee;
-  border-right: 1px solid #eee;
-  padding: 2px 0px 2px 10px;
-  background: #eee;
-}
-
-.viewer-SelectedRow {
-  background: #eee;
-}
-
diff --git a/tools/benchmark-viewer/war/ReportViewer.html b/tools/benchmark-viewer/war/ReportViewer.html
deleted file mode 100644
index 8c6f35a..0000000
--- a/tools/benchmark-viewer/war/ReportViewer.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-	<head>
-    <link type="text/css" rel="stylesheet" href="ReportViewer.css">
-		<title>ReportViewer</title>
-	</head>
-	<body>
-		<script language="javascript" src="reportViewer/reportViewer.nocache.js"></script>
-		<iframe src="javascript:''" id='__gwt_historyFrame' style='width:0;height:0;border:0'></iframe>
-	</body>
-</html>
diff --git a/tools/benchmark-viewer/war/WEB-INF/classes/marker b/tools/benchmark-viewer/war/WEB-INF/classes/marker
deleted file mode 100644
index e69de29..0000000
--- a/tools/benchmark-viewer/war/WEB-INF/classes/marker
+++ /dev/null
diff --git a/tools/benchmark-viewer/war/WEB-INF/web.xml b/tools/benchmark-viewer/war/WEB-INF/web.xml
deleted file mode 100644
index 301ee6c..0000000
--- a/tools/benchmark-viewer/war/WEB-INF/web.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<web-app>
-
-  <!-- Default page to serve -->
-  <welcome-file-list>
-    <welcome-file>ReportViewer.html</welcome-file>
-  </welcome-file-list>
-  
-  <!-- Servlets -->
-  <servlet>
-    <servlet-name>test_reports</servlet-name>
-    <servlet-class>com.google.gwt.benchmarks.viewer.server.ReportServerImpl</servlet-class>
-  </servlet>
-  
-  <servlet-mapping>
-    <servlet-name>test_reports</servlet-name>
-    <url-pattern>/reportViewer/test_reports</url-pattern>
-  </servlet-mapping>
-
-  <servlet>
-    <servlet-name>test_images</servlet-name>
-    <servlet-class>com.google.gwt.benchmarks.viewer.server.ReportImageServer</servlet-class>
-  </servlet>
-  
-  <servlet-mapping>
-    <servlet-name>test_images</servlet-name>
-    <url-pattern>/reportViewer/test_images/*</url-pattern>
-  </servlet-mapping>
-
-</web-app>
diff --git a/tools/benchmark-viewer/war/gradient.gif b/tools/benchmark-viewer/war/gradient.gif
deleted file mode 100644
index 3e0ae44..0000000
--- a/tools/benchmark-viewer/war/gradient.gif
+++ /dev/null
Binary files differ
diff --git a/tools/build.xml b/tools/build.xml
index cc6c10a..5f3f123 100755
--- a/tools/build.xml
+++ b/tools/build.xml
@@ -6,11 +6,6 @@
         <!-- "build" is the default when subprojects are directly targeted -->
         <property name="target" value="build" />
 
-        <target name="benchmark-viewer" depends=""
-          description="Run benchmark-viewer">
-                <gwt.ant dir="benchmark-viewer" />
-        </target>
-
         <target name="api-checker" depends=""
           description="Compile api-checker">
                 <gwt.ant dir="api-checker" />
@@ -24,7 +19,7 @@
                 <gwt.ant dir="cldr-import" />
         </target>
 
-  <target name="-do" depends="benchmark-viewer,api-checker,soyc-vis,cldr-import"
+  <target name="-do" depends="api-checker,soyc-vis,cldr-import"
     description="Run all subfolders that don't have additional dependencies" />
 
   <target name="build" description="Build each subfolder">
diff --git a/user/build.xml b/user/build.xml
index d49f25f..bfea83a 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -28,10 +28,6 @@
   <property name="gwt.junit.testcase.dev.includes" value="${gwt.junit.testcase.includes}" />
   <property name="gwt.junit.testcase.dev.excludes" value="" />
 
-  <property name="benchmark.timeout" value="30" />
-  <property name="gwt.benchmark.testcase.web.includes" value="${gwt.benchmark.testcase.includes}" />
-  <property name="gwt.benchmark.testcase.web.excludes" value="${gwt.benchmark.testcase.excludes}" />
-  
   <property name="gwt.tck.testcase.dev.includes" value="com/google/gwt/validation/tck/**/*GwtSuite.class" />
   <property name="gwt.tct.testcase.dev.excludes" value="" />
 
@@ -886,80 +882,6 @@
       </gwt.junit>
     </target>
   
-  <target name="benchmark"
-      description="Run all benchmarks for this project.">
-
-    <property.ensure name="distro.built" location="${gwt.dev.staging.jar}"
-        message="GWT must be built before performing any tests.  This can be fixed by running ant in the ${gwt.root} directory." />
-    <limit failonerror="true" hours="${benchmark.timeout}">
-      <!-- no-op unless gwt.hosts.web.remote is defined -->
-      <antcall target="benchmark.web.remote"/>
-      <!-- no-op unless gwt.hosts.web.selenium is defined -->
-      <antcall target="benchmark.web.selenium"/>
-      <antcall target="benchmark.web.htmlunit"/>
-    </limit>
-  </target>
-
-  <target name="benchmark.web.htmlunit"
-      depends="compile, compile.tests"
-      description="Run web-mode benchmarks with HtmlUnit."
-      unless="benchmark.web.htmlunit.disable">
-    <fileset id="benchmark.web.htmlunit.tests" dir="${javac.junit.out}"
-        includes="${gwt.benchmark.testcase.web.includes}"
-        excludes="${gwt.benchmark.testcase.web.excludes}" />
-    <gwt.junit test.name="benchmark.web.htmlunit"
-        test.args="${test.args} -testMethodTimeout ${benchmark.timeout} -out www -prod -standardsMode"
-        test.jvmargs="${test.jvmargs}"
-        test.out="${junit.out}/web-htmlunit-benchmark"
-        test.cases="benchmark.web.htmlunit.tests" >
-      <extraclasspaths>
-        <path refid="test.extraclasspath" />
-      </extraclasspaths>
-    </gwt.junit>
-  </target>
-
-  <target name="benchmark.web.selenium"
-      depends="compile, compile.tests"
-      description="Run web benchmark using Selenium RC"
-      if="gwt.hosts.web.selenium"
-      unless="benchmark.web.selenium.disable">
-    <echo message="Performing web benchmarking using Selenium RC at ${gwt.hosts.web.selenium}" />
-    <property name="test.web.selenium.args" value="${test.args.web.selenium}" />
-    <fileset id="benchmark.web.selenium.tests" dir="${javac.junit.out}"
-        includes="${gwt.benchmark.testcase.web.includes}"
-        excludes="${gwt.benchmark.testcase.web.excludes}" />
-    <gwt.junit test.name="benchmark.web.selenium"
-        test.args='${test.web.selenium.args} -testMethodTimeout ${benchmark.timeout}'
-        test.jvmargs="${test.jvmargs}"
-        test.out="${junit.out}/web-selenium-benchmark"
-        test.cases="benchmark.web.selenium.tests" >
-      <extraclasspaths>
-        <path refid="test.extraclasspath" />
-      </extraclasspaths>
-    </gwt.junit>
-  </target>
-
-  <target name="benchmark.web.remote"
-      depends="compile, compile.tests"
-      description="Run web benchmarks with remote browsers"
-      if="gwt.hosts.web.remote"
-      unless="benchmark.web.remote.disable">
-    <echo message="Performing web remote benchmarking at ${gwt.hosts.web.remote}" />
-    <property name="test.web.remote.args" value="${test.args.web.remote}" />
-    <fileset id="benchmark.web.remote.tests" dir="${javac.junit.out}"
-        includes="${gwt.benchmark.testcase.web.includes}"
-        excludes="${gwt.benchmark.testcase.web.excludes}" />
-    <gwt.junit test.name="benchmark.web.remote"
-        test.args="${test.web.remote.args} -testMethodTimeout ${benchmark.timeout}"
-        test.jvmargs="${test.jvmargs}"
-        test.out="${junit.out}/web-remote-benchmark"
-        test.cases="benchmark.web.remote.tests" >
-      <extraclasspaths>
-        <path refid="test.extraclasspath" />
-      </extraclasspaths>
-    </gwt.junit>
-  </target>
-
   <!--
       Merges coverage data for the entire project
   -->
diff --git a/user/javadoc/com/google/gwt/examples/Benchmarks.gwt.xml b/user/javadoc/com/google/gwt/examples/Benchmarks.gwt.xml
deleted file mode 100644
index b61f09d..0000000
--- a/user/javadoc/com/google/gwt/examples/Benchmarks.gwt.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-<module>
-  <source path='benchmarks'/>
-</module>
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java
deleted file mode 100644
index 1ab1a89..0000000
--- a/user/javadoc/com/google/gwt/examples/benchmarks/AllocBenchmark.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.examples.benchmarks;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-
-/**
- * Provides profile statistics on allocation times for different kinds of
- * objects.
- *
- */
-public class AllocBenchmark extends Benchmark {
-
-  private static final int numAllocs = 1000;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.examples.Benchmarks";
-  }
-
-  /**
-   * Allocates java.lang.Object in a for loop 1,000 times.
-   *
-   * The current version of the compiler lifts the declaration of obj outside
-   * of this loop and also does constant folding of numAllocs.
-   * Also, this loop allocs the GWT JS mirror for java.lang.Object
-   * <em>NOT</em> an empty JS object, for example.
-   *
-   */
-  public void testJavaObjectAlloc() {
-    for ( int i = 0; i < numAllocs; ++i ) {
-      Object obj = new Object();
-    }
-  }
-
-  /**
-   * Compares GWT mirror allocations of java.lang.Object to an empty JS object.
-   */
-  public native void testJsniObjectAlloc1() /*-{
-    for (var i = 0; i < @com.google.gwt.examples.benchmarks.AllocBenchmark::numAllocs; ++i ) {
-      var obj = {}; // An empty JS object alloc
-    }
-  }-*/;
-
-  /**
-   * Like version 1, but also folds the constant being used in the iteration.
-   */
-  public native void testJsniObjectAlloc2() /*-{
-    for (var i = 0; i < 1000; ++i ) {
-      var obj = {}; // An empty JS object alloc
-    }
-  }-*/;
-
-  /**
-   * Like version 2, but hoists the variable declaration from the loop.
-   */
-  public native void testJsniObjectAlloc3() /*-{
-    var obj;
-    for (var i = 0; i < 1000; ++i ) {
-      obj = {}; // An empty JS object alloc
-    }
-  }-*/;
-
-  /**
-   * Like version 3, but counts down (and in a slightly different range).
-   */
-  public native void testJsniObjectAlloc4() /*-{
-    var obj;
-    for (var i = 1000; i > 0; --i ) {
-      obj = {}; // An empty JS object alloc
-    }
-  }-*/;
-}
-
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java
deleted file mode 100644
index a0a58ba..0000000
--- a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListAndVectorBenchmark.java
+++ /dev/null
@@ -1,300 +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.examples.benchmarks;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.benchmarks.client.IntRange;
-import com.google.gwt.benchmarks.client.Operator;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-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.
- * 
- */
-public class ArrayListAndVectorBenchmark extends Benchmark {
-
-  /**
-   * Many profiled widgets have position dependent insert/remove code.
-   * <code>Position</code> is a helper class meant to capture the positional
-   * information for these sorts of operations.
-   */
-  protected static class Position {
-
-    public static final Position BEGIN = new Position("at the beginning");
-    public static final Position END = new Position("at the end");
-    public static final Position NONE = new Position("no location specified");
-    public static final Position VARIED = new Position("in varied locations");
-
-    public static final Iterable positions = new Iterable() {
-      public Iterator iterator() {
-        return Arrays.asList(new Position[] {BEGIN, END, NONE, VARIED}).iterator();
-      }
-    };
-
-    public static final Iterable positions2 = new Iterable() {
-      public Iterator iterator() {
-        return Arrays.asList(new Position[] {BEGIN, END, VARIED}).iterator();
-      }
-    };
-
-    private String label;
-
-    /**
-     * Constructor for <code>Position</code>.
-     */
-    public Position(String label) {
-      this.label = label;
-    }
-
-    @Override
-    public String toString() {
-      return " " + label;
-    }
-  }
-
-  private static final int PRIME = 3001;
-
-  final IntRange insertRemoveRange = new IntRange(64, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  final IntRange baseRange = new IntRange(512, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  ArrayList list;
-  Vector vector;
-  int index = 0;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.examples.Benchmarks";
-  }
-
-  /**
-   * Appends <code>size</code> items to an empty ArrayList.
-   * 
-   * @gwt.benchmark.param size -limit = baseRange
-   */
-  public void testArrayListAdds(Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.add("hello");
-    }
-  }
-
-  // Required for JUnit
-  public void testArrayListAdds() {
-  }
-
-  /**
-   * Performs <code>size</code> gets on an ArrayList of size,
-   * <code>size</code>.
-   * 
-   * @gwt.benchmark.param size -limit = baseRange
-   */
-  public void testArrayListGets(Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.get(i);
-    }
-  }
-
-  // Required for JUnit
-  public void testArrayListGets() {
-  }
-
-  /**
-   * 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) {
-    insertIntoCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testArrayListInserts() {
-  }
-
-  /**
-   * 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
-   */
-  public void testArrayListRemoves(Position where, Integer size) {
-    removeFromCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testArrayListRemoves() {
-  }
-
-  /**
-   * Appends <code>size</code> items to an empty Vector.
-   * 
-   * @gwt.benchmark.param size -limit = baseRange
-   */
-  public void testVectorAdds(Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      vector.add("hello");
-    }
-  }
-
-  // Required for JUnit
-  public void testVectorAdds() {
-  }
-
-  /**
-   * Performs <code>size</code> gets on a Vector of size, <code>size</code>.
-   * 
-   * @gwt.benchmark.param size -limit = baseRange
-   */
-  public void testVectorGets(Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      vector.get(i);
-    }
-  }
-
-  // Required for JUnit
-  public void testVectorGets() {
-  }
-
-  /**
-   * 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);
-  }
-
-  // Required for JUnit
-  public void testVectorInserts() {
-  }
-
-  /**
-   * 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);
-  }
-
-  // Required for JUnit
-  public void testVectorRemoves() {
-  }
-
-  void beginArrayListAdds(Integer size) {
-    list = new ArrayList();
-  }
-
-  void beginArrayListGets(Integer size) {
-    createArrayList(size);
-  }
-
-  void beginArrayListInserts(Position where, Integer size) {
-    list = new ArrayList();
-    index = 0;
-  }
-
-  void beginArrayListRemoves(Position where, Integer size) {
-    beginArrayListInserts(where, size);
-    testArrayListInserts(where, size);
-  }
-
-  void beginVectorAdds(Integer size) {
-    vector = new Vector();
-  }
-
-  void beginVectorGets(Integer size) {
-    createVector(size);
-  }
-
-  void beginVectorInserts(Position where, Integer size) {
-    vector = new Vector();
-    index = 0;
-  }
-
-  void beginVectorRemoves(Position where, Integer size) {
-    beginVectorInserts(where, size);
-    testVectorInserts(where, size);
-  }
-
-  private void createArrayList(Integer size) {
-    beginArrayListAdds(size);
-    testArrayListAdds(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) {
-        v.add("hello");
-      } else if (where == Position.BEGIN) {
-        v.add(0, "hello");
-      } else if (where == Position.END) {
-        v.add(v.size(), "hello");
-      } else if (where == Position.VARIED) {
-        v.add(index, "hello");
-        index += PRIME;
-        index %= v.size();
-      }
-    }
-  }
-
-  private int removeFromCollection(Integer size, Position where, List v) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.NONE) {
-        throw new RuntimeException("cannot remove with no position");
-      } else if (where == Position.BEGIN) {
-        v.remove(0);
-      } else if (where == Position.END) {
-        v.remove(v.size() - 1);
-      } else if (where == Position.VARIED) {
-        v.remove(index);
-        index += PRIME;
-        int currentSize = v.size();
-        if (currentSize > 0) {
-          index %= v.size();
-        }
-      }
-    }
-    return index;
-  }
-}
diff --git a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java b/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java
deleted file mode 100644
index 4b95434..0000000
--- a/user/javadoc/com/google/gwt/examples/benchmarks/ArrayListBenchmark.java
+++ /dev/null
@@ -1,229 +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.examples.benchmarks;
-
-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
- * appends, inserts, and removes for various sizes and positions.
- */
-public class ArrayListBenchmark extends Benchmark {
-
-  private static final int PRIME = 3001;
-
-  /**
-   * The various positions that data can be inserted into a list.
-   */
-  protected enum Position {
-
-    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>.
-     */
-    Position(String label) {
-      this.label = label;
-    }
-
-    /**
-     * Returns the textual description for the position.
-     * 
-     * @return a not <code>null</code> description.
-     */
-    @Override
-    public String toString() {
-      return label;
-    }
-  }
-
-  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);
-
-  protected final IntRange baseRange = new IntRange(512, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  List<String> list;
-
-  int index = 0;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuite";
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.add("hello");
-    }
-  }
-
-  // Required for JUnit
-  public void testListAdds() {
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.get(i);
-    }
-  }
-
-  // Required for JUnit
-  public void testListGets() {
-  }
-
-  /**
-   * 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) {
-    insertIntoCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testListInserts() {
-  }
-
-  /**
-   * 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) {
-    removeFromCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testListRemoves() {
-  }
-
-  /**
-   * Creates a new empty List.
-   * 
-   * @return a not <code>null</code>, empty List
-   */
-  protected List<String> newList() {
-    return new ArrayList<String>();
-  }
-
-  void beginListAdds(Integer size) {
-    list = newList();
-  }
-
-  void beginListGets(Integer size) {
-    createList(size);
-  }
-
-  void beginListInserts(Position where, Integer size) {
-    list = newList();
-    index = 0;
-  }
-
-  void beginListRemoves(Position where, Integer size) {
-    beginListInserts(where, size);
-    testListInserts(where, size);
-  }
-
-  private void createList(Integer size) {
-    beginListAdds(size);
-    testListAdds(size);
-  }
-
-  private void insertIntoCollection(Integer size, Position where, List<String> l) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        l.add("hello");
-      } else if (where == Position.BEGIN) {
-        l.add(0, "hello");
-      } else if (where == Position.EXPLICIT_END) {
-        l.add(l.size(), "hello");
-      } else if (where == Position.VARIED) {
-        l.add(index, "hello");
-        index += PRIME;
-        index %= l.size();
-      }
-    }
-  }
-
-  private int removeFromCollection(Integer size, Position where, List<String> l) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        throw new RuntimeException("cannot remove from the end implicitly");
-      } else if (where == Position.BEGIN) {
-        l.remove(0);
-      } else if (where == Position.EXPLICIT_END) {
-        l.remove(l.size() - 1);
-      } else if (where == Position.VARIED) {
-        l.remove(index);
-        index += PRIME;
-        int currentSize = l.size();
-        if (currentSize > 0) {
-          index %= l.size();
-        }
-      }
-    }
-    return index;
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/BenchmarkReport.java b/user/src/com/google/gwt/benchmarks/BenchmarkReport.java
deleted file mode 100644
index 7b410c5..0000000
--- a/user/src/com/google/gwt/benchmarks/BenchmarkReport.java
+++ /dev/null
@@ -1,451 +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.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.JClassType;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.dev.util.Util;
-import com.google.gwt.util.tools.Utility;
-
-import junit.framework.TestCase;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.BreakIterator;
-import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-/**
- * Generates a detailed report that contains the results of all of the
- * benchmark-related unit tests executed during a unit test session. The primary
- * user of this class is {@link com.google.gwt.junit.JUnitShell}.
- * 
- * The report is in XML format. To view the XML reports, use benchmarkViewer.
- */
-public class BenchmarkReport {
-
-  /**
-   * Converts a set of test results for a single benchmark method into XML.
-   */
-  private class BenchmarkXml {
-
-    private MetaData metaData;
-
-    private List<BenchmarkResults> results;
-
-    private TestCase test;
-
-    BenchmarkXml(TestCase test, List<BenchmarkResults> results) {
-      this.test = test;
-      this.results = results;
-      Map<String, MetaData> methodMetaData = testMetaData.get(test.getClass().toString());
-      metaData = methodMetaData.get(test.getName());
-    }
-
-    Element toElement(Document doc) {
-      Element benchmark = doc.createElement("benchmark");
-      benchmark.setAttribute("class", test.getClass().getName());
-      benchmark.setAttribute("name", metaData.getTestName());
-      benchmark.setAttribute("description", metaData.getTestDescription());
-
-      String sourceCode = metaData.getSourceCode();
-      if (sourceCode != null) {
-        Element sourceCodeElement = doc.createElement("source_code");
-        sourceCodeElement.appendChild(doc.createTextNode(sourceCode));
-        benchmark.appendChild(sourceCodeElement);
-      }
-
-      // TODO(tobyr): create target_code element
-
-      for (BenchmarkResults result : results) {
-        benchmark.appendChild(toElement(doc, result));
-      }
-
-      return benchmark;
-    }
-
-    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) {
-        Element trialElement = toElement(doc, trial);
-        resultElement.appendChild(trialElement);
-      }
-
-      return resultElement;
-    }
-
-    private Element toElement(Document doc, Trial trial) {
-      Element trialElement = doc.createElement("trial");
-
-      Map<String, String> variables = trial.getVariables();
-
-      for (Map.Entry<String, String> entry : variables.entrySet()) {
-        Object name = entry.getKey();
-        Object value = entry.getValue();
-        Element variableElement = doc.createElement("variable");
-        variableElement.setAttribute("name", name.toString());
-        variableElement.setAttribute("value", value.toString());
-        trialElement.appendChild(variableElement);
-      }
-
-      trialElement.setAttribute("timing",
-          String.valueOf(trial.getRunTimeMillis()));
-
-      return trialElement;
-    }
-  }
-
-  /**
-   * Parses .java source files to get source code for methods.
-   */
-  private static class Parser {
-
-    /**
-     * Maps classes to the contents of their source files.
-     */
-    private Map<JClassType, String> classSources = new HashMap<JClassType, String>();
-
-    /**
-     * Returns the source code for the method of the given name.
-     * 
-     * @param logger to log the process
-     * @param method a not <code>null</code> method
-     * @return <code>null</code> if the source code for the method cannot be
-     *         located
-     */
-    public String getMethod(TreeLogger logger, JMethod method) {
-      JClassType clazz = method.getEnclosingType();
-
-      if (!classSources.containsKey(clazz)) {
-        char[] sourceContents = null;
-        File sourceFile = findSourceFile(clazz);
-        if (sourceFile != null) {
-          sourceContents = Util.readFileAsChars(sourceFile);
-          classSources.put(clazz, new String(sourceContents));
-        }
-
-        if (sourceContents == null) {
-          classSources.put(clazz, null);
-          String msg = "An unknown I/O exception occured while trying to read "
-              + (sourceFile == null ? "class " + clazz + " (not found)" :
-                sourceFile.getAbsolutePath());
-          logger.log(TreeLogger.WARN, msg, null);
-        } else {
-          classSources.put(clazz, new String(sourceContents));
-          String msg = "BenchmarkReport read the contents of "
-              + sourceFile.getAbsolutePath();
-          TreeLogger branch = logger.branch(TreeLogger.DEBUG, msg, null);
-          if (logger.isLoggable(TreeLogger.SPAM)) {
-            branch.log(TreeLogger.SPAM, new String(sourceContents), null);
-          }
-        }
-      }
-
-      String source = classSources.get(clazz);
-
-      if (source == null) {
-        return source;
-      }
-
-      // TODO: search for the method manually?
-      return null;
-    }
-  }
-
-  /**
-   * Converts an entire report into XML.
-   */
-  private class ReportXml {
-
-    private Date date = new Date();
-
-    private String version = "unknown";
-
-    Element toElement(Document doc) {
-      Element report = doc.createElement("gwt_benchmark_report");
-      String dateString = DateFormat.getDateTimeInstance().format(date);
-      report.setAttribute("date", dateString);
-      report.setAttribute("gwt_version", version);
-
-      // Add each test result into the report.
-      // Add the category for the test result, if necessary.
-      for (Map.Entry<TestCase, List<BenchmarkResults>> entry : testResults.entrySet()) {
-        TestCase test = entry.getKey();
-        List<BenchmarkResults> results = entry.getValue();
-        BenchmarkXml xml = new BenchmarkXml(test, results);
-        Element categoryElement = getCategoryElement(doc, report);
-        categoryElement.appendChild(xml.toElement(doc));
-      }
-
-      return report;
-    }
-
-    /**
-     * Locates or creates the category element by the specified name.
-     * 
-     * @param doc The document to search
-     * @param report The report to which the category belongs
-     * @param name The name of the category
-     * 
-     * @return The matching category element
-     */
-    private Element getCategoryElement(Document doc, Element report) {
-      Element categoryElement = doc.createElement("category");
-      categoryElement.setAttribute("name", "");
-      categoryElement.setAttribute("description", "");
-      report.appendChild(categoryElement);
-      return categoryElement;
-    }
-  }
-
-  private static File findSourceFile(JClassType clazz) {
-    final char separator = File.separator.charAt(0);
-    String filePath = clazz.getPackage().getName().replace('.', separator)
-        + separator + clazz.getSimpleSourceName() + ".java";
-    String[] paths = getClassPath();
-
-    for (int i = 0; i < paths.length; ++i) {
-      File maybeSourceFile = new File(paths[i] + separator + filePath);
-
-      if (maybeSourceFile.exists()) {
-        return maybeSourceFile;
-      }
-    }
-
-    return null;
-  }
-
-  private static String[] getClassPath() {
-    String path = System.getProperty("java.class.path");
-    return path.split(File.pathSeparator);
-  }
-
-  private Parser parser = new Parser();
-
-  private Map<String, Map<String, MetaData>> testMetaData = new HashMap<String, Map<String, MetaData>>();
-
-  private Map<TestCase, List<BenchmarkResults>> testResults = new HashMap<TestCase, List<BenchmarkResults>>();
-
-  public BenchmarkReport() {
-  }
-
-  /**
-   * Adds the Benchmark to the report. All of the metadata about the benchmark
-   * (category, name, description, etc...) is recorded from the TypeOracle.
-   * 
-   * @param logger to log the process
-   * @param benchmarkClass The benchmark class to record. Must not be
-   *          <code>null</code>.
-   */
-  public void addBenchmark(TreeLogger logger, JClassType benchmarkClass) {
-    Map<String, JMethod> zeroArgMethods = BenchmarkGenerator.getNotOverloadedTestMethods(benchmarkClass);
-    Map<String, JMethod> parameterizedMethods = BenchmarkGenerator.getParameterizedTestMethods(
-        benchmarkClass, TreeLogger.NULL);
-    List<JMethod> testMethods = new ArrayList<JMethod>(zeroArgMethods.size()
-        + parameterizedMethods.size());
-    testMethods.addAll(zeroArgMethods.values());
-    testMethods.addAll(parameterizedMethods.values());
-
-    Map<String, MetaData> metaDataMap = testMetaData.get(benchmarkClass.toString());
-    if (metaDataMap == null) {
-      metaDataMap = new HashMap<String, MetaData>();
-      testMetaData.put(benchmarkClass.toString(), metaDataMap);
-    }
-
-    // Add all of the benchmark methods
-    for (JMethod method : testMethods) {
-      String methodName = method.getName();
-      String methodSource = parser.getMethod(logger, method);
-      StringBuffer sourceBuffer = (methodSource == null) ? null
-          : new StringBuffer(methodSource);
-      StringBuffer summary = new StringBuffer();
-      StringBuffer comment = new StringBuffer();
-      getComment(sourceBuffer, summary, comment);
-
-      MetaData metaData = new MetaData(benchmarkClass.toString(), methodName,
-          (sourceBuffer != null) ? sourceBuffer.toString() : null, methodName,
-          summary.toString());
-      metaDataMap.put(methodName, metaData);
-    }
-  }
-
-  public void addBenchmarkResults(TestCase test, BenchmarkResults results) {
-    List<BenchmarkResults> currentResults = testResults.get(test);
-    if (currentResults == null) {
-      currentResults = new ArrayList<BenchmarkResults>();
-      testResults.put(test, currentResults);
-    }
-    currentResults.add(results);
-  }
-
-  /**
-   * Generates reports for all of the benchmarks which were added to the
-   * generator.
-   * 
-   * @param outputPath The path to write the reports to.
-   * @throws ParserConfigurationException If an error occurs during xml parsing
-   * @throws IOException If anything goes wrong writing to outputPath
-   */
-  public void generate(String outputPath) throws ParserConfigurationException,
-      IOException {
-
-    // Don't generate a new report if no tests were actually run.
-    if (testResults.size() == 0) {
-      return;
-    }
-
-    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-    DocumentBuilder builder = factory.newDocumentBuilder();
-    Document doc = builder.newDocument();
-    doc.appendChild(new ReportXml().toElement(doc));
-    byte[] xmlBytes = Util.toXmlUtf8(doc);
-    FileOutputStream fos = null;
-    try {
-      fos = new FileOutputStream(outputPath);
-      fos.write(xmlBytes);
-    } finally {
-      Utility.close(fos);
-    }
-
-    // TODO(bruce) The code below is commented out because of GWT Issue 958.
-
-    // // TODO(tobyr) Looks like indenting is busted
-    // // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446
-    // // Not a big deal, since we don't intend to read the XML by hand anyway
-    // TransformerFactory transformerFactory = TransformerFactory.newInstance();
-    // // Think this can be used with JDK 1.5
-    // // transformerFactory.setAttribute( "indent-number", new Integer(2) );
-    // Transformer serializer = transformerFactory.newTransformer();
-    // serializer.setOutputProperty(OutputKeys.METHOD, "xml");
-    // serializer.setOutputProperty(OutputKeys.INDENT, "yes");
-    // serializer
-    // .setOutputProperty("{ http://xml.apache.org/xslt }indent-amount", "2");
-    // BufferedOutputStream docOut = new BufferedOutputStream(
-    // new FileOutputStream(outputPath));
-    // serializer.transform(new DOMSource(doc), new StreamResult(docOut));
-    // docOut.close();
-  }
-
-  /**
-   * Parses out the JavaDoc comment from a string of source code. Returns the
-   * first sentence summary in <code>summary</code> and the body of the entire
-   * comment (including the summary) in <code>comment</code>.
-   * 
-   * @param sourceCode The source code of a function, including its comment.
-   *          Modified to remove leading whitespace.
-   * @param summary Modified to contain the first sentence of the comment.
-   * @param comment Modified to contain the entire comment.
-   */
-  private void getComment(StringBuffer sourceCode, StringBuffer summary,
-      StringBuffer comment) {
-
-    if (sourceCode == null) {
-      return;
-    }
-
-    summary.setLength(0);
-    comment.setLength(0);
-
-    String regex = "/\\*\\*(.(?!}-\\*/))*\\*/";
-
-    Pattern p = Pattern.compile(regex, Pattern.DOTALL);
-    Matcher m = p.matcher(sourceCode);
-
-    // Early out if there is no javadoc comment.
-    if (!m.find()) {
-      return;
-    }
-
-    String commentStr = m.group();
-
-    p = Pattern.compile("(/\\*\\*\\s*)" + // The comment header
-        "(((\\s*\\**\\s*)([^\n\r]*)[\n\r]+)*)" // The comment body
-    );
-
-    m = p.matcher(commentStr);
-
-    if (!m.find()) {
-      return;
-    }
-
-    String stripped = m.group(2);
-
-    p = Pattern.compile("^\\p{Blank}*\\**\\p{Blank}*", Pattern.MULTILINE);
-    String bareComment = p.matcher(stripped).replaceAll("");
-
-    BreakIterator iterator = BreakIterator.getSentenceInstance();
-    iterator.setText(bareComment);
-    int firstSentenceEnd = iterator.next();
-    if (firstSentenceEnd == BreakIterator.DONE) {
-      summary.append(bareComment);
-    } else {
-      summary.append(bareComment.substring(0, firstSentenceEnd));
-    }
-
-    comment.append(bareComment);
-
-    // Measure the indentation width on the second line to infer what the
-    // first line indent should be.
-    p = Pattern.compile("[^\\r\\n]+[\\r\\n]+(\\s+)\\*", Pattern.MULTILINE);
-    m = p.matcher(sourceCode);
-    int indentLen = 0;
-    if (m.find()) {
-      String indent = m.group(1);
-      indentLen = indent.length() - 1;
-    }
-    StringBuffer leadingIndent = new StringBuffer();
-    for (int i = 0; i < indentLen; ++i) {
-      leadingIndent.append(' ');
-    }
-
-    // By inserting at 0 here, we are assuming that sourceCode begins with
-    // /**, which is actually a function of how JDT sees a declaration start.
-    // If in the future, you see bogus indentation here, it means that this
-    // assumption is bad.
-    sourceCode.insert(0, leadingIndent);
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/BenchmarkShell.java b/user/src/com/google/gwt/benchmarks/BenchmarkShell.java
deleted file mode 100644
index 40afc4a..0000000
--- a/user/src/com/google/gwt/benchmarks/BenchmarkShell.java
+++ /dev/null
@@ -1,105 +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.benchmarks;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.core.ext.UnableToCompleteException;
-import com.google.gwt.junit.JUnitShell;
-import com.google.gwt.junit.client.GWTTestCase;
-
-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
- * @deprecated This class is scheduled to be removed in the next GWT release.
- */
-@Deprecated
-public class BenchmarkShell {
-
-  /**
-   * 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;
-  }
-
-  /**
-   * @deprecated use {@link #runTest(GWTTestCase, TestResult)} instead
-   */
-  @Deprecated
-  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);
-  }
-
-  public static void runTest(GWTTestCase testCase,
-      TestResult testResult) throws UnableToCompleteException {
-    if (!shutdownHookSet) {
-      shutdownHookSet = true;
-      Runtime.getRuntime().addShutdownHook(new Thread(new Shutdown()));
-    }
-    JUnitShell.runTest(testCase, testResult);
-  }
-
-  private BenchmarkShell() {
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml b/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml
deleted file mode 100644
index e4b9f3c..0000000
--- a/user/src/com/google/gwt/benchmarks/Benchmarks.gwt.xml
+++ /dev/null
@@ -1,35 +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   -->
-<!-- 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"/>
-
-
-  <!-- We do not want stack traces. -->
-  <set-configuration-property name="compiler.emulatedStack.recordFileNames" value="false" />
-  <set-property name="compiler.stackMode" value="native" />
-  
-  <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/benchmarks/MetaData.java b/user/src/com/google/gwt/benchmarks/MetaData.java
deleted file mode 100644
index 816837e..0000000
--- a/user/src/com/google/gwt/benchmarks/MetaData.java
+++ /dev/null
@@ -1,80 +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.benchmarks;
-
-/**
- * The benchmark metadata for a single benchmark method.
- */
-class MetaData {
-
-  private String className;
-
-  private String methodName;
-
-  private String sourceCode;
-
-  private String testDescription;
-
-  private String testName;
-
-  public MetaData(String className, String methodName, String sourceCode,
-      String testName, String testDescription) {
-    this.className = className;
-    this.methodName = methodName;
-    this.sourceCode = sourceCode;
-    this.testName = testName;
-    this.testDescription = testDescription;
-  }
-
-  @Override
-  public boolean equals(Object obj) {
-    if (!(obj instanceof MetaData)) {
-      return false;
-    }
-
-    MetaData md = (MetaData) obj;
-
-    return md.className.equals(className) && md.methodName.equals(methodName);
-  }
-
-  public String getClassName() {
-    return className;
-  }
-
-  public String getMethodName() {
-    return methodName;
-  }
-
-  public String getSourceCode() {
-    return sourceCode;
-  }
-
-  public String getTestDescription() {
-    return testDescription;
-  }
-
-  public String getTestName() {
-    return testName;
-  }
-
-  @Override
-  public int hashCode() {
-    int result;
-    result = (className != null ? className.hashCode() : 0);
-    result = 29 * result + (methodName != null ? methodName.hashCode() : 0);
-    return result;
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/Benchmark.java b/user/src/com/google/gwt/benchmarks/client/Benchmark.java
deleted file mode 100644
index 0e4ede7..0000000
--- a/user/src/com/google/gwt/benchmarks/client/Benchmark.java
+++ /dev/null
@@ -1,161 +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.benchmarks.client;
-
-import com.google.gwt.benchmarks.BenchmarkShell;
-import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
-import com.google.gwt.junit.PropertyDefiningStrategy;
-import com.google.gwt.junit.JUnitShell.Strategy;
-import com.google.gwt.junit.client.GWTTestCase;
-import com.google.gwt.junit.client.impl.JUnitResult;
-
-import junit.framework.TestCase;
-
-/**
- * A type of {@link com.google.gwt.junit.client.GWTTestCase} which specifically
- * records performance results. {@code Benchmarks} have additional functionality
- * above and beyond GWT's JUnit support for standard <code>TestCases</code>.
- * 
- * <h2>Reporting</h2>
- * <p>
- * In a single <code>JUnit</code> run, the results of all executed benchmarks
- * are collected and stored in an XML report viewable with the
- * <code>benchmarkViewer</code>.
- * </p>
- * 
- * <h2>Permutations</h2>
- * <p>
- * 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 RangeField}
- * or {@link RangeEnum}.
- * 
- * For example,
- * 
- * <code><pre> 
- * public void testArrayListRemoves(
- *   &#64;RangeEnum(Position.class) Position where, 
- *   &#64;RangeField("insertRemoveRange") Integer size) { ... 
- * }
- * </pre></code>
- * </p>
- * 
- * <h2>Timing</h2>
- * <ul>
- * <li>GWT automatically removes jitter from your benchmark methods by running
- * them for a minimum period of time (150ms).</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 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>
- * <p>
- * Please note that {@code Benchmarks} do not currently support asynchronous
- * testing mode. Calling
- * {@link com.google.gwt.junit.client.GWTTestCase#delayTestFinish(int)} or
- * {@link com.google.gwt.junit.client.GWTTestCase#finishTest()} will result in
- * an UnsupportedOperationException.
- * </p>
- * 
- * <h2>Examples of benchmarking in action</h2>
- * 
- * <h3>A simple benchmark example</h3>
- * <code>AllocBenchmark</code> is an example of a basic benchmark that doesn't
- * take advantage of most of benchmarking's advanced features.
- * 
- * {@example com.google.gwt.examples.benchmarks.AllocBenchmark}
- * 
- * <h3>An advanced benchmark example</h3>
- * <code>ArrayListBenchmark</code> is a more sophisticated example of
- * benchmarking. It demonstrates the use of {@code Setup} and {@code Teardown}
- * test methods, parameterized test methods, and time limits.
- * 
- * {@example com.google.gwt.examples.benchmarks.ArrayListBenchmark}
- *
- * @deprecated This class is scheduled to be removed in the next GWT release.
- */
-@Deprecated
-public abstract class Benchmark extends GWTTestCase {
-
-  /**
-   * The name of the system property that specifies the location where benchmark
-   * reports are both written to and read from. Its value is
-   * <code>com.google.gwt.junit.reportPath</code>.
-   * 
-   * If this system property is not set, the path defaults to the user's current
-   * working directory.
-   */
-  public static final String REPORT_PATH = "com.google.gwt.junit.reportPath";
-
-  /**
-   * The {@link Strategy} used for benchmarking.
-   */
-  public static class BenchmarkStrategy extends PropertyDefiningStrategy {
-    public BenchmarkStrategy(TestCase test) {
-      super(test);
-    }
-
-    @Override
-    public String getModuleInherit() {
-      return "com.google.gwt.benchmarks.Benchmarks";
-    }
-
-    @Override
-    public void processResult(TestCase testCase, JUnitResult result) {
-      super.processResult(testCase, result);
-      if (result instanceof BenchmarkResults) {
-        BenchmarkShell.getReport().addBenchmarkResults(testCase,
-            (BenchmarkResults) result);
-      }
-    }
-
-    @Override
-    protected String getBaseModuleExtension() {
-      return "Benchmarks";
-    }
-  }
-
-  @Override
-  protected Strategy createStrategy() {
-    return new BenchmarkStrategy(this);
-  }
-
-  /**
-   * 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(this, testResult);
-  }
-
-  /**
-   * Benchmarks do not support asynchronous mode.
-   */
-  @Override
-  protected final boolean supportsAsync() {
-    return false;
-  }
-
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/Category.java b/user/src/com/google/gwt/benchmarks/client/Category.java
deleted file mode 100644
index 22d537b..0000000
--- a/user/src/com/google/gwt/benchmarks/client/Category.java
+++ /dev/null
@@ -1,25 +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.benchmarks.client;
-
-/**
- * A named category that provides classification for
- * {@link Benchmark Benchmarks}. Categories are now deprecated.
- * 
- */
-@Deprecated
-public interface Category {
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/IntRange.java b/user/src/com/google/gwt/benchmarks/client/IntRange.java
deleted file mode 100644
index 5b56cf5..0000000
--- a/user/src/com/google/gwt/benchmarks/client/IntRange.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.benchmarks.client;
-
-/**
- * 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 Iterable<Integer> {
-
-  /**
-   * Implementation of the Iterator.
-   * 
-   */
-  private static class IntRangeIterator extends RangeIterator<Integer> {
-
-    int end;
-
-    Operator operator;
-
-    int step;
-
-    int value;
-
-    IntRangeIterator(IntRange r) {
-      this.value = r.start;
-      this.end = r.end;
-      this.operator = r.operator;
-      if (operator == null) {
-        throw new IllegalArgumentException("operator must be \"*\" or \"+\"");
-      }
-      this.step = r.step;
-    }
-
-    public boolean hasNext() {
-      return value <= end;
-    }
-
-    public Integer next() {
-      int currentValue = value;
-      value = step();
-      return currentValue;
-    }
-
-    public int step() {
-      if (operator == Operator.MULTIPLY) {
-        return value * step;
-      } else {
-        return value + step;
-      }
-    }
-  }
-
-  int end;
-
-  Operator operator;
-
-  int start;
-
-  int step;
-
-  /**
-   * Creates a new range that produces Iterators which begin at
-   * <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.
-   * @param step The amount to step by, for each iteration.
-   */
-  public IntRange(int start, int end, Operator operator, int step) {
-    this.start = start;
-    this.end = end;
-    this.operator = operator;
-    this.step = step;
-    if (step <= 0) {
-      throw new IllegalArgumentException("step must be > 0");
-    }
-  }
-
-  public IntRangeIterator iterator() {
-    return new IntRangeIterator(this);
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java b/user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java
deleted file mode 100644
index e24276b..0000000
--- a/user/src/com/google/gwt/benchmarks/client/IterationTimeLimit.java
+++ /dev/null
@@ -1,39 +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.benchmarks.client;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Documented;
-
-/**
- * Specifies a custom time limit for iterations on the decorated
- * {@link Benchmark} method. Methods that aren't explicitly decorated with an
- * IterationTimeLimit, receive the default value.
- */
-@Target(ElementType.METHOD)
-@Documented
-public @interface IterationTimeLimit {
-
-  /**
-   * The maximum amount of time, in milliseconds, an iteration is pursued before
-   * skipping to the next set of values in the {@code Range}. A value of 0
-   * means that all values in the {@code Range} will be exhaustively tested.
-   * 
-   * @return a maximum duration in milliseconds >= 0
-   */
-  long value() default 1000;
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/Operator.java b/user/src/com/google/gwt/benchmarks/client/Operator.java
deleted file mode 100644
index f4a9309..0000000
--- a/user/src/com/google/gwt/benchmarks/client/Operator.java
+++ /dev/null
@@ -1,49 +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.benchmarks.client;
-
-/**
- * A mathematical operator used in {@link IntRange}s to indicate the stepping
- * function.
- */
-public final class Operator {
-
-  /**
-   * The standard multiplication operator.
-   */
-  public static Operator MULTIPLY = new Operator("*");
-
-  /**
-   * The standard addition operator.
-   */
-  public static Operator ADD = new Operator("+");
-
-  private String value;
-
-  private Operator(String value) {
-    this.value = value;
-  }
-
-  /**
-   * Returns the textual representation of the <code>Operator</code>.
-   * 
-   * @return a non-null {@link String}
-   */
-  @Override
-  public String toString() {
-    return value;
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/RangeEnum.java b/user/src/com/google/gwt/benchmarks/client/RangeEnum.java
deleted file mode 100644
index da69913..0000000
--- a/user/src/com/google/gwt/benchmarks/client/RangeEnum.java
+++ /dev/null
@@ -1,37 +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.benchmarks.client;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Documented;
-
-/**
- * Specifies an Enum containing the entire range of values for a parameter to a
- * {@link Benchmark} method.
- */
-@Target(ElementType.PARAMETER)
-@Documented
-public @interface RangeEnum {
-
-  /**
-   * An <code>Enum</code> that contains the range of values that will be
-   * supplied to the test method.
-   * 
-   * @return for example, {@code MyEnum.class}
-   */
-  Class<? extends Enum<?>> value();
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/RangeField.java b/user/src/com/google/gwt/benchmarks/client/RangeField.java
deleted file mode 100644
index e05b885..0000000
--- a/user/src/com/google/gwt/benchmarks/client/RangeField.java
+++ /dev/null
@@ -1,40 +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.benchmarks.client;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Documented;
-
-/**
- * Specifies a field containing the entire range of values for a parameter to a
- * {@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
- */
-@Target(ElementType.PARAMETER)
-@Documented
-public @interface RangeField {
-
-  /**
-   * The name of the field that this range refers to.
-   * 
-   * @return for example, {@code myCommonRange}
-   */
-  String value();
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/RangeIterator.java b/user/src/com/google/gwt/benchmarks/client/RangeIterator.java
deleted file mode 100644
index 9f345cc..0000000
--- a/user/src/com/google/gwt/benchmarks/client/RangeIterator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.benchmarks.client;
-
-import java.util.Iterator;
-
-/**
- * A base class useful for implementing Iterators for Ranges.
- *
- * @param <T> the type that the Range contains
- */
-public abstract class RangeIterator<T> implements Iterator<T> {
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/Setup.java b/user/src/com/google/gwt/benchmarks/client/Setup.java
deleted file mode 100644
index 6cc1d0f..0000000
--- a/user/src/com/google/gwt/benchmarks/client/Setup.java
+++ /dev/null
@@ -1,45 +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.benchmarks.client;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Documented;
-
-/**
- * Specifies a setup method that will be executed before the annotated
- * {@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
- * <code>testInserts</code> with {@code @Setup("setupTestInserts")} to ensure
- * <code>setupTestInserts</code>is always executed before
- * <code>testInserts</code>.
- * </p>
- */
-@Target(ElementType.METHOD)
-@Documented
-public @interface Setup {
-
-  /**
-   * The name of the method to execute before the annotated test method.
-   * 
-   * @return for example, "setupTestInserts"
-   */
-  String value();
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/Teardown.java b/user/src/com/google/gwt/benchmarks/client/Teardown.java
deleted file mode 100644
index 22bd302..0000000
--- a/user/src/com/google/gwt/benchmarks/client/Teardown.java
+++ /dev/null
@@ -1,45 +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.benchmarks.client;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Target;
-
-/**
- * Specifies a teardown method that will be executed after the annotated
- * {@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
- * <code>testInserts</code> with {@code @Teardown("endTestInserts")} to ensure
- * <code>endTestInserts</code> is always executed after
- * <code>testInserts</code>.
- * </p>
- */
-@Target(ElementType.METHOD)
-@Documented
-public @interface Teardown {
-
-  /**
-   * The name of the method to execute after the annotated test method.
-   * 
-   * @return for example, "endTestInserts"
-   */
-  String value();
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java b/user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java
deleted file mode 100644
index 71d9967..0000000
--- a/user/src/com/google/gwt/benchmarks/client/impl/BenchmarkResults.java
+++ /dev/null
@@ -1,75 +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.benchmarks.client.impl;
-
-import com.google.gwt.junit.client.impl.JUnitResult;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 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.benchmarks.BenchmarkReport
- */
-public class BenchmarkResults extends JUnitResult {
-
-  /**
-   * The URL of the document on the browser (document.location). This is used to
-   * locate the *cache.html document containing the generated JavaScript for the
-   * test. In the case of Development Mode, this points (uselessly) to the
-   * nocache file, because there is no generated JavaScript.
-   *
-   * Apparently, we can't get this value on the server-side because of the
-   * goofy way HTTP_REFERER is set by different browser implementations of
-   * XMLHttpRequest.
-   */
-  private String sourceRef;
-
-  private List<Trial> trials = new ArrayList<Trial>();
-
-  public String getSourceRef() {
-    return sourceRef;
-  }
-
-  public List<Trial> getTrials() {
-    return trials;
-  }
-
-  public void setSourceRef(String sourceRef) {
-    this.sourceRef = sourceRef;
-  }
-
-  @Override
-  public String toString() {
-    return "BenchmarkResults {" + toStringInner() + "}";
-  }
-
-  @Override
-  protected String toStringInner() {
-    return super.toStringInner() + ", trials: " + trials + ", sourceRef: "
-        + sourceRef;
-  }
-
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java b/user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java
deleted file mode 100644
index 87ecd6e..0000000
--- a/user/src/com/google/gwt/benchmarks/client/impl/IterableAdapter.java
+++ /dev/null
@@ -1,46 +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.benchmarks.client.impl;
-
-import java.util.Arrays;
-
-/**
- * Provides convenience methods for adapting various values to the Iterable
- * interface.
- * 
- */
-public class IterableAdapter {
-
-  /**
-   * Returns an <code>Iterable</code> from an array.
-   * 
-   * @param array a not <code>null</code> array
-   * @return an <code>Iterable</code> that wraps the array
-   */
-  public static <T> Iterable<T> toIterable(T[] array) {
-    return Arrays.asList(array);
-  }
-
-  /**
-   * Returns <code>iterable</code> as itself. Useful for code-gen situations.
-   * 
-   * @param iterable a maybe <code>null</code> <code>Iterable</code>
-   * @return <code>iterable</code>
-   */
-  public static <T> Iterable<T> toIterable(Iterable<T> iterable) {
-    return iterable;
-  }
-}
diff --git a/user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java b/user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java
deleted file mode 100644
index 2269b71..0000000
--- a/user/src/com/google/gwt/benchmarks/client/impl/PermutationIterator.java
+++ /dev/null
@@ -1,244 +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.benchmarks.client.impl;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Iterates over all the possible permutations available in a list of {@link
- * Iterable Iterables}.
- * 
- * <p>
- * The simplest way to iterate over the permutations of multiple iterators is in
- * a nested for loop. The PermutationIterator turns that for loop inside out
- * into a single iterator, which enables you to access each permutation in a
- * piecemeal fashion.
- * </p>
- */
-public class PermutationIterator implements
-    Iterator<PermutationIterator.Permutation> {
-
-  /**
-   * A single permutation of all the iterators. Contains the current value of
-   * each iterator for the permutation.
-   */
-  public static class Permutation {
-
-    private List<Object> values;
-
-    public Permutation(List<?> values) {
-      this.values = new ArrayList<Object>(values);
-    }
-
-    public List<Object> getValues() {
-      return values;
-    }
-
-    @Override
-    public String toString() {
-      return values.toString();
-    }
-  }
-
-  public static void main(String[] args) {
-    List<Iterable<String>> iterables = new ArrayList<Iterable<String>>(3);
-    iterables.add(Arrays.asList("a", "b", "c"));
-    iterables.add(Arrays.asList("1", "2", "3"));
-    iterables.add(Arrays.asList("alpha", "beta", "gamma", "delta"));
-
-    System.out.println("Testing normal iteration.");
-    for (Iterator<Permutation> it = new PermutationIterator(iterables); it.hasNext();) {
-      Permutation p = it.next();
-      System.out.println(p);
-    }
-
-    System.out.println("\nTesting skipping iteration.");
-
-    Iterator<String> skipIterator = Arrays.asList("alpha", "beta", "gamma",
-        "delta").iterator();
-    boolean skipped = true;
-    String skipValue = null;
-    for (PermutationIterator it = new PermutationIterator(iterables); it.hasNext();) {
-      Permutation p = it.next();
-
-      if (skipped) {
-        if (skipIterator.hasNext()) {
-          skipValue = skipIterator.next();
-          skipped = false;
-        }
-      }
-
-      System.out.println(p);
-
-      Object value = p.getValues().get(p.getValues().size() - 1);
-
-      if (value.equals(skipValue)) {
-        it.skipCurrentRange();
-        skipped = true;
-      }
-    }
-  }
-
-  /**
-   * Is this the first run?
-   */
-  private boolean firstRun = true;
-
-  /**
-   * The iterator from every range.
-   */
-  private List<Iterator<?>> iterators;
-
-  /**
-   * Are more permutations available?
-   */
-  private boolean maybeHaveMore = true;
-
-  /**
-   * The {@code Iterables} to permute.
-   */
-  private List<? extends Iterable<?>> iterables;
-
-  /**
-   * Did we just skip a range? If so, the values List already contains the
-   * values of the next permutation.
-   */
-  private boolean rangeSkipped = false;
-
-  /**
-   * The current permutation of values.
-   */
-  private List<Object> values;
-
-  /**
-   * Constructs a new PermutationIterator that provides the values for each
-   * possible permutation of <code>iterables</code>.
-   * 
-   * @param iterables non-null. Each {@link Iterable} must have at least one
-   *          element. iterables.size() must be > 1
-   * 
-   * TODO(tobyr) Consider if empty Iterables ever make sense in the context of
-   * permutations.
-   */
-  public PermutationIterator(List<? extends Iterable<?>> iterables) {
-    this.iterables = iterables;
-
-    iterators = new ArrayList<Iterator<?>>();
-
-    for (Iterable<?> iterable : iterables) {
-      iterators.add(iterable.iterator());
-    }
-
-    values = new ArrayList<Object>();
-  }
-
-  /**
-   * Returns a new <code>Permutation</code> containing the values of the next
-   * permutation.
-   * 
-   * @return a non-null <code>Permutation</code>
-   */
-  public boolean hasNext() {
-
-    if (!maybeHaveMore) {
-      return false;
-    }
-
-    // Walk the iterators from bottom to top checking to see if any still have
-    // any available values
-
-    for (int currentIterator = iterators.size() - 1; currentIterator >= 0; --currentIterator) {
-      Iterator<?> it = iterators.get(currentIterator);
-      if (it.hasNext()) {
-        return true;
-      }
-    }
-
-    return false;
-  }
-
-  public Permutation next() {
-    assert hasNext() : "No more available permutations in this iterator.";
-
-    if (firstRun) {
-
-      // Initialize all of our iterators and values on the first run
-      for (Iterator<?> it : iterators) {
-        values.add(it.next());
-      }
-      firstRun = false;
-      return new Permutation(values);
-    }
-
-    if (rangeSkipped) {
-      rangeSkipped = false;
-      return new Permutation(values);
-    }
-
-    // Walk through the iterators from bottom to top, finding the first one
-    // which has a value available. Increment it, reset all of the subsequent
-    // iterators, and then return the current permutation.
-    for (int currentIteratorIndex = iterators.size() - 1; currentIteratorIndex >= 0; --currentIteratorIndex) {
-      Iterator<?> it = iterators.get(currentIteratorIndex);
-      if (it.hasNext()) {
-        values.set(currentIteratorIndex, it.next());
-        for (int i = currentIteratorIndex + 1; i < iterators.size(); ++i) {
-          Iterable<?> resetIterable = iterables.get(i);
-          Iterator<?> resetIterator = resetIterable.iterator();
-          iterators.set(i, resetIterator);
-          values.set(i, resetIterator.next());
-        }
-
-        return new Permutation(values);
-      }
-    }
-
-    throw new AssertionError(
-        "Assertion failed - Couldn't find a non-empty iterator.");
-  }
-
-  public void remove() {
-    throw new UnsupportedOperationException();
-  }
-
-  /**
-   * Skips the remaining set of values in the bottom {@code Iterable}. This
-   * method affects the results of both hasNext() and next().
-   */
-  public void skipCurrentRange() {
-
-    rangeSkipped = true;
-
-    for (int currentIteratorIndex = iterators.size() - 2; currentIteratorIndex >= 0; --currentIteratorIndex) {
-      Iterator<?> it = iterators.get(currentIteratorIndex);
-      if (it.hasNext()) {
-        values.set(currentIteratorIndex, it.next());
-        for (int i = currentIteratorIndex + 1; i < iterators.size(); ++i) {
-          Iterable<?> resetIterable = iterables.get(i);
-          Iterator<?> resetIterator = resetIterable.iterator();
-          iterators.set(i, resetIterator);
-          values.set(i, resetIterator.next());
-        }
-        return;
-      }
-    }
-
-    maybeHaveMore = false;
-  }
-}
\ No newline at end of file
diff --git a/user/src/com/google/gwt/benchmarks/client/impl/Trial.java b/user/src/com/google/gwt/benchmarks/client/impl/Trial.java
deleted file mode 100644
index e89e297..0000000
--- a/user/src/com/google/gwt/benchmarks/client/impl/Trial.java
+++ /dev/null
@@ -1,58 +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.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-info.java b/user/src/com/google/gwt/benchmarks/client/package-info.java
deleted file mode 100644
index 82d7b1c..0000000
--- a/user/src/com/google/gwt/benchmarks/client/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2010 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.
- */
-
-/**
- * Classes and modules used in building benchmarks.
- */
-@com.google.gwt.util.PreventSpuriousRebuilds
-package com.google.gwt.benchmarks.client;
diff --git a/user/src/com/google/gwt/benchmarks/package-info.java b/user/src/com/google/gwt/benchmarks/package-info.java
deleted file mode 100644
index 58f9080..0000000
--- a/user/src/com/google/gwt/benchmarks/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright 2010 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.
- */
-
-/**
- * Classes for benchmarking support.
- */
-@com.google.gwt.util.PreventSpuriousRebuilds
-package com.google.gwt.benchmarks;
diff --git a/user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java b/user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java
deleted file mode 100644
index 1abd4be..0000000
--- a/user/src/com/google/gwt/benchmarks/rebind/BenchmarkGenerator.java
+++ /dev/null
@@ -1,664 +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.benchmarks.rebind;
-
-import com.google.gwt.benchmarks.BenchmarkShell;
-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;
-import com.google.gwt.core.ext.typeinfo.JField;
-import com.google.gwt.core.ext.typeinfo.JMethod;
-import com.google.gwt.core.ext.typeinfo.JParameter;
-import com.google.gwt.dev.generator.ast.ForLoop;
-import com.google.gwt.dev.generator.ast.MethodCall;
-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.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;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Implements a generator for Benchmark classes. Benchmarks require additional
- * code generation above and beyond standard JUnit tests.
- */
-public class BenchmarkGenerator extends JUnitTestCaseStubGenerator {
-
-  private static class MutableLong {
-    long value;
-  }
-
-  private static final String BEGIN_PREFIX = "begin";
-
-  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 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
-   * overloads.
-   * 
-   * @return Map<String,JMethod>
-   */
-  public static Map<String, JMethod> getNotOverloadedTestMethods(
-      JClassType requestedClass) {
-    Map<String, List<JMethod>> methods = getAllMethods(requestedClass,
-        new MethodFilter() {
-          public boolean accept(JMethod method) {
-            return isJUnitTestMethod(method, true);
-          }
-        });
-
-    // Create a new map to store the methods
-    Map<String, JMethod> notOverloadedMethods = new HashMap<String, JMethod>();
-    for (Map.Entry<String, List<JMethod>> entry : methods.entrySet()) {
-      List<JMethod> methodOverloads = entry.getValue();
-      if (methodOverloads.size() == 1) {
-        JMethod overload = methodOverloads.get(0);
-        if (overload.getParameters().length == 0) {
-          notOverloadedMethods.put(entry.getKey(), overload);
-        }
-      }
-    }
-
-    return notOverloadedMethods;
-  }
-
-  /**
-   * Returns all the JUnit test methods that are overloaded test methods with
-   * parameters. Does not include the zero-argument test methods.
-   * 
-   * @return Map<String,JMethod>
-   */
-  public static Map<String, JMethod> getParameterizedTestMethods(
-      JClassType requestedClass, TreeLogger logger) {
-    Map<String, List<JMethod>> testMethods = getAllMethods(requestedClass,
-        new MethodFilter() {
-          public boolean accept(JMethod method) {
-            return isJUnitTestMethod(method, true);
-          }
-        });
-
-    // Create a new mapping to return
-    Map<String, JMethod> overloadedMethods = new HashMap<String, JMethod>();
-
-    // Remove all non-overloaded test methods
-    for (Map.Entry<String, List<JMethod>> entry : testMethods.entrySet()) {
-      String name = entry.getKey();
-      List<JMethod> methods = entry.getValue();
-
-      if (methods.size() > 2) {
-        String msg = requestedClass + "." + name
-            + " has more than one overloaded version"
-            + "; it will not be included in the test case execution";
-        logger.log(TreeLogger.WARN, msg, null);
-        continue;
-      }
-
-      if (methods.size() == 1) {
-        JMethod method = methods.get(0);
-        if (method.getParameters().length != 0) {
-          /*
-           * User probably goofed - otherwise why create a test method with
-           * arguments but not the corresponding no-argument version? Would be
-           * better if our benchmarking system didn't require the no-argument
-           * test to make the benchmarks run correctly (JUnit artifact).
-           */
-          String msg = requestedClass + "." + name
-              + " 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.
-        continue;
-      }
-
-      JMethod method1 = methods.get(0);
-      JMethod method2 = methods.get(1);
-      JMethod noArgMethod = null;
-      JMethod overloadedMethod = null;
-
-      if (method1.getParameters().length == 0) {
-        noArgMethod = method1;
-      } else {
-        overloadedMethod = method1;
-      }
-
-      if (method2.getParameters().length == 0) {
-        noArgMethod = method2;
-      } else {
-        overloadedMethod = method2;
-      }
-
-      if (noArgMethod == null) {
-        String msg = requestedClass + "." + name
-            + " does not have a zero-argument overload"
-            + "; it will not be included in the test case execution";
-        logger.log(TreeLogger.WARN, msg, null);
-        continue;
-      }
-
-      overloadedMethods.put(entry.getKey(), overloadedMethod);
-    }
-
-    return overloadedMethods;
-  }
-
-  private static JMethod getBeginMethod(JClassType type, JMethod method) {
-    Setup setup = method.getAnnotation(Setup.class);
-    String methodName;
-    if (setup != null) {
-      methodName = setup.value();
-    } else {
-      methodName = new StringBuffer(method.getName()).replace(0,
-          "test".length(), BEGIN_PREFIX).toString();
-    }
-    return getMethod(type, methodName);
-  }
-
-  private static JMethod getEndMethod(JClassType type, JMethod method) {
-    Teardown teardown = method.getAnnotation(Teardown.class);
-    String methodName;
-    if (teardown != null) {
-      methodName = teardown.value();
-    } else {
-      methodName = new StringBuffer(method.getName()).replace(0,
-          "test".length(), END_PREFIX).toString();
-    }
-    return getMethod(type, methodName);
-  }
-
-  private static JMethod getMethod(JClassType type, MethodFilter filter) {
-    Map<String, List<JMethod>> map = getAllMethods(type, filter);
-    Set<Map.Entry<String, List<JMethod>>> entrySet = map.entrySet();
-    if (entrySet.size() == 0) {
-      return null;
-    }
-    List<JMethod> methods = entrySet.iterator().next().getValue();
-    return methods.get(0);
-  }
-
-  private static JMethod getMethod(JClassType type, final String name) {
-    return getMethod(type, new MethodFilter() {
-      public boolean accept(JMethod method) {
-        return method.getName().equals(name);
-      }
-    });
-  }
-
-  @Override
-  public void writeSource() throws UnableToCompleteException {
-    super.writeSource();
-
-    generateEmptyFunc(getSourceWriter());
-    implementZeroArgTestMethods();
-    implementParameterizedTestMethods();
-    generateAsyncCode();
-    BenchmarkShell.getReport().addBenchmark(logger, getRequestedClass());
-  }
-
-  /**
-   * Generates benchmarking code which wraps <code>stmts</code> The timing
-   * result is a double in units of milliseconds. It's value is placed in the
-   * variable named, <code>timeMillisName</code>.
-   * 
-   * @return The set of Statements containing the benchmark code along with the
-   *         wrapped <code>stmts</code>
-   */
-  private Statements benchmark(Statements stmts, String timeMillisName,
-      long bound, Statements recordCode, Statements breakCode) {
-    Statements benchmarkCode = new StatementsList();
-    List<Statements> benchStatements = benchmarkCode.getStatements();
-
-    ForLoop loop = new ForLoop("int numLoops = 1", "true", "");
-    benchStatements.add(loop);
-    List<Statements> loopStatements = loop.getStatements();
-
-    loopStatements.add(new Statement("long start = System.currentTimeMillis()"));
-    ForLoop runLoop = new ForLoop("int i = 0", "i < numLoops", "++i", stmts);
-    loopStatements.add(runLoop);
-
-    // Put the rest of the code in 1 big statement to simplify things
-    String benchCode = "long duration = System.currentTimeMillis() - start;\n\n"
-        +
-
-        "if ( duration < 150 ) {\n"
-        + "  numLoops += numLoops;\n"
-        + "  continue;\n"
-        + "}\n\n"
-        +
-
-        "double durationMillis = duration * 1.0;\n"
-        + "double numLoopsAsDouble = numLoops * 1.0;\n"
-        + timeMillisName
-        + " = durationMillis / numLoopsAsDouble";
-
-    loopStatements.add(new Statement(benchCode));
-
-    if (recordCode != null) {
-      loopStatements.add(recordCode);
-    }
-
-    if (bound != 0) {
-      loopStatements.add(new Statement("if ( numLoops == 1 && duration > "
-          + bound + " ) {\n" + breakCode.toString() + "\n" + "}\n\n"));
-    }
-
-    loopStatements.add(new Statement("break"));
-
-    return benchmarkCode;
-  }
-
-  private boolean fieldExists(JClassType type, String fieldName) {
-    JField field = type.findField(fieldName);
-    if (field == null) {
-      JClassType superClass = type.getSuperclass();
-      // noinspection SimplifiableIfStatement
-      if (superClass == null) {
-        return false;
-      }
-      return fieldExists(superClass, fieldName);
-    }
-    return true;
-  }
-
-  private Statements genBenchTarget(JMethod beginMethod, JMethod endMethod,
-      List<String> paramNames, Statements test) {
-    Statements statements = new StatementsList();
-    List<Statements> statementsList = statements.getStatements();
-
-    if (beginMethod != null) {
-      statementsList.add(new Statement(new MethodCall(beginMethod.getName(),
-          paramNames)));
-    }
-
-    statementsList.add(test);
-
-    if (endMethod != null) {
-      statementsList.add(new Statement(
-          new MethodCall(endMethod.getName(), null)));
-    }
-
-    return statements;
-  }
-
-  /**
-   * Currently, the benchmarking subsystem does not support async Benchmarks, so
-   * we need to generate some additional code that prevents the user from
-   * entering async mode in their Benchmark, even though we're using it
-   * internally.
-   * 
-   * <p>
-   * Generates the code for the "supportsAsync" functionality in the
-   * translatable version of GWTTestCase. This includes:
-   * <ul>
-   * <li>the supportsAsync flag</li>
-   * <li>the supportsAsync method</li>
-   * <li>the privateDelayTestFinish method</li>
-   * <li>the privateFinishTest method</li>
-   * </ul>
-   * </p>
-   */
-  private void generateAsyncCode() {
-    SourceWriter writer = getSourceWriter();
-
-    writer.println("private boolean supportsAsync;");
-    writer.println();
-    writer.println("public boolean supportsAsync() {");
-    writer.println("  return supportsAsync;");
-    writer.println("}");
-    writer.println();
-    writer.println("private void privateDelayTestFinish(int timeout) {");
-    writer.println("  supportsAsync = true;");
-    writer.println("  try {");
-    writer.println("    delayTestFinish(timeout);");
-    writer.println("  } finally {");
-    writer.println("    supportsAsync = false;");
-    writer.println("  }");
-    writer.println("}");
-    writer.println();
-    writer.println("private void privateFinishTest() {");
-    writer.println("  supportsAsync = true;");
-    writer.println("  try {");
-    writer.println("    finishTest();");
-    writer.println("  } finally {");
-    writer.println("    supportsAsync = false;");
-    writer.println("  }");
-    writer.println("}");
-    writer.println();
-  }
-
-  /**
-   * Generates an empty JSNI function to help us benchmark function call
-   * overhead.
-   * 
-   * We prevent our empty function call from being inlined by the compiler by
-   * 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 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.
-   * 
-   * 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 micro-benchmark itself.
-   */
-  private void generateEmptyFunc(SourceWriter writer) {
-    writer.println("private native void " + EMPTY_FUNC + "() /*-{");
-    writer.println("}-*/;");
-    writer.println();
-  }
-
-  private Map<String, String> getAnnotationMetaData(JMethod method,
-      MutableLong bound) throws UnableToCompleteException {
-
-    IterationTimeLimit limit = method.getAnnotation(IterationTimeLimit.class);
-    // noinspection SimplifiableIfStatement
-    if (limit == null) {
-      bound.value = getDefaultTimeout();
-    } else {
-      bound.value = limit.value();
-    }
-
-    Map<String, String> paramMetaData = new HashMap<String, String>();
-
-    JParameter[] params = method.getParameters();
-
-    for (JParameter param : params) {
-      RangeField rangeField = param.getAnnotation(RangeField.class);
-      if (rangeField != null) {
-        String fieldName = rangeField.value();
-        JClassType enclosingType = method.getEnclosingType();
-        if (!fieldExists(enclosingType, fieldName)) {
-          logger.log(TreeLogger.ERROR, "The RangeField annotation on "
-              + enclosingType + " at " + method + " specifies a field, "
-              + fieldName + ", which could not be found. Perhaps it is "
-              + "mis-spelled?", null);
-          throw new UnableToCompleteException();
-        }
-        paramMetaData.put(param.getName(), fieldName);
-        continue;
-      }
-      RangeEnum rangeEnum = param.getAnnotation(RangeEnum.class);
-      if (rangeEnum != null) {
-        Class<? extends Enum<?>> enumClass = rangeEnum.value();
-        // Handle inner classes
-        String className = enumClass.getName().replace('$', '.');
-        paramMetaData.put(param.getName(), className + ".values()");
-        continue;
-      }
-
-      String msg = "The parameter, " + param.getName() + ", on method, "
-          + method.getName() + ", must have it's range specified"
-          + "by a RangeField or RangeEnum annotation.";
-      logger.log(TreeLogger.ERROR, msg, null);
-      throw new UnableToCompleteException();
-    }
-
-    return paramMetaData;
-  }
-
-  private synchronized long getDefaultTimeout()
-      throws UnableToCompleteException {
-    if (defaultTimeout != -1) {
-      return defaultTimeout;
-    }
-    Method m = null;
-    try {
-      m = IterationTimeLimit.class.getDeclaredMethod("value");
-      defaultTimeout = (Long) m.getDefaultValue();
-    } catch (Exception e) {
-      /*
-       * Possibly one of: - NullPointerException (if somehow TimeLimit weren't
-       * an annotation or value() didn't have a default). -
-       * NoSuchMethodException if we somehow spelled value wrong -
-       * TypeNotPresentException if somehow value were some type of Class that
-       * couldn't be loaded instead of long It really doesn't make any
-       * difference, because regardless of what could possibly have failed,
-       * we'll still need to go this route.
-       */
-      logger.log(TreeLogger.ERROR,
-          "Unable to retrieve the default benchmark time limit", e);
-      throw new UnableToCompleteException();
-    }
-
-    return defaultTimeout;
-  }
-
-  private void implementParameterizedTestMethods()
-      throws UnableToCompleteException {
-
-    Map<String, JMethod> parameterizedMethods = getParameterizedTestMethods(
-        getRequestedClass(), logger);
-    SourceWriter sw = getSourceWriter();
-    JClassType type = getRequestedClass();
-
-    // For each test method, benchmark its:
-    // a) overhead (setup + teardown + loop + function calls) and
-    // b) execution time
-    // for all possible parameter values
-    for (Map.Entry<String, JMethod> entry : parameterizedMethods.entrySet()) {
-      String name = entry.getKey();
-      JMethod method = entry.getValue();
-      JMethod beginMethod = getBeginMethod(type, method);
-      JMethod endMethod = getEndMethod(type, method);
-
-      sw.println("public void " + name + "() {");
-      sw.indent();
-      sw.println("  privateDelayTestFinish( 2000 );");
-      sw.println();
-
-      MutableLong bound = new MutableLong();
-      Map<String, String> metaDataByParams = getAnnotationMetaData(method,
-          bound);
-      validateParams(method, metaDataByParams);
-
-      JParameter[] methodParams = method.getParameters();
-      List<String> paramNames = new ArrayList<String>(methodParams.length);
-      for (int i = 0; i < methodParams.length; ++i) {
-        paramNames.add(methodParams[i].getName());
-      }
-
-      sw.print("final java.util.List<Iterable<?>> iterables = java.util.Arrays.asList( new Iterable<?>[] { ");
-
-      for (int i = 0; i < paramNames.size(); ++i) {
-        String paramName = paramNames.get(i);
-        sw.print(ITERABLE_ADAPTER_CLASS + ".toIterable("
-            + metaDataByParams.get(paramName) + ")");
-        if (i != paramNames.size() - 1) {
-          sw.print(",");
-        } else {
-          sw.println("} );");
-        }
-        sw.print(" ");
-      }
-
-      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" + "      "
-          + PERMUTATION_ITERATOR_CLASS
-          + ".Permutation permutation = permutationIt.next();\n");
-
-      for (int i = 0; i < methodParams.length; ++i) {
-        JParameter methodParam = methodParams[i];
-        String typeName = methodParam.getType().getQualifiedSourceName();
-        String paramName = paramNames.get(i);
-        sw.println("      " + typeName + " " + paramName + " = (" + typeName
-            + ") permutation.getValues().get(" + i + ");");
-      }
-
-      final String setupTimingName = "__setupTiming";
-      final String testTimingName = "__testTiming";
-
-      sw.println("double " + setupTimingName + " = 0;");
-      sw.println("double " + testTimingName + " = 0;");
-
-      Statements setupBench = genBenchTarget(beginMethod, endMethod,
-          paramNames, new Statement(new MethodCall(EMPTY_FUNC, null)));
-      Statements testBench = genBenchTarget(beginMethod, endMethod, paramNames,
-          new Statement(new MethodCall(method.getName(), paramNames)));
-
-      StringBuffer recordResultsCode = new StringBuffer(BENCHMARK_RESULTS_CLASS
-          + " results = __getOrCreateTestResult();\n" + TRIAL_CLASS
-          + " trial = new " + TRIAL_CLASS + "();\n"
-          + "trial.setRunTimeMillis( " + testTimingName + " - "
-          + setupTimingName + " );\n"
-          + "java.util.Map<String, String> variables = trial.getVariables();\n");
-
-      for (String paramName : paramNames) {
-        recordResultsCode.append("variables.put( \"").append(paramName).append(
-            "\", ").append(paramName).append(".toString() );\n");
-      }
-
-      recordResultsCode.append("results.getTrials().add( trial )");
-      Statements recordCode = new Statement(recordResultsCode.toString());
-
-      Statements breakCode = new Statement("  permutationIt.skipCurrentRange()");
-      setupBench = benchmark(setupBench, setupTimingName, 0, null, breakCode);
-      testBench = benchmark(testBench, testTimingName, bound.value, recordCode,
-          breakCode);
-
-      Statements testAndSetup = new StatementsList();
-      testAndSetup.getStatements().addAll(setupBench.getStatements());
-      testAndSetup.getStatements().addAll(testBench.getStatements());
-
-      sw.println(testAndSetup.toString());
-
-      sw.println("      return true;\n" + "    }\n"
-          + "    privateFinishTest();\n" + "    return false;\n" + "  }\n"
-          + "} );\n");
-
-      sw.outdent();
-      sw.println("}");
-    }
-  }
-
-  /**
-   * Overrides the zero-arg test methods that don't have any
-   * overloaded/parameterized versions.
-   * 
-   * TODO(tobyr) This code shares a lot of similarity with
-   * implementParameterizedTestMethods and they should probably be refactored
-   * into a single function.
-   */
-  private void implementZeroArgTestMethods() throws UnableToCompleteException {
-    Map<String, JMethod> zeroArgMethods = getNotOverloadedTestMethods(getRequestedClass());
-    SourceWriter sw = getSourceWriter();
-    JClassType type = getRequestedClass();
-
-    for (Map.Entry<String, JMethod> entry : zeroArgMethods.entrySet()) {
-      String name = entry.getKey();
-      JMethod method = entry.getValue();
-      JMethod beginMethod = getBeginMethod(type, method);
-      JMethod endMethod = getEndMethod(type, method);
-
-      sw.println("public void " + name + "() {");
-      sw.indent();
-
-      final String setupTimingName = "__setupTiming";
-      final String testTimingName = "__testTiming";
-
-      sw.println("double " + setupTimingName + " = 0;");
-      sw.println("double " + testTimingName + " = 0;");
-
-      Statements setupBench = genBenchTarget(beginMethod, endMethod,
-          Collections.<String> emptyList(), new Statement(new MethodCall(
-              EMPTY_FUNC, null)));
-
-      StatementsList testStatements = new StatementsList();
-      testStatements.getStatements().add(
-          new Statement(new MethodCall("super." + method.getName(), null)));
-      Statements testBench = genBenchTarget(beginMethod, endMethod,
-          Collections.<String> emptyList(), testStatements);
-
-      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);
-
-      setupBench = benchmark(setupBench, setupTimingName, 0, null, breakCode);
-      testBench = benchmark(testBench, testTimingName, getDefaultTimeout(),
-          new Statement(recordResultsCode), breakCode);
-      ForLoop loop = (ForLoop) testBench.getStatements().get(0);
-      loop.setLabel(ESCAPE_LOOP);
-
-      sw.println(setupBench.toString());
-      sw.println(testBench.toString());
-
-      sw.outdent();
-      sw.println("}");
-    }
-  }
-
-  private void validateParams(JMethod method, Map<String, String> params)
-      throws UnableToCompleteException {
-    JParameter[] methodParams = method.getParameters();
-    for (JParameter methodParam : methodParams) {
-      String paramName = methodParam.getName();
-      String paramValue = params.get(paramName);
-
-      if (paramValue == null) {
-        String msg = "Could not find the meta data attribute "
-            + BENCHMARK_PARAM_META + " for the parameter " + paramName
-            + " on method " + method.getName();
-        logger.log(TreeLogger.ERROR, msg, null);
-        throw new UnableToCompleteException();
-      }
-    }
-  }
-}
diff --git a/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java b/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
index 5c8df7d..23a7202 100644
--- a/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
+++ b/user/src/com/google/gwt/core/client/impl/StringBufferImpl.java
@@ -23,9 +23,8 @@
  * 
  * <p>
  * All of the implementations have been carefully tweaked to get the most
- * inlining possible, so be sure to check with
- * {@link com.google.gwt.emultest.java.lang.StringBuilderBenchmark StringBuilderBenchmark}
- * whenever these classes are modified.
+ * inlining possible, so be sure to check with benchmark whenever these classes
+ * are modified.
  * </p>
  */
 public abstract class StringBufferImpl {
diff --git a/user/src/com/google/gwt/core/client/impl/StringBuilderImpl.java b/user/src/com/google/gwt/core/client/impl/StringBuilderImpl.java
index 6fb07fd..56abf35 100644
--- a/user/src/com/google/gwt/core/client/impl/StringBuilderImpl.java
+++ b/user/src/com/google/gwt/core/client/impl/StringBuilderImpl.java
@@ -24,11 +24,10 @@
  * </p>
  * 
  * <p>
- * The main implementations are static classes nested within this one. All of
- * the implementations have been carefully tweaked to get the most inlining
- * possible, so be sure to check with
- * {@link com.google.gwt.emultest.java.lang.StringBuilderBenchmark StringBuilderBenchmark}
- * whenever these classes are modified.
+ * The main implementations are static classes nested within this one.
+ * All of the implementations have been carefully tweaked to get the most
+ * inlining possible, so be sure to check with benchmark whenever these classes
+ * are modified.
  * </p>
  */
 public class StringBuilderImpl {
diff --git a/user/src/com/google/gwt/junit/CompileStrategy.java b/user/src/com/google/gwt/junit/CompileStrategy.java
index c329fd8..7824c36 100644
--- a/user/src/com/google/gwt/junit/CompileStrategy.java
+++ b/user/src/com/google/gwt/junit/CompileStrategy.java
@@ -163,8 +163,7 @@
      * but also includes JUnit support.
      */
     ModuleDef moduleDef = ModuleDefLoader.createSyntheticModule(treeLogger,
-        syntheticModuleName, new String[]{
-            moduleName, strategy.getModuleInherit()}, false);
+        syntheticModuleName, new String[] {moduleName, "com.google.gwt.junit.JUnit"}, false);
 
     // Replace any user entry points with our test runner.
     moduleDef.clearEntryPoints();
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 1911031..ce1c6a7 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -118,13 +118,9 @@
    * A strategy for running the test.
    */
   public interface Strategy {
-    String getModuleInherit();
-
     String getSyntheticModuleExtension();
 
     void processModule(ModuleDef module);
-
-    void processResult(TestCase testCase, JUnitResult result);
   }
 
   static class ArgProcessor extends ArgProcessorBase {
@@ -1253,8 +1249,7 @@
     return true;
   }
 
-  private void processTestResult(TestCase testCase, TestResult testResult,
-      Strategy strategy) {
+  private void processTestResult(TestCase testCase, TestResult testResult) {
 
     Map<ClientStatus, JUnitResult> results = messageQueue.getResults(currentTestInfo);
     assert results != null;
@@ -1294,8 +1289,6 @@
         }
         testResult.addError(testCase, exception);
       }
-
-      strategy.processResult(testCase, result);
     }
   }
 
@@ -1350,7 +1343,7 @@
     numTries++;
     if (messageQueue.hasResults(currentTestInfo)) {
       // Already have a result.
-      processTestResult(testCase, testResult, strategy);
+      processTestResult(testCase, testResult);
       return;
     }
     compileStrategy.maybeAddTestBlockForCurrentTest(testCase, batchingStrategy);
@@ -1400,7 +1393,7 @@
       }
     }
     assert (messageQueue.hasResults(currentTestInfo));
-    processTestResult(testCase, testResult, testCase.getStrategy());
+    processTestResult(testCase, testResult);
   }
 
   /**
diff --git a/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java b/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java
index b10af04..6183133 100644
--- a/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java
+++ b/user/src/com/google/gwt/junit/PropertyDefiningStrategy.java
@@ -19,7 +19,7 @@
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.dev.cfg.Properties;
 import com.google.gwt.dev.util.Util;
-import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.junit.JUnitShell.Strategy;
 import com.google.gwt.junit.client.WithProperties;
 import com.google.gwt.junit.client.WithProperties.Property;
 
@@ -34,7 +34,7 @@
  * A {@link JUnitShell.Strategy} that will alter the module the tests are run
  * in by defining module properties as requested by annotations on the tests.
  */
-public class PropertyDefiningStrategy extends GWTTestCase.BaseStrategy {
+public class PropertyDefiningStrategy implements Strategy {
   private TestCase testCase;
   private Set<Property> properties;
 
@@ -42,13 +42,9 @@
     this.testCase = testCase;
   }
 
-  protected String getBaseModuleExtension() {
-    return super.getSyntheticModuleExtension();
-  }
-
   @Override
   public String getSyntheticModuleExtension() {
-    String extension = getBaseModuleExtension();
+    String extension = "JUnit";
     computePropertiesMap();
     if (properties.size() > 0) {
       StringBuilder sb = new StringBuilder();
@@ -63,7 +59,6 @@
 
   @Override
   public void processModule(ModuleDef module) {
-    super.processModule(module);
     computePropertiesMap();
     if (properties.size() > 0) {
       Properties props = module.getProperties();
diff --git a/user/src/com/google/gwt/junit/client/GWTTestCase.java b/user/src/com/google/gwt/junit/client/GWTTestCase.java
index b3c0258..a254db9 100644
--- a/user/src/com/google/gwt/junit/client/GWTTestCase.java
+++ b/user/src/com/google/gwt/junit/client/GWTTestCase.java
@@ -15,11 +15,9 @@
  */
 package com.google.gwt.junit.client;
 
-import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.junit.JUnitShell;
-import com.google.gwt.junit.PropertyDefiningStrategy;
 import com.google.gwt.junit.JUnitShell.Strategy;
-import com.google.gwt.junit.client.impl.JUnitResult;
+import com.google.gwt.junit.PropertyDefiningStrategy;
 import com.google.gwt.junit.client.impl.JUnitHost.TestInfo;
 
 import junit.framework.TestCase;
@@ -48,25 +46,6 @@
 public abstract class GWTTestCase extends TestCase {
 
   /**
-   * The base class for strategies to use for tests.
-   */
-  public static class BaseStrategy implements Strategy {
-    public String getModuleInherit() {
-      return "com.google.gwt.junit.JUnit";
-    }
-
-    public String getSyntheticModuleExtension() {
-      return "JUnit";
-    }
-
-    public void processModule(ModuleDef module) {
-    }
-
-    public void processResult(TestCase testCase, JUnitResult result) {
-    }
-  }
-
-  /**
    * Information about a synthetic module used for testing.
    */
   public static final class TestModuleInfo {
@@ -254,7 +233,7 @@
    */
   public Strategy getStrategy() {
     if (strategy == null) {
-      strategy = createStrategy();
+      strategy = new PropertyDefiningStrategy(this);
     }
     return strategy;
   }
@@ -334,13 +313,6 @@
   }
 
   /**
-   * Creates the test strategy to use (see {@link #getStrategy()}).
-   */
-  protected Strategy createStrategy() {
-    return new PropertyDefiningStrategy(this);
-  }
-
-  /**
    * Put the current test in asynchronous mode. If the test method completes
    * normally, this test will not immediately succeed. Instead, a <i>delay
    * period</i> begins. During the delay period, the test system will wait for
diff --git a/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java b/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java
deleted file mode 100644
index 5eb419c..0000000
--- a/user/super/com/google/gwt/benchmarks/translatable/com/google/gwt/benchmarks/client/Benchmark.java
+++ /dev/null
@@ -1,46 +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.benchmarks.client;
-
-import com.google.gwt.benchmarks.client.impl.BenchmarkResults;
-import com.google.gwt.junit.client.GWTTestCase;
-
-/**
- * The translatable implementation of {@link Benchmark}.
- */
-public abstract class Benchmark 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 86ec411..fcd6e7c 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
@@ -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
@@ -95,11 +95,6 @@
   private boolean mainTestHasRun = false;
 
   /**
-   * Test result.
-   */
-  private JUnitResult result;
-
-  /**
    * Tracks whether this test is completely done.
    */
   private boolean testIsFinished = false;
@@ -194,15 +189,6 @@
     // hence assumed not to be pure Java.
   }
 
-  // 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) {
@@ -267,7 +253,7 @@
   /**
    * Cleans up any outstanding state, reports ex to the remote runner, and kicks
    * off the next test.
-   * 
+   *
    * @param ex The results of this test.
    */
   private void reportResultsAndRunNextMethod(Throwable ex) {
@@ -281,7 +267,7 @@
     GWT.setUncaughtExceptionHandler(null);
     uncaughtHandler = null;
 
-    JUnitResult myResult = __getOrCreateTestResult();
+    JUnitResult myResult = new JUnitResult();
     if (ex != null) {
       myResult.setException(ex);
     }
@@ -314,7 +300,7 @@
    * A helper method to determine if we should catch exceptions. Wraps the call
    * into user code with a try/catch; if the user's code throws an exception, we
    * just ignore the exception and use the default behavior.
-   * 
+   *
    * @return <code>true</code> if exceptions should be handled normally,
    *         <code>false</code> if they should be allowed to escape.
    */
diff --git a/user/test/com/google/gwt/benchmarks/BenchmarkNoClientTest.java b/user/test/com/google/gwt/benchmarks/BenchmarkNoClientTest.java
deleted file mode 100644
index 06247d7..0000000
--- a/user/test/com/google/gwt/benchmarks/BenchmarkNoClientTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-
-package com.google.gwt.benchmarks;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.junit.GWTTestCaseNoClientTest;
-import com.google.gwt.junit.JUnitShell.Strategy;
-
-/**
- * Tests for {@link Benchmark} that cannot run on the client.
- */
-public class BenchmarkNoClientTest extends GWTTestCaseNoClientTest {
-
-  /**
-   * A mock version of the {@link Benchmark} used for testing.
-   */
-  private static class MockBenchmark extends Benchmark {
-    @Override
-    public String getModuleName() {
-      return "com.google.gwt.mock.Mock";
-    }
-  }
-
-  @Override
-  public void testGetStrategy() {
-    Benchmark testCase = new MockBenchmark();
-    Strategy strategy = testCase.getStrategy();
-    assertEquals("com.google.gwt.benchmarks.Benchmarks",
-        strategy.getModuleInherit());
-    assertEquals("Benchmarks", strategy.getSyntheticModuleExtension());
-    assertEquals("com.google.gwt.mock.Mock.Benchmarks",
-        testCase.getSyntheticModuleName());
-  }
-}
diff --git a/user/test/com/google/gwt/benchmarks/BenchmarksSuite.java b/user/test/com/google/gwt/benchmarks/BenchmarksSuite.java
deleted file mode 100644
index a00f741..0000000
--- a/user/test/com/google/gwt/benchmarks/BenchmarksSuite.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2009 Google Inc.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.google.gwt.benchmarks;
-
-import com.google.gwt.junit.tools.GWTTestSuite;
-
-import junit.framework.Test;
-
-/**
- * Tests of the junit package.
- */
-public class BenchmarksSuite {
-  public static Test suite() {
-    GWTTestSuite suite = new GWTTestSuite(
-        "Test for suite for com.google.gwt.benchmarks");
-
-    // client
-    // Suppressed due to flakiness on Linux
-    // suite.addTestSuite(BenchmarkTest.class);
-
-    suite.addTestSuite(BenchmarkNoClientTest.class);
-
-    return suite;
-  }
-}
diff --git a/user/test/com/google/gwt/benchmarks/client/BenchmarkTest.java b/user/test/com/google/gwt/benchmarks/client/BenchmarkTest.java
deleted file mode 100644
index d1c055d..0000000
--- a/user/test/com/google/gwt/benchmarks/client/BenchmarkTest.java
+++ /dev/null
@@ -1,180 +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.benchmarks.client;
-
-/**
- * Basic Benchmark testing.
- */
-public class BenchmarkTest extends Benchmark {
-
-  /**
-   * Test enum.
-   */
-  protected enum TestEnum {
-    A, B, C;
-  }
-
-  final IntRange intRange = new IntRange(0, 20, Operator.ADD, 5);
-
-  final IntRange intRange2 = new IntRange(10, 1000, Operator.MULTIPLY, 10);
-
-  long startTime;
-
-  String stateString = null;
-
-  final String stringField = "foo";
-
-  final IntRange veryLargeRange = new IntRange(0, Integer.MAX_VALUE,
-      Operator.ADD, 1);
-
-  public void disabledTestTimeLimit() {
-  }
-
-  /**
-   * Tests {@link @IterationTimeLimit}.
-   * 
-   * <p>
-   * TODO(tobyr) Disabled, because it can hang some browsers (Safari at least)
-   * TimeLimits work in general (as evidenced by working benchmarks), but
-   * there's something peculiar about this test causing problems.
-   * </p>
-   * 
-   * @param numIterations
-   */
-  @IterationTimeLimit(1L)
-  public void disabledTestTimeLimit(@RangeField("veryLargeRange")
-  Integer numIterations) {
-
-    somethingExpensive();
-
-    // Make sure we hit the time limit, instead of running through all
-    // iterations.
-    assertTrue(numIterations < Integer.MAX_VALUE);
-  }
-
-  public String getModuleName() {
-    return "com.google.gwt.benchmarks.Benchmarks";
-  }
-
-  public void disableTestAutoboxing() {
-  }
-
-  /**
-   * Tests that autoboxing works correctly.
-   * 
-   * <p>
-   * TODO(tobyr): this causes the generated code to not compile; should probably
-   * be a warning or error if autoboxing args isn't supported.
-   * </p>
-   */
-  public void disableTestAutoboxing(@SuppressWarnings("unused")
-  @RangeField("intRange")
-  int value) {
-  }
-
-  public void testEnumRange() {
-  }
-
-  /**
-   * Tests that we receive the enums in a range.
-   * 
-   * @param enumValue
-   */
-  @Setup("setupEnum")
-  @Teardown("teardownEnum")
-  public void testEnumRange(@RangeEnum(TestEnum.class)
-  TestEnum enumValue) {
-    assertNotNull(enumValue);
-  }
-
-  /**
-   * Tests that a zero argument function works correctly.
-   * 
-   */
-  public void testNoParameters() {
-    assertEquals("foo", stringField);
-  }
-
-  public void testOneParameterField() {
-  }
-
-  /**
-   * Tests that a single argument function works correctly.
-   * 
-   * @param value
-   */
-  public void testOneParameterField(@RangeField("intRange")
-  Integer value) {
-    assertTrue(value >= 0 && value <= 100 && value % 5 == 0);
-  }
-
-  /**
-   * Tests {@link Setup} and {@link Teardown}.
-   * 
-   */
-  @Setup("customSetup")
-  @Teardown("customTeardown")
-  public void testSetupAndTeardown() {
-    assertEquals("setup", stateString);
-    stateString = "running";
-  }
-
-  /**
-   * Tests that this method without a corresponding zero-arg method won't break
-   * the compile.
-   */
-  public void testStrayMethodCompiles(@SuppressWarnings("unused")
-  @RangeField("intRange")
-  int value) {
-  }
-
-  public void testTwoParameterField() {
-  }
-
-  /**
-   * Tests that a multiple argument function works correctly.
-   * 
-   */
-  public void testTwoParameterField(@RangeField("intRange")
-  Integer intOne, @RangeField("intRange2")
-  Integer intTwo) {
-    assertTrue(intOne >= 0 && intOne <= 100 && intOne % 5 == 0);
-    assertTrue(intTwo >= 10 && intTwo <= 1000 && intTwo % 10 == 0);
-  }
-
-  protected void customSetup() {
-    assertNull(stateString);
-    stateString = "setup";
-  }
-
-  protected void customTeardown() {
-    assertNotNull(stateString);
-    assertTrue(stateString.equals("running") || stateString.equals("setup"));
-    stateString = null;
-  }
-
-  /**
-   * Do something that is relatively expensive both in Development Mode and
-   * Production Mode.
-   */
-  private native void somethingExpensive() /*-{
-    var deadField = 0;
-    for (var i = 0; i < 10000; ++i) {
-      deadField += Math.pow(deadField, i);
-    }
-  }-*/;
-}
diff --git a/user/test/com/google/gwt/emultest/EmulSuiteBenchmark.java b/user/test/com/google/gwt/emultest/EmulSuiteBenchmark.java
deleted file mode 100644
index c262c8b..0000000
--- a/user/test/com/google/gwt/emultest/EmulSuiteBenchmark.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2010 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.emultest;
-
-import com.google.gwt.emultest.benchmarks.LongBenchmark;
-import com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark;
-import com.google.gwt.emultest.benchmarks.java.lang.StringBufferImplBenchmark;
-import com.google.gwt.emultest.benchmarks.java.util.ArrayListBenchmark;
-import com.google.gwt.emultest.benchmarks.java.util.ArraySortBenchmark;
-import com.google.gwt.emultest.benchmarks.java.util.HashMapBenchmark;
-import com.google.gwt.emultest.benchmarks.java.util.TreeMapBenchmark;
-import com.google.gwt.emultest.benchmarks.java.util.VectorBenchmark;
-import com.google.gwt.junit.tools.GWTTestSuite;
-
-import junit.framework.Test;
-
-/**
- * Test JRE emulations.
- */
-public class EmulSuiteBenchmark {
-
-  public static Test suite() {
-    GWTTestSuite suite 
-      = new GWTTestSuite("Benchmarks for com.google.gwt.emul.java");
-
-    // $JUnit-BEGIN$
-    // java.lang
-    suite.addTestSuite(StringBufferBenchmark.class);
-    suite.addTestSuite(StringBufferImplBenchmark.class);
-    suite.addTestSuite(LongBenchmark.class);
-
-    // java.util
-    suite.addTestSuite(ArrayListBenchmark.class);
-    suite.addTestSuite(ArraySortBenchmark.class);
-    suite.addTestSuite(HashMapBenchmark.class);
-    suite.addTestSuite(TreeMapBenchmark.class);
-    suite.addTestSuite(VectorBenchmark.class);
-    // $JUnit-END$
-
-    return suite;
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/EmulSuiteBenchmarks.gwt.xml b/user/test/com/google/gwt/emultest/EmulSuiteBenchmarks.gwt.xml
deleted file mode 100644
index 1a7f2bd..0000000
--- a/user/test/com/google/gwt/emultest/EmulSuiteBenchmarks.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2010 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.                                         -->
-
-<module>
-  <inherits name='com.google.gwt.benchmarks.Benchmarks' />
-  <source path='benchmarks' />
-</module>
diff --git a/user/test/com/google/gwt/emultest/benchmarks/LongBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/LongBenchmark.java
deleted file mode 100644
index 78859ca..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/LongBenchmark.java
+++ /dev/null
@@ -1,87 +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.emultest.benchmarks;
-
-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.RangeField;
-
-/**
- * Benchmark for operations on <code>long</code>.
- */
-public class LongBenchmark extends Benchmark {
-  /**
-   * Which implementations can be benchmarked. ALT is present for benchmarking
-   * alternative implementations against the standard one.
-   */
-  enum LongKind {
-    ALT, STANDARD
-  }
-
-  protected final IntRange incrementRange = new IntRange(0, 62, Operator.ADD, 1);
-  protected final LongKind[] toStringKinds = new LongKind[] {LongKind.STANDARD};
-  protected final IntRange toStringRange = new IntRange(0, 62, Operator.ADD, 1);
-
-  /**
-   * This field is used as a target of assignments that should not be pruned.
-   */
-  @SuppressWarnings("unused")
-  private volatile long volatileLong;
-
-  /**
-   * This field is used as a target of assignments that should not be pruned.
-   */
-  @SuppressWarnings("unused")
-  private volatile String volatileString;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  public void testIncrement() {
-  }
-
-  public void testIncrement(@RangeField("incrementRange")
-  Integer xPwr) {
-    long x = 1L << xPwr;
-    for (int i = 1000; i != 0; i--) {
-      x++;
-      x++;
-      x++;
-    }
-    volatileLong = x;
-  }
-
-  public void testToString() {
-  }
-
-  public void testToString(@RangeField("toStringRange")
-  Integer xPwr, @RangeField("toStringKinds")
-  LongKind longKind) {
-    long x = 1L << xPwr;
-    switch (longKind) {
-      case STANDARD:
-        for (int i = 100; i != 0; i--) {
-          volatileString = String.valueOf(x);
-          volatileString = String.valueOf(x);
-          volatileString = String.valueOf(x);
-        }
-        break;
-    }
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferBenchmark.java
deleted file mode 100644
index 1707742..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferBenchmark.java
+++ /dev/null
@@ -1,400 +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.emultest.benchmarks.java.lang;
-
-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.RangeField;
-import com.google.gwt.core.client.JavaScriptObject;
-
-/**
- * A {@link Benchmark} for {@link StringBuilder StringBuilders}. This includes
- * a benchmark from Ray Cromwell that builds display commands in one of two
- * ways. One version uses a StringBuilder, and the other uses raw pushes with
- * JavaScript. Note that there is no actual DisplayList interface, because
- * otherwise the benchmark might have some dynamic dispatch involved. By default
- * this benchmarks only the standard <code>StringBuilder</code> and
- * <code>StringBuffer</code>. To run the full suite, comment in the alternate
- * version of {@link #appendKindsRange}.
- */
-public class StringBufferBenchmark extends Benchmark {
-  /**
-   * The type of StringBuilder to use for a test.
-   */
-  protected enum SBType {
-    JS("raw JavaScrpt"), STRBLD("StringBuilder"), STRBUF("StringBuffer");
-
-    public String description;
-
-    private SBType(String description) {
-      this.description = description;
-    }
-  }
-
-  /**
-   * A DisplayList represented using a native JavaScript array, and updated via
-   * the JavaScript push() method.
-   */
-  @SuppressWarnings("unused")
-  private static class JSArrayDisplayList {
-    private JavaScriptObject jso = JavaScriptObject.createArray();
-
-    public void begin() {
-      jso = JavaScriptObject.createArray();
-    }
-
-    public native void cmd(String cmd) /*-{
-      this.@com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark$JSArrayDisplayList::jso.push(cmd, 0);
-    }-*/;
-
-    public native void cmd(String cmd, int a) /*-{
-      this.@com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark$JSArrayDisplayList::jso.push(cmd, 1, a);
-    }-*/;
-
-    public native void cmd(String cmd, int a, int b) /*-{
-      this.@com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark$JSArrayDisplayList::jso.push(cmd, 2, a, b);
-    }-*/;
-
-    public native void cmd(String cmd, int a, int b, int c) /*-{
-      this.@com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark$JSArrayDisplayList::jso.push(cmd, 3, a, b, c);
-    }-*/;
-
-    public native String end() /*-{
-      return this.@com.google.gwt.emultest.benchmarks.java.lang.StringBufferBenchmark$JSArrayDisplayList::jso.join('');
-    }-*/;
-
-    public void fill() {
-      cmd("F");
-    }
-
-    public void lineTo(int x, int y) {
-      cmd("L", 0, 0);
-    }
-
-    public void moveTo(int x, int y) {
-      cmd("M", 0, 0);
-    }
-
-    public void rotate(int angle) {
-      cmd("R", angle);
-    }
-
-    public void stroke() {
-      cmd("S");
-    }
-
-    public void translate(int x, int y) {
-      cmd("T", x, y);
-    }
-  }
-
-  /**
-   * A DisplayList represented as a {@link StringBuffer} of commands and
-   * arguments. To contrast, see {@link JSArrayDisplayList}.
-   */
-  @SuppressWarnings("unused")
-  private static class StringBufferDisplayList {
-    private StringBuffer strbld = new StringBuffer();
-
-    public void begin() {
-      strbld = new StringBuffer();
-    }
-
-    public void cmd(String cmd) {
-      strbld.append(cmd);
-      strbld.append(0);
-    }
-
-    public void cmd(String cmd, int a) {
-      strbld.append(cmd);
-      strbld.append(1);
-      strbld.append(a);
-    }
-
-    public void cmd(String cmd, int a, int b) {
-      strbld.append(cmd);
-      strbld.append(2);
-      strbld.append(a);
-      strbld.append(b);
-    }
-
-    public void cmd(String cmd, int a, int b, int c) {
-      strbld.append(cmd);
-      strbld.append(3);
-      strbld.append(a);
-      strbld.append(b);
-      strbld.append(c);
-    }
-
-    public String end() {
-      return strbld.toString();
-    }
-
-    public void fill() {
-      cmd("F");
-    }
-
-    public void lineTo(int x, int y) {
-      cmd("L", 0, 0);
-    }
-
-    public void moveTo(int x, int y) {
-      cmd("M", 0, 0);
-    }
-
-    public void rotate(int angle) {
-      cmd("R", angle);
-    }
-
-    public void stroke() {
-      cmd("S");
-    }
-
-    public void translate(int x, int y) {
-      cmd("T", x, y);
-    }
-  }
-
-  /**
-   * A DisplayList represented as a {@link StringBuilder} of commands and
-   * arguments. To contrast, see {@link JSArrayDisplayList}.
-   */
-  @SuppressWarnings("unused")
-  private static class StringBuilderDisplayList {
-    private StringBuilder strbld = new StringBuilder();
-
-    public void begin() {
-      strbld = new StringBuilder();
-    }
-
-    public void cmd(String cmd) {
-      strbld.append(cmd);
-      strbld.append(0);
-    }
-
-    public void cmd(String cmd, int a) {
-      strbld.append(cmd);
-      strbld.append(1);
-      strbld.append(a);
-    }
-
-    public void cmd(String cmd, int a, int b) {
-      strbld.append(cmd);
-      strbld.append(2);
-      strbld.append(a);
-      strbld.append(b);
-    }
-
-    public void cmd(String cmd, int a, int b, int c) {
-      strbld.append(cmd);
-      strbld.append(3);
-      strbld.append(a);
-      strbld.append(b);
-      strbld.append(c);
-    }
-
-    public String end() {
-      return strbld.toString();
-    }
-
-    public void fill() {
-      cmd("F");
-    }
-
-    public void lineTo(int x, int y) {
-      cmd("L", 0, 0);
-    }
-
-    public void moveTo(int x, int y) {
-      cmd("M", 0, 0);
-    }
-
-    public void rotate(int angle) {
-      cmd("R", angle);
-    }
-
-    public void stroke() {
-      cmd("S");
-    }
-
-    public void translate(int x, int y) {
-      cmd("T", x, y);
-    }
-  }
-
-  private static final String P_CLOSE = "</p>";
-  private static final String P_OPEN = "<p>";
-
-  public final SBType[] appendKindsRange = new SBType[] {
-      SBType.STRBUF, SBType.STRBLD};
-  public final IntRange appendTimesRange = new IntRange(32, 4096,
-      Operator.MULTIPLY, 2);
-  public final SBType[] displayListKindsRange = new SBType[] {
-      SBType.STRBUF, SBType.STRBLD, SBType.JS};
-  public final IntRange displayListTimesRange = new IntRange(32, 4096,
-      Operator.MULTIPLY, 2);
-
-  private volatile String abcde = "abcde";
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  /**
-   * Needed for JUnit.
-   */
-  public void testAppend() {
-  }
-
-  public void testAppend(@RangeField("appendTimesRange")
-  Integer times, @RangeField("appendKindsRange")
-  SBType sbtype) {
-    int outerTimes = 1;
-    switch (sbtype) {
-      case STRBLD:
-        for (int i = 0; i < outerTimes; i++) {
-          appendWithStringBuilder(times);
-        }
-        break;
-
-      case STRBUF:
-        for (int i = 0; i < outerTimes; i++) {
-          appendWithStringBuffer(times);
-        }
-        break;
-    }
-  }
-
-  /**
-   * Needed for JUnit.
-   */
-  public void testDisplayList() {
-  }
-
-  /**
-   * Test creating a display list command sequence.
-   */
-  public void testDisplayList(@RangeField("displayListTimesRange")
-  Integer times, @RangeField("displayListKindsRange")
-  SBType sbtype) {
-    switch (sbtype) {
-      case JS:
-        drawWithJSArrayDisplayList(times);
-        break;
-
-      case STRBUF:
-        drawWithStringBufferDisplayList(times);
-        break;
-
-      case STRBLD:
-        drawWithStringBuilderDisplayList(times);
-        break;
-    }
-  }
-
-  private void appendWithStringBuffer(int times) {
-    StringBuffer sb = new StringBuffer();
-    for (int i = 0; i < times; i++) {
-      sb.append(P_OPEN);
-      sb.append(abcde);
-      sb.append(P_CLOSE);
-    }
-    pretendToUse(sb.toString().length());
-  }
-
-  private void appendWithStringBuilder(int times) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < times; i++) {
-      sb.append(P_OPEN);
-      sb.append(abcde);
-      sb.append(P_CLOSE);
-    }
-    pretendToUse(sb.toString().length());
-  }
-
-  /**
-   * Test drawing commands using JSArrayDisplayList.
-   */
-  private void drawWithJSArrayDisplayList(int times) {
-    JSArrayDisplayList dl = new JSArrayDisplayList();
-    dl.begin();
-    for (int i = 0; i < times; i++) {
-      // draw a box
-      dl.translate(50, 50);
-      dl.rotate(45);
-      dl.moveTo(0, 0);
-      dl.lineTo(100, 0);
-      dl.lineTo(100, 100);
-      dl.lineTo(0, 100);
-      dl.lineTo(0, 0);
-      dl.stroke();
-      dl.fill();
-    }
-    pretendToUse(dl.end().length());
-  }
-
-  /**
-   * Test drawing commands using {@link StringBufferDisplayList}.
-   */
-  private void drawWithStringBufferDisplayList(int times) {
-    final StringBufferDisplayList dl = new StringBufferDisplayList();
-    dl.begin();
-    for (int i = 0; i < times; i++) {
-      // draw a box
-      dl.translate(50, 50);
-      dl.rotate(45);
-      dl.moveTo(0, 0);
-      dl.lineTo(100, 0);
-      dl.lineTo(100, 100);
-      dl.lineTo(0, 100);
-      dl.lineTo(0, 0);
-      dl.stroke();
-      dl.fill();
-    }
-    pretendToUse(dl.end().length());
-  }
-
-  /**
-   * Test drawing commands using {@link StringBufferDisplayList}.
-   */
-  private void drawWithStringBuilderDisplayList(int times) {
-    final StringBuilderDisplayList dl = new StringBuilderDisplayList();
-    dl.begin();
-    for (int i = 0; i < times; i++) {
-      // draw a box
-      dl.translate(50, 50);
-      dl.rotate(45);
-      dl.moveTo(0, 0);
-      dl.lineTo(100, 0);
-      dl.lineTo(100, 100);
-      dl.lineTo(0, 100);
-      dl.lineTo(0, 0);
-      dl.stroke();
-      dl.fill();
-    }
-    pretendToUse(dl.end().length());
-  }
-
-  /**
-   * Make a value appear to be live, so that dead code elimination will not
-   * strip it out.
-   */
-  private native void pretendToUse(int x) /*-{
-    $wnd.completelyUselessField = x
-  }-*/;
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferImplBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferImplBenchmark.java
deleted file mode 100644
index 3061f63..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/lang/StringBufferImplBenchmark.java
+++ /dev/null
@@ -1,177 +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.emultest.benchmarks.java.lang;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.benchmarks.client.IntRange;
-import com.google.gwt.benchmarks.client.IterationTimeLimit;
-import com.google.gwt.benchmarks.client.Operator;
-import com.google.gwt.benchmarks.client.RangeField;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.impl.StringBufferImpl;
-import com.google.gwt.core.client.impl.StringBufferImplAppend;
-import com.google.gwt.core.client.impl.StringBufferImplArray;
-import com.google.gwt.core.client.impl.StringBufferImplConcat;
-import com.google.gwt.core.client.impl.StringBufferImplPush;
-
-/**
- * Tests StringBuilder impl directly against each other. Useful when profiling
- * browser behavior.
- */
-public class StringBufferImplBenchmark extends Benchmark {
-
-  /**
-   * The type of StringBuilder to use for a test.
-   */
-  protected enum SBType {
-    APPEND("Append"), ARRAY("Array"), CONCAT("Concat"), PUSH("Push");
-
-    public String description;
-
-    private SBType(String description) {
-      this.description = description;
-    }
-
-    @Override
-    public String toString() {
-      return description;
-    }
-  }
-
-  @SuppressWarnings("unused")
-  private static volatile String result;
-
-  private static volatile Object[] stashSomeGarbage;
-
-  static {
-    if (GWT.isClient()) {
-      stashSomeGarbage = new Object[10000];
-      for (int i = 0; i < stashSomeGarbage.length; ++i) {
-        stashSomeGarbage[i] = new Object();
-      }
-    }
-  }
-
-  final SBType[] appendKindsRange = new SBType[] {
-      SBType.APPEND, SBType.ARRAY, SBType.CONCAT, SBType.PUSH};
-
-  final IntRange manyTimesRange = new IntRange(32, 8192, Operator.MULTIPLY, 2);
-
-  final IntRange singleTimesRange = new IntRange(32, 8192, Operator.MULTIPLY, 2);
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  public void testManyAppends() {
-  }
-
-  @IterationTimeLimit(0)
-  public void testManyAppends(@RangeField("manyTimesRange")
-  Integer times, @RangeField("appendKindsRange")
-  SBType sbtype) {
-    int number = (int) Math.sqrt(times.intValue());
-    switch (sbtype) {
-      case APPEND:
-        for (int i = 0; i < number; ++i) {
-          result = doAppend(number);
-          result = null;
-        }
-        break;
-      case ARRAY:
-        for (int i = 0; i < number; ++i) {
-          result = doArray(number);
-          result = null;
-        }
-        break;
-      case CONCAT:
-        for (int i = 0; i < number; ++i) {
-          result = doConcat(number);
-          result = null;
-        }
-        break;
-      case PUSH:
-        for (int i = 0; i < number; ++i) {
-          result = doPush(number);
-          result = null;
-        }
-        break;
-    }
-  }
-
-  public void testSingleAppend() {
-  }
-
-  @IterationTimeLimit(0)
-  public void testSingleAppend(@RangeField("singleTimesRange")
-  Integer times, @RangeField("appendKindsRange")
-  SBType sbtype) {
-    int number = times;
-    switch (sbtype) {
-      case APPEND:
-        result = doAppend(number);
-        break;
-      case ARRAY:
-        result = doArray(number);
-        break;
-      case CONCAT:
-        result = doConcat(number);
-        break;
-      case PUSH:
-        result = doPush(number);
-        break;
-    }
-    result = null;
-  }
-
-  private String doAppend(int limit) {
-    StringBufferImpl impl = new StringBufferImplAppend();
-    Object data = impl.createData();
-    for (int i = 0; i < limit; i++) {
-      impl.appendNonNull(data, "hello");
-    }
-    return impl.toString(data);
-  }
-
-  private String doArray(int limit) {
-    StringBufferImpl impl = new StringBufferImplArray();
-    Object data = impl.createData();
-    for (int i = 0; i < limit; i++) {
-      impl.appendNonNull(data, "hello");
-    }
-    return impl.toString(data);
-  }
-
-  private String doConcat(int limit) {
-    StringBufferImpl impl = new StringBufferImplConcat();
-    Object data = impl.createData();
-    for (int i = 0; i < limit; i++) {
-      impl.appendNonNull(data, "hello");
-    }
-    return impl.toString(data);
-  }
-
-  private String doPush(int limit) {
-    StringBufferImpl impl = new StringBufferImplPush();
-    Object data = impl.createData();
-    for (int i = 0; i < limit; i++) {
-      impl.appendNonNull(data, "hello");
-    }
-    return impl.toString(data);
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/ArrayListBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/ArrayListBenchmark.java
deleted file mode 100644
index 9131632..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/ArrayListBenchmark.java
+++ /dev/null
@@ -1,29 +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.emultest.benchmarks.java.util;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * A {@link ListBenchmark} for {@link ArrayList ArrayLists}.
- */
-public class ArrayListBenchmark extends ListBenchmark {
-
-  protected List<String> newList() {
-    return new ArrayList<String>();
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/ArraySortBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/ArraySortBenchmark.java
deleted file mode 100644
index 5309ff6..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/ArraySortBenchmark.java
+++ /dev/null
@@ -1,152 +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.emultest.benchmarks.java.util;
-
-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.RangeField;
-import com.google.gwt.benchmarks.client.Setup;
-
-import java.util.Arrays;
-
-/**
- * Benchmarks sorts on arrays.
- */
-public class ArraySortBenchmark extends Benchmark {
-
-  private static class TestObject implements Comparable<TestObject> {
-
-    private int value;
-    
-    public TestObject(int value) {
-      this.value = value;
-    }
-
-    public int compareTo(TestObject o) {
-      return value - o.value;
-    }
-  }
-
-  public final static int SUBARRAY_SKIP = 2;
-
-  public final static int MAX_ARRAY_SIZE = 8192;
-
-  // protected since the generated code is a subclass
-  protected byte[] initByteArray;
-  protected int[] initIntArray;
-  protected TestObject[] initObjectArray;
-
-  protected byte[] byteArray;
-  protected int[] intArray;
-  protected TestObject[] objectArray;
-
-  final IntRange sizeRange = new IntRange(128, MAX_ARRAY_SIZE, Operator.ADD,
-      256);
-
-  public void beginByteArray(Integer size) {
-    byteArray = new byte[size.intValue()];
-    System.arraycopy(initByteArray, 0, byteArray, 0, size.intValue());
-  }
-
-  public void beginIntArray(Integer size) {
-    intArray = new int[size.intValue()];
-    System.arraycopy(initIntArray, 0, intArray, 0, size.intValue());
-  }
-
-  public void beginObjectArray(Integer size) {
-    objectArray = new TestObject[size.intValue()];
-    System.arraycopy(initObjectArray, 0, objectArray, 0, size.intValue());
-  }
-
-  public void beginSubarray(Integer size) {
-    byteArray = new byte[size.intValue()];
-    System.arraycopy(initByteArray, 0, byteArray, 0, size.intValue());
-  }
-
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  // Required for JUnit
-  public void testByteArray() {
-  }
-
-  /**
-   * Sorts <code>size</code> byte entries.
-   */
-  @Setup("beginByteArray")
-  public void testByteArray(@RangeField("sizeRange") Integer size) {
-    Arrays.sort(byteArray);
-  }
-
-  // Required for JUnit
-  public void testIntArray() {
-  }
-
-  /**
-   * Sorts <code>size</code> int entries.
-   */
-  @Setup("beginIntArray")
-  public void testIntArray(@RangeField("sizeRange") Integer size) {
-    Arrays.sort(intArray);
-  }
-
-  // Required for JUnit
-  public void testObjectArray() {
-  }
-
-  /**
-   * Sorts <code>size</code> object entries.
-   */
-  @Setup("beginObjectArray")
-  public void testObjectArray(@RangeField("sizeRange") Integer size) {
-    Arrays.sort(objectArray);
-  }
-
-  // Required for JUnit
-  public void testSubarray() {
-  }
-
-  /**
-   * Sorts <code>size</code> byte entries as a subarray.
-   */
-  @Setup("beginSubarray")
-  public void testSubarray(@RangeField("sizeRange") Integer size) {
-    Arrays.sort(byteArray, SUBARRAY_SKIP, size);
-  }
-
-  @Override
-  protected void gwtSetUp() throws Exception {
-    /*
-     * Since the RNG available in Production Mode cannot accept a seed for
-     * reproducible reports we use a simple pseudorandom sequence here. Its only
-     * purpose is to reasonably shuffle the data.
-     */
-    initByteArray = new byte[MAX_ARRAY_SIZE + SUBARRAY_SKIP];
-    for (int i = 0; i < MAX_ARRAY_SIZE + SUBARRAY_SKIP; i++) {
-      initByteArray[i] = (byte) (i * 31 + 17);
-    }
-    initIntArray = new int[MAX_ARRAY_SIZE];
-    for (int i = 0; i < MAX_ARRAY_SIZE; i++) {
-      initIntArray[i] = i * 3151017 + 17;
-    }
-    initObjectArray = new TestObject[MAX_ARRAY_SIZE + SUBARRAY_SKIP];
-    for (int i = 0; i < MAX_ARRAY_SIZE + SUBARRAY_SKIP; i++) {
-      initObjectArray[i] = new TestObject((i * 31 + 17) % 500);
-    }
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/HashMapBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/HashMapBenchmark.java
deleted file mode 100644
index 53bd546..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/HashMapBenchmark.java
+++ /dev/null
@@ -1,201 +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.emultest.benchmarks.java.util;
-
-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.RangeField;
-import com.google.gwt.benchmarks.client.Setup;
-
-import java.util.HashMap;
-
-/**
- * Benchmarks the HashMap implementation.
- */
-public class HashMapBenchmark extends Benchmark {
-
-  protected IntRange baseRange = new IntRange(32, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  protected IntRange containsRange = new IntRange(10, 200, Operator.ADD, 20);
-
-  private HashMap<Object, Object> map;
-
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  public void testHashMapContainsValueInt() {
-  }
-
-  /**
-   * Checks for <code>size</code> values in a populated HashMap. All items are
-   * Integers, and contain duplicate values.
-   */
-  @Setup("beginHashMapContainsValueInt")
-  public void testHashMapContainsValueInt(@RangeField("containsRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      Integer intVal = new Integer(i);
-      map.containsValue(intVal);
-    }
-  }
-
-  public void testHashMapContainsValueString() {
-  }
-
-  /**
-   * Checks for <code>size</code> values in a populated HashMap. All items are
-   * Strings, and contain duplicate values.
-   */
-  @Setup("beginHashMapContainsValueString")
-  public void testHashMapContainsValueString(@RangeField("containsRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      String strVal = Integer.toString(i);
-      map.containsValue(strVal);
-    }
-  }
-
-  public void testHashMapDuplicateIntAdds() {
-  }
-
-  /**
-   * Appends <code>size</code> items to an empty HashMap. All items are
-   * Integers, and contain duplicate values.
-   */
-  @Setup("initMap")
-  public void testHashMapDuplicateIntAdds(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      Integer intVal = new Integer(i / 10);
-      map.put(intVal, intVal);
-    }
-  }
-
-  public void testHashMapDuplicateStringAdds() {
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      String strVal = Integer.toString(i / 10);
-      map.put(strVal, strVal);
-    }
-  }
-
-  public void testHashMapIntAdds() {
-  }
-
-  /**
-   * Appends <code>size</code> items to an empty HashMap. All items are
-   * Integers, and do not contain duplicate values.
-   */
-  @Setup("initMap")
-  public void testHashMapIntAdds(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      Integer intVal = new Integer(i);
-      map.put(intVal, intVal);
-    }
-  }
-
-  public void testHashMapIntGets() {
-  }
-
-  /**
-   * Checks for <code>size</code> values in a populated HashMap. All items are
-   * Integers, and contain duplicate values.
-   */
-  @Setup("beginHashMapIntGets")
-  public void testHashMapIntGets(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      Integer intVal = new Integer(i);
-      map.get(intVal);
-    }
-  }
-
-  public void testHashMapStringAdds() {
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      String strVal = Integer.toString(i);
-      map.put(strVal, strVal);
-    }
-  }
-
-  public void testHashMapStringGets() {
-  }
-
-  /**
-   * Checks for size values in a populated HashMap. All items are Strings, and
-   * contain duplicate values.
-   */
-  @Setup("beginHashMapStringGets")
-  public void testHashMapStringGets(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      String strVal = Integer.toString(i);
-      map.get(strVal);
-    }
-  }
-
-  protected void beginHashMapContainsValueInt(Integer size) {
-    map = new HashMap<Object, Object>();
-    testHashMapDuplicateIntAdds(size);
-  }
-
-  protected void beginHashMapContainsValueString(Integer size) {
-    map = new HashMap<Object, Object>();
-    testHashMapDuplicateStringAdds(size);
-  }
-
-  protected void beginHashMapIntGets(Integer size) {
-    map = new HashMap<Object, Object>();
-    testHashMapIntAdds(size);
-  }
-
-  protected void beginHashMapStringGets(Integer size) {
-    map = new HashMap<Object, Object>();
-    testHashMapStringAdds(size);
-  }
-
-  protected void initMap(Integer size) {
-    map = new HashMap<Object, Object>(size);
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/ListBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/ListBenchmark.java
deleted file mode 100644
index 26c4d1e..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/ListBenchmark.java
+++ /dev/null
@@ -1,230 +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.emultest.benchmarks.java.util;
-
-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.Arrays;
-import java.util.List;
-
-/**
- * Benchmarks common operations on {@link List Lists}. This test covers
- * appends, inserts, and removes for various sizes and positions.
- * 
- */
-public abstract class ListBenchmark extends Benchmark {
-
-  /*
-   * TODO(tobyr) Add more tests such as iteration, non-sequential random access,
-   * and sublists.
-   */
-
-  private static final int PRIME = 3001;
-
-  /**
-   * The various positions that data can be inserted into a list.
-   */
-  protected enum Position {
-
-    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>.
-     */
-    Position(String label) {
-      this.label = label;
-    }
-
-    /**
-     * Returns the textual description for the position.
-     * 
-     * @return a not <code>null</code> description.
-     */
-    public String toString() {
-      return label;
-    }
-  }
-
-  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);
-
-  protected final IntRange baseRange = new IntRange(512, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  List<String> list;
-
-  int index = 0;
-
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.add("hello");
-    }
-  }
-
-  // Required for JUnit
-  public void testListAdds() {
-  }
-
-  /**
-   * 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) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      list.get(i);
-    }
-  }
-
-  // Required for JUnit
-  public void testListGets() {
-  }
-
-  /**
-   * 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) {
-    insertIntoCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testListInserts() {
-  }
-
-  /**
-   * 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) {
-    removeFromCollection(size, where, list);
-  }
-
-  // Required for JUnit
-  public void testListRemoves() {
-  }
-
-  /**
-   * Creates a new empty List.
-   * 
-   * @return a not <code>null</code>, empty List
-   */
-  protected abstract List<String> newList();
-
-  void beginListAdds(Integer size) {
-    list = newList();
-  }
-
-  void beginListGets(Integer size) {
-    createList(size);
-  }
-
-  void beginListInserts(Position where, Integer size) {
-    list = newList();
-    index = 0;
-  }
-
-  void beginListRemoves(Position where, Integer size) {
-    beginListInserts(where, size);
-    testListInserts(where, size);
-  }
-
-  private void createList(Integer size) {
-    beginListAdds(size);
-    testListAdds(size);
-  }
-
-  private void insertIntoCollection(Integer size, Position where, List<String> l) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        l.add("hello");
-      } else if (where == Position.BEGIN) {
-        l.add(0, "hello");
-      } else if (where == Position.EXPLICIT_END) {
-        l.add(l.size(), "hello");
-      } else if (where == Position.VARIED) {
-        l.add(index, "hello");
-        index += PRIME;
-        index %= l.size();
-      }
-    }
-  }
-
-  private int removeFromCollection(Integer size, Position where, List<String> l) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        throw new RuntimeException("cannot remove from the end implicitly");
-      } else if (where == Position.BEGIN) {
-        l.remove(0);
-      } else if (where == Position.EXPLICIT_END) {
-        l.remove(l.size() - 1);
-      } else if (where == Position.VARIED) {
-        l.remove(index);
-        index += PRIME;
-        int currentSize = l.size();
-        if (currentSize > 0) {
-          index %= l.size();
-        }
-      }
-    }
-    return index;
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/SortedMapBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/SortedMapBenchmark.java
deleted file mode 100644
index fac8ddb..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/SortedMapBenchmark.java
+++ /dev/null
@@ -1,242 +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.emultest.benchmarks.java.util;
-
-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.Arrays;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.SortedMap;
-
-/**
- * Benchmarks common operations on {@link SortedMap SortedMaps}. This test covers
- * appends, inserts, and removes for various sizes and positions.
- * 
- */
-public abstract class SortedMapBenchmark extends Benchmark {
-
-  /*
-   * TODO(rovrevik) Add more tests such as iteration, non-sequential random
-   * access, and sublists.
-   */
-
-  /**
-   * The various positions that data can be inserted into a list.
-   */
-  protected enum Position {
-
-    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>.
-     */
-    Position(String label) {
-      this.label = label;
-    }
-
-    /**
-     * Returns the textual description for the position.
-     * 
-     * @return a not <code>null</code> description.
-     */
-    @Override
-    public String toString() {
-      return label;
-    }
-  }
-
-  private static final int PRIME = 3001;
-
-  protected final IntRange baseRange = new IntRange(512, Integer.MAX_VALUE,
-      Operator.MULTIPLY, 2);
-
-  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);
-
-  int index = 0;
-
-  SortedMap<Integer, String> sortedMap;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.emultest.EmulSuiteBenchmarks";
-  }
-
-  // Required for JUnit
-  public void testSortedMapGets() {
-  }
-
-  /**
-   * Performs <code>size</code> gets on a {@code SortedMap} of size,
-   * <code>size</code>.
-   * 
-   * @param size the size of the {@code SortedMap}
-   */
-  @Setup("beginSortedMapGets")
-  public void testSortedMapGets(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      sortedMap.get(i);
-    }
-  }
-
-  // Required for JUnit
-  public void testSortedMapInserts() {
-  }
-
-  /**
-   * Performs <code>size</code> inserts at position, <code>where</code>, on
-   * an empty <code>SortedMap</code>.
-   * 
-   * @param where Where the inserts happen
-   * @param size The size of the <code>SortedMap</code>
-   * 
-   */
-  @Setup("beginSortedMapInserts")
-  public void testSortedMapInserts(@RangeEnum(Position.class)
-  Position where, @RangeField("insertRemoveRange")
-  Integer size) {
-    insertIntoCollection(size, where, sortedMap);
-  }
-
-  // Required for JUnit
-  public void testSortedMapPuts() {
-  }
-
-  /**
-   * Appends <code>size</code> items to an empty {@code SortedMap}.
-   * 
-   * @param size the size of the {@code SortedMap}
-   */
-  @Setup("beginSortedMapPuts")
-  public void testSortedMapPuts(@RangeField("baseRange")
-  Integer size) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      sortedMap.put(i, "hello");
-    }
-  }
-
-  // Required for JUnit
-  public void testSortedMapRemoves() {
-  }
-
-  /**
-   * Performs <code>size</code> removes at position, <code>where</code>, on
-   * an TreeMap of size, <code>size</code>.
-   * 
-   * @param where Where the inserts happen
-   * @param size The size of the <code>SortedMap</code>
-   */
-  @Setup("beginSortedMapRemoves")
-  public void testSortedMapRemoves(@RangeField("explicitPositions")
-  Position where, @RangeField("insertRemoveRange")
-  Integer size) {
-    removeFromCollection(size, where, sortedMap);
-  }
-
-  /**
-   * Creates a new empty SortedMap.
-   * 
-   * @return a not <code>null</code>, empty SortedMap
-   */
-  protected abstract SortedMap<Integer, String> newSortedMap();
-
-  void beginSortedMapGets(Integer size) {
-    createSortedMap(size);
-  }
-
-  void beginSortedMapInserts(Position where, Integer size) {
-    sortedMap = newSortedMap();
-    index = 0;
-  }
-
-  void beginSortedMapPuts(Integer size) {
-    sortedMap = newSortedMap();
-  }
-
-  void beginSortedMapRemoves(Position where, Integer size) {
-    beginSortedMapInserts(where, size);
-    testSortedMapInserts(where, size);
-  }
-
-  private void createSortedMap(Integer size) {
-    beginSortedMapPuts(size);
-    testSortedMapPuts(size);
-  }
-
-  private void insertIntoCollection(Integer size, Position where,
-      SortedMap<Integer, String> m) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        Integer key;
-        try {
-          key = m.lastKey();
-        } catch (NoSuchElementException e) {
-          key = Integer.valueOf(0);
-        }
-        m.put((key.intValue() + 1), "hello");
-      } else if (where == Position.BEGIN) {
-        m.put(0, "hello");
-      } else if (where == Position.EXPLICIT_END) {
-        m.put(m.size(), "hello");
-      } else if (where == Position.VARIED) {
-        m.put(index, "hello");
-        index += PRIME;
-        index %= m.size();
-      }
-    }
-  }
-
-  private int removeFromCollection(Integer size, Position where,
-      SortedMap<Integer, String> m) {
-    int num = size.intValue();
-    for (int i = 0; i < num; i++) {
-      if (where == Position.IMPLICIT_END) {
-        throw new RuntimeException("cannot remove from the end implicitly");
-      } else if (where == Position.BEGIN) {
-        m.remove(0);
-      } else if (where == Position.EXPLICIT_END) {
-        m.remove(m.size() - 1);
-      } else if (where == Position.VARIED) {
-        m.remove(index);
-        index += PRIME;
-        int currentSize = m.size();
-        if (currentSize > 0) {
-          index %= m.size();
-        }
-      }
-    }
-    return index;
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/TreeMapBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/TreeMapBenchmark.java
deleted file mode 100644
index b4a8a33..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/TreeMapBenchmark.java
+++ /dev/null
@@ -1,29 +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.emultest.benchmarks.java.util;
-
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-/**
- * A {@link SortedMapBenchmark} for {@link TreeMap TreeMaps}.
- */
-public class TreeMapBenchmark extends SortedMapBenchmark {
-  @Override
-  protected SortedMap<Integer, String> newSortedMap() {
-    return new TreeMap<Integer, String>();
-  }
-}
diff --git a/user/test/com/google/gwt/emultest/benchmarks/java/util/VectorBenchmark.java b/user/test/com/google/gwt/emultest/benchmarks/java/util/VectorBenchmark.java
deleted file mode 100644
index c2ad174..0000000
--- a/user/test/com/google/gwt/emultest/benchmarks/java/util/VectorBenchmark.java
+++ /dev/null
@@ -1,29 +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.emultest.benchmarks.java.util;
-
-import java.util.List;
-import java.util.Vector;
-
-/**
- * A {@link ListBenchmark} for {@link Vector Vectors}.
- */
-public class VectorBenchmark extends ListBenchmark {
-
-  protected List<String> newList() {
-    return new Vector<String>();
-  }
-}
diff --git a/user/test/com/google/gwt/i18n/I18NBenchmarks.gwt.xml b/user/test/com/google/gwt/i18n/I18NBenchmarks.gwt.xml
deleted file mode 100644
index 1a7f2bd..0000000
--- a/user/test/com/google/gwt/i18n/I18NBenchmarks.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2010 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.                                         -->
-
-<module>
-  <inherits name='com.google.gwt.benchmarks.Benchmarks' />
-  <source path='benchmarks' />
-</module>
diff --git a/user/test/com/google/gwt/i18n/I18NSuiteBenchmark.java b/user/test/com/google/gwt/i18n/I18NSuiteBenchmark.java
deleted file mode 100644
index 160417d..0000000
--- a/user/test/com/google/gwt/i18n/I18NSuiteBenchmark.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2010 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.i18n;
-
-import com.google.gwt.i18n.benchmarks.NumberFormatBenchmark;
-import com.google.gwt.junit.tools.GWTTestSuite;
-
-import junit.framework.Test;
-
-/**
- * All I18N tests.
- */
-public class I18NSuiteBenchmark {
-  public static Test suite() {
-    GWTTestSuite suite = new GWTTestSuite("All I18N benchmarks");
-
-    // $JUnit-BEGIN$
-    suite.addTestSuite(NumberFormatBenchmark.class);
-    // $JUnit-END$
-
-    return suite;
-  }
-}
diff --git a/user/test/com/google/gwt/i18n/benchmarks/NumberFormatBenchmark.java b/user/test/com/google/gwt/i18n/benchmarks/NumberFormatBenchmark.java
deleted file mode 100644
index 1c8a895..0000000
--- a/user/test/com/google/gwt/i18n/benchmarks/NumberFormatBenchmark.java
+++ /dev/null
@@ -1,56 +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.i18n.benchmarks;
-
-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.RangeField;
-import com.google.gwt.i18n.client.NumberFormat;
-
-/**
- * Benchmark for number format.
- */
-public class NumberFormatBenchmark extends Benchmark {
-  final IntRange sizeRange = new IntRange(50, 2000, Operator.ADD, 50);
-
-  /**
-   * Must refer to a valid module that inherits from com.google.gwt.junit.JUnit.
-   */
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.i18n.I18NBenchmarks";
-  }
-
-  // Required for JUnit
-  public void testCurrency() {
-  }
-
-  /**
-   * Basic test of currency format.
-   * 
-   * @param size the size
-   */
-  public void testCurrency(@RangeField("sizeRange")
-  Integer size) {
-    NumberFormat format = NumberFormat.getCurrencyFormat();
-    int limit = size.intValue();
-    for (int i = 0; i < limit; i++) {
-      format.format(i);
-    }
-  }
-}
diff --git a/user/test/com/google/gwt/junit/GWTTestCaseNoClientTest.java b/user/test/com/google/gwt/junit/GWTTestCaseNoClientTest.java
index c25473f..b3a6d08 100644
--- a/user/test/com/google/gwt/junit/GWTTestCaseNoClientTest.java
+++ b/user/test/com/google/gwt/junit/GWTTestCaseNoClientTest.java
@@ -39,7 +39,6 @@
   public void testGetStrategy() {
     GWTTestCase testCase = new MockGWTTestCase();
     Strategy strategy = testCase.getStrategy();
-    assertEquals("com.google.gwt.junit.JUnit", strategy.getModuleInherit());
     assertEquals("JUnit", strategy.getSyntheticModuleExtension());
     assertEquals("com.google.gwt.mock.Mock.JUnit",
         testCase.getSyntheticModuleName());
diff --git a/user/test/com/google/gwt/junit/JUnitSuite.java b/user/test/com/google/gwt/junit/JUnitSuite.java
index 746432a..fb684c0 100644
--- a/user/test/com/google/gwt/junit/JUnitSuite.java
+++ b/user/test/com/google/gwt/junit/JUnitSuite.java
@@ -32,10 +32,6 @@
   public static Test suite() {
     TestSuite suite = new GwtTestSuiteWithExpectedFailures("Test suite for com.google.gwt.junit");
 
-    // client
-    // Suppressed due to flakiness on Linux
-    // suite.addTestSuite(BenchmarkTest.class);
-
     suite.addTestSuite(GWTTestCaseTest.class);
     suite.addTestSuite(GWTTestCaseUncaughtExceptionHandlerTest.class);
     suite.addTest(new TestSuiteWithOrder(GWTTestCaseAsyncTest.class));
diff --git a/user/test/com/google/gwt/junit/client/DevModeOnCompiledScriptTest.java b/user/test/com/google/gwt/junit/client/DevModeOnCompiledScriptTest.java
index f9aefe8..77cfeb7 100644
--- a/user/test/com/google/gwt/junit/client/DevModeOnCompiledScriptTest.java
+++ b/user/test/com/google/gwt/junit/client/DevModeOnCompiledScriptTest.java
@@ -19,11 +19,8 @@
 import com.google.gwt.dev.cfg.ModuleDef;
 import com.google.gwt.junit.DoNotRunWith;
 import com.google.gwt.junit.JUnitBridge;
-import com.google.gwt.junit.Platform;
 import com.google.gwt.junit.JUnitShell.Strategy;
-import com.google.gwt.junit.client.impl.JUnitResult;
-
-import junit.framework.TestCase;
+import com.google.gwt.junit.Platform;
 
 /**
  * Tests that we can run a test in dev mode even when the selection script is
@@ -45,10 +42,6 @@
   public Strategy getStrategy() {
     final Strategy impl = super.getStrategy();
     return new Strategy() {
-      public String getModuleInherit() {
-        return impl.getModuleInherit();
-      }
-
       public String getSyntheticModuleExtension() {
         return impl.getSyntheticModuleExtension();
       }
@@ -62,10 +55,6 @@
               e);
         }
       }
-
-      public void processResult(TestCase testCase, JUnitResult result) {
-        impl.processResult(testCase, result);
-      }
     };
   }
 
diff --git a/user/test/com/google/gwt/user/UserBenchmarks.gwt.xml b/user/test/com/google/gwt/user/UserBenchmarks.gwt.xml
deleted file mode 100644
index 1a7f2bd..0000000
--- a/user/test/com/google/gwt/user/UserBenchmarks.gwt.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2010 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.                                         -->
-
-<module>
-  <inherits name='com.google.gwt.benchmarks.Benchmarks' />
-  <source path='benchmarks' />
-</module>
diff --git a/user/test/com/google/gwt/user/benchmarks/DomEventBenchmark.java b/user/test/com/google/gwt/user/benchmarks/DomEventBenchmark.java
deleted file mode 100644
index 882f2f4..0000000
--- a/user/test/com/google/gwt/user/benchmarks/DomEventBenchmark.java
+++ /dev/null
@@ -1,135 +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.user.benchmarks;
-
-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.RangeField;
-import com.google.gwt.benchmarks.client.Setup;
-import com.google.gwt.user.client.ui.ClickListener;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwt.user.client.ui.SimpleCheckBox;
-import com.google.gwt.user.client.ui.Widget;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Measures the speed with which event handlers can be added and removed to a
- * few simple UI classes. This is here to allow us to compare the performance of
- * the old event listeners and the new event handlers. This first version, of
- * course, can only look at listeners, as handlers aren't here yet.
- */
-public class DomEventBenchmark extends Benchmark {
-
-  /**
-   * Whether to use old listeners or new handlers.
-   */
-  // protected enum RegistrationStyle {
-  // OLD_LISTENERS, NEW_HANDLERS
-  // }
-  private static final int NUM_WIDGETS = 250;
-
-  protected final IntRange listenerRange =
-      new IntRange(4, 400, Operator.MULTIPLY, 10);
-
-  private List<SimpleCheckBox> widgets;
-
-  private List<ClickListener> listeners;
-
-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.user.UserBenchmarks";
-  }
-
-  // Required for JUnit
-  public void testSimpleCheckBoxAddAndRemoveForClicks() {
-  }
-
-  @Setup("reset")
-  public void testSimpleCheckBoxAddAndRemoveForClicks(
-  // @RangeEnum(RegistrationStyle.class) RegistrationStyle style,
-      @RangeField("listenerRange")
-      Integer numListeners) {
-
-    // The RegistrationStyle blank is here to be filled in when handlers arrive.
-    // Until then, just run the tests twice.
-
-    // if (RegistrationStyle.OLD_LISTENERS == style) {
-    for (SimpleCheckBox cb : widgets) {
-      for (int i = 0; i < numListeners; i++) {
-        cb.addClickListener(listeners.get(i));
-      }
-    }
-    for (SimpleCheckBox cb : widgets) {
-      for (int i = 0; i < numListeners; i++) {
-        cb.removeClickListener(listeners.get(i));
-      }
-    }
-    // }
-  }
-
-  // Required for JUnit
-  public void testSimpleCheckBoxAddForClicks() {
-  }
-
-  @Setup("reset")
-  public void testSimpleCheckBoxAddForClicks(
-  // @RangeEnum(RegistrationStyle.class) RegistrationStyle style,
-      @RangeField("listenerRange")
-      Integer numListeners) {
-
-    // The RegistrationStyle blank is here to be filled in when handlers arrive.
-    // Until then, just run the tests twice.
-
-    // if (RegistrationStyle.OLD_LISTENERS == style) {
-    for (SimpleCheckBox cb : widgets) {
-      for (int i = 0; i < numListeners; i++) {
-        cb.addClickListener(listeners.get(i));
-      }
-    }
-    // }
-  }
-
-  void reset(/* RegistrationStyle style , */Integer numListeners) {
-    RootPanel root = RootPanel.get();
-    root.clear();
-    widgets = new ArrayList<SimpleCheckBox>();
-    listeners = new ArrayList<ClickListener>();
-
-    for (int i = 0; i < NUM_WIDGETS; i++) {
-      SimpleCheckBox cb = new SimpleCheckBox();
-      widgets.add(cb);
-      root.add(cb);
-    }
-
-    for (int i = 0; i < numListeners; i++) {
-      listeners.add(new ClickListener() {
-        public void onClick(Widget sender) {
-        }
-      });
-    }
-  }
-
-  // /**
-  // * Cannot do this until we fix our inability to synthesize events,
-  // * pending...
-  // */
-  // public void testDispatch() {
-  //     
-  // }
-}
diff --git a/user/test/com/google/web/bindery/autobean/AutoBeanBenchmarks.gwt.xml b/user/test/com/google/web/bindery/autobean/AutoBeanBenchmarks.gwt.xml
deleted file mode 100644
index fe63fae..0000000
--- a/user/test/com/google/web/bindery/autobean/AutoBeanBenchmarks.gwt.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<!--                                                                        -->
-<!-- Copyright 2011 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.                                         -->
-
-<module>
-  <inherits name='com.google.gwt.benchmarks.Benchmarks' />
-  <inherits name='com.google.web.bindery.autobean.AutoBean' />
-  <source path='benchmarks' />
-</module>
diff --git a/user/test/com/google/web/bindery/autobean/benchmarks/ValueCodexBenchmark.java b/user/test/com/google/web/bindery/autobean/benchmarks/ValueCodexBenchmark.java
deleted file mode 100644
index 9b8ac87..0000000
--- a/user/test/com/google/web/bindery/autobean/benchmarks/ValueCodexBenchmark.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2012 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.web.bindery.autobean.benchmarks;
-
-import com.google.gwt.benchmarks.client.Benchmark;
-import com.google.gwt.benchmarks.client.RangeField;
-import com.google.web.bindery.autobean.shared.ValueCodex;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Benchmarks {@link ValueCodex#findType} (by mean of
- * {@link ValueCodex#canDecode(Class)} and {@link ValueCodex#encode(Object)}) to
- * measure the impact of a change made to it.
- * 
- * @see http://gwt-code-reviews.appspot.com/1601805/
- */
-public class ValueCodexBenchmark extends Benchmark {
-
-  enum MyEnum {
-    /** */
-    FOO,
-    /** */
-    BAR {
-      @SuppressWarnings("unused")
-      private void dummy() {
-      }
-    }
-  }
-
-  final Object[] values = {
-      MyEnum.FOO, MyEnum.BAR, Boolean.TRUE, Integer.valueOf(42), "string", new java.util.Date(),
-      new java.sql.Date(new java.util.Date().getTime())};
-
-  final Set<Class<?>> allValueTypes;
-  {
-    allValueTypes = new HashSet<Class<?>>(ValueCodex.getAllValueTypes());
-    allValueTypes.add(MyEnum.class);
-    allValueTypes.add(MyEnum.BAR.getClass());
-  }
-
-  @Override
-  public String getModuleName() {
-    return "com.google.web.bindery.autobean.AutoBeanBenchmarks";
-  }
-
-  // Required by JUnit
-  public void testEncode() {
-  }
-
-  public void testEncode(@RangeField("values") Object value) {
-    final int times = 100;
-    for (int i = 0; i < times; i++) {
-      ValueCodex.encode(value);
-    }
-  }
-
-  // Required by JUnit
-  public void testCanDecode() {
-  }
-
-  public void testCanDecode(@RangeField("allValueTypes") Class<?> valueType) {
-    final int times = 100;
-    for (int i = 0; i < times; i++) {
-      ValueCodex.canDecode(valueType);
-    }
-  }
-}
