code: public BoxAPIResponse send(ProgressListener listener) {
          if (this.api == null) {
              this.backoffCounter.reset(BoxGlobalSettings.getMaxRequestAttempts());
          } else {
              this.backoffCounter.reset(this.api.getMaxRequestAttempts());
          }
  
          while (this.backoffCounter.getAttemptsRemaining() > 0) {
              try {
                  return this.trySend(listener);
              } catch (BoxAPIException apiException) {
                  if (!this.backoffCounter.decrement() || !isResponseRetryable(apiException.getResponseCode())) {
                      throw apiException;
                  }
  
                  try {
                      this.resetBody();
                  } catch (IOException ioException) {
                      throw apiException;
                  }
  
                  try {
                      this.backoffCounter.waitBackoff();
                  } catch (InterruptedException interruptedException) {
                      Thread.currentThread().interrupt();
                      throw apiException;
                  }
              }
          }
  
          throw new RuntimeException();
      }
docs: Sends this request while monitoring its progress and returns a BoxAPIResponse containing the server's response.
  
  <p>A ProgressListener is generally only useful when the size of the request is known beforehand. If the size is
  unknown, then the ProgressListener will be updated for each byte sent, but the total number of bytes will be
  reported as 0.</p>
  
  <p> See {@link #send} for more information on sending requests.</p>
  
  @param  listener a listener for monitoring the progress of the request.
  @throws BoxAPIException if the server returns an error code or if a network error occurs.
  @return a {@link BoxAPIResponse} containing the server's response.