api/src/main/java/net/signalr/client/util/concurrent/promise/Compose.java
public abstract class Compose<T, R> implements Continuation<T, R> {

    /**
     * Handles the compose continuation.
     * 
     * @param value The value.
     * @return The result.
     * @throws Exception
     */
    protected abstract Promise<R> doCompose(T value) throws Exception;

    /**
     * Handles the failure continuation.
     * 
     * @param cause The cause.
     * @throws Exception
     */
    protected void onFailure(final Throwable cause) throws Exception {
    }

    @Override
    public final void onSuccess(final T value, final Completable<? super R> result) throws Exception {
        final Promise<R> promise = doCompose(value);

        promise.then(result);
    }

    @Override
    public final void onFailure(final Throwable cause, final Completable<? super R> result) throws Exception {
        onFailure(cause);
        result.setFailure(cause);
    }
}
api/src/main/java/net/signalr/client/util/concurrent/promise/ExecuteOn.java
public final class ExecuteOn<T> implements Continuation<T, T> {

    /**
     * The private logger.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ExecuteOn.class);

    /**
     * The executor.
     */
    private final Executor _executor;

    /**
     * Initializes a new instance of the {@link ExecuteOn} class.
     * 
     * @param executor The executor.
     */
    public ExecuteOn(final Executor executor) {
        if (executor == null) {
            throw new IllegalArgumentException("Executor must not be null");
        }

        _executor = executor;
    }

    @Override
    public void onSuccess(final T value, final Completable<? super T> result) throws Exception {
        _executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    result.setSuccess(value);
                } catch (final Throwable t) {
                    LOGGER.warn("Failed to execute completable", t);
                }
            }
        });
    }

    @Override
    public void onFailure(final Throwable cause, final Completable<? super T> result) throws Exception {
        _executor.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    result.setFailure(cause);
                } catch (final Throwable t) {
                    LOGGER.warn("Failed to execute completable", t);
                }
            }
        });
    }
}
api/src/main/java/net/signalr/client/transport/Channel.java
public interface Channel {

    /**
     * Sends the specified message.
     * 
     * @param message The message.
     * @return The send result.
     */
    Promise<Void> send(String message);

    /**
     * Closes the channel.
     * 
     * @return The close result.
     */
    Promise<Void> close();
}
api/src/main/java/net/signalr/client/transport/TransportManager.java
public interface TransportManager extends Lifecycle<TransportContext>, ChannelHandler {

    /**
     * Returns the transport.
     * 
     * @return The transport.
     */
    Transport getTransport();

    /**
     * Adds the specified transport listener.
     * 
     * @param listener The transport listener.
     */
    void addTransportListener(TransportListener listener);

    /**
     * Removes the specified transport listener.
     * 
     * @param listener The transport listener.
     */
    void removeTransportListener(TransportListener listener);

    /**
     * Invoked when the connection has been lost.
     */
    void handleConnectionLost();

    /**
     * Invoked when the connection is slow.
     */
    void handleConnectionSlow();
}
api/src/main/java/net/signalr/client/util/concurrent/promise/Catch.java
public abstract class Catch<T> implements Continuation<T, T> {

    /**
     * Handles the success continuation.
     * 
     * @param value The value.
     * @throws Exception
     */
    protected void onSuccess(final T value) throws Exception {
    }

    /**
     * Handles the catch continuation.
     * 
     * @param cause The cause.
     * @return The result.
     * @throws Exception
     */
    protected abstract T doCatch(Throwable cause) throws Exception;

    @Override
    public final void onSuccess(final T value, final Completable<? super T> result) throws Exception {
        onSuccess(value);
        result.setSuccess(value);
    }

    @Override
    public final void onFailure(final Throwable cause, final Completable<? super T> result) throws Exception {
        final T value = doCatch(cause);

        result.setSuccess(value);
    }
}
api/src/main/java/net/signalr/client/util/concurrent/promise/OnFailure.java
public abstract class OnFailure<T> implements Continuation<T, T> {

    /**
     * Handles the failure continuation.
     * 
     * @param cause The cause.
     * @throws Exception
     */
    protected abstract void onFailure(Throwable cause) throws Exception;

    @Override
    public final void onSuccess(final T value, final Completable<? super T> result) throws Exception {
        result.setSuccess(value);
    }

