Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Format all build files with buildifier
  Update bazlets to latest stable-2.14 and adjust to 2.14.12 API
  Format all Java files with google-java-format
  Update bazlets to latest stable-2.14

This merge removes the username validation changes that were done for
compatibility with the 2.14.12 API, since this plugin's standalone
build is still building against the 2.15.2 API which doesn't have the
corresponding changes.

In a follow-up commit we should upgrade to use the 2.15.3-SNAPSHOT API
and make the necessary changes at the same time.

Change-Id: I6593dd8ecfa9eb3c708e919fca3463462cb60a17
diff --git a/WORKSPACE b/WORKSPACE
index 03e715d..1cba3d1 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "cbbab83e99c3fa44b6ff37863cbd7bb3e9f84f47",
+    commit = "7ce9a3f58f030635b3a1229b7fb4c62ee7979bc8",
     # local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
index c4e3e65..b3f62de 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
@@ -32,7 +32,6 @@
 import com.google.gerrit.server.account.AccountState;
 import com.google.gerrit.server.account.AuthRequest;
 import com.google.gerrit.server.account.CreateAccount;
-import com.google.gerrit.server.account.ExternalId;
 import com.google.gerrit.server.account.VersionedAuthorizedKeys;
 import com.google.gerrit.server.config.AuthConfig;
 import com.google.gwtorm.server.OrmException;
