ApprovalsUtil: Use ChangeNotes and CurrentUser instead of ChangeControl

Change-Id: I1ff07204f8b6b6cd3f2c00f05b94c4635e1822f7
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalCopier.java b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalCopier.java
index 538c7c2..6971b48 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalCopier.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalCopier.java
@@ -29,9 +29,9 @@
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.change.ChangeKindCache;
 import com.google.gerrit.server.git.LabelNormalizer;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.notedb.NoteDbChangeState.PrimaryStorage;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -79,7 +79,8 @@
    * Apply approval copy settings from prior PatchSets to a new PatchSet.
    *
    * @param db review database.
-   * @param ctl change control for user uploading PatchSet
+   * @param notes change notes for user uploading PatchSet
+   * @param user user uploading PatchSet
    * @param ps new PatchSet
    * @param rw open walk that can read the patch set commit; null to open the repo on demand.
    * @param repoConfig repo config used for change kind detection; null to read from repo on demand.
@@ -87,19 +88,21 @@
    */
   public void copyInReviewDb(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet ps,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig)
       throws OrmException {
-    copyInReviewDb(db, ctl, ps, rw, repoConfig, Collections.emptyList());
+    copyInReviewDb(db, notes, user, ps, rw, repoConfig, Collections.emptyList());
   }
 
   /**
    * Apply approval copy settings from prior PatchSets to a new PatchSet.
    *
    * @param db review database.
-   * @param ctl change control for user uploading PatchSet
+   * @param notes change notes for user uploading PatchSet
+   * @param user user uploading PatchSet
    * @param ps new PatchSet
    * @param rw open walk that can read the patch set commit; null to open the repo on demand.
    * @param repoConfig repo config used for change kind detection; null to read from repo on demand.
@@ -108,52 +111,57 @@
    */
   public void copyInReviewDb(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet ps,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig,
       Iterable<PatchSetApproval> dontCopy)
       throws OrmException {
-    if (PrimaryStorage.of(ctl.getChange()) == PrimaryStorage.REVIEW_DB) {
-      db.patchSetApprovals().insert(getForPatchSet(db, ctl, ps, rw, repoConfig, dontCopy));
+    if (PrimaryStorage.of(notes.getChange()) == PrimaryStorage.REVIEW_DB) {
+      db.patchSetApprovals().insert(getForPatchSet(db, notes, user, ps, rw, repoConfig, dontCopy));
     }
   }
 
   Iterable<PatchSetApproval> getForPatchSet(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet.Id psId,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig)
       throws OrmException {
-    return getForPatchSet(db, ctl, psId, rw, repoConfig, Collections.<PatchSetApproval>emptyList());
+    return getForPatchSet(
+        db, notes, user, psId, rw, repoConfig, Collections.<PatchSetApproval>emptyList());
   }
 
   Iterable<PatchSetApproval> getForPatchSet(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet.Id psId,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig,
       Iterable<PatchSetApproval> dontCopy)
       throws OrmException {
-    PatchSet ps = psUtil.get(db, ctl.getNotes(), psId);
+    PatchSet ps = psUtil.get(db, notes, psId);
     if (ps == null) {
       return Collections.emptyList();
     }
-    return getForPatchSet(db, ctl, ps, rw, repoConfig, dontCopy);
+    return getForPatchSet(db, notes, user, ps, rw, repoConfig, dontCopy);
   }
 
   private Iterable<PatchSetApproval> getForPatchSet(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet ps,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig,
       Iterable<PatchSetApproval> dontCopy)
       throws OrmException {
     checkNotNull(ps, "ps should not be null");
-    ChangeData cd = changeDataFactory.create(db, ctl);
+    ChangeData cd = changeDataFactory.create(db, notes);
     try {
       ProjectState project = projectCache.checkedGet(cd.change().getDest().getParentKey());
       ListMultimap<PatchSet.Id, PatchSetApproval> all = cd.approvals();
@@ -204,7 +212,7 @@
           byUser.put(psa.getLabel(), psa.getAccountId(), copy(psa, ps.getId()));
         }
       }
-      return labelNormalizer.normalize(ctl, byUser.values()).getNormalized();
+      return labelNormalizer.normalize(notes, user, byUser.values()).getNormalized();
     } catch (IOException | PermissionBackendException e) {
       throw new OrmException(e);
     }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
