Merge "Add experiment flag to disable change etags"
diff --git a/java/com/google/gerrit/acceptance/testsuite/account/AccountOperationsImpl.java b/java/com/google/gerrit/acceptance/testsuite/account/AccountOperationsImpl.java
index b2abac1..bdda27a 100644
--- a/java/com/google/gerrit/acceptance/testsuite/account/AccountOperationsImpl.java
+++ b/java/com/google/gerrit/acceptance/testsuite/account/AccountOperationsImpl.java
@@ -234,7 +234,7 @@
 
       if (testAccountInvalidation.preferredEmailWithoutExternalId().isPresent()) {
         updateAccount(
-            (account, deltaBuilder) ->
+            (unusedState, deltaBuilder) ->
                 deltaBuilder.setPreferredEmail(
                     testAccountInvalidation.preferredEmailWithoutExternalId().get()));
       }
diff --git a/java/com/google/gerrit/server/account/AccountsUpdate.java b/java/com/google/gerrit/server/account/AccountsUpdate.java
index c84c204..5ec97ff 100644
--- a/java/com/google/gerrit/server/account/AccountsUpdate.java
+++ b/java/com/google/gerrit/server/account/AccountsUpdate.java
@@ -24,11 +24,13 @@
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
 import com.google.errorprone.annotations.CanIgnoreReturnValue;
+import com.google.gerrit.common.UsedAt;
 import com.google.gerrit.entities.Account;
 import com.google.gerrit.exceptions.DuplicateKeyException;
 import com.google.gerrit.git.LockFailureException;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.Sequences;
