diff --git a/README b/README
index fba3f30..6ca0de4 100644
--- a/README
+++ b/README
@@ -8,8 +8,8 @@
 
 Description:
 Mocking framework. Looks very like Mockito (see http://mockito.org).
-Has a number of restrictions - mocks interfaces only, no class
-generation. Has no dependencies, consequently can be used on Android.
+Has a number of restrictions.
+Can mock concrete classes, requires dexmaker.jar on classpath.
 
 Local Modifications:
 No modifications.
diff --git a/src/com/google/testing/littlemock/AppDataDirGuesser.java b/src/com/google/testing/littlemock/AppDataDirGuesser.java
new file mode 100644
index 0000000..0fdd475
--- /dev/null
+++ b/src/com/google/testing/littlemock/AppDataDirGuesser.java
@@ -0,0 +1,97 @@
+/*
+ * 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 com.google.testing.littlemock;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Utility class for helping guess the application data directory.
+ */
+public class AppDataDirGuesser {
+
+  /** A single default instance of app data dir guesser, for overriding if you really need to. */
+  private static volatile AppDataDirGuesser sInjectableInstance = new AppDataDirGuesser();
+
+  public static void setInstance(AppDataDirGuesser instance) {
+    sInjectableInstance = instance;
+  }
+
+  public static AppDataDirGuesser getsInstance() {
+    return sInjectableInstance;
+  }
+
+  public File guessSuitableDirectoryForGeneratedClasses() {
+    try {
+      ClassLoader classLoader = AppDataDirGuesser.class.getClassLoader();
+      // Check that we have an instance of the PathClassLoader.
+      Class<?> clazz = Class.forName("dalvik.system.PathClassLoader");
+      clazz.cast(classLoader);
+      // Use the toString() method to calculate the data directory.
+      String pathFromThisClassLoader = getPathFromThisClassLoader(classLoader);
+      File[] results = guessPath(pathFromThisClassLoader);
+      if (results.length > 0) {
+        return results[0];
+      }
+    } catch (ClassCastException e) {
+      // Fall through, we will return null.
+    } catch (ClassNotFoundException e) {
+      // Fall through, we will return null.
+    }
+    return null;
+  }
+
+  private String getPathFromThisClassLoader(ClassLoader classLoader) {
+    // Parsing toString() method: yuck.  But no other way to get the path.
+    // Strip out the bit between angle brackets, that's our path.
+    String result = classLoader.toString();
+    int index = result.lastIndexOf('[');
+    result = (index == -1) ? result : result.substring(index + 1);
+    index = result.indexOf(']');
+    return (index == -1) ? result : result.substring(0, index);
+  }
+
+  // @VisibleForTesting
+  File[] guessPath(String input) {
+    List<File> results = new ArrayList<File>();
+    for (String potential : input.split(":")) {
+      if (!potential.startsWith("/data/app/")) {
+        continue;
+      }
+      int start = "/data/app/".length();
+      int end = potential.lastIndexOf(".apk");
+      if (end != potential.length() - 4) {
+        continue;
+      }
+      int dash = potential.indexOf("-");
+      if (dash != -1) {
+        end = dash;
+      }
+      File file = new File("/data/data/" + potential.substring(start, end) + "/cache");
+      if (isWriteableDirectory(file)) {
+        results.add(file);
+      }
+    }
+    return results.toArray(new File[results.size()]);
+  }
+
+  // @VisibleForTesting
+  boolean isWriteableDirectory(File file) {
+    return file.isDirectory() && file.canWrite();
+  }
+}
diff --git a/src/com/google/testing/littlemock/LittleMock.java b/src/com/google/testing/littlemock/LittleMock.java
index 03e2c7a..c8f2b2f 100644
--- a/src/com/google/testing/littlemock/LittleMock.java
+++ b/src/com/google/testing/littlemock/LittleMock.java
@@ -16,6 +16,7 @@
 
 package com.google.testing.littlemock;
 
+import java.io.File;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -23,10 +24,11 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * Very lightweight and simple mocking framework, inspired by Mockito, http://mockito.org.
@@ -35,9 +37,6 @@
  * <ul>
  *   <li>Doesn't support mocking concrete classes, <b>interfaces only</b>.</li>
  *
- *   <li><b>Is not thread-safe.</b> You'll need to provide your own synchronization if you want to
- *   run multi-threaded unit tests.</li>
- *
  *   <li>It supports only a <b>small subset</b> of the APIs provided by Mockito and other mocking
  *   frameworks.</li>
  * </ul>
@@ -149,11 +148,21 @@
     if (howManyTimes == null) {
       throw new IllegalArgumentException("Can't pass null for howManyTimes parameter");
     }
+    DefaultInvocationHandler handler = getHandlerFrom(mock);
+    checkState(handler.mHowManyTimes == null, "Unfinished verify() statements");
+    checkState(handler.mStubbingAction == null, "Unfinished stubbing statements");
     checkNoMatchers();
-    getHandlerFrom(mock).mHowManyTimes = howManyTimes;
-    return mock;
+    handler.mHowManyTimes = howManyTimes;
+    sUnfinishedCallCounts.add(howManyTimes);
+    return handler.<T>getVerifyingMock();
   }
 
+  /** The list of outstanding calls to verify() that haven't finished, used to check for errors. */
+  private static List<CallCount> sUnfinishedCallCounts = new ArrayList<CallCount>();
+
+  /** The list of outstanding calls to when() that haven't finished, used to check for errors. */
+  private static List<Action> sUnfinishedStubbingActions = new ArrayList<Action>();
+
   /** Begins a verification step for exactly one method call. */
   public static <T> T verify(T mock) { return verify(mock, times(1)); }
 
@@ -161,7 +170,7 @@
   public static void verifyZeroInteractions(Object... mocks) {
     checkNoMatchers();
     for (Object mock : mocks) {
-      LinkedList<MethodCall> mMethodCalls = getHandlerFrom(mock).mRecordedCalls;
+      List<MethodCall> mMethodCalls = getHandlerFrom(mock).mRecordedCalls;
       expect(mMethodCalls.isEmpty(), "Mock expected zero interactions, had " + mMethodCalls);
     }
   }
@@ -200,7 +209,12 @@
   /** Creates a {@link CallCount} that matches exactly the given number of calls. */
   public static CallCount times(long n) { return new CallCount(n, n); }
 
-  /** Creates a {@link CallCount} that only matches if the method was never called. */
+  /** Claims that the verified call must happen before the given timeout. */
+  public static Timeout timeout(long timeoutMillis) {
+    return new Timeout(1, 1, timeoutMillis);
+  }
+
+/** Creates a {@link CallCount} that only matches if the method was never called. */
   public static CallCount never() { return new CallCount(0, 0); }
 
   /** Creates a {@link CallCount} that matches at least one method call. */
@@ -362,8 +376,9 @@
   }
 
   /** Creates a mock, more easily done via the {@link #initMocks(Object)} method. */