    @Override
    public final void onFailure(final Throwable cause, final Completable<? super T> result) throws Exception {
        onFailure(cause);
        result.setFailure(cause);
    }
}
api/src/main/java/net/signalr/client/util/concurrent/promise/Deferred.java
public final class Deferred<T> implements Promise<T>, Completable<T> {

    /**
     * The private logger.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(Deferred.class);

    /**
     * The state of the deferred.
     */
    private final AtomicReference<State<T>> _state;

    /**
     * Initializes a new instance of the {@link Deferred} class.
     */
    public Deferred() {
        final State<T> initialState = new PendingState();

        _state = new AtomicReference<>(initialState);
    }

    /**
     * Initializes a new instance of the {@link Deferred} class.
     * 
     * @param value The value.
     */
    public Deferred(final T value) {
        final State<T> initialState = new SuccessState<>(value);

        _state = new AtomicReference<>(initialState);
    }

    /**
     * Initializes a new instance of the {@link Deferred} class.
     * 
     * @param cause The cause.
     */
    public Deferred(final Throwable cause) {
        if (cause == null) {
            throw new IllegalArgumentException("Cause must not be null");
        }

        final State<T> initialState = new FailureState<>(cause);

        _state = new AtomicReference<>(initialState);
    }

    /**
     * Tries to complete the deferred with the specified value.
     * 
     * @param value The value.
     * @return A value indicating whether the deferred has been completed.
     */
    public final boolean trySuccess(final T value) {
        return _state.get().trySuccess(value);
    }

    /**
     * Tries to complete the deferred with the specified cause.
     * 
     * @param cause The cause.
     * @return A value indicating whether the deferred has been completed.
     */
    public final boolean tryFailure(final Throwable cause) {
        if (cause == null) {
            throw new IllegalArgumentException("Cause must not be null");
        }

        return _state.get().tryFailure(cause);
    }

    @Override
    public void setSuccess(final T value) {
        if (!trySuccess(value)) {
            throw new IllegalStateException("Deferred is already complete");
        }
    }

    @Override
    public void setFailure(final Throwable cause) {
        if (!tryFailure(cause)) {
            throw new IllegalStateException("Deferred is already complete");
        }
    }

    @Override
    public final boolean isComplete() {
        return _state.get().isComplete();
    }

    @Override
    public void then(final Completable<? super T> completable) {
        if (completable == null) {
            throw new IllegalArgumentException("Completable must not be null");
        }

        _state.get().then(completable);
    }

    @Override
    public final <R> Promise<R> then(final Continuation<? super T, ? extends R> continuation) {
        if (continuation == null) {
            throw new IllegalArgumentException("Continuation must not be null");
        }

        final Deferred<R> result = new Deferred<>();

        _state.get().then(new Completable<T>() {
            @Override
            public void setSuccess(final T value) {
                try {
                    continuation.onSuccess(value, result);
                } catch (final Throwable t) {
                    result.setFailure(t);
                }
            }

            @Override
            public void setFailure(final Throwable cause) {
                try {
                    continuation.onFailure(cause, result);
                } catch (final Throwable t) {
                    t.addSuppressed(cause);
                    result.setFailure(t);
                }
            }
        });

        return result;
    }

    /**
     * Defines a state.
     * 
     * @param <T> The value type.
     */
    private interface State<T> {

        /**
         * Returns a value indicating whether the deferred is complete.
         * 
         * @return a value indicating whether the deferred is complete.
         */
        boolean isComplete();

        /**
         * Tries to complete the deferred with the specified value.
         * 
         * @param value The value.
         * @return A value indicating whether the deferred has been completed.
         */
        boolean trySuccess(T value);

        /**
         * Tries to complete the deferred with the specified cause.
         * 
         * @param cause The cause.
         * @return A value indicating whether the deferred has been completed.
         */
        boolean tryFailure(Throwable cause);

        /**
         * Adds the specified completable.
         * 
         * @param completable The completable.
         */
        void then(Completable<? super T> completable);
    }

    /**
     * Represents a pending state.
     */
    private final class PendingState implements State<T> {

        /**
         * The stage queue.
         */
        private final Queue<Stage<T>> _stages;

        /**
         * Initializes a new instance of the {@link PendingState} class.
         */
        public PendingState() {
            _stages = new ConcurrentLinkedQueue<>();
        }

        /**
         * Tries to change the state to the specified state.
         * 
         * @param state The state.
         * @return A value indicating whether the state has been changed.
         */
        private boolean tryChangeState(final State<T> state) {
            if (!_state.compareAndSet(this, state)) {
                return false;
            }
            completeStages(state);

            return true;
        }

