Merge "Clean up remaining command reference files" into stable-2.16
diff --git a/.gitignore b/.gitignore
index e544356..319b3cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@
 /test_site
 /tools/format
 /.vscode
+/.ijwb
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index bc9f782..8710a2b 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -166,7 +166,7 @@
 link:https://github.com/google/google-java-format[`google-java-format`]
 tool (version 1.6), and to format Bazel BUILD, WORKSPACE and .bzl files the
 link:https://github.com/bazelbuild/buildtools/tree/master/buildifier[`buildifier`]
-tool (version 0.15.0).
+tool (version 0.17.2).
 These tools automatically apply format according to the style guides; this
 streamlines code review by reducing the need for time-consuming, tedious,
 and contentious discussions about trivial issues like whitespace.
diff --git a/Documentation/user-review-ui.txt b/Documentation/user-review-ui.txt
index 75f2b3f..de17c00 100644
--- a/Documentation/user-review-ui.txt
+++ b/Documentation/user-review-ui.txt
@@ -329,7 +329,10 @@
 
 - `U` (Unchanged):
 +
-The file is unchanged and has the same content.
+The file is unchanged and has the same content. Unchanged files only
+appear in the file list if 2 patch sets are compared and the file has
+comments on at least one of the sides. Otherwise unchanged files are
+filtered out.
 
 image::images/user-review-ui-change-screen-file-list-modification-type.png[width=800, link="images/user-review-ui-change-screen-file-list-modification-type.png"]
 
diff --git a/WORKSPACE b/WORKSPACE
index 62331cd..b2b3b6f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -30,9 +30,9 @@
     urls = ["https://raw.githubusercontent.com/google/closure-compiler/35d2b3340ff23a69441f10fa3bc820691c2942f2/contrib/externs/polymer-1.0.js"],
 )
 
-load("@bazel_skylib//:lib.bzl", "versions")
+load("@bazel_skylib//lib:versions.bzl", "versions")
 
-versions.check(minimum_bazel_version = "0.17.1")
+versions.check(minimum_bazel_version = "0.19.0")
 
 load("@io_bazel_rules_closure//closure:defs.bzl", "closure_repositories")
 
@@ -759,7 +759,7 @@
     sha1 = "bb562ee73f740bb6b2bf7955f97be6b870d9e9f0",
 )
 
-# When updading Bouncy Castle, also update it in bazlets.
+# When updating Bouncy Castle, also update it in bazlets.
 BC_VERS = "1.60"
 
 maven_jar(
@@ -833,10 +833,18 @@
     sha1 = "f5aa318bda4c6c8d688c9d00b90681dcd82ce636",
 )
 
+# elasticsearch-rest-client explicitly depends on this version
 maven_jar(
-    name = "httpmime",
-    artifact = "org.apache.httpcomponents:httpmime:" + HTTPCOMP_VERS,
-    sha1 = "2f8757f5ac5e38f46c794e5229d1f3c522e9b1df",
+    name = "httpasyncclient",
+    artifact = "org.apache.httpcomponents:httpasyncclient:4.1.2",
+    sha1 = "95aa3e6fb520191a0970a73cf09f62948ee614be",
+)
+
+# elasticsearch-rest-client explicitly depends on this version
+maven_jar(
+    name = "httpcore-nio",
+    artifact = "org.apache.httpcomponents:httpcore-nio:4.4.5",
+    sha1 = "f4be009e7505f6ceddf21e7960c759f413f15056",
 )
 
 # Test-only dependencies below.
@@ -956,9 +964,9 @@
 
 maven_jar(
     name = "derby",
-    artifact = "org.apache.derby:derby:10.11.1.1",
+    artifact = "org.apache.derby:derby:10.12.1.1",
     attach_source = False,
-    sha1 = "df4b50061e8e4c348ce243b921f53ee63ba9bbe1",
+    sha1 = "75070c744a8e52a7d17b8b476468580309d5cd09",
 )
 
 JETTY_VERS = "9.4.12.v20180830"
@@ -1038,8 +1046,8 @@
 
 maven_jar(
     name = "postgresql",
-    artifact = "org.postgresql:postgresql:42.2.4",
-    sha1 = "dff98730c28a4b3a3263f0cf4abb9a3392f815a7",
+    artifact = "org.postgresql:postgresql:42.2.5",
+    sha1 = "951b7eda125f3137538a94e2cbdcf744088ad4c2",
 )
 
 maven_jar(
@@ -1079,10 +1087,12 @@
     sha1 = "76716d529710fc03d1d429b43e3cedd4419f78d4",
 )
 
+# When upgrading elasticsearch-rest-client, also upgrade http-niocore
+# and httpasyncclient as necessary.
 maven_jar(
     name = "elasticsearch-rest-client",
-    artifact = "org.elasticsearch.client:elasticsearch-rest-client:6.4.2",
-    sha1 = "a2baf2d4fdf03f31fbd39351a32bee25fcdfa1cf",
+    artifact = "org.elasticsearch.client:elasticsearch-rest-client:6.4.3",
+    sha1 = "5c24325430971ba2fa4769eb446f026b7680d5e7",
 )
 
 JACKSON_VERSION = "2.9.7"