index d858da5..31107c9 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ApprovalsUtil.java
@@ -49,7 +49,6 @@
 import com.google.gerrit.server.permissions.LabelPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.util.LabelVote;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
@@ -385,7 +384,8 @@
 
   public Iterable<PatchSetApproval> byPatchSet(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet.Id psId,
       @Nullable RevWalk rw,
       @Nullable Config repoConfig)
@@ -393,12 +393,13 @@
     if (!migration.readChanges()) {
       return sortApprovals(db.patchSetApprovals().byPatchSet(psId));
     }
-    return copier.getForPatchSet(db, ctl, psId, rw, repoConfig);
+    return copier.getForPatchSet(db, notes, user, psId, rw, repoConfig);
   }
 
   public Iterable<PatchSetApproval> byPatchSetUser(
       ReviewDb db,
-      ChangeControl ctl,
+      ChangeNotes notes,
+      CurrentUser user,
       PatchSet.Id psId,
       Account.Id accountId,
       @Nullable RevWalk rw,
@@ -407,7 +408,7 @@
     if (!migration.readChanges()) {
       return sortApprovals(db.patchSetApprovals().byPatchSetUser(psId, accountId));
     }
-    return filterApprovals(byPatchSet(db, ctl, psId, rw, repoConfig), accountId);
+    return filterApprovals(byPatchSet(db, notes, user, psId, rw, repoConfig), accountId);
   }
 
   public PatchSetApproval getSubmitter(ReviewDb db, ChangeNotes notes, PatchSet.Id c) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
index 02c04f4..c2b93a6 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
@@ -1080,11 +1080,16 @@
   private Map<String, Short> currentLabels(PermissionBackend.ForChange perm, ChangeData cd)
       throws OrmException {
     IdentifiedUser user = perm.user().asIdentifiedUser();
-    ChangeControl ctl = cd.changeControl().forUser(user);
     Map<String, Short> result = new HashMap<>();
     for (PatchSetApproval psa :
         approvalsUtil.byPatchSetUser(
-            db.get(), ctl, cd.change().currentPatchSetId(), user.getAccountId(), null, null)) {
+            db.get(),
+            cd.notes(),
+            user,
+            cd.change().currentPatchSetId(),
+            user.getAccountId(),
+            null,
+            null)) {
       result.put(psa.getLabel(), psa.getValue());
     }
     return result;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteVote.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteVote.java
index c725089..10164ce 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteVote.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeleteVote.java
@@ -41,7 +41,6 @@
 import com.google.gerrit.server.mail.send.DeleteVoteSender;
 import com.google.gerrit.server.mail.send.ReplyToChangeSender;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.project.RemoveReviewerControl;
