public function authorize(ClientInterface $http = null)
  {
    $credentials = null;
    $token = null;
    $scopes = null;
    if (null === $http) {
      $http = $this->getHttpClient();
    }

    // These conditionals represent the decision tree for authentication
    //   1.  Check for Application Default Credentials
    //   2.  Check for API Key
    //   3a. Check for an Access Token
    //   3b. If access token exists but is expired, try to refresh it
    if ($this->isUsingApplicationDefaultCredentials()) {
      $credentials = $this->createApplicationDefaultCredentials();
    } elseif ($token = $this->getAccessToken()) {
      $scopes = $this->prepareScopes();
      // add refresh subscriber to request a new token
      if (isset($token['refresh_token']) && $this->isAccessTokenExpired()) {
        $credentials = $this->createUserRefreshCredentials(
            $scopes,
            $token['refresh_token']
        );
      }
    }

    $authHandler = $this->getAuthHandler();

    if ($credentials) {
      $callback = $this->config['token_callback'];
      $http = $authHandler->attachCredentials($http, $credentials, $callback);
    } elseif ($token) {
      $http = $authHandler->attachToken($http, $token, (array) $scopes);
    } elseif ($key = $this->config['developer_key']) {
      $http = $authHandler->attachKey($http, $key);
    }

    return $http;
  }