@@ -1094,18 +1104,6 @@
 )
 
 maven_jar(
-    name = "httpasyncclient",
-    artifact = "org.apache.httpcomponents:httpasyncclient:4.1.2",
-    sha1 = "95aa3e6fb520191a0970a73cf09f62948ee614be",
-)
-
-maven_jar(
-    name = "httpcore-nio",
-    artifact = "org.apache.httpcomponents:httpcore-nio:" + HTTPCOMP_VERS,
-    sha1 = "a8c5e3c3bfea5ce23fb647c335897e415eb442e3",
-)
-
-maven_jar(
     name = "testcontainers",
     artifact = "org.testcontainers:testcontainers:1.8.0",
     sha1 = "bc413912f7044f9f12aa0782853aef0a067ee52a",
diff --git a/java/com/google/gerrit/extensions/common/GroupBaseInfo.java b/java/com/google/gerrit/extensions/common/GroupBaseInfo.java
index 288adb6..4d35b36 100644
--- a/java/com/google/gerrit/extensions/common/GroupBaseInfo.java
+++ b/java/com/google/gerrit/extensions/common/GroupBaseInfo.java
@@ -14,7 +14,14 @@
 
 package com.google.gerrit.extensions.common;
 
+import com.google.common.base.MoreObjects;
+
 public class GroupBaseInfo {
   public String id;
   public String name;
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(this).add("name", name).add("id", id).toString();
+  }
 }
diff --git a/java/com/google/gerrit/httpd/UrlModule.java b/java/com/google/gerrit/httpd/UrlModule.java
index f337718..1dd176a 100644
--- a/java/com/google/gerrit/httpd/UrlModule.java
+++ b/java/com/google/gerrit/httpd/UrlModule.java
@@ -110,7 +110,9 @@
     serveRegex("^/(?:a/)?groups/(.*)?$").with(GroupsRestApiServlet.class);
     serveRegex("^/(?:a/)?projects/(.*)?$").with(ProjectsRestApiServlet.class);
 
-    filter("/Documentation/").through(QueryDocumentationFilter.class);
+    serveRegex("^/Documentation$").with(redirectDocumentation());
+    serveRegex("^/Documentation/$").with(redirectDocumentation());
+    filter("/Documentation/*").through(QueryDocumentationFilter.class);
   }
 
   private Key<HttpServlet> notFound() {
@@ -259,6 +261,19 @@
         });
   }
 
+  private Key<HttpServlet> redirectDocumentation() {
+    return key(
+        new HttpServlet() {
+          private static final long serialVersionUID = 1L;
+
+          @Override
+          protected void doGet(HttpServletRequest req, HttpServletResponse rsp) throws IOException {
+            String path = "/Documentation/index.html";
+            toGerrit(path, req, rsp);
+          }
+        });
+  }
+
   static void toGerrit(String target, HttpServletRequest req, HttpServletResponse rsp)
       throws IOException {
     final StringBuilder url = new StringBuilder();
diff --git a/java/com/google/gerrit/httpd/raw/StaticModule.java b/java/com/google/gerrit/httpd/raw/StaticModule.java
index 664d881..124ad1c 100644
--- a/java/com/google/gerrit/httpd/raw/StaticModule.java
+++ b/java/com/google/gerrit/httpd/raw/StaticModule.java
@@ -119,6 +119,8 @@
 
   @Override
   protected void configureServlets() {
+    serveRegex("^/Documentation$").with(named(DOC_SERVLET));
+    serveRegex("^/Documentation/$").with(named(DOC_SERVLET));
     serveRegex("^/Documentation/(.+)$").with(named(DOC_SERVLET));
     serve("/static/*").with(SiteStaticDirectoryServlet.class);
     install(
diff --git a/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java b/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
index 6229041..cefc13c 100644
--- a/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
+++ b/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
@@ -38,7 +38,9 @@
 
   public static final ProjectSchemaDefinitions INSTANCE = new ProjectSchemaDefinitions();
 
+  public static final String NAME = "projects";
+
   private ProjectSchemaDefinitions() {
-    super("projects", ProjectData.class);
+    super(NAME, ProjectData.class);
   }
 }
diff --git a/java/com/google/gerrit/pgm/BUILD b/java/com/google/gerrit/pgm/BUILD
index b34aec0..0bebad4 100644
--- a/java/com/google/gerrit/pgm/BUILD
+++ b/java/com/google/gerrit/pgm/BUILD
@@ -24,6 +24,7 @@
         "//java/com/google/gerrit/httpd/auth/oauth",
         "//java/com/google/gerrit/httpd/auth/openid",
         "//java/com/google/gerrit/index",
+        "//java/com/google/gerrit/index/project",
         "//java/com/google/gerrit/launcher",
         "//java/com/google/gerrit/lifecycle",
         "//java/com/google/gerrit/lucene",
diff --git a/java/com/google/gerrit/pgm/Init.java b/java/com/google/gerrit/pgm/Init.java
index a93e64c..1739de9 100644
--- a/java/com/google/gerrit/pgm/Init.java
+++ b/java/com/google/gerrit/pgm/Init.java
@@ -14,11 +14,15 @@
 
 package com.google.gerrit.pgm;
 
+import static java.util.stream.Collectors.joining;
+
 import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Sets;
 import com.google.gerrit.common.IoUtil;
 import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.common.PluginData;
+import com.google.gerrit.index.project.ProjectSchemaDefinitions;
 import com.google.gerrit.pgm.init.BaseInit;
 import com.google.gerrit.pgm.init.Browser;
 import com.google.gerrit.pgm.init.InitPlugins;
@@ -55,6 +59,9 @@
   @Option(name = "--no-auto-start", usage = "Don't automatically start daemon after init")
   private boolean noAutoStart;
 
+  @Option(name = "--no-reindex", usage = "Don't automatically reindex any entities")
+  private boolean noReindex;
+
   @Option(name = "--skip-plugins", usage = "Don't install plugins")
   private boolean skipPlugins;
 
@@ -137,6 +144,7 @@
         });
     modules.add(new GerritServerConfigModule());
     Guice.createInjector(modules).injectMembers(this);
