Merge branch 'stable-2.14'

* stable-2.14:
  Replace additional anonymous classes with lambda expressions
  Replace anonymous classes with lambda expressions
  Remove redundant type argument
  Replace anonymous class with list method
  Use multi catch
  Change project compliance to Java 8
  Remove Buck build
  Add standalone bazel build
  Clean up .gitignore
  Guard against NPE while unboxing possible null Boolean

Change-Id: Icd3e79df864f79ba8ed3c10f48b628f20edad8bb
diff --git a/WORKSPACE b/WORKSPACE
index 6b11560..4c89bfa 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,27 +3,27 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "c2a97a12543ce2ab59126570ca0aea163a0ee743",
+    commit = "b7514d03a7798905ff1513295b46620e57b8f386",
     # local_path = "/home/<user>/projects/bazlets",
 )
 
 #Snapshot Plugin API
-#load(
-#    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
-#    "gerrit_api_maven_local",
-#)
-
-# Load snapshot Plugin API
-#gerrit_api_maven_local()
-
-# Release Plugin API
 load(
-    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
-    "gerrit_api",
+    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+    "gerrit_api_maven_local",
 )
 
+# Load snapshot Plugin API
+gerrit_api_maven_local()
+
+# Release Plugin API
+#load(
+#    "@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+#    "gerrit_api",
+#)
+
 # Load release Plugin API
