Merge branch 'stable-2.14'

* stable-2.14:
  Remove classpath target
  Add eclipse-out to .gitignore

Change-Id: I2575b20b31c58d5cd674789448006fa32d797c5f
diff --git a/WORKSPACE b/WORKSPACE
index 0bc7f74..334b195 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,24 +3,24 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "e8160a65a591e602a2fb48953b269dd8d42a7c37",
+    commit = "f2e78d4042490178a9cc1da59fc590dec55278cb",
     #    local_path = "/home/<user>/projects/bazlets",
 )
 
 #Snapshot Plugin API
-#load(
-#    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
-#    "gerrit_api_maven_local",
-#)
-
-# Load snapshot Plugin API
-#gerrit_api_maven_local()
-
-# Release Plugin API
 load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
-    "gerrit_api",
+    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+    "gerrit_api_maven_local",
 )
 
+#Load snapshot Plugin API
+gerrit_api_maven_local()
+
+# Release Plugin API
+#load(
+#    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+#    "gerrit_api",
+#)
+
 # Load release Plugin API
-gerrit_api()
+#gerrit_api()
diff --git a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/GetFullPathCommand.java b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/GetFullPathCommand.java
index 5dcbed0..7171746 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/GetFullPathCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/GetFullPathCommand.java
@@ -12,7 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-
 package com.googlesource.gerrit.plugins.adminconsole;
 
 import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE;
@@ -21,18 +20,21 @@
 import com.google.gerrit.extensions.annotations.CapabilityScope;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LocalDiskRepositoryManager;
+import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
-import com.google.gerrit.server.git.LocalDiskRepositoryManager;
-import com.google.gerrit.server.git.GitRepositoryManager;
-import com.google.gerrit.server.project.ProjectCache;
 import com.google.inject.Inject;
-
 import org.eclipse.jgit.lib.Constants;
 import org.kohsuke.args4j.Argument;
 
 @RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