+    reindexProjects();
     start(run);
   }
 
@@ -194,7 +202,6 @@
     if (run.flags.autoStart) {
       if (HostPlatform.isWin32()) {
         System.err.println("Automatic startup not supported on Win32.");
-
       } else {
         startDaemon(run);
         if (!run.ui.isBatch()) {
@@ -249,6 +256,25 @@
     }
   }
 
+  private void reindexProjects() throws Exception {
+    if (noReindex) {
+      return;
+    }
+    // Reindex all projects, so that we bootstrap the project index for new installations
+    List<String> reindexArgs =
+        ImmutableList.of(
+            "--site-path",
+            getSitePath().toString(),
+            "--threads",
+            Integer.toString(1),
+            "--index",
+            ProjectSchemaDefinitions.NAME);
+    getConsoleUI().message("Init complete, reindexing projects with:");
+    getConsoleUI().message(" reindex " + reindexArgs.stream().collect(joining(" ")));
+    Reindex reindexPgm = new Reindex();
+    reindexPgm.main(reindexArgs.stream().toArray(String[]::new));
+  }
+
   private static boolean nullOrEmpty(List<?> list) {
     return list == null || list.isEmpty();
   }
diff --git a/java/com/google/gerrit/server/query/change/OutputStreamQuery.java b/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
index 1287970..17c23b6 100644
--- a/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
+++ b/java/com/google/gerrit/server/query/change/OutputStreamQuery.java
@@ -24,6 +24,7 @@
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.server.ReviewDb;
+import com.google.gerrit.server.DynamicOptions;
 import com.google.gerrit.server.config.TrackingFooters;
 import com.google.gerrit.server.data.ChangeAttribute;
 import com.google.gerrit.server.data.PatchSetAttribute;
@@ -180,6 +181,10 @@
     this.outputFormat = fmt;
   }
 
