Index: java/main/src/test/java/com/framsticks/test/TestConfiguration.java
===================================================================
--- java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 90)
+++ java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 96)
@@ -1,6 +1,8 @@
 package com.framsticks.test;
 
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.log4j.Logger;
@@ -8,6 +10,12 @@
 import org.testng.annotations.*;
 
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.dispatching.Dispatcher;
-import com.framsticks.util.dispatching.RunAt;
+import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.Dispatching.Waiter;
+import com.framsticks.util.dispatching.ExceptionHandler;
+import com.framsticks.util.dispatching.ExceptionResultHandler;
+
+import static org.fest.assertions.Assertions.*;
 
 public class TestConfiguration {
@@ -21,70 +29,71 @@
 	}
 
-	private final List<AsyncAssert<?>> asyncAssertions = new LinkedList<AsyncAssert<?>>();
+	private final List<AssertionError> asyncAssertions = new LinkedList<>();
 
-	public class AsyncAssert<C> extends RunAt<C> {
-		final RunAt<? extends C> runnable;
-		boolean done = false;
-		AssertionError assertion;
+	public ExceptionHandler createExceptionHandler() {
+		return new ExceptionHandler() {
+			@Override
+			public boolean handle(Dispatcher<?> dispatcher, Throwable throwable) {
+				AssertionError ae;
+				if (AssertionError.class.isInstance(throwable)) {
+					ae = AssertionError.class.cast(throwable);
+				} else {
+					ae = new AssertionError();
+					ae.initCause(throwable);
+				}
+				synchronized (asyncAssertions) {
+					asyncAssertions.add(ae);
+				}
+				return true;
+			}
+		};
+	}
 
-		/**
-		 * @param runnable
-		 */
-		public AsyncAssert(RunAt<? extends C> runnable) {
-			this.runnable = runnable;
-		}
-
-		@Override
-		public void run() {
+	@AfterMethod
+	public void waitForWaiters() {
+		for (Waiter w : waiters) {
 			try {
-				runnable.run();
-			} catch (AssertionError e) {
-				assertion = e;
-			}
-			synchronized (this) {
-				done = true;
-				this.notifyAll();
+				w.waitFor();
+			} catch (FramsticksException e) {
+				AssertionError ae = new AssertionError();
+				ae.initCause(e);
+				asyncAssertions.add(ae);
 			}
 		}
 	}
 
-	public <C> void assertDispatch(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
-		AsyncAssert<C> assertion = new AsyncAssert<C>(runnable);
+	@AfterMethod(timeOut = 1000, dependsOnMethods = "waitForWaiters")
+	public void processAsyncAssertions() {
 		synchronized (asyncAssertions) {
-			asyncAssertions.add(assertion);
-		}
-		dispatcher.dispatch(assertion);
-	}
-
-	@BeforeMethod
-	public void clearAsyncAsserts() {
-		synchronized (asyncAssertions) {
-			asyncAssertions.clear();
+			if (asyncAssertions.isEmpty()) {
+				return;
+			}
+			AssertionError a = asyncAssertions.get(0);
+			asyncAssertions.remove(0);
+			throw a;
 		}
 	}
 
-	@AfterMethod(timeOut = 5000)
-	public void waitForAsyncAsserts() {
-		while (true) {
-			AsyncAssert<?> assertion;
-			synchronized (asyncAssertions) {
-				if (asyncAssertions.isEmpty()) {
-					return;
-				}
-				assertion = asyncAssertions.get(0);
-				asyncAssertions.remove(0);
+	final Set<Waiter> waiters = new HashSet<>();
+
+	@BeforeMethod
+	public void clearWaiters() {
+		waiters.clear();
+	}
+
+	protected Dispatching.Waiter produceWaiter(double timeOut) {
+		Waiter waiter = new Waiter(timeOut);
+		waiters.add(waiter);
+		return waiter;
+	}
+
+	public static ExceptionResultHandler failOnException() {
+		return new ExceptionResultHandler() {
+			@Override
+			public void handle(FramsticksException e) {
+				assertThat(e).isNull();
 			}
-			synchronized (assertion) {
-				while (!assertion.done) {
-					try {
-						assertion.wait();
-					} catch (InterruptedException ignored) {
-					}
-				}
-				if (assertion.assertion != null) {
-					throw assertion.assertion;
-				}
-			}
-		}
+		};
+
 	}
 }
