Upgrade to latest (at the time of writing) version of Caliper

This does not upgrade to a released version of Caliper, it's
just a snapshot, see README.android for details.

Since 0.5-rc1 Caliper has gone through a huge number of changes
but it still does essentially the same job in the same way it
is just more flexible and capable than the previous version.

One major change that impacts the build is that this version
uses the Dagger2 dependency injection framework that generates
some of its code using annotation processors and so it was
necessary to change the build to use Dagger2.

Not all the Caliper tests run on Android, some are written for
the JVM and rely on some characteristic of it that is not the
same on Android, whether it be available memory, exception
message, supported classes or file structure. There are also a
couple of failures that are not completely explainable at the
moment. The details of these failures are listed in the
expectations/knownfailures.txt and will be addressed at a later
date.

Bug: 24848946
Change-Id: Ia245db56c57315ce18db8eb219003fecf3c64ab9
diff --git a/examples/pom.xml b/examples/pom.xml
index 7352d7b..0e904cb 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -1,19 +1,57 @@
-<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">
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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 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.
+  -->
+
+<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.caliper</groupId>
-  <artifactId>caliper-examples</artifactId>
-  <packaging>jar</packaging>
-  <version>0.5-rc1</version>
-  <inceptionYear>2009</inceptionYear>
-  <name>Caliper Examples</name>
   <parent>
     <groupId>org.sonatype.oss</groupId>
     <artifactId>oss-parent</artifactId>
-    <version>5</version>
+    <version>7</version>
   </parent>
-  <url>http://code.google.com/p/caliper/</url>
+
+  <groupId>com.google.caliper</groupId>
+  <artifactId>caliper-examples</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>jar</packaging>
+
+  <name>Caliper Examples</name>
   <description>Caliper Examples</description>
+
+  <url>http://code.google.com/p/caliper/</url>
+
+  <inceptionYear>2009</inceptionYear>
+
+  <organization>
+    <name>Google Inc.</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <developers>
+    <developer>
+      <name>Gregory Kick</name>
+      <organization>Google Inc.</organization>
+    </developer>
+    <developer>
+      <name>Jesse Wilson</name>
+    </developer>
+  </developers>
+
   <licenses>
     <license>
       <name>The Apache Software License, Version 2.0</name>
@@ -21,24 +59,23 @@
       <distribution>repo</distribution>
     </license>
   </licenses>
+
   <scm>
     <connection>scm:git:http://code.google.com/p/caliper/examples</connection>
     <developerConnection>scm:git:git:http://code.google.com/p/caliper/examples</developerConnection>
     <url>http://caliper.codegoogle.com/svn/trunk/examples</url>
   </scm>
+
   <issueManagement>
     <system>Google Code Issue Tracking</system>
     <url>http://code.google.com/p/caliper/issues/list</url>
   </issueManagement>
-  <organization>
-    <name>Google, Inc.</name>
-    <url>http://www.google.com</url>
-  </organization>
+
   <dependencies>
     <dependency>
       <groupId>com.google.caliper</groupId>
       <artifactId>caliper</artifactId>
-      <version>0.5-rc1</version>
+      <version>1.0-SNAPSHOT</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
@@ -47,13 +84,14 @@
       <scope>test</scope>
     </dependency>
   </dependencies>
+
   <build>
     <defaultGoal>package</defaultGoal>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
-        <version>2.3.2</version>
+        <version>3.2</version>
         <configuration>
           <source>1.6</source>
           <target>1.6</target>
@@ -62,7 +100,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-eclipse-plugin</artifactId>
-        <version>2.8</version>
+        <version>2.9</version>
         <configuration>
           <downloadSources>true</downloadSources>
           <downloadJavadocs>true</downloadJavadocs>
@@ -72,17 +110,12 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-release-plugin</artifactId>
-        <version>2.1</version>
+        <version>2.5.1</version>
         <configuration>
           <arguments>-DenableCiProfile=true</arguments>
         </configuration>
       </plugin>
     </plugins>
   </build>
-  <developers>
-    <developer>
-      <name>Jesse Wilson</name>
-      <organization>Google Inc.</organization>
-    </developer>
-  </developers>
+
 </project>
diff --git a/examples/src/main/java/examples/ArraySortBenchmark.java b/examples/src/main/java/examples/ArraySortBenchmark.java
index f42390f..81be2a6 100644
--- a/examples/src/main/java/examples/ArraySortBenchmark.java
+++ b/examples/src/main/java/examples/ArraySortBenchmark.java
@@ -16,16 +16,17 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+
 import java.util.Arrays;
 import java.util.Random;
 
 /**
  * Measures sorting on different distributions of integers.
  */
