// Path: github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthProtocol.java
// public static class AccessToken {
//   public String accessToken;
//   public String tokenType;
//   public String error;
//   public String errorDescription;
//   public String errorUri;
//   public String raw;
// 
//   public AccessToken() {}
// 
//   public AccessToken(String token) {
//     this(token, "");
//   }
// 
//   public AccessToken(String token, String type) {
//     this();
//     this.accessToken = token;
//     this.tokenType = type;
//   }
// 
//   @Override
//   public String toString() {
//     if (isError()) {
//       return "Error AccessToken [error="
//           + error
//           + ", error_description="
//           + errorDescription
//           + ", error_uri="
//           + errorUri
//           + "]";
//     }
//     return "AccessToken [access_token=" + accessToken + ", token_type=" + tokenType + "]";
//   }
// 
//   @Override
//   public int hashCode() {
//     return Objects.hash(accessToken, tokenType, error, errorDescription, errorUri);
//   }
// 
//   @Override
//   public boolean equals(Object obj) {
//     if (obj == null) {
//       return false;
//     }
//     if (getClass() != obj.getClass()) {
//       return false;
//     }
//     final AccessToken other = (AccessToken) obj;
//     return Objects.equals(this.accessToken, other.accessToken)
//         && Objects.equals(this.raw, other.raw)
//         && Objects.equals(this.tokenType, other.tokenType);
//   }
// 
//   public boolean isError() {
//     return !Strings.isNullOrEmpty(error);
//   }
// 
//   public String getRaw() {
//     return raw;
//   }
// 
//   public void setRaw(String raw) {
//     this.raw = raw;
//   }
// 
//   public OAuthToken toOAuthToken() {
//     return new OAuthToken(accessToken, null, getRaw());
//   }
// }


import com.google.gerrit.common.Nullable;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol.AccessToken;
import java.io.IOException;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

  @Override
  public GitHubLogin get() {
    IdentifiedUser currentUser = userProvider.get();
    return get(currentUser.getUserName().get());
  }

  @Override
  @Nullable
  public GitHubLogin get(String username) {
    try {
      AccessToken accessToken = newAccessTokenFromUser(username);
      if (accessToken != null) {
        GitHubLogin login = new GitHubLogin(config, httpConnector);
        login.login(accessToken);
        return login;
      }
      return null;
    } catch (IOException e) {
      log.error("Cannot login to GitHub as '" + username + "'", e);
      return null;
    }
  }

  private AccessToken newAccessTokenFromUser(String username) {
    AccountState account = accountCache.getByUsername(username).get();
    Collection<ExternalId> externalIds = account.externalIds();
    for (ExternalId accountExternalId : externalIds) {
      String key = accountExternalId.key().get();
      if (key.startsWith(EXTERNAL_ID_PREFIX)) {
// Path: github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/OAuthProtocol.java
// public static class AccessToken {
//   public String accessToken;
//   public String tokenType;
//   public String error;
//   public String errorDescription;
//   public String errorUri;
//   public String raw;
// 
//   public AccessToken() {}
// 
//   public AccessToken(String token) {
//     this(token, "");
//   }
// 
//   public AccessToken(String token, String type) {
//     this();
//     this.accessToken = token;
//     this.tokenType = type;
//   }
// 
//   @Override
//   public String toString() {
//     if (isError()) {
//       return "Error AccessToken [error="
//           + error
//           + ", error_description="
//           + errorDescription
//           + ", error_uri="
//           + errorUri
//           + "]";
//     }
//     return "AccessToken [access_token=" + accessToken + ", token_type=" + tokenType + "]";
//   }
// 
//   @Override
//   public int hashCode() {
//     return Objects.hash(accessToken, tokenType, error, errorDescription, errorUri);
//   }
// 
//   @Override
//   public boolean equals(Object obj) {
//     if (obj == null) {
//       return false;
//     }
//     if (getClass() != obj.getClass()) {
//       return false;
//     }
//     final AccessToken other = (AccessToken) obj;
//     return Objects.equals(this.accessToken, other.accessToken)
//         && Objects.equals(this.raw, other.raw)
//         && Objects.equals(this.tokenType, other.tokenType);
//   }
// 
//   public boolean isError() {
//     return !Strings.isNullOrEmpty(error);
//   }
// 
//   public String getRaw() {
//     return raw;
//   }
// 
//   public void setRaw(String raw) {
//     this.raw = raw;
//   }
// 
//   public OAuthToken toOAuthToken() {
//     return new OAuthToken(accessToken, null, getRaw());
//   }
// }


// Path: github-oauth/src/main/java/com/googlesource/gerrit/plugins/github/oauth/IdentifiedUserGitHubLoginProvider.java
import com.google.gerrit.common.Nullable;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.googlesource.gerrit.plugins.github.oauth.OAuthProtocol.AccessToken;
import java.io.IOException;
import java.util.Collection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


  @Override
  public GitHubLogin get() {
    IdentifiedUser currentUser = userProvider.get();
    return get(currentUser.getUserName().get());
  }

  @Override
  @Nullable
  public GitHubLogin get(String username) {
    try {
      AccessToken accessToken = newAccessTokenFromUser(username);
      if (accessToken != null) {
        GitHubLogin login = new GitHubLogin(config, httpConnector);
        login.login(accessToken);
        return login;
      }
      return null;
    } catch (IOException e) {
      log.error("Cannot login to GitHub as '" + username + "'", e);
      return null;
    }
  }

  private AccessToken newAccessTokenFromUser(String username) {
    AccountState account = accountCache.getByUsername(username).get();
    Collection<ExternalId> externalIds = account.externalIds();
    for (ExternalId accountExternalId : externalIds) {
      String key = accountExternalId.key().get();
      if (key.startsWith(EXTERNAL_ID_PREFIX)) {
        return new AccessToken(key.substring(EXTERNAL_ID_PREFIX.length()));