+import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.inject.BindingAnnotation;
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -89,15 +91,20 @@
   public static class UpdateArguments {
     public final String message;
     public final Account.Id accountId;
-    public final ConfigureDeltaFromState configureDelta;
+    public final ConfigureDeltaFromStateAndContext configureDelta;
 
     public UpdateArguments(
         String message, Account.Id accountId, ConfigureStatelessDelta configureDelta) {
-      this(message, accountId, (a, u) -> configureDelta.configure(u));
+      this(message, accountId, withContext(configureDelta));
     }
 
     public UpdateArguments(
         String message, Account.Id accountId, ConfigureDeltaFromState configureDelta) {
+      this(message, accountId, withContext(configureDelta));
+    }
+
+    public UpdateArguments(
+        String message, Account.Id accountId, ConfigureDeltaFromStateAndContext configureDelta) {
       this.message = message;
       this.accountId = accountId;
       this.configureDelta = configureDelta;
@@ -113,12 +120,24 @@
   }
 
   /**
-   * The most basic interface for updating the account delta, providing no state.
+   * Storage readers/writers which are accessible through {@link ConfigureDeltaFromStateAndContext}.
    *
-   * <p>Account updates that do not need to know the current account state should use this
-   * interface.
+   * <p>If you need to perform extra reads/writes during the update, prefer using these, to avoid
+   * mishmash between different storage systems where multiple ones are supported. If you need an
+   * accessor which is not yet here, please do add it.
+   */
+  public interface InUpdateStorageAccessors {
+    ExternalIds externalIdsReader();
+  }
+
+  /**
+   * The most basic interface for updating the account delta, providing no state nor context.
    *
-   * <p>If the current {@link AccountState} is needed, use {@link ConfigureDeltaFromState} instead.
+   * <p>Account updates that do not need to know the current account state, nor read/write any extra
+   * data during the update, should use this interface.
+   *
+   * <p>If the above capabilities are needed, use {@link ConfigureDeltaFromState} or {@link
+   * ConfigureDeltaFromStateAndContext} instead.
    */
   @FunctionalInterface
   public interface ConfigureStatelessDelta {
@@ -138,6 +157,8 @@
    * a delta to be applied to it in a later step. This is done by implementing this interface.
    *
    * <p>If the current account state is not needed, use {@link ConfigureStatelessDelta} instead.
+   * Alternatively, if you need to perform extra storage reads/writes during the update, use {@link
+   * ConfigureDeltaFromStateAndContext}.
    */
   @FunctionalInterface
   public interface ConfigureDeltaFromState {
@@ -151,6 +172,35 @@
     void configure(AccountState accountState, AccountDelta.Builder delta) throws IOException;
   }
 
+  /**
+   * Interface for updating the account delta, providing the current state and storage accessors.
+   *
+   * <p>Account updates which need to perform extra storage reads/writes during the update, should
+   * use this interface.
+   *
+   * <p>If storage accessors are not needed, use {@link ConfigureStatelessDelta} or {@link
+   * ConfigureDeltaFromState} instead.
+   */
+  @FunctionalInterface
+  public interface ConfigureDeltaFromStateAndContext {
+    /**
+     * Receives {@link InUpdateStorageAccessors} for reading/modifying data on the respective
+     * storage system, as well as the current {@link AccountState} (which is immutable). Configures
+     * an {@link com.google.gerrit.server.account.AccountDelta.Builder} with changes to the account.
+     *
+     * @param inUpdateStorageAccessors storage accessor which have the context of the update (e.g.,
+     *     use the same storage system as the calling updater)
+     * @param accountState the state of the account that is being updated
+     * @param delta the changes to be applied
+     * @see InUpdateStorageAccessors
+     */
+    void configure(
+        InUpdateStorageAccessors inUpdateStorageAccessors,
+        AccountState accountState,
+        AccountDelta.Builder delta)
+        throws IOException;
+  }
+
   /** Returns an instance that runs all specified consumers. */
   public static ConfigureStatelessDelta joinDeltaConfigures(
       List<ConfigureStatelessDelta> deltaConfigures) {
@@ -161,11 +211,21 @@
   protected final PersonIdent authorIdent;
 
   protected final Optional<IdentifiedUser> currentUser;
+  private final InUpdateStorageAccessors inUpdateStorageAccessors;
 
-  protected AccountsUpdate(PersonIdent serverIdent, Optional<IdentifiedUser> user) {
+  @SuppressWarnings("Convert2Lambda")
+  protected AccountsUpdate(
+      PersonIdent serverIdent, Optional<IdentifiedUser> user, ExternalIds externalIdsReader) {
     this.currentUser = user;
     this.committerIdent = serverIdent;
     this.authorIdent = createPersonIdent(serverIdent, user);
+    this.inUpdateStorageAccessors =
+        new InUpdateStorageAccessors() {
+          @Override
+          public ExternalIds externalIdsReader() {
+            return externalIdsReader;
+          }
+        };
   }
 
   /**
@@ -184,18 +244,34 @@
    */
   @CanIgnoreReturnValue
   public abstract AccountState insert(
-      String message, Account.Id accountId, ConfigureDeltaFromState init)
+      String message, Account.Id accountId, ConfigureDeltaFromStateAndContext init)
       throws IOException, ConfigInvalidException;
 
   /**
-   * Like {@link #insert(String, Account.Id, ConfigureDeltaFromState)}, but using {@link
-   * ConfigureStatelessDelta} instead. I.e. the update does not depend on the current account state.
+   * Like {@link #insert(String, Account.Id, ConfigureDeltaFromStateAndContext)}, but using {@link
+   * ConfigureDeltaFromState} instead. I.e. the update does not require any extra storage
+   * reads/writes, except for the current {@link AccountState}.
+   *
+   * <p>If the current account state is not needed as well, use {@link #insert(String, Account.Id,
+   * ConfigureStatelessDelta)} instead.
+   */
+  @CanIgnoreReturnValue
+  public final AccountState insert(
+      String message, Account.Id accountId, ConfigureDeltaFromState init)
+      throws IOException, ConfigInvalidException {
+    return insert(message, accountId, withContext(init));
+  }
+
+  /**
+   * Like {@link #insert(String, Account.Id, ConfigureDeltaFromStateAndContext)}, but using {@link
+   * ConfigureStatelessDelta} instead. I.e. the update does not depend on the current account state,
+   * nor requires any extra storage reads/writes.
    */
   @CanIgnoreReturnValue
   public final AccountState insert(
       String message, Account.Id accountId, ConfigureStatelessDelta init)
       throws IOException, ConfigInvalidException {
-    return insert(message, accountId, (a, u) -> init.configure(u));
+    return insert(message, accountId, withContext(init));
   }
 
   /**
@@ -217,14 +293,29 @@
    */
   @CanIgnoreReturnValue
   public final Optional<AccountState> update(
-      String message, Account.Id accountId, ConfigureDeltaFromState configureDelta)
+      String message, Account.Id accountId, ConfigureDeltaFromStateAndContext configureDelta)
       throws IOException, ConfigInvalidException {
     return updateBatch(ImmutableList.of(new UpdateArguments(message, accountId, configureDelta)))
         .get(0);
   }
 
   /**
-   * Like {@link #update(String, Account.Id, ConfigureDeltaFromState)} , but using {@link
+   * Like {@link #update(String, Account.Id, ConfigureDeltaFromStateAndContext)}, but using {@link
+   * ConfigureDeltaFromState} instead. I.e. the update does not require any extra storage
+   * reads/writes, except for the current {@link AccountState}.
+   *
+   * <p>If the current account state is not needed as well, use {@link #update(String, Account.Id,
+   * ConfigureStatelessDelta)} instead.
+   */
+  @CanIgnoreReturnValue
+  public final Optional<AccountState> update(
+      String message, Account.Id accountId, ConfigureDeltaFromState configureDelta)
+      throws IOException, ConfigInvalidException {
+    return update(message, accountId, withContext(configureDelta));
+  }
+
+  /**
+   * Like {@link #update(String, Account.Id, ConfigureDeltaFromStateAndContext)} , but using {@link
    * ConfigureStatelessDelta} instead. I.e. the update does not depend on the current account state,
    * nor requires any extra storage reads/writes.
    */
@@ -232,7 +323,7 @@
   public final Optional<AccountState> update(
       String message, Account.Id accountId, ConfigureStatelessDelta configureDelta)
       throws IOException, ConfigInvalidException {
-    return update(message, accountId, (a, u) -> configureDelta.configure(u));
+    return update(message, accountId, withContext(configureDelta));
   }
 
   /**
@@ -269,6 +360,29 @@
   public abstract ImmutableList<Optional<AccountState>> executeUpdates(
       List<UpdateArguments> updates) throws ConfigInvalidException, IOException;
 
+  /**
+   * Intended for internal usage only. This is public because some implementations are calling this
+   * method for other instances.
+   */
+  @UsedAt(UsedAt.Project.GOOGLE)
+  public final void configureDelta(
+      ConfigureDeltaFromStateAndContext configureDelta,
+      AccountState accountState,
+      AccountDelta.Builder delta)
+      throws IOException {
+    configureDelta.configure(inUpdateStorageAccessors, accountState, delta);
+  }
+
+  private static ConfigureDeltaFromStateAndContext withContext(
+      ConfigureDeltaFromState configureDelta) {
+    return (unusedAccessors, accountState, delta) -> configureDelta.configure(accountState, delta);
+  }
+
+  private static ConfigureDeltaFromStateAndContext withContext(
+      ConfigureStatelessDelta configureDelta) {
+    return (unusedAccessors, unusedAccountState, delta) -> configureDelta.configure(delta);
+  }
+
   private static PersonIdent createPersonIdent(
       PersonIdent serverIdent, Optional<IdentifiedUser> user) {
     return user.isPresent() ? user.get().newCommitterIdent(serverIdent) : serverIdent;
diff --git a/java/com/google/gerrit/server/account/storage/notedb/AccountsUpdateNoteDbImpl.java b/java/com/google/gerrit/server/account/storage/notedb/AccountsUpdateNoteDbImpl.java
index 08b2fa5..551cd78 100644
--- a/java/com/google/gerrit/server/account/storage/notedb/AccountsUpdateNoteDbImpl.java
+++ b/java/com/google/gerrit/server/account/storage/notedb/AccountsUpdateNoteDbImpl.java
@@ -271,7 +271,7 @@
       PersonIdent committerIdent,
       Runnable afterReadRevision,
       Runnable beforeCommit) {
-    super(committerIdent, currentUser);
+    super(committerIdent, currentUser, externalIds);
     this.repoManager = requireNonNull(repoManager, "repoManager");
     this.gitRefUpdated = requireNonNull(gitRefUpdated, "gitRefUpdated");
     this.allUsersName = requireNonNull(allUsersName, "allUsersName");
@@ -285,7 +285,8 @@
   }
 
   @Override
-  public AccountState insert(String message, Account.Id accountId, ConfigureDeltaFromState init)
+  public AccountState insert(
+      String message, Account.Id accountId, ConfigureDeltaFromStateAndContext init)
       throws IOException, ConfigInvalidException {
     return execute(
             ImmutableList.of(
@@ -294,7 +295,7 @@
                   Account account = accountConfig.getNewAccount(committerIdent.getWhenAsInstant());
                   AccountState accountState = AccountState.forAccount(account);
                   AccountDelta.Builder deltaBuilder = AccountDelta.builder();
-                  init.configure(accountState, deltaBuilder);
+                  configureDelta(init, accountState, deltaBuilder);
 
                   AccountDelta accountDelta = deltaBuilder.build();
                   accountConfig.setAccountDelta(accountDelta);
@@ -330,7 +331,7 @@
       }
 
       AccountDelta.Builder deltaBuilder = AccountDelta.builder();
-      updateArguments.configureDelta.configure(accountState.get(), deltaBuilder);
+      configureDelta(updateArguments.configureDelta, accountState.get(), deltaBuilder);
 
       AccountDelta delta = deltaBuilder.build();
       updateExternalIdNotes(
diff --git a/java/com/google/gerrit/server/query/change/ChangeNumberBitmapMaskAlgorithm.java b/java/com/google/gerrit/server/query/change/ChangeNumberBitmapMaskAlgorithm.java
index 95c287a..ecd1fe2 100644
--- a/java/com/google/gerrit/server/query/change/ChangeNumberBitmapMaskAlgorithm.java
+++ b/java/com/google/gerrit/server/query/change/ChangeNumberBitmapMaskAlgorithm.java
@@ -19,6 +19,9 @@
 import com.google.gerrit.entities.Change;
 import com.google.gerrit.server.config.GerritImportedServerIds;
 import com.google.gerrit.server.config.GerritServerId;
+import com.google.gerrit.server.logging.Metadata;
+import com.google.gerrit.server.logging.TraceContext;
+import com.google.gerrit.server.logging.TraceContext.TraceTimer;
 import com.google.inject.Inject;
 import com.google.inject.ProvisionException;
 import com.google.inject.Singleton;
@@ -68,20 +71,24 @@
     }
 
     int changeNum = changeNumId.get();
+    try (TraceTimer timer =
+        TraceContext.newTimer(
+            "ChangeNumberBitmapMaskAlgorithm", Metadata.builder().changeId(changeNum).build())) {
+      if ((changeNum & LEGACY_ID_BIT_MASK) != changeNum) {
+        throw new IllegalArgumentException(
+            String.format(
+                "Change number %d is too large to be converted into a virtual id", changeNum));
+      }
 
-    if ((changeNum & LEGACY_ID_BIT_MASK) != changeNum) {
-      throw new IllegalArgumentException(
-          String.format(
-              "Change number %d is too large to be converted into a virtual id", changeNum));
+      Integer encodedServerId = serverIdCodes.get(changeServerId);
+      if (encodedServerId == null) {
+        throw new IllegalArgumentException(
+            String.format(
+                "ServerId %s is not part of the GerritImportedServerIds", changeServerId));
+      }
+      int virtualId = (changeNum & LEGACY_ID_BIT_MASK) | (encodedServerId << CHANGE_NUM_BIT_LEN);
+
+      return Change.id(virtualId);
     }
-
-    Integer encodedServerId = serverIdCodes.get(changeServerId);
-    if (encodedServerId == null) {
-      throw new IllegalArgumentException(
-          String.format("ServerId %s is not part of the GerritImportedServerIds", changeServerId));
-    }
-    int virtualId = (changeNum & LEGACY_ID_BIT_MASK) | (encodedServerId << CHANGE_NUM_BIT_LEN);
-
-    return Change.id(virtualId);
   }
 }
diff --git a/java/com/google/gerrit/server/restapi/account/PutPreferred.java b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
index b1af85e..1c7b1ca 100644
--- a/java/com/google/gerrit/server/restapi/account/PutPreferred.java
+++ b/java/com/google/gerrit/server/restapi/account/PutPreferred.java
@@ -33,7 +33,6 @@
 import com.google.gerrit.server.account.AccountsUpdate;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.account.externalids.ExternalIdFactory;
-import com.google.gerrit.server.account.externalids.ExternalIds;
 import com.google.gerrit.server.permissions.GlobalPermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
@@ -63,7 +62,6 @@
   private final Provider<CurrentUser> self;
   private final PermissionBackend permissionBackend;
   private final Provider<AccountsUpdate> accountsUpdateProvider;
-  private final ExternalIds externalIds;
   private final ExternalIdFactory externalIdFactory;
 
   @Inject
@@ -71,12 +69,10 @@
       Provider<CurrentUser> self,
       PermissionBackend permissionBackend,
       @ServerInitiated Provider<AccountsUpdate> accountsUpdateProvider,
-      ExternalIds externalIds,
       ExternalIdFactory externalIdFactory) {
     this.self = self;
     this.permissionBackend = permissionBackend;
     this.accountsUpdateProvider = accountsUpdateProvider;
-    this.externalIds = externalIds;
     this.externalIdFactory = externalIdFactory;
   }
 
@@ -99,7 +95,7 @@
             .update(
                 "Set Preferred Email via API",
                 user.getAccountId(),
-                (a, u) -> {
+                (r, a, u) -> {
                   if (preferredEmail.equals(a.account().preferredEmail())) {
                     alreadyPreferred.set(true);
                   } else {
@@ -125,7 +121,7 @@
                       if (user.hasEmailAddress(preferredEmail)) {
                         // but Realm says the user is allowed to use this email
                         ImmutableSet<ExternalId> existingExtIdsWithThisEmail =
-                            externalIds.byEmail(preferredEmail);
+                            r.externalIdsReader().byEmail(preferredEmail);
                         if (!existingExtIdsWithThisEmail.isEmpty()) {
                           // but the email is already assigned to another account
                           logger.atWarning().log(
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index fdf7457..b720a0dc 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -2765,10 +2765,10 @@
     int initialCommits = countExternalIdsCommits();
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", admin.id(), (a, u) -> u.addExternalId(extId1));
+            "Add External ID", admin.id(), u -> u.addExternalId(extId1));
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", user.id(), (a, u) -> u.addExternalId(extId2));
+            "Add External ID", user.id(), u -> u.addExternalId(extId2));
     ImmutableList<Optional<AccountState>> accountStates =
         accountsUpdateProvider.get().updateBatch(ImmutableList.of(ua1, ua2));
     assertThat(accountStates).hasSize(2);
@@ -2811,11 +2811,11 @@
 
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", admin.id(), (a, u) -> u.addExternalId(extId1));
+            "Add External ID", admin.id(), u -> u.addExternalId(extId1));
     // Another update for the same account is not allowed.
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", admin.id(), (a, u) -> u.addExternalId(extId2));
+            "Add External ID", admin.id(), u -> u.addExternalId(extId2));
     IllegalArgumentException e =
         assertThrows(
             IllegalArgumentException.class,
@@ -2834,10 +2834,10 @@
 
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", admin.id(), (a, u) -> u.addExternalId(extIdAdmin));
+            "Add External ID", admin.id(), u -> u.addExternalId(extIdAdmin));
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", user.id(), (a, u) -> u.addExternalId(extIdUser));
+            "Add External ID", user.id(), u -> u.addExternalId(extIdUser));
     DuplicateExternalIdKeyException e =
         assertThrows(
             DuplicateExternalIdKeyException.class,
@@ -2856,10 +2856,10 @@
 
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "first message", admin.id(), (a, u) -> u.addExternalId(extId1));
+            "first message", admin.id(), u -> u.addExternalId(extId1));
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
-            "second message", user.id(), (a, u) -> u.addExternalId(extId2));
+            "second message", user.id(), u -> u.addExternalId(extId2));
     accountsUpdateProvider.get().updateBatch(ImmutableList.of(ua1, ua2));
 
     try (Repository allUsersRepo = repoManager.openRepository(allUsers);
@@ -2877,7 +2877,7 @@
         getExternalIdFactory()
             .createWithEmail(externalIdKeyFactory.parse("foo:bar"), admin.id(), "1@foo.com");
 
-    accountsUpdateProvider.get().update("foobar", admin.id(), (a, u) -> u.addExternalId(extId));
+    accountsUpdateProvider.get().update("foobar", admin.id(), u -> u.addExternalId(extId));
 
     try (Repository allUsersRepo = repoManager.openRepository(allUsers);
         RevWalk rw = new RevWalk(allUsersRepo)) {
@@ -2997,7 +2997,7 @@
     ExternalId externalId = getExternalIdFactory().create("custom", "value", admin.id());
     accountsUpdateProvider
         .get()
-        .update("Add External ID", admin.id(), (a, u) -> u.addExternalId(externalId));
+        .update("Add External ID", admin.id(), u -> u.addExternalId(externalId));
     assertExternalIds(
         admin.id(), ImmutableSet.of("mailto:admin@example.com", "username:admin", "custom:value"));
 
@@ -3013,7 +3013,7 @@
     ExternalId externalId = createEmailExternalId(admin.id(), "admin@example.com");
     accountsUpdateProvider
         .get()
-        .update("Remove External ID", admin.id(), (a, u) -> u.deleteExternalId(externalId));
+        .update("Remove External ID", admin.id(), u -> u.deleteExternalId(externalId));
     assertExternalIds(admin.id(), ImmutableSet.of("username:admin"));
 
     AccountState updatedState = accountCache.get(admin.id()).get();
@@ -3031,7 +3031,7 @@
                 SCHEME_MAILTO, "secondary@non.google", admin.id(), "secondary@non.google");
     accountsUpdateProvider
         .get()
-        .update("Update External ID", admin.id(), (a, u) -> u.updateExternalId(externalId));
+        .update("Update External ID", admin.id(), u -> u.updateExternalId(externalId));
     assertExternalIds(
         admin.id(),
         ImmutableSet.of(
@@ -3055,11 +3055,7 @@
     accountsUpdateProvider
         .get()
         .update(
-            "Replace External ID",
-            admin.id(),
-            (a, u) -> {
-              u.replaceExternalId(oldExternalId, externalId);
-            });
+            "Replace External ID", admin.id(), u -> u.replaceExternalId(oldExternalId, externalId));
     assertExternalIds(admin.id(), ImmutableSet.of("mailto:secondary@non.google", "username:admin"));
 
     AccountState updatedState = accountCache.get(admin.id()).get();
@@ -3089,10 +3085,10 @@
 
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", admin.id(), (a, u) -> u.addExternalId(extId1));
+            "Add External ID", admin.id(), u -> u.addExternalId(extId1));
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
-            "Add External ID", user.id(), (a, u) -> u.addExternalId(extId2));
+            "Add External ID", user.id(), u -> u.addExternalId(extId2));
     AccountIndexedCounter accountIndexedCounter = getAccountIndexedCounter();
     try (Registration registration =
         extensionRegistry.newRegistration().add(accountIndexedCounter)) {
@@ -3129,12 +3125,12 @@
     requestScopeOperations.setApiUser(admin.id());
     AccountsUpdate.UpdateArguments ua1 =
         new AccountsUpdate.UpdateArguments(
-            "Update Display Name", admin.id(), (a, u) -> u.setDisplayName("DN"));
+            "Update Display Name", admin.id(), u -> u.setDisplayName("DN"));
     AccountsUpdate.UpdateArguments ua2 =
         new AccountsUpdate.UpdateArguments(
             "Remove external Id",
             user.id(),
-            (a, u) -> u.deleteExternalId(createEmailExternalId(user.id(), user.email())));
+            u -> u.deleteExternalId(createEmailExternalId(user.id(), user.email())));
     AccountIndexedCounter accountIndexedCounter = getAccountIndexedCounter();
     try (Registration registration =
         extensionRegistry.newRegistration().add(accountIndexedCounter)) {
diff --git a/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java b/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
index 2476f00..a696354 100644
--- a/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/account/AccountResolverIT.java
@@ -433,7 +433,7 @@
     Optional<AccountState> result =
         accountsUpdateProvider
             .get()
-            .update("Force set preferred email", id, (s, u) -> u.setPreferredEmail(email));
+            .update("Force set preferred email", id, u -> u.setPreferredEmail(email));
     assertThat(result.map(a -> a.account().preferredEmail())).hasValue(email);
   }
 }