        /**
         * Adds the specified stage.
         * 
         * @param stage The stage.
         */
        private void addStage(final Stage<T> stage) {
            // As the queue is unbounded, this method will never return false.
            _stages.offer(stage);
            // Trigger completion when the promise has been completed in the meantime.
            final State<T> state = _state.get();

            if (state.isComplete()) {
                completeStages(state);
            }
        }

        /**
         * Completes the stages with the specified state.
         * 
         * @param state The state.
         */
        private void completeStages(final State<T> state) {
            Stage<T> stage;

            while ((stage = _stages.poll()) != null) {
                try {
                    stage.complete(state);
                } catch (final Throwable t) {
                    LOGGER.warn("Failed to complete stage", t);
                }
            }
        }

        @Override
        public boolean isComplete() {
            return false;
        }

        @Override
        public boolean trySuccess(final T value) {
            final State<T> state = new SuccessState<>(value);

            return tryChangeState(state);
        }

        @Override
        public boolean tryFailure(final Throwable cause) {
            final State<T> state = new FailureState<>(cause);

            return tryChangeState(state);
        }

        @Override
        public void then(final Completable<? super T> completable) {
            final Stage<T> stage = new Stage<>(completable);

            addStage(stage);
        }
    }

    /**
     * Represents a complete state.
     * 
     * @param <T> The value type.
     */
    private abstract static class CompleteState<T> implements State<T> {

        @Override
        public boolean isComplete() {
            return true;
        }

        @Override
        public final boolean trySuccess(final T value) {
            return false;
        }

        @Override
        public final boolean tryFailure(final Throwable cause) {
            return false;
        }
    }

    /**
     * Represents a success state.
     * 
     * @param <T> The value type.
     */
    private static final class SuccessState<T> extends CompleteState<T> {

        /**
         * The value.
         */
        private final T _value;

        /**
         * Initializes a new instance of the {@link SuccessState} class.
         * 
         * @param value The value.
         */
        public SuccessState(final T value) {
            _value = value;
        }

        @Override
        public void then(final Completable<? super T> completable) {
            completable.setSuccess(_value);
        }
    }

    /**
     * Represents a failure state.
     * 
     * @param <T> The value type.
     */
    private static final class FailureState<T> extends CompleteState<T> {

        /**
         * The cause.
         */
        private final Throwable _cause;

        /**
         * Initializes a new instance of the {@link FailureState} class.
         * 
         * @param cause The cause.
         */
        public FailureState(final Throwable cause) {
            _cause = cause;
        }

        @Override
        public void then(final Completable<? super T> completable) {
            completable.setFailure(_cause);
        }
    }

    /**
     * Represents a stage.
     * 
     * @param <T> The value type.
     */
    private static final class Stage<T> {

        /**
         * The completable.
         */
        private final Completable<? super T> _completable;

        /**
         * A value indicating whether the stage completed.
         */
        private final AtomicBoolean _completed;

        /**
         * Initializes a new instance of the {@link Stage} class.
         * 
         * @param completable The completable.
         */
        public Stage(final Completable<? super T> completable) {
            _completable = completable;

            _completed = new AtomicBoolean(false);
        }

        /**
         * Completes the stage with the specified state.
         * 
         * @param state The state.
         */
        public void complete(final State<T> state) {
            if (_completed.compareAndSet(false, true)) {
                state.then(_completable);
            }
        }
    }
}
api/src/main/java/net/signalr/client/util/concurrent/promise/Promises.java
public final class Promises {

    /**
     * Initializes a new instance of the {@link Promises} class.
     */
    private Promises() {
    }

    /**
     * Returns a new success promise.
     * 
     * @return The promise.
     */
    public static Promise<Void> newSuccess() {
        return newSuccess(null);
    }

    /**
     * Returns a new success promise.
     * 
     * @param value The value.
     * @return The promise.
     */
    public static <T> Promise<T> newSuccess(final T value) {
        return new Deferred<>(value);
    }

    /**
     * Returns a new failure promise.
     * 
     * @param cause The cause.
     * @return The promise.
     */
    public static <T> Promise<T> newFailure(final Throwable cause) {
        return new Deferred<>(cause);
    }