@@ -164,10 +163,9 @@
     public boolean updateChange(ChangeContext ctx)
         throws OrmException, AuthException, ResourceNotFoundException, IOException,
             PermissionBackendException {
-      ChangeControl ctl = ctx.getControl();
-      change = ctl.getChange();
+      change = ctx.getChange();
       PatchSet.Id psId = change.currentPatchSetId();
-      ps = psUtil.current(db.get(), ctl.getNotes());
+      ps = psUtil.current(db.get(), ctx.getNotes());
 
       boolean found = false;
       LabelTypes labelTypes = projectState.getLabelTypes(ctx.getNotes(), ctx.getUser());
@@ -175,7 +173,8 @@
       for (PatchSetApproval a :
           approvalsUtil.byPatchSetUser(
               ctx.getDb(),
-              ctl,
+              ctx.getNotes(),
+              ctx.getUser(),
               psId,
               account.getId(),
               ctx.getRevWalk(),
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
index 77f4e5c..05f10b5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
@@ -49,7 +49,6 @@
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.ssh.NoSshInfo;
 import com.google.gerrit.server.update.BatchUpdateOp;
@@ -228,7 +227,6 @@
   public boolean updateChange(ChangeContext ctx)
       throws ResourceConflictException, OrmException, IOException {
     ReviewDb db = ctx.getDb();
-    ChangeControl ctl = ctx.getControl();
 
     change = ctx.getChange();
     ChangeUpdate update = ctx.getUpdate(psId);
@@ -261,7 +259,7 @@
             description);
 
     if (notify != NotifyHandling.NONE) {
-      oldReviewers = approvalsUtil.getReviewers(db, ctl.getNotes());
+      oldReviewers = approvalsUtil.getReviewers(db, ctx.getNotes());
     }
 
     if (message != null) {
@@ -283,7 +281,12 @@
     change.setCurrentPatchSet(patchSetInfo);
     if (copyApprovals) {
       approvalCopier.copyInReviewDb(
-          db, ctl, patchSet, ctx.getRevWalk(), ctx.getRepoView().getConfig());
+          db,
+          ctx.getNotes(),
+          ctx.getUser(),
+          patchSet,
+          ctx.getRevWalk(),
+          ctx.getRepoView().getConfig());
     }
     if (changeMessage != null) {
       cmUtil.addChangeMessage(db, update, changeMessage);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
index 8c4dd04..ca62719 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostReview.java
@@ -1311,7 +1311,8 @@
       for (PatchSetApproval a :
           approvalsUtil.byPatchSetUser(
               ctx.getDb(),
-              ctx.getControl(),
+              ctx.getNotes(),
+              ctx.getUser(),
               psId,
               user.getAccountId(),
               ctx.getRevWalk(),
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ReviewerJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ReviewerJson.java
index 310f700..60ec582 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ReviewerJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ReviewerJson.java
@@ -111,7 +111,7 @@
         perm,
         cd,
         approvalsUtil.byPatchSetUser(
-            db.get(), ctl, psId, new Account.Id(out._accountId), null, null));
+            db.get(), cd.notes(), ctl.getUser(), psId, new Account.Id(out._accountId), null, null));
   }
 
   public ReviewerInfo format(
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Votes.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Votes.java
index 980e6e5..c2631d5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Votes.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Votes.java
@@ -84,7 +84,8 @@
       Iterable<PatchSetApproval> byPatchSetUser =
           approvalsUtil.byPatchSetUser(
               db.get(),
-              rsrc.getChangeResource().getControl(),
+              rsrc.getChangeResource().getNotes(),
+              rsrc.getChangeResource().getUser(),
               rsrc.getChange().currentPatchSetId(),
               rsrc.getReviewerUser().getAccountId(),
               null,
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/LabelNormalizer.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/LabelNormalizer.java
index 2eeed24..6a332cd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/LabelNormalizer.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/LabelNormalizer.java
@@ -28,16 +28,18 @@
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.permissions.LabelPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.project.ChangeControl;
+import com.google.gerrit.server.project.ProjectCache;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
+import java.io.IOException;
 import java.util.Collection;
 import java.util.List;
 
@@ -76,57 +78,59 @@
   }
 
   private final Provider<ReviewDb> db;
-  private final ChangeControl.GenericFactory changeFactory;
   private final IdentifiedUser.GenericFactory userFactory;
   private final PermissionBackend permissionBackend;
+  private final ProjectCache projectCache;
 
   @Inject
   LabelNormalizer(
       Provider<ReviewDb> db,
-      ChangeControl.GenericFactory changeFactory,
       IdentifiedUser.GenericFactory userFactory,
-      PermissionBackend permissionBackend) {
+      PermissionBackend permissionBackend,
+      ProjectCache projectCache) {
     this.db = db;
-    this.changeFactory = changeFactory;
     this.userFactory = userFactory;
     this.permissionBackend = permissionBackend;
+    this.projectCache = projectCache;
   }
 
   /**
-   * @param change change containing the given approvals.
+   * @param notes change containing the given approvals.
    * @param approvals list of approvals.
    * @return copies of approvals normalized to the defined ranges for the label type and permissions
    *     for the user. Approvals for unknown labels are not included in the output, nor are
    *     approvals where the user has no permissions for that label.
    * @throws OrmException
    */
-  public Result normalize(Change change, Collection<PatchSetApproval> approvals)
-      throws OrmException, PermissionBackendException {
-    IdentifiedUser user = userFactory.create(change.getOwner());
-    return normalize(changeFactory.controlFor(db.get(), change, user), approvals);
+  public Result normalize(ChangeNotes notes, Collection<PatchSetApproval> approvals)
+      throws OrmException, PermissionBackendException, IOException {
+    IdentifiedUser user = userFactory.create(notes.getChange().getOwner());
+    return normalize(notes, user, approvals);
   }
 
   /**
-   * @param ctl change control containing the given approvals.
+   * @param notes change notes containing the given approvals.
+   * @param user current user.
    * @param approvals list of approvals.
    * @return copies of approvals normalized to the defined ranges for the label type and permissions
    *     for the user. Approvals for unknown labels are not included in the output, nor are
    *     approvals where the user has no permissions for that label.
    */
-  public Result normalize(ChangeControl ctl, Collection<PatchSetApproval> approvals)
-      throws PermissionBackendException {
+  public Result normalize(
+      ChangeNotes notes, CurrentUser user, Collection<PatchSetApproval> approvals)
+      throws PermissionBackendException, IOException {
     List<PatchSetApproval> unchanged = Lists.newArrayListWithCapacity(approvals.size());
     List<PatchSetApproval> updated = Lists.newArrayListWithCapacity(approvals.size());
     List<PatchSetApproval> deleted = Lists.newArrayListWithCapacity(approvals.size());
     LabelTypes labelTypes =
-        ctl.getProjectControl().getProjectState().getLabelTypes(ctl.getNotes(), ctl.getUser());
+        projectCache.checkedGet(notes.getProjectName()).getLabelTypes(notes, user);
     for (PatchSetApproval psa : approvals) {
       Change.Id changeId = psa.getKey().getParentKey().getParentKey();
       checkArgument(
-          changeId.equals(ctl.getId()),
+          changeId.equals(notes.getChangeId()),
           "Approval %s does not match change %s",
           psa.getKey(),
-          ctl.getChange().getKey());
+          notes.getChange().getKey());
       if (psa.isLegacySubmit()) {
         unchanged.add(psa);
         continue;
@@ -138,7 +142,7 @@
       }
       PatchSetApproval copy = copy(psa);
       applyTypeFloor(label, copy);
-      if (!applyRightFloor(ctl.getNotes(), label, copy)) {
+      if (!applyRightFloor(notes, label, copy)) {
         deleted.add(psa);
       } else if (copy.getValue() != psa.getValue()) {
         updated.add(copy);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
index 1cabc53..8f409ec 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeUtil.java
@@ -39,11 +39,13 @@
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
+import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.config.CanonicalWebUrl;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk;
 import com.google.gerrit.server.git.strategy.CommitMergeStatus;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.project.ChangeControl;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gwtorm.server.OrmException;
@@ -355,7 +357,7 @@
 
     PatchSetApproval submitAudit = null;
 
-    for (PatchSetApproval a : safeGetApprovals(ctl, psId)) {
+    for (PatchSetApproval a : safeGetApprovals(ctl.getNotes(), ctl.getUser(), psId)) {
       if (a.getValue() <= 0) {
         // Negative votes aren't counted.
         continue;
@@ -448,9 +450,10 @@
     return "Verified".equalsIgnoreCase(id.get());
   }
 
-  private Iterable<PatchSetApproval> safeGetApprovals(ChangeControl ctl, PatchSet.Id psId) {
+  private Iterable<PatchSetApproval> safeGetApprovals(
+      ChangeNotes notes, CurrentUser user, PatchSet.Id psId) {
     try {
-      return approvalsUtil.byPatchSet(db.get(), ctl, psId, null, null);
+      return approvalsUtil.byPatchSet(db.get(), notes, user, psId, null, null);
     } catch (OrmException e) {
       log.error("Can't read approval records for " + psId, e);
       return Collections.emptyList();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReplaceOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReplaceOp.java
index 3399071..8c67c72 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReplaceOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/receive/ReplaceOp.java
@@ -311,7 +311,8 @@
             approvals);
     approvalCopier.copyInReviewDb(
         ctx.getDb(),
-        ctx.getControl(),
+        ctx.getNotes(),
+        ctx.getUser(),
         newPatchSet,
         ctx.getRevWalk(),
         ctx.getRepoView().getConfig(),
@@ -401,7 +402,8 @@
       for (PatchSetApproval a :
           approvalsUtil.byPatchSetUser(
               ctx.getDb(),
-              ctx.getControl(),
+              ctx.getNotes(),
+              ctx.getUser(),
               priorPatchSetId,
               ctx.getAccountId(),
               ctx.getRevWalk(),
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/strategy/SubmitStrategyOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/strategy/SubmitStrategyOp.java
index affa918..1284fca 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/strategy/SubmitStrategyOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/strategy/SubmitStrategyOp.java
@@ -358,7 +358,12 @@
     Map<PatchSetApproval.Key, PatchSetApproval> byKey = new HashMap<>();
     for (PatchSetApproval psa :
         args.approvalsUtil.byPatchSet(
-            ctx.getDb(), ctx.getControl(), psId, ctx.getRevWalk(), ctx.getRepoView().getConfig())) {
+            ctx.getDb(),
+            ctx.getNotes(),
+            ctx.getUser(),
+            psId,
+            ctx.getRevWalk(),
+            ctx.getRepoView().getConfig())) {
       byKey.put(psa.getKey(), psa);
     }
 
@@ -372,7 +377,7 @@
     // was added. So we need to make sure votes are accurate now. This way if
     // permissions get modified in the future, historical records stay accurate.
     LabelNormalizer.Result normalized =
-        args.labelNormalizer.normalize(ctx.getControl(), byKey.values());
+        args.labelNormalizer.normalize(ctx.getNotes(), ctx.getUser(), byKey.values());
     update.putApproval(submitter.getLabel(), submitter.getValue());
     saveApprovals(normalized, ctx, update, false);
     return normalized;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
index 68bcda4..0f4f376 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/receive/MailProcessor.java
@@ -292,7 +292,8 @@
       approvalsUtil
           .byPatchSetUser(
               ctx.getDb(),
-              changeControl,
+              changeControl.getNotes(),
+              changeControl.getUser(),
               psId,
               ctx.getAccountId(),
               ctx.getRevWalk(),
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/MergedSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/MergedSender.java
index 9c2e39d..2afb4a5 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/MergedSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/send/MergedSender.java
@@ -70,7 +70,12 @@
       Table<Account.Id, String, PatchSetApproval> neg = HashBasedTable.create();
       for (PatchSetApproval ca :
           args.approvalsUtil.byPatchSet(
-              args.db.get(), changeData.changeControl(), patchSet.getId(), null, null)) {
+              args.db.get(),
+              changeData.notes(),
+              changeData.changeControl().getUser(),
+              patchSet.getId(),
+              null,
+              null)) {
         LabelType lt = labelTypes.byLabel(ca.getLabelId());
         if (lt == null) {
           continue;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index f5e4542..13fc362 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -293,7 +293,8 @@
     }
 
     for (PatchSetApproval ap :
-        approvalsUtil.byPatchSet(db, this, getChange().currentPatchSetId(), null, null)) {
+        approvalsUtil.byPatchSet(
+            db, getNotes(), getUser(), getChange().currentPatchSetId(), null, null)) {
       LabelType type =
           getProjectControl()
               .getProjectState()
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
index fb19ba2..3a1c60a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeData.java
@@ -718,7 +718,8 @@
         try {
           currentApprovals =
               ImmutableList.copyOf(
-                  approvalsUtil.byPatchSet(db, changeControl(), c.currentPatchSetId(), null, null));
+                  approvalsUtil.byPatchSet(
+                      db, notes(), changeControl().getUser(), c.currentPatchSetId(), null, null));
         } catch (OrmException e) {
           if (e.getCause() instanceof NoSuchChangeException) {
             currentApprovals = Collections.emptyList();
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/LabelNormalizerTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/LabelNormalizerTest.java
index eabccf7..75b00fd 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/LabelNormalizerTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/LabelNormalizerTest.java
@@ -40,6 +40,7 @@
 import com.google.gerrit.server.account.AuthRequest;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.git.LabelNormalizer.Result;
+import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.schema.SchemaCreator;
 import com.google.gerrit.server.util.RequestContext;
@@ -69,12 +70,14 @@
   @Inject private ProjectCache projectCache;
   @Inject private SchemaCreator schemaCreator;
   @Inject protected ThreadLocalRequestContext requestContext;
+  @Inject private ChangeNotes.Factory changeNotesFactory;
 
   private LifecycleManager lifecycle;
   private ReviewDb db;
   private Account.Id userId;
   private IdentifiedUser user;
   private Change change;
+  private ChangeNotes notes;
 
   @Before
   public void setUpInjector() throws Exception {
@@ -131,6 +134,7 @@
     ps.setSubject("Test change");
     change.setCurrentPatchSet(ps);
     db.changes().insert(ImmutableList.of(change));
+    notes = changeNotesFactory.createChecked(db, change);
   }
 
   @After
@@ -155,7 +159,7 @@
     PatchSetApproval cr = psa(userId, "Code-Review", 2);
     PatchSetApproval v = psa(userId, "Verified", 1);
     assertEquals(
-        Result.create(list(v), list(copy(cr, 1)), list()), norm.normalize(change, list(cr, v)));
+        Result.create(list(v), list(copy(cr, 1)), list()), norm.normalize(notes, list(cr, v)));
   }
 
   @Test
@@ -169,14 +173,14 @@
     PatchSetApproval v = psa(userId, "Verified", 5);
     assertEquals(
         Result.create(list(), list(copy(cr, 2), copy(v, 1)), list()),
-        norm.normalize(change, list(cr, v)));
+        norm.normalize(notes, list(cr, v)));
   }
 
   @Test
   public void emptyPermissionRangeOmitsResult() throws Exception {
     PatchSetApproval cr = psa(userId, "Code-Review", 1);
     PatchSetApproval v = psa(userId, "Verified", 1);
-    assertEquals(Result.create(list(), list(), list(cr, v)), norm.normalize(change, list(cr, v)));
+    assertEquals(Result.create(list(), list(), list(cr, v)), norm.normalize(notes, list(cr, v)));
   }
 
   @Test
@@ -187,7 +191,7 @@
 
     PatchSetApproval cr = psa(userId, "Code-Review", 0);
     PatchSetApproval v = psa(userId, "Verified", 0);
-    assertEquals(Result.create(list(cr), list(), list(v)), norm.normalize(change, list(cr, v)));
+    assertEquals(Result.create(list(cr), list(), list(v)), norm.normalize(notes, list(cr, v)));
   }
 
   private ProjectConfig loadAllProjects() throws Exception {
diff --git a/plugins/reviewnotes b/plugins/reviewnotes
index fe99eb4..5e6d0fb 160000
--- a/plugins/reviewnotes
+++ b/plugins/reviewnotes
@@ -1 +1 @@
-Subproject commit fe99eb4399054d3fd67ff2330aa92841d76e53bb
+Subproject commit 5e6d0fb102a2d5486c94a0ea7463efd1508f5ade