docs: @SuppressWarnings("deprecation")
    public HttpResponse execute() throws IOException {
      boolean retryRequest = false;
      Preconditions.checkArgument(numRetries >= 0);
      int retriesRemaining = numRetries;
      if (backOffPolicy != null) {
        // Reset the BackOffPolicy at the start of each execute.
        backOffPolicy.reset();
      }
      HttpResponse response = null;
      IOException executeException;
  
      Preconditions.checkNotNull(requestMethod);
      Preconditions.checkNotNull(url);
  
      Span span =
          tracer
              .spanBuilder(OpenCensusUtils.SPAN_NAME_HTTP_REQUEST_EXECUTE)
              .setRecordEvents(OpenCensusUtils.isRecordEvent())
              .startSpan();
      do {
        span.addAnnotation("retry #" + (numRetries - retriesRemaining));
        // Cleanup any unneeded response from a previous iteration
        if (response != null) {
          response.ignore();
        }
  
        response = null;
        executeException = null;
  
        // run the interceptor
        if (executeInterceptor != null) {
          executeInterceptor.intercept(this);
        }
        // build low-level HTTP request
        String urlString = url.build();
        addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_METHOD, requestMethod);
        addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_HOST, url.getHost());
        addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_PATH, url.getRawPath());
        addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_URL, urlString);
  
        LowLevelHttpRequest lowLevelHttpRequest = transport.buildRequest(requestMethod, urlString);
        Logger logger = HttpTransport.LOGGER;
        boolean loggable = loggingEnabled && logger.isLoggable(Level.CONFIG);
        StringBuilder logbuf = null;
        StringBuilder curlbuf = null;
        // log method and URL
        if (loggable) {
          logbuf = new StringBuilder();
          logbuf.append("-------------- REQUEST  --------------").append(StringUtils.LINE_SEPARATOR);
          logbuf
              .append(requestMethod)
              .append(' ')
              .append(urlString)
              .append(StringUtils.LINE_SEPARATOR);
  
          // setup curl logging
          if (curlLoggingEnabled) {
            curlbuf = new StringBuilder("curl -v --compressed");
            if (!requestMethod.equals(HttpMethods.GET)) {
              curlbuf.append(" -X ").append(requestMethod);
            }
          }
        }
        // add to user agent
        String originalUserAgent = headers.getUserAgent();
        if (!suppressUserAgentSuffix) {
          if (originalUserAgent == null) {
            headers.setUserAgent(USER_AGENT_SUFFIX);
            addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_USER_AGENT, USER_AGENT_SUFFIX);
          } else {
            String newUserAgent = originalUserAgent + " " + USER_AGENT_SUFFIX;
            headers.setUserAgent(newUserAgent);
            addSpanAttribute(span, HttpTraceAttributeConstants.HTTP_USER_AGENT, newUserAgent);
          }
        }
        OpenCensusUtils.propagateTracingContext(span, headers);
  
        // headers
        HttpHeaders.serializeHeaders(headers, logbuf, curlbuf, logger, lowLevelHttpRequest);
        if (!suppressUserAgentSuffix) {
          // set the original user agent back so that retries do not keep appending to it
          headers.setUserAgent(originalUserAgent);
        }
  
        // content
        StreamingContent streamingContent = content;
        final boolean contentRetrySupported = streamingContent == null || content.retrySupported();
        if (streamingContent != null) {
          final String contentEncoding;
          final long contentLength;
          final String contentType = content.getType();
          // log content
          if (loggable) {
            streamingContent =
                new LoggingStreamingContent(
                    streamingContent, HttpTransport.LOGGER, Level.CONFIG, contentLoggingLimit);
          }
          // encoding
          if (encoding == null) {
            contentEncoding = null;
            contentLength = content.getLength();
          } else {
            contentEncoding = encoding.getName();
            streamingContent = new HttpEncodingStreamingContent(streamingContent, encoding);
            contentLength = contentRetrySupported ? IOUtils.computeLength(streamingContent) : -1;
          }
          // append content headers to log buffer
          if (loggable) {
            if (contentType != null) {
              String header = "Content-Type: " + contentType;
              logbuf.append(header).append(StringUtils.LINE_SEPARATOR);
              if (curlbuf != null) {
                curlbuf.append(" -H '" + header + "'");
              }
            }
            if (contentEncoding != null) {
              String header = "Content-Encoding: " + contentEncoding;
              logbuf.append(header).append(StringUtils.LINE_SEPARATOR);
              if (curlbuf != null) {
                curlbuf.append(" -H '" + header + "'");
              }
            }
            if (contentLength >= 0) {
              String header = "Content-Length: " + contentLength;
              logbuf.append(header).append(StringUtils.LINE_SEPARATOR);
              // do not log @ curl as the user will most likely manipulate the content
            }
          }
          if (curlbuf != null) {
            curlbuf.append(" -d '@-'");
          }
          // send content information to low-level HTTP request
          lowLevelHttpRequest.setContentType(contentType);
          lowLevelHttpRequest.setContentEncoding(contentEncoding);
          lowLevelHttpRequest.setContentLength(contentLength);
          lowLevelHttpRequest.setStreamingContent(streamingContent);
        }
        // log from buffer
        if (loggable) {
          logger.config(logbuf.toString());
          if (curlbuf != null) {
            curlbuf.append(" -- '");
            curlbuf.append(urlString.replaceAll("\'", "'\"'\"'"));
            curlbuf.append("'");
            if (streamingContent != null) {
              curlbuf.append(" << $$$");
            }
            logger.config(curlbuf.toString());
          }
        }
  
        // We need to make sure our content type can support retry
        // null content is inherently able to be retried
        retryRequest = contentRetrySupported && retriesRemaining > 0;
  
        // execute
        lowLevelHttpRequest.setTimeout(connectTimeout, readTimeout);
        lowLevelHttpRequest.setWriteTimeout(writeTimeout);
  
        // switch tracing scope to current span
        @SuppressWarnings("MustBeClosedChecker")
        Scope ws = tracer.withSpan(span);
        OpenCensusUtils.recordSentMessageEvent(span, lowLevelHttpRequest.getContentLength());
        try {
          LowLevelHttpResponse lowLevelHttpResponse = lowLevelHttpRequest.execute();
          if (lowLevelHttpResponse != null) {
            OpenCensusUtils.recordReceivedMessageEvent(span, lowLevelHttpResponse.getContentLength());
          }
          // Flag used to indicate if an exception is thrown before the response is constructed.
          boolean responseConstructed = false;
          try {
            response = new HttpResponse(this, lowLevelHttpResponse);
            responseConstructed = true;
          } finally {
            if (!responseConstructed) {
              InputStream lowLevelContent = lowLevelHttpResponse.getContent();
              if (lowLevelContent != null) {
                lowLevelContent.close();
              }
            }
          }
        } catch (IOException e) {
          if (!retryOnExecuteIOException
              && (ioExceptionHandler == null
                  || !ioExceptionHandler.handleIOException(this, retryRequest))) {
            throw e;
          }
          // Save the exception in case the retries do not work and we need to re-throw it later.
          executeException = e;
          if (loggable) {
            logger.log(Level.WARNING, "exception thrown while executing request", e);
          }
        } finally {
          ws.close();
        }
  
        // Flag used to indicate if an exception is thrown before the response has completed
        // processing.
        boolean responseProcessed = false;
        try {
          if (response != null && !response.isSuccessStatusCode()) {
            boolean errorHandled = false;
            if (unsuccessfulResponseHandler != null) {
              // Even if we don't have the potential to retry, we might want to run the
              // handler to fix conditions (like expired tokens) that might cause us
              // trouble on our next request
              errorHandled = unsuccessfulResponseHandler.handleResponse(this, response, retryRequest);
            }
            if (!errorHandled) {
              if (handleRedirect(response.getStatusCode(), response.getHeaders())) {
                // The unsuccessful request's error could not be handled and it is a redirect request.
                errorHandled = true;
              } else if (retryRequest
                  && backOffPolicy != null
                  && backOffPolicy.isBackOffRequired(response.getStatusCode())) {
                // The unsuccessful request's error could not be handled and should be backed off
                // before retrying
                long backOffTime = backOffPolicy.getNextBackOffMillis();
                if (backOffTime != BackOffPolicy.STOP) {
                  try {
                    sleeper.sleep(backOffTime);
                  } catch (InterruptedException exception) {
                    // ignore
                  }
                  errorHandled = true;
                }
              }
            }
            // A retry is required if the error was successfully handled or if it is a redirect
            // request or if the back off policy determined a retry is necessary.
            retryRequest &= errorHandled;
            // need to close the response stream before retrying a request
            if (retryRequest) {
              response.ignore();
            }
          } else {
            // Retry is not required for a successful status code unless the response is null.
            retryRequest &= (response == null);
          }
          // Once there are no more retries remaining, this will be -1
          // Count redirects as retries, we want a finite limit of redirects.
          retriesRemaining--;
  
          responseProcessed = true;
        } finally {
          if (response != null && !responseProcessed) {
            response.disconnect();
          }
        }
      } while (retryRequest);
      span.end(OpenCensusUtils.getEndSpanOptions(response == null ? null : response.getStatusCode()));
  
      if (response == null) {
        // Retries did not help resolve the execute exception, re-throw it.
        throw executeException;
      }
      // response interceptor
      if (responseInterceptor != null) {
        responseInterceptor.interceptResponse(response);
      }
      // throw an exception if unsuccessful response
      if (throwExceptionOnExecuteError && !response.isSuccessStatusCode()) {
        try {
          throw new HttpResponseException(response);
        } finally {
          response.disconnect();
        }
      }
      return response;
    }