@@ -114,7 +113,7 @@
   private Account.Id createAccountByLdapAndAddSshKeys(GerritApi api, AccountInfo acc)
       throws NoSuchAccountException, IOException, OrmException, RestApiException,
           ConfigInvalidException {
-    if (!ExternalId.isValidUsername(acc.username)) {
+    if (!acc.username.matches(Account.USER_NAME_PATTERN)) {
       throw new NoSuchAccountException(String.format("User %s not found", acc.username));
     }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
index 51e5dcc..ac8bf2d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AddApprovalsStep.java
@@ -18,7 +18,6 @@
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.common.data.LabelType;
 import com.google.gerrit.common.errors.NoSuchAccountException;
-import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.common.ApprovalInfo;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.common.LabelInfo;
@@ -29,8 +28,8 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
@@ -54,7 +53,7 @@
   private final ChangeUpdate.Factory updateFactory;
   private final ReviewDb db;
   private final IdentifiedUser.GenericFactory genericUserFactory;
-  private final ChangeControl.GenericFactory changeControlFactory;
+  private final ChangeData.Factory changeDataFactory;
   private final Change change;
   private final ChangeInfo changeInfo;
   private final boolean resume;
@@ -65,7 +64,7 @@
       ChangeUpdate.Factory updateFactory,
       ReviewDb db,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeData.Factory changeDataFactory,
       @Assisted Change change,
       @Assisted ChangeInfo changeInfo,
       @Assisted boolean resume) {
@@ -73,7 +72,7 @@
     this.updateFactory = updateFactory;
     this.db = db;
     this.genericUserFactory = genericUserFactory;
-    this.changeControlFactory = changeControlFactory;
+    this.changeDataFactory = changeDataFactory;
     this.change = change;
     this.changeInfo = changeInfo;
     this.resume = resume;
@@ -93,8 +92,8 @@
       if (label.all != null) {
         for (ApprovalInfo a : label.all) {
           Account.Id user = accountUtil.resolveUser(api, a);
-          ChangeControl ctrl = control(change, a);
-          LabelType labelType = ctrl.getLabelTypes().byLabel(labelName);
+          ChangeData cd = changeDataFactory.create(db, change);
+          LabelType labelType = cd.getLabelTypes().byLabel(labelName);
           if (labelType == null) {
             log.warn(
                 String.format(
@@ -114,7 +113,7 @@
                       change.currentPatchSetId(), user, labelType.getLabelId()),
                   shortValue,
                   MoreObjects.firstNonNull(a.date, TimeUtil.nowTs())));
-          ChangeUpdate update = updateFactory.create(ctrl);
+          ChangeUpdate update = updateFactory.create(cd.notes(), genericUserFactory.create(user));
           if (shortValue != 0) {
             update.putApproval(labelName, shortValue);
           } else {
@@ -126,16 +125,4 @@
     }
     db.patchSetApprovals().insert(approvals);
   }
-
-  private ChangeControl control(Change change, AccountInfo acc) throws NoSuchChangeException {
-    return control(change, new Account.Id(acc._accountId));
-  }
-
-  private ChangeControl control(Change change, Account.Id id) throws NoSuchChangeException {
-    try {
-      return changeControlFactory.controlFor(db, change, genericUserFactory.create(id));
-    } catch (OrmException e) {
-      throw new NoSuchChangeException(change.getId());
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
index f2d241a..213d2d4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AddHashtagsStep.java
@@ -24,7 +24,7 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.change.ChangeTriplet;
 import com.google.gerrit.server.change.SetHashtagsOp;
-import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.update.BatchUpdate;
 import com.google.gerrit.server.update.UpdateException;
@@ -45,7 +45,7 @@
   private static final Logger log = LoggerFactory.getLogger(AddHashtagsStep.class);
 
   private final CurrentUser currentUser;
-  private final ChangeControl.GenericFactory changeControlFactory;
+  private final ChangeNotes.Factory changeNotesFactory;
   private final Change change;
   private final ChangeInfo changeInfo;
   private final boolean resume;
@@ -56,7 +56,7 @@
   @Inject
   AddHashtagsStep(
       CurrentUser currentUser,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeNotes.Factory changeNotesFactory,
       Provider<ReviewDb> db,
       BatchUpdate.Factory batchUpdateFactory,
       SetHashtagsOp.Factory hashtagsFactory,
@@ -64,7 +64,7 @@
       @Assisted ChangeInfo changeInfo,
       @Assisted boolean resume) {
     this.currentUser = currentUser;
-    this.changeControlFactory = changeControlFactory;
+    this.changeNotesFactory = changeNotesFactory;
     this.db = db;
     this.batchUpdateFactory = batchUpdateFactory;
     this.hashtagsFactory = hashtagsFactory;
@@ -76,12 +76,13 @@
   void add()
       throws IllegalArgumentException, OrmException, NoSuchChangeException, UpdateException,
           RestApiException {
-    ChangeControl ctrl = changeControlFactory.controlFor(db.get(), change, currentUser);
+
+    ChangeNotes notes = changeNotesFactory.createChecked(db.get(), change);
 
     try {
       if (resume) {
         HashtagsInput input = new HashtagsInput();
-        input.remove = ctrl.getNotes().load().getHashtags();
+        input.remove = notes.load().getHashtags();
         try (BatchUpdate bu =
             batchUpdateFactory.create(
                 db.get(), change.getProject(), currentUser, TimeUtil.nowTs())) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
index dcb6409..731ec1c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
@@ -14,8 +14,11 @@
 
 package com.googlesource.gerrit.plugins.importer;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceConflictException;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -24,9 +27,9 @@
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Project;
 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.git.GitRepositoryManager;
+import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
@@ -99,6 +102,8 @@
           case REJECTED:
           case REJECTED_CURRENT_BRANCH:
           case RENAMED:
+          case REJECTED_MISSING_OBJECT:
+          case REJECTED_OTHER_REASON:
           default:
             throw new IOException(
                 String.format("Failed to delete %s, RefUpdate.Result = %s", ref, result));
@@ -113,17 +118,20 @@
     private final CompleteProjectImport completeProjectImport;
     private final Provider<CurrentUser> currentUserProvider;
     private final String pluginName;
+    private final PermissionBackend permissionBackend;
 
     @Inject
     public OnProjects(
         ProjectsCollection projectsCollection,
         CompleteProjectImport completeProjectImport,
         Provider<CurrentUser> currentUserProvider,
-        @PluginName String pluginName) {
+        @PluginName String pluginName,
+        PermissionBackend permissionBackend) {
       this.projectsCollection = projectsCollection;
       this.completeProjectImport = completeProjectImport;
       this.currentUserProvider = currentUserProvider;
       this.pluginName = pluginName;
+      this.permissionBackend = permissionBackend;
     }
 
     @Override
@@ -162,9 +170,10 @@
     }
 
     private boolean canCompleteImport(ProjectResource rsrc) {
-      CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-      return ctl.canAdministrateServer()
-          || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
+      return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER)
+          || (permissionBackend
+                  .user(currentUserProvider)
+                  .testOrFalse(new PluginPermission(pluginName, ImportCapability.ID))
               && rsrc.getControl().isOwner());
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
index 670b9ab..d4ea7b5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
@@ -14,18 +14,23 @@
 
 package com.googlesource.gerrit.plugins.importer;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.common.base.Strings;
 import com.google.gerrit.common.errors.NoSuchAccountException;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Project;
 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.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.update.UpdateException;
@@ -33,7 +38,6 @@
 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.importer.CopyProject.Input;
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -41,7 +45,6 @@
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 
-@Singleton
 @RequiresCapability(CopyProjectCapability.ID)
 class CopyProject implements RestModifyView<ProjectResource, Input>, UiAction<ProjectResource> {
   public static class Input {
@@ -51,23 +54,26 @@
   private final ImportProject.Factory importProjectFactory;
   private final Provider<CurrentUser> currentUserProvider;
   private final String pluginName;
-
+  private final PermissionBackend permissionBackend;
   private Writer err;
 
   @Inject
   CopyProject(
       ImportProject.Factory importProjectFactory,
       Provider<CurrentUser> currentUserProvider,
-      @PluginName String pluginName) {
+      @PluginName String pluginName,
+      PermissionBackend permissionBackend) {
     this.importProjectFactory = importProjectFactory;
     this.currentUserProvider = currentUserProvider;
     this.pluginName = pluginName;
+    this.permissionBackend = permissionBackend;
   }
 
   @Override
   public ImportStatistic apply(ProjectResource rsrc, Input input)
       throws RestApiException, OrmException, IOException, ValidationException, GitAPIException,
-          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     if (Strings.isNullOrEmpty(input.name)) {
       throw new BadRequestException("name is required");
     }
@@ -91,9 +97,10 @@
   }
 
   private boolean canCopy() {
-    CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-    return ctl.canAdministrateServer()
-        || ctl.canPerform(pluginName + "-" + CopyProjectCapability.ID);
+    return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER)
+        || permissionBackend
+            .user(currentUserProvider)
+            .testOrFalse(new PluginPermission(pluginName, CopyProjectCapability.ID));
   }
 
   void setErr(PrintWriter err) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
index e362b96..e51544b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
@@ -78,6 +78,8 @@
         case REJECTED:
         case REJECTED_CURRENT_BRANCH:
         case RENAMED:
+        case REJECTED_MISSING_OBJECT:
+        case REJECTED_OTHER_REASON:
         default:
           throw new IOException(
               String.format("Failed to update %s, RefUpdate.Result = %s", targetRef, result));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java b/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java
index af59bd6..3e7dfa9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java
@@ -58,7 +58,6 @@
   }
 
   @Override
-  @SuppressWarnings("unchecked")
   public ImportGroup create(ConfigResource parent, IdString id) throws RestApiException {
     return importGroupFactory.create(new AccountGroup.NameKey(id.get()));
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
index 230af5d..c41fdbf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportGroup.java
@@ -16,6 +16,7 @@
 
 import static com.google.gerrit.reviewdb.client.AccountGroup.isInternalGroup;
 
+import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.common.errors.NoSuchAccountException;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.common.AccountInfo;
@@ -40,6 +41,7 @@
 import com.google.gerrit.server.account.GroupIncludeCache;
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.group.InternalGroup;
 import com.google.gerrit.server.validators.GroupCreationValidationListener;
 import com.google.gerrit.server.validators.ValidationException;
 import com.google.gwtorm.server.OrmDuplicateKeyException;
@@ -52,6 +54,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
@@ -174,11 +177,11 @@
     }
   }
 
-  private AccountGroup getGroupByName(String groupName) {
+  private Optional<InternalGroup> getGroupByName(String groupName) {
     return groupCache.get(new AccountGroup.NameKey(groupName));
   }
 
-  private AccountGroup getGroupByUUID(String uuid) {
+  private Optional<InternalGroup> getGroupByUUID(String uuid) {
     return groupCache.get(new AccountGroup.UUID(uuid));
   }
 
@@ -190,7 +193,7 @@
     args.groupDescription = groupInfo.description;
     args.visibleToAll = cfg.getBoolean("groups", "newGroupsVisibleToAll", false);
     if (!groupInfo.ownerId.equals(groupInfo.id)) {
-      args.ownerGroupId = getGroupByUUID(groupInfo.ownerId).getId();
+      args.ownerGroupId = getGroupByUUID(groupInfo.ownerId).get().getId();
     }
     Set<Account.Id> initialMembers = new HashSet<>();
     for (AccountInfo member : groupInfo.members) {
@@ -221,7 +224,7 @@
       throw new ResourceConflictException(info.name);
     }
     db.accountGroups().insert(Collections.singleton(group));
-    groupCache.evict(group);
+    groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
 
     if (!info.id.equals(info.ownerId)) {
       if (getGroupByUUID(info.ownerId) == null) {
@@ -246,7 +249,7 @@
     addMembers(group.getId(), info.members);
     addGroups(input, group.getId(), info.name, info.includes);
 
-    groupCache.evict(group);
+    groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
 
     return group;
   }
@@ -274,7 +277,8 @@
   private AccountGroup createAccountGroup(GroupInfo info) throws OrmException {
     AccountGroup.Id groupId = new AccountGroup.Id(db.nextAccountGroupId());
     AccountGroup.UUID uuid = new AccountGroup.UUID(info.id);
-    AccountGroup group = new AccountGroup(new AccountGroup.NameKey(info.name), groupId, uuid);
+    AccountGroup group =
+        new AccountGroup(new AccountGroup.NameKey(info.name), groupId, uuid, TimeUtil.nowTs());
     group.setVisibleToAll(cfg.getBoolean("groups", "newGroupsVisibleToAll", false));
     group.setDescription(info.description);
     return group;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportMenu.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportMenu.java
index 1e969af..6e606d8 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportMenu.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportMenu.java
@@ -14,12 +14,15 @@
 
 package com.googlesource.gerrit.plugins.importer;
 
+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.webui.TopMenu;
 import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
+import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import java.util.List;
@@ -28,11 +31,16 @@
   private final String pluginName;
   private final Provider<CurrentUser> userProvider;
   private final List<MenuEntry> menuEntries;
+  private final PermissionBackend permissionBackend;
 
   @Inject
-  ImportMenu(@PluginName String pluginName, Provider<CurrentUser> userProvider) {
+  ImportMenu(
+      @PluginName String pluginName,
+      Provider<CurrentUser> userProvider,
+      PermissionBackend permissionBackend) {
     this.pluginName = pluginName;
     this.userProvider = userProvider;
+    this.permissionBackend = permissionBackend;
     menuEntries = Lists.newArrayList();
 
     List<MenuItem> projectItems = Lists.newArrayListWithExpectedSize(2);
@@ -51,8 +59,10 @@
   }
 
   private boolean canImport() {
-    CapabilityControl ctl = userProvider.get().getCapabilities();
-    return ctl.canAdministrateServer() || ctl.canPerform(pluginName + "-" + ImportCapability.ID);
+    return permissionBackend
+            .user(userProvider)
+            .testOrFalse(new PluginPermission(pluginName, ImportCapability.ID))
+        || permissionBackend.user(userProvider).testOrFalse(ADMINISTRATE_SERVER);
   }
 
   @Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
index 4090c99..b399ed1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
@@ -28,6 +28,8 @@
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
@@ -162,7 +164,8 @@
   @Override
   public ImportStatistic apply(ConfigResource rsrc, Input input)
       throws RestApiException, OrmException, IOException, ValidationException, GitAPIException,
-          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     if (input == null) {
       input = new Input();
     }
@@ -177,7 +180,8 @@
 
   public ResumeImportStatistic resume(String user, String pass, boolean force, File importStatus)
       throws RestApiException, OrmException, IOException, GitAPIException, NoSuchChangeException,
-          NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     LockFile lockFile = lockForImport();
     try {
       ImportProjectInfo info = ImportJson.parse(importStatus);
@@ -199,7 +203,8 @@
 
   private ResumeImportStatistic apply(LockFile lockFile, Input input, ImportProjectInfo info)
       throws RestApiException, OrmException, IOException, GitAPIException, NoSuchChangeException,
-          NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     boolean resume = info != null;
     api = apiFactory.create(input.from, input.user, input.pass);
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
index 90f4af1..337b36c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/InsertLinkToOriginalChangeStep.java
@@ -28,8 +28,8 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
@@ -40,7 +40,7 @@
   private final CurrentUser currentUser;
   private final ChangeUpdate.Factory updateFactory;
   private final IdentifiedUser.GenericFactory genericUserFactory;
-  private final ChangeControl.GenericFactory changeControlFactory;
+  private final ChangeData.Factory changeDataFactory;
   private final ReviewDb db;
   private final ChangeMessagesUtil cmUtil;
   private final String canonicalWebUrl;
@@ -59,7 +59,7 @@
       CurrentUser currentUser,
       ChangeUpdate.Factory updateFactory,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeData.Factory changeDataFactory,
       ReviewDb db,
       ChangeMessagesUtil cmUtil,
       @CanonicalWebUrl String canonicalWebUrl,
@@ -70,7 +70,7 @@
     this.currentUser = currentUser;
     this.updateFactory = updateFactory;
     this.genericUserFactory = genericUserFactory;
-    this.changeControlFactory = changeControlFactory;
+    this.changeDataFactory = changeDataFactory;
     this.db = db;
     this.cmUtil = cmUtil;
     this.canonicalWebUrl = canonicalWebUrl;
@@ -95,7 +95,8 @@
   private void insertMessage(Change change, String message)
       throws NoSuchChangeException, OrmException, IOException {
     Account.Id userId = ((IdentifiedUser) currentUser).getAccountId();
-    ChangeUpdate update = updateFactory.create(control(change, userId));
+    ChangeData cd = changeDataFactory.create(db, change);
+    ChangeUpdate update = updateFactory.create(cd.notes(), genericUserFactory.create(userId));
     ChangeMessage cmsg =
         new ChangeMessage(
             new ChangeMessage.Key(change.getId(), ChangeUtil.messageUuid()),
@@ -107,14 +108,6 @@
     update.commit();
   }
 
-  private ChangeControl control(Change change, Account.Id id) throws NoSuchChangeException {
-    try {
-      return changeControlFactory.controlFor(db, change, genericUserFactory.create(id));
-    } catch (OrmException e) {
-      throw new NoSuchChangeException(change.getId());
-    }
-  }
-
   private static String ensureSlash(String in) {
     if (in != null && !in.endsWith("/")) {
       return in + "/";
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/LocalApi.java b/src/main/java/com/googlesource/gerrit/plugins/importer/LocalApi.java
index 420b8d6..e3030aa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/LocalApi.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/LocalApi.java
@@ -31,6 +31,7 @@
 import com.google.gerrit.server.account.AccountResource;
 import com.google.gerrit.server.account.AccountsCollection;
 import com.google.gerrit.server.account.GetSshKeys;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.io.IOException;
@@ -121,7 +122,7 @@
       AccountResource rsrc =
           accounts.parse(TopLevelResource.INSTANCE, IdString.fromDecoded(userId));
       return getSshKeys.apply(rsrc);
-    } catch (ResourceNotFoundException | AuthException e) {
+    } catch (ResourceNotFoundException | AuthException | PermissionBackendException e) {
       throw new BadRequestException(e.getMessage());
     }
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
index 75cd315..16f63d6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/OpenRepositoryStep.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.CreateProjectArgs;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectsCollection;
@@ -55,7 +56,8 @@
   }
 
   Repository open(Project.NameKey name, boolean resume, ProgressMonitor pm, Project.NameKey parent)
-      throws ResourceConflictException, IOException, UnprocessableEntityException {
+      throws ResourceConflictException, IOException, UnprocessableEntityException,
+          PermissionBackendException {
     pm.beginTask("Open repository", 1);
     try {
       Repository repo = git.openRepository(name);
@@ -78,10 +80,11 @@
   }
 
   private void beforeCreateProject(Project.NameKey name, Project.NameKey parent)
-      throws ResourceConflictException, UnprocessableEntityException, IOException {
+      throws ResourceConflictException, UnprocessableEntityException, IOException,
+          PermissionBackendException {
     CreateProjectArgs args = new CreateProjectArgs();
     args.setProjectName(name);
-    args.newParent = projectsCollection.get().parse(parent.get()).getControl();
+    args.newParent = projectsCollection.get().parse(parent.get()).getNameKey();
     for (ProjectCreationValidationListener l : projectCreationValidationListeners) {
       try {
         l.validateNewProject(args);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
index 060087b..f69eb9d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
@@ -20,6 +20,8 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.ConfigResource;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.update.UpdateException;
 import com.google.gerrit.server.validators.ValidationException;
@@ -91,7 +93,8 @@
   @Override
   protected void run()
       throws OrmException, IOException, UnloggedFailure, ValidationException, GitAPIException,
-          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     ImportProject.Input input = new ImportProject.Input();
     input.from = url;
     input.name = name;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java
index 600ca02..cb50841 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java
@@ -135,7 +135,6 @@
   }
 
   @Override
-  @SuppressWarnings("unchecked")
   public ImportProject create(ConfigResource parent, IdString id) throws RestApiException {
     return importProjectFactory.create(new Project.NameKey(id.get()));
   }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
index dca177e..ab106a6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -18,7 +18,6 @@
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.common.errors.NoSuchAccountException;
-import com.google.gerrit.extensions.client.ChangeStatus;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.extensions.restapi.Url;
@@ -30,6 +29,7 @@
 import com.google.gerrit.server.Sequences;
 import com.google.gerrit.server.index.change.ChangeIndexer;
 import com.google.gerrit.server.notedb.NotesMigration;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
@@ -130,12 +130,13 @@
     this.resume = resume;
     this.importStatistic = importStatistic;
     this.pm = pm;
-    this.isNoteDbEnabled = migration.enabled();
+    this.isNoteDbEnabled = migration.readChanges();
   }
 
   void replay()
       throws IOException, OrmException, NoSuchAccountException, NoSuchChangeException,
-          RestApiException, UpdateException, ConfigInvalidException {
+          RestApiException, UpdateException, ConfigInvalidException,
+          PatchListNotAvailableException {
     int start = 0;
     int limit = GlobalCapability.DEFAULT_MAX_QUERY_LIMIT;
     pm.beginTask("Replay Changes", ProgressMonitor.UNKNOWN);
@@ -167,12 +168,8 @@
 
   private void replayChange(RevWalk rw, ChangeInfo c)
       throws IOException, OrmException, NoSuchAccountException, NoSuchChangeException,
-          RestApiException, IllegalArgumentException, UpdateException, ConfigInvalidException {
-    if (c.status == ChangeStatus.DRAFT) {
-      // no import of draft changes
-      return;
-    }
-
+          RestApiException, IllegalArgumentException, UpdateException, ConfigInvalidException,
+          PatchListNotAvailableException {
     Change change = resume ? findChange(c) : null;
     boolean resumeChange;
     if (change == null) {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
index 07c524d..4895861 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
@@ -41,9 +41,10 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.config.GerritServerId;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.notedb.ChangeUpdate;
 import com.google.gerrit.server.patch.PatchListCache;
-import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.patch.PatchListNotAvailableException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -71,7 +72,7 @@
   private final AccountUtil accountUtil;
   private final ReviewDb db;
   private final IdentifiedUser.GenericFactory genericUserFactory;
-  private final ChangeControl.GenericFactory changeControlFactory;
+  private final ChangeNotes.Factory changeNotesFactory;
   private final ChangeUpdate.Factory updateFactory;
   private final CommentsUtil commentsUtil;
   private final PatchListCache patchListCache;
@@ -87,7 +88,7 @@
       AccountUtil accountUtil,
       ReviewDb db,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeNotes.Factory changeNotesFactory,
       ChangeUpdate.Factory updateFactory,
       CommentsUtil commentsUtil,
       PatchListCache patchListCache,
@@ -100,7 +101,7 @@
     this.accountUtil = accountUtil;
     this.db = db;
     this.genericUserFactory = genericUserFactory;
-    this.changeControlFactory = changeControlFactory;
+    this.changeNotesFactory = changeNotesFactory;
     this.updateFactory = updateFactory;
     this.commentsUtil = commentsUtil;
     this.patchListCache = patchListCache;
@@ -114,9 +115,9 @@
 
   void replay()
       throws RestApiException, OrmException, IOException, NoSuchChangeException,
-          NoSuchAccountException, ConfigInvalidException {
-    ChangeControl ctrl = control(change, change.getOwner());
-    for (PatchSet ps : ChangeUtil.PS_ID_ORDER.sortedCopy(psUtil.byChange(db, ctrl.getNotes()))) {
+          NoSuchAccountException, ConfigInvalidException, PatchListNotAvailableException {
+    ChangeNotes notes = changeNotesFactory.createChecked(db, change);
+    for (PatchSet ps : ChangeUtil.PS_ID_ORDER.sortedCopy(psUtil.byChange(db, notes))) {
       Iterable<CommentInfo> comments = api.getComments(changeInfo._number, ps.getRevision().get());
       if (resume) {
         if (comments == null) {
@@ -173,10 +174,10 @@
   }
 
   private void insertComments(PatchSet ps, Account.Id author, Collection<CommentInfo> comments)
-      throws OrmException, IOException, NoSuchChangeException {
-    ChangeControl ctrl = control(change, author);
+      throws OrmException, IOException, NoSuchChangeException, PatchListNotAvailableException {
+    ChangeNotes notes = changeNotesFactory.createChecked(db, change);
 
-    Map<String, Comment> drafts = scanDraftComments(ctrl, ps);
+    Map<String, Comment> drafts = scanDraftComments(notes, ps, author);
 
     List<Comment> del = Lists.newArrayList();
     List<Comment> ups = Lists.newArrayList();
@@ -211,7 +212,8 @@
     }
 
     Iterables.addAll(del, drafts.values());
-    ChangeUpdate update = updateFactory.create(ctrl, TimeUtil.nowTs());
+    ChangeUpdate update =
+        updateFactory.create(notes, genericUserFactory.create(author), TimeUtil.nowTs());
     update.setPatchSetId(ps.getId());
 
     commentsUtil.deleteComments(db, update, del);
@@ -219,22 +221,12 @@
     update.commit();
   }
 
-  private Map<String, Comment> scanDraftComments(ChangeControl ctrl, PatchSet ps)
+  private Map<String, Comment> scanDraftComments(ChangeNotes notes, PatchSet ps, Account.Id account)
       throws OrmException {
     Map<String, Comment> drafts = Maps.newHashMap();
-    for (Comment c :
-        commentsUtil.draftByPatchSetAuthor(
-            db, ps.getId(), ((IdentifiedUser) ctrl.getUser()).getAccountId(), ctrl.getNotes())) {
+    for (Comment c : commentsUtil.draftByPatchSetAuthor(db, ps.getId(), account, notes)) {
       drafts.put(c.key.uuid, c);
     }
     return drafts;
   }
-
-  private ChangeControl control(Change change, Account.Id id) throws NoSuchChangeException {
-    try {
-      return changeControlFactory.controlFor(db, change, genericUserFactory.create(id));
-    } catch (OrmException e) {
-      throw new NoSuchChangeException(change.getId());
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
index d93b9c5..98186f5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
@@ -24,9 +24,10 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -47,7 +48,7 @@
   private final ChangeMessagesUtil cmUtil;
   private final ReviewDb db;
   private final IdentifiedUser.GenericFactory genericUserFactory;
-  private final ChangeControl.GenericFactory changeControlFactory;
+  private final ChangeNotes.Factory changeNotesFactory;
   private final Change change;
   private final ChangeInfo changeInfo;
   private final boolean resume;
@@ -58,7 +59,7 @@
       ChangeUpdate.Factory updateFactory,
       ChangeMessagesUtil cmUtil,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeNotes.Factory changeNotesFactory,
       ReviewDb db,
       @Assisted Change change,
       @Assisted ChangeInfo changeInfo,
@@ -68,7 +69,7 @@
     this.cmUtil = cmUtil;
     this.db = db;
     this.genericUserFactory = genericUserFactory;
-    this.changeControlFactory = changeControlFactory;
+    this.changeNotesFactory = changeNotesFactory;
     this.change = change;
     this.changeInfo = changeInfo;
     this.resume = resume;
@@ -89,7 +90,9 @@
           msg._revisionNumber != null ? new PatchSet.Id(change.getId(), msg._revisionNumber) : null;
       if (msg.author != null) {
         Account.Id userId = accountUtil.resolveUser(api, msg.author);
-        ChangeUpdate update = updateFactory.create(control(change, userId), ts);
+        ChangeNotes notes = changeNotesFactory.createChecked(db, change);
+        CurrentUser user = genericUserFactory.create(userId);
+        ChangeUpdate update = updateFactory.create(notes, user, ts);
         ChangeMessage cmsg = new ChangeMessage(msgKey, userId, ts, psId);
         cmsg.setMessage(msg.message);
         cmUtil.addChangeMessage(db, update, cmsg);
@@ -103,12 +106,4 @@
       }
     }
   }
-
-  private ChangeControl control(Change change, Account.Id id) throws NoSuchChangeException {
-    try {
-      return changeControlFactory.controlFor(db, change, genericUserFactory.create(id));
-    } catch (OrmException e) {
-      throw new NoSuchChangeException(change.getId());
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
index cafb248..be52f2d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
@@ -85,10 +85,6 @@
     try {
       PatchSetInfo info = null;
       for (RevisionInfo r : revisions) {
-        if (r.draft != null && r.draft) {
-          // no import of draft patch sets
-          continue;
-        }
         PatchSet ps = new PatchSet(new PatchSet.Id(change.getId(), r._number));
         String newRef = ps.getId().toRefName();
         ObjectId newId = repo.resolve(newRef);
@@ -119,7 +115,6 @@
         ps.setUploader(accountUtil.resolveUser(api, r.uploader));
         ps.setCreatedOn(r.created);
         ps.setRevision(new RevId(commit.name()));
-        ps.setDraft(r.draft != null && r.draft);
 
         info = patchSetInfoFactory.get(rw, commit, ps.getId());
         if (info.getRevId().equals(changeInfo.currentRevision)) {
@@ -179,6 +174,8 @@
       case REJECTED:
       case REJECTED_CURRENT_BRANCH:
       case RENAMED:
+      case REJECTED_MISSING_OBJECT:
+      case REJECTED_OTHER_REASON:
       default:
         throw new IOException(
             String.format("Failed to create ref %s, RefUpdate.Result = %s", ref, result));
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
index d43f5a9..0b85b8f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeCopyProject.java
@@ -14,9 +14,12 @@
 
 package com.googlesource.gerrit.plugins.importer;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.gerrit.common.errors.NoSuchAccountException;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestApiException;
@@ -24,8 +27,10 @@
 import com.google.gerrit.extensions.webui.UiAction;
 import com.google.gerrit.reviewdb.client.Project;
 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.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectResource;
@@ -52,6 +57,7 @@
   private final Provider<CurrentUser> currentUserProvider;
   private final String pluginName;
   private final ProjectCache projectCache;
+  private final PermissionBackend permissionBackend;
 
   private Writer err;
 
@@ -61,12 +67,14 @@
       ProjectsCollection projectsCollection,
       Provider<CurrentUser> currentUserProvider,
       @PluginName String pluginName,
-      ProjectCache projectCache) {
+      ProjectCache projectCache,
+      PermissionBackend permissionBackend) {
     this.resumeProjectImport = resumeProjectImport;
     this.projectsCollection = projectsCollection;
     this.currentUserProvider = currentUserProvider;
     this.pluginName = pluginName;
     this.projectCache = projectCache;
+    this.permissionBackend = permissionBackend;
   }
 
   ResumeCopyProject setErr(Writer err) {
@@ -77,7 +85,8 @@
   @Override
   public ResumeImportStatistic apply(ProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException, GitAPIException,
-          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     ImportProjectResource projectResource =
         projectsCollection.parse(new ConfigResource(), IdString.fromDecoded(rsrc.getName()));
     ResumeProjectImport.Input in = new ResumeProjectImport.Input();
@@ -94,9 +103,10 @@
   }
 
   private boolean canResumeCopy(ProjectResource rsrc) {
-    CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-    return ctl.canAdministrateServer()
-        || (ctl.canPerform(pluginName + "-" + CopyProjectCapability.ID)
+    return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER)
+        || (permissionBackend
+                .user(currentUserProvider)
+                .testOrFalse(new PluginPermission(pluginName, CopyProjectCapability.ID))
             && rsrc.getControl().isOwner());
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
index 80d2dd3..aa74c1c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ResumeProjectImport.java
@@ -14,10 +14,13 @@
 
 package com.googlesource.gerrit.plugins.importer;
 
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
 import com.google.common.base.Strings;
 import com.google.gerrit.common.errors.NoSuchAccountException;
 import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
+import com.google.gerrit.extensions.api.access.PluginPermission;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
@@ -25,8 +28,10 @@
 import com.google.gerrit.extensions.restapi.RestModifyView;
 import com.google.gerrit.extensions.webui.UiAction;
 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.patch.PatchListNotAvailableException;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.project.ProjectResource;
 import com.google.gerrit.server.update.UpdateException;
@@ -91,7 +96,8 @@
   @Override
   public ResumeImportStatistic apply(ImportProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException, GitAPIException,
-          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+          NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+          PermissionBackendException, PatchListNotAvailableException {
     if (copy) {
       input.validateResumeCopy();
     } else {
@@ -111,23 +117,27 @@
     private final ResumeProjectImport resumeProjectImport;
     private final Provider<CurrentUser> currentUserProvider;
     private final String pluginName;
+    private final PermissionBackend permissionBackend;
 
     @Inject
     public OnProjects(
         ProjectsCollection projectsCollection,
         ResumeProjectImport resumeProjectImport,
         Provider<CurrentUser> currentUserProvider,
-        @PluginName String pluginName) {
+        @PluginName String pluginName,
+        PermissionBackend permissionBackend) {
       this.projectsCollection = projectsCollection;
       this.resumeProjectImport = resumeProjectImport;
       this.currentUserProvider = currentUserProvider;
       this.pluginName = pluginName;
+      this.permissionBackend = permissionBackend;
     }
 
     @Override
     public ResumeImportStatistic apply(ProjectResource rsrc, Input input)
         throws RestApiException, IOException, OrmException, ValidationException, GitAPIException,
-            NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException {
+            NoSuchChangeException, NoSuchAccountException, UpdateException, ConfigInvalidException,
+            PermissionBackendException, PatchListNotAvailableException {
       ImportProjectResource projectResource =
           projectsCollection.parse(new ConfigResource(), IdString.fromDecoded(rsrc.getName()));
       return resumeProjectImport.apply(projectResource, input);
@@ -142,9 +152,10 @@
     }
 
     private boolean canResumeImport(ProjectResource rsrc) {
-      CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-      return ctl.canAdministrateServer()
-          || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
+      return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER)
+          || (permissionBackend
+                  .user(currentUserProvider)
+                  .testOrFalse(new PluginPermission(pluginName, ImportCapability.ID))
               && rsrc.getControl().isOwner());
     }
 
diff --git a/src/main/resources/Documentation/about.md b/src/main/resources/Documentation/about.md
index b914b97..40814f0 100644
--- a/src/main/resources/Documentation/about.md
+++ b/src/main/resources/Documentation/about.md
@@ -1,7 +1,7 @@
 The @PLUGIN@ plugin allows to import projects and groups from a remote
 Gerrit server into the Gerrit server where the plugin is installed.
 
-The imports are done online while both, source and target Gerrit
+The imports are done online while both source and target Gerrit
 server, are running.
 
 The user that does the import must be a member of a group that is
@@ -40,8 +40,7 @@
 On project import the configured max object size on the target Gerrit
 server is ignored.
 
-Draft changes, draft patch sets, change edits and draft comments are
-*not* imported.
+Change edits and draft comments are *not* imported.
 
 #### Process
 
@@ -92,9 +91,9 @@
 Account] or the link:access-control.html#capability_administrateServer[
 Administrate Server] capability assigned on the source system.
 
-If for any reason an user is no longer existent in the LDAP instance but it
+If for any reason a user no longer exists in the LDAP instance but it
 is listed as a change owner, reviewer or as part of a group, a local user
-account is created with the same username. Giving that such user is not longer
+account is created with the same username. Given that such a user is no longer
 active in the system, their account status is set to inactive.
 
 Gerrit internal users (e.g. service users) should be created in the target