docs: public final boolean refreshToken() throws IOException {
      lock.lock();
      try {
        try {
          TokenResponse tokenResponse = executeRefreshToken();
          if (tokenResponse != null) {
            setFromTokenResponse(tokenResponse);
            for (CredentialRefreshListener refreshListener : refreshListeners) {
              refreshListener.onTokenResponse(this, tokenResponse);
            }
            return true;
          }
        } catch (TokenResponseException e) {
          boolean statusCode4xx = 400 <= e.getStatusCode() && e.getStatusCode() < 500;
          // check if it is a normal error response
          if (e.getDetails() != null && statusCode4xx) {
            // We were unable to get a new access token (e.g. it may have been revoked), we must now
            // indicate that our current token is invalid.
            setAccessToken(null);
            setExpiresInSeconds(null);
          }
          for (CredentialRefreshListener refreshListener : refreshListeners) {
            refreshListener.onTokenErrorResponse(this, e.getDetails());
          }
          if (statusCode4xx) {
            throw e;
          }
        }
        return false;
      } finally {
        lock.unlock();
      }
    }