Commits

Samuel Le Berrigaud  committed 25e7c83

Updating to 2.4-m1 of atlassian-util-concurrent, including the new Promise interface.

Change-Id: I0c75d03fa0f92e835358bc2a1d0f52bcfcfa2492

  • Participants
  • Parent commits 3b896f9

Comments (0)

Files changed (50)

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/cache/BulkPromise.java

 package com.atlassian.labs.remoteapps.api.service.cache;
 
-import com.atlassian.labs.remoteapps.api.Promise;
+import com.atlassian.util.concurrent.Promise;
 
 import java.util.concurrent.TimeUnit;
 

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/cache/PluginCache.java

 package com.atlassian.labs.remoteapps.api.service.cache;
 
-import com.atlassian.labs.remoteapps.api.Promise;
+import com.atlassian.util.concurrent.Promise;
 
 import java.util.Map;
 

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceAdminClient.java

 package com.atlassian.labs.remoteapps.api.service.confluence;
 
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.ServerInfo;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 import java.io.InputStream;
 

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceAttachmentClient.java

 
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.Attachment;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.MutableAttachment;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 import java.io.InputStream;
 

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceBlogClient.java

 import com.atlassian.labs.remoteapps.api.service.confluence.domain.BlogEntry;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.BlogEntrySummary;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.MutableBlogEntry;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  */

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceLabelClient.java

 import com.atlassian.labs.remoteapps.api.service.confluence.domain.MutableLabel;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SearchResult;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.Space;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  */

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceNotificationClient.java

 
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.ContentType;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.User;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  */

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluencePageClient.java

 import com.atlassian.labs.remoteapps.api.service.confluence.domain.RenderOptions;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SearchOptions;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SearchResult;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  *

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceSpaceClient.java

 import com.atlassian.labs.remoteapps.api.service.confluence.domain.Space;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SpacePermission;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SpaceSummary;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 import java.io.InputStream;
 

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/confluence/ConfluenceUserClient.java

 import com.atlassian.labs.remoteapps.api.service.confluence.domain.MutableUserInformation;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.User;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.UserInformation;
-import com.atlassian.labs.remoteapps.api.Promise;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  */

File api/src/main/java/com/atlassian/labs/remoteapps/api/service/http/HostXmlRpcClient.java

 package com.atlassian.labs.remoteapps.api.service.http;
 
-import com.atlassian.labs.remoteapps.api.Promise;
+import com.atlassian.util.concurrent.Promise;
 
 /**
  * Makes xml-rpc calls to the host using the {@link HostHttpClient}

File concurrent/pom.xml

 
     <dependencies>
         <dependency>
+            <groupId>com.atlassian.util.concurrent</groupId>
+            <artifactId>atlassian-util-concurrent</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <scope>compile</scope>

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/Deferred.java

 package com.atlassian.labs.remoteapps.api;
 
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
+import com.atlassian.util.concurrent.Promises;
+import com.google.common.base.Function;
 import com.google.common.util.concurrent.AbstractFuture;
 import com.google.common.util.concurrent.FutureCallback;
 
  *         // perform an async operation to get mydata, typically with a lower-level async api
  *         rawDataClient.get(id)
  *             // handle success case
- *             .done(new PromiseCallback<Map<String, Object>>() {
+ *             .done(new Effect<Map<String, Object>>() {
  *                 public void handle(Map<String, Object> value) {
  *                     // convert the result into the target type and resolve the deferred
  *                     deferred.resolve(myDataFromRawData(value));
      */
     private Deferred()
     {
-        promise = new WrappingPromise<V>(this);
+        promise = Promises.forListenableFuture(this);
     }
 
     /**
     }
 
     @Override
-    public Deferred<V> done(final PromiseCallback<V> callback)
+    public Deferred<V> onSuccess(final Effect<V> callback)
     {
-        promise.done(callback);
+        promise.onSuccess(callback);
         return this;
     }
 
     @Override
-    public Deferred<V> fail(final PromiseCallback<Throwable> callback)
+    public Deferred<V> onFailure(final Effect<Throwable> callback)
     {
-        promise.fail(callback);
+        promise.onFailure(callback);
         return this;
     }
 
     @Override
-    public Deferred<V> then(FutureCallback<V> callback)
+    public Deferred<V> on(FutureCallback<V> callback)
     {
-        promise.then(callback);
+        promise.on(callback);
         return this;
     }
+
+    @Override
+    public <T> Promise<T> map(Function<? super V, ? extends T> function)
+    {
+        return promise.map(function);
+    }
+
+    @Override
+    public <T> Promise<T> flatMap(Function<? super V, Promise<T>> function)
+    {
+        return promise.flatMap(function);
+    }
 }

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/Deferreds.java

+package com.atlassian.labs.remoteapps.api;
+
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
+
+public final class Deferreds
+{
+    private Deferreds()
+    {
+    }
+
+    /**
+     * Creates a new, resolved promise for the specified concrete value.
+     *
+     * @param value The value for which a promise should be created
+     * @return The new promise
+     */
+    public static <V> Promise<V> resolved(V value)
+    {
+        return Deferred.<V>create().resolve(value).promise();
+    }
+
+    public static Effect<Throwable> reject(final Deferred<?> deferred)
+    {
+        return new Effect<Throwable>()
+        {
+            @Override
+            public void apply(Throwable throwable)
+            {
+                deferred.reject(throwable);
+            }
+        };
+    }
+}

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/Promise.java