+  @SuppressWarnings("unchecked")
   private static <T> T mock(Class<T> clazz, String fieldName) {
-    return LittleMock.<T>newProxy(clazz, new DefaultInvocationHandler(clazz, fieldName));
+    return (T) createProxy(clazz, new DefaultInvocationHandler(clazz, fieldName));
   }
 
   /** Pick a suitable name for a field of the given clazz. */
@@ -380,7 +395,19 @@
   }
 
   /** Use this in tear down to check for programming errors. */
-  public static void checkForProgrammingErrorsDuringTearDown() { checkNoMatchers(); }
+  public static void checkForProgrammingErrorsDuringTearDown() {
+    checkNoMatchers();
+    checkNoUnfinishedCalls(sUnfinishedCallCounts, "verify()");
+    checkNoUnfinishedCalls(sUnfinishedStubbingActions, "stubbing");
+  }
+
+  /** Helper function to check that there are no verify or stubbing commands outstanding. */
+  private static void checkNoUnfinishedCalls(List<?> list, String type) {
+    if (!list.isEmpty()) {
+      list.clear();
+      throw new IllegalStateException("Unfinished " + type + " statements");
+    }
+  }
 
   /** Implementation of {@link Behaviour}. */
   private static class BehaviourImpl implements Behaviour {
@@ -392,8 +419,12 @@
 
     @Override
     public <T> T when(T mock) {
-      getHandlerFrom(mock).mStubbingAction = mAction;
-      return mock;
+      DefaultInvocationHandler handler = getHandlerFrom(mock);
+      checkState(handler.mHowManyTimes == null, "Unfinished verify() statements");
+      checkState(handler.mStubbingAction == null, "Unfinished stubbing statements");
+      handler.mStubbingAction = mAction;
+      sUnfinishedStubbingActions.add(mAction);
+      return handler.<T>getStubbingMock();
     }
   }
 
@@ -478,9 +509,10 @@
     private final String mFieldName;
 
     /** The list of method calls executed on the mock. */
-    private LinkedList<MethodCall> mRecordedCalls = new LinkedList<MethodCall>();
+    private List<MethodCall> mRecordedCalls = new CopyOnWriteArrayList<MethodCall>();
     /** The list of method calls that were stubbed out and their corresponding actions. */
-    private LinkedList<StubbedCall> mStubbedCalls = new LinkedList<StubbedCall>();
+    private List<StubbedCall> mStubbedCalls = new CopyOnWriteArrayList<StubbedCall>();
+
     /**
      * The number of times a given call should be verified.
      *
@@ -490,6 +522,7 @@
      * <p>It is reset to null once the verification has occurred.
      */
     private CallCount mHowManyTimes = null;
+
     /**
      * The action to be associated with the stubbed method.
      *
@@ -498,6 +531,12 @@
      */
     private Action mStubbingAction = null;
 
+    /** Dynamic proxy used to verify calls against this mock. */
+    private final Object mVerifyingMock;
+
+    /** Dynamic proxy used to stub calls against this mock. */
+    private final Object mStubbingMock;
+
     /**
      * Creates a new invocation handler for an object.
      *
@@ -509,24 +548,84 @@
     public DefaultInvocationHandler(Class<?> clazz, String fieldName) {
       mClazz = clazz;
       mFieldName = fieldName;
+      mVerifyingMock = createVerifyingMock(clazz);
+      mStubbingMock = createStubbingMock(clazz);
+    }
+
+    // Safe if you call getHandlerFrom(mock).getVerifyingMock(), since this is guaranteed to be
+    // of the same type as mock itself.
+    @SuppressWarnings("unchecked")
+    public <T> T getVerifyingMock() {
+      return (T) mVerifyingMock;
+    }
+
+    // Safe if you call getHandlerFrom(mock).getStubbingMock(), since this is guaranteed to be
+    // of the same type as mock itself.
+    @SuppressWarnings("unchecked")
+    public <T> T getStubbingMock() {
+      return (T) mStubbingMock;
+    }
+
+    /** Used to check that we always stub and verify from the same thread. */
+    private AtomicReference<Thread> mCurrentThread = new AtomicReference<Thread>();
+
+    /** Check that we are stubbing and verifying always from the same thread. */
+    private void checkThread() {
+      Thread currentThread = Thread.currentThread();
+      mCurrentThread.compareAndSet(null, currentThread);
+      if (mCurrentThread.get() != currentThread) {
+        throw new IllegalStateException("Must always mock and stub from one thread only.  "
+            + "This thread: " + currentThread + ", the other thread: " + mCurrentThread.get());
+      }
+    }
+
+    /** Generate the dynamic proxy that will handle verify invocations. */
+    private Object createVerifyingMock(Class<?> clazz) {
+      return createProxy(clazz, new InvocationHandler() {
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+          checkThread();
+          expect(mHowManyTimes != null, "verifying mock doesn't know how many times");
+          try {
+            ArgumentMatcher[] matchers = checkClearAndGetMatchers(method);
+            StackTraceElement callSite = new Exception().getStackTrace()[2];
+            MethodCall methodCall = new MethodCall(method, callSite, args);
+            innerVerify(method, matchers, methodCall, proxy, callSite, mHowManyTimes);
+            return defaultReturnValue(method.getReturnType());
+          } finally {
+            sUnfinishedCallCounts.remove(mHowManyTimes);
+            mHowManyTimes = null;
+          }
+        }
+      });
+    }
+
+    /** Generate the dynamic proxy that will handle stubbing invocations. */
+    private Object createStubbingMock(Class<?> clazz) {
+      return createProxy(clazz, new InvocationHandler() {
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+          checkThread();
+          expect(mStubbingAction != null, "stubbing mock doesn't know what action to perform");
+          try {
+            ArgumentMatcher[] matchers = checkClearAndGetMatchers(method);
+            StackTraceElement callSite = new Exception().getStackTrace()[2];
+            MethodCall methodCall = new MethodCall(method, callSite, args);
+            innerStub(method, matchers, methodCall, callSite, mStubbingAction);
+            return defaultReturnValue(method.getReturnType());
+          } finally {
+            sUnfinishedStubbingActions.remove(mStubbingAction);
+            mStubbingAction = null;
+          }
+        }
+      });
     }
 
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-      ArgumentMatcher[] matchers = checkClearAndGetMatchers(method);
       StackTraceElement callSite = new Exception().getStackTrace()[2];
       MethodCall methodCall = new MethodCall(method, callSite, args);
