ExtendedSettableFuture extends AbstractFuture<V> { public void setAsync(ListenableFuture<? extends V> delegate) { delegate.addListener(() -> { if (super.isDone()) { return; } try { set(getDone(delegate)); } catch (ExecutionException e) { setException(e.getCause()); } catch (RuntimeException | Error e) { setException(e); } }, directExecutor()); super.addListener(() -> { if (super.isCancelled()) { delegate.cancel(super.wasInterrupted()); } }, directExecutor()); } private  ExtendedSettableFuture(); static ExtendedSettableFuture<V> create(); @Override boolean set(@Nullable V value); @Override boolean setException(Throwable throwable); void setAsync(ListenableFuture<? extends V> delegate);  }
@Test public void testSetAsync() throws Exception { ExtendedSettableFuture<String> fromFuture = ExtendedSettableFuture.create(); ExtendedSettableFuture<String> toFuture = ExtendedSettableFuture.create(); toFuture.setAsync(fromFuture); fromFuture.set("abc"); assertEquals(toFuture.get(), "abc"); fromFuture = ExtendedSettableFuture.create(); toFuture = ExtendedSettableFuture.create(); toFuture.setAsync(fromFuture); fromFuture.setException(new RuntimeException()); assertThrows(ExecutionException.class, toFuture::get); fromFuture = ExtendedSettableFuture.create(); toFuture = ExtendedSettableFuture.create(); toFuture.setAsync(fromFuture); toFuture.cancel(false); assertTrue(fromFuture.isCancelled()); assertFalse(fromFuture.checkWasInterrupted()); fromFuture = ExtendedSettableFuture.create(); toFuture = ExtendedSettableFuture.create(); toFuture.setAsync(fromFuture); toFuture.cancel(true); assertTrue(fromFuture.isCancelled()); assertTrue(fromFuture.checkWasInterrupted()); }