Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  fixup!: docker: Enable reruning tests without bringing down setup
  docker: Enable reruning tests without bringing down setup
  docker: Add support for "--preserve" option

Change-Id: I214bb7d870a88953652fc344d9a3d27367c4526e
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