code: @SuppressWarnings({"rawtypes", "unchecked"})
    public static <V> ListenableFuture<V> dereference(
        ListenableFuture<? extends ListenableFuture<? extends V>> nested) {
      return transformAsync((ListenableFuture) nested, (AsyncFunction) DEREFERENCER);
    }
docs: Returns a new {@code ListenableFuture} whose result is the product of calling {@code get()} on
  the {@code Future} nested within the given {@code Future}, effectively chaining the futures one
  after the other.  Example:
  
  <pre>   {@code
  SettableFuture<ListenableFuture<String>> nested = SettableFuture.create();
  ListenableFuture<String> dereferenced = dereference(nested);}</pre>
  
  <p>Most users will not need this method. To create a {@code Future} that completes with the
  result of another {@code Future}, create a {@link SettableFuture}, and call {@link
  SettableFuture#setFuture setFuture(otherFuture)} on it.
  
  <p>{@code dereference} has the same cancellation and execution semantics as {@link
  #transformAsync(ListenableFuture, AsyncFunction)}, in that the returned {@code Future}
  attempts to keep its cancellation state in sync with both the input {@code Future} and the
  nested {@code Future}.  The transformation is very lightweight and therefore takes place in
  the same thread (either the thread that called {@code dereference}, or the thread in which
  the dereferenced future completes).
  
  @param nested The nested future to transform.
  @return A future that holds result of the inner future.
  @since 13.0