public static MockHttpRequest deepCopy(HttpRequest request) throws IOException {
   MockHttpRequest mock = new MockHttpRequest();
   mock.uri = request.getUri();
   mock.httpHeaders = (ResteasyHttpHeaders) request.getHttpHeaders();
   mock.httpMethod = request.getHttpMethod();
   byte[] bytes = ReadFromStream.readFromStream(1024, request.getInputStream());
   mock.inputStream = new ByteArrayInputStream(bytes);
   return mock;
 }
  public ClientResponse cacheIfPossible(ClientRequest request, BaseClientResponse response)
      throws Exception {
    String cc = (String) response.getResponseHeaders().getFirst(HttpHeaders.CACHE_CONTROL);
    String exp = (String) response.getResponseHeaders().getFirst(HttpHeaders.EXPIRES);
    int expires = -1;

    if (cc != null) {
      CacheControl cacheControl = CacheControl.valueOf(cc);
      if (cacheControl.isNoCache()) return response;
      expires = cacheControl.getMaxAge();
    } else if (exp != null) {
      Date date = DateUtil.parseDate(exp);
      expires = (int) ((date.getTime() - System.currentTimeMillis()) / 1000);
    }

    String lastModified =
        (String) response.getResponseHeaders().getFirst(HttpHeaders.LAST_MODIFIED);
    String etag = (String) response.getResponseHeaders().getFirst(HttpHeaders.ETAG);

    String contentType = (String) response.getResponseHeaders().getFirst(HttpHeaders.CONTENT_TYPE);

    byte[] cached =
        ReadFromStream.readFromStream(1024, response.getStreamFactory().getInputStream());
    response.getStreamFactory().performReleaseConnection();

    MediaType mediaType = MediaType.valueOf(contentType);
    final BrowserCache.Entry entry =
        cache.put(
            request.getUri(),
            mediaType,
            response.getResponseHeaders(),
            cached,
            expires,
            etag,
            lastModified);

    response.setStreamFactory(new CachedStreamFactory(entry));

    return response;
  }
  /**
   * Store entity within a byte array input stream because we want to release the connection if a
   * ClientResponseFailure is thrown. Copy status and headers, but ignore all type information
   * stored in the ClientResponse.
   *
   * @param copy
   * @return
   */
  public static ClientResponse copyFromError(ClientResponse copy) {
    if (copy instanceof BaseClientResponse) {
      BaseClientResponse base = (BaseClientResponse) copy;
      InputStream is = null;
      if (copy.getResponseHeaders().containsKey("Content-Type")) {
        try {
          is = base.streamFactory.getInputStream();
          byte[] bytes = ReadFromStream.readFromStream(1024, is);
          is = new ByteArrayInputStream(bytes);
        } catch (IOException e) {
          // ignored
        }
      }
      final InputStream theIs = is;
      BaseClientResponse tmp =
          new BaseClientResponse(
              new BaseClientResponse.BaseClientResponseStreamFactory() {
                InputStream stream;

                public InputStream getInputStream() throws IOException {
                  return theIs;
                }

                public void performReleaseConnection() {}
              });
      tmp.executor = base.executor;
      tmp.status = base.status;
      tmp.providerFactory = base.providerFactory;
      tmp.headers = new CaseInsensitiveMap<String>();
      tmp.headers.putAll(base.headers);
      tmp.readerInterceptors = base.readerInterceptors;
      return tmp;
    } else {
      // Not sure how this codepath could ever be reached.
      InputStream is = null;
      if (copy.getResponseHeaders().containsKey("Content-Type")) {
        GenericType<byte[]> gt = new GenericType<byte[]>() {};
        try {
          byte[] bytes = (byte[]) copy.getEntity(gt);
          is = new ByteArrayInputStream(bytes);
        } catch (Exception ignore) {
        }
      }
      final InputStream theIs = is;
      BaseClientResponse tmp =
          new BaseClientResponse(
              new BaseClientResponse.BaseClientResponseStreamFactory() {
                InputStream stream;

                public InputStream getInputStream() throws IOException {
                  return theIs;
                }

                public void performReleaseConnection() {}
              });
      tmp.status = copy.getStatus();
      tmp.providerFactory = ResteasyProviderFactory.getInstance();
      tmp.headers = new CaseInsensitiveMap<String>();
      tmp.headers.putAll(copy.getResponseHeaders());
      tmp.headers.remove(
          "Content-Encoding"); // remove encoding because we will have already extracted byte array
      return tmp;
    }
  }