Merge "Upgrade guava to 25.0-jre"
diff --git a/WORKSPACE b/WORKSPACE
index 2e462f7..15d8651 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -680,8 +680,8 @@
 
 maven_jar(
     name = "junit",
-    artifact = "junit:junit:4.11",
-    sha1 = "4e031bb61df09069aeb2bffb4019e7a5034a4ee0",
+    artifact = "junit:junit:4.12",
+    sha1 = "2973d150c0dc1fefe998f834810d68f278ea58ec",
 )
 
 maven_jar(
diff --git a/java/com/google/gerrit/extensions/registration/DynamicMap.java b/java/com/google/gerrit/extensions/registration/DynamicMap.java
index e0db0c7..7178a16 100644
--- a/java/com/google/gerrit/extensions/registration/DynamicMap.java
+++ b/java/com/google/gerrit/extensions/registration/DynamicMap.java
@@ -83,6 +83,11 @@
     binder.bind(key).toProvider(new DynamicMapProvider<>(member)).in(Scopes.SINGLETON);
   }
 
+  /** Returns an empty DynamicMap instance * */
+  public static <T> DynamicMap<T> emptyMap() {
+    return new PrivateInternals_DynamicMapImpl<>();
+  }
+
   final ConcurrentMap<NamePair, Provider<T>> items;
 
   DynamicMap() {
@@ -188,8 +193,8 @@
     private final String exportName;
 
     NamePair(String pn, String en) {
-      this.pluginName = pn;
-      this.exportName = en;
+      pluginName = pn;
+      exportName = en;
     }
 
     @Override
@@ -206,8 +211,4 @@
       return false;
     }
   }
-
-  public static <T> DynamicMap<T> emptyMap() {
-    return new DynamicMap<T>() {};
-  }
 }
diff --git a/java/com/google/gerrit/extensions/registration/DynamicSet.java b/java/com/google/gerrit/extensions/registration/DynamicSet.java
index 5cdf267..7ffb86d 100644
--- a/java/com/google/gerrit/extensions/registration/DynamicSet.java
+++ b/java/com/google/gerrit/extensions/registration/DynamicSet.java
@@ -139,7 +139,7 @@
   }
 
   public DynamicSet() {
-    this(Collections.<AtomicReference<Provider<T>>>emptySet());
+    this(Collections.emptySet());
   }
 
   @Override
diff --git a/java/com/google/gerrit/extensions/registration/PrivateInternals_DynamicMapImpl.java b/java/com/google/gerrit/extensions/registration/PrivateInternals_DynamicMapImpl.java
index 50aed7d..1973f70 100644
--- a/java/com/google/gerrit/extensions/registration/PrivateInternals_DynamicMapImpl.java
+++ b/java/com/google/gerrit/extensions/registration/PrivateInternals_DynamicMapImpl.java
@@ -14,6 +14,8 @@
 
 package com.google.gerrit.extensions.registration;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import com.google.gerrit.extensions.annotations.Export;
 import com.google.inject.Key;
 import com.google.inject.Provider;
