private Object dispatch(Actor anActor, Message aMessage, boolean isAsking) {
		Object answer = null;

		Class<? extends Actor> actorType = anActor.getClass();

		Class<? extends Message> messageType = aMessage.getClass();

		String key = messageType.getName();

		Method whenMethod = null;

		synchronized (whenMethods) {

			whenMethod = whenMethods.get(key);

			if (whenMethod == null) {
				whenMethod = this.cacheWhenMethodFor(key, actorType, messageType);
			}
		}

		try {

			answer = whenMethod.invoke(anActor, aMessage);

		} catch (InvocationTargetException e) {
			if (e.getCause() != null) {
				throw new RuntimeException(
						"Method "
								+ WHEN_METHOD_NAME
								+ "("
								+ messageType.getSimpleName()
								+ ") failed. See cause: "
								+ e.getMessage(),
						e.getCause());
			}

			throw new RuntimeException(
						"Method "
							+ WHEN_METHOD_NAME
							+ "("
							+ messageType.getSimpleName()
							+ ") failed. See cause: "
							+ e.getMessage(),
						e);

		} catch (IllegalAccessException e) {
			throw new RuntimeException(
						"Method "
								+ WHEN_METHOD_NAME
								+ "("
								+ messageType.getSimpleName()
								+ ") failed because of illegal access. See cause: "
								+ e.getMessage(),
						e);
		}

		return answer;
	}