-      if (mHowManyTimes != null) {
-        innerVerify(method, matchers, methodCall, proxy, callSite);
-        mHowManyTimes = null;
-        return defaultReturnValue(method.getReturnType());
-      } else if (mStubbingAction != null) {
-        innerStub(method, matchers, methodCall, callSite);
-        mStubbingAction = null;
-        return defaultReturnValue(method.getReturnType());
-      } else {
-        return innerRecord(method, args, methodCall, proxy, callSite);
-      }
+      return innerRecord(method, args, methodCall, proxy, callSite);
     }
 
     /**
@@ -579,13 +678,12 @@
     }
 
     private void innerStub(Method method, final ArgumentMatcher[] matchers, MethodCall methodCall,
-        StackTraceElement callSite) {
-      final Action stubbingAction = mStubbingAction;
+        StackTraceElement callSite, final Action stubbingAction) {
       checkSpecialObjectMethods(method, "stub");
       checkThisActionCanBeUsedForThisMethod(method, stubbingAction, callSite);
       if (matchers.length == 0) {
         // If there are no matchers, then this is a simple stubbed method call with an action.
-        mStubbedCalls.addFirst(new StubbedCall(methodCall, stubbingAction));
+        mStubbedCalls.add(0, new StubbedCall(methodCall, stubbingAction));
         return;
       }
       // If there are matchers, then we need to make a new method call which matches only
@@ -607,7 +705,7 @@
           return stubbingAction.getReturnType();
         }
       };
-      mStubbedCalls.addFirst(new StubbedCall(matchMatchersMethodCall, setCapturesThenAction));
+      mStubbedCalls.add(0, new StubbedCall(matchMatchersMethodCall, setCapturesThenAction));
     }
 
     private void checkThisActionCanBeUsedForThisMethod(Method method, final Action stubbingAction,
@@ -645,8 +743,32 @@
     }
 
     private void innerVerify(Method method, ArgumentMatcher[] matchers, MethodCall methodCall,
-            Object proxy, StackTraceElement callSite) {
+        Object proxy, StackTraceElement callSite, CallCount callCount) {
       checkSpecialObjectMethods(method, "verify");
+      int total = countMatchingInvocations(method, matchers, methodCall);
+      long callTimeout = callCount.getTimeout();
+      if (callTimeout > 0) {
+        long endTime = System.currentTimeMillis() + callTimeout;
+        while (!callCount.matches(total)) {
+          try {
+            Thread.sleep(1);
+          } catch (InterruptedException e) {
+            fail("interrupted whilst waiting to verify");
+          }
+          if (System.currentTimeMillis() > endTime) {
+            fail(formatFailedVerifyMessage(methodCall, total, callTimeout, callCount));
+          }
+          total = countMatchingInvocations(method, matchers, methodCall);
+        }
+      } else {
+        if (!callCount.matches(total)) {
+          fail(formatFailedVerifyMessage(methodCall, total, 0, callCount));
+        }
+      }
+    }
+
+    private int countMatchingInvocations(Method method, ArgumentMatcher[] matchers,
+        MethodCall methodCall) {
       int total = 0;
       for (MethodCall call : mRecordedCalls) {
         if (call.mMethod.equals(method)) {
@@ -658,17 +780,22 @@
           }
         }
       }
-      expect(mHowManyTimes.matches(total), formatFailedVerifyMessage(methodCall, total));
+      return total;
     }
 
-    private String formatFailedVerifyMessage(MethodCall methodCall, int total) {
+    private String formatFailedVerifyMessage(MethodCall methodCall, int total, long timeoutMillis,
+        CallCount callCount) {
       StringBuffer sb = new StringBuffer();
-      sb.append("\nExpected ").append(mHowManyTimes).append(" to:");
+      sb.append("\nExpected ").append(callCount);
+      if (timeoutMillis > 0) {
+        sb.append(" within " + timeoutMillis + "ms");
+      }
+      sb.append(" to:");
       appendDebugStringForMethodCall(sb, methodCall.mMethod,
           methodCall.mElement, mFieldName, false);
       sb.append("\n\n");
       if (mRecordedCalls.size() == 0) {
-        sb.append("No method calls happened to this mock");
+        sb.append("No method calls happened on this mock");
       } else {
         sb.append("Method calls that did happen:");
         for (MethodCall recordedCall : mRecordedCalls) {
@@ -768,10 +895,10 @@
 
   /** Encapsulates the number of times a method is called, between upper and lower bounds. */
   private static class CallCount {
-    long mLowerBound;
-    long mUpperBound;
+    private long mLowerBound;
+    private long mUpperBound;
 
-    private CallCount(long lowerBound, long upperBound) {
+    public CallCount(long lowerBound, long upperBound) {
       mLowerBound = lowerBound;
       mUpperBound = upperBound;
     }
@@ -781,6 +908,21 @@
       return total >= mLowerBound && total <= mUpperBound;
     }
 
+    /** Tells us how long we should block waiting for the verify to happen. */
+    public long getTimeout() {
+      return 0;
+    }
+
+    public CallCount setLowerBound(long lowerBound) {
+      mLowerBound = lowerBound;
+      return this;
+    }
+
+    public CallCount setUpperBound(long upperBound) {
+      mUpperBound = upperBound;
+      return this;
+    }
+
     @Override
     public String toString() {
       if (mLowerBound == mUpperBound) {
@@ -792,6 +934,26 @@
     }
   }
 
+  /** Encapsulates adding number of times behaviour to a call count with timeout. */
+  public static final class Timeout extends CallCount {
+    private long mTimeoutMillis;
+
+    public Timeout(long lowerBound, long upperBound, long timeoutMillis) {
+      super(lowerBound, upperBound);
+      mTimeoutMillis = timeoutMillis;
+    }
+
+    @Override
+    public long getTimeout() {
+      return mTimeoutMillis;
+    }
+
+    public CallCount times(int times) { return setLowerBound(times).setUpperBound(times); }
+    public CallCount atLeast(long n) { return setLowerBound(n).setUpperBound(Long.MAX_VALUE); }
+    public CallCount atLeastOnce() { return setLowerBound(1).setUpperBound(Long.MAX_VALUE); }
+    public CallCount between(long n, long m) { return setLowerBound(n).setUpperBound(m); }
+  }
+
   /** Helper method to add an 's' to a string iff the count is not 1. */
   private static String plural(String prefix, long count) {
     return (count == 1) ? prefix : (prefix + "s");
@@ -861,12 +1023,6 @@
     return (DefaultInvocationHandler) invocationHandler;
   }
 
-  /** Builds a dynamic proxy that implements the given interface, delegating to given handler. */
-  @SuppressWarnings("unchecked")
-  private static <T> T newProxy(Class<?> theInterface, InvocationHandler theHandler) {
-    return (T) Proxy.newProxyInstance(getClassLoader(), new Class<?>[]{ theInterface }, theHandler);
-  }
-
   /** Gets a suitable class loader for use with the proxy. */
   private static ClassLoader getClassLoader() {
     return LittleMock.class.getClassLoader();
@@ -878,4 +1034,32 @@
     field.set(object, value);
     field.setAccessible(false);
   }
+
+  /** Helper method to throw an IllegalStateException if given condition is not met. */
+  private static void checkState(boolean condition, String message) {
+    if (!condition) {
+      throw new IllegalStateException(message);
+    }
+  }
+
+  /** Create a dynamic proxy for the given class, delegating to the given invocation handler. */
+  private static Object createProxy(Class<?> clazz, InvocationHandler handler) {
+    if (clazz.isInterface()) {
+      return Proxy.newProxyInstance(getClassLoader(), new Class<?>[] { clazz }, handler);
+    }
+    try {
+      Class<?> proxyBuilder = Class.forName("com.google.dexmaker.stock.ProxyBuilder");
+      Method forClassMethod = proxyBuilder.getMethod("forClass", Class.class);
+      Object builder = forClassMethod.invoke(null, clazz);
+      Method handlerMethod = builder.getClass().getMethod("handler", InvocationHandler.class);
+      builder = handlerMethod.invoke(builder, handler);
+      Method dexCacheMethod = builder.getClass().getMethod("dexCache", File.class);
+      File directory = AppDataDirGuesser.getsInstance().guessSuitableDirectoryForGeneratedClasses();
+      builder = dexCacheMethod.invoke(builder, directory);
+      Method buildMethod = builder.getClass().getMethod("build");
+      return buildMethod.invoke(builder);
+    } catch (Exception e) {
+      throw new IllegalStateException("Could not mock this concrete class", e);
+    }
+  }
 }
