public boolean cancel(boolean mayInterruptIfRunning) {
   if (!cancelled.get() && innerFuture != null) {
     method.abort();
     try {
       asyncHandler.onThrowable(new CancellationException());
     } catch (Throwable t) {
       logger.debug("asyncHandler.onThrowable", t);
     }
     cancelled.set(true);
     if (reaperFuture != null) {
       reaperFuture.cancel(true);
     }
     super.done();
     return innerFuture.cancel(mayInterruptIfRunning);
   } else {
     super.done();
     return false;
   }
 }
  public void abort(Throwable t) {
    if (innerFuture != null) {
      innerFuture.cancel(true);
    }

    if (method != null) {
      method.abort();
    }

    if (reaperFuture != null) {
      reaperFuture.cancel(true);
    }

    exception.set(t);
    if (!timedOut.get() && !cancelled.get()) {
      try {
        asyncHandler.onThrowable(t);
      } catch (Throwable t2) {
        logger.debug("asyncHandler.onThrowable", t2);
      }
    }
    super.done();
  }
  @Override
  public <T> ListenableFuture<T> execute(Request request, AsyncHandler<T> handler)
      throws IOException {
    final Expectation expectation = expectations.get(new URL(request.getUrl()));
    if (expectation == null) {
      throw new RuntimeException("Unknown URL requested, failing test: " + request.getUrl());
    }
    fulfilledExpectations.add(expectation);
    T t = null;
    try {
      final URI uri = expectation.getUrl().toURI();
      handler.onStatusReceived(
          new HttpResponseStatus(uri, this) {
            @Override
            public int getStatusCode() {
              return expectation.getStatusCode();
            }

            @Override
            public String getStatusText() {
              return ""; // TODO
            }

            @Override
            public String getProtocolName() {
              return expectation.getUrl().getProtocol();
            }

            @Override
            public int getProtocolMajorVersion() {
              return 1;
            }

            @Override
            public int getProtocolMinorVersion() {
              return 1;
            }

            @Override
            public String getProtocolText() {
              return ""; // TODO
            }
          });
      handler.onHeadersReceived(
          new HttpResponseHeaders(uri, this) {
            @Override
            public FluentCaseInsensitiveStringsMap getHeaders() {
              return new FluentCaseInsensitiveStringsMap();
            }
          });
      handler.onBodyPartReceived(
          new HttpResponseBodyPart(uri, this) {
            @Override
            public byte[] getBodyPartBytes() {
              return expectation.getPayload().getBytes(Charset.forName("UTF-8"));
            }

            @Override
            public int writeTo(OutputStream outputStream) throws IOException {
              final byte[] bodyPartBytes = getBodyPartBytes();
              outputStream.write(bodyPartBytes);
              return bodyPartBytes.length;
            }

            @Override
            public ByteBuffer getBodyByteBuffer() {
              return ByteBuffer.wrap(getBodyPartBytes());
            }

            @Override
            public boolean isLast() {
              return true;
            }

            @Override
            public void markUnderlyingConnectionAsClosed() {}

            @Override
            public boolean closeUnderlyingConnection() {
              return true;
            }
          });
      t = handler.onCompleted();
    } catch (Exception e) {
      e
          .printStackTrace(); // To change body of catch statement use File | Settings | File
                              // Templates.
    }
    final T finalT = t;
    final Future<T> futureT =
        Executors.newSingleThreadExecutor()
            .submit(
                new Callable<T>() {
                  @Override
                  public T call() throws Exception {
                    return finalT;
                  }
                });
    return new ImmediateFuture<>(futureT);
  }