-gerrit_api()
+#gerrit_api()
 
 load(
     "@com_googlesource_gerrit_bazlets//:gerrit_gwt.bzl",
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 b541966..267925f 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;
@@ -57,7 +56,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;
@@ -67,7 +66,7 @@
       ChangeUpdate.Factory updateFactory,
       ReviewDb db,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeData.Factory changeDataFactory,
       @Assisted Change change,
       @Assisted ChangeInfo changeInfo,
       @Assisted boolean resume) {
@@ -75,7 +74,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;
@@ -96,8 +95,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("Label '%s' not found in target system."
                 + " This label was referenced by an approval provided from '%s'"
@@ -112,7 +111,7 @@
           approvals.add(new PatchSetApproval(new PatchSetApproval.Key(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 {
@@ -124,19 +123,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/CompleteProjectImport.java b/src/main/java/com/googlesource/gerrit/plugins/importer/CompleteProjectImport.java
index 2df913f..f5cabb9 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;
@@ -109,6 +112,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));
@@ -123,16 +128,19 @@
     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
@@ -170,10 +178,10 @@
     }
 
     private boolean canCompleteImport(ProjectResource rsrc) {
-      CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-      return ctl.canAdministrateServer()
-          || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
-              && rsrc.getControl().isOwner());
+      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 579d684..7d9f712 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/CopyProject.java
@@ -14,26 +14,29 @@
 
 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.update.UpdateException;
+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.validators.ValidationException;
 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;
 
@@ -44,7 +47,6 @@
 import java.io.PrintWriter;
 import java.io.Writer;
 
-@Singleton
 @RequiresCapability(CopyProjectCapability.ID)
 class CopyProject implements RestModifyView<ProjectResource, Input>,
     UiAction<ProjectResource> {
@@ -55,24 +57,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 {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     if (Strings.isNullOrEmpty(input.name)) {
       throw new BadRequestException("name is required");
     }
@@ -95,9 +99,9 @@
   }
 
   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 132a36c..a3421d1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/GitFetchStep.java
@@ -83,6 +83,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 bb692cd..c25f5b5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/GroupsCollection.java
@@ -60,7 +60,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 c4bdd7e..88df701 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;
@@ -59,6 +61,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 @RequiresCapability(ImportCapability.ID)
@@ -178,7 +181,7 @@
     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) {
@@ -220,7 +223,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) {
@@ -243,7 +246,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;
   }
@@ -272,7 +275,8 @@
     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);
+        new AccountGroup(new AccountGroup.NameKey(info.name), groupId, uuid,
+            TimeUtil.nowTs());
     group.setVisibleToAll(cfg.getBoolean("groups", "newGroupsVisibleToAll",
         false));
     group.setDescription(info.description);
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 f0b0976..2edfdc1 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;
 
@@ -29,13 +32,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) {
+      Provider<CurrentUser> userProvider,
+      PermissionBackend permissionBackend) {
     this.pluginName = pluginName;
     this.userProvider = userProvider;
+    this.permissionBackend = permissionBackend;
     menuEntries = Lists.newArrayList();
 
     List<MenuItem> projectItems = Lists.newArrayListWithExpectedSize(2);
@@ -54,9 +60,9 @@
   }
 
   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 ea00a2d..9e7c61b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ImportProject.java
@@ -29,6 +29,7 @@
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.update.UpdateException;
+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;
@@ -166,7 +167,7 @@
   public ImportStatistic apply(ConfigResource rsrc, Input input)
       throws RestApiException, OrmException, IOException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException,
-      UpdateException, ConfigInvalidException {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     if (input == null) {
       input = new Input();
     }
@@ -182,7 +183,7 @@
   public ResumeImportStatistic resume(String user, String pass, boolean force,
       File importStatus) throws RestApiException, OrmException, IOException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException,
-      UpdateException, ConfigInvalidException {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     LockFile lockFile = lockForImport();
     try {
       ImportProjectInfo info = ImportJson.parse(importStatus);
@@ -205,7 +206,8 @@
   private ResumeImportStatistic apply(LockFile lockFile, Input input,
       ImportProjectInfo info) throws RestApiException, OrmException,
       IOException, GitAPIException, NoSuchChangeException,
-      NoSuchAccountException, UpdateException, ConfigInvalidException {
+      NoSuchAccountException, UpdateException, ConfigInvalidException,
+      PermissionBackendException {
     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 ba25273..eb3dbe9 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;
@@ -41,7 +41,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;
@@ -62,7 +62,7 @@
   InsertLinkToOriginalChangeStep(CurrentUser currentUser,
       ChangeUpdate.Factory updateFactory,
       IdentifiedUser.GenericFactory genericUserFactory,
-      ChangeControl.GenericFactory changeControlFactory,
+      ChangeData.Factory changeDataFactory,
       ReviewDb db,
       ChangeMessagesUtil cmUtil,
       @CanonicalWebUrl String canonicalWebUrl,
@@ -73,7 +73,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;
@@ -99,7 +99,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()), userId, TimeUtil.nowTs(),
@@ -109,16 +110,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 a5dd841..9248b8c 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;
 
@@ -128,7 +129,7 @@
           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 9386c68..06fb06c 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;
@@ -58,7 +59,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);
@@ -83,10 +85,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 5dbbaae..d55bb4c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectCommand.java
@@ -21,6 +21,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.ConfigResource;
 import com.google.gerrit.server.update.UpdateException;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.NoSuchChangeException;
 import com.google.gerrit.server.validators.ValidationException;
 import com.google.gerrit.sshd.CommandMetaData;
@@ -73,7 +74,7 @@
   protected void run()
       throws OrmException, IOException, UnloggedFailure, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException,
-      UpdateException, ConfigInvalidException {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     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 74d3efb..ded7130 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ProjectsCollection.java
@@ -136,7 +136,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 4f05b44..8f495fd 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayChangesStep.java
@@ -132,7 +132,7 @@
     this.resume = resume;
     this.importStatistic = importStatistic;
     this.pm = pm;
-    this.isNoteDbEnabled = migration.enabled();
+    this.isNoteDbEnabled = migration.readChanges();
   }
 
   void replay() throws IOException, OrmException,
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 07293a6..ec1062c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayInlineCommentsStep.java
@@ -214,7 +214,7 @@
     }
 
     Iterables.addAll(del, drafts.values());
-    ChangeUpdate update = updateFactory.create(ctrl, TimeUtil.nowTs());
+    ChangeUpdate update = updateFactory.create(ctrl.getNotes(), ctrl.getUser(), TimeUtil.nowTs());
     update.setPatchSetId(ps.getId());
 
     commentsUtil.deleteComments(db, update, del);
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 dde14ee..9b1d130 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayMessagesStep.java
@@ -92,7 +92,8 @@
           : null;
       if (msg.author != null) {
         Account.Id userId = accountUtil.resolveUser(api, msg.author);
-        ChangeUpdate update = updateFactory.create(control(change, userId), ts);
+        ChangeControl ctrl = control(change, userId);
+        ChangeUpdate update = updateFactory.create(ctrl.getNotes(), ctrl.getUser(), ts);
         ChangeMessage cmsg = new ChangeMessage(msgKey, userId, ts, psId);
         cmsg.setMessage(msg.message);
         cmUtil.addChangeMessage(db, update, cmsg);
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 85e1a07..c2d20cf 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/importer/ReplayRevisionsStep.java
@@ -181,6 +181,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 f58d421..ae6ed9f 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,9 +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.update.UpdateException;
+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;
@@ -55,6 +59,7 @@
   private final Provider<CurrentUser> currentUserProvider;
   private final String pluginName;
   private final ProjectCache projectCache;
+  private final PermissionBackend permissionBackend;
 
   private Writer err;
 
@@ -64,12 +69,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) {
@@ -81,7 +88,7 @@
   public ResumeImportStatistic apply(ProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException,
-      UpdateException, ConfigInvalidException {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     ImportProjectResource projectResource =
         projectsCollection.parse(new ConfigResource(),
             IdString.fromDecoded(rsrc.getName()));
@@ -103,10 +110,10 @@
   }
 
   private boolean canResumeCopy(ProjectResource rsrc) {
-    CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-    return ctl.canAdministrateServer()
-        || (ctl.canPerform(pluginName + "-" + CopyProjectCapability.ID)
-            && rsrc.getControl().isOwner());
+    return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER) ||
+      (permissionBackend.user(currentUserProvider).testOrFalse(
+      new PluginPermission(pluginName, CopyProjectCapability.ID)) &&
+      rsrc.getControl().isOwner());
   }
 
   private boolean isCopied(ProjectResource rsrc) {
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 40e0d26..996c7e4 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,9 +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.update.UpdateException;
+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.validators.ValidationException;
@@ -95,7 +99,7 @@
   public ResumeImportStatistic apply(ImportProjectResource rsrc, Input input)
       throws RestApiException, IOException, OrmException, ValidationException,
       GitAPIException, NoSuchChangeException, NoSuchAccountException,
-      UpdateException, ConfigInvalidException {
+      UpdateException, ConfigInvalidException, PermissionBackendException {
     if (copy) {
       input.validateResumeCopy();
     } else {
@@ -115,24 +119,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 {
+        UpdateException, ConfigInvalidException, PermissionBackendException {
       ImportProjectResource projectResource =
           projectsCollection.parse(new ConfigResource(),
               IdString.fromDecoded(rsrc.getName()));
@@ -148,10 +155,10 @@
     }
 
     private boolean canResumeImport(ProjectResource rsrc) {
-      CapabilityControl ctl = currentUserProvider.get().getCapabilities();
-      return ctl.canAdministrateServer()
-          || (ctl.canPerform(pluginName + "-" + ImportCapability.ID)
-              && rsrc.getControl().isOwner());
+      return permissionBackend.user(currentUserProvider).testOrFalse(ADMINISTRATE_SERVER) ||
+        (permissionBackend.user(currentUserProvider).testOrFalse(
+        new PluginPermission(pluginName, ImportCapability.ID)) &&
+        rsrc.getControl().isOwner());
     }
 
     private boolean isImported(ProjectResource rsrc) {