public function getOAuthAccessToken(PhabricatorExternalAccount $account, $force_refresh = false)
 {
     if ($account->getProviderKey() !== $this->getProviderKey()) {
         throw new Exception(pht('Account does not match provider!'));
     }
     if (!$force_refresh) {
         $access_expires = $account->getProperty('oauth.token.access.expires');
         $access_token = $account->getProperty('oauth.token.access');
         // Don't return a token with fewer than this many seconds remaining until
         // it expires.
         $shortest_token = 60;
         if ($access_token) {
             if ($access_expires === null || $access_expires > time() + $shortest_token) {
                 return $access_token;
             }
         }
     }
     $refresh_token = $account->getProperty('oauth.token.refresh');
     if ($refresh_token) {
         $adapter = $this->getAdapter();
         if ($adapter->supportsTokenRefresh()) {
             $adapter->refreshAccessToken($refresh_token);
             $this->synchronizeOAuthAccount($account);
             $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
             $account->save();
             unset($unguarded);
             return $account->getProperty('oauth.token.access');
         }
     }
     return null;
 }