// Path: src/test/java/com/github/vbauer/caesar/basic/BasicRunnerTest.java
// public abstract class BasicRunnerTest extends BasicTest {
// 
//     protected static final String PARAMETER = "World";
// 
//     private final ThreadLocal<ExecutorService> executorServiceHolder = new ThreadLocal<>();
//     private final ThreadLocal<Sync> syncBeanHolder = new ThreadLocal<>();
//     private final ThreadLocal<CallbackAsync> callbackAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<FutureCallbackAsync> futureCallbackAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<FutureAsync> futureAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<ListenableFutureAsync> listenableFutureAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<ObservableAsync> observableAsyncHolder = new ThreadLocal<>();
// 
//     @Before
//     public final void before() {
//         final ExecutorService executor = Executors.newScheduledThreadPool(5);
//         final Sync sync = new Sync();
//         final CallbackAsync callbackAsync = AsyncProxyCreator.create(sync, CallbackAsync.class, executor, false);
//         final FutureCallbackAsync futureCallbackAsync = AsyncProxyCreator.create(sync, FutureCallbackAsync.class, executor, false);
//         final FutureAsync futureAsync = AsyncProxyCreator.create(sync, FutureAsync.class, executor, false);
//         final ListenableFutureAsync listenableFutureAsync = AsyncProxyCreator.create(sync, ListenableFutureAsync.class, executor, false);
//         final ObservableAsync observableAsync = AsyncProxyCreator.create(sync, ObservableAsync.class, executor, false);
// 
//         executorServiceHolder.set(executor);
//         syncBeanHolder.set(sync);
//         callbackAsyncHolder.set(callbackAsync);
//         futureCallbackAsyncHolder.set(futureCallbackAsync);
//         futureAsyncHolder.set(futureAsync);
//         listenableFutureAsyncHolder.set(listenableFutureAsync);
//         observableAsyncHolder.set(observableAsync);
//     }
// 
//     @After
//     public final void after() {
//         getExecutorService().shutdown();
//         executorServiceHolder.remove();
//         syncBeanHolder.remove();
//         callbackAsyncHolder.remove();
//         futureCallbackAsyncHolder.remove();
//         futureAsyncHolder.remove();
//         listenableFutureAsyncHolder.remove();
//         observableAsyncHolder.remove();
//     }
// 
// 
//     protected ExecutorService getExecutorService() {
//         return executorServiceHolder.get();
//     }
// 
//     protected Sync getSync() {
//         return syncBeanHolder.get();
//     }
// 
//     protected CallbackAsync getCallbackAsync() {
//         return callbackAsyncHolder.get();
//     }
// 
//     protected FutureCallbackAsync getFutureCallbackAsync() {
//         return futureCallbackAsyncHolder.get();
//     }
// 
//     protected FutureAsync getFutureAsync() {
//         return futureAsyncHolder.get();
//     }
// 
//     protected ListenableFutureAsync getListenableFutureAsync() {
//         return listenableFutureAsyncHolder.get();
//     }
// 
//     protected ObservableAsync getObservableAsync() {
//         return observableAsyncHolder.get();
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/callback/AsyncCallback.java
// public interface AsyncCallback<T> {
// 
//     /**
//      * Callback-method on success.
//      *
//      * @param result result of operation
//      */
//     void onSuccess(T result);
// 
//     /**
//      * Callback-method on failure.
//      *
//      * @param caught exception
//      */
//     void onFailure(Throwable caught);
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/callback/AsyncCallbackAdapter.java
// public class AsyncCallbackAdapter<T> implements AsyncCallback<T> {
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void onSuccess(final T result) {
//         // Do nothing.
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void onFailure(final Throwable caught) {
//         // Do nothing.
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/exception/MissedSyncMethodException.java
// @SuppressWarnings("serial")
// public class MissedSyncMethodException extends AbstractCaesarException {
// 
//     private final Method method;
//     private final Object[] arguments;
// 
// 
//     public MissedSyncMethodException(final Method method, final Object... arguments) {
//         this.method = method;
//         this.arguments = arguments;
//     }
// 
// 
//     public Method getMethod() {
//         return method;
//     }
// 
//     public Object[] getArguments() {
//         return arguments;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format(
//             "Can not find appropriate sync-method \"%s\", parameters: %s",
//             getMethod(), Arrays.toString(getArguments())
//         );
//     }
// 
// }


import com.github.vbauer.caesar.basic.BasicRunnerTest;
import com.github.vbauer.caesar.callback.AsyncCallback;
import com.github.vbauer.caesar.callback.AsyncCallbackAdapter;
import com.github.vbauer.caesar.exception.MissedSyncMethodException;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
        );
    }

    @Test
    public void test2ArgumentsWithResult() throws Throwable {
        Assert.assertTrue(
            check(
                callback -> getCallbackAsync().hello(callback, PARAMETER, PARAMETER),
                new AsyncCallbackAdapter<String>() {
                    @Override
                    public void onSuccess(final String result) {
                        Assert.assertEquals(getSync().hello(PARAMETER, PARAMETER), result);
                    }
                },
                true
            )
        );
    }

    @Test(expected = UnsupportedOperationException.class)
    public void testException() throws Throwable {
        Assert.assertTrue(
            check(
                callback -> getCallbackAsync().exception(callback),
                new AsyncCallbackAdapter<Void>(),
                true
            )
        );
    }