-package com.atlassian.labs.remoteapps.api;
-
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.ListenableFuture;
-
-/**
- * A promise that presents a nicer interface to {@link java.util.concurrent.Future}
- * // TODO move into the com.atlassian.labs.remoteapps.concurrent package when extracted out of the Remote Apps Plugin project
- */
-public interface Promise<V> extends ListenableFuture<V>
-{
-    /**
-     * Blocks the thread waiting for a result.  Exceptions are thrown as runtime exceptions.
-     *
-     * @return The promised object
-     */
-    V claim();
-
-    /**
-     * Registers a callback to be called when the promised object is available.  May not be executed
-     * in the same thread as the caller.
-     *
-     * @param callback The callback
-     * @return This object for chaining
-     */
-    Promise<V> done(PromiseCallback<V> callback);
-
-    /**
-     * Registers a callback to be called when an exception is thrown.  May not be executed
-     * in the same thread as the caller.
-     *
-     * @param callback The callback
-     * @return This object for chaining
-     */
-    Promise<V> fail(PromiseCallback<Throwable> callback);
-
-    /**
-     * Registers a FutureCallback to handle both done (success) and fail (exception) cases.
-     * May not be executed in the same thread as the caller.
-     *
-     * @param callback The future callback
-     * @return This object for chaining
-     */
-    Promise<V> then(FutureCallback<V> callback);
-}

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/PromiseCallback.java

-package com.atlassian.labs.remoteapps.api;
-
-/**
- * Callback for promise events
- * // TODO move into the com.atlassian.labs.remoteapps.concurrent package when extracted out of the Remote Apps Plugin project
- */
-public interface PromiseCallback<V>
-{
-    void handle(V value);
-}

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/Promises.java

-package com.atlassian.labs.remoteapps.api;
-
-import com.google.common.base.Function;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-import java.util.List;
-
-import static java.util.Arrays.asList;
-
-/**
- * Helper methods for working with promises
- */
-public final class Promises
-{
-    private Promises() { }
-
-    /**
-     * Returns a new promise representing the status of a list of other promises.
-     *
-     * @param promises The promises that the new promise should track
-     * @return The new, aggregate promise
-     */
-    public static <V> Promise<List<V>> when(Promise<? extends V>... promises)
-    {
-        return when(asList(promises));
-    }
-
-    /**
-     * Returns a new promise representing the status of a list of other promises.
-     *
-     * @param promises The promises that the new promise should track
-     * @return The new, aggregate promise
-     */
-    public static <V> Promise<List<V>> when(Iterable<? extends Promise<? extends V>> promises)
-    {
-        return toPromise(Futures.<V>allAsList(promises));
-    }
-
-    /**
-     * Creates a new, resolved promise for the specified concrete value.
-     *
-     * @param value The value for which a promise should be created
-     * @return The new promise
-     */
-    public static <V> Promise<V> toResolvedPromise(V value)
-    {
-        return Deferred.<V>create().resolve(value).promise();
-    }
-
-    /**
-     * Creates a new, rejected promise from the given Throwable and result type.
-     *
-     * @param t The throwable
-     * @param resultType The result type
-     * @return The new promise
-     */
-    public static <V> Promise<V> toRejectedPromise(Throwable t, Class<V> resultType)
-    {
-        return Deferred.<V>create().reject(t).promise();
-    }
-
-    /**
-     * Creates a promise from the given future.
-     *
-     * @param future The future delegte for the new promise
-     * @return The new promise
-     */
-    public static <V> Promise<V> toPromise(ListenableFuture<V> future)
-    {
-        return new WrappingPromise<V>(future);
-    }
-
-    /**
-     * Transforms a promise from one type to another by way of a transformation function.
-     *
-     * @param promise The promise to transform
-     * @param function THe transformation function
-     * @return The promise resulting from the transformation
-     */
-    public static <I, O> Promise<O> transform(Promise<I> promise, Function<? super I, ? extends O> function)
-    {
-        return toPromise(Futures.transform(promise, function));
-    }
-
-    /**
-     * Creates a new <code>PromiseCallback</code> that forwards a promise's fail events to
-     * the specified deferred delegate's <code>reject</code> method -- that is, the new
-     * callback rejects the delegate deferred if invoked.
-     *
-     * @param delegate The deferred to be rejected on a fail event
-     * @return The fail callback
-     */
-    public static PromiseCallback<Throwable> reject(final Deferred<?> delegate)
-    {
-        return new PromiseCallback<Throwable>()
-        {
-            @Override
-            public void handle(Throwable t)
-            {
-                delegate.reject(t);
-            }
-        };
-    }
-}

File concurrent/src/main/java/com/atlassian/labs/remoteapps/api/WrappingPromise.java