@@ -31,6 +33,7 @@
    * @return handle to remove the item at a later point in time.
    */
   public RegistrationHandle put(String pluginName, String exportName, Provider<T> item) {
+    checkNotNull(item);
     final NamePair key = new NamePair(pluginName, exportName);
     items.put(key, item);
     return new RegistrationHandle() {
@@ -53,6 +56,7 @@
    *     the collection.
    */
   public ReloadableRegistrationHandle<T> put(String pluginName, Key<T> key, Provider<T> item) {
+    checkNotNull(item);
     String exportName = ((Export) key.getAnnotation()).value();
     NamePair np = new NamePair(pluginName, exportName);
     items.put(np, item);
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalId.java b/java/com/google/gerrit/server/account/externalids/ExternalId.java
index 442bc2a..db8ea41 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalId.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalId.java
@@ -118,6 +118,8 @@
    * AuthType#HTTP_LDAP}, and {@link AuthType#LDAP_BIND} usernames.
    *
    * <p>The name {@code gerrit:} was a very poor choice.
+   *
+   * <p>Scheme names must not contain colons (':').
    */
   public static final String SCHEME_GERRIT = "gerrit";
 
@@ -140,6 +142,13 @@
   public abstract static class Key implements Serializable {
     private static final long serialVersionUID = 1L;
 
+    /**
+     * Creates an external ID key.
+     *
+     * @param scheme the scheme name, must not contain colons (':'), can be {@code null}
+     * @param id the external ID, must not contain colons (':')
+     * @return the created external ID key
+     */
     public static Key create(@Nullable String scheme, String id) {
       return new AutoValue_ExternalId_Key(Strings.emptyToNull(scheme), id);
     }
@@ -198,10 +207,28 @@
     }
   }
 
+  /**
+   * Creates an external ID.
+   *
+   * @param scheme the scheme name, must not contain colons (':')
+   * @param id the external ID, must not contain colons (':')
+   * @param accountId the ID of the account to which the external ID belongs
+   * @return the created external ID
+   */
   public static ExternalId create(String scheme, String id, Account.Id accountId) {
     return create(Key.create(scheme, id), accountId, null, null);
   }
 
+  /**
+   * Creates an external ID.
+   *
+   * @param scheme the scheme name, must not contain colons (':')
+   * @param id the external ID, must not contain colons (':')
+   * @param accountId the ID of the account to which the external ID belongs
+   * @param email the email of the external ID, may be {@code null}
+   * @param hashedPassword the hashed password of the external ID, may be {@code null}
+   * @return the created external ID
+   */
   public static ExternalId create(
       String scheme,
       String id,
@@ -222,17 +249,35 @@
   }
 
   public static ExternalId createWithPassword(
-      Key key, Account.Id accountId, @Nullable String email, String plainPassword) {
+      Key key, Account.Id accountId, @Nullable String email, @Nullable String plainPassword) {
     plainPassword = Strings.emptyToNull(plainPassword);
     String hashedPassword =
         plainPassword != null ? HashedPassword.fromPassword(plainPassword).encode() : null;
     return create(key, accountId, email, hashedPassword);
   }
 
-  public static ExternalId createUsername(String id, Account.Id accountId, String plainPassword) {
+  /**
+   * Create a external ID for a username (scheme "username").
+   *
+   * @param id the external ID, must not contain colons (':')
+   * @param accountId the ID of the account to which the external ID belongs
+   * @param plainPassword the plain HTTP password, may be {@code null}
+   * @return the created external ID
+   */
+  public static ExternalId createUsername(
+      String id, Account.Id accountId, @Nullable String plainPassword) {
     return createWithPassword(Key.create(SCHEME_USERNAME, id), accountId, null, plainPassword);
   }
 
+  /**
+   * Creates an external ID with an email.
+   *
+   * @param scheme the scheme name, must not contain colons (':')
+   * @param id the external ID, must not contain colons (':')
+   * @param accountId the ID of the account to which the external ID belongs
+   * @param email the email of the external ID, may be {@code null}
+   * @return the created external ID
+   */
   public static ExternalId createWithEmail(
       String scheme, String id, Account.Id accountId, @Nullable String email) {
     return createWithEmail(Key.create(scheme, id), accountId, email);
diff --git a/java/com/google/gerrit/server/permissions/ChangeControl.java b/java/com/google/gerrit/server/permissions/ChangeControl.java
index b13d921..3a17965 100644
--- a/java/com/google/gerrit/server/permissions/ChangeControl.java
+++ b/java/com/google/gerrit/server/permissions/ChangeControl.java
@@ -29,6 +29,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 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.PermissionBackend.ForChange;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -47,11 +48,16 @@
   static class Factory {
     private final ChangeData.Factory changeDataFactory;
     private final ChangeNotes.Factory notesFactory;
+    private final IdentifiedUser.GenericFactory identifiedUserFactory;
 
     @Inject
-    Factory(ChangeData.Factory changeDataFactory, ChangeNotes.Factory notesFactory) {
+    Factory(
+        ChangeData.Factory changeDataFactory,
+        ChangeNotes.Factory notesFactory,
+        IdentifiedUser.GenericFactory identifiedUserFactory) {
       this.changeDataFactory = changeDataFactory;
       this.notesFactory = notesFactory;
+      this.identifiedUserFactory = identifiedUserFactory;
     }
 
     ChangeControl create(
@@ -61,17 +67,22 @@
     }
 
     ChangeControl create(RefControl refControl, ChangeNotes notes) {
-      return new ChangeControl(changeDataFactory, refControl, notes);
+      return new ChangeControl(changeDataFactory, identifiedUserFactory, refControl, notes);
     }
   }
 
   private final ChangeData.Factory changeDataFactory;
+  private final IdentifiedUser.GenericFactory identifiedUserFactory;
   private final RefControl refControl;
   private final ChangeNotes notes;
 
   private ChangeControl(
-      ChangeData.Factory changeDataFactory, RefControl refControl, ChangeNotes notes) {
+      ChangeData.Factory changeDataFactory,
+      IdentifiedUser.GenericFactory identifiedUserFactory,
+      RefControl refControl,
+      ChangeNotes notes) {
     this.changeDataFactory = changeDataFactory;
+    this.identifiedUserFactory = identifiedUserFactory;
     this.refControl = refControl;
     this.notes = notes;
   }
@@ -84,7 +95,8 @@
     if (getUser().equals(who)) {
       return this;
     }
-    return new ChangeControl(changeDataFactory, refControl.forUser(who), notes);
+    return new ChangeControl(
+        changeDataFactory, identifiedUserFactory, refControl.forUser(who), notes);
   }
 
   private CurrentUser getUser() {
@@ -261,6 +273,11 @@
     }
 
     @Override
+    public ForChange absentUser(Account.Id id) {
+      return user(identifiedUserFactory.create(id));
+    }
+
+    @Override
     public String resourcePath() {
       if (resourcePath == null) {
         resourcePath =
diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
index 02eed30..490b45e 100644
--- a/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/DefaultPermissionBackend.java
@@ -79,8 +79,8 @@
   }
 
   @Override
-  public WithUser absentUser(Account.Id user) {
-    IdentifiedUser identifiedUser = identifiedUserFactory.create(checkNotNull(user, "user"));
+  public WithUser absentUser(Account.Id id) {
+    IdentifiedUser identifiedUser = identifiedUserFactory.create(checkNotNull(id, "user"));
     return new WithUserImpl(identifiedUser);
   }
 
diff --git a/java/com/google/gerrit/server/permissions/FailedPermissionBackend.java b/java/com/google/gerrit/server/permissions/FailedPermissionBackend.java
index 35b6e0d..431bfd9 100644
--- a/java/com/google/gerrit/server/permissions/FailedPermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/FailedPermissionBackend.java
@@ -15,6 +15,7 @@
 package com.google.gerrit.server.permissions;
 
 import com.google.gerrit.extensions.api.access.GlobalOrPluginPermission;
+import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
@@ -129,6 +130,11 @@
     }
 
     @Override
+    public ForProject absentUser(Account.Id id) {
+      return this;
+    }
+
+    @Override
     public String resourcePath() {
       throw new UnsupportedOperationException(
           "FailedPermissionBackend is not scoped to a resource");
@@ -182,6 +188,11 @@
     }
 
     @Override
+    public ForRef absentUser(Account.Id id) {
+      return this;
+    }
+
+    @Override
     public String resourcePath() {
       throw new UnsupportedOperationException(
           "FailedPermissionBackend is not scoped to a resource");
@@ -234,6 +245,11 @@
     }
 
     @Override
+    public ForChange absentUser(Account.Id id) {
+      return this;
+    }
+
+    @Override
     public String resourcePath() {
       throw new UnsupportedOperationException(
           "FailedPermissionBackend is not scoped to a resource");
diff --git a/java/com/google/gerrit/server/permissions/PermissionBackend.java b/java/com/google/gerrit/server/permissions/PermissionBackend.java
index 4cbd77e..8cdb61d 100644
--- a/java/com/google/gerrit/server/permissions/PermissionBackend.java
+++ b/java/com/google/gerrit/server/permissions/PermissionBackend.java
@@ -112,7 +112,7 @@
    *
    * <p>Usage should be very limited as this can expose a group-oracle.
    */
-  public abstract WithUser absentUser(Account.Id user);
+  public abstract WithUser absentUser(Account.Id id);
 
   /**
    * Check whether this {@code PermissionBackend} respects the same global capabilities as the
@@ -305,6 +305,9 @@
     /** Returns a new instance rescoped to same project, but different {@code user}. */
     public abstract ForProject user(CurrentUser user);
 
+    /** @see PermissionBackend#absentUser(Account.Id) */
+    public abstract ForProject absentUser(Account.Id id);
+
     /** Returns an instance scoped for {@code ref} in this project. */
     public abstract ForRef ref(String ref);
 
@@ -413,6 +416,9 @@
     /** Returns a new instance rescoped to same reference, but different {@code user}. */
     public abstract ForRef user(CurrentUser user);
 
+    /** @see PermissionBackend#absentUser(Account.Id) */
+    public abstract ForRef absentUser(Account.Id id);
+
     /** Returns an instance scoped to change. */
     public abstract ForChange change(ChangeData cd);
 
@@ -471,6 +477,9 @@
     /** Returns a new instance rescoped to same change, but different {@code user}. */
     public abstract ForChange user(CurrentUser user);
 
+    /** @see PermissionBackend#absentUser(Account.Id) */
+    public abstract ForChange absentUser(Account.Id id);
+
     /** Verify scoped user can {@code perm}, throwing if denied. */
     public abstract void check(ChangePermissionOrLabel perm)
         throws AuthException, PermissionBackendException;
diff --git a/java/com/google/gerrit/server/permissions/ProjectControl.java b/java/com/google/gerrit/server/permissions/ProjectControl.java
index dbd60ea..2d2a64d 100644
--- a/java/com/google/gerrit/server/permissions/ProjectControl.java
+++ b/java/com/google/gerrit/server/permissions/ProjectControl.java
@@ -20,6 +20,7 @@
 import com.google.gerrit.common.data.Permission;
 import com.google.gerrit.common.data.PermissionRule;
 import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
@@ -27,6 +28,7 @@
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.GroupMembership;
 import com.google.gerrit.server.config.GitReceivePackGroups;
 import com.google.gerrit.server.config.GitUploadPackGroups;
@@ -67,6 +69,7 @@
   private final ChangeControl.Factory changeControlFactory;
   private final PermissionCollection.Factory permissionFilter;
   private final DefaultRefFilter.Factory refFilterFactory;
+  private final IdentifiedUser.GenericFactory identifiedUserFactory;
 
   private List<SectionMatcher> allSections;
   private Map<String, RefControl> refControls;
@@ -80,6 +83,7 @@
       ChangeControl.Factory changeControlFactory,
       PermissionBackend permissionBackend,
       DefaultRefFilter.Factory refFilterFactory,
+      IdentifiedUser.GenericFactory identifiedUserFactory,
       @Assisted CurrentUser who,
       @Assisted ProjectState ps) {
     this.changeControlFactory = changeControlFactory;
@@ -88,6 +92,7 @@
     this.permissionFilter = permissionFilter;
     this.permissionBackend = permissionBackend;
     this.refFilterFactory = refFilterFactory;
+    this.identifiedUserFactory = identifiedUserFactory;
     user = who;
     state = ps;
   }
@@ -101,6 +106,7 @@
             changeControlFactory,
             permissionBackend,
             refFilterFactory,
+            identifiedUserFactory,
             who,
             state);
     // Not per-user, and reusing saves lookup time.
@@ -132,7 +138,7 @@
     RefControl ctl = refControls.get(refName);
     if (ctl == null) {
       PermissionCollection relevant = permissionFilter.filter(access(), refName, user);
-      ctl = new RefControl(this, refName, relevant);
+      ctl = new RefControl(identifiedUserFactory, this, refName, relevant);
       refControls.put(refName, ctl);
     }
     return ctl;
@@ -327,6 +333,11 @@
     }
 
     @Override
+    public ForProject absentUser(Account.Id id) {
+      return user(identifiedUserFactory.create(id));
+    }
+
+    @Override
     public String resourcePath() {
       if (resourcePath == null) {
         resourcePath = "/projects/" + getProjectState().getName();
diff --git a/java/com/google/gerrit/server/permissions/RefControl.java b/java/com/google/gerrit/server/permissions/RefControl.java
index 28781ea..cd1f84a 100644
--- a/java/com/google/gerrit/server/permissions/RefControl.java
+++ b/java/com/google/gerrit/server/permissions/RefControl.java
@@ -21,10 +21,12 @@
 import com.google.gerrit.common.data.PermissionRule;
 import com.google.gerrit.common.data.PermissionRule.Action;
 import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
 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.PermissionBackend.ForChange;
 import com.google.gerrit.server.permissions.PermissionBackend.ForRef;
@@ -39,6 +41,7 @@
 
 /** Manages access control for Git references (aka branches, tags). */
 class RefControl {
+  private final IdentifiedUser.GenericFactory identifiedUserFactory;
   private final ProjectControl projectControl;
   private final String refName;
 
@@ -52,7 +55,12 @@
   private Boolean canForgeCommitter;
   private Boolean isVisible;
 
-  RefControl(ProjectControl projectControl, String ref, PermissionCollection relevant) {
+  RefControl(
+      IdentifiedUser.GenericFactory identifiedUserFactory,
+      ProjectControl projectControl,
+      String ref,
+      PermissionCollection relevant) {
+    this.identifiedUserFactory = identifiedUserFactory;
     this.projectControl = projectControl;
     this.refName = ref;
     this.relevant = relevant;
@@ -71,7 +79,7 @@
     if (relevant.isUserSpecific()) {
       return newCtl.controlForRef(refName);
     }
-    return new RefControl(newCtl, refName, relevant);
+    return new RefControl(identifiedUserFactory, newCtl, refName, relevant);
   }
 
   /** Is this user a ref owner? */
@@ -404,6 +412,11 @@
     }
 
     @Override
+    public ForRef absentUser(Account.Id id) {
+      return user(identifiedUserFactory.create(id));
+    }
+
+    @Override
     public String resourcePath() {
       if (resourcePath == null) {
         resourcePath =
diff --git a/java/com/google/gerrit/server/restapi/change/PostReviewers.java b/java/com/google/gerrit/server/restapi/change/PostReviewers.java
index 46955e8..c344513 100644
--- a/java/com/google/gerrit/server/restapi/change/PostReviewers.java
+++ b/java/com/google/gerrit/server/restapi/change/PostReviewers.java
@@ -376,18 +376,18 @@
 
   private boolean isValidReviewer(Account member, PermissionBackend.ForRef perm)
       throws PermissionBackendException {
-    if (member.isActive()) {
-      IdentifiedUser user = identifiedUserFactory.create(member.getId());
-      // Does not account for draft status as a user might want to let a
-      // reviewer see a draft.
-      try {
-        perm.user(user).check(RefPermission.READ);
-        return true;
-      } catch (AuthException e) {
-        return false;
-      }
+    if (!member.isActive()) {
+      return false;
     }
-    return false;
+
+    // Does not account for draft status as a user might want to let a
+    // reviewer see a draft.
+    try {
+      perm.absentUser(member.getId()).check(RefPermission.READ);
+      return true;
+    } catch (AuthException e) {
+      return false;
+    }
   }
 
   private Addition fail(String reviewer, String error) {
@@ -464,8 +464,8 @@
       if (migration.readChanges() && state == CC) {
         result.ccs = Lists.newArrayListWithCapacity(opResult.addedCCs().size());
         for (Account.Id accountId : opResult.addedCCs()) {
-          IdentifiedUser u = identifiedUserFactory.create(accountId);
-          result.ccs.add(json.format(new ReviewerInfo(accountId.get()), perm.user(u), cd));
+          result.ccs.add(
+              json.format(new ReviewerInfo(accountId.get()), perm.absentUser(accountId), cd));
         }
         accountLoaderFactory.create(true).fill(result.ccs);
         for (Address a : reviewersByEmail) {
@@ -475,11 +475,10 @@
         result.reviewers = Lists.newArrayListWithCapacity(opResult.addedReviewers().size());
         for (PatchSetApproval psa : opResult.addedReviewers()) {
           // New reviewers have value 0, don't bother normalizing.
-          IdentifiedUser u = identifiedUserFactory.create(psa.getAccountId());
           result.reviewers.add(
               json.format(
                   new ReviewerInfo(psa.getAccountId().get()),
-                  perm.user(u),
+                  perm.absentUser(psa.getAccountId()),
                   cd,
                   ImmutableList.of(psa)));
         }
diff --git a/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java b/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
index 935dfc6..fd9c925 100644
--- a/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
+++ b/javatests/com/google/gerrit/server/config/ListCapabilitiesTest.java
@@ -87,7 +87,7 @@
     }
 
     @Override
-    public WithUser absentUser(Id user) {
+    public WithUser absentUser(Id id) {
       throw new UnsupportedOperationException();
     }
 
diff --git a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
index d242962..834f658 100644
--- a/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
+++ b/javatests/com/google/gerrit/server/extensions/webui/UiActionsTest.java
@@ -78,6 +78,11 @@
     }
 
     @Override
+    public ForProject absentUser(Account.Id id) {
+      throw new UnsupportedOperationException("not implemented");
+    }
+
+    @Override
     public ForRef ref(String ref) {
       throw new UnsupportedOperationException("not implemented");
     }
diff --git a/javatests/com/google/gerrit/server/permissions/RefControlTest.java b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
index c30803a..7890de8 100644
--- a/javatests/com/google/gerrit/server/permissions/RefControlTest.java
+++ b/javatests/com/google/gerrit/server/permissions/RefControlTest.java
@@ -47,6 +47,7 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.CapabilityCollection;
 import com.google.gerrit.server.account.GroupMembership;
 import com.google.gerrit.server.account.ListGroupMembership;
@@ -202,6 +203,7 @@
   @Inject private InMemoryDatabase schemaFactory;
   @Inject private ThreadLocalRequestContext requestContext;
   @Inject private DefaultRefFilter.Factory refFilterFactory;
+  @Inject private IdentifiedUser.GenericFactory identifiedUserFactory;
 
   @Before
   public void setUp() throws Exception {
@@ -986,6 +988,7 @@
         changeControlFactory,
         permissionBackend,
         refFilterFactory,
+        identifiedUserFactory,
         new MockUser(name, memberOf),
         newProjectState(local));
   }