    /**
     * Returns a new promise based on the execution of the specified runnable.
     * 
     * @param runnable The runnable.
     * @return The promise.
     */
    public static Promise<Void> newPromise(final Runnable runnable) {
        if (runnable == null) {
            throw new IllegalArgumentException("Runnable must not be null");
        }

        try {
            runnable.run();
        } catch (final Throwable t) {
            return newFailure(t);
        }

        return newSuccess();
    }

    /**
     * Returns a new promise based on the execution of the specified callable.
     * 
     * @param callable The callable.
     * @return The promise.
     */
    public static <V> Promise<V> newPromise(final Callable<V> callable) {
        if (callable == null) {
            throw new IllegalArgumentException("Callable must not be null");
        }

        try {
            final V value = callable.call();

            return newSuccess(value);
        } catch (final Throwable t) {
            return newFailure(t);
        }
    }

    /**
     * Awaits the specified promise.
     * 
     * @param promise The promise.
     * @return The value.
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static <T> T await(final Promise<T> promise) throws InterruptedException, ExecutionException {
        if (promise == null) {
            throw new IllegalArgumentException("Promise must not be null");
        }

        final CompletableFuture<T> future = new CompletableFuture<>();

        promise.then(future);

        return future.get();
    }

    /**
     * Awaits the specified promise.
     * 
     * @param promise The promise.
     * @param timeout The timeout.
     * @param timeUnit The time unit.
     * @return The value.
     * @throws InterruptedException
     * @throws ExecutionException
     * @throws TimeoutException
     */
    public static <T> T await(final Promise<T> promise, final long timeout, final TimeUnit timeUnit) throws InterruptedException, ExecutionException, TimeoutException {
        if (promise == null) {
            throw new IllegalArgumentException("Promise must not be null");
        }

        final CompletableFuture<T> future = new CompletableFuture<>();

        promise.then(future);

        return future.get(timeout, timeUnit);
    }

    /**
     * Returns a future for the specified promise.
     * 
     * @param promise The promise.
     * @return The future.
     */
    public static <T> Future<T> toFuture(final Promise<T> promise) {
        if (promise == null) {
            throw new IllegalArgumentException("Promise must not be null");
        }

        final CompletableFuture<T> future = new CompletableFuture<>();

        promise.then(future);

        return future;
    }
}
api/src/main/java/net/signalr/client/util/concurrent/promise/Promise.java
public interface Promise<T> {

    /**
     * Returns a value indicating whether the promise is complete.
     * 
     * @return A value indicating whether the promise is complete.
     */
    boolean isComplete();

    /**
     * Adds the specified completable.
     * 
     * @param completable The completable.
     */
    void then(Completable<? super T> completable);

    /**
     * Adds the specified continuation.
     * 
     * @param continuation The continuation.
     * @return The result.
     */
    <R> Promise<R> then(Continuation<? super T, ? extends R> continuation);
}
api/src/main/java/net/signalr/client/util/concurrent/promise/Accept.java
public abstract class Accept<T> implements Continuation<T, Void> {

    /**
     * Handles the accept continuation.
     * 
     * @param value The value.
     * @throws Exception
     */
    protected abstract void doAccept(T value) throws Exception;

    /**
     * Handles the failure continuation.
     * 
     * @param cause The cause.
     * @throws Exception
     */
    protected void onFailure(final Throwable cause) throws Exception {
    }

    @Override
    public void onSuccess(final T value, final Completable<? super Void> result) throws Exception {
        doAccept(value);
        result.setSuccess(null);
    }

    @Override
    public void onFailure(final Throwable cause, final Completable<? super Void> result) throws Exception {
        onFailure(cause);
        result.setFailure(cause);
    }
}
api/src/main/java/net/signalr/client/transport/Transport.java
public interface Transport extends Lifecycle<TransportContext> {

    /**
     * Returns the transport name.
     * 
     * @return the transport name.
     */
    String getName();

    /**
     * Negotiates the transport.
     * 
     * @param context The transport context.
     * @return The negotiation response.
     */
    Promise<NegotiationResponse> negotiate(TransportContext context);

    /**
     * Connects the transport.
     * 
     * @param context The transport context.
     * @param handler The channel handler.
     * @param reconnect A value indicating whether to reconnect.
     * @return The channel.
     */
    Promise<Channel> connect(TransportContext context, ChannelHandler handler, boolean reconnect);

    /**
     * Performs a transport ping.
     * 
     * @param context The transport context.
     * @return The ping response.
     */
    Promise<PingResponse> ping(TransportContext context);