-package com.atlassian.labs.remoteapps.api;
-
-import com.google.common.util.concurrent.ForwardingListenableFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-import java.util.concurrent.ExecutionException;
-
-/**
- * Wraps a ListenableFuture to be a promise
- */
-final class WrappingPromise<V> extends ForwardingListenableFuture.SimpleForwardingListenableFuture<V> implements Promise<V>
-{
-    public WrappingPromise(ListenableFuture<V> delegate)
-    {
-        super(delegate);
-    }
-
-    @Override
-    public V claim()
-    {
-        try
-        {
-            return get();
-        }
-        catch (InterruptedException e)
-        {
-            throw new RuntimeException(e);
-        }
-        catch (ExecutionException e)
-        {
-            Throwable cause = e.getCause();
-            if (cause instanceof RuntimeException)
-            {
-                throw (RuntimeException) cause;
-            }
-            else
-            {
-                throw new RuntimeException(cause);
-            }
-        }
-    }
-
-    @Override
-    public Promise<V> done(final PromiseCallback<V> callback)
-    {
-        Futures.addCallback(this, new FutureCallback<V>()
-        {
-            @Override
-            public void onSuccess(V result)
-            {
-                callback.handle(result);
-            }
-
-            @Override
-            public void onFailure(Throwable t)
-            {
-                // no-op
-            }
-        });
-        return this;
-    }
-
-    @Override
-    public Promise<V> fail(final PromiseCallback<Throwable> callback)
-    {
-        Futures.addCallback(this, new FutureCallback<V>()
-        {
-            @Override
-            public void onSuccess(V result)
-            {
-                // no-op
-            }
-
-            @Override
-            public void onFailure(Throwable t)
-            {
-                callback.handle(t);
-            }
-        });
-        return this;
-    }
-
-    @Override
-    public Promise<V> then(FutureCallback<V> callback)
-    {
-        Futures.addCallback(this, callback);
-        return this;
-    }
-}

File container/src/main/resources/log4j.properties

 #log4j.rootCategory=INFO, CONSOLE, LOGFILE
 
 # Set the enterprise logger category to FATAL and its only appender to CONSOLE.
-#log4j.logger.com.atlassian.plugin=DEBUG
+log4j.logger.com.atlassian.plugin=DEBUG, CONSOLE
+log4j.additivity.com.atlassian.plugin = false
 
 #log4j.logger.com.atlassian.plugin.servlet=INFO
 #log4j.logger.org.apache.http.wire=DEBUG

File host-common/src/main/java/com/atlassian/labs/remoteapps/host/common/service/confluence/ClientInvocationHandler.java

  */
 
 import com.atlassian.labs.remoteapps.api.Deferred;