+  public void setDynamicBean(String plugin, DynamicOptions.DynamicBean dynamicBean) {
+    queryProcessor.setDynamicBean(plugin, dynamicBean);
+  }
+
   public void query(String queryString) throws IOException {
     out =
         new PrintWriter( //
diff --git a/java/com/google/gerrit/server/restapi/change/QueryChanges.java b/java/com/google/gerrit/server/restapi/change/QueryChanges.java
index 2284b00..d1eea44 100644
--- a/java/com/google/gerrit/server/restapi/change/QueryChanges.java
+++ b/java/com/google/gerrit/server/restapi/change/QueryChanges.java
@@ -25,6 +25,7 @@
 import com.google.gerrit.index.query.QueryParseException;
 import com.google.gerrit.index.query.QueryRequiresAuthException;
 import com.google.gerrit.index.query.QueryResult;
+import com.google.gerrit.server.DynamicOptions;
 import com.google.gerrit.server.change.ChangeJson;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -38,7 +39,7 @@
 import java.util.List;
 import org.kohsuke.args4j.Option;
 
-public class QueryChanges implements RestReadView<TopLevelResource> {
+public class QueryChanges implements RestReadView<TopLevelResource>, DynamicOptions.BeanReceiver {
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   private final ChangeJson.Factory json;
@@ -81,6 +82,11 @@
     imp.setStart(start);
   }
 
+  @Override
+  public void setDynamicBean(String plugin, DynamicOptions.DynamicBean dynamicBean) {
+    imp.setDynamicBean(plugin, dynamicBean);
+  }
+
   @Inject
   QueryChanges(ChangeJson.Factory json, ChangeQueryBuilder qb, ChangeQueryProcessor qp) {
     this.json = json;
diff --git a/java/com/google/gerrit/sshd/commands/Query.java b/java/com/google/gerrit/sshd/commands/Query.java
index 3fe0396..4d8351e 100644
--- a/java/com/google/gerrit/sshd/commands/Query.java
+++ b/java/com/google/gerrit/sshd/commands/Query.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.sshd.commands;
 
+import com.google.gerrit.server.DynamicOptions;
 import com.google.gerrit.server.query.change.OutputStreamQuery;
 import com.google.gerrit.server.query.change.OutputStreamQuery.OutputFormat;
 import com.google.gerrit.sshd.CommandMetaData;
@@ -24,7 +25,7 @@
 import org.kohsuke.args4j.Option;
 
 @CommandMetaData(name = "query", description = "Query the change database")
-public class Query extends SshCommand {
+public class Query extends SshCommand implements DynamicOptions.BeanReceiver {
   @Inject private OutputStreamQuery processor;
 
   @Option(name = "--format", metaVar = "FMT", usage = "Output display format")
@@ -104,6 +105,11 @@
   }
 
   @Override
+  public void setDynamicBean(String plugin, DynamicOptions.DynamicBean dynamicBean) {
+    processor.setDynamicBean(plugin, dynamicBean);
+  }
+
+  @Override
   protected void parseCommandLine() throws UnloggedFailure {
     processor.setOutput(out, OutputFormat.TEXT);
     super.parseCommandLine();
diff --git a/javatests/com/google/gerrit/acceptance/pgm/BUILD b/javatests/com/google/gerrit/acceptance/pgm/BUILD
index a91b815..e0d2f86 100644
--- a/javatests/com/google/gerrit/acceptance/pgm/BUILD
+++ b/javatests/com/google/gerrit/acceptance/pgm/BUILD
@@ -13,6 +13,8 @@
     vm_args = ["-Xmx512m"],
     deps = [
         ":util",
+        "//java/com/google/gerrit/index",
+        "//java/com/google/gerrit/index/project",
         "//java/com/google/gerrit/server/schema",
     ],
 )
diff --git a/javatests/com/google/gerrit/acceptance/pgm/InitIT.java b/javatests/com/google/gerrit/acceptance/pgm/InitIT.java
new file mode 100644
index 0000000..a573e35
--- /dev/null
+++ b/javatests/com/google/gerrit/acceptance/pgm/InitIT.java
@@ -0,0 +1,51 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.acceptance.pgm;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.gerrit.acceptance.NoHttpd;
+import com.google.gerrit.acceptance.StandaloneSiteTest;
+import com.google.gerrit.index.IndexConfig;
+import com.google.gerrit.index.QueryOptions;
+import com.google.gerrit.index.project.ProjectData;
+import com.google.gerrit.index.project.ProjectIndexCollection;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.config.AllUsersName;
+import java.util.Optional;
+import org.junit.Test;
+
+@NoHttpd
+public class InitIT extends StandaloneSiteTest {
+
+  @Test
+  public void indexesAllProjectsAndAllUsers() throws Exception {
+    runGerrit("init", "-d", sitePaths.site_path.toString(), "--show-stack-trace");
+    try (ServerContext ctx = startServer()) {
+      ProjectIndexCollection projectIndex =
+          ctx.getInjector().getInstance(ProjectIndexCollection.class);
+      Project.NameKey allProjects = ctx.getInjector().getInstance(AllProjectsName.class);
+      Project.NameKey allUsers = ctx.getInjector().getInstance(AllUsersName.class);
+      QueryOptions opts =
+          QueryOptions.create(IndexConfig.createDefault(), 0, 1, ImmutableSet.of("name"));
+      Optional<ProjectData> allProjectsData = projectIndex.getSearchIndex().get(allProjects, opts);
+      assertThat(allProjectsData.isPresent()).isTrue();
+      Optional<ProjectData> allUsersData = projectIndex.getSearchIndex().get(allUsers, opts);
+      assertThat(allUsersData.isPresent()).isTrue();
+    }
+  }
+}
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
index bb545c9..93e97c4 100644
--- a/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
+++ b/javatests/com/google/gerrit/elasticsearch/ElasticContainer.java
@@ -45,13 +45,13 @@
       case V2_4:
         return "elasticsearch:2.4.6-alpine";
       case V5_6:
-        return "docker.elastic.co/elasticsearch/elasticsearch:5.6.12";
+        return "docker.elastic.co/elasticsearch/elasticsearch:5.6.13";
       case V6_2:
         return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.4";
       case V6_3:
         return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.3.2";
       case V6_4:
-        return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.2";
+        return "docker.elastic.co/elasticsearch/elasticsearch-oss:6.4.3";
     }
     throw new IllegalStateException("No tests for version: " + version.name());
   }
diff --git a/lib/httpcomponents/BUILD b/lib/httpcomponents/BUILD
index 8e9fbc5..a875eaf 100644
--- a/lib/httpcomponents/BUILD
+++ b/lib/httpcomponents/BUILD
@@ -28,20 +28,15 @@
 )
 
 java_library(
-    name = "httpmime",
-    data = ["//lib:LICENSE-Apache2.0"],
-    visibility = ["//visibility:public"],
-    exports = ["@httpmime//jar"],
-)
-
-java_library(
     name = "httpasyncclient",
     data = ["//lib:LICENSE-Apache2.0"],
+    visibility = ["//java/com/google/gerrit/elasticsearch:__pkg__"],
     exports = ["@httpasyncclient//jar"],
 )
 
 java_library(
     name = "httpcore-nio",
     data = ["//lib:LICENSE-Apache2.0"],
+    visibility = ["//java/com/google/gerrit/elasticsearch:__pkg__"],
     exports = ["@httpcore-nio//jar"],
 )
diff --git a/plugins/replication b/plugins/replication
index 092792e..bc5efb5 160000
--- a/plugins/replication
+++ b/plugins/replication
@@ -1 +1 @@
-Subproject commit 092792edacf9c29732a560a30967b92664cd65f9
+Subproject commit bc5efb5b60a5a93c25c075f3667841e02532a99c
diff --git a/plugins/singleusergroup b/plugins/singleusergroup
index cc636d7..0f798f6 160000
--- a/plugins/singleusergroup
+++ b/plugins/singleusergroup
@@ -1 +1 @@
-Subproject commit cc636d7e36afb62455a9f045b125d246fd84afd0
+Subproject commit 0f798f61c0c598c1499cbaacc1c609078c8bf0d5
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
index 4be674f..2cb00f4 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior.html
@@ -110,8 +110,9 @@
     /**
      *  @return {string}
      */
-    changeBaseURL(changeNum, patchNum) {
-      let v = this.getBaseUrl() + '/changes/' + changeNum;
+    changeBaseURL(project, changeNum, patchNum) {
+      let v = this.getBaseUrl() + '/changes/' +
+         encodeURIComponent(project) + '~' + changeNum;
       if (patchNum) {
         v += '/revisions/' + patchNum;
       }
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
index d3ce73c..49d90f0 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.html
@@ -68,8 +68,8 @@
 
     test('changeBaseURL', () => {
       assert.deepEqual(
-          element.changeBaseURL('1', '1'),
-          '/r/changes/1/revisions/1'
+          element.changeBaseURL('test/project', '1', '2'),
+          '/r/changes/test%2Fproject~1/revisions/2'
       );
     });
 
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
index d55d7e9..f43a3e2 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.html
@@ -71,6 +71,17 @@
           </span>
         </section>
         <section>
+          <span class="title">Owner</span>
+          <span class="value">
+            <gr-autocomplete
+                id="ownerInput"
+                text="{{_repoOwner}}"
+                value="{{_repoOwnerId}}"
+                query="[[_queryGroups]]">
+            </gr-autocomplete>
+          </span>
+        </section>
+        <section>
           <span class="title">Create initial empty commit</span>
           <span class="value">
             <gr-select
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
index 9dde290..bb2b5f2 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog.js
@@ -43,6 +43,11 @@
         type: Boolean,
         value: false,
       },
+      _repoOwner: String,
+      _repoOwnerId: {
+        type: String,
+        observer: '_repoOwnerIdUpdate',
+      },
 
       _query: {
         type: Function,
@@ -50,6 +55,12 @@
           return this._getRepoSuggestions.bind(this);
         },
       },
+      _queryGroups: {
+        type: Function,
+        value() {
+          return this._getGroupSuggestions.bind(this);
+        },
+      },
     },
 
     observers: [
@@ -70,6 +81,14 @@
       this.hasNewRepoName = !!name;
     },
 
+    _repoOwnerIdUpdate(id) {
+      if (id) {
+        this.set('_repoConfig.owners', [id]);
+      } else {
+        this.set('_repoConfig.owners', undefined);
+      }
+    },
+
     handleCreateRepo() {
       return this.$.restAPI.createRepo(this._repoConfig)
           .then(repoRegistered => {
@@ -94,5 +113,20 @@
             return repos;
           });
     },
+
+    _getGroupSuggestions(input) {
+      return this.$.restAPI.getSuggestedGroups(input)
+          .then(response => {
+            const groups = [];
+            for (const key in response) {
+              if (!response.hasOwnProperty(key)) { continue; }
+              groups.push({
+                name: key,
+                value: decodeURIComponent(response[key].id),
+              });
+            }
+            return groups;
+          });
+    },
   });
 })();
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
index e70c11a..6bc3522 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.html
@@ -60,6 +60,7 @@
         create_empty_commit: true,
         parent: 'All-Project',
         permissions_only: false,
