docs: private void executeWithRetry(final HttpMethod method) 
          throws IOException, HttpException {
          
          /** How many times did this transparently handle a recoverable exception? */
          int execCount = 0;
          // loop until the method is successfully processed, the retryHandler 
          // returns false or a non-recoverable exception is thrown
          try {
              while (true) {
                  execCount++;
                  try {
  
                      if (LOG.isTraceEnabled()) {
                          LOG.trace("Attempt number " + execCount + " to process request");
                      }
                      if (this.conn.getParams().isStaleCheckingEnabled()) {
                          this.conn.closeIfStale();
                      }
                      if (!this.conn.isOpen()) {
                          // this connection must be opened before it can be used
                          // This has nothing to do with opening a secure tunnel
                          this.conn.open();
                          boolean upgrade = isConnectionUpgrade(method);
                          if ((this.conn.isProxied() && (this.conn.isSecure() || upgrade))
                          && !(method instanceof ConnectMethod)) {
                              this.conn.setTunnelRequested(upgrade);
                              // we need to create a tunnel before we can execute the real method
                              if (!executeConnect()) {
                                  // abort, the connect method failed
                                  return;
                              }
                          }
                      }
                      applyConnectionParams(method);                    
                      method.execute(state, this.conn);
                      break;
                  } catch (HttpException e) {
                      // filter out protocol exceptions which cannot be recovered from
                      throw e;
                  } catch (IOException e) {
                      LOG.debug("Closing the connection.");
                      this.conn.close();
                      // test if this method should be retried
                      // ========================================
                      // this code is provided for backward compatibility with 2.0
                      // will be removed in the next major release
                      if (method instanceof HttpMethodBase) {
                          MethodRetryHandler handler = 
                              ((HttpMethodBase)method).getMethodRetryHandler();
                          if (handler != null) {
                              if (!handler.retryMethod(
                                      method,
                                      this.conn, 
                                      new HttpRecoverableException(e.getMessage()),
                                      execCount, 
                                      method.isRequestSent())) {
                                  LOG.debug("Method retry handler returned false. "
                                          + "Automatic recovery will not be attempted");
                                  throw e;
                              }
                          }
                      }
                      // ========================================
                      HttpMethodRetryHandler handler = 
                          (HttpMethodRetryHandler)method.getParams().getParameter(
                                  HttpMethodParams.RETRY_HANDLER);
                      if (handler == null) {
                          handler = new DefaultHttpMethodRetryHandler();
                      }
                      if (!handler.retryMethod(method, e, execCount)) {
                          LOG.debug("Method retry handler returned false. "
                                  + "Automatic recovery will not be attempted");
                          throw e;
                      }
                      if (LOG.isInfoEnabled()) {
                          LOG.info("I/O exception ("+ e.getClass().getName() +") caught when processing request: "
                                  + e.getMessage());
                      }
                      if (LOG.isDebugEnabled()) {
                          LOG.debug(e.getMessage(), e);
                      }
                      LOG.info("Retrying request");
                  }
              }
          } catch (IOException e) {
              if (this.conn.isOpen()) {
                  LOG.debug("Closing the connection.");
                  this.conn.close();
              }
              releaseConnection = true;
              throw e;
          } catch (RuntimeException e) {
              if (this.conn.isOpen()) {
                  LOG.debug("Closing the connection.");
                  this.conn.close();
              }
              releaseConnection = true;
              throw e;
          }
      }