Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Update bazlets to latest revision on stable-2.14

Change-Id: Ib0b5467d6f0b60dc5b1de243ec57f22be272356a
diff --git a/WORKSPACE b/WORKSPACE
index f336abb..fd849e0 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "8d7664e169100e537340aed89345c3245cf12f22",
+    commit = "f4fcc606a6afa8ce27a013bcf62e495a5ec2505c",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
index 04c945c..cadde7b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUser.java
@@ -47,6 +47,7 @@
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.git.MetaDataUpdate;
 import com.google.gerrit.server.git.ProjectLevelConfig;
+import com.google.gerrit.server.group.InternalGroup;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -63,6 +64,7 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
+import java.util.Optional;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.PersonIdent;
@@ -212,10 +214,10 @@
   private void addToGroups(Account.Id accountId, String[] groupNames)
       throws OrmException, IOException {
     for (String groupName : groupNames) {
-      AccountGroup group = groupCache.get(new AccountGroup.NameKey(groupName));
-      if (group != null) {
+      Optional<InternalGroup> group = groupCache.get(new AccountGroup.NameKey(groupName));
+      if (group.isPresent()) {
         AccountGroupMember m =
-            new AccountGroupMember(new AccountGroupMember.Key(accountId, group.getId()));
+            new AccountGroupMember(new AccountGroupMember.Key(accountId, group.get().getId()));
         db.get()
             .accountGroupMembersAudit()
             .insert(
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
index 0fa9aa7..31333fd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/CreateServiceUserNotes.java
@@ -17,6 +17,7 @@
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATED_BY;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_OWNER;
 import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.eclipse.jgit.lib.Constants.OBJ_COMMIT;
 
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.reviewdb.client.Project;
@@ -28,7 +29,7 @@
 import com.google.inject.assistedinject.Assisted;
 import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;
 import java.io.IOException;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
@@ -37,6 +38,7 @@
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.notes.NoteMap;
 import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
 import org.eclipse.jgit.revwalk.RevWalk;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,14 +80,18 @@
   }
 
   void createNotes(String branch, ObjectId oldObjectId, ObjectId newObjectId)
-      throws IOException, OrmException {
+      throws IOException, OrmException, ConfigInvalidException {
     if (ObjectId.zeroId().equals(newObjectId)) {
       return;
     }
 
     try (RevWalk rw = new RevWalk(git)) {
       try {
-        RevCommit n = rw.parseCommit(newObjectId);
+        RevObject obj = rw.peel(rw.parseAny(newObjectId));
+        if (obj.getType() != OBJ_COMMIT) {
+          return;
+        }
+        RevCommit n = (RevCommit) obj;
         rw.markStart(n);
         if (n.getParentCount() == 1 && n.getParent(0).equals(oldObjectId)) {
           rw.markUninteresting(rw.parseCommit(oldObjectId));
@@ -108,7 +114,7 @@
     }
   }
 
-  void commitNotes() throws IOException, ConcurrentRefUpdateException {
+  void commitNotes() throws IOException {
     try {
       if (serviceUserNotes == null) {
         return;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteActive.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteActive.java
index 126df90..58532fd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteActive.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteActive.java
@@ -23,6 +23,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 @Singleton
 class DeleteActive implements RestModifyView<ServiceUserResource, Input> {
@@ -35,7 +36,7 @@
 
   @Override
   public Response<?> apply(ServiceUserResource rsrc, Input input)
-      throws RestApiException, OrmException, IOException {
+      throws RestApiException, OrmException, IOException, ConfigInvalidException {
     return deleteActive.get().apply(rsrc, input);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteSshKey.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteSshKey.java
index 943a488..09031bc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteSshKey.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/DeleteSshKey.java
@@ -19,6 +19,7 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.DeleteSshKey.Input;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -39,7 +40,7 @@
   @Override
   public Response<?> apply(ServiceUserResource.SshKey rsrc, Input input)
       throws OrmException, AuthException, RepositoryNotFoundException, IOException,
-          ConfigInvalidException {
+          ConfigInvalidException, PermissionBackendException {
     return deleteSshKey
         .get()
         .apply(new AccountResource.SshKey(rsrc.getUser(), rsrc.getSshKey()), input);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
index 71c3b99..cd30b45 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/GetConfig.java
@@ -15,7 +15,6 @@
 package com.googlesource.gerrit.plugins.serviceuser;
 
 import com.google.common.base.Strings;
-import com.google.gerrit.common.data.GroupDescriptions;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.common.GroupInfo;
 import com.google.gerrit.extensions.restapi.RestReadView;
@@ -25,12 +24,15 @@
 import com.google.gerrit.server.config.PluginConfig;
 import com.google.gerrit.server.config.PluginConfigFactory;
 import com.google.gerrit.server.group.GroupJson;
+import com.google.gerrit.server.group.InternalGroup;
+import com.google.gerrit.server.group.InternalGroupDescription;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.TreeMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -75,9 +77,9 @@
     String[] groups = cfg.getStringList("group");
     info.groups = new TreeMap<>();
     for (String g : groups) {
-      AccountGroup group = groupCache.get(new AccountGroup.NameKey(g));
-      if (group != null) {
-        GroupInfo groupInfo = groupJson.format(GroupDescriptions.forAccountGroup(group));
+      Optional<InternalGroup> group = groupCache.get(new AccountGroup.NameKey(g));
+      if (group.isPresent()) {
+        GroupInfo groupInfo = groupJson.format(new InternalGroupDescription(group.get()));
         groupInfo.name = null;
         info.groups.put(g, groupInfo);
       } else {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
index 12e5bf6..3b696bc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ListServiceUsers.java
@@ -27,13 +27,16 @@
 import com.google.gerrit.server.account.AccountState;
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.git.ProjectLevelConfig;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;
+import java.io.IOException;
 import java.util.Map;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
 
 @Singleton
@@ -63,7 +66,8 @@
 
   @Override
   public Map<String, ServiceUserInfo> apply(ConfigResource rscr)
-      throws OrmException, AuthException {
+      throws OrmException, IOException, AuthException, PermissionBackendException,
+          ConfigInvalidException {
     ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
     CurrentUser user = userProvider.get();
     if (user == null || !user.isIdentifiedUser()) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutActive.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutActive.java
index 9a5ffcd..517ccbc 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutActive.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutActive.java
@@ -23,6 +23,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 @Singleton
 class PutActive implements RestModifyView<ServiceUserResource, Input> {
@@ -35,7 +36,7 @@
 
   @Override
   public Response<String> apply(ServiceUserResource rsrc, Input input)
-      throws ResourceNotFoundException, OrmException, IOException {
+      throws ResourceNotFoundException, OrmException, IOException, ConfigInvalidException {
     return putActive.get().apply(rsrc, input);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutEmail.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutEmail.java
index 602d395..8ea158c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutEmail.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutEmail.java
@@ -14,6 +14,8 @@
 
 package com.googlesource.gerrit.plugins.serviceuser;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.common.base.Strings;
 import com.google.gerrit.common.errors.EmailException;
 import com.google.gerrit.extensions.api.accounts.EmailInput;
@@ -30,6 +32,8 @@
 import com.google.gerrit.server.account.DeleteEmail;
 import com.google.gerrit.server.account.PutPreferred;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -50,6 +54,7 @@
   private final Provider<DeleteEmail> deleteEmail;
   private final Provider<PutPreferred> putPreferred;
   private final Provider<CurrentUser> self;
+  private final PermissionBackend permissionBackend;
 
   @Inject
   PutEmail(
@@ -58,24 +63,25 @@
       Provider<CreateEmail.Factory> createEmailFactory,
       Provider<DeleteEmail> deleteEmail,
       Provider<PutPreferred> putPreferred,
-      Provider<CurrentUser> self) {
+      Provider<CurrentUser> self,
+      PermissionBackend permissionBackend) {
     this.getConfig = getConfig;
     this.getEmail = getEmail;
     this.createEmailFactory = createEmailFactory;
     this.deleteEmail = deleteEmail;
     this.putPreferred = putPreferred;
     this.self = self;
+    this.permissionBackend = permissionBackend;
   }
 
   @Override
   public Response<?> apply(ServiceUserResource rsrc, Input input)
       throws AuthException, ResourceNotFoundException, ResourceConflictException,
           MethodNotAllowedException, OrmException, BadRequestException, ConfigInvalidException,
-          EmailException, IOException {
+          EmailException, IOException, PermissionBackendException {
     Boolean emailAllowed = getConfig.get().apply(new ConfigResource()).allowEmail;
-    if ((emailAllowed == null || !emailAllowed)
-        && !self.get().getCapabilities().canAdministrateServer()) {
-      throw new ResourceConflictException("setting email not allowed");
+    if ((emailAllowed == null || !emailAllowed)) {
+      permissionBackend.user(self).check(ADMINISTRATE_SERVER);
     }
 
     String email = getEmail.get().apply(rsrc);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutHttpPassword.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutHttpPassword.java
index ea8059b..a920f62 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutHttpPassword.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutHttpPassword.java
@@ -13,6 +13,8 @@
 // limitations under the License.
 package com.googlesource.gerrit.plugins.serviceuser;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
@@ -21,6 +23,8 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -53,21 +57,24 @@
   private final Provider<GetConfig> getConfig;
   private final com.google.gerrit.server.account.PutHttpPassword putHttpPassword;
   private final Provider<CurrentUser> self;
+  private final PermissionBackend permissionBackend;
 
   @Inject
   PutHttpPassword(
       Provider<GetConfig> getConfig,
       com.google.gerrit.server.account.PutHttpPassword putHttpPassword,
-      Provider<CurrentUser> self) {
+      Provider<CurrentUser> self,
+      PermissionBackend permissionBackend) {
     this.getConfig = getConfig;
     this.putHttpPassword = putHttpPassword;
     this.self = self;
+    this.permissionBackend = permissionBackend;
   }
 
   @Override
   public Response<String> apply(ServiceUserResource rsrc, Input input)
       throws AuthException, ResourceConflictException, ConfigInvalidException,
-          ResourceNotFoundException, OrmException, IOException {
+          ResourceNotFoundException, OrmException, IOException, PermissionBackendException {
     if (input == null) {
       input = new Input();
     }
@@ -75,16 +82,11 @@
 
     Boolean httpPasswordAllowed = getConfig.get().apply(new ConfigResource()).allowHttpPassword;
     if (input.generate || input.httpPassword == null) {
-      if ((httpPasswordAllowed == null || !httpPasswordAllowed)
-          && !self.get().getCapabilities().canAdministrateServer()) {
-        throw new ResourceConflictException("not allowed to generate HTTP password");
+      if ((httpPasswordAllowed == null || !httpPasswordAllowed)) {
+        permissionBackend.user(self).check(ADMINISTRATE_SERVER);
       }
     } else {
-      if (!self.get().getCapabilities().canAdministrateServer()) {
-        throw new AuthException(
-            "not allowed to set HTTP password directly, "
-                + "requires the Administrate Server permission");
-      }
+      permissionBackend.user(self).check(ADMINISTRATE_SERVER);
     }
 
     String newPassword = input.generate ? generate() : input.httpPassword;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutName.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutName.java
index cae013d..4cfca2c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutName.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutName.java
@@ -24,6 +24,7 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 @Singleton
 class PutName implements RestModifyView<ServiceUserResource, Input> {
@@ -36,7 +37,8 @@
 
   @Override
   public Response<String> apply(ServiceUserResource rsrc, Input input)
-      throws MethodNotAllowedException, ResourceNotFoundException, OrmException, IOException {
+      throws MethodNotAllowedException, ResourceNotFoundException, OrmException, IOException,
+          ConfigInvalidException {
     return putName.get().apply(rsrc.getUser(), input);
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
index 17d99a9..67be740 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/PutOwner.java
@@ -14,20 +14,22 @@
 
 package com.googlesource.gerrit.plugins.serviceuser;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_OWNER;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.common.data.GroupDescription;
-import com.google.gerrit.common.data.GroupDescriptions;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.common.GroupInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.DefaultInput;
 import com.google.gerrit.extensions.restapi.MethodNotAllowedException;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.config.ConfigResource;
@@ -35,6 +37,8 @@
 import com.google.gerrit.server.git.ProjectLevelConfig;
 import com.google.gerrit.server.group.GroupJson;
 import com.google.gerrit.server.group.GroupsCollection;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -59,6 +63,7 @@
   private final MetaDataUpdate.User metaDataUpdateFactory;
   private final GroupJson json;
   private final Provider<CurrentUser> self;
+  private final PermissionBackend permissionBackend;
 
   @Inject
   PutOwner(
@@ -68,7 +73,8 @@
       ProjectCache projectCache,
       MetaDataUpdate.User metaDataUpdateFactory,
       GroupJson json,
-      Provider<CurrentUser> self) {
+      Provider<CurrentUser> self,
+      PermissionBackend permissionBackend) {
     this.getConfig = getConfig;
     this.groups = groups;
     this.pluginName = pluginName;
@@ -77,17 +83,18 @@
     this.metaDataUpdateFactory = metaDataUpdateFactory;
     this.json = json;
     this.self = self;
+    this.permissionBackend = permissionBackend;
   }
 
   @Override
   public Response<GroupInfo> apply(ServiceUserResource rsrc, Input input)
       throws UnprocessableEntityException, RepositoryNotFoundException, MethodNotAllowedException,
-          IOException, OrmException, ResourceConflictException {
+          IOException, OrmException, ResourceConflictException, AuthException,
+          PermissionBackendException {
     ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
     Boolean ownerAllowed = getConfig.get().apply(new ConfigResource()).allowOwner;
-    if ((ownerAllowed == null || !ownerAllowed)
-        && !self.get().getCapabilities().canAdministrateServer()) {
-      throw new ResourceConflictException("setting owner not allowed");
+    if ((ownerAllowed == null || !ownerAllowed)) {
+      permissionBackend.user(self).check(ADMINISTRATE_SERVER);
     }
 
     if (input == null) {
@@ -100,7 +107,7 @@
       db.unset(USER, rsrc.getUser().getUserName(), KEY_OWNER);
     } else {
       group = groups.parse(input.group);
-      if (GroupDescriptions.toAccountGroup(group) == null) {
+      if (!AccountGroup.isInternalGroup(group.getGroupUUID())) {
         throw new MethodNotAllowedException();
       }
       db.setString(USER, rsrc.getUser().getUserName(), KEY_OWNER, group.getGroupUUID().get());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
index b60e8e5..bcf4c6b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/RefUpdateListener.java
@@ -26,7 +26,7 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
-import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.Repository;
 import org.slf4j.Logger;
@@ -106,7 +106,7 @@
           ObjectId.fromString(e.getOldObjectId()),
           ObjectId.fromString(e.getNewObjectId()));
       crn.commitNotes();
-    } catch (IOException | OrmException | ConcurrentRefUpdateException x) {
+    } catch (IOException | OrmException | ConfigInvalidException x) {
       log.error(x.getMessage(), x);
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
index 599b841..f449391 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserCollection.java
@@ -14,6 +14,7 @@
 
 package com.googlesource.gerrit.plugins.serviceuser;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_CREATOR_ID;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.KEY_OWNER;
 import static com.googlesource.gerrit.plugins.serviceuser.CreateServiceUser.USER;
@@ -35,11 +36,15 @@
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.git.ProjectLevelConfig;
 import com.google.gerrit.server.group.GroupsCollection;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import java.io.IOException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 @Singleton
 class ServiceUserCollection
@@ -53,6 +58,7 @@
   private final ProjectCache projectCache;
   private final Provider<CurrentUser> userProvider;
   private final GroupsCollection groups;
+  private final PermissionBackend permissionBackend;
 
   @Inject
   ServiceUserCollection(
@@ -63,7 +69,8 @@
       @PluginName String pluginName,
       ProjectCache projectCache,
       Provider<CurrentUser> userProvider,
-      GroupsCollection groups) {
+      GroupsCollection groups,
+      PermissionBackend permissionBackend) {
     this.views = views;
     this.createServiceUserFactory = createServiceUserFactory;
     this.list = list;
@@ -72,11 +79,13 @@
     this.projectCache = projectCache;
     this.userProvider = userProvider;
     this.groups = groups;
+    this.permissionBackend = permissionBackend;
   }
 
   @Override
   public ServiceUserResource parse(ConfigResource parent, IdString id)
-      throws ResourceNotFoundException, AuthException, OrmException {
+      throws ResourceNotFoundException, AuthException, IOException, OrmException,
+          PermissionBackendException, ConfigInvalidException {
     ProjectLevelConfig storage = projectCache.getAllProjects().getConfig(pluginName + ".db");
     IdentifiedUser serviceUser = accounts.get().parseId(id.get());
     if (serviceUser == null
@@ -87,7 +96,7 @@
     if (user == null || !user.isIdentifiedUser()) {
       throw new AuthException("Authentication required");
     }
-    if (!user.getCapabilities().canAdministrateServer()) {
+    if (!permissionBackend.user(userProvider).testOrFalse(ADMINISTRATE_SERVER)) {
       String owner = storage.get().getString(USER, id.get(), KEY_OWNER);
       if (owner != null) {
         try {
@@ -118,7 +127,6 @@
   }
 
   @Override
-  @SuppressWarnings("unchecked")
   public CreateServiceUser create(ConfigResource parent, IdString username) {
     return createServiceUserFactory.create(username.get());
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java
index 0d0cdba..2756143 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserMenu.java
@@ -14,34 +14,44 @@
 
 package com.googlesource.gerrit.plugins.serviceuser;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.common.collect.Lists;
 import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.client.MenuItem;
 import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.webui.TopMenu;
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import java.io.IOException;
 import java.util.List;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 class ServiceUserMenu implements TopMenu {
   private final String pluginName;
   private final Provider<CurrentUser> userProvider;
   private final List<MenuEntry> menuEntries;
   private final Provider<ListServiceUsers> listServiceUsers;
+  private final PermissionBackend permissionBackend;
 
   @Inject
   ServiceUserMenu(
       @PluginName String pluginName,
       Provider<CurrentUser> userProvider,
-      Provider<ListServiceUsers> listServiceUsers) {
+      Provider<ListServiceUsers> listServiceUsers,
+      PermissionBackend permissionBackend)
+      throws IOException, PermissionBackendException, ConfigInvalidException {
     this.pluginName = pluginName;
     this.userProvider = userProvider;
     this.listServiceUsers = listServiceUsers;
     menuEntries = Lists.newArrayList();
+    this.permissionBackend = permissionBackend;
 
     List<MenuItem> peopleItems = Lists.newArrayListWithExpectedSize(2);
     if (canCreateServiceUser()) {
@@ -57,14 +67,16 @@
 
   private boolean canCreateServiceUser() {
     if (userProvider.get().isIdentifiedUser()) {
-      CapabilityControl ctl = userProvider.get().getCapabilities();
-      return ctl.canPerform(pluginName + "-" + CreateServiceUserCapability.ID)
-          || ctl.canAdministrateServer();
+      return permissionBackend
+              .user(userProvider)
+              .testOrFalse(new PluginPermission(pluginName, CreateServiceUserCapability.ID))
+          || permissionBackend.user(userProvider).testOrFalse(ADMINISTRATE_SERVER);
     }
     return false;
   }
 
-  private boolean hasServiceUser() {
+  private boolean hasServiceUser()
+      throws PermissionBackendException, IOException, ConfigInvalidException {
     try {
       return !listServiceUsers.get().apply(new ConfigResource()).isEmpty();
     } catch (AuthException | OrmException e) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserResolver.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserResolver.java
index 772acde..734f47e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserResolver.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ServiceUserResolver.java
@@ -34,10 +34,12 @@
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.PersonIdent;
 
 @Singleton
@@ -68,25 +70,24 @@
     this.accountCache = accountCache;
   }
 
-  ServiceUserInfo getAsServiceUser(PersonIdent committerIdent) throws OrmException {
+  ServiceUserInfo getAsServiceUser(PersonIdent committerIdent)
+      throws ConfigInvalidException, IOException, OrmException {
     StringBuilder committer = new StringBuilder();
     committer.append(committerIdent.getName());
     committer.append(" <");
     committer.append(committerIdent.getEmailAddress());
     committer.append("> ");
 
-    try (ReviewDb db = schema.open()) {
-      Account account = resolver.find(db, committer.toString());
-      if (account == null) {
-        return null;
-      }
-      try {
-        return getServiceUser
-            .get()
-            .apply(new ServiceUserResource(genericUserFactory.create(account.getId())));
-      } catch (ResourceNotFoundException e) {
-        return null;
-      }
+    Account account = resolver.find(committer.toString());
+    if (account == null) {
+      return null;
+    }
+    try {
+      return getServiceUser
+          .get()
+          .apply(new ServiceUserResource(genericUserFactory.create(account.getId())));
+    } catch (ResourceNotFoundException e) {
+      return null;
     }
   }
 
@@ -100,7 +101,7 @@
           new RequestContext() {
             @Override
             public CurrentUser getUser() {
-              return new CurrentUser(null) {
+              return new CurrentUser() {
 
                 @Override
                 public GroupMembership getEffectiveGroups() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ValidateServiceUserCommits.java b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ValidateServiceUserCommits.java
index fc4ff00..f7b1179 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ValidateServiceUserCommits.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/serviceuser/ValidateServiceUserCommits.java
@@ -25,8 +25,10 @@
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.serviceuser.GetServiceUser.ServiceUserInfo;
+import java.io.IOException;
 import java.util.Collections;
 import java.util.List;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.PersonIdent;
 
 @Singleton
@@ -68,7 +70,7 @@
                   committer.getEmailAddress()));
         }
       }
-    } catch (OrmException e) {
+    } catch (IOException | OrmException | ConfigInvalidException e) {
       throw new CommitValidationException(
           "Internal error while checking for service user commits.", e);
     }