-public class ArraySortBenchmark extends SimpleBenchmark {
+public class ArraySortBenchmark {
 
   @Param({"10", "100", "1000", "10000"}) private int length;
 
@@ -34,12 +35,12 @@
   private int[] values;
   private int[] copy;
 
-  @Override protected void setUp() throws Exception {
+  @BeforeExperiment void setUp() throws Exception {
     values = distribution.create(length);
     copy = new int[length];
   }
 
-  public void timeSort(int reps) {
+  @Benchmark void sort(int reps) {
     for (int i = 0; i < reps; i++) {
       System.arraycopy(values, 0, copy, 0, values.length);
       Arrays.sort(copy);
@@ -95,8 +96,4 @@
 
     abstract int[] create(int length);
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(ArraySortBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/BitSetBenchmark.java b/examples/src/main/java/examples/BitSetBenchmark.java
index 3154b01..98cdcc8 100644
--- a/examples/src/main/java/examples/BitSetBenchmark.java
+++ b/examples/src/main/java/examples/BitSetBenchmark.java
@@ -16,8 +16,10 @@
 
 package examples;
 
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+
 import java.util.BitSet;
 import java.util.Random;
 
@@ -44,17 +46,17 @@
  * BaselineIteration   68 XX|||||||||||||||||
  * </pre>
  *
- * <p>Initially things look simple. The {@link #timeSetBitSetX64(int)} benchmark
- * takes approximately twice as long as {@link #timeSetMaskX64(int)}. However
+ * <p>Initially things look simple. The {@link #setBitSetX64(int)} benchmark
+ * takes approximately twice as long as {@link #setMaskX64(int)}. However
  * the inner loops in these benchmarks have almost no content, so a more
  * 'real world' benchmark was devised in an attempt to back up these results.
  *
- * <p>The {@link #timeCharsToMask(int)} and {@link #timeCharsToBitSet(int)}
+ * <p>The {@link #charsToMask(int)} and {@link #charsToBitSet(int)}
  * benchmarks convert a simple char[] of '1's and '0's to a corresponding BitSet
  * or bit mask. These also processes 64 bits per iteration and so appears to be
  * doing the same amount of work as the first benchmarks.
  *
- * <p>Additionally the {@link BitSetBenchmark#timeBaselineIteration(int)}
+ * <p>Additionally the {@link BitSetBenchmark#baselineIteration(int)}
  * benchmark attempts to measure the raw cost of looping through and reading the
  * source data.
  *
@@ -83,11 +85,11 @@
  * <p><b>2:</b>Overly simplistic benchmarks can give a very false impression of
  * performance.
  */
-public class BitSetBenchmark extends SimpleBenchmark {
+public class BitSetBenchmark {
   private BitSet bitSet;
   private char[] bitString;
 
-  @Override protected void setUp() throws Exception {
+  @BeforeExperiment void setUp() throws Exception {
     bitSet = new BitSet(64);
     bitString = new char[64];
     Random r = new Random();
@@ -99,7 +101,7 @@
   /**
    * This benchmark attempts to measure performance of {@link BitSet#set}.
    */
-  public int timeSetBitSetX64(int reps) {
+  @Benchmark int setBitSetX64(int reps) {
     long count = 64L * reps;
     for (int i = 0; i < count; i++) {
       bitSet.set(i & 0x3F, true);
@@ -110,7 +112,7 @@
   /**
    * This benchmark attempts to measure performance of direct bit-manipulation.
    */
-  public long timeSetMaskX64(int reps) {
+  @Benchmark long setMaskX64(int reps) {
     long count = 64L * reps;
     long bitMask = 0L;
     for (int i = 0; i < count; i++) {
@@ -122,9 +124,9 @@
   /**
    * This benchmark parses a char[] of 1's and 0's into a BitSet. Results from
    * this benchmark should be comparable with those from
-   * {@link #timeCharsToMask(int)}.
+   * {@link #charsToMask(int)}.
    */
-  public String timeCharsToBitSet(int reps) {
+  @Benchmark String charsToBitSet(int reps) {
     /*
      * This benchmark now measures the complete parsing of a char[] rather than
      * a single invocation of {@link BitSet#set}. However this fine because
@@ -141,9 +143,9 @@
   /**
    * This benchmark parses a char[] of 1's and 0's into a bit mask. Results from
    * this benchmark should be comparable with those from
-   * {@link #timeCharsToBitSet(int)}.
+   * {@link #charsToBitSet(int)}.
    */
-  public long timeCharsToMask(int reps) {
+  @Benchmark long charsToMask(int reps) {
     /*
      * Comparing results we see a far more realistic sounding result whereby
      * using a bit mask is a little over 4x faster than using BitSet.
@@ -164,12 +166,12 @@
 
   /**
    * This benchmark attempts to measure the baseline cost of both
-   * {@link #timeCharsToBitSet(int)} and {@link #timeCharsToMask(int)}.
+   * {@link #charsToBitSet(int)} and {@link #charsToMask(int)}.
    * It does this by unconditionally summing the character values of the char[].
    * This is as close to a no-op case as we can expect to get without unwanted
    * over-optimization.
    */
-  public long timeBaselineIteration(int reps) {
+  @Benchmark long baselineIteration(int reps) {
     int badHash = 0;
     for (int i = 0; i < reps; i++) {
       for (int n = 0; n < bitString.length; n++) {
@@ -178,9 +180,4 @@
     }
     return badHash;
   }
-
-  // TODO: remove this from all examples when IDE plugins are ready
-  public static void main(String[] args) throws Exception {
-      Runner.main(BitSetBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/CharacterBenchmark.java b/examples/src/main/java/examples/CharacterBenchmark.java
index 1e013af..82c4439 100644
--- a/examples/src/main/java/examples/CharacterBenchmark.java
+++ b/examples/src/main/java/examples/CharacterBenchmark.java
@@ -16,15 +16,15 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 /**
  * Tests various Character methods, intended for testing multiple
  * implementations against each other.
  */
-public class CharacterBenchmark extends SimpleBenchmark {
+public class CharacterBenchmark {
 
     @Param private CharacterSet characterSet;
 
@@ -32,7 +32,7 @@
 
     private char[] chars;
 
-    @Override protected void setUp() throws Exception {
+    @BeforeExperiment void setUp() throws Exception {
         this.chars = characterSet.chars;
     }
 
@@ -51,7 +51,7 @@
     }
 
     // A fake benchmark to give us a baseline.
-    public boolean timeIsSpace(int reps) {
+    @Benchmark boolean isSpace(int reps) {
         boolean dummy = false;
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
@@ -69,7 +69,7 @@
         return dummy;
     }
 
-    public void timeDigit(int reps) {
+    @Benchmark void digit(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -85,7 +85,7 @@
         }
     }
 
-    public void timeGetNumericValue(int reps) {
+    @Benchmark void getNumericValue(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -101,7 +101,7 @@
         }
     }
 
-    public void timeIsDigit(int reps) {
+    @Benchmark void isDigit(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -117,7 +117,7 @@
         }
     }
 
-    public void timeIsIdentifierIgnorable(int reps) {
+    @Benchmark void isIdentifierIgnorable(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -133,7 +133,7 @@
         }
     }
 
-    public void timeIsJavaIdentifierPart(int reps) {
+    @Benchmark void isJavaIdentifierPart(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -149,7 +149,7 @@
         }
     }
 
-    public void timeIsJavaIdentifierStart(int reps) {
+    @Benchmark void isJavaIdentifierStart(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -165,7 +165,7 @@
         }
     }
 
-    public void timeIsLetter(int reps) {
+    @Benchmark void isLetter(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -181,7 +181,7 @@
         }
     }
 
-    public void timeIsLetterOrDigit(int reps) {
+    @Benchmark void isLetterOrDigit(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -197,7 +197,7 @@
         }
     }
 
-    public void timeIsLowerCase(int reps) {
+    @Benchmark void isLowerCase(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -213,7 +213,7 @@
         }
     }
 
-    public void timeIsSpaceChar(int reps) {
+    @Benchmark void isSpaceChar(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -229,7 +229,7 @@
         }
     }
 
-    public void timeIsUpperCase(int reps) {
+    @Benchmark void isUpperCase(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -245,7 +245,7 @@
         }
     }
 
-    public void timeIsWhitespace(int reps) {
+    @Benchmark void isWhitespace(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -261,7 +261,7 @@
         }
     }
 
-    public void timeToLowerCase(int reps) {
+    @Benchmark void toLowerCase(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -277,7 +277,7 @@
         }
     }
 
-    public void timeToUpperCase(int reps) {
+    @Benchmark void toUpperCase(int reps) {
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
@@ -292,9 +292,4 @@
             }
         }
     }
-
-    // TODO: remove this from all examples when IDE plugins are ready
-    public static void main(String[] args) throws Exception {
-        Runner.main(CharacterBenchmark.class, args);
-    }
 }
diff --git a/examples/src/main/java/examples/CompressionSizeBenchmark.java b/examples/src/main/java/examples/CompressionSizeBenchmark.java
index 90ddd39..d4fed5e 100644
--- a/examples/src/main/java/examples/CompressionSizeBenchmark.java
+++ b/examples/src/main/java/examples/CompressionSizeBenchmark.java
@@ -16,10 +16,9 @@
 
 package examples;
 
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.api.Benchmark;
 import com.google.caliper.model.ArbitraryMeasurement;
-import com.google.caliper.runner.CaliperMain;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -30,7 +29,7 @@
 /**
  * Example "arbitrary measurement" benchmark.
  */
-public class CompressionSizeBenchmark extends Benchmark {
+public class CompressionSizeBenchmark {
 
   @Param({
       "this string will compress badly",
@@ -50,7 +49,7 @@
       compressionLevelMap.put("huffmanOnly", Deflater.HUFFMAN_ONLY);
   }
 
-  public long timeSimpleCompression(int reps) {
+  @Benchmark long simpleCompression(int reps) {
     long dummy = 0;
     for (int i = 0; i < reps; i++) {
       dummy += compress(toCompress.getBytes()).length;
@@ -83,8 +82,4 @@
     }
     return bos.toByteArray();
   }
-
-  public static void main(String[] args) {
-    CaliperMain.main(CompressionSizeBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/ContainsBenchmark.java b/examples/src/main/java/examples/ContainsBenchmark.java
index 01bb8c6..26d2eb9 100644
--- a/examples/src/main/java/examples/ContainsBenchmark.java
+++ b/examples/src/main/java/examples/ContainsBenchmark.java
@@ -16,20 +16,19 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Random;
 import java.util.Set;
 
-public class ContainsBenchmark extends SimpleBenchmark {
+public class ContainsBenchmark {
   @Param({"0", "25", "50", "75", "100"}) private int percentNulls;
   @Param({"100", "1000", "10000"}) private int containsPerRep;
 
@@ -39,7 +38,7 @@
   /** twenty-five percent nulls */
   private final List<Object> queries = new ArrayList<Object>();
 
-  @Override protected void setUp() {
+  @BeforeExperiment void setUp() {
     set.addAll(Arrays.asList("str1", "str2", "str3", "str4"));
     int nullThreshold = percentNulls * containsPerRep / 100;
     for (int i = 0; i < nullThreshold; i++) {
@@ -51,28 +50,11 @@
     Collections.shuffle(queries, new Random(0));
   }
 
-  @Override public Map<String, Integer> getTimeUnitNames() {
-    Map<String, Integer> unitNames = new HashMap<String, Integer>();
-    unitNames.put("ns/contains", 1);
-    unitNames.put("us/contains", 1000);
-    unitNames.put("ms/contains", 1000000);
-    unitNames.put("s/contains", 1000000000);
-    return unitNames;
-  }
-
-  @Override public double nanosToUnits(double nanos) {
-    return nanos / containsPerRep;
-  }
-
-  public void timeContains(int reps) {
+  @Benchmark void contains(int reps) {
     for (int i = 0; i < reps; i++) {
       for (Object query : queries) {
         set.contains(query);
       }
     }
   }
-
-  public static void main(String[] args) {
-    Runner.main(ContainsBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/CopyArrayBenchmark.java b/examples/src/main/java/examples/CopyArrayBenchmark.java
index fed0950..543db5b 100644
--- a/examples/src/main/java/examples/CopyArrayBenchmark.java
+++ b/examples/src/main/java/examples/CopyArrayBenchmark.java
@@ -16,9 +16,9 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 import java.util.Arrays;
 import java.util.Random;
@@ -44,7 +44,7 @@
  *     memory (boolean arrays count as byte arrays!).
  * </ul>
  */
-public class CopyArrayBenchmark extends SimpleBenchmark {
+public class CopyArrayBenchmark {
   public enum Strategy {
     CLONE {
       @Override Object[] copy(Object[] array) {
@@ -252,7 +252,7 @@
   long[] longArray;
   short[] shortArray;
 
-  @Override protected void setUp() {
+  @BeforeExperiment void setUp() {
     objectArray = new Object[size];
     booleanArray = new boolean[size];
     byteArray = new byte[size];
@@ -271,86 +271,82 @@
       byteArray[i] = (byte) num;
       charArray[i] = (char) num;
       doubleArray[i] = num;
-      floatArray[i] = (float) num;
+      floatArray[i] = num;
       intArray[i] = num;
       longArray[i] = num;
       shortArray[i] = (short) num;
     }
   }
 
-  public int timeObjects(int reps) {
+  @Benchmark int objects(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(objectArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(objectArray));
     }
     return dummy;
   }
 
-  public int timeBooleans(int reps) {
+  @Benchmark int booleans(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(booleanArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(booleanArray));
     }
     return dummy;
   }
 
-  public int timeBytes(int reps) {
+  @Benchmark int bytes(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(byteArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(byteArray));
     }
     return dummy;
   }
 
-  public int timeChars(int reps) {
+  @Benchmark int chars(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(charArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(charArray));
     }
     return dummy;
   }
 
-  public int timeDoubles(int reps) {
+  @Benchmark int doubles(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(doubleArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(doubleArray));
     }
     return dummy;
   }
 
-  public int timeFloats(int reps) {
+  @Benchmark int floats(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(floatArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(floatArray));
     }
     return dummy;
   }
 
-  public int timeInts(int reps) {
+  @Benchmark int ints(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(intArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(intArray));
     }
     return dummy;
   }
 
-  public int timeLongs(int reps) {
+  @Benchmark int longs(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(longArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(longArray));
     }
     return dummy;
   }
 
-  public int timeShorts(int reps) {
+  @Benchmark int shorts(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
-      dummy += strategy.copy(shortArray).hashCode();
+      dummy += System.identityHashCode(strategy.copy(shortArray));
     }
     return dummy;
   }
-
-  public static void main(String[] args) {
-    Runner.main(CopyArrayBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/DemoBenchmark.java b/examples/src/main/java/examples/DemoBenchmark.java
index 3b7e2dd..3313eee 100644
--- a/examples/src/main/java/examples/DemoBenchmark.java
+++ b/examples/src/main/java/examples/DemoBenchmark.java
@@ -16,23 +16,24 @@
 
 package examples;
 
+import com.google.caliper.AfterExperiment;
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.api.Benchmark;
 import com.google.caliper.api.SkipThisScenarioException;
-import com.google.caliper.api.VmParam;
-import com.google.caliper.runner.CaliperMain;
+import com.google.caliper.api.VmOptions;
 import com.google.caliper.util.ShortDuration;
 
 import java.math.BigDecimal;
 
-public class DemoBenchmark extends Benchmark {
+@VmOptions("-server")
+public class DemoBenchmark {
   @Param({"abc", "def", "xyz"}) String string;
   @Param({"1", "2"}) int number;
   @Param Foo foo;
 
   @Param({"0.00", "123.45"}) BigDecimal money;
   @Param({"1ns", "2 minutes"}) ShortDuration duration;
-  @VmParam({"-Xmx32m", "-Xmx1g"}) String memoryMax;
 
   enum Foo {
     FOO, BAR, BAZ, QUX;
@@ -42,13 +43,13 @@
 //    System.out.println("I should not do this.");
   }
 
-  @Override protected void setUp() throws Exception {
+  @BeforeExperiment void setUp() throws Exception {
     if (string.equals("abc") && number == 1) {
       throw new SkipThisScenarioException();
     }
   }
 
-  public int timeSomething(int reps) {
+  @Benchmark int something(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
       dummy += i;
@@ -56,7 +57,7 @@
     return dummy;
   }
 
-  public int timeSomethingElse(int reps) {
+  @Benchmark int somethingElse(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
       dummy -= i;
@@ -64,11 +65,7 @@
     return dummy;
   }
 
-  @Override protected void tearDown() throws Exception {
+  @AfterExperiment void tearDown() throws Exception {
 //    System.out.println("Hey, I'm tearing up the joint.");
   }
-
-  public static void main(String[] args) {
-    CaliperMain.main(DemoBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/DoubleToStringBenchmark.java b/examples/src/main/java/examples/DoubleToStringBenchmark.java
index 291ec84..d28f9b0 100644
--- a/examples/src/main/java/examples/DoubleToStringBenchmark.java
+++ b/examples/src/main/java/examples/DoubleToStringBenchmark.java
@@ -16,17 +16,13 @@
 
 package examples;
 
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
-
-import java.util.Arrays;
-import java.util.List;
 
 /**
  * Measures the various ways the JDK converts doubles to strings.
  */
-public class DoubleToStringBenchmark extends SimpleBenchmark {
+public class DoubleToStringBenchmark {
   @Param Method method;
 
   public enum Method {
@@ -83,7 +79,7 @@
 
   @Param Value value;
 
-  public int timePrimitive(int reps) {
+  @Benchmark int primitive(int reps) {
     double d = value.value;
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
@@ -92,7 +88,7 @@
     return dummy;
   }
 
-  public int timeWrapper(int reps) {
+  @Benchmark int wrapper(int reps) {
     Double d = value.value;
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
@@ -100,8 +96,4 @@
     }
     return dummy;
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(DoubleToStringBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/DoubleToStringBenchmark2.java b/examples/src/main/java/examples/DoubleToStringBenchmark2.java
index 8e6c69a..3a6da5b 100644
--- a/examples/src/main/java/examples/DoubleToStringBenchmark2.java
+++ b/examples/src/main/java/examples/DoubleToStringBenchmark2.java
@@ -16,14 +16,13 @@
 
 package examples;
 
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 /**
  * Measures the various ways the JDK converts doubles to strings.
  */
-public class DoubleToStringBenchmark2 extends SimpleBenchmark {
+public class DoubleToStringBenchmark2 {
   @Param boolean useWrapper;
 
   enum Value {
@@ -41,7 +40,7 @@
 
   @Param Value value;
 
-  public int timeToString(int reps) {
+  @Benchmark int toString(int reps) {
     int dummy = 0;
     if (useWrapper) {
       Double d = value.d;
@@ -57,7 +56,7 @@
     return dummy;
   }
 
-  public int timeStringValueOf(int reps) {
+  @Benchmark int stringValueOf(int reps) {
     int dummy = 0;
     if (useWrapper) {
       Double d = value.d;
@@ -73,7 +72,7 @@
     return dummy;
   }
 
-  public int timeStringFormat(int reps) {
+  @Benchmark int stringFormat(int reps) {
     int dummy = 0;
     if (useWrapper) {
       Double d = value.d;
@@ -89,7 +88,7 @@
     return dummy;
   }
 
-  public int timeQuoteTrick(int reps) {
+  @Benchmark int quoteTrick(int reps) {
     int dummy = 0;
     if (useWrapper) {
       Double d = value.d;
@@ -104,8 +103,4 @@
     }
     return dummy;
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(DoubleToStringBenchmark2.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/EnumSetContainsBenchmark.java b/examples/src/main/java/examples/EnumSetContainsBenchmark.java
index b232514..10660a9 100644
--- a/examples/src/main/java/examples/EnumSetContainsBenchmark.java
+++ b/examples/src/main/java/examples/EnumSetContainsBenchmark.java
@@ -16,16 +16,17 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+
 import java.util.EnumSet;
 import java.util.Set;
 
 /**
  * Measures EnumSet#contains().
  */
-public class EnumSetContainsBenchmark extends SimpleBenchmark {
+public class EnumSetContainsBenchmark {
 
   @Param private SetMaker setMaker;
 
@@ -75,18 +76,14 @@
   private Set<?> set;
   private Object[] testValues;
 
-  @Override protected void setUp() {
+  @BeforeExperiment void setUp() {
     this.set = setMaker.newSet();
     this.testValues = setMaker.testValues();
   }
 
-  public void timeContains(int reps) {
+  @Benchmark void contains(int reps) {
     for (int i = 0; i < reps; i++) {
       set.contains(testValues[i % testValues.length]);
     }
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(EnumSetContainsBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/ExpensiveObjectsBenchmark.java b/examples/src/main/java/examples/ExpensiveObjectsBenchmark.java
index a11b1bd..7c4bc79 100644
--- a/examples/src/main/java/examples/ExpensiveObjectsBenchmark.java
+++ b/examples/src/main/java/examples/ExpensiveObjectsBenchmark.java
@@ -16,9 +16,7 @@
 
 package examples;
 
-import com.google.caliper.SimpleBenchmark;
-import com.google.caliper.runner.CaliperMain;
-
+import com.google.caliper.Benchmark;
 import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;
 import java.text.SimpleDateFormat;
@@ -28,49 +26,43 @@
  * Benchmarks creation and cloning various expensive objects.
  */
 @SuppressWarnings({"ResultOfObjectAllocationIgnored"}) // TODO: should fix!
-public class ExpensiveObjectsBenchmark extends SimpleBenchmark {
-  public void timeNewDecimalFormatSymbols(int reps) {
+public class ExpensiveObjectsBenchmark {
+  @Benchmark void newDecimalFormatSymbols(int reps) {
     for (int i = 0; i < reps; ++i) {
       new DecimalFormatSymbols(Locale.US);
     }
   }
 
-  public void timeClonedDecimalFormatSymbols(int reps) {
+  @Benchmark void clonedDecimalFormatSymbols(int reps) {
     DecimalFormatSymbols dfs = new DecimalFormatSymbols(Locale.US);
     for (int i = 0; i < reps; ++i) {
       dfs.clone();
     }
   }
 
-  public void timeNewNumberFormat(int reps) {
+  @Benchmark void newNumberFormat(int reps) {
     for (int i = 0; i < reps; ++i) {
       NumberFormat.getInstance(Locale.US);
     }
   }
 
-  public void timeClonedNumberFormat(int reps) {
+  @Benchmark void clonedNumberFormat(int reps) {
     NumberFormat nf = NumberFormat.getInstance(Locale.US);
     for (int i = 0; i < reps; ++i) {
       nf.clone();
     }
   }
 
-  public void timeNewSimpleDateFormat(int reps) {
+  @Benchmark void newSimpleDateFormat(int reps) {
     for (int i = 0; i < reps; ++i) {
       new SimpleDateFormat();
     }
   }
 
-  public void timeClonedSimpleDateFormat(int reps) {
+  @Benchmark void clonedSimpleDateFormat(int reps) {
     SimpleDateFormat sdf = new SimpleDateFormat();
     for (int i = 0; i < reps; ++i) {
       sdf.clone();
     }
   }
-
-  // TODO: remove this from all examples when IDE plugins are ready
-  public static void main(String[] args) throws Exception {
-    CaliperMain.main(ExpensiveObjectsBenchmark.class, args);
-//    Runner.main(ExpensiveObjectsBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/FormatterBenchmark.java b/examples/src/main/java/examples/FormatterBenchmark.java
index b4a0541..93ed936 100644
--- a/examples/src/main/java/examples/FormatterBenchmark.java
+++ b/examples/src/main/java/examples/FormatterBenchmark.java
@@ -16,36 +16,37 @@
 
 package examples;
 
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.Benchmark;
 import java.util.Formatter;
 
 /**
  * Compares Formatter against hand-written StringBuilder code.
  */
-public class FormatterBenchmark extends SimpleBenchmark {
-  public void timeFormatter_NoFormatting(int reps) {
+public class FormatterBenchmark {
+  @Benchmark void formatter_NoFormatting(int reps) {
     for (int i = 0; i < reps; i++) {
       Formatter f = new Formatter();
       f.format("this is a reasonably short string that doesn't actually need any formatting");
+      f.close();
     }
   }
 
-  public void timeStringBuilder_NoFormatting(int reps) {
+  @Benchmark void stringBuilder_NoFormatting(int reps) {
     for (int i = 0; i < reps; i++) {
       StringBuilder sb = new StringBuilder();
       sb.append("this is a reasonably short string that doesn't actually need any formatting");
     }
   }
 
-  public void timeFormatter_OneInt(int reps) {
+  @Benchmark void formatter_OneInt(int reps) {
     for (int i = 0; i < reps; i++) {
       Formatter f = new Formatter();
       f.format("this is a reasonably short string that has an int %d in it", i);
+      f.close();
     }
   }
 
-  public void timeStringBuilder_OneInt(int reps) {
+  @Benchmark void stringBuilder_OneInt(int reps) {
     for (int i = 0; i < reps; i++) {
       StringBuilder sb = new StringBuilder();
       sb.append("this is a reasonably short string that has an int ");
@@ -54,14 +55,15 @@
     }
   }
 
-  public void timeFormatter_OneString(int reps) {
+  @Benchmark void formatter_OneString(int reps) {
     for (int i = 0; i < reps; i++) {
       Formatter f = new Formatter();
       f.format("this is a reasonably short string that has a string %s in it", "hello");
+      f.close();
     }
   }
 
-  public void timeStringBuilder_OneString(int reps) {
+  @Benchmark void stringBuilder_OneString(int reps) {
     for (int i = 0; i < reps; i++) {
       StringBuilder sb = new StringBuilder();
       sb.append("this is a reasonably short string that has a string ");
@@ -69,8 +71,4 @@
       sb.append(" in it");
     }
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(FormatterBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/IntModBenchmark.java b/examples/src/main/java/examples/IntModBenchmark.java
index 55a119c..bed415f 100644
--- a/examples/src/main/java/examples/IntModBenchmark.java
+++ b/examples/src/main/java/examples/IntModBenchmark.java
@@ -16,17 +16,16 @@
 
 package examples;
 
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+import com.google.caliper.Benchmark;
 
 /**
  * Measures several candidate implementations for mod().
  */
 @SuppressWarnings("SameParameterValue")
-public class IntModBenchmark extends SimpleBenchmark {
+public class IntModBenchmark {
   private static final int M = (1 << 16) - 1;
 
-  public int timeConditional(int reps) {
+  @Benchmark int conditional(int reps) {
     int dummy = 5;
     for (int i = 0; i < reps; i++) {
       dummy += Integer.MAX_VALUE + conditionalMod(dummy, M);
@@ -39,7 +38,7 @@
     return r < 0 ? r + m : r;
   }
 
-  public int timeDoubleRemainder(int reps) {
+  @Benchmark int doubleRemainder(int reps) {
     int dummy = 5;
     for (int i = 0; i < reps; i++) {
       dummy += Integer.MAX_VALUE + doubleRemainderMod(dummy, M);
@@ -52,7 +51,7 @@
     return (int) ((a % m + (long) m) % m);
   }
 
-  public int timeRightShiftingMod(int reps) {
+  @Benchmark int rightShiftingMod(int reps) {
     int dummy = 5;
     for (int i = 0; i < reps; i++) {
       dummy += Integer.MAX_VALUE + rightShiftingMod(dummy, M);
@@ -66,7 +65,7 @@
      return (int) (r + (r >> 63 & m));
   }
 
-  public int timeLeftShiftingMod(int reps) {
+  @Benchmark int leftShiftingMod(int reps) {
     int dummy = 5;
     for (int i = 0; i < reps; i++) {
       dummy += Integer.MAX_VALUE + leftShiftingMod(dummy, M);
@@ -79,16 +78,11 @@
     return (int) ((a + ((long) m << 32)) % m);
   }
 
-  public int timeWrongMod(int reps) {
+  @Benchmark int wrongMod(int reps) {
     int dummy = 5;
     for (int i = 0; i < reps; i++) {
       dummy += Integer.MAX_VALUE + dummy % M;
     }
     return dummy;
   }
-
-  // TODO: remove this from all examples when IDE plugins are ready
-  public static void main(String[] args) throws Exception {
-    Runner.main(IntModBenchmark.class, args);
-  }
-}
\ No newline at end of file
+}
diff --git a/examples/src/main/java/examples/ListIterationBenchmark.java b/examples/src/main/java/examples/ListIterationBenchmark.java
index a8cfb05..07ae8eb 100644
--- a/examples/src/main/java/examples/ListIterationBenchmark.java
+++ b/examples/src/main/java/examples/ListIterationBenchmark.java
@@ -16,16 +16,17 @@
 
 package examples;
 
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
+
 import java.util.AbstractList;
 import java.util.List;
 
 /**
  * Measures iterating through list elements.
  */
-public class ListIterationBenchmark extends SimpleBenchmark {
+public class ListIterationBenchmark {
 
   @Param({"0", "10", "100", "1000"})
   private int length;
@@ -33,7 +34,7 @@
   private List<Object> list;
   private Object[] array;
 
-  @Override protected void setUp() {
+  @BeforeExperiment void setUp() {
     array = new Object[length];
     for (int i = 0; i < length; i++) {
       array[i] = new Object();
@@ -50,24 +51,23 @@
     };
   }
 
-  @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix
-  public void timeListIteration(int reps) {
+  @Benchmark int listIteration(int reps) {
+    int dummy = 0;
     for (int i = 0; i < reps; i++) {
       for (Object value : list) {
+        dummy |= value.hashCode();
       }
     }
+    return dummy;
   }
 
-  @SuppressWarnings({"UnusedDeclaration"}) // TODO: fix
-  public void timeArrayIteration(int reps) {
+  @Benchmark int arrayIteration(int reps) {
+    int dummy = 0;
     for (int i = 0; i < reps; i++) {
       for (Object value : array) {
+        dummy |= value.hashCode();
       }
     }
-  }
-
-  // TODO: remove this from all examples when IDE plugins are ready
-  public static void main(String[] args) throws Exception {
-    Runner.main(ListIterationBenchmark.class, args);
+    return dummy;
   }
 }
\ No newline at end of file
diff --git a/examples/src/main/java/examples/ListModificationBenchmark.java b/examples/src/main/java/examples/ListModificationBenchmark.java
new file mode 100644
index 0000000..81d14f9
--- /dev/null
+++ b/examples/src/main/java/examples/ListModificationBenchmark.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 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 examples;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Measures performance of list operations.
+ */
+public class ListModificationBenchmark {
+
+  private enum Element {
+    INSTANCE,
+  }
+  private enum ListImpl {
+    Array {
+      @Override List<Element> create() {
+        return new ArrayList<Element>();
+      }
+    },
+    Linked {
+      @Override List<Element> create() {
+        return new LinkedList<Element>();
+      }
+    };
+
+    abstract List<Element> create();
+  }
+
+  @Param({"10", "100", "1000", "10000"})
+  private int size;
+
+  @Param({"Array", "Linked"})
+  private ListImpl implementation;
+
+  private List<Element> list;
+
+  @BeforeExperiment void setUp() throws Exception {
+    list = implementation.create();
+    for (int i = 0; i < size; i++) {
+      list.add(Element.INSTANCE);
+    }
+  }
+
+  @Benchmark void populate(int reps) throws Exception {
+    for (int rep = 0; rep < reps; rep++) {
+      List<Element> list = implementation.create();
+      for (int i = 0; i < size; i++) {
+        list.add(Element.INSTANCE);
+      }
+    }
+  }
+
+  @Benchmark void iteration(int reps) {
+    for (int rep = 0; rep < reps; rep++) {
+      Iterator<Element> iterator = list.iterator();
+      while (iterator.hasNext()) {
+        iterator.next();
+      }
+    }
+  }
+
+  @Benchmark void headAddRemove(int reps) {
+    for (int rep = 0; rep < reps; rep++) {
+      list.add(0, Element.INSTANCE);
+      list.remove(0);
+    }
+  }
+
+  @Benchmark void middleAddRemove(int reps) {
+    int index = size / 2;
+    for (int rep = 0; rep < reps; rep++) {
+      list.add(index, Element.INSTANCE);
+      list.remove(index);
+    }
+  }
+
+  @Benchmark void tailAddRemove(int reps) {
+    int index = size - 1;
+    for (int rep = 0; rep < reps; rep++) {
+      list.add(Element.INSTANCE);
+      list.remove(index);
+    }
+  }
+}
diff --git a/examples/src/main/java/examples/LoopingBackwardsBenchmark.java b/examples/src/main/java/examples/LoopingBackwardsBenchmark.java
index 1e3d1ad..d23a28d 100644
--- a/examples/src/main/java/examples/LoopingBackwardsBenchmark.java
+++ b/examples/src/main/java/examples/LoopingBackwardsBenchmark.java
@@ -16,17 +16,16 @@
 
 package examples;
 
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 /**
  * Testing the old canard that looping backwards is faster.
  */
-public class LoopingBackwardsBenchmark extends SimpleBenchmark {
+public class LoopingBackwardsBenchmark {
   @Param({"2", "20", "2000", "20000000"}) int max;
 
-  public int timeForwards(int reps) {
+  @Benchmark int forwards(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
       for (int j = 0; j < max; j++) {
@@ -36,7 +35,7 @@
     return dummy;
   }
 
-  public int timeBackwards(int reps) {
+  @Benchmark int backwards(int reps) {
     int dummy = 0;
     for (int i = 0; i < reps; i++) {
       for (int j = max - 1; j >= 0; j--) {
@@ -45,8 +44,4 @@
     }
     return dummy;
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(LoopingBackwardsBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/MessageDigestCreationBenchmark.java b/examples/src/main/java/examples/MessageDigestCreationBenchmark.java
index c9437bd..681d10e 100644
--- a/examples/src/main/java/examples/MessageDigestCreationBenchmark.java
+++ b/examples/src/main/java/examples/MessageDigestCreationBenchmark.java
@@ -16,29 +16,24 @@
 
 package examples;
 
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 import java.security.MessageDigest;
 
 /**
  * Times creating new MessageDigest instances.
  */
-public class MessageDigestCreationBenchmark extends SimpleBenchmark {
+public class MessageDigestCreationBenchmark {
   // By default, just the "interesting ones". Also consider Adler32 and CRC32,
   // but these are not guaranteed to be supported in all runtime environments.
   @Param({"MD5", "SHA-1", "SHA-256", "SHA-512"})
   String algorithm;
 
-  public void time(int reps) throws Exception {
+  @Benchmark void time(int reps) throws Exception {
     // Change this to use a dummy if the results look suspicious.
     for (int i = 0; i < reps; i++) {
       MessageDigest.getInstance(algorithm);
     }
   }
-
-  public static void main(String[] args) throws Exception {
-    Runner.main(MessageDigestCreationBenchmark.class, args);
-  }
 }
diff --git a/examples/src/main/java/examples/NoOpBenchmark.java b/examples/src/main/java/examples/NoOpBenchmark.java
new file mode 100644
index 0000000..fa24805
--- /dev/null
+++ b/examples/src/main/java/examples/NoOpBenchmark.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 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 examples;
+
+import com.google.caliper.Benchmark;
+
+/**
+ * This is the absolute minimal benchmark. It does nothing but time the rep loop.
+ */
+public class NoOpBenchmark {
+  @Benchmark long increment(long reps) {
+    long result = 0;
+    for (; result < reps; result++) {}
+    return result;
+  }
+}
diff --git a/examples/src/main/java/examples/StringBuilderBenchmark.java b/examples/src/main/java/examples/StringBuilderBenchmark.java
index 3c839d3..c39b3be 100644
--- a/examples/src/main/java/examples/StringBuilderBenchmark.java
+++ b/examples/src/main/java/examples/StringBuilderBenchmark.java
@@ -16,117 +16,176 @@
 
 package examples;
 
+import static java.lang.Character.MIN_SURROGATE;
+
+import com.google.caliper.Benchmark;
 import com.google.caliper.Param;
-import com.google.caliper.Runner;
-import com.google.caliper.SimpleBenchmark;
 
 /**
  * Tests the performance of various StringBuilder methods.
  */
-public class StringBuilderBenchmark extends SimpleBenchmark {
+public class StringBuilderBenchmark {
 
-    @Param({"1", "10", "100"}) private int length;
+  @Param({"1", "10", "100"}) private int length;
 
-    public void timeAppendBoolean(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(true);
-            }
+  @Benchmark void appendBoolean(int reps) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < reps; ++i) {
+      sb.setLength(0);
+      for (int j = 0; j < length; ++j) {
+        sb.append(true);
+        sb.append(false);
+      }
+    }
+  }
+
+  @Benchmark void appendChar(int reps) {
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append('c');
+      }
+    }
+  }
+
+  @Benchmark void appendCharArray(int reps) {
+    char[] chars = "chars".toCharArray();
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(chars);
+      }
+    }
+  }
+
+  @Benchmark void appendCharSequence(int reps) {
+    CharSequence cs = "chars";
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(cs);
+      }
+    }
+  }
+
+  @Benchmark void appendDouble(int reps) {
+    double d = 1.2;
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(d);
+      }
+    }
+  }
+
+  @Benchmark void appendFloat(int reps) {
+    float f = 1.2f;
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(f);
+      }
+    }
+  }
+
+  @Benchmark void appendInt(int reps) {
+    int n = 123;
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(n);
+      }
+    }
+  }
+
+  @Benchmark void appendLong(int reps) {
+    long l = 123;
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(l);
+      }
+    }
+  }
+
+  @Benchmark void appendObject(int reps) {
+    Object o = new Object();
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(o);
+      }
+    }
+  }
+
+  @Benchmark void appendString(int reps) {
+    String s = "chars";
+    for (int i = 0; i < reps; ++i) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < length; ++j) {
+        sb.append(s);
+      }
+    }
+  }
+
+  @Benchmark void appendNull(int reps) {
+    StringBuilder sb = new StringBuilder();
+    for (int i = 0; i < reps; ++i) {
+      sb.setLength(0);
+      for (int j = 0; j < length; ++j) {
+        sb.append((String)null);
+        sb.append((StringBuilder)null);
+      }
+    }
+  }
+
+  /** Times .reverse() when no surrogates are present. */
+  @Benchmark void reverseNoSurrogates(int reps) {
+    final int length = Math.min(this.length, MIN_SURROGATE);
+    StringBuilder sb = new StringBuilder();
+    for (int j = 0; j < length; j++) {
+      sb.appendCodePoint(j);
+    }
+    for (int i = 0; i < reps; i++) {
+      for (int j = 0; j < 4; j++) {
+        sb.reverse();
+      }
+      if (sb.codePointAt(0) > MIN_SURROGATE)
+        throw new Error();
+    }
+  }
+
+  /** Times .codePointAt(int) when no surrogates are present. */
+  @Benchmark void codePointAtNoSurrogates(int reps) {
+    final int length = Math.min(this.length, MIN_SURROGATE);
+    StringBuilder sb = new StringBuilder();
+    for (int j = 0; j < length; j++) {
+      sb.appendCodePoint(j);
+    }
+    for (int i = 0; i < reps; i++) {
+      for (int j = 0; j < 4; j++) {
+        for (int k = 0; k < length - 1; k++) {
+          if (sb.codePointAt(k) > MIN_SURROGATE)
+            throw new Error();
         }
+      }
     }
+  }
 
-    public void timeAppendChar(int reps) {
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append('c');
-            }
+  /** Times .codePointBefore(int) when no surrogates are present. */
+  @Benchmark void codePointBeforeNoSurrogates(int reps) {
+    final int length = Math.min(this.length, MIN_SURROGATE);
+    StringBuilder sb = new StringBuilder();
+    for (int j = 0; j < length; j++) {
+      sb.appendCodePoint(j);
+    }
+    for (int i = 0; i < reps; i++) {
+      for (int j = 0; j < 4; j++) {
+        for (int k = 1; k < length; k++) {
+          if (sb.codePointBefore(k) > MIN_SURROGATE)
+            throw new Error();
         }
+      }
     }
-
-    public void timeAppendCharArray(int reps) {
-        char[] chars = "chars".toCharArray();
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(chars);
-            }
-        }
-    }
-
-    public void timeAppendCharSequence(int reps) {
-        CharSequence cs = "chars";
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(cs);
-            }
-        }
-    }
-
-    public void timeAppendDouble(int reps) {
-        double d = 1.2;
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(d);
-            }
-        }
-    }
-
-    public void timeAppendFloat(int reps) {
-        float f = 1.2f;
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(f);
-            }
-        }
-    }
-
-    public void timeAppendInt(int reps) {
-        int n = 123;
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(n);
-            }
-        }
-    }
-
-    public void timeAppendLong(int reps) {
-        long l = 123;
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(l);
-            }
-        }
-    }
-
-    public void timeAppendObject(int reps) {
-        Object o = new Object();
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(o);
-            }
-        }
-    }
-
-    public void timeAppendString(int reps) {
-        String s = "chars";
-        for (int i = 0; i < reps; ++i) {
-            StringBuilder sb = new StringBuilder();
-            for (int j = 0; j < length; ++j) {
-                sb.append(s);
-            }
-        }
-    }
-
-    // TODO: remove this from all examples when IDE plugins are ready
-    public static void main(String[] args) throws Exception {
-        Runner.main(StringBuilderBenchmark.class, args);
-    }
+  }
 }
diff --git a/examples/src/main/java/examples/Utf8Benchmark.java b/examples/src/main/java/examples/Utf8Benchmark.java
new file mode 100644
index 0000000..97b4e00
--- /dev/null
+++ b/examples/src/main/java/examples/Utf8Benchmark.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 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 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 examples;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+
+import java.nio.charset.Charset;
+import java.util.Random;
+
+/**
+ * Benchmark for operations with the UTF-8 charset.
+ */
+public class Utf8Benchmark {
+
+  static final Charset UTF_8 = Charset.forName("UTF-8");
+
+  /**
+   * The maximum code point used in generated text.  Different values
+   * provide reasonable models of different real-world human text.
+   */
+  static class MaxCodePoint {
+    final int value;
+
+    /**
+     * Convert the input string to a code point.  Accepts regular
+     * decimal numerals, hex strings, and some symbolic names
+     * meaningful to humans.
+     */
+    private static int decode(String userFriendly) {
+      try {
+        return Integer.decode(userFriendly);
+      } catch (NumberFormatException ignored) {
+        if (userFriendly.matches("(?i)(?:American|English|ASCII)")) {
+          // 1-byte UTF-8 sequences - "American" ASCII text
+          return 0x80;
+        } else if (userFriendly.matches("(?i)(?:French|Latin|Western.*European)")) {
+          // Mostly 1-byte UTF-8 sequences, mixed with occasional 2-byte
+          // sequences - "Western European" text
+          return 0x90;
+        } else if (userFriendly.matches("(?i)(?:Branch.*Prediction.*Hostile)")) {
+          // Defeat branch predictor for: c < 0x80 ; branch taken 50% of the time.
+          return 0x100;
+        } else if (userFriendly.matches("(?i)(?:Greek|Cyrillic|European|ISO.?8859)")) {
+          // Mostly 2-byte UTF-8 sequences - "European" text
+          return 0x800;
+        } else if (userFriendly.matches("(?i)(?:Chinese|Han|Asian|BMP)")) {
+          // Mostly 3-byte UTF-8 sequences - "Asian" text
+          return Character.MIN_SUPPLEMENTARY_CODE_POINT;
+        } else if (userFriendly.matches("(?i)(?:Cuneiform|rare|exotic|supplementary.*)")) {
+          // Mostly 4-byte UTF-8 sequences - "rare exotic" text
+          return Character.MAX_CODE_POINT;
+        } else {
+          throw new IllegalArgumentException("Can't decode codepoint " + userFriendly);
+        }
+      }
+    }
+
+    public static MaxCodePoint valueOf(String userFriendly) {
+      return new MaxCodePoint(userFriendly);
+    }
+
+    private MaxCodePoint(String userFriendly) {
+      value = decode(userFriendly);
+    }
+  }
+
+  /**
+   * The default values of maxCodePoint below provide pretty good
+   * performance models of different kinds of common human text.
+   * @see MaxCodePoint#decode
+   */
+  @Param({"0x80", "0x100", "0x800", "0x10000", "0x10ffff"}) MaxCodePoint maxCodePoint;
+
+  static final int STRING_COUNT = 1 << 7;
+
+  @Param({"65536"}) int charCount;
+  private String[] strings;
+
+  /**
+   * Computes arrays of valid unicode Strings.
+   */
+  @BeforeExperiment void setUp() {
+    final long seed = 99;
+    final Random rnd = new Random(seed);
+    strings = new String[STRING_COUNT];
+    for (int i = 0; i < STRING_COUNT; i++) {
+      StringBuilder sb = new StringBuilder();
+      for (int j = 0; j < charCount; j++) {
+        int codePoint;
+        // discard illegal surrogate "codepoints"
+        do {
+          codePoint = rnd.nextInt(maxCodePoint.value);
+        } while (isSurrogate(codePoint));
+        sb.appendCodePoint(codePoint);
+      }
+      strings[i] = sb.toString();
+    }
+    // The reps will continue until the non-determinism detector is pacified!
+    getBytes(100);
+  }
+
+  /**
+   * Benchmarks {@link String#getBytes} on valid strings containing
+   * pseudo-randomly-generated codePoints less than {@code
+   * maxCodePoint}.  A constant seed is used, so separate runs perform
+   * identical computations.
+   */
+  @Benchmark void getBytes(int reps) {
+    final String[] strings = this.strings;
+    final int mask = STRING_COUNT - 1;
+    for (int i = 0; i < reps; i++) {
+      String string = strings[i & mask];
+      byte[] bytes = string.getBytes(UTF_8);
+      if (bytes[0] == 86 && bytes[bytes.length - 1] == 99) {
+        throw new Error("Unlikely! We're just defeating the optimizer!");
+      }
+    }
+  }
+
+  /** Character.isSurrogate was added in Java SE 7. */
+  private boolean isSurrogate(int c) {
+    return (Character.MIN_HIGH_SURROGATE <= c &&
+            c <= Character.MAX_LOW_SURROGATE);
+  }
+}
diff --git a/examples/src/main/java/examples/VarargsBenchmark.java b/examples/src/main/java/examples/VarargsBenchmark.java
new file mode 100644
index 0000000..eceb72d
--- /dev/null
+++ b/examples/src/main/java/examples/VarargsBenchmark.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 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 examples;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import com.google.caliper.Param;
+import com.google.caliper.api.SkipThisScenarioException;
+
+import java.util.Random;
+
+/**
+ * Benchmarks the overhead created by using varargs instead of parameter expansion.
+ *
+ * @author gak@google.com (Gregory Kick)
+ */
+public final class VarargsBenchmark {
+  enum Strategy {
+    VARARGS {
+      @Override long one(long a) {
+        return varargs(a);
+      }
+
+      @Override long two(long a, long b) {
+        return varargs(a, b);
+      }
+
+      @Override long three(long a, long b, long c) {
+        return varargs(a, b, c);
+      }
+
+      @Override long four(long a, long b, long c, long d) {
+        return varargs(a, b, c, d);
+      }
+
+      @Override long five(long a, long b, long c, long d, long e) {
+        return varargs(a, b, c, d);
+      }
+
+      @Override long six(long a, long b, long c, long d, long e, long f) {
+        return varargs(a, b, c, d, e, f);
+      }},
+    EXPANSION {
+      @Override long one(long a) {
+        return VarargsBenchmark.one(a);
+      }
+
+      @Override long two(long a, long b) {
+        return VarargsBenchmark.two(a, b);
+      }
+
+      @Override long three(long a, long b, long c) {
+        return VarargsBenchmark.three(a, b, c);
+      }
+
+      @Override long four(long a, long b, long c, long d) {
+        return VarargsBenchmark.four(a, b, c, d);
+      }
+
+      @Override long five(long a, long b, long c, long d, long e) {
+        return VarargsBenchmark.five(a, b, c, d, e);
+      }
+
+      @Override long six(long a, long b, long c, long d, long e, long f) {
+         return VarargsBenchmark.six(a, b, c, d, e, f);
+      }
+    };
+
+    abstract long one(long a);
+
+    abstract long two(long a, long b);
+
+    abstract long three(long a, long b, long c);
+
+    abstract long four(long a, long b, long c, long d);
+
+    abstract long five(long a, long b, long c, long d, long e);
+
+    abstract long six(long a, long b, long c, long d, long e, long f);
+  }
+
+  private static long varargs(long... longs) {
+    long result = 0;
+    for (long i : longs) {
+      result ^= i;
+    }
+    return result;
+  }
+
+  private static long one(long a) {
+    return a;
+  }
+
+  private static long two(long a, long b) {
+    return a ^ b;
+  }
+
+  private static long three(long a, long b, long c) {
+    return a ^ b ^ c;
+  }
+
+  private static long four(long a, long b, long c, long d) {
+    return a ^ b ^ c ^ d;
+  }
+
+  private static long five(long a, long b, long c, long d, long e) {
+    return a ^ b ^ c ^ d ^ e;
+  }
+
+  private static long six(long a, long b, long c, long d, long e, long f) {
+    return a ^ b ^ c ^ d ^ e ^ f;
+  }
+
+  @Param private Strategy strategy;
+  @Param({"1", "2", "3", "4", "5", "6"}) private int arguments;
+
+  private long[] data = new long[2048];
+
+  @BeforeExperiment void setUp() {
+    Random random = new Random();
+    for (int i = 0; i < data.length; i++) {
+      data[i] = random.nextLong();
+    }
+  }
+
+  @Benchmark long invocation(int reps) {
+    switch (arguments) {
+      case 1:
+        return oneArgument(reps);
+      case 2:
+        return twoArguments(reps);
+      case 3:
+        return threeArguments(reps);
+      case 4:
+        return fourArguments(reps);
+      case 5:
+        return fiveArguments(reps);
+      case 6:
+        return sixArguments(reps);
+      default:
+        throw new SkipThisScenarioException();
+    }
+  }
+
+  private long oneArgument(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.one(data[i % dataLength]);
+    }
+    return dummy;
+  }
+
+  private long twoArguments(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.two(data[i % dataLength], data[(i + 1) % dataLength]);
+    }
+    return dummy;
+  }
+
+  private long threeArguments(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.three(
+          data[i % dataLength],
+          data[(i + 1) % dataLength],
+          data[(i + 2) % dataLength]);
+    }
+    return dummy;
+  }
+
+  private long fourArguments(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.four(
+          data[i % dataLength],
+          data[(i + 1) % dataLength],
+          data[(i + 2) % dataLength],
+          data[(i + 3) % dataLength]);
+    }
+    return dummy;
+  }
+
+  private long fiveArguments(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.five(
+          data[i % dataLength],
+          data[(i + 1) % dataLength],
+          data[(i + 2) % dataLength],
+          data[(i + 3) % dataLength],
+          data[(i + 4) % dataLength]);
+    }
+    return dummy;
+  }
+
+  private long sixArguments(int reps) {
+    long dummy = 0;
+    long[] data = this.data;
+    int dataLength = data.length;
+    for (int i = 0; i < reps; i++) {
+      dummy += strategy.six(
+          data[i % dataLength],
+          data[(i + 1) % dataLength],
+          data[(i + 2) % dataLength],
+          data[(i + 3) % dataLength],
+          data[(i + 4) % dataLength],
+          data[(i + 5) % dataLength]);
+    }
+    return dummy;
+  }
+}