Added benchmark framework

Change-Id: I1f82b988fde7738b34ee1b3d26540ca116b65cbe
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..911fa5c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+benchmarks/.classpath
+benchmarks/.project
+benchmarks/.settings/
+benchmarks/target/
+
diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
new file mode 100644
index 0000000..4bac6c2
--- /dev/null
+++ b/benchmarks/pom.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.google.gwt.benchmark</groupId>
+  <artifactId>gwt-benchmark-benchmarks</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+
+  <parent>
+    <groupId>com.google.gwt.benchmark</groupId>
+    <artifactId>gwt-benchmark-parent</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <!-- Using an older version of GWT here allows the benchmarks to execute against old      -->
+    <!-- versions of the GWT SDK. This will help to find old commits that changed performance -->
+    <gwtversion>2.0.0</gwtversion>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-user</artifactId>
+      <version>${gwtversion}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-dev</artifactId>
+      <version>${gwtversion}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/java</directory>
+        <includes>
+          <include>**/*.java</include>
+          <include>**/*.js</include>
+          <include>**/*.gwt.xml</include>
+        </includes>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.3</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <version>2.5.1</version>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <!-- enforcing java 1.5 so we can make sure benchmarks can be -->
+          <!-- compiled with old GWT versions -->
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-eclipse-plugin</artifactId>
+        <version>2.8</version>
+        <configuration>
+          <downloadSources>true</downloadSources>
+          <downloadJavadocs>false</downloadJavadocs>
+          <projectnatures>
+            <projectnature>org.eclipse.jdt.core.javanature</projectnature>
+          </projectnatures>
+          <buildcommands>
+            <buildcommand>org.eclipse.jdt.core.javabuilder</buildcommand>
+          </buildcommands>
+          <classpathContainers>
+            <classpathContainer>org.eclipse.jdt.launching.JRE_CONTAINER</classpathContainer>
+          </classpathContainers>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.6</version>
+        <configuration>
+          <excludes>
+            <exclude>**/*GwtTest.java</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>gwt-maven-plugin</artifactId>
+        <version>2.1.0</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test</goal>
+            </goals>
+            <configuration>
+              <includes>**/*GwtTest.java</includes>
+              <productionMode>true</productionMode>
+              <mode>htmlunit</mode>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
+
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/Collections.gwt.xml b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/Collections.gwt.xml
new file mode 100644
index 0000000..c1abf04
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/Collections.gwt.xml
@@ -0,0 +1,25 @@
+<!--                                                                        -->
+<!-- Copyright 2014 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.                                         -->
+
+<!-- Collections based on JavaScript arrays / JavaScript Objects.           -->
+<!--                                                                        -->
+<!-- These collections exist to write benchmarks that do not depend on      -->
+<!-- the performance of GWT emulated collection classes. Benchmarks should  -->
+<!-- prefer these collection over the standard Java ones.                   -->
+
+<module>
+  <inherits name="com.google.gwt.core.Core"/>
+  <source path="client" />
+  <source path="shared" />
+</module>
\ No newline at end of file
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayBooleanGwtImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayBooleanGwtImpl.java
new file mode 100644
index 0000000..053c3fc
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayBooleanGwtImpl.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2014 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.benchmark.collection.client;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayBoolean;
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * GWT implementation of {@link JavaScriptArrayBoolean}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public final class JavaScriptArrayBooleanGwtImpl<T> extends JavaScriptObject implements
+    JavaScriptArrayBoolean {
+
+  public static <T> JavaScriptArrayBooleanGwtImpl<T> create() {
+    return JavaScriptObject.createArray().cast();
+  }
+
+  public static native <T> JavaScriptArrayBooleanGwtImpl<T> create(int initialCapacity) /*-{
+    return new Array(initialCapacity);
+  }-*/;
+
+  public native boolean get(int i) /*-{
+    return this[i];
+  }-*/;
+
+  public native int length() /*-{
+    return this.length;
+  }-*/;
+
+  public native void push(boolean t) /*-{
+    return this.push(t);
+  }-*/;
+
+  protected JavaScriptArrayBooleanGwtImpl() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayGwtImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayGwtImpl.java
new file mode 100644
index 0000000..ff6d016
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayGwtImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 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.benchmark.collection.client;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArray;
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * GWT implementation of {@link JavaScriptArray}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public final class JavaScriptArrayGwtImpl<T> extends JavaScriptObject implements
+    JavaScriptArray<T> {
+
+  public static <T> JavaScriptArrayGwtImpl<T> create() {
+    return JavaScriptObject.createArray().cast();
+  }
+
+  public static native <T> JavaScriptArrayGwtImpl<T> create(int initialCapacity) /*-{
+    return new Array(initialCapacity);
+  }-*/;
+
+  public native T get(int i) /*-{
+    return this[i];
+  }-*/;
+
+  public native int length() /*-{
+    return this.length;
+  }-*/;
+
+  public native void push(T t) /*-{
+    return this.push(t);
+  }-*/;
+
+  public native void set(int index, T value) /*-{
+    this[index] = value;
+  }-*/;
+
+  protected JavaScriptArrayGwtImpl() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayIntGwtImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayIntGwtImpl.java
new file mode 100644
index 0000000..80787bc
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayIntGwtImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 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.benchmark.collection.client;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayInt;
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * GWT implementation of {@link JavaScriptArrayInt}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public final class JavaScriptArrayIntGwtImpl<T> extends JavaScriptObject implements
+    JavaScriptArrayInt {
+
+  public static <T> JavaScriptArrayIntGwtImpl<T> create() {
+    return JavaScriptObject.createArray().cast();
+  }
+
+  public static native <T> JavaScriptArrayIntGwtImpl<T> create(int initialCapacity) /*-{
+    return new Array(initialCapacity);
+  }-*/;
+
+  public native int get(int i) /*-{
+    return this[i];
+  }-*/;
+
+  public native int length() /*-{
+    return this.length;
+  }-*/;
+
+  public native void push(int t) /*-{
+    return this.push(t);
+  }-*/;
+
+  public native void set(int index, int value) /*-{
+    this[index] = value;
+  }-*/;
+
+  protected JavaScriptArrayIntGwtImpl() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayNumberGwtImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayNumberGwtImpl.java
new file mode 100644
index 0000000..cd752c1
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/client/JavaScriptArrayNumberGwtImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 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.benchmark.collection.client;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * GWT implementation of {@link JavaScriptArrayNumber}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public final class JavaScriptArrayNumberGwtImpl<T> extends JavaScriptObject implements
+    JavaScriptArrayNumber {
+
+  public static <T> JavaScriptArrayNumberGwtImpl<T> create() {
+    return JavaScriptObject.createArray().cast();
+  }
+
+  public static native <T> JavaScriptArrayNumberGwtImpl<T> create(int initialCapacity) /*-{
+    return new Array(initialCapacity);
+  }-*/;
+
+  public native double get(int i) /*-{
+    return this[i];
+  }-*/;
+
+  public native int length() /*-{
+    return this.length;
+  }-*/;
+
+  public native void push(double t) /*-{
+    return this.push(t);
+  }-*/;
+
+  public native void set(int index, double value) /*-{
+    this[index] = value;
+  }-*/;
+
+  protected JavaScriptArrayNumberGwtImpl() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/CollectionFactory.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/CollectionFactory.java
new file mode 100644
index 0000000..c3e0ae7
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/CollectionFactory.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+import com.google.gwt.benchmark.collection.client.JavaScriptArrayBooleanGwtImpl;
+import com.google.gwt.benchmark.collection.client.JavaScriptArrayGwtImpl;
+import com.google.gwt.benchmark.collection.client.JavaScriptArrayIntGwtImpl;
+import com.google.gwt.benchmark.collection.client.JavaScriptArrayNumberGwtImpl;
+import com.google.gwt.benchmark.collection.shared.impl.JavaScriptArrayIntJavaImpl;
+import com.google.gwt.benchmark.collection.shared.impl.JavaScriptArrayJavaImpl;
+import com.google.gwt.benchmark.collection.shared.impl.JavaScriptArrayNumberJavaImpl;
+import com.google.gwt.core.client.GWT;
+
+/**
+ * CollectionFactory creates instances for collection interfaces.
+ * <p>
+ * The Factory instantiates different implementation for JavaScript vs. JVM and should be
+ * used inside of benchmarks.
+ */
+public class CollectionFactory {
+  public static <T> JavaScriptArray<T> create() {
+    if (GWT.isScript()) {
+      return JavaScriptArrayGwtImpl.create();
+    } else {
+      return new JavaScriptArrayJavaImpl<T>();
+    }
+  }
+
+  public static <T> JavaScriptArray<T> create(int initialCapacity) {
+    if (GWT.isScript()) {
+      return JavaScriptArrayGwtImpl.create(initialCapacity);
+    } else {
+      return new JavaScriptArrayJavaImpl<T>(initialCapacity);
+    }
+  }
+
+  public static JavaScriptArrayBoolean createBoolean() {
+    if (GWT.isScript()) {
+      return JavaScriptArrayBooleanGwtImpl.create();
+    } else {
+      return new JavaScriptArrayBooleanJavaImpl();
+    }
+  }
+
+  public static JavaScriptArrayBoolean createBoolean(int initialCapacity) {
+    if (GWT.isScript()) {
+      return JavaScriptArrayBooleanGwtImpl.create(initialCapacity);
+    } else {
+      return new JavaScriptArrayBooleanJavaImpl(initialCapacity);
+    }
+  }
+
+  public static JavaScriptArrayInt createInt(int initialCapacity) {
+    if (GWT.isScript()) {
+      return JavaScriptArrayIntGwtImpl.create(initialCapacity);
+    } else {
+      return new JavaScriptArrayIntJavaImpl(initialCapacity);
+    }
+  }
+
+  public static JavaScriptArrayNumber createNumber() {
+    if (GWT.isScript()) {
+      return JavaScriptArrayNumberGwtImpl.create();
+    } else {
+      return new JavaScriptArrayNumberJavaImpl();
+    }
+  }
+
+  public static JavaScriptArrayNumber createNumber(int initialCapacity) {
+    if (GWT.isScript()) {
+      return JavaScriptArrayNumberGwtImpl.create(initialCapacity);
+    } else {
+      return new JavaScriptArrayNumberJavaImpl(initialCapacity);
+    }
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArray.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArray.java
new file mode 100644
index 0000000..3dbf14d
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArray.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+/**
+ * A simple interface for JavaScript arrays.
+ *<p>
+ * Using these interfaces allows benchmarks to run on a JVM and be compiled to JavaScript.
+ * @param <T> the type of the object to store.
+ */
+public interface JavaScriptArray<T> {
+  T get(int i);
+
+  int length();
+
+  void push(T t);
+
+  void set(int index, T value);
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBoolean.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBoolean.java
new file mode 100644
index 0000000..cdf3e83
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBoolean.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+/**
+ * A simple interface for JavaScript arrays containing only numbers.
+ * <p>
+ * Using these interfaces allows benchmarks to run on a JVM and be compiled to JavaScript.
+ */
+public interface JavaScriptArrayBoolean {
+  boolean get(int i);
+
+  int length();
+
+  void push(boolean t);
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBooleanJavaImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBooleanJavaImpl.java
new file mode 100644
index 0000000..885102a
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayBooleanJavaImpl.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+/**
+ * Java implementation of {@link JavaScriptArrayBoolean}.
+ */
+public class JavaScriptArrayBooleanJavaImpl implements JavaScriptArrayBoolean {
+
+  private boolean[] array;
+  private int length = 0;
+
+  public JavaScriptArrayBooleanJavaImpl() {
+    array = new boolean[64];
+  }
+
+  public JavaScriptArrayBooleanJavaImpl(int capacity) {
+    array = new boolean[capacity];
+  }
+
+  public boolean get(int i) {
+    return array[i];
+  }
+
+  public int length() {
+    return length;
+  }
+
+  public void push(boolean t) {
+    if(length > array.length) {
+      boolean[] newArray = new boolean[array.length * 2];
+      System.arraycopy(array, 0, newArray, 0, array.length);
+      array = newArray;
+    }
+
+    array[length] = t;
+    length++;
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayInt.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayInt.java
new file mode 100644
index 0000000..312db44
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayInt.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+/**
+ * A simple interface for JavaScript arrays containing only numbers.
+ * <p>
+ * Using these interfaces allows benchmarks to run on a JVM and be compiled to JavaScript.
+ */
+public interface JavaScriptArrayInt {
+  int get(int i);
+
+  int length();
+
+  void push(int t);
+
+  void set(int i, int d);
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayNumber.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayNumber.java
new file mode 100644
index 0000000..a460ee4
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/JavaScriptArrayNumber.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared;
+
+/**
+ * A simple interface for JavaScript arrays containing only numbers.
+ * <p>
+ * Using these interfaces allows benchmarks to run on a JVM and be compiled to JavaScript.
+ */
+public interface JavaScriptArrayNumber {
+  double get(int i);
+
+  int length();
+
+  void push(double t);
+
+  void set(int i, double d);
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayIntJavaImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayIntJavaImpl.java
new file mode 100644
index 0000000..0b68df2
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayIntJavaImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared.impl;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayInt;
+
+/**
+ * Java implementation of {@link JavaScriptArrayInt}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public class JavaScriptArrayIntJavaImpl implements JavaScriptArrayInt {
+
+  private int[] array;
+  private int length;
+
+  public JavaScriptArrayIntJavaImpl() {
+    array = new int[64];
+  }
+
+  public JavaScriptArrayIntJavaImpl(int initialCapacity) {
+    array = new int[initialCapacity];
+  }
+
+  public int get(int i) {
+    return array[i];
+  }
+
+  public int length() {
+    return length;
+  }
+
+  public void push(int t) {
+    if (length >= array.length) {
+      int[] newArray = new int[array.length * 2];
+      System.arraycopy(array, 0, newArray, 0, array.length);
+      array = newArray;
+    }
+
+    array[length] = t;
+    length++;
+  }
+
+  public void set(int index, int value) {
+    // This does not handle out of bounds access currently.
+    // No benchmark has run into trouble so far.
+    array[index] = value;
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayJavaImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayJavaImpl.java
new file mode 100644
index 0000000..dfb1fd8
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayJavaImpl.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared.impl;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArray;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Java implementation of {@link JavaScriptArray}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public class JavaScriptArrayJavaImpl<T> implements JavaScriptArray<T> {
+
+  private List<T> list = new ArrayList<T>();
+
+  public JavaScriptArrayJavaImpl() {
+    list = new ArrayList<T>();
+  }
+
+  public JavaScriptArrayJavaImpl(int initialCapacity) {
+    list = new ArrayList<T>(initialCapacity);
+  }
+
+  public T get(int i) {
+    return list.get(i);
+  }
+
+  public int length() {
+    return list.size();
+  }
+
+  public void push(T t) {
+    list.add(t);
+  }
+
+  public void set(int index, T value) {
+    // This does not handle out of bounds access currently.
+    // No benchmark has run into trouble so far.
+    if(index == list.size()) {
+      list.add(value);
+    } else {
+      list.set(index, value);
+    }
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayNumberJavaImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayNumberJavaImpl.java
new file mode 100644
index 0000000..4919d50
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/collection/shared/impl/JavaScriptArrayNumberJavaImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014 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.benchmark.collection.shared.impl;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+
+/**
+ * Java implementation of {@link JavaScriptArrayNumber}.
+ * <p>
+ * These collections exist to write benchmarks that do not depend on the performance of GWT
+ * emulated collection classes. Benchmarks should prefer these collection over the standard
+ * Java ones.
+ * <p>
+ * See also {@link CollectionFactory} for a way to instantiate the right implementation
+ * depending on running on the JVM or in JavaScript.
+ */
+public class JavaScriptArrayNumberJavaImpl implements JavaScriptArrayNumber {
+
+  private double[] array;
+  private int length;
+
+  public JavaScriptArrayNumberJavaImpl() {
+    array = new double[64];
+  }
+
+  public JavaScriptArrayNumberJavaImpl(int initialCapacity) {
+    array = new double[initialCapacity];
+  }
+
+  public double get(int i) {
+    return array[i];
+  }
+
+  public int length() {
+    return length;
+  }
+
+  public void push(double t) {
+    if (length >= array.length) {
+      double[] newArray = new double[array.length * 2];
+      System.arraycopy(array, 0, newArray, 0, array.length);
+      array = newArray;
+    }
+
+    array[length] = t;
+    length++;
+  }
+
+  public void set(int index, double value) {
+    // This does not handle out of bounds access currently.
+    // No benchmark has run into trouble so far.
+    array[index] = value;
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/d8/D8.gwt.xml b/benchmarks/src/main/java/com/google/gwt/benchmark/d8/D8.gwt.xml
new file mode 100644
index 0000000..39c180d
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/d8/D8.gwt.xml
@@ -0,0 +1,23 @@
+<!--                                                                        -->
+<!-- Copyright 2014 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.                                         -->
+
+<!-- This module is intended to be inherited from Benchmarks that want to   -->
+<!-- run on D8 (the V8 command line version)                                -->
+<!--                                                                        -->
+
+<module>
+  <define-linker name="d8" class="com.google.gwt.core.linker.D8ScriptLinker" />
+  <add-linker name="d8" />
+  <set-property name="user.agent" value="safari" />
+</module>
\ No newline at end of file
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/BenchmarkFramework.gwt.xml b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/BenchmarkFramework.gwt.xml
new file mode 100644
index 0000000..967d526
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/BenchmarkFramework.gwt.xml
@@ -0,0 +1,19 @@
+<!--                                                                        -->
+<!-- Copyright 2014 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.benchmark.collection.Collections"/>
+  <inherits name="com.google.gwt.core.Core"/>
+  <source path="client" />
+  <source path="shared" />
+</module>
\ No newline at end of file
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/AbstractBenchmarkEntryPoint.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/AbstractBenchmarkEntryPoint.java
new file mode 100644
index 0000000..67d1894
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/AbstractBenchmarkEntryPoint.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 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.benchmark.framework.client;
+
+import com.google.gwt.benchmark.framework.shared.AbstractBenchmark;
+import com.google.gwt.benchmark.framework.shared.BenchmarkExecutor;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+import com.google.gwt.benchmark.framework.shared.Performance;
+import com.google.gwt.benchmark.framework.shared.PerformanceFactory;
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+
+/**
+ * Base class for all Benchmark entry points.
+ */
+public abstract class AbstractBenchmarkEntryPoint implements EntryPoint {
+
+  public void onModuleLoad() {
+    try {
+      maybePatchPerformanceNow();
+      BenchmarkExecutor executor = new BenchmarkExecutor();
+      BenchmarkResult benchmarkResult =
+          executor.executeWithFixedTime(getBenchmark());
+      double runsPerSecond =
+          (benchmarkResult.getNumberOfRuns() * 1000) / benchmarkResult.getTotalTimePassedMs();
+      update(runsPerSecond);
+    } catch (Exception e) {
+      setFailed();
+      GWT.log("Benchmark failed", e);
+    }
+  }
+
+  protected abstract AbstractBenchmark getBenchmark();
+
+  private native boolean hasWindowPerformanceNow() /*-{
+    return !!$wnd.performance && !!$wnd.performance.now;
+  }-*/;
+
+  private void maybePatchPerformanceNow() {
+    if(!hasWindowPerformanceNow()) {
+      polyfill(PerformanceFactory.create());
+    }
+  }
+
+  private native void polyfill(Performance p) /*-{
+    var now = function() {
+      return p.@com.google.gwt.benchmark.framework.shared.Performance::now()();
+    };
+    $wnd.performance = {};
+    $wnd.performance.now = now;
+    // If we are runninn with a linker that loads our code in an iframe
+    // patch the local window object as well.
+    window.performance = {};
+    window.performance.now = now;
+  }-*/;
+
+  private native void update(double result) /*-{
+    $wnd.__gwt__benchmarking__failed = false;
+    $wnd.__gwt__benchmarking__result = result;
+    $wnd.__gwt__benchmarking__ran = true;
+  }-*/;
+
+  private native void setFailed() /*-{
+    $wnd.__gwt__benchmarking__failed = true;
+    $wnd.__gwt__benchmarking__ran = true;
+  }-*/;
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/BenchmarkResultJsImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/BenchmarkResultJsImpl.java
new file mode 100644
index 0000000..cf9353d
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/BenchmarkResultJsImpl.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014 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.benchmark.framework.client;
+
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * Implementation of {@link BenchmarkResult} for JavaScript code.
+ * <p>
+ * Note: This is a pure model object and does not contain any logic.
+ */
+public final class BenchmarkResultJsImpl extends JavaScriptObject implements BenchmarkResult {
+
+  public native static BenchmarkResultJsImpl create() /*-{
+    return {name: "", numberOfRuns: 0, totalTimePassedMs: 0, timesForIndividualRunsMs: []};
+  }-*/;
+
+  public native String getName() /*-{
+    return this.name;
+  }-*/;
+
+  public native int getNumberOfRuns() /*-{
+    return this.numberOfRuns;
+  }-*/;
+
+  public native JavaScriptArrayNumber getTimesForIndividualRunsMs() /*-{
+    return this.timesForIndividualRunsMs;
+  }-*/;
+
+  public native double getTotalTimePassedMs() /*-{
+    return this.totalTimePassedMs;
+  }-*/;
+
+  public native void setName(String name) /*-{
+    this.name = name;
+  }-*/;
+
+  public native void setNumberOfRuns(int runs) /*-{
+    this.numberOfRuns = runs;
+  }-*/;
+
+  public native void setTimesForIndividualRunsMs(
+      JavaScriptArrayNumber timesForIndividualRunsMs) /*-{
+    this.timesForIndividualRunsMs = timesForIndividualRunsMs;
+  }-*/;
+
+  public native void setTotalTimePassed(double time) /*-{
+    this.totalTimePassedMs = time;
+  }-*/;
+
+  protected BenchmarkResultJsImpl() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/Injector.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/Injector.java
new file mode 100644
index 0000000..c63a164
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/client/Injector.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2014 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.benchmark.framework.client;
+
+/**
+ * Injector provides a method that a benchmark's entry point can use to set up a JavaScript
+ * benchmark.
+ * <p>
+ * Note: Injection is done using eval because in D8 we do not have a head element to add script
+ * tags to (GWT ScriptInjector works that way). This class is intended to be used with original
+ * Benchmarks that have been ported from JS (Octane). It allows us to keep the original file as is
+ * and simply inject it into the benchmarking system.
+ */
+public class Injector {
+
+  /**
+   * Maps a JavaScript value stored in a local variable to a global variable.
+   */
+  public static class GlobalMapping {
+    private String globalName;
+    private String localName;
+
+    public GlobalMapping(String globalName, String localName) {
+      this.globalName = globalName;
+      this.localName = localName;
+    }
+
+    public String getGlobalName() {
+      return globalName;
+    }
+
+    public String getLocalName() {
+      return localName;
+    }
+  }
+
+  /**
+   * Inject JavaScript into a a private scope.
+   *
+   * @param js the main JavaScript to inject
+   * @param mappings An array of mappings to publish from the scope
+   */
+  public void injectJavaScript(String js, GlobalMapping... mappings) {
+    StringBuilder builder = new StringBuilder();
+    builder.append("(function() {\n");
+    builder.append(js);
+    for (int i = 0; i < mappings.length; i++) {
+      builder.append(
+          "$wnd." + mappings[0].getGlobalName() + " = " + mappings[0].getLocalName() + ";\n");
+    }
+    builder.append("})();");
+
+    eval(builder.toString());
+  }
+
+  private native void eval(String js) /*-{
+    eval(js);
+  }-*/;
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/server/JavaBenchmarkLauncher.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/server/JavaBenchmarkLauncher.java
new file mode 100644
index 0000000..cb6248b
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/server/JavaBenchmarkLauncher.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2014 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.benchmark.framework.server;
+
+import com.google.gwt.benchmark.framework.shared.AbstractBenchmark;
+import com.google.gwt.benchmark.framework.shared.BenchmarkExecutor;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Runs a benchmark directly on the JVM.
+ */
+public class JavaBenchmarkLauncher {
+
+  public static void main(String[] args) {
+    // Validate arguments
+    if(args.length != 1) {
+      System.out.println("Usage: JavaEntryPoint <BenchmarkClass>");
+      System.exit(1);
+    }
+    String benchmarkClassName = args[0];
+
+    // Instantiate Benchmark
+    AbstractBenchmark benchmark = null;
+    try {
+      benchmark = getBenchmark(benchmarkClassName);
+    } catch (Exception e) {
+      System.out.println(String.format("Can't instantiate class %s", benchmarkClassName));
+      e.printStackTrace();
+      System.exit(1);
+    }
+
+    // Execute Benchmark
+    BenchmarkExecutor executor = new BenchmarkExecutor();
+    BenchmarkResult benchmarkResult = executor.executeWithFixedTime(benchmark);
+    double runsPerSecond =
+        (benchmarkResult.getNumberOfRuns() * 1000) / benchmarkResult.getTotalTimePassedMs();
+    System.out.println(benchmark.getName() + ": " + runsPerSecond);
+  }
+
+  private static AbstractBenchmark getBenchmark(String className) throws Exception {
+    Class<?> clazz = Class.forName(className);
+    Constructor<?> ctor = clazz.getConstructor();
+    AbstractBenchmark abstractBenchmark = (AbstractBenchmark) ctor.newInstance();
+    return abstractBenchmark;
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/AbstractBenchmark.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/AbstractBenchmark.java
new file mode 100644
index 0000000..6901377
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/AbstractBenchmark.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+/**
+ * Base class for all benchmarks.
+ * <p>
+ * If you want to write a benchmark you will need to extend from this class.
+ */
+public abstract class AbstractBenchmark {
+
+  private final String name;
+
+  public AbstractBenchmark(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Get the name of the benchmark.
+   * @return the name of the benchmark
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Run is called repeatedly by the benchmark framework.
+   * <p>
+   * In general a benchmark should return an object that has been calculated in
+   * the benchmark, so that it will be impossible for GWT / JavaScript engines to
+   * precalculate results of a benchmark. The returned object will be stored by the
+   * benchmark system.
+   * @return the object that should be stored by the benchmark system.
+   */
+  public abstract Object run();
+
+  /**
+   * Called every time before {@link #run()} is called.
+   */
+  public void setup() {
+  }
+
+  /**
+   * Called one time before the benchmark is executed.
+   */
+  public void setupOneTime() {
+  }
+
+  /**
+   * Called every time after {@link #run()} has been called.
+   */
+  public void tearDown() {
+  }
+
+  /**
+   * Called one time after the benchmark is executed.
+   */
+  public void tearDownOneTime() {
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java
new file mode 100644
index 0000000..f76a463
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+import com.google.gwt.benchmark.collection.shared.CollectionFactory;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArray;
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+
+/**
+ * The BenchmarkExecutor executes benchmarks and measures their performance.
+ */
+public class BenchmarkExecutor {
+
+  private Performance performance;
+
+  public BenchmarkExecutor() {
+    performance = PerformanceFactory.create();
+  }
+
+  public BenchmarkResult executeWithFixedTime(AbstractBenchmark benchmark) {
+
+    benchmark.setupOneTime();
+    // Give the vm a chance to warm up
+    runBenchmarkForAtLeast(benchmark, 100, 2);
+
+    // At least 2 seconds and 2 runs
+    BenchmarkResult benchmarkResult = runBenchmarkForAtLeast(benchmark, 2000, 2);
+    benchmark.tearDownOneTime();
+
+    return benchmarkResult;
+  }
+
+  private BenchmarkResult runBenchmarkForAtLeast(AbstractBenchmark benchmark,
+      double minimalTime, int minimalRuns) {
+
+    double startMs = performance.now();
+    double minimalEnd = startMs + minimalTime;
+
+    int runs = 0;
+    JavaScriptArray<Object> array = CollectionFactory.create();
+    JavaScriptArrayNumber times = CollectionFactory.createNumber();
+
+    while (runs <= minimalRuns || performance.now() < minimalEnd) {
+      benchmark.setup();
+      double currentMs = performance.now();
+      Object result = benchmark.run();
+      array.push(result);
+      times.push(performance.now() - currentMs);
+      runs++;
+      benchmark.tearDown();
+    }
+
+    double tookMs = performance.now() - startMs;
+
+    // Keep GWT compiler / JavaScript engine from removing code
+    Util.disableOpt(array);
+
+    BenchmarkResult benchmarkResult = BenchmarkResultFactory.create();
+    benchmarkResult.setName(benchmark.getName());
+    benchmarkResult.setNumberOfRuns(runs);
+    benchmarkResult.setTimesForIndividualRunsMs(times);
+    benchmarkResult.setTotalTimePassed(tookMs);
+    return benchmarkResult;
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResult.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResult.java
new file mode 100644
index 0000000..53f6040
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResult.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+
+/**
+ * A benchmark result contains all information for an executed benchmark.
+ */
+public interface BenchmarkResult {
+  /**
+   * Returns the name of the benchmark.
+   */
+  String getName();
+
+  /**
+   * Returns the number of times the benchmark was run.
+   */
+  int getNumberOfRuns();
+
+  /**
+   * Returns the {@link JavaScriptArrayNumber} containing times of individual runs.
+   */
+  JavaScriptArrayNumber getTimesForIndividualRunsMs();
+
+  /**
+   * Returns the time it took to execute the benchmark in milliseconds
+   */
+  double getTotalTimePassedMs();
+
+  /**
+   * Sets the name of the benchmark.
+   */
+  void setName(String name);
+
+  /**
+   * Sets how many times a benchmark was run.
+   */
+  void setNumberOfRuns(int runs);
+
+  /**
+   * Sets the {@link JavaScriptArrayNumber} that contains all times for individual runs.
+   */
+  void setTimesForIndividualRunsMs(JavaScriptArrayNumber numbers);
+
+  /**
+   * Sets how much time it took to execute the benchmark in milliseconds.
+   */
+  void setTotalTimePassed(double time);
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResultFactory.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResultFactory.java
new file mode 100644
index 0000000..575e1e2
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkResultFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+import com.google.gwt.benchmark.framework.client.BenchmarkResultJsImpl;
+import com.google.gwt.benchmark.framework.shared.ui.BenchmarkResultJavaImpl;
+import com.google.gwt.core.client.GWT;
+
+/**
+ * Factory to create {@link BenchmarkResult}.
+ */
+public class BenchmarkResultFactory {
+  /**
+   * Create a {@link BenchmarkResult}.
+   *
+   * @return the created {@link BenchmarkResult}
+   */
+  public static BenchmarkResult create() {
+    if (GWT.isScript()) {
+      return BenchmarkResultJsImpl.create();
+    } else {
+      return new BenchmarkResultJavaImpl();
+    }
+  }
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Performance.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Performance.java
new file mode 100644
index 0000000..cbd08b2
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Performance.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+/**
+ * Abstraction for current time.
+ *
+ * Implementations should use window.performance.now if available otherwise fall back to
+ * {@link System#currentTimeMillis()}.
+ */
+public interface Performance {
+  /**
+   * Get the current (relative) time.
+   *
+   * <p>The time is not guaranteed to be absolute to 1. Jan 1970.
+   *
+   * @return the current relative time.
+   */
+  public double now();
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/PerformanceFactory.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/PerformanceFactory.java
new file mode 100644
index 0000000..f217c22
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/PerformanceFactory.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+import com.google.gwt.core.client.GWT;
+
+/**
+ * Factory to create {@link Performance}.
+ * <p>
+ * When running on a JVM an implementation is used based on {@link System#currentTimeMillis()},
+ * when running in JavaScript a feature check for window.performance.now is made and might
+ * get polyfilled using {@link System#currentTimeMillis()}.
+ */
+public final class PerformanceFactory {
+
+  private static class PerformanceDefaultImpl implements Performance {
+    public double now() {
+      return System.currentTimeMillis();
+    }
+  }
+
+  private static class PerformanceWindowPerformanceImpl implements Performance {
+    public native double now() /*-{
+      return $wnd.performance.now();
+    }-*/;
+  }
+
+  public static Performance create() {
+    if (GWT.isScript() && hasPerformance()) {
+      return new PerformanceWindowPerformanceImpl();
+    } else {
+      return new PerformanceDefaultImpl();
+    }
+  }
+
+  private static native boolean hasPerformance() /*-{
+    return !!$wnd.performance && !!$wnd.performance.now;
+  }-*/;
+
+  private PerformanceFactory() {}
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Util.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Util.java
new file mode 100644
index 0000000..cb19491
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/Util.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+import com.google.gwt.core.client.GWT;
+
+public class Util {
+
+  /**
+   * Placing results of a benchmark on a global static field should effectly disable any bad
+   * optimizations since the field could be read by another class that might get loaded later.
+   */
+  public static Object disableOptField;
+
+  public static void disableOpt(Object o) {
+    if(GWT.isScript()) {
+      disableOptGwt(o);
+    } else {
+      disableOptField = o;
+    }
+  }
+
+  private static native void disableOptGwt(Object o) /*-{
+    if(!$wnd.__private_disableOpt) {
+      $wnd.__private_disableOpt = function(){};
+    }
+    $wnd.__private_disableOpt(o);
+  }-*/;
+}
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/ui/BenchmarkResultJavaImpl.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/ui/BenchmarkResultJavaImpl.java
new file mode 100644
index 0000000..72b3d93
--- /dev/null
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/ui/BenchmarkResultJavaImpl.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared.ui;
+
+import com.google.gwt.benchmark.collection.shared.JavaScriptArrayNumber;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+
+/**
+ * Java implementation of {@link BenchmarkResult}.
+ */
+public class BenchmarkResultJavaImpl implements BenchmarkResult {
+
+  private int numberOfRuns;
+  private double totalTimePassedMs;
+  private JavaScriptArrayNumber timesForIndividualRunsMs;
+  private String name;
+
+  public String getName() {
+    return name;
+  }
+
+  public int getNumberOfRuns() {
+    return numberOfRuns;
+  }
+
+  public JavaScriptArrayNumber getTimesForIndividualRunsMs() {
+    return timesForIndividualRunsMs;
+  }
+
+  public double getTotalTimePassedMs() {
+    return totalTimePassedMs;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public void setNumberOfRuns(int numberOfRuns) {
+    this.numberOfRuns = numberOfRuns;
+  }
+
+  public void setTimesForIndividualRunsMs(JavaScriptArrayNumber timesForIndividualRunsMs) {
+    this.timesForIndividualRunsMs = timesForIndividualRunsMs;
+  }
+
+  public void setTotalTimePassed(double time) {
+    this.totalTimePassedMs = time;
+  }
+}
diff --git a/benchmarks/src/test/java/com/google/gwt/benchmark/framework/client/BenchmarkFrameworkGwtTest.java b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/client/BenchmarkFrameworkGwtTest.java
new file mode 100644
index 0000000..df55659
--- /dev/null
+++ b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/client/BenchmarkFrameworkGwtTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2014 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.benchmark.framework.client;
+
+import com.google.gwt.benchmark.framework.shared.BenchmarkExecutor;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+import com.google.gwt.benchmark.framework.shared.MockBenchmark;
+import com.google.gwt.junit.client.GWTTestCase;
+
+/**
+ * IntegrationTest for the Benchmark framework running in JavaScript.
+ */
+public class BenchmarkFrameworkGwtTest extends GWTTestCase {
+
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.benchmark.framework.BenchmarkFramework";
+  }
+
+  public void test() {
+    MockBenchmark benchmark = new MockBenchmark();
+    BenchmarkExecutor executor = new BenchmarkExecutor();
+    BenchmarkResult benchmarkResult = executor.executeWithFixedTime(benchmark);
+    assertEquals(2000, benchmarkResult.getTotalTimePassedMs(), 100);
+    assertEquals(40, benchmarkResult.getNumberOfRuns(), 2);
+    assertTrue(benchmark.isTearDownOneTimeCalled());
+  }
+}
diff --git a/benchmarks/src/test/java/com/google/gwt/benchmark/framework/server/BenchmarkFrameworkTest.java b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/server/BenchmarkFrameworkTest.java
new file mode 100644
index 0000000..d02c433
--- /dev/null
+++ b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/server/BenchmarkFrameworkTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2014 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.benchmark.framework.server;
+
+import com.google.gwt.benchmark.framework.shared.BenchmarkExecutor;
+import com.google.gwt.benchmark.framework.shared.BenchmarkResult;
+import com.google.gwt.benchmark.framework.shared.MockBenchmark;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * IntegrationTest for the Benchmark framework running in Java.
+ */
+public class BenchmarkFrameworkTest {
+
+  @Test
+  public void test() {
+    MockBenchmark benchmark = new MockBenchmark();
+    BenchmarkExecutor executor = new BenchmarkExecutor();
+    BenchmarkResult benchmarkResult = executor.executeWithFixedTime(benchmark);
+    Assert.assertEquals(2000, benchmarkResult.getTotalTimePassedMs(), 100);
+    Assert.assertEquals(40, benchmarkResult.getNumberOfRuns(), 2);
+    Assert.assertTrue(benchmark.isTearDownOneTimeCalled());
+  }
+}
diff --git a/benchmarks/src/test/java/com/google/gwt/benchmark/framework/shared/MockBenchmark.java b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/shared/MockBenchmark.java
new file mode 100644
index 0000000..f190303
--- /dev/null
+++ b/benchmarks/src/test/java/com/google/gwt/benchmark/framework/shared/MockBenchmark.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2014 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.benchmark.framework.shared;
+
+/**
+ * A MockBenchmark with a known timing that is used for testing.
+ */
+public class MockBenchmark extends AbstractBenchmark {
+
+  private int counter = 0;
+  boolean firstTime = true;
+  private boolean runCalled;
+  private boolean setupOneTimeCalled;
+  private boolean setupCalled;
+  private boolean tearDownCalled;
+  private boolean tearDownOneTimeCalled;
+
+  public MockBenchmark() {
+    super("JavaBenchmark");
+  }
+
+  @Override
+  public void setupOneTime() {
+    if (setupOneTimeCalled) {
+      throw new IllegalStateException("setupOneTime called more than once");
+    }
+    setupOneTimeCalled = true;
+  }
+
+  @Override
+  public void setup() {
+    if (!setupOneTimeCalled) {
+      throw new IllegalStateException("setupOneTime not called before setup");
+    }
+    if (setupCalled) {
+      throw new IllegalStateException("setup called more than once");
+    }
+    setupCalled = true;
+
+    if (firstTime) {
+      firstTime = false;
+    } else {
+      if (!tearDownCalled) {
+        throw new IllegalStateException("tear down was not called before next setup");
+      }
+    }
+  }
+
+  @Override
+  public Object run() {
+    if (!setupCalled) {
+      throw new IllegalStateException("setup not called before bench");
+    }
+    setupCalled = false;
+    long end = System.currentTimeMillis() + 50;
+    while (System.currentTimeMillis() < end) {
+      // Busy waiting since we can not sleep in JavaScript
+    }
+    runCalled = true;
+    return counter++;
+  }
+
+  @Override
+  public void tearDown() {
+    if (!runCalled) {
+      throw new IllegalStateException("run not called before tearDown");
+    }
+    runCalled = false;
+    tearDownCalled = true;
+  }
+
+  @Override
+  public void tearDownOneTime() {
+    tearDownOneTimeCalled = true;
+  }
+
+  // Visible for testing
+  public boolean isTearDownOneTimeCalled() {
+    return tearDownOneTimeCalled;
+  }
+}
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..40eded3
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,16 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                             http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.google.gwt.benchmark</groupId>
+    <artifactId>gwt-benchmark-parent</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0-SNAPSHOT</version>
+    <name>GWT benchmarks parent project</name>
+
+    <modules>
+        <module>benchmarks</module>
+    </modules>
+</project>