diff --git a/tests/com/google/testing/littlemock/AppDataDirGuesserTest.java b/tests/com/google/testing/littlemock/AppDataDirGuesserTest.java
new file mode 100644
index 0000000..b537097
--- /dev/null
+++ b/tests/com/google/testing/littlemock/AppDataDirGuesserTest.java
@@ -0,0 +1,101 @@
+/*
+ * 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 com.google.testing.littlemock;
+
+import junit.framework.TestCase;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class AppDataDirGuesserTest extends TestCase {
+  public void testGuessCacheDir_SimpleExample() {
+    guessCacheDirFor("/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
+    guessCacheDirFor("/data/app/a.b.c.tests.apk").shouldGive("/data/data/a.b.c.tests/cache");
+  }
+
+  public void testGuessCacheDir_MultipleResultsSeparatedByColon() {
+    guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
+        .shouldGive("/data/data/a.b.c/cache", "/data/data/d.e.f/cache");
+  }
+
+  public void testGuessCacheDir_NotWriteableSkipped() {
+    guessCacheDirFor("/data/app/a.b.c.apk:/data/app/d.e.f.apk")
+        .withNonWriteable("/data/data/a.b.c/cache")
+        .shouldGive("/data/data/d.e.f/cache");
+  }
+
+  public void testGuessCacheDir_StripHyphenatedSuffixes() {
+    guessCacheDirFor("/data/app/a.b.c-2.apk").shouldGive("/data/data/a.b.c/cache");
+  }
+
+  public void testGuessCacheDir_LeadingAndTrailingColonsIgnored() {
+    guessCacheDirFor("/data/app/a.b.c.apk:asdf:").shouldGive("/data/data/a.b.c/cache");
+    guessCacheDirFor(":asdf:/data/app/a.b.c.apk").shouldGive("/data/data/a.b.c/cache");
+  }
+
+  public void testGuessCacheDir_InvalidInputsGiveEmptyArray() {
+    guessCacheDirFor("").shouldGive();
+  }
+
+  public void testGuessCacheDir_JarsIgnored() {
+    guessCacheDirFor("/data/app/a.b.c.jar").shouldGive();
+    guessCacheDirFor("/system/framework/android.test.runner.jar").shouldGive();
+  }
+
+  public void testGuessCacheDir_RealWorldExample() {
+    String realPath = "/system/framework/android.test.runner.jar:" +
+        "/data/app/com.google.android.voicesearch.tests-2.apk:" +
+        "/data/app/com.google.android.voicesearch-1.apk";
+    guessCacheDirFor(realPath)
+        .withNonWriteable("/data/data/com.google.android.voicesearch.tests/cache")
+        .shouldGive("/data/data/com.google.android.voicesearch/cache");
+  }
+
+  private interface TestCondition {
+    TestCondition withNonWriteable(String... files);
+    void shouldGive(String... files);
+  }
+
+  private TestCondition guessCacheDirFor(final String path) {
+    final Set<String> notWriteable = new HashSet<String>();
+    return new TestCondition() {
+      @Override
+      public void shouldGive(String... files) {
+        AppDataDirGuesser guesser = new AppDataDirGuesser() {
+          @Override
+          public boolean isWriteableDirectory(File file) {
+            return !notWriteable.contains(file.getAbsolutePath());
+          }
+        };
+        File[] results = guesser.guessPath(path);
+        assertNotNull("Null results for " + path, results);
+        assertEquals("Bad lengths for " + path, files.length, results.length);
+        for (int i = 0; i < files.length; ++i) {
+          assertEquals("Element " + i, new File(files[i]), results[i]);
+        }
+      }
+
+      @Override
+      public TestCondition withNonWriteable(String... files) {
+        notWriteable.addAll(Arrays.asList(files));
+        return this;
+      }
+    };
+  }
+}
diff --git a/tests/com/google/testing/littlemock/LittleMockTest.java b/tests/com/google/testing/littlemock/LittleMockTest.java
index 9d3cf38..e8c7b1e 100644
--- a/tests/com/google/testing/littlemock/LittleMockTest.java
+++ b/tests/com/google/testing/littlemock/LittleMockTest.java
@@ -42,6 +42,7 @@
 import static com.google.testing.littlemock.LittleMock.mock;
 import static com.google.testing.littlemock.LittleMock.never;
 import static com.google.testing.littlemock.LittleMock.reset;
+import static com.google.testing.littlemock.LittleMock.timeout;
 import static com.google.testing.littlemock.LittleMock.times;
 import static com.google.testing.littlemock.LittleMock.verify;
 import static com.google.testing.littlemock.LittleMock.verifyNoMoreInteractions;
@@ -50,16 +51,18 @@
 import junit.framework.TestCase;
 
 import java.io.IOException;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 
 /**
  * Unit tests for the LittleMock class.
@@ -67,16 +70,6 @@
  * @author hugohudson@gmail.com (Hugo Hudson)
  */
 public class LittleMockTest extends TestCase {
-  /**
-   * Used in these unit tests to indicate that the method should throw a given type of exception.
-   */
-  @Target({ ElementType.METHOD })
-  @Retention(RetentionPolicy.RUNTIME)
-  public @interface ShouldThrow {
-    public Class<? extends Throwable> value();
-    public String[] messages() default {};
-  }
-
   @Mock private Foo mFoo;
   @Mock private Bar mBar;
   @Mock private BarSubtype mBarSubtype;
@@ -84,36 +77,20 @@
   @Captor private ArgumentCaptor<String> mCaptureAnotherString;
   @Captor private ArgumentCaptor<Integer> mCaptureInteger;
   @Captor private ArgumentCaptor<Callback> mCaptureCallback;
+  private ExecutorService mExecutorService;
 
   @Override
   protected void setUp() throws Exception {
     super.setUp();
     LittleMock.initMocks(this);
+    mExecutorService = Executors.newCachedThreadPool();
   }
 
   @Override
-  protected void runTest() throws Throwable {
-    Method method = getClass().getMethod(getName(), (Class[]) null);
-    ShouldThrow shouldThrowAnnotation = method.getAnnotation(ShouldThrow.class);
-    if (shouldThrowAnnotation != null) {
-      try {
-        super.runTest();
-        fail("Should have thrown " + shouldThrowAnnotation.value());
-      } catch (Throwable e) {
-        if (!e.getClass().equals(shouldThrowAnnotation.value())) {
-          fail("Should have thrown " + shouldThrowAnnotation.value() + " but threw " + e);
-        }
-        for (String requiredSubstring : shouldThrowAnnotation.messages()) {
-          if (!e.getMessage().contains(requiredSubstring)) {
-            fail("Error message didn't contain " + requiredSubstring + ", was " + e.getMessage());
-          }
-        }
-        // Good, test passes.
-      }
-    } else {
-      super.runTest();
+    protected void tearDown() throws Exception {
+      mExecutorService.shutdown();
+      super.tearDown();
     }
-  }
 
   /** Simple interface for testing against. */
   public interface Callback {
@@ -186,14 +163,18 @@
     assertEquals(null, mFoo.anInterface());
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testVerify_FailsIfNotDoneOnAProxy() {
-    verify("hello").contains("something");
+    try {
+      verify("hello").contains("something");
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testVerify_FailsIfNotCreatedByOurMockMethod() {
-    verify(createNotARealMock()).add("something");
+    try {
+      verify(createNotARealMock()).add("something");
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
   public void testVerify_SuccessfulVerification() {
@@ -215,22 +196,28 @@
     verify(mFoo).add("something");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_MeansOnlyOnceSoShouldFailIfCalledTwice() {
     mFoo.add("something");
     mFoo.add("something");
-    verify(mFoo).add("something");
+    try {
+      verify(mFoo).add("something");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_FailedVerification_CalledWithWrongArgument() {
     mFoo.add("something else");
-    verify(mFoo).add("something");
+    try {
+      verify(mFoo).add("something");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_FailedVerification_WasNeverCalled() {
-    verify(mFoo).add("something");
+    try {
+      verify(mFoo).add("something");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_TimesTwice_Succeeds() {
@@ -239,25 +226,31 @@
     verify(mFoo, LittleMock.times(2)).add("jim");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_TimesTwice_ButThreeTimesFails() {
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
-    verify(mFoo, LittleMock.times(2)).add("jim");
+    try {
+      verify(mFoo, LittleMock.times(2)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_TimesTwice_ButOnceFails() {
     mFoo.add("jim");
-    verify(mFoo, LittleMock.times(2)).add("jim");
+    try {
+      verify(mFoo, LittleMock.times(2)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_TimesTwice_DifferentStringsFails() {
     mFoo.add("jim");
     mFoo.add("bob");
-    verify(mFoo, LittleMock.times(2)).add("jim");
+    try {
+      verify(mFoo, LittleMock.times(2)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_TimesTwice_WorksWithAnyString() {
@@ -266,18 +259,22 @@
     verify(mFoo, LittleMock.times(2)).add(anyString());
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_TimesTwice_FailsIfJustOnceWithAnyString() {
     mFoo.add("bob");
-    verify(mFoo, LittleMock.times(2)).add(anyString());
+    try {
+      verify(mFoo, LittleMock.times(2)).add(anyString());
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_TimesTwice_FailsIfThreeTimesWithAnyString() {
     mFoo.add("bob");
     mFoo.add("jim");
     mFoo.add("james");
-    verify(mFoo, LittleMock.times(2)).add(anyString());
+    try {
+      verify(mFoo, LittleMock.times(2)).add(anyString());
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_Never_Succeeds() {
@@ -285,10 +282,12 @@
     verify(mFoo, never()).anInt();
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_Never_FailsIfWasCalled() {
     mFoo.add("jim");
-    verify(mFoo, never()).add("jim");
+    try {
+      verify(mFoo, never()).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_Never_PassesIfArgumentsDontMatch() {
@@ -308,9 +307,11 @@
     verify(mFoo, atLeastOnce()).add("jim");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_AtLeastOnce_FailsForNoCalls() {
-    verify(mFoo, atLeastOnce()).add("jim");
+    try {
+      verify(mFoo, atLeastOnce()).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_AtLeastThreeTimes_SuceedsForThreeCalls() {
@@ -329,11 +330,13 @@
     verify(mFoo, atLeast(3)).add("jim");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_AtLeastThreeTimes_FailsForTwoCalls() {
     mFoo.add("jim");
     mFoo.add("jim");
-    verify(mFoo, atLeast(3)).add("jim");
+    try {
+      verify(mFoo, atLeast(3)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_AtMostThreeTimes_SuceedsForThreeCalls() {
@@ -343,14 +346,16 @@
     verify(mFoo, atMost(3)).add("jim");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_AtMostThreeTimes_FailsForFiveCalls() {
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
-    verify(mFoo, atMost(3)).add("jim");
+    try {
+      verify(mFoo, atMost(3)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerify_AtMostThreeTimes_SucceedsForTwoCalls() {
@@ -377,20 +382,24 @@
     verify(mFoo, between(2, 4)).add("jim");
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_BetweenTwoAndFour_FailsForOneCall() {
     mFoo.add("jim");
-    verify(mFoo, between(2, 4)).add("jim");
+    try {
+      verify(mFoo, between(2, 4)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerify_BetweenTwoAndFour_FailsForFiveCalls() {
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
     mFoo.add("jim");
-    verify(mFoo, LittleMock.between(2, 4)).add("jim");
+    try {
+      verify(mFoo, LittleMock.between(2, 4)).add("jim");
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testDoReturnWhen_SimpleReturn() {
@@ -416,14 +425,18 @@
     assertEquals(null, mFoo.get(2));
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testDoReturnWhen_CalledOnString() {
-    doReturn("first").when("hello").contains("something");
+    try {
+      doReturn("first").when("hello").contains("something");
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testDoReturnWhen_CalledOnNonMock() {
-    doReturn("first").when(createNotARealMock()).get(0);
+    try {
+      doReturn("first").when(createNotARealMock()).get(0);
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
   public void testDoReturnWhen_CanAlsoBeVerified() {
@@ -469,10 +482,12 @@
     assertEquals(null, mFoo.anInterface());
   }
 
-  @ShouldThrow(RuntimeException.class)
   public void testDoThrow_SimpleException() {
     doThrow(new RuntimeException()).when(mFoo).aDouble();
-    mFoo.aDouble();
+    try {
+      mFoo.aDouble();
+      fail();
+    } catch (RuntimeException expected) {}
   }
 
   public void testDoThrow_IfItDoesntMatchItIsntThrown() {
@@ -480,17 +495,17 @@
     mFoo.aChar();
   }
 
-  @ShouldThrow(RuntimeException.class)
   public void testDoThrow_KeepsThrowingForever() {
     doThrow(new RuntimeException()).when(mFoo).aDouble();
     try {
       mFoo.aDouble();
-      fail("Should have thrown a RuntimeException");
-    } catch (RuntimeException e) {
-      // Expected.
-    }
+      fail();
+    } catch (RuntimeException expected) {}
     // This second call should also throw a RuntimeException.
-    mFoo.aDouble();
+    try {
+      mFoo.aDouble();
+      fail();
+    } catch (RuntimeException expected) {}
   }
 
   public void testDoNothing() {
@@ -502,21 +517,25 @@
     verifyZeroInteractions(mFoo);
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyZeroInteractions_FailsIfSomethingHasHappened() {
     mFoo.aBoolean();
-    verifyZeroInteractions(mFoo);
+    try {
+      verifyZeroInteractions(mFoo);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerifyZeroInteractions_HappyWithMultipleArguments() {
     verifyZeroInteractions(mFoo, mBar);
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyZeroInteractions_ShouldFailEvenIfOtherInteractionsWereFirstVerified() {
     mFoo.add("test");
     verify(mFoo).add("test");
-    verifyZeroInteractions(mFoo);
+    try {
+      verifyZeroInteractions(mFoo);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerifyEq_Method() {
@@ -534,22 +553,28 @@
     verify(mBar).mixedArguments(eq(8), eq("test"));
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyEq_MethodFailsIfNotEqual() {
     mFoo.add("bob");
-    verify(mFoo).add(eq("jim"));
+    try {
+      verify(mFoo).add(eq("jim"));
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyEq_MethodFailsIfJustOneIsNotEqual() {
     mBar.twoStrings("first", "second");
-    verify(mBar).twoStrings(eq("first"), eq("third"));
+    try {
+      verify(mBar).twoStrings(eq("first"), eq("third"));
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyEq_MethodFailsIfSameParamsButInWrongOrder() {
     mBar.twoStrings("first", "second");
-    verify(mBar).twoStrings(eq("second"), eq("first"));
+    try {
+      verify(mBar).twoStrings(eq("second"), eq("first"));
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testCapture_SimpleCapture() {
@@ -622,14 +647,6 @@
     assertEquals(newList("whinny", "jessica"), mCaptureAnotherString.getAllValues());
   }
 
-  public static <T> List<T> newList(T... things) {
-    ArrayList<T> list = new ArrayList<T>();
-    for (T thing : things) {
-      list.add(thing);
-    }
-    return list;
-  }
-
   public void testAnyString() {
     doReturn("jim").when(mFoo).lookup(anyString());
     assertEquals("jim", mFoo.lookup("barney"));
@@ -641,10 +658,12 @@
     verify(mFoo).takesObject(anyString());
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testAnyString_ObjectValue() {
     mFoo.takesObject(new Object());
-    verify(mFoo).takesObject(anyString());
+    try {
+      verify(mFoo).takesObject(anyString());
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testAnyObject() {
@@ -696,11 +715,13 @@
     verifyZeroInteractions(mFoo);
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testReset_VerifyFailsAfterReset() {
     mFoo.aByte();
     reset(mFoo);
-    verify(mFoo).aByte();
+    try {
+      verify(mFoo).aByte();
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testCapture_BothBeforeAndAfter() {
@@ -738,7 +759,6 @@
     verify(mFoo).add("yes");
   }
 
-  @ShouldThrow(IOException.class)
   public void testDoAction_CanThrowDeclaredException() throws Exception {
     doAnswer(new Callable<Void>() {
       @Override
@@ -746,10 +766,12 @@
         throw new IOException("Problem");
       }
     }).when(mFoo).exceptionThrower();
-    mFoo.exceptionThrower();
+    try {
+      mFoo.exceptionThrower();
+      fail();
+    } catch (IOException expected) {}
   }
 
-  @ShouldThrow(RuntimeException.class)
   public void testDoAction_CanThrowUndelcaredException() {
     doAnswer(new Callable<Void>() {
       @Override
@@ -757,7 +779,10 @@
         throw new RuntimeException("Problem");
       }
     }).when(mFoo).aBoolean();
-    mFoo.aBoolean();
+    try {
+      mFoo.aBoolean();
+      fail();
+    } catch (RuntimeException expected) {}
   }
 
   public void testRunThisIsAnAliasForDoAction() {
@@ -796,10 +821,12 @@
     verifyNoMoreInteractions(mFoo, mBar);
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyNoMoreInteractions_FailsWhenOneActionWasNotVerified() {
     mFoo.aBoolean();
-    verifyNoMoreInteractions(mFoo, mBar);
+    try {
+      verifyNoMoreInteractions(mFoo, mBar);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerifyNoMoreInteractions_SucceedsWhenAllActionsWereVerified() {
@@ -809,13 +836,15 @@
     verifyNoMoreInteractions(mFoo);
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testVerifyNoMoreInteractions_FailsWhenMostButNotAllActionsWereVerified() {
     mFoo.get(3);
     mFoo.get(20);
     mFoo.aByte();
     verify(mFoo, atLeastOnce()).get(anyInt());
-    verifyNoMoreInteractions(mFoo);
+    try {
+      verifyNoMoreInteractions(mFoo);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testVerifyNoMoreInteractions_ShouldIngoreStubbedCalls() {
@@ -824,17 +853,20 @@
     verifyNoMoreInteractions(mFoo);
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testMatchers_WrongNumberOfMatchersOnStubbingCausesError() {
-    doReturn("hi").when(mBar).twoStrings("jim", eq("bob"));
+    try {
+      doReturn("hi").when(mBar).twoStrings("jim", eq("bob"));
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testMatchers_WrongNumberOfMatchersOnVerifyCausesError() {
-    verify(mBar).twoStrings("jim", eq("bob"));
+    try {
+      verify(mBar).twoStrings("jim", eq("bob"));
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalStateException.class)
   public void testCreateACaptureButDontUseItShouldFailAtNextVerify() {
     // If we create a capture illegally, outside of a method call, like so:
     mCaptureString.capture();
@@ -843,23 +875,29 @@
     // call on the mock object.
     // Thus we should check in the verify() method that there are *no matchers* on the static
     // list, as this would indicate a programming error such as the above.
-    verify(mFoo, anyTimes()).aBoolean();
+    try {
+      verify(mFoo, anyTimes()).aBoolean();
+      fail();
+    } catch (IllegalStateException expected) {}
   }
 
-  @ShouldThrow(IllegalStateException.class)
   public void testCreateACaptureButDontUseItShouldFailAtNextVerify_AlsoNoMoreInteractions() {
     // Same result desired as in previous test.
     mCaptureString.capture();
-    verifyNoMoreInteractions(mFoo);
+    try {
+      verifyNoMoreInteractions(mFoo);
+      fail();
+    } catch (IllegalStateException expected) {}
   }
 
-  @ShouldThrow(IllegalStateException.class)
   public void testCreateACaptureButDontUseItShouldFailAtNextVerify_AlsoZeroInteraction() {
     mCaptureString.capture();
-    verifyZeroInteractions(mFoo);
+    try {
+      verifyZeroInteractions(mFoo);
+      fail();
+    } catch (IllegalStateException expected) {}
   }
 
-  @ShouldThrow(IllegalStateException.class)
   public void testCheckStaticVariablesMethod() {
     // To help us avoid programming errors, I'm adding a method that you can call from tear down,
     // which will explode if there is anything still left in your static variables at the end
@@ -867,12 +905,17 @@
     // variable (so that the next test won't fail).  It should fail if we create a matcher
     // be it a capture or anything else that is then not consumed.
     anyInt();
-    checkForProgrammingErrorsDuringTearDown();
+    try {
+      checkForProgrammingErrorsDuringTearDown();
+      fail();
+    } catch (IllegalStateException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testCantPassNullToVerifyCount() {
-    verify(mFoo, null).aBoolean();
+    try {
+      verify(mFoo, null).aBoolean();
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
   public void testInjectionInNestedClasses() throws Exception {
@@ -901,10 +944,12 @@
     verify(mFoo).takesObject(isA(String.class));
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testIsA_FailsWithSuperclass() {
     mFoo.takesObject(new Object());
-    verify(mFoo).takesObject(isA(String.class));
+    try {
+      verify(mFoo).takesObject(isA(String.class));
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testIsA_WillAcceptNull() {
@@ -918,49 +963,57 @@
     verify(mFoo).takesBar(isA(BarSubtype.class));
   }
 
-  @ShouldThrow(AssertionError.class)
   public void testIsA_MatchSubtypeFailed() {
     mFoo.takesBar(mBar);
-    verify(mFoo).takesBar(isA(BarSubtype.class));
+    try {
+      verify(mFoo).takesBar(isA(BarSubtype.class));
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot verify call to", "boolean java.lang.Object.equals(java.lang.Object)"})
   public void testVerifyEquals_ShouldFail() {
     mFoo.equals(null);
-    verify(mFoo).equals(null);
+    try {
+      verify(mFoo).equals(null);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot verify call to", "int java.lang.Object.hashCode()"})
   public void testVerifyHashCode_ShouldFail() {
     mFoo.hashCode();
-    verify(mFoo).hashCode();
+    try {
+      verify(mFoo).hashCode();
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot verify call to", "java.lang.String java.lang.Object.toString()"})
   public void testVerifyToString_ShouldFail() {
     mFoo.toString();
-    verify(mFoo).toString();
+    try {
+      verify(mFoo).toString();
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot stub call to", "boolean java.lang.Object.equals(java.lang.Object)"})
   public void testStubEquals_ShouldFail() {
-    doReturn(false).when(mFoo).equals(null);
+    try {
+      doReturn(false).when(mFoo).equals(null);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot stub call to", "int java.lang.Object.hashCode()"})
   public void testStubHashCode_ShouldFail() {
-    doReturn(0).when(mFoo).hashCode();
+    try {
+      doReturn(0).when(mFoo).hashCode();
+      fail();
+    } catch (AssertionError expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = {"cannot stub call to", "java.lang.String java.lang.Object.toString()"})
   public void testStubToString_ShouldFail() {
-    doReturn("party").when(mFoo).toString();
+    try {
+      doReturn("party").when(mFoo).toString();
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testEqualsMethod_DoesntCountAsInteraction() {
@@ -1014,7 +1067,7 @@
           + "  mFoo.aBoolean()\n"
           + "  at " + singleLineStackTrace(verifyLineNumber) + "\n"
           + "\n"
-          + "No method calls happened to this mock\n";
+          + "No method calls happened on this mock\n";
       assertEquals(expectedMessage, e.getMessage());
     }
   }
@@ -1100,23 +1153,29 @@
     }
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testDoReturn_ThisShouldFailSinceDoubleIsNotAString() {
-    doReturn("hello").when(mFoo).aDouble();
+    try {
+      doReturn("hello").when(mFoo).aDouble();
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
   public void testDoReturn_ThisShouldPassSinceStringCanBeReturnedFromObjectMethod() {
     doReturn("hello").when(mFoo).anObject();
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testDoReturn_ThisShouldFailSinceObjectCantBeReturnedFromString() {
-    doReturn(new Object()).when(mFoo).aString();
+    try {
+      doReturn(new Object()).when(mFoo).aString();
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testDoReturn_ThisShouldFailSinceBarIsNotSubtypeOfBarSubtype() {
-    doReturn(mBar).when(mFoo).aBarSubtype();
+    try {
+      doReturn(mBar).when(mFoo).aBarSubtype();
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
   public void testDoReturn_ThisShouldPassSinceBarSubTypeIsABar() {
@@ -1132,10 +1191,12 @@
   // TODO(hugohudson): 7. Should fix this.
   // Once we fix the previous test we won't need this one.
   // I'm just demonstrating that currently this fails with NPE at use-time not at stub-time.
-  @ShouldThrow(NullPointerException.class)
   public void testDoReturn_ThisShouldFailBecauseNullIsNotAByte2() {
     doReturn(null).when(mFoo).aByte();
-    mFoo.aByte();
+    try {
+      mFoo.aByte();
+      fail();
+    } catch (NullPointerException expected) {}
   }
 
   public void testDoReturn_ThisShouldPassSinceNullIsAnObject() {
@@ -1155,30 +1216,36 @@
   // TODO(hugohudson): 7. Should fix this to give proper message.
   // We could at least give a good message saying why you get failure - saying that your string
   // is not a byte, and pointing to where you stubbed it.
-  @ShouldThrow(ClassCastException.class)
   public void testDoAnswer_ThisShouldFailSinceStringIsNotAByte2() {
     doAnswer(new Callable<String>() {
       @Override public String call() throws Exception { return "hi"; }
     }).when(mFoo).aByte();
-    mFoo.aByte();
+    try {
+      mFoo.aByte();
+      fail();
+    } catch (ClassCastException expected) {}
   }
 
-  @ShouldThrow(value = IllegalArgumentException.class,
-      messages = { "  (Bar) mFoo.aBar()" })
   public void testDoAnswer_ShouldHaveSimpleNameOnReturnValue() {
-    doReturn("hi").when(mFoo).aBar();
+    try {
+      doReturn("hi").when(mFoo).aBar();
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(IllegalArgumentException.class)
   public void testCantCreateMockOfNullType() {
-    mock(null);
+    try {
+      mock(null);
+      fail();
+    } catch (IllegalArgumentException expected) {}
   }
 
-  @ShouldThrow(value = AssertionError.class,
-      messages = { "Expected exactly 1 call to:", "onClickListener.onClick(Bar)" })
   public void testCreateMockWithNullFieldName() {
     OnClickListener mockClickListener = mock(OnClickListener.class);
-    verify(mockClickListener).onClick(null);
+    try {
+      verify(mockClickListener).onClick(null);
+      fail();
+    } catch (AssertionError expected) {}
   }
 
   public void testDoubleVerifyNoProblems() {
@@ -1191,10 +1258,185 @@
     verify(mFoo).aByte();
   }
 
-  // TODO(hugohudson): 5. Every @ShouldThrow method should be improved by adding test for the
-  // content of the error message.  First augment the annotation to take a String which must
-  // form a substring of the getMessage() for the Exception, then check that the exceptions
-  // thrown are as informative as possible.
+  public void testUnfinishedVerifyCaughtInTearDown_Issue5() {
+    verify(mFoo);
+    try {
+      checkForProgrammingErrorsDuringTearDown();
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testUnfinishedWhenCaughtInTearDown_Issue5() {
+    doThrow(new RuntimeException()).when(mFoo);
+    try {
+      checkForProgrammingErrorsDuringTearDown();
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testUnfinishedVerifyCaughtByStartingWhen_Issue5() {
+    verify(mFoo, never());
+    try {
+      doReturn(null).when(mFoo).clear();
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testUnfinishedWhenCaughtByStartingVerify_Issue5() {
+    doThrow(new RuntimeException()).when(mFoo);
+    try {
+      verify(mFoo).clear();
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testSecondUnfinishedVerifyShouldFailImmediately() throws Exception {
+    verify(mFoo);
+    try {
+      verify(mFoo);
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testSecondUnfinishedWhenShouldFailImmediately() throws Exception {
+    doReturn(null).when(mFoo);
+    try {
+      doReturn(null).when(mFoo);
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public void testVerifyWithTimeout_SuccessCase() throws Exception {
+    CountDownLatch countDownLatch = new CountDownLatch(1);
+    invokeBarMethodAfterLatchAwait(countDownLatch);
+    doReturn(null).when(mFoo).aBar();
+    verify(mFoo, never()).aBar();
+    countDownLatch.countDown();
+    verify(mFoo, timeout(100)).aBar();
+  }
+
+  public void testVerifyWithTimeout_FailureCase() throws Exception {
+    long start = System.currentTimeMillis();
+    try {
+      verify(mFoo, timeout(10)).aBar();
+      fail();
+    } catch (AssertionError expected) {}
+    long duration = System.currentTimeMillis() - start;
+    assertTrue(duration > 5);
+  }
+
+  public void testVerifyWithTimeoutMultipleInvocations_SuccessCase() throws Exception {
+    CountDownLatch countDownLatch = new CountDownLatch(1);
+    invokeBarMethodAfterLatchAwait(countDownLatch);
+    invokeBarMethodAfterLatchAwait(countDownLatch);
+    doReturn(null).when(mFoo).aBar();
+    verify(mFoo, never()).aBar();
+    countDownLatch.countDown();
+    verify(mFoo, timeout(100).times(2)).aBar();
+    verify(mFoo, timeout(100).atLeast(2)).aBar();
+    verify(mFoo, timeout(100).between(2, 4)).aBar();
+    verify(mFoo, timeout(100).atLeastOnce()).aBar();
+  }
+
+  public void testVerifyWithTimeoutMultipleInvocations_FailureCase() throws Exception {
+    long start = System.currentTimeMillis();
+    mFoo.aBar();
+    try {
+      verify(mFoo, timeout(10).between(2, 3)).aBar();
+      fail();
+    } catch (AssertionError expected) {}
+    long duration = System.currentTimeMillis() - start;
+    assertTrue(duration > 5);
+
+  }
+
+  public void testConcurrentModificationExceptions() throws Exception {
+    // This test concurrently stubs, verifies, and uses a mock.
+    // It used to totally reproducibly throw a ConcurrentModificationException.
+    Future<?> task1 = mExecutorService.submit(new Runnable() {
+      @Override
+      public void run() {
+        while (!Thread.currentThread().isInterrupted()) {
+          mFoo.aBar();
+          Thread.yield();
+        }
+      }
+    });
+    Future<?> task2 = mExecutorService.submit(new Runnable() {
+        @Override
+        public void run() {
+          while (!Thread.currentThread().isInterrupted()) {
+            verify(mFoo, anyTimes()).aBar();
+            Thread.yield();
+          }
+        }
+      });
+    Thread.sleep(20);
+    task1.cancel(true);
+    task2.cancel(true);
+    try {
+      task1.get();
+      fail();
+    } catch (CancellationException expected) {}
+    try {
+      task2.get();
+      fail();
+    } catch (CancellationException expected) {}
+  }
+
+  public void testCannotVerifyFromSecondThreadAfterStubbingInFirst() throws Exception {
+    doReturn(null).when(mFoo).aBar();
+    Future<?> submit = mExecutorService.submit(new Runnable() {
+      @Override
+      public void run() {
+        verify(mFoo, anyTimes()).aBar();
+      }
+    });
+    try {
+      submit.get();
+      fail();
+    } catch (ExecutionException expected) {
+      assertTrue(expected.getCause() instanceof IllegalStateException);
+    }
+  }
+
+  public void testCannotStubFromSecondThreadAfterVerifyingInFirst() throws Exception {
+    mExecutorService.submit(new Runnable() {
+      @Override
+      public void run() {
+        verify(mFoo, anyTimes()).aBar();
+      }
+    }).get();
+    try {
+      doReturn(null).when(mFoo).aBar();
+      fail();
+    } catch (IllegalStateException expected) {}
+  }
+
+  public class Jim {
+    public void bob() {
+      fail();
+    }
+  }
+
+  public void testMockingConcreteClasses() throws Exception {
+    Jim mock = mock(Jim.class);
+    mock.bob();
+  }
+
+  private Future<Void> invokeBarMethodAfterLatchAwait(final CountDownLatch countDownLatch) {
+    return mExecutorService.submit(new Callable<Void>() {
+      @Override
+      public Void call() throws Exception {
+        countDownLatch.await();
+        mFoo.aBar();
+        return null;
+      }
+    });
+  }
+
+  // TODO(hugohudson): 5. Every method that throws exceptions could be improved by adding
+  // test for the content of the error message.
 
   // TODO(hugohudson): 5. Add InOrder class, so that we can check that the given methods on
   // the given mocks happen in the right order.  It will be pretty easy to do.  The syntax
@@ -1258,14 +1500,8 @@
   //  //then
   //  assertThat(goods, containBread());
 
-  // TODO(hugohudson): 6. How about timeouts that are mentioned in Mockito docs?
-  // Sounds like a good idea.  Would look like this:
-  // verify(mFoo, within(50).milliseconds()).get(0);
-
-  // TODO(hugohudson): 6. Consider bringing back in the async code I wrote for the AndroidMock
-  // framework so that you can expect to wait for the method call.
-  // Although obviously we're more keen on encouraging people to write unit tests that don't
-  // require async behaviour in the first place.
+  // TODO: All unfinished verify and when statements should have sensible error messages telling
+  // you where the unfinished statement comes from.
 
   /** Returns the line number of the line following the method call. */
   private int getNextLineNumber() {
@@ -1307,4 +1543,12 @@
       }
     };
   }
+
+  private static <T> List<T> newList(T... things) {
+    ArrayList<T> list = new ArrayList<T>();
+    for (T thing : things) {
+      list.add(thing);
+    }
+    return list;
+  }
 }