    /**
     * Aborts the transport.
     * 
     * @param context The transport context.
     * @return The abort result.
     */
    Promise<Void> abort(TransportContext context);
}
api/src/main/java/net/signalr/client/util/concurrent/promise/OnComplete.java
public abstract class OnComplete<T> implements Continuation<T, T> {

    /**
     * Handles the success continuation.
     * 
     * @param value The value.
     * @throws Exception
     */
    protected void onSuccess(final T value) throws Exception {
        onComplete(value, null);
    }

    /**
     * Handles the failure continuation.
     * 
     * @param cause The cause.
     * @throws Exception
     */
    protected void onFailure(final Throwable cause) throws Exception {
        onComplete(null, cause);
    }

    /**
     * Handles the complete continuation.
     * 
     * @param cause The cause.
     * @throws Exception
     */
    protected void onComplete(final T value, final Throwable cause) throws Exception {
    }

    @Override
    public final void onSuccess(final T value, final Completable<? super T> result) throws Exception {
        onSuccess(value);
        result.setSuccess(value);
    }

    @Override
    public final void onFailure(final Throwable cause, final Completable<? super T> result) throws Exception {
        onFailure(cause);
        result.setFailure(cause);
    }
}


Question: import net.signalr.client.util.concurrent.promise.Promises;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.signalr.client.transport.Transport;
import net.signalr.client.transport.Channel;
import net.signalr.client.transport.TransportManager;
import net.signalr.client.util.concurrent.promise.Accept;
import net.signalr.client.util.concurrent.promise.Catch;
import net.signalr.client.util.concurrent.promise.Compose;
import net.signalr.client.util.concurrent.promise.Deferred;
import net.signalr.client.util.concurrent.promise.ExecuteOn;
import net.signalr.client.util.concurrent.promise.OnComplete;
import net.signalr.client.util.concurrent.promise.OnFailure;
import net.signalr.client.util.concurrent.promise.Promise;
/*
 * Copyright © Martin Tamme
 *
 * 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 net.signalr.client;



/**
 * Represents the connected connection state.
 */
final class ConnectedConnectionState implements ConnectionState {

    /**
     * The private logger.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectedConnectionState.class);

    /**
     * The channel.
     */
    private final Channel _channel;

    /**
     * A value indicating whether a reconnect occurred.
     */
    private final boolean _reconnect;

    /**
     * Initializes a new instance of the {@link ConnectedConnectionState} class.
     * 
     * @param channel The channel.
     * @param reconnect A value indicating whether a reconnect occurred.
     */
    public ConnectedConnectionState(final Channel channel, final boolean reconnect) {
        if (channel == null) {
            throw new IllegalArgumentException("Channel must not be null");
        }

        _channel = channel;
        _reconnect = reconnect;
    }

    @Override
    public boolean isConnected() {
        return true;
    }

    @Override
    public void addHeader(final ConnectionContext context, final String name, final String value) {
        throw new IllegalStateException("Connection is connected");
    }

    @Override
    public void addParameter(final ConnectionContext context, final String name, final String value) {
        throw new IllegalStateException("Connection is connected");
    }

    @Override
    public void setConnectionData(final ConnectionContext context, final String connectionData) {
        throw new IllegalStateException("Connection is connected");
    }

    @Override
    public void notifyConnectionListener(final ConnectionListener listener) {
        if (_reconnect) {
            listener.onReconnected();
        } else {
            listener.onConnected();
        }
    }

    @Override
    public Promise<Void> connect(final ConnectionContext context) {
        return Promises.newSuccess();
    }

    @Override
    public Promise<Void> reconnect(final ConnectionContext context) {
        final Deferred<Void> deferred = new Deferred<>();
        final ReconnectingConnectionState reconnecting = new ReconnectingConnectionState(deferred);

        if (!context.tryChangeConnectionState(this, reconnecting)) {
            return context.getConnectionState().reconnect(context);
        }
        final TransportManager manager = context.getTransportManager();
        final Transport transport = manager.getTransport();

        _channel.close().then(new Catch<Void>() {
            @Override
            protected Void doCatch(final Throwable cause) throws Exception {
                context.handleError(cause);

                return null;
            }
        }).then(new Compose<Void, Channel>() {
            @Override
            protected Promise<Channel> doCompose(final Void value) throws Exception {
                LOGGER.debug("Reconnecting transport...");

                return transport.connect(context, manager, true);
            }
Answer:         }).then(new ExecuteOn<Channel>(context.getExecutor())).then(new Accept<Channel>() {