-@CommandMetaData(runsAt = MASTER_OR_SLAVE, name = "get-path", description = "Gets the full path of a repository")
+@CommandMetaData(
+  runsAt = MASTER_OR_SLAVE,
+  name = "get-path",
+  description = "Gets the full path of a repository"
+)
 public final class GetFullPathCommand extends SshCommand {
 
   @Argument(index = 0, required = true, metaVar = "PROJECT", usage = "Name of the project")
@@ -52,13 +54,14 @@
   @Override
   protected void run() throws UnloggedFailure {
     if (localDiskRepositoryManager == null) {
-      throw new UnloggedFailure(1,
-          "Command only works with disk based repository managers");
+      throw new UnloggedFailure(1, "Command only works with disk based repository managers");
     }
     Project.NameKey nameKey = new Project.NameKey(projectName);
     if (projectCache.get(nameKey) != null) {
-      stdout.println(localDiskRepositoryManager.getBasePath(nameKey)
-          .resolve(nameKey.get().concat(Constants.DOT_GIT_EXT)));
+      stdout.println(
+          localDiskRepositoryManager
+              .getBasePath(nameKey)
+              .resolve(nameKey.get().concat(Constants.DOT_GIT_EXT)));
     } else {
       throw new UnloggedFailure(1, "Repository not found");
     }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ListUsersCommand.java b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ListUsersCommand.java
index 8ead5ad..5e96f37 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ListUsersCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ListUsersCommand.java
@@ -23,13 +23,11 @@
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
-import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.ResultSet;
 import com.google.inject.Inject;
-
 import org.kohsuke.args4j.Option;
 
-@RequiresCapability(value=GlobalCapability.ADMINISTRATE_SERVER, scope=CapabilityScope.CORE)
+@RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
 @CommandMetaData(name = "ls-users", description = "List users")
 public final class ListUsersCommand extends SshCommand {
   private ReviewDb db;
@@ -42,8 +40,7 @@
   private boolean inactiveOnly = false;
 
   @Inject
-  ListUsersCommand(ReviewDb db,
-      AccountResolver accountResolver) {
+  ListUsersCommand(ReviewDb db, AccountResolver accountResolver) {
     this.db = db;
     this.accountResolver = accountResolver;
   }
@@ -59,33 +56,29 @@
         continue;
       }
       String username = getUsername(account);
-      String out = new StringBuilder()
-        .append(account.getId().toString())
-        .append(" |")
-        .append(Strings.isNullOrEmpty(username)
-            ? ""
-            : " " + username)
-        .append(" |")
-        .append(Strings.isNullOrEmpty(account.getFullName())
-            ? ""
-            : " " + account.getFullName())
-        .append(" |")
-        .append(Strings.isNullOrEmpty(account.getPreferredEmail())
-            ? ""
-            : " " + account.getPreferredEmail())
-        .append(" |")
-        .append(account.isActive()
-            ? " active"
-            : " inactive")
-        .toString();
+      String out =
+          new StringBuilder()
+              .append(account.getId().toString())
+              .append(" |")
+              .append(Strings.isNullOrEmpty(username) ? "" : " " + username)
+              .append(" |")
+              .append(
+                  Strings.isNullOrEmpty(account.getFullName()) ? "" : " " + account.getFullName())
+              .append(" |")
+              .append(
+                  Strings.isNullOrEmpty(account.getPreferredEmail())
+                      ? ""
+                      : " " + account.getPreferredEmail())
+              .append(" |")
+              .append(account.isActive() ? " active" : " inactive")
+              .toString();
       stdout.println(out);
     }
   }
 
-  private String getUsername(Account account) throws OrmException {
+  private String getUsername(Account account) throws Exception {
     String id = account.getId().toString();
     Account accountFromResolver = accountResolver.find(db, id);
-    return accountFromResolver == null ? null
-        : accountFromResolver.getUserName();
+    return accountFromResolver == null ? null : accountFromResolver.getUserName();
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowAccountCommand.java b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowAccountCommand.java
index 5c439ff..f60a4b8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowAccountCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowAccountCommand.java
@@ -22,35 +22,37 @@
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.client.AccountExternalId;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.GetGroups;
 import com.google.gerrit.server.account.GetSshKeys;
+import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.account.externalids.ExternalIds;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
-import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
-import org.eclipse.jgit.errors.ConfigInvalidException;
-import org.kohsuke.args4j.Argument;
-import org.kohsuke.args4j.Option;
-
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Set;
+import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
 
-@RequiresCapability(value=GlobalCapability.ADMINISTRATE_SERVER, scope=CapabilityScope.CORE)
+@RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
 @CommandMetaData(name = "show-account", description = "Displays user information")
 public final class ShowAccountCommand extends SshCommand {
 
-  @Argument(usage = "User information to find: LastName,\\ Firstname,  email@address.com, account id or an user name.  Be sure to double-escape spaces, for example: \"show-account Last,\\\\ First\"")
+  @Argument(
+    usage =
+        "User information to find: LastName,\\ Firstname,  email@address.com, account id or an user name.  Be sure to double-escape spaces, for example: \"show-account Last,\\\\ First\""
+  )
   private String name = "";
 
   @Option(name = "--show-groups", usage = "show group membership by user?")
@@ -67,40 +69,52 @@
   private final Provider<GetGroups> accountGetGroups;
   private final IdentifiedUser.GenericFactory userFactory;
   private final Provider<GetSshKeys> getSshKeys;
+  private final ExternalIds externalIds;
 
   @Inject
-  ShowAccountCommand(AccountResolver accountResolver,
+  ShowAccountCommand(
+      AccountResolver accountResolver,
       Provider<GetGroups> accountGetGroups,
       IdentifiedUser.GenericFactory userFactory,
       Provider<GetSshKeys> getSshKeys,
-      SchemaFactory<ReviewDb> schema) {
+      SchemaFactory<ReviewDb> schema,
+      ExternalIds externalIds) {
     this.accountResolver = accountResolver;
     this.accountGetGroups = accountGetGroups;
     this.userFactory = userFactory;
-    this.schema = schema;
     this.getSshKeys = getSshKeys;
+    this.schema = schema;
+    this.externalIds = externalIds;
   }
 
   @Override
-  public void run() throws UnloggedFailure, OrmException {
+  public void run() throws UnloggedFailure, Exception {
     Account account;
 
     if (name.isEmpty()) {
-      throw new UnloggedFailure(1,
+      throw new UnloggedFailure(
+          1,
           "You need to tell me who to find:  LastName,\\\\ Firstname, email@address.com, account id or an user name.  "
               + "Be sure to double-escape spaces, for example: \"show-account Last,\\\\ First\"");
     }
     try (ReviewDb db = schema.open()) {
       Set<Id> idList = accountResolver.findAll(db, name);
       if (idList.isEmpty()) {
-        throw new UnloggedFailure(1,
+        throw new UnloggedFailure(
+            1,
             "No accounts found for your query: \""
                 + name
                 + "\""
                 + " Tip: Try double-escaping spaces, for example: \"show-account Last,\\\\ First\"");
       }
-      stdout.println("Found " + idList.size() + " result"
-          + (idList.size() > 1 ? "s" : "") + ": for query: \"" + name + "\"");
+      stdout.println(
+          "Found "
+              + idList.size()
+              + " result"
+              + (idList.size() > 1 ? "s" : "")
+              + ": for query: \""
+              + name
+              + "\"");
       stdout.println();
 
       for (Id id : idList) {
@@ -115,27 +129,29 @@
         stdout.println("Active:            " + account.isActive());
         stdout.println("Registered on:     " + account.getRegisteredOn());
 
-
         stdout.println("");
         stdout.println("External Ids:");
-        stdout.println(String
-            .format("%-50s %s", "Email Address:", "External Id:"));
-        for (AccountExternalId accountExternalId : db.accountExternalIds()
-            .byAccount(account.getId())) {
-          stdout.println(String.format("%-50s %s",
-              (accountExternalId.getEmailAddress() == null ? ""
-                  : accountExternalId.getEmailAddress()), accountExternalId
-                  .getExternalId()));
+        stdout.println(String.format("%-50s %s", "Email Address:", "External Id:"));
+        try {
+          for (ExternalId externalId : externalIds.byAccount(account.getId())) {
+            stdout.println(
+                String.format(
+                    "%-50s %s",
+                    (externalId.email() == null ? "" : externalId.email()), externalId.key()));
+          }
+        } catch (IOException e) {
+          throw new UnloggedFailure(1, "Error getting external Ids: " + e.getMessage(), e);
         }
-
         if (showKeys) {
           stdout.println("");
           stdout.println("Public Keys:");
           List<SshKeyInfo> sshKeys;
           try {
-            sshKeys = getSshKeys.get()
-                .apply(new AccountResource(userFactory.create(id)));
-          } catch (AuthException | IOException | ConfigInvalidException e) {
+            sshKeys = getSshKeys.get().apply(new AccountResource(userFactory.create(id)));
+          } catch (AuthException
+              | IOException
+              | ConfigInvalidException
+              | PermissionBackendException e) {
             throw new UnloggedFailure(1, "Error getting sshkeys: " + e.getMessage(), e);
           }
           if (sshKeys == null || sshKeys.isEmpty()) {
@@ -143,25 +159,26 @@
           } else {
             stdout.println(String.format("%-9s %s", "Status:", "Key:"));
             for (SshKeyInfo sshKey : sshKeys) {
-              stdout.println(String.format("%-9s %s", (sshKey.valid
-                  ? "Active" : "Inactive"), sshKey.sshPublicKey));
+              stdout.println(
+                  String.format(
+                      "%-9s %s", (sshKey.valid ? "Active" : "Inactive"), sshKey.sshPublicKey));
             }
           }
         }
 
         if (showGroups) {
           stdout.println();
-          stdout.println("Member of groups"
-              + (filterGroups == null ? "" : " (Filtering on \"" + filterGroups
-                  + "\")") + ":");
+          stdout.println(
+              "Member of groups"
+                  + (filterGroups == null ? "" : " (Filtering on \"" + filterGroups + "\")")
+                  + ":");
           List<GroupInfo> groupInfos =
-              accountGetGroups.get().apply(
-                  new AccountResource(userFactory.create(id)));
+              accountGetGroups.get().apply(new AccountResource(userFactory.create(id)));
 
           Collections.sort(groupInfos, new CustomComparator());
           for (GroupInfo groupInfo : groupInfos) {
-            if (null == filterGroups || groupInfo.name.toLowerCase().contains(filterGroups.toLowerCase
-                ())) {
+            if (null == filterGroups
+                || groupInfo.name.toLowerCase().contains(filterGroups.toLowerCase())) {
               stdout.println(groupInfo.name);
             }
           }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccessCommand.java b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccessCommand.java
index 1252b23..ff117fb 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccessCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccessCommand.java
@@ -26,16 +26,17 @@
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
-
+import java.io.IOException;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
 
-import java.io.IOException;
-
-@RequiresCapability(value=GlobalCapability.ADMINISTRATE_SERVER, scope=CapabilityScope.CORE)
-@CommandMetaData(name = "show-repo-access", description = "Displays access on a specific repository")
+@RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
+@CommandMetaData(
+  name = "show-repo-access",
+  description = "Displays access on a specific repository"
+)
 public final class ShowRepoAccessCommand extends SshCommand {
 
   @Argument(usage = "project to show access for?")
@@ -55,8 +56,7 @@
   private int permissionGroupWidth;
 
   @Override
-  public void run() throws UnloggedFailure, Failure, IOException,
-      ConfigInvalidException {
+  public void run() throws UnloggedFailure, Failure, IOException, ConfigInvalidException {
     // space indented Strings to be used as format for String.format() later
     String sectionNameFormatter = "  %-25s\n";
     String ruleNameFormatter = "    %-15s\n ";
@@ -75,19 +75,20 @@
       config = ProjectConfig.read(md);
       for (AccessSection accessSection : config.getAccessSections()) {
 
-        stdout.print((String.format(sectionNameFormatter, accessSection
-            .getName().toString())));
+        stdout.print((String.format(sectionNameFormatter, accessSection.getName().toString())));
 
         for (Permission permission : accessSection.getPermissions()) {
 
           for (PermissionRule rule : permission.getRules()) {
-            stdout
-                .print(String.format(ruleNameFormatter, permission.getName()));
-            stdout.print(String.format(permissionNameFormatter,
-                (!rule.getMin().equals(rule.getMax())) ? "" + rule.getMin() + " "
-                    + rule.getMax() : rule.getAction(),
-                (permission.getExclusiveGroup() ? "EXCLUSIVE" : ""),
-                format(rule.getGroup().getName())));
+            stdout.print(String.format(ruleNameFormatter, permission.getName()));
+            stdout.print(
+                String.format(
+                    permissionNameFormatter,
+                    (!rule.getMin().equals(rule.getMax()))
+                        ? "" + rule.getMin() + " " + rule.getMax()
+                        : rule.getAction(),
+                    (permission.getExclusiveGroup() ? "EXCLUSIVE" : ""),
+                    format(rule.getGroup().getName())));
           }
         }
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccountAccessCommand.java b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccountAccessCommand.java
index e80f81b..9bd7977 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccountAccessCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/adminconsole/ShowRepoAccountAccessCommand.java
@@ -23,8 +23,8 @@
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountResolver;
 import com.google.gerrit.server.account.AccountResource;
@@ -36,24 +36,29 @@
 import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
-
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.kohsuke.args4j.Argument;
 import org.kohsuke.args4j.Option;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-@RequiresCapability(value=GlobalCapability.ADMINISTRATE_SERVER, scope=CapabilityScope.CORE)
-@CommandMetaData(name = "show-repo-account-access", description = "Displays user's access on a specific repository")
+@RequiresCapability(value = GlobalCapability.ADMINISTRATE_SERVER, scope = CapabilityScope.CORE)
+@CommandMetaData(
+  name = "show-repo-account-access",
+  description = "Displays user's access on a specific repository"
+)
 public final class ShowRepoAccountAccessCommand extends SshCommand {
 
   @Argument(usage = "project to show access for?")
   private String projectName = "";
 
-  @Option(name = "--user", usage = "User information to find: LastName,\\ Firstname,  email@address.com, account id or an user name. "
-      + "Be sure to double-escape spaces, for example: \"show-repo-account-access All-Projects --user Last,\\\\ First\"")
+  @Option(
+    name = "--user",
+    usage =
+        "User information to find: LastName,\\ Firstname,  email@address.com, account id or an user name. "
+            + "Be sure to double-escape spaces, for example: \"show-repo-account-access All-Projects --user Last,\\\\ First\""
+  )
   private String name = "";
 
   @Option(name = "-w", usage = "display without line width truncation")
@@ -96,14 +101,16 @@
     }
 
     if (name.isEmpty()) {
-      throw new UnloggedFailure(1,
+      throw new UnloggedFailure(
+          1,
           "You need to tell me who to find:  LastName,\\\\ Firstname, email@address.com, account id or an user name.  "
               + "Be sure to double-escape spaces, for example: \"show-repo-account-access All-Projects --user Last,\\\\ First\"");
     }
     try (ReviewDb db = schema.open()) {
       Set<Id> idList = accountResolver.findAll(db, name);
       if (idList.isEmpty()) {
-        throw new UnloggedFailure(1,
+        throw new UnloggedFailure(
+            1,
             "No accounts found for your query: \""
                 + name
                 + "\""
@@ -126,8 +133,7 @@
           // Need to know what groups the user is in. This is not a great
           // solution, but it does work.
           List<GroupInfo> groupInfos =
-              accountGetGroups.get().apply(
-                  new AccountResource(userFactory.create(id)));
+              accountGetGroups.get().apply(new AccountResource(userFactory.create(id)));
           HashSet<String> groupHash = new HashSet<>();
 
           for (GroupInfo groupInfo : groupInfos) {
@@ -136,8 +142,7 @@
 
           for (AccessSection accessSection : config.getAccessSections()) {
             StringBuilder sb = new StringBuilder();
-            sb.append((String.format(sectionNameFormatter, accessSection
-                .getName().toString())));
+            sb.append((String.format(sectionNameFormatter, accessSection.getName().toString())));
             // This is a solution to prevent displaying a section heading unless
             // the user has permissions for it
             // not the best solution, but I haven't been able to find
@@ -150,11 +155,14 @@
 
                 if (groupHash.contains(rule.getGroup().getName())) {
                   sb.append(String.format(ruleNameFormatter, permission.getName()));
-                  sb.append(String.format(permissionNameFormatter,
-                      (!rule.getMin().equals(rule.getMax())) ? "" + rule.getMin() + " "
-                          + rule.getMax() : rule.getAction(),
-                      (permission.getExclusiveGroup() ? "EXCLUSIVE" : ""),
-                      format(rule.getGroup().getName())));
+                  sb.append(
+                      String.format(
+                          permissionNameFormatter,
+                          (!rule.getMin().equals(rule.getMax()))
+                              ? "" + rule.getMin() + " " + rule.getMax()
+                              : rule.getAction(),
+                          (permission.getExclusiveGroup() ? "EXCLUSIVE" : ""),
+                          format(rule.getGroup().getName())));
                   userHasPermissionsInSection = true;
                 }
               }
@@ -167,7 +175,6 @@
             }
           }
 
-
           if (!userHasPermissionsInProject) {
             stdout.println("  No access found for this user on this repository");
           }