Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Fix classpath generation for Eclipse project
  Align Eclipse compiler settings with core Gerrit's

Change-Id: I7b6ba3f25f871b4346629c414496833644f030e5
diff --git a/WORKSPACE b/WORKSPACE
index fc37c3a..2704b12 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "0cdf281f110834b71ae134afe0a7e3fe346f0078",
+    commit = "6d3fd710ea4ca44805bb8c858d72b53bd3a500f3",
     # 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..feb5da6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/AccountUtil.java
@@ -32,8 +32,8 @@
 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.account.externalids.ExternalId;
 import com.google.gerrit.server.config.AuthConfig;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
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