Merge branch 'stable-3.0' into stable-3.1

* stable-3.0: (49 commits)
  Add change number to task output
  Only copy required folders for testing
  Add missing copyright/license header
  Use a bash associative array to speedup task tests
  plugins/task: Move TaskExpression iteration to Preloader
  Add bazel rule for junit tests
  Introduce TaskKey, SubSectionKey and FileKey
  plugins/task: Fix cache name in Preloader
  Only reload nodes when needed
  Skip re-expanding properties for local properties
  Use a lazy loading task property expansion model
  Refresh TaskTree.Nodes when getting them
  Cache preloaded tasks
  Rename a bunch of TaskTree addNode() methods
  Add preload-task to external file tests
  Add Root Preload tasks-factory test
  Create a TaskExpression with unit tests
  Do not modify definition during preload
  Return Optional<Task> in Task.Config
  Make task config collection fields immutable
  ...

Change-Id: Iae62d42a6448c132521df7d384ae06945bafef0a
diff --git a/.bazelversion b/.bazelversion
index 7c69a55..fcdb2e1 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-3.7.0
+4.0.0
diff --git a/BUILD b/BUILD
index 39b3d0d..e721ac7 100644
--- a/BUILD
+++ b/BUILD
@@ -69,7 +69,7 @@
     name = "junit-tests",
     size = "small",
     srcs = glob(["src/test/java/**/*Test.java"]),
-    deps = PLUGIN_TEST_DEPS + [plugin_name],
+    deps = PLUGIN_TEST_DEPS + PLUGIN_DEPS + [plugin_name],
 )
 
 sh_test(
diff --git a/WORKSPACE b/WORKSPACE
index 0c9c56f..f6120db 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "a88174652e6f853ead5bbc5dacc1030dbb2d50c3",
+    commit = "321fab31e6fbb63c940aad3252f0167f88d52e2e",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/gr-task-plugin/gr-task-plugin.html b/gr-task-plugin/gr-task-plugin.html
index 4a5e5c5..ea59b9f 100644
--- a/gr-task-plugin/gr-task-plugin.html
+++ b/gr-task-plugin/gr-task-plugin.html
@@ -17,7 +17,10 @@
 <dom-module id="gr-task-plugin">
   <template>
       <style>
-        ul { padding-left: 0.5em; }
+        ul {
+          padding-left: 0.5em;
+          margin-top: 0;
+        }
         h3 { padding-left: 0.1em; }
         .cursor { cursor: pointer; }
         #tasks_header {
@@ -32,6 +35,7 @@
           cursor: pointer;
           text-decoration: underline;
         }
+        .no-margins { margin: 0 0 0 0; }
       </style>
 
       <div id="tasks" hidden$="[[!_tasks.length]]">
@@ -47,16 +51,16 @@
               on-tap="_switch_expand"
               class="cursor"> </iron-icon>
           <div style="display: flex; align-items: center; column-gap: 1em;">
-          <h3 on-tap="_switch_expand" class="cursor"> Tasks </h3>
+          <h3 class="no-margins" on-tap="_switch_expand" class="cursor"> Tasks </h3>
           <template is="dom-if" if="[[_is_show_all(_show_all)]]">
-            <p>All ([[_all_count]]) |&nbsp;
+            <p class="no-margins">All ([[_all_count]]) |&nbsp;
               <span
                   on-click="_needs_and_blocked_tap"
                   class="links">Needs ([[_ready_count]]) + Blocked ([[_fail_count]])</span>
             <p>
           </template>
           <template is="dom-if" if="[[!_is_show_all(_show_all)]]">
-            <p> <span
+            <p class="no-margins"> <span
                   class="links"
                   on-click="_show_all_tap">All ([[_all_count]])</span>
               &nbsp;| Needs ([[_ready_count]]) + Blocked ([[_fail_count]])</p>
diff --git a/src/main/java/com/google/gerrit/server/git/meta/AbstractVersionedMetaData.java b/src/main/java/com/google/gerrit/server/git/meta/AbstractVersionedMetaData.java
index e5c1809..7997a05 100644
--- a/src/main/java/com/google/gerrit/server/git/meta/AbstractVersionedMetaData.java
+++ b/src/main/java/com/google/gerrit/server/git/meta/AbstractVersionedMetaData.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.server.git.meta;
 
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.entities.BranchNameKey;
 import java.io.IOException;
 import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.CommitBuilder;