// Path: src/test/java/com/github/vbauer/caesar/basic/BasicRunnerTest.java
// public abstract class BasicRunnerTest extends BasicTest {
// 
//     protected static final String PARAMETER = "World";
// 
//     private final ThreadLocal<ExecutorService> executorServiceHolder = new ThreadLocal<>();
//     private final ThreadLocal<Sync> syncBeanHolder = new ThreadLocal<>();
//     private final ThreadLocal<CallbackAsync> callbackAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<FutureCallbackAsync> futureCallbackAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<FutureAsync> futureAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<ListenableFutureAsync> listenableFutureAsyncHolder = new ThreadLocal<>();
//     private final ThreadLocal<ObservableAsync> observableAsyncHolder = new ThreadLocal<>();
// 
//     @Before
//     public final void before() {
//         final ExecutorService executor = Executors.newScheduledThreadPool(5);
//         final Sync sync = new Sync();
//         final CallbackAsync callbackAsync = AsyncProxyCreator.create(sync, CallbackAsync.class, executor, false);
//         final FutureCallbackAsync futureCallbackAsync = AsyncProxyCreator.create(sync, FutureCallbackAsync.class, executor, false);
//         final FutureAsync futureAsync = AsyncProxyCreator.create(sync, FutureAsync.class, executor, false);
//         final ListenableFutureAsync listenableFutureAsync = AsyncProxyCreator.create(sync, ListenableFutureAsync.class, executor, false);
//         final ObservableAsync observableAsync = AsyncProxyCreator.create(sync, ObservableAsync.class, executor, false);
// 
//         executorServiceHolder.set(executor);
//         syncBeanHolder.set(sync);
//         callbackAsyncHolder.set(callbackAsync);
//         futureCallbackAsyncHolder.set(futureCallbackAsync);
//         futureAsyncHolder.set(futureAsync);
//         listenableFutureAsyncHolder.set(listenableFutureAsync);
//         observableAsyncHolder.set(observableAsync);
//     }
// 
//     @After
//     public final void after() {
//         getExecutorService().shutdown();
//         executorServiceHolder.remove();
//         syncBeanHolder.remove();
//         callbackAsyncHolder.remove();
//         futureCallbackAsyncHolder.remove();
//         futureAsyncHolder.remove();
//         listenableFutureAsyncHolder.remove();
//         observableAsyncHolder.remove();
//     }
// 
// 
//     protected ExecutorService getExecutorService() {
//         return executorServiceHolder.get();
//     }
// 
//     protected Sync getSync() {
//         return syncBeanHolder.get();
//     }
// 
//     protected CallbackAsync getCallbackAsync() {
//         return callbackAsyncHolder.get();
//     }
// 
//     protected FutureCallbackAsync getFutureCallbackAsync() {
//         return futureCallbackAsyncHolder.get();
//     }
// 
//     protected FutureAsync getFutureAsync() {
//         return futureAsyncHolder.get();
//     }
// 
//     protected ListenableFutureAsync getListenableFutureAsync() {
//         return listenableFutureAsyncHolder.get();
//     }
// 
//     protected ObservableAsync getObservableAsync() {
//         return observableAsyncHolder.get();
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/callback/AsyncCallback.java
// public interface AsyncCallback<T> {
// 
//     /**
//      * Callback-method on success.
//      *
//      * @param result result of operation
//      */
//     void onSuccess(T result);
// 
//     /**
//      * Callback-method on failure.
//      *
//      * @param caught exception
//      */
//     void onFailure(Throwable caught);
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/callback/AsyncCallbackAdapter.java
// public class AsyncCallbackAdapter<T> implements AsyncCallback<T> {
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void onSuccess(final T result) {
//         // Do nothing.
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public void onFailure(final Throwable caught) {
//         // Do nothing.
//     }
// 
// }
// 
// Path: src/main/java/com/github/vbauer/caesar/exception/MissedSyncMethodException.java
// @SuppressWarnings("serial")
// public class MissedSyncMethodException extends AbstractCaesarException {
// 
//     private final Method method;
//     private final Object[] arguments;
// 
// 
//     public MissedSyncMethodException(final Method method, final Object... arguments) {
//         this.method = method;
//         this.arguments = arguments;
//     }
// 
// 
//     public Method getMethod() {
//         return method;
//     }
// 
//     public Object[] getArguments() {
//         return arguments;
//     }
// 
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getMessage() {
//         return String.format(
//             "Can not find appropriate sync-method \"%s\", parameters: %s",
//             getMethod(), Arrays.toString(getArguments())
//         );
//     }
// 
// }


// Path: src/test/java/com/github/vbauer/caesar/runner/impl/AsyncCallbackMethodRunnerTest.java
import com.github.vbauer.caesar.basic.BasicRunnerTest;
import com.github.vbauer.caesar.callback.AsyncCallback;
import com.github.vbauer.caesar.callback.AsyncCallbackAdapter;
import com.github.vbauer.caesar.exception.MissedSyncMethodException;
import org.junit.Assert;
import org.junit.Test;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

        );
    }

    @Test
    public void test2ArgumentsWithResult() throws Throwable {
        Assert.assertTrue(
            check(
                callback -> getCallbackAsync().hello(callback, PARAMETER, PARAMETER),
                new AsyncCallbackAdapter<String>() {
                    @Override
                    public void onSuccess(final String result) {
                        Assert.assertEquals(getSync().hello(PARAMETER, PARAMETER), result);
                    }
                },
                true
            )
        );
    }

    @Test(expected = UnsupportedOperationException.class)
    public void testException() throws Throwable {
        Assert.assertTrue(
            check(
                callback -> getCallbackAsync().exception(callback),
                new AsyncCallbackAdapter<Void>(),
                true
            )
        );
    }

    @Test(expected = MissedSyncMethodException.class)