code: public static <V> void addCallback(
        final ListenableFuture<V> future,
        final FutureCallback<? super V> callback,
        Executor executor) {
      Preconditions.checkNotNull(callback);
      future.addListener(new CallbackListener<V>(future, callback), executor);
    }
docs: Registers separate success and failure callbacks to be run when the {@code Future}'s
  computation is {@linkplain java.util.concurrent.Future#isDone() complete} or, if the
  computation is already complete, immediately.
  
  <p>The callback is run on {@code executor}. There is no guaranteed ordering of execution of
  callbacks, but any callback added through this method is guaranteed to be called once the
  computation is complete.
  
  <p>Example:
  
  <pre>{@code
  ListenableFuture<QueryResult> future = ...;
  Executor e = ...
  addCallback(future,
  new FutureCallback<QueryResult>() {
  public void onSuccess(QueryResult result) {
  storeInCache(result);
  }
  public void onFailure(Throwable t) {
  reportError(t);
  }
  }, e);
  }</pre>
  
  <p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
  the discussion in the {@link ListenableFuture#addListener ListenableFuture.addListener}
  documentation. All its warnings about heavyweight listeners are also applicable to heavyweight
  callbacks passed to this method.
  
  <p>For a more general interface to attach a completion listener to a {@code Future}, see {@link
  ListenableFuture#addListener addListener}.
  
  @param future The future attach the callback to.
  @param callback The callback to invoke when {@code future} is completed.
  @param executor The executor to run {@code callback} when the future completes.
  @since 10.0