private HttpResponse executeRequest(
        final Callable<HttpResponse> task, final long timeout, final TimeUnit unit)
        throws TimeoutException, IOException {
      ExecutorService executor = Executors.newSingleThreadExecutor();
      try {
        Throwable lastCause = null;
        long endTime = System.currentTimeMillis() + unit.toMillis(timeout);
        while (System.currentTimeMillis() < endTime) {
          Future<HttpResponse> result = executor.submit(task);
          try {
            return result.get(timeout, unit);
          } catch (InterruptedException ex) {
            throw new IllegalStateException(ex);
          } catch (ExecutionException ex) {
            lastCause = ex.getCause();

            // HttpURLConnection throws FileNotFoundException on 404 so handle this
            if (lastCause instanceof FileNotFoundException) {
              HttpResponse httpResult = new HttpResponse();
              httpResult.setStatusCode(HttpURLConnection.HTTP_NOT_FOUND);
              return httpResult;
            } else {
              continue;
            }
          }
        }
        TimeoutException toex = new TimeoutException();
        if (lastCause != null) {
          toex.initCause(lastCause);
        }
        throw toex;
      } finally {
        executor.shutdownNow();
      }
    }