protected function _finish($code, $originalRedirectUri)
 {
     $url = RequestUtil::buildUri($this->appInfo->getHost()->getApi(), "1/oauth2/token");
     $params = array("grant_type" => "authorization_code", "code" => $code, "redirect_uri" => $originalRedirectUri, "locale" => $this->userLocale);
     $curl = RequestUtil::mkCurlWithoutAuth($this->clientIdentifier, $url);
     // Add Basic auth header.
     $basic_auth = $this->appInfo->getKey() . ":" . $this->appInfo->getSecret();
     $curl->addHeader("Authorization: Basic " . base64_encode($basic_auth));
     $curl->set(CURLOPT_POST, true);
     $curl->set(CURLOPT_POSTFIELDS, RequestUtil::buildPostBody($params));
     $curl->set(CURLOPT_RETURNTRANSFER, true);
     $response = $curl->exec();
     if ($response->statusCode !== 200) {
         throw RequestUtil::unexpectedStatus($response);
     }
     $parts = RequestUtil::parseResponseJson($response->body);
     if (!array_key_exists('token_type', $parts) or !is_string($parts['token_type'])) {
         throw new Exception_BadResponse("Missing \"token_type\" field.");
     }
     $tokenType = $parts['token_type'];
     if (!array_key_exists('access_token', $parts) or !is_string($parts['access_token'])) {
         throw new Exception_BadResponse("Missing \"access_token\" field.");
     }
     $accessToken = $parts['access_token'];
     if (!array_key_exists('uid', $parts) or !is_string($parts['uid'])) {
         throw new Exception_BadResponse("Missing \"uid\" string field.");
     }
     $userId = $parts['uid'];
     if ($tokenType !== "Bearer" && $tokenType !== "bearer") {
         throw new Exception_BadResponse("Unknown \"token_type\"; expecting \"Bearer\", got  " . Client::q($tokenType));
     }
     return array($accessToken, $userId);
 }