IoFuture<Connection> connect(FutureResult<Connection> orig) {
   AtomicReference<FutureResult<Connection>> futureConnectionRef = this.futureConnectionRef;
   FutureResult<Connection> oldVal;
   oldVal = futureConnectionRef.get();
   if (oldVal != orig) {
     return oldVal.getIoFuture();
   }
   final FutureResult<Connection> futureResult = new FutureResult<>();
   while (!futureConnectionRef.compareAndSet(oldVal, futureResult)) {
     oldVal = futureConnectionRef.get();
     if (oldVal != orig) {
       // discard our new one
       return oldVal.getIoFuture();
     }
   }
   IoFuture<Connection> realFuture;
   try {
     realFuture = endpoint.connect(uri);
   } catch (IOException e) {
     realFuture = new FailedIoFuture<>(e);
   }
   splice(futureResult, realFuture);
   final IoFuture<Connection> ioFuture = futureResult.getIoFuture();
   ioFuture.addNotifier(HANDLER, this);
   return ioFuture;
 }
 void splice(FutureResult<Connection> futureResult, IoFuture<Connection> realFuture) {
   // always add in this order
   futureResult.addCancelHandler(realFuture);
   realFuture.addNotifier(IoUtils.resultNotifier(), futureResult);
 }