+        owners: ['testId'],
       };
 
       const saveStub = sandbox.stub(element.$.restAPI,
@@ -76,8 +77,12 @@
         permissions_only: false,
       };
 
+      element._repoOwner = 'test';
+      element._repoOwnerId = 'testId';
+
       element.$.repoNameInput.bindValue = configInputObj.name;
       element.$.rightsInheritFromInput.bindValue = configInputObj.parent;
+      element.$.ownerInput.text = configInputObj.owners[0];
       element.$.initalCommit.bindValue =
           configInputObj.create_empty_commit;
       element.$.parentRepo.bindValue =
@@ -92,5 +97,10 @@
         done();
       });
     });
+
+    test('testing observer of _repoOwner', () => {
+      element._repoOwnerId = 'test-5';
+      assert.deepEqual(element._repoConfig.owners, ['test-5']);
+    });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
index 20449b0..5fc81e8 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog.js
@@ -115,8 +115,8 @@
      * @return {string} Not sure why there was a mismatch
      */
     _computeDownloadLink(change, patchNum, opt_zip) {
-      return this.changeBaseURL(change._number, patchNum) + '/patch?' +
-          (opt_zip ? 'zip' : 'download');
+      return this.changeBaseURL(change.project, change._number, patchNum) +
+          '/patch?' + (opt_zip ? 'zip' : 'download');
     },
 
 
