Merge branch 'stable-3.0' into stable-3.1

* stable-3.0: (38 commits)
  docker: make sure to cleanup containers before force exit
  fixup! Add TaskTree definitions more directly
  fixup! refactor predicate cache into its own class
  fixup! Add support for tasks-factory and names-factory keywords
  fixup! Support outputting elapsed evaluation time on tasks
  fixup! Revert "Revert "plugin:task Adds support for names-factory of type change""
  Add a Container.toString() to help when debugging.
  Harden inputs to basename
  Add Zuul postflight publish job
  Pass around Task parent instead of its fields
  Fix to alter change context for TaskChangeFactories
  Add tasks-factories static properties tests
  Add a names-factory STATIC Properties test
  Add ensures to the task tests setups
  Split the task preload properties test out
  Split the task preload optional test out
  Split the append preloaded subtasks test out
  Split the task override preload pass/fail tests out
  Split the task preload hints tests out
  Split the task preload preload test out
  ...

Change-Id: I900333ab21824d9f7509084351e8f21b6b659044
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/WORKSPACE b/WORKSPACE
index c047530..4bbfd4c 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/Properties.java b/src/main/java/com/googlesource/gerrit/plugins/task/Properties.java
index 555f8df..028762c 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;
@@ -76,7 +76,7 @@
     properties.put("_change_number", String.valueOf(c.getId().get()));
     properties.put("_change_id", c.getKey().get());
     properties.put("_change_project", c.getProject().get());
-    properties.put("_change_branch", c.getDest().get());
+    properties.put("_change_branch", c.getDest().branch());
     properties.put("_change_status", c.getStatus().toString());
     properties.put("_change_topic", c.getTopic());
 
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 8cd8022..5e987ca 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.primitives.Primitives;
 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.lang.reflect.Field;
 import java.util.ArrayList;
@@ -223,7 +223,7 @@
     return task;
   }
 
-  public TaskConfig(Branch.NameKey branch, String fileName, boolean isVisible, boolean isTrusted) {
+  public TaskConfig(BranchNameKey branch, String fileName, boolean isVisible, boolean isTrusted) {
     super(branch, fileName);
     this.isVisible = isVisible;
     this.isTrusted = isTrusted;
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 d5003b4..f790ccc 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,11 +66,11 @@
     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(Branch.NameKey branch, String fileName, boolean isTrusted)
+  public TaskConfig getTaskConfig(BranchNameKey branch, String fileName, boolean isTrusted)
       throws ConfigInvalidException, IOException {
     PatchSetArgument psa = psaMasquerades.get(branch);
     boolean visible = true; // invisible psas are filtered out by commandline
@@ -78,10 +78,10 @@
       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 = branch.getParentKey();
+    Project.NameKey project = branch.project();
     TaskConfig cfg = new TaskConfig(branch, fileName, visible, isTrusted);
     try (Repository git = gitMgr.openRepository(project)) {
       cfg.load(project, git);
@@ -94,11 +94,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/TaskTree.java b/src/main/java/com/googlesource/gerrit/plugins/task/TaskTree.java
index 311c07e..9c4b476 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;
@@ -272,7 +272,7 @@
       return getTaskDefinitions(resolveUserBranch(external.user), external.file);
     }
 
-    protected List<Task> getTaskDefinitions(Branch.NameKey branch, String file)
+    protected List<Task> getTaskDefinitions(BranchNameKey branch, String file)
         throws ConfigInvalidException, IOException {
       return taskFactory
           .getTaskConfig(branch, resolveTaskFileName(file), task.isTrusted)
@@ -295,18 +295,18 @@
       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/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