public function sign(HttpRequest $request) {
    // add the developer key to the request before signing it
    if ($this->developerKey) {
      $requestUrl = $request->getUrl();
      $requestUrl .= (strpos($request->getUrl(), '?') === false) ? '?' : '&';
      $requestUrl .=  'key=' . urlencode($this->developerKey);
      $request->setUrl($requestUrl);
    }

    // Cannot sign the request without an OAuth access token.
    if (null == $this->accessToken && null == $this->assertionCredentials) {
      return $request;
    }

    // If the token is set to expire in the next 30 seconds (or has already
    // expired), refresh it and set the new token.
    $expired = (null == $this->accessToken) ||
        ($this->accessToken['created'] + ($this->accessToken['expires_in'] - 30)) < time();

    if ($expired) {
      if ($this->assertionCredentials) {
        $this->refreshTokenWithAssertion();
      } else {
        if (! array_key_exists('refresh_token', $this->accessToken)) {
            throw new Exception("The OAuth 2.0 access token has expired, "
                . "and a refresh token is not available. Refresh tokens are not "
                . "returned for responses that were auto-approved.");
        }
        $this->refreshToken($this->accessToken['refresh_token']);
      }
    }

    // Add the OAuth2 header to the request
    $request->setRequestHeaders(
        array('Authorization' => 'Bearer ' . $this->accessToken['access_token'])
    );

    return $request;
  }