-import com.atlassian.labs.remoteapps.api.Promise;
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
-import com.atlassian.labs.remoteapps.api.Promises;
 import com.atlassian.labs.remoteapps.api.service.RequestContext;
 import com.atlassian.labs.remoteapps.api.service.http.*;
 import com.atlassian.labs.remoteapps.api.service.http.Response;
 import com.atlassian.labs.remoteapps.spi.util.RemoteName;
 import com.atlassian.labs.remoteapps.spi.util.RequirePermission;
 import com.atlassian.plugin.util.ChainingClassLoader;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
 import com.google.common.base.Function;
 import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.FutureCallback;
                     {
                         httpClient.newRequest(
                                 convertAbsoluteUrlToRelative(result))
-                                .get().ok(new PromiseCallback<Response>()
+                                .get().ok(new Effect<Response>()
                         {
                             @Override
-                            public void handle(Response value)
+                            public void apply(Response value)
                             {
                                 deferred.resolve(value.getEntityStream());
                             }
-                        }).others(new PromiseCallback<Response>()
+                        }).others(new Effect<Response>()
                         {
                             @Override
-                            public void handle(Response value)
+                            public void apply(Response value)
                             {
                                 deferred.reject(new UnexpectedResponseException(value));
                             }
-                        }).fail(new PromiseCallback<Throwable>()
+                        }).onFailure(new Effect<Throwable>()
                         {
                             @Override
-                            public void handle(Throwable value)
+                            public void apply(Throwable value)
                             {
                                 deferred.reject(value);
                             }
                 final Deferred<Object> deferred = Deferred.create();
 
                 Promise<Object> actualPromise = (Promise<Object>) returnValue;
-                actualPromise.then(new FutureCallback<Object>()
+                actualPromise.on(new FutureCallback<Object>()
                 {
                     @Override
                     public void onSuccess(Object result)

File host-common/src/main/java/com/atlassian/labs/remoteapps/host/common/service/http/DefaultHostXmlRpcClient.java

 package com.atlassian.labs.remoteapps.host.common.service.http;
 
 import com.atlassian.labs.remoteapps.api.Deferred;
+import com.atlassian.labs.remoteapps.api.Deferreds;
 import com.atlassian.labs.remoteapps.api.service.http.HostHttpClient;
 import com.atlassian.labs.remoteapps.api.service.http.HostXmlRpcClient;
 import com.atlassian.labs.remoteapps.api.service.http.Response;
 import com.atlassian.labs.remoteapps.api.service.http.XmlRpcException;
 import com.atlassian.labs.remoteapps.api.service.http.XmlRpcFault;
-import com.atlassian.labs.remoteapps.api.Promise;
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
 import com.atlassian.plugin.util.ChainingClassLoader;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
 import com.atlassian.xmlrpc.BindingException;
 import com.atlassian.xmlrpc.ServiceObject;
 import com.atlassian.xmlrpc.XmlRpcClientProvider;
-import com.google.common.util.concurrent.SettableFuture;
 import redstone.xmlrpc.XmlRpcMessages;
 import redstone.xmlrpc.XmlRpcSerializer;
 import redstone.xmlrpc.XmlRpcStruct;
 import java.net.URI;
 import java.util.Vector;
 
-import static com.atlassian.labs.remoteapps.api.Promises.*;
 import static java.lang.System.*;
 
 /**
                 .setContentCharset(XmlRpcMessages.getString("XmlRpcClient.Encoding"))
                 .setEntity(writer.toString())
                 .post()
-                .ok(new PromiseCallback<Response>()
+                .ok(new Effect<Response>()
                 {
                     @Override
-                    public void handle(Response response)
+                    public void apply(Response response)
                     {
                         try
                         {
                 })
                 // since xmlrpc should always return 200 OK responses unless an error has occurred,
                 // treat all other response codes as errors
-                .otherwise(reject(deferred));
+                .otherwise(Deferreds.reject(deferred));
         }
         catch (IOException ioe)
         {

File host-common/src/main/java/com/atlassian/labs/remoteapps/host/common/service/http/PromiseAwareXmlRpcInvocationHandler.java

  */
 
 import com.atlassian.labs.remoteapps.api.Deferred;
-import com.atlassian.labs.remoteapps.api.Promise;
+import com.atlassian.util.concurrent.Promise;
 import com.atlassian.xmlrpc.ServiceBean;
 import com.atlassian.xmlrpc.ServiceBeanField;
 import com.atlassian.xmlrpc.ServiceMethod;
 import java.util.Map;
 import java.util.Vector;
 
-import static com.atlassian.labs.remoteapps.api.Promises.toPromise;
-
 /**
  * {@link java.lang.reflect.InvocationHandler} for the XML-RPC service object proxy
  *
             final Deferred<Object> deferred = Deferred.create();
 
             Promise<Object> actualPromise = (Promise<Object>) returnValue;
-            actualPromise.then(new FutureCallback<Object>()
+            actualPromise.on(new FutureCallback<Object>()
             {
                 @Override
                 public void onSuccess(Object result)

File host-common/src/test/java/com/atlassian/labs/remoteapps/host/common/service/confluence/TestClientInvocationHandler.java

 package com.atlassian.labs.remoteapps.host.common.service.confluence;
 
+import com.atlassian.labs.remoteapps.api.Deferreds;
 import com.atlassian.labs.remoteapps.api.service.RequestContext;
 import com.atlassian.labs.remoteapps.api.service.confluence.ConfluenceLabelClient;
 import com.atlassian.labs.remoteapps.api.service.confluence.ConfluencePageClient;
 import com.atlassian.labs.remoteapps.api.service.confluence.domain.SpacePermission;
 import com.atlassian.labs.remoteapps.api.service.http.HostHttpClient;
 import com.atlassian.labs.remoteapps.api.service.http.HostXmlRpcClient;
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
-import com.atlassian.labs.remoteapps.api.Promises;
 import com.atlassian.labs.remoteapps.api.service.http.Request;
 import com.atlassian.labs.remoteapps.api.service.http.Response;
 import com.atlassian.labs.remoteapps.api.service.http.ResponsePromise;
 import com.atlassian.labs.remoteapps.spi.PermissionDeniedException;
 import com.atlassian.plugin.util.ChainingClassLoader;
+import com.atlassian.util.concurrent.Effect;
 import com.google.common.collect.ImmutableMap;
 import org.hamcrest.BaseMatcher;
 import org.hamcrest.Description;
                 .put("url", "http://example.com/foo")
                 .build();
         when(client.invoke("confluence2.getPageSummary", Object.class, "", "100")).thenReturn(
-                Promises.<Object>toResolvedPromise(data));
+                Deferreds.<Object>resolved(data));
 
         PageSummary page = confluencePageClient.getPageSummary(100L).claim();
         assertEquals(100L, page.getId());
         Map data = ImmutableMap.builder()
                 .put("id", "100")
                 .build();
-        when(client.invoke("confluence2.addLabelByObject", Object.class, "", data, "200")).thenReturn(Promises.<Object>toResolvedPromise(data));
+        when(client.invoke("confluence2.addLabelByObject", Object.class, "", data, "200")).thenReturn(Deferreds.<Object>resolved(data));
 
         MutableLabel label = newLabel();
         label.setId(100);
     public void testEnumInRequest()
     {
         when(client.invoke("confluence2.removePermissionFromSpace", Object.class, "", "COMMENT", "entityName", "DS")).thenReturn(
-                Promises.<Object>toResolvedPromise(null));
+                Deferreds.<Object>resolved(null));
 
         confluenceSpaceClient.removePermissionFromSpace(SpacePermission.COMMENT_PERMISSION, "entityName", "DS");
         verify(client, atLeastOnce()).invoke("confluence2.removePermissionFromSpace", Object.class, "", "COMMENT", "entityName", "DS");
         when(client.invoke(eq("confluence2.setContentPermissions"), eq(Object.class), eq(""),
                 eq("100"), eq("View"),
                 argThat(new CollectionsMatcher(permissions)))).thenReturn(
-                Promises.<Object>toResolvedPromise(null));
+                Deferreds.<Object>resolved(null));
 
         MutableContentPermission permission = newContentPermission();
         permission.setUserName("bob");
                 .build();
         when(client.invoke(eq("confluence2.getContentPermissionSet"), eq(Object.class), eq(""),
                 eq("100"), eq("View"))).thenReturn(
-                Promises.<Object>toResolvedPromise(contentPermissionSet));
+                Deferreds.<Object>resolved(contentPermissionSet));
 
         MutableContentPermission permission = newContentPermission();
         permission.setUserName("bob");
         when(requestContext.getHostBaseUrl()).thenReturn("http://localhost");
         when(client.invoke("confluence2.exportSpace", Object.class, "",
                 "DS", getEnumRemoteName(ExportType.HTML))).thenReturn(
-                Promises.<Object>toResolvedPromise("http://localhost/export"));
+                Deferreds.<Object>resolved("http://localhost/export"));
         Request request = mock(Request.class);
         when(httpClient.newRequest("/export"))
                 .thenReturn(request);
         when(response.getEntityStream()).thenReturn(bin);
         final ResponsePromise responsePromise = mock(ResponsePromise.class);
         when(request.get()).thenReturn(responsePromise);
-        when(responsePromise.others(any(PromiseCallback.class))).thenReturn(responsePromise);
-        when(responsePromise.fail(any(PromiseCallback.class))).thenReturn(responsePromise);
-        when(responsePromise.ok(any(PromiseCallback.class))).then(new Answer<Object>()
+        when(responsePromise.others(any(Effect.class))).thenReturn(responsePromise);
+        when(responsePromise.onFailure(any(Effect.class))).thenReturn(responsePromise);
+        when(responsePromise.ok(any(Effect.class))).then(new Answer<Object>()
         {
             @Override
             public Object answer(InvocationOnMock invocation) throws Throwable
             {
-                PromiseCallback<Response> callback = (PromiseCallback<Response>) invocation
+                Effect<Response> callback = (Effect<Response>) invocation
                         .getArguments()[0];
-                callback.handle(response);
+                callback.apply(response);
                 return responsePromise;
             }
         });
                 .build();
         when(client.invoke(eq("confluence2.getContentPermissionSet"), eq(Object.class), eq(""),
                 eq("100"), eq("View"))).thenReturn(
-                Promises.<Object>toResolvedPromise(contentPermissionSet));
+                Deferreds.<Object>resolved(contentPermissionSet));
 
         MutableContentPermission permission = newContentPermission();
         permission.setUserName("bob");
                 .put("contentStatus", "current")
                 .build();
         when(client.invoke("confluence2.getPage", Object.class, "", "100")).thenReturn(
-                Promises.<Object>toResolvedPromise(data));
+                Deferreds.<Object>resolved(data));
 
         Page page = confluencePageClient.getPage(100L).claim();
         assertEquals(100L, page.getId());
                 .put("url", "http://example.com/foo")
                 .build();
         when(client.invoke("confluence2.getPages", Object.class, "", "DS")).thenReturn(
-                Promises.<Object>toResolvedPromise(singletonList(data)));
+                Deferreds.<Object>resolved(singletonList(data)));
 
         Iterable<PageSummary> pageIterable = confluencePageClient.getPages("DS").claim();
         assertNotNull(pageIterable);

File http-client/src/main/java/com/atlassian/labs/remoteapps/api/service/http/BaseResponsePromise.java

 package com.atlassian.labs.remoteapps.api.service.http;
 
-import com.atlassian.labs.remoteapps.api.Promise;
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
 import com.google.common.util.concurrent.FutureCallback;
 
 /**
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> on(int statusCode, PromiseCallback<V> callback);
+    BaseResponsePromise<V> on(int statusCode, Effect<V> callback);
 
     // Informational (1xx) Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> informational(PromiseCallback<V> callback);
+    BaseResponsePromise<V> informational(Effect<V> callback);
 
     // Successful (2xx) Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> successful(PromiseCallback<V> callback);
+    BaseResponsePromise<V> successful(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'ok' (200) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> ok(PromiseCallback<V> callback);
+    BaseResponsePromise<V> ok(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'created' (201) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> created(PromiseCallback<V> callback);
+    BaseResponsePromise<V> created(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'no content' (204) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> noContent(PromiseCallback<V> callback);
+    BaseResponsePromise<V> noContent(Effect<V> callback);
 
     // Redirection (3xx) Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> redirection(PromiseCallback<V> callback);
+    BaseResponsePromise<V> redirection(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'see other' (303) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> seeOther(PromiseCallback<V> callback);
+    BaseResponsePromise<V> seeOther(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'not modified' (304) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> notModified(PromiseCallback<V> callback);
+    BaseResponsePromise<V> notModified(Effect<V> callback);
 
     // Client Error (4xx) Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> clientError(PromiseCallback<V> callback);
+    BaseResponsePromise<V> clientError(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'bad request' (400) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> badRequest(PromiseCallback<V> callback);
+    BaseResponsePromise<V> badRequest(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'unauthorized' (401) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> unauthorized(PromiseCallback<V> callback);
+    BaseResponsePromise<V> unauthorized(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'forbidden' (403) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> forbidden(PromiseCallback<V> callback);
+    BaseResponsePromise<V> forbidden(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'not found' (404) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> notFound(PromiseCallback<V> callback);
+    BaseResponsePromise<V> notFound(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'conflict' (409) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> conflict(PromiseCallback<V> callback);
+    BaseResponsePromise<V> conflict(Effect<V> callback);
 
     // Server Error (5xx) Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> serverError(PromiseCallback<V> callback);
+    BaseResponsePromise<V> serverError(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'internal server error' (500) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> internalServerError(PromiseCallback<V> callback);
+    BaseResponsePromise<V> internalServerError(Effect<V> callback);
 
     /**
      * Register a callback to respond to 'service unavailable' (503) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> serviceUnavailable(PromiseCallback<V> callback);
+    BaseResponsePromise<V> serviceUnavailable(Effect<V> callback);
 
     // Aggregate Selectors
 
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> error(PromiseCallback<V> callback);
+    BaseResponsePromise<V> error(Effect<V> callback);
 
     /**
      * Register a callback to respond to all non-'successful' (1xx, 3xx, 4xx, 5xx) HTTP responses.
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> notSuccessful(PromiseCallback<V> callback);
+    BaseResponsePromise<V> notSuccessful(Effect<V> callback);
 
     /**
      * Register a callback to respond to all other HTTP responses (i.e. those not explcitly registered for).
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> others(PromiseCallback<V> callback);
+    BaseResponsePromise<V> others(Effect<V> callback);
 
     /**
      * Registers the specified callback as a handler for both of the following events:
      * @param callback The callback
      * @return This instance for chaining
      */
-    BaseResponsePromise<V> otherwise(PromiseCallback<Throwable> callback);
+    BaseResponsePromise<V> otherwise(Effect<Throwable> callback);
 
     /**
      * Register a callback to respond to all completed (1xx, 2xx, 3xx, 4xx, and 5xx) HTTP responses.
      * @return This instance for chaining
      */
     @Override
-    BaseResponsePromise<V> done(PromiseCallback<V> callback);
+    BaseResponsePromise<V> onSuccess(Effect<V> callback);
 
     // Exception Selectors
 
      * @return This instance for chaining
      */
     @Override
-    BaseResponsePromise<V> fail(PromiseCallback<Throwable> callback);
+    BaseResponsePromise<V> onFailure(Effect<Throwable> callback);
 
     // Universal Selectors
 
      * @return This instance for chaining
      */
     @Override
-    BaseResponsePromise<V> then(FutureCallback<V> callback);
+    BaseResponsePromise<V> on(FutureCallback<V> callback);
 }

File http-client/src/main/java/com/atlassian/labs/remoteapps/api/service/http/WrappingBaseResponsePromise.java

 package com.atlassian.labs.remoteapps.api.service.http;
 
-import com.atlassian.labs.remoteapps.api.Promise;
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promise;
+import com.atlassian.util.concurrent.Promises;
+import com.google.common.base.Function;
 import com.google.common.util.concurrent.ForwardingListenableFuture;
 import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.Arrays;
 import java.util.Set;
 
-import static com.atlassian.labs.remoteapps.api.Promises.*;
 import static com.google.common.collect.Sets.*;
 
 abstract class WrappingBaseResponsePromise<V> extends ForwardingListenableFuture.SimpleForwardingListenableFuture<V> implements BaseResponsePromise<V>
 
     public WrappingBaseResponsePromise(ListenableFuture<V> delegate)
     {
-        super(toPromise(delegate));
+        super(Promises.forListenableFuture(delegate));
         this.statuses = newHashSet();
         this.statusSets = newHashSet();
     }
 
     @Override
-    public BaseResponsePromise<V> on(int statusCode, PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> on(int statusCode, Effect<V> callback)
     {
         statuses.add(statusCode);
-        done(newStatusSelector(statusCode, callback));
+        onSuccess(newStatusSelector(statusCode, callback));
         return this;
     }
 
     @Override
-    public BaseResponsePromise<V> informational(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> informational(Effect<V> callback)
     {
         return onRange(100, 200, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> successful(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> successful(Effect<V> callback)
     {
         return onRange(200, 300, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> ok(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> ok(Effect<V> callback)
     {
         return on(200, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> created(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> created(Effect<V> callback)
     {
         return on(201, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> noContent(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> noContent(Effect<V> callback)
     {
         return on(204, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> redirection(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> redirection(Effect<V> callback)
     {
         return onRange(300, 400, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> seeOther(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> seeOther(Effect<V> callback)
     {
         return on(303, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> notModified(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> notModified(Effect<V> callback)
     {
         return on(304, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> clientError(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> clientError(Effect<V> callback)
     {
         return onRange(400, 500, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> badRequest(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> badRequest(Effect<V> callback)
     {
         return on(400, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> unauthorized(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> unauthorized(Effect<V> callback)
     {
         return on(401, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> forbidden(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> forbidden(Effect<V> callback)
     {
         return on(403, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> notFound(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> notFound(Effect<V> callback)
     {
         return on(404, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> conflict(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> conflict(Effect<V> callback)
     {
         return on(409, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> serverError(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> serverError(Effect<V> callback)
     {
         return onRange(500, 600, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> internalServerError(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> internalServerError(Effect<V> callback)
     {
         return on(500, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> serviceUnavailable(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> serviceUnavailable(Effect<V> callback)
     {
         return on(503, callback);
     }
 
     @Override
-    public BaseResponsePromise<V> error(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> error(Effect<V> callback)
     {
         clientError(callback);
         serverError(callback);
     }
 
     @Override
-    public BaseResponsePromise<V> notSuccessful(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> notSuccessful(Effect<V> callback)
     {
         MultiRange multi = new MultiRange(new Range(100, 200), new Range(300, 600));
         statusSets.add(multi);
-        done(newStatusSetSelector(multi, callback));
+        onSuccess(newStatusSetSelector(multi, callback));
         return this;
     }
 
     @Override
-    public BaseResponsePromise<V> others(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> others(Effect<V> callback)
     {
-        done(newOthersSelector(statuses, statusSets, callback));
+        onSuccess(newOthersSelector(statuses, statusSets, callback));
         return this;
     }
 
     @Override
-    public V claim()
+    public final V claim()
     {
         return delegatePromise().claim();
     }
 
     @Override
-    public BaseResponsePromise<V> done(PromiseCallback<V> callback)
+    public final BaseResponsePromise<V> onSuccess(Effect<V> callback)
     {
-        delegatePromise().done(callback);
+        delegatePromise().onSuccess(callback);
         return this;
     }
 
     @Override
-    public BaseResponsePromise<V> fail(PromiseCallback<Throwable> callback)
+    public final BaseResponsePromise<V> onFailure(Effect<Throwable> callback)
     {
-        delegatePromise().fail(callback);
+        delegatePromise().onFailure(callback);
         return this;
     }
 
     @Override
-    public BaseResponsePromise<V> then(FutureCallback<V> callback)
+    public final BaseResponsePromise<V> on(FutureCallback<V> callback)
     {
-        delegatePromise().then(callback);
+        delegatePromise().on(callback);
         return this;
     }
 
-    protected Promise<V> delegatePromise()
+    @Override
+    public final <T> Promise<T> map(Function<? super V, ? extends T> function)
+    {
+        return Promises.forListenableFuture(Futures.transform(delegate(), function));
+    }
+
+    @Override
+    public final <T> Promise<T> flatMap(Function<? super V, Promise<T>> function)
+    {
+        return Promises.forListenableFuture(Futures.chain(delegate(), function));
+    }
+
+    protected final Promise<V> delegatePromise()
     {
         return (Promise<V>) delegate();
     }
 
-    protected abstract PromiseCallback<V> newStatusSelector(int statusCode, PromiseCallback<V> callback);
+    protected abstract Effect<V> newStatusSelector(int statusCode, Effect<V> callback);
 
-    protected abstract PromiseCallback<V> newStatusSetSelector(StatusSet statusSet, PromiseCallback<V> callback);
+    protected abstract Effect<V> newStatusSetSelector(StatusSet statusSet, Effect<V> callback);
 
-    protected abstract PromiseCallback<V> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, PromiseCallback<V> callback);
+    protected abstract Effect<V> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, Effect<V> callback);
 
-    private BaseResponsePromise<V> onRange(int lower, int upper, PromiseCallback<V> callback)
+    private BaseResponsePromise<V> onRange(int lower, int upper, Effect<V> callback)
     {
         Range range = new Range(lower, upper);
         statusSets.add(range);
-        done(newStatusSetSelector(range, callback));
+        onSuccess(newStatusSetSelector(range, callback));
         return this;
     }
 

File http-client/src/main/java/com/atlassian/labs/remoteapps/api/service/http/WrappingResponsePromise.java

 package com.atlassian.labs.remoteapps.api.service.http;
 
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promises;
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.HashSet;
 import java.util.Set;
 
-import static com.atlassian.labs.remoteapps.api.Promises.toPromise;
-
 /**
  * Extends WrappingBaseResponsePromise with the ResponsePromise interface
  */
 {
     public WrappingResponsePromise(ListenableFuture<Response> delegate)
     {
-        super(toPromise(delegate));
+        super(Promises.forListenableFuture(delegate));
     }
 
     @Override
-    public BaseResponsePromise<Response> otherwise(final PromiseCallback<Throwable> callback)
+    public BaseResponsePromise<Response> otherwise(final Effect<Throwable> callback)
     {
-        others(new PromiseCallback<Response>()
+        others(new Effect<Response>()
         {
             @Override
-            public void handle(Response response)
+            public void apply(Response response)
             {
-                callback.handle(new UnexpectedResponseException(response));
+                callback.apply(new UnexpectedResponseException(response));
             }
         });
-        fail(callback);
+        onFailure(callback);
         return this;
     }
 
     @Override
-    protected PromiseCallback<Response> newStatusSelector(int statusCode, PromiseCallback<Response> callback)
+    protected Effect<Response> newStatusSelector(int statusCode, Effect<Response> callback)
     {
         return new StatusSelector(statusCode, callback);
     }
 
     @Override
-    protected PromiseCallback<Response> newStatusSetSelector(StatusSet statusSet, PromiseCallback<Response> callback)
+    protected Effect<Response> newStatusSetSelector(StatusSet statusSet, Effect<Response> callback)
     {
         return new StatusSetSelector(statusSet, callback);
     }
 
     @Override
-    protected PromiseCallback<Response> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, PromiseCallback<Response> callback)
+    protected Effect<Response> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, Effect<Response> callback)
     {
         return new OthersSelector(statuses, statusSets, callback);
     }
 
-    private static class StatusSelector implements PromiseCallback<Response>
+    private static class StatusSelector implements Effect<Response>
     {
         private final int statusCode;
-        private final PromiseCallback<Response> callback;
+        private final Effect<Response> callback;
 
-        private StatusSelector(int statusCode, PromiseCallback<Response> callback)
+        private StatusSelector(int statusCode, Effect<Response> callback)
         {
             this.statusCode = statusCode;
             this.callback = callback;
         }
 
         @Override
-        public void handle(Response response)
+        public void apply(Response response)
         {
             if (response.getStatusCode() == statusCode)
             {
-                callback.handle(response);
+                callback.apply(response);
             }
         }
     }
 
-    private static class StatusSetSelector implements PromiseCallback<Response>
+    private static class StatusSetSelector implements Effect<Response>
     {
         private StatusSet statusSet;
-        private final PromiseCallback<Response> callback;
+        private final Effect<Response> callback;
 
-        private StatusSetSelector(StatusSet statusSet, PromiseCallback<Response> callback)
+        private StatusSetSelector(StatusSet statusSet, Effect<Response> callback)
         {
             this.statusSet = statusSet;
             this.callback = callback;
         }
 
         @Override
-        public void handle(Response response)
+        public void apply(Response response)
         {
             if (statusSet.contains(response.getStatusCode()))
             {
-                callback.handle(response);
+                callback.apply(response);
             }
         }
     }
 
-    private static class OthersSelector implements PromiseCallback<Response>
+    private static class OthersSelector implements Effect<Response>
     {
-        private final PromiseCallback<Response> callback;
+        private final Effect<Response> callback;
         private final Set<Integer> statuses;
         private final Set<StatusSet> statusSets;
 
-        private OthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, PromiseCallback<Response> callback)
+        private OthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, Effect<Response> callback)
         {
             this.statuses = new HashSet<Integer>(statuses);
             this.statusSets = new HashSet<StatusSet>(statusSets);
         }
 
         @Override
-        public void handle(Response response)
+        public void apply(Response response)
         {
             int status = response.getStatusCode();
             boolean inStatusSets = false;
             }
             if (!inStatusSets && !statuses.contains(status))
             {
-                callback.handle(response);
+                callback.apply(response);
             }
         }
     }

File http-client/src/main/java/com/atlassian/labs/remoteapps/api/service/http/WrappingResponsesPromise.java

 package com.atlassian.labs.remoteapps.api.service.http;
 
-import com.atlassian.labs.remoteapps.api.PromiseCallback;
+import com.atlassian.util.concurrent.Effect;
+import com.atlassian.util.concurrent.Promises;
 import com.google.common.util.concurrent.ListenableFuture;
 
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import static com.atlassian.labs.remoteapps.api.Promises.*;
-
 /**
  * Extends WrappingBaseResponsePromise with the ResponsesPromise interface
  */
 {
     public WrappingResponsesPromise(ListenableFuture<List<Response>> delegate)
     {
-        super(toPromise(delegate));
+        super(Promises.forListenableFuture(delegate));
     }
 
     @Override
-    public BaseResponsePromise<List<Response>> otherwise(final PromiseCallback<Throwable> callback)
+    public BaseResponsePromise<List<Response>> otherwise(final Effect<Throwable> callback)
     {
-        others(new PromiseCallback<List<Response>>()
+        others(new Effect<List<Response>>()
         {
             @Override
-            public void handle(List<Response> responses)
+            public void apply(List<Response> responses)
             {
-                callback.handle(new UnexpectedResponsesException(responses));
+                callback.apply(new UnexpectedResponsesException(responses));
             }
         });
-        fail(callback);
+        onFailure(callback);
         return this;
     }
 
     @Override
-    protected PromiseCallback<List<Response>> newStatusSelector(int statusCode, PromiseCallback<List<Response>> callback)
+    protected Effect<List<Response>> newStatusSelector(int statusCode, Effect<List<Response>> callback)
     {
         return new StatusSelector(statusCode, callback);
     }
 
     @Override
-    protected PromiseCallback<List<Response>> newStatusSetSelector(StatusSet statusSet, PromiseCallback<List<Response>> callback)
+    protected Effect<List<Response>> newStatusSetSelector(StatusSet statusSet, Effect<List<Response>> callback)
     {
         return new StatusSetSelector(statusSet, callback);
     }
 
     @Override
-    protected PromiseCallback<List<Response>> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, PromiseCallback<List<Response>> callback)
+    protected Effect<List<Response>> newOthersSelector(Set<Integer> statuses, Set<StatusSet> statusSets, Effect<List<Response>> callback)
     {
         return new OthersSelector(statuses, statusSets, callback);
     }
 
-    private static class StatusSelector implements PromiseCallback<List<Response>>
+    private static class StatusSelector implements Effect<List<Response>>
     {
         private final int statusCode;
-        private final PromiseCallback<List<Response>> callback;
+        private final Effect<List<Response>> callback;
 
-        private StatusSelector(int statusCode, PromiseCallback<List<Response>> callback)
+        private StatusSelector(int statusCode, Effect<List<Response>> callback)
         {
             this.statusCode = statusCode;
             this.callback = callback;
         }
 
         @Override
-        public void handle(List<Response> responses)
+        public void apply(List<Response> responses)
         {
             boolean allMatch = true;