@@ -22,18 +22,18 @@
 
 /** Versioned Configuration file living in git */
 public class AbstractVersionedMetaData extends VersionedMetaData {
-  protected final Branch.NameKey branch;
+  protected final BranchNameKey branch;
   protected final String fileName;
   protected Config cfg;
 
-  public AbstractVersionedMetaData(Branch.NameKey branch, String fileName) {
+  public AbstractVersionedMetaData(BranchNameKey branch, String fileName) {
     this.branch = branch;
     this.fileName = fileName;
   }
 
   @Override
   protected String getRefName() {
-    return branch.get();
+    return branch.branch();
   }
 
   protected String getFileName() {
@@ -52,7 +52,7 @@
     return cfg;
   }
 
-  public Branch.NameKey getBranch() {
+  public BranchNameKey getBranch() {
     return branch;
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/FileKey.java b/src/main/java/com/googlesource/gerrit/plugins/task/FileKey.java
index c320aa7..2d44757 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/FileKey.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/FileKey.java
@@ -15,16 +15,16 @@
 package com.googlesource.gerrit.plugins.task;
 
 import com.google.auto.value.AutoValue;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.entities.BranchNameKey;
 
 /** An immutable reference to a fully qualified file in gerrit repo. */
 @AutoValue
 public abstract class FileKey {
-  public static FileKey create(Branch.NameKey branch, String file) {
+  public static FileKey create(BranchNameKey branch, String file) {
     return new AutoValue_FileKey(branch, file);
   }
 
-  public abstract Branch.NameKey branch();
+  public abstract BranchNameKey branch();
 
   public abstract String file();
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/Properties.java b/src/main/java/com/googlesource/gerrit/plugins/task/Properties.java
index 5f9a8d5..b7284a1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/Properties.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/Properties.java
@@ -15,8 +15,8 @@
 package com.googlesource.gerrit.plugins.task;
 
 import com.google.common.collect.Sets;
+import com.google.gerrit.entities.Change;
 import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.googlesource.gerrit.plugins.task.TaskConfig.NamesFactory;
 import com.googlesource.gerrit.plugins.task.TaskConfig.Task;
@@ -157,7 +157,7 @@
         case "project":
           return change().getProject().get();
         case "branch":
-          return change().getDest().get();
+          return change().getDest().branch();
         case "status":
           return change().getStatus().toString();
         case "topic":
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
index 698b33a..81bc735 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfig.java
@@ -16,7 +16,7 @@
 
 import com.google.common.collect.Sets;
 import com.google.gerrit.common.Container;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.entities.BranchNameKey;
 import com.google.gerrit.server.git.meta.AbstractVersionedMetaData;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -221,7 +221,7 @@
   }
 
   public TaskConfig(
-      Branch.NameKey masqueraded, FileKey file, boolean isVisible, boolean isTrusted) {
+      BranchNameKey masqueraded, FileKey file, boolean isVisible, boolean isTrusted) {
     super(masqueraded, file.file());
     this.file = file;
     this.isVisible = isVisible;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfigFactory.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfigFactory.java
index bbf424b..f8b1dda 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfigFactory.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskConfigFactory.java
@@ -15,9 +15,9 @@
 package com.googlesource.gerrit.plugins.task;
 
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.reviewdb.client.Branch;
-import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.config.AllProjectsName;
 import com.google.gerrit.server.git.GitRepositoryManager;
@@ -44,7 +44,7 @@
   protected final CurrentUser user;
   protected final AllProjectsName allProjects;
 
-  protected final Map<Branch.NameKey, PatchSetArgument> psaMasquerades = new HashMap<>();
+  protected final Map<BranchNameKey, PatchSetArgument> psaMasquerades = new HashMap<>();
 
   @Inject
   protected TaskConfigFactory(
@@ -66,23 +66,23 @@
     psaMasquerades.put(psa.change.getDest(), psa);
   }
 
-  protected Branch.NameKey getRootBranch() {
-    return new Branch.NameKey(allProjects, "refs/meta/config");
+  protected BranchNameKey getRootBranch() {
+    return BranchNameKey.create(allProjects, "refs/meta/config");
   }
 
   public TaskConfig getTaskConfig(FileKey file, boolean isTrusted)
       throws ConfigInvalidException, IOException {
-    Branch.NameKey branch = file.branch();
+    BranchNameKey branch = file.branch();
     PatchSetArgument psa = psaMasquerades.get(branch);
     boolean visible = true; // invisible psas are filtered out by commandline
     if (psa == null) {
       visible = canRead(branch);
     } else {
       isTrusted = false;
-      branch = new Branch.NameKey(psa.change.getProject(), psa.patchSet.getId().toRefName());
+      branch = BranchNameKey.create(psa.change.getProject(), psa.patchSet.refName());
     }
 
-    Project.NameKey project = file.branch().getParentKey();
+    Project.NameKey project = file.branch().project();
     TaskConfig cfg =
         psa == null
             ? new TaskConfig(file, visible, isTrusted)
@@ -98,11 +98,11 @@
     return cfg;
   }
 
-  public boolean canRead(Branch.NameKey branch) {
+  public boolean canRead(BranchNameKey branch) {
     try {
       PermissionBackend.ForProject permissions =
-          permissionBackend.user(user).project(branch.getParentKey());
-      permissions.ref(branch.get()).check(RefPermission.READ);
+          permissionBackend.user(user).project(branch.project());
+      permissions.ref(branch.branch()).check(RefPermission.READ);
       return true;
     } catch (AuthException | PermissionBackendException e) {
       return false;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
index 0af75c8..7f1426a 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskKey.java
@@ -15,7 +15,7 @@
 package com.googlesource.gerrit.plugins.task;
 
 import com.google.auto.value.AutoValue;
-import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.entities.BranchNameKey;
 
 /** An immutable reference to a task in task config file. */
 @AutoValue
@@ -30,7 +30,7 @@
     return new AutoValue_TaskKey(section, task);
   }
 
-  public Branch.NameKey branch() {
+  public BranchNameKey branch() {
     return subSection().file().branch();
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
index 2bd8cf6..8e4fd37 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
@@ -15,12 +15,12 @@
 package com.googlesource.gerrit.plugins.task;
 
 import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.index.query.QueryParseException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Branch;
-import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.AnonymousUser;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.account.AccountResolver;
@@ -364,17 +364,17 @@
     return p.toString();
   }
 
-  protected Branch.NameKey resolveUserBranch(String user)
+  protected BranchNameKey resolveUserBranch(String user)
       throws ConfigInvalidException, IOException, StorageException {
     if (user == null) {
       throw new ConfigInvalidException("External user not defined");
     }
     Account.Id acct;
     try {
-      acct = accountResolver.resolve(user).asUnique().getAccount().getId();
+      acct = accountResolver.resolve(user).asUnique().account().id();
     } catch (UnprocessableEntityException e) {
       throw new ConfigInvalidException("Cannot resolve user: " + user);
     }
-    return new Branch.NameKey(allUsers.get(), RefNames.refsUsers(acct));
+    return BranchNameKey.create(allUsers.get(), RefNames.refsUsers(acct));
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/task/cli/PatchSetArgument.java b/src/main/java/com/googlesource/gerrit/plugins/task/cli/PatchSetArgument.java
index 9fbddeb..e0e2317 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/task/cli/PatchSetArgument.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/task/cli/PatchSetArgument.java
@@ -13,10 +13,10 @@
 // limitations under the License.
 package com.googlesource.gerrit.plugins.task.cli;
 
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.PatchSet;
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.notedb.ChangeNotes;
@@ -48,7 +48,7 @@
     public PatchSetArgument createForArgument(String token) {
       try {
         PatchSet.Id patchSetId = parsePatchSet(token);
-        ChangeNotes changeNotes = notesFactory.createChecked(patchSetId.getParentKey());
+        ChangeNotes changeNotes = notesFactory.createChecked(patchSetId.changeId());
         permissionBackend.user(user).change(changeNotes).check(ChangePermission.READ);
         return new PatchSetArgument(changeNotes.getChange(), psUtil.get(changeNotes, patchSetId));
       } catch (PermissionBackendException | AuthException e) {
@@ -90,7 +90,7 @@
   }
 
   public void ensureLatest() {
-    if (!change.currentPatchSetId().equals(patchSet.getId())) {
+    if (!change.currentPatchSetId().equals(patchSet.id())) {
       throw new IllegalArgumentException(patchSet + " is not the latest patch set");
     }
   }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java b/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
index ac4ee88..1bece85 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/task/TaskExpressionTest.java
@@ -14,8 +14,8 @@
 
 package com.googlesource.gerrit.plugins.task;
 
-import com.google.gerrit.reviewdb.client.Branch;
-import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.entities.BranchNameKey;
+import com.google.gerrit.entities.Project;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 import junit.framework.TestCase;
@@ -181,6 +181,6 @@
   }
 
   protected static FileKey createFileKey(String project, String branch, String file) {
-    return FileKey.create(new Branch.NameKey(new Project.NameKey(project), branch), file);
+    return FileKey.create(BranchNameKey.create(Project.NameKey.parse(project), branch), file);
   }
 }
diff --git a/test/docker/gerrit/Dockerfile b/test/docker/gerrit/Dockerfile
index b9d1715..94c40ff 100755
--- a/test/docker/gerrit/Dockerfile
+++ b/test/docker/gerrit/Dockerfile
@@ -1,4 +1,4 @@
-FROM gerritcodereview/gerrit:3.0.16-ubuntu18
+FROM gerritcodereview/gerrit:3.1.15-ubuntu18
 
 USER root