@@ -139,7 +139,7 @@
     },
 
     _computeArchiveDownloadLink(change, patchNum, format) {
-      return this.changeBaseURL(change._number, patchNum) +
+      return this.changeBaseURL(change.project, change._number, patchNum) +
           '/archive?format=' + format;
     },
 
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
index 19932c5..2915e29 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
@@ -172,8 +172,8 @@
 
       test('computed fields', () => {
         assert.equal(element._computeArchiveDownloadLink(
-            {_number: 123}, 2, 'tgz'),
-            '/changes/123/revisions/2/archive?format=tgz');
+            {project: 'test/project', _number: 123}, 2, 'tgz'),
+            '/changes/test%2Fproject~123/revisions/2/archive?format=tgz');
       });
 
       test('close event', done => {
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
index ff5b290..f2cfe87 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js
@@ -290,14 +290,14 @@
     _resultsChanged(related, submittedTogether, conflicts,
         cherryPicks, sameTopic) {
       const results = [
-        related,
-        submittedTogether,
+        related && related.changes,
+        submittedTogether && submittedTogether.changes,
         conflicts,
         cherryPicks,
         sameTopic,
       ];
       for (let i = 0; i < results.length; i++) {
-        if (results[i].length > 0) {
+        if (results[i] && results[i].length > 0) {
           this.hidden = false;
           this.fire('update', null, {bubbles: false});
           return;
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
index bfeb694..48cc565 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
@@ -382,7 +382,7 @@
           true);
     });
 
-    test('clear and empties', () => {
+    suite('hidden attribute and update event', () => {
       const changes = [{
         project: 'foo/bar',
         change_id: 'Ideadbeef',
@@ -397,33 +397,68 @@
         _current_revision_number: 1,
         status: 'NEW',
       }];
-      element._relatedResponse = {changes};
-      element._submittedTogether = {changes};
-      element._conflicts = changes;
-      element._cherryPicks = changes;
-      element._sameTopic = changes;
 
-      element.hidden = false;
-      element.clear();
-      assert.isTrue(element.hidden);
-      assert.equal(element._relatedResponse.changes.length, 0);
-      assert.equal(element._submittedTogether.changes.length, 0);
-      assert.equal(element._conflicts.length, 0);
-      assert.equal(element._cherryPicks.length, 0);
-      assert.equal(element._sameTopic.length, 0);
-    });
+      test('clear and empties', () => {
+        element._relatedResponse = {changes};
+        element._submittedTogether = {changes};
+        element._conflicts = changes;
+        element._cherryPicks = changes;
+        element._sameTopic = changes;
 
-    test('update fires', () => {
-      const updateHandler = sandbox.stub();
-      element.addEventListener('update', updateHandler);
+        element.hidden = false;
+        element.clear();
+        assert.isTrue(element.hidden);
+        assert.equal(element._relatedResponse.changes.length, 0);
+        assert.equal(element._submittedTogether.changes.length, 0);
+        assert.equal(element._conflicts.length, 0);
+        assert.equal(element._cherryPicks.length, 0);
+        assert.equal(element._sameTopic.length, 0);
+      });
 
-      element._resultsChanged([], [], [], [], []);
-      assert.isTrue(element.hidden);
-      assert.isFalse(updateHandler.called);
+      test('update fires', () => {
+        const updateHandler = sandbox.stub();
+        element.addEventListener('update', updateHandler);
 
-      element._resultsChanged([], [], [], [], ['test']);
-      assert.isFalse(element.hidden);
-      assert.isTrue(updateHandler.called);
+        element._resultsChanged({}, {}, [], [], []);
+        assert.isTrue(element.hidden);
+        assert.isFalse(updateHandler.called);
+
+        element._resultsChanged({}, {}, [], [], ['test']);
+        assert.isFalse(element.hidden);
+        assert.isTrue(updateHandler.called);
+      });
+
+      suite('hiding and unhiding', () => {
+        test('related response', () => {
+          assert.isTrue(element.hidden);
+          element._resultsChanged({changes}, {}, [], [], []);
+          assert.isFalse(element.hidden);
+        });
+
+        test('submitted together', () => {
+          assert.isTrue(element.hidden);
+          element._resultsChanged({}, {changes}, [], [], []);
+          assert.isFalse(element.hidden);
+        });
+
+        test('conflicts', () => {
+          assert.isTrue(element.hidden);
+          element._resultsChanged({}, {}, changes, [], []);
+          assert.isFalse(element.hidden);
+        });
+
+        test('cherrypicks', () => {
+          assert.isTrue(element.hidden);
+          element._resultsChanged({}, {}, [], changes, []);
+          assert.isFalse(element.hidden);
+        });
+
+        test('same topic', () => {
+          assert.isTrue(element.hidden);
+          element._resultsChanged({}, {}, [], [], changes);
+          assert.isFalse(element.hidden);
+        });
+      });
     });
 
     test('_computeChangeURL uses Gerrit.Nav', () => {
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
index 53a7c07..781e25b 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.html
@@ -673,6 +673,22 @@
         assert.equal(redirectStub.lastCall.args[0], '/q/foo+bar');
       });
 
+      test('_handleQueryRoute', () => {
+        const data = {params: ['project:foo/bar/baz']};
+        assertDataToParams(data, '_handleQueryRoute', {
+          view: Gerrit.Nav.View.SEARCH,
+          query: 'project:foo/bar/baz',
+          offset: undefined,
+        });
+
+        data.params.push(',123', '123');
+        assertDataToParams(data, '_handleQueryRoute', {
+          view: Gerrit.Nav.View.SEARCH,
+          query: 'project:foo/bar/baz',
+          offset: '123',
+        });
+      });
+
       suite('_handleRegisterRoute', () => {
         test('happy path', () => {
           const ctx = {params: ['/foo/bar']};
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
index 04d53a4..0866849 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.html
@@ -269,7 +269,7 @@
             <a
               class="downloadLink"
               download
-              href$="[[_computeDownloadLink(_changeNum, _patchRange, _path)]]">
+              href$="[[_computeDownloadLink(_change.project, _changeNum, _patchRange, _path)]]">
               Download
             </a>
           </span>
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
index 0f717e7..6f361d8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.js
@@ -883,8 +883,8 @@
       history.replaceState(null, '', url);
     },
 
-    _computeDownloadLink(changeNum, patchRange, path) {
-      let url = this.changeBaseURL(changeNum, patchRange.patchNum);
+    _computeDownloadLink(project, changeNum, patchRange, path) {
+      let url = this.changeBaseURL(project, changeNum, patchRange.patchNum);
       url += '/patch?zip&path=' + encodeURIComponent(path);
       return url;
     },
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
index 2a0a0f3..431578b 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.html
@@ -556,6 +556,7 @@
     });
 
     test('download link', () => {
+      element._change = {project: 'test'},
       element._changeNum = '42';
       element._patchRange = {
         basePatchNum: PARENT,
@@ -566,7 +567,7 @@
       flushAsynchronousOperations();
       const link = element.$$('.downloadLink');
       assert.equal(link.getAttribute('href'),
-          '/changes/42/revisions/10/patch?zip&path=glados.txt');
+          '/changes/test~42/revisions/10/patch?zip&path=glados.txt');
       assert.isTrue(link.hasAttribute('download'));
     });
 
diff --git a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
index 782100e..b3e6990 100644
--- a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
+++ b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences.html
@@ -35,6 +35,7 @@
               prevent-invalid-input
               allowed-pattern="[0-9]"
               bind-value="{{editPrefs.tab_size}}"
+              on-keypress="_handleEditPrefsChanged"
               on-change="_handleEditPrefsChanged">
         </span>
       </section>
@@ -47,6 +48,7 @@
               prevent-invalid-input
               allowed-pattern="[0-9]"
               bind-value="{{editPrefs.line_length}}"
+              on-keypress="_handleEditPrefsChanged"
               on-change="_handleEditPrefsChanged">
         </span>
       </section>
@@ -59,6 +61,7 @@
               prevent-invalid-input
               allowed-pattern="[0-9]"
               bind-value="{{editPrefs.indent_unit}}"
+              on-keypress="_handleEditPrefsChanged"
               on-change="_handleEditPrefsChanged">
         </span>
       </section>
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
index dcb428f..3d9d36b 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.js
@@ -229,7 +229,7 @@
       if (typeof link.url === 'undefined') {
         return '';
       }
-      if (link.target) {
+      if (link.target || !link.url.startsWith('/')) {
         return link.url;
       }
       return this._computeRelativeURL(link.url);
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
index 456f235..7bb4dce 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -73,6 +73,12 @@
 
     test('link URLs', () => {
       assert.equal(
+          element._computeLinkURL({url: 'http://example.com/test'}),
+          'http://example.com/test');
+      assert.equal(
+          element._computeLinkURL({url: 'https://example.com/test'}),
+          'https://example.com/test');
+      assert.equal(
           element._computeLinkURL({url: '/test'}),
           '//' + window.location.host + '/test');
       assert.equal(
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
index e0854f0..c0078e9 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js
@@ -2086,10 +2086,17 @@
     },
 
     saveChangeStarred(changeNum, starred) {
-      return this._send({
-        method: starred ? 'PUT' : 'DELETE',
-        url: '/accounts/self/starred.changes/' + changeNum,
-        anonymizedUrl: '/accounts/self/starred.changes/*',
+      // Some servers may require the project name to be provided
+      // alongside the change number, so resolve the project name
+      // first.
+      return this.getFromProjectLookup(changeNum).then(project => {
+        const url = '/accounts/self/starred.changes/' +
+            (project ? encodeURIComponent(project) + '~' : '') + changeNum;
+        return this._send({
+          method: starred ? 'PUT' : 'DELETE',
+          url,
+          anonymizedUrl: '/accounts/self/starred.changes/*',
+        });
       });
     },
 
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
index 8161c35..eaac5ef 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html
@@ -1446,5 +1446,28 @@
       flushAsynchronousOperations();
       assert.isTrue(handler.calledOnce);
     });
+
+    test('saveChangeStarred', async () => {
+      sandbox.stub(element, 'getFromProjectLookup')
+          .returns(Promise.resolve('test'));
+      const sendStub =
+          sandbox.stub(element, '_send').returns(Promise.resolve());
+
+      await element.saveChangeStarred(123, true);
+      assert.isTrue(sendStub.calledOnce);
+      assert.deepEqual(sendStub.lastCall.args[0], {
+        method: 'PUT',
+        url: '/accounts/self/starred.changes/test~123',
+        anonymizedUrl: '/accounts/self/starred.changes/*',
+      });
+
+      await element.saveChangeStarred(456, false);
+      assert.isTrue(sendStub.calledTwice);
+      assert.deepEqual(sendStub.lastCall.args[0], {
+        method: 'DELETE',
+        url: '/accounts/self/starred.changes/test~456',
+        anonymizedUrl: '/accounts/self/starred.changes/*',
+      });
+    });
   });
 </script>
diff --git a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
index 816dd23..78c8684 100644
--- a/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
+++ b/resources/com/google/gerrit/httpd/raw/PolyGerritIndexHtml.soy
@@ -30,6 +30,7 @@
   <html lang="en">{\n}
   <meta charset="utf-8">{\n}
   <meta name="description" content="Gerrit Code Review">{\n}
+  <meta name="referrer" content="never">{\n}
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">{\n}
 
   <script>
diff --git a/tools/BUILD b/tools/BUILD
index c368eed..aefb867 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -13,7 +13,7 @@
 
 default_java_toolchain(
     name = "error_prone_warnings_toolchain",
-    bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath9.jar"],
+    bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath.jar"],
     jvm_opts = JDK9_JVM_OPTS,
     package_configuration = [
         ":error_prone",
diff --git a/tools/maven/gerrit-acceptance-framework_pom.xml b/tools/maven/gerrit-acceptance-framework_pom.xml
index 73aba64..e66a938 100644
--- a/tools/maven/gerrit-acceptance-framework_pom.xml
+++ b/tools/maven/gerrit-acceptance-framework_pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.gerrit</groupId>
   <artifactId>gerrit-acceptance-framework</artifactId>
-  <version>2.16-rc1</version>
+  <version>2.16-rc3</version>
   <packaging>jar</packaging>
   <name>Gerrit Code Review - Acceptance Test Framework</name>
   <description>Framework for Gerrit's acceptance tests</description>
diff --git a/tools/maven/gerrit-extension-api_pom.xml b/tools/maven/gerrit-extension-api_pom.xml
index 45540fd..623964c 100644
--- a/tools/maven/gerrit-extension-api_pom.xml
+++ b/tools/maven/gerrit-extension-api_pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.gerrit</groupId>
   <artifactId>gerrit-extension-api</artifactId>
-  <version>2.16-rc1</version>
+  <version>2.16-rc3</version>
   <packaging>jar</packaging>
   <name>Gerrit Code Review - Extension API</name>
   <description>API for Gerrit Extensions</description>
diff --git a/tools/maven/gerrit-plugin-api_pom.xml b/tools/maven/gerrit-plugin-api_pom.xml
index 826aa4e..212e739 100644
--- a/tools/maven/gerrit-plugin-api_pom.xml
+++ b/tools/maven/gerrit-plugin-api_pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.gerrit</groupId>
   <artifactId>gerrit-plugin-api</artifactId>
-  <version>2.16-rc1</version>
+  <version>2.16-rc3</version>
   <packaging>jar</packaging>
   <name>Gerrit Code Review - Plugin API</name>
   <description>API for Gerrit Plugins</description>
diff --git a/tools/maven/gerrit-plugin-gwtui_pom.xml b/tools/maven/gerrit-plugin-gwtui_pom.xml
index d63d04e4..1fe482c 100644
--- a/tools/maven/gerrit-plugin-gwtui_pom.xml
+++ b/tools/maven/gerrit-plugin-gwtui_pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.gerrit</groupId>
   <artifactId>gerrit-plugin-gwtui</artifactId>
-  <version>2.16-rc1</version>
+  <version>2.16-rc3</version>
   <packaging>jar</packaging>
   <name>Gerrit Code Review - Plugin GWT UI</name>
   <description>Common Classes for Gerrit GWT UI Plugins</description>
diff --git a/tools/maven/gerrit-war_pom.xml b/tools/maven/gerrit-war_pom.xml
index 6d963c7..4a84174 100644
--- a/tools/maven/gerrit-war_pom.xml
+++ b/tools/maven/gerrit-war_pom.xml
@@ -2,7 +2,7 @@
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.google.gerrit</groupId>
   <artifactId>gerrit-war</artifactId>
-  <version>2.16-rc1</version>
+  <version>2.16-rc3</version>
   <packaging>war</packaging>
   <name>Gerrit Code Review - WAR</name>
   <description>Gerrit WAR</description>
diff --git a/version.bzl b/version.bzl
index fae1d68..04b03a7 100644
--- a/version.bzl
+++ b/version.bzl
@@ -2,4 +2,4 @@
 # Used by :api_install and :api_deploy targets
 # when talking to the destination repository.
 #
-GERRIT_VERSION = "2.16-rc1"
+GERRIT_VERSION = "2.16-rc3"