Merge "File list comment count summary should also consider the base patchset"
diff --git a/WORKSPACE b/WORKSPACE
index bf207b5..8f1ff3e 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -579,24 +579,24 @@
 )
 
 # When updading Bouncy Castle, also update it in bazlets.
-BC_VERS = "1.57"
+BC_VERS = "1.59"
 
 maven_jar(
     name = "bcprov",
     artifact = "org.bouncycastle:bcprov-jdk15on:" + BC_VERS,
-    sha1 = "f66a135611d42c992e5745788c3f94eb06464537",
+    sha1 = "2507204241ab450456bdb8e8c0a8f986e418bd99",
 )
 
 maven_jar(
     name = "bcpg",
     artifact = "org.bouncycastle:bcpg-jdk15on:" + BC_VERS,
-    sha1 = "7b2d587f5e3780b79e1d35af3e84d00634e9420b",
+    sha1 = "ee93e5376bb6cf0a15c027b5f5e4393f2738e709",
 )
 
 maven_jar(
     name = "bcpkix",
     artifact = "org.bouncycastle:bcpkix-jdk15on:" + BC_VERS,
-    sha1 = "5c96e34bc9bd4cd6870e6d193a99438f1e274ca7",
+    sha1 = "9cef0aab8a4bb849a8476c058ce3ff302aba3fff",
 )
 
 # TODO(davido): Remove exlusion of file system provider, when this issue is fixed:
diff --git a/java/com/google/gerrit/extensions/restapi/RestCollection.java b/java/com/google/gerrit/extensions/restapi/RestCollection.java
index 46a4984..e79bde4 100644
--- a/java/com/google/gerrit/extensions/restapi/RestCollection.java
+++ b/java/com/google/gerrit/extensions/restapi/RestCollection.java
@@ -65,10 +65,11 @@
    * "q" parameter option to narrow the results.
    *
    * @return view to list the collection.
-   * @throws ResourceNotFoundException if the collection cannot be listed.
+   * @throws ResourceNotFoundException if the collection doesn't support listing.
    * @throws AuthException if the collection requires authentication.
+   * @throws RestApiException if the collection cannot be listed.
    */
-  RestView<P> list() throws ResourceNotFoundException, AuthException;
+  RestView<P> list() throws RestApiException;
 
   /**
    * Parse a path component into a resource handle.
diff --git a/java/com/google/gerrit/httpd/BUILD b/java/com/google/gerrit/httpd/BUILD
index 4bd3e2e..bbb5b66 100644
--- a/java/com/google/gerrit/httpd/BUILD
+++ b/java/com/google/gerrit/httpd/BUILD
@@ -18,8 +18,6 @@
         "//java/com/google/gerrit/server/restapi",
         "//java/com/google/gerrit/util/cli",
         "//java/com/google/gerrit/util/http",
-        "//java/com/google/gwtexpui/linker:server",
-        "//java/com/google/gwtexpui/server",
         "//java/org/eclipse/jgit:server",
         "//lib:args4j",
         "//lib:gson",
diff --git a/java/com/google/gwtexpui/server/CacheControlFilter.java b/java/com/google/gerrit/httpd/GwtCacheControlFilter.java
similarity index 94%
rename from java/com/google/gwtexpui/server/CacheControlFilter.java
rename to java/com/google/gerrit/httpd/GwtCacheControlFilter.java
index 571f72d..5ac3d2f 100644
--- a/java/com/google/gwtexpui/server/CacheControlFilter.java
+++ b/java/com/google/gerrit/httpd/GwtCacheControlFilter.java
@@ -12,8 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gwtexpui.server;
+package com.google.gerrit.httpd;
 
+import com.google.gerrit.util.http.CacheHeaders;
+import com.google.inject.Singleton;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 import javax.servlet.Filter;
@@ -46,7 +48,8 @@
  *   &lt;/filter-mapping&gt;
  * </pre>
  */
-public class CacheControlFilter implements Filter {
+@Singleton
+class GwtCacheControlFilter implements Filter {
   @Override
   public void init(FilterConfig config) {}
 
diff --git a/java/com/google/gerrit/httpd/UrlModule.java b/java/com/google/gerrit/httpd/UrlModule.java
index 6210385..1702a38 100644
--- a/java/com/google/gerrit/httpd/UrlModule.java
+++ b/java/com/google/gerrit/httpd/UrlModule.java
@@ -34,7 +34,6 @@
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.config.AuthConfig;
 import com.google.gerrit.server.config.GerritOptions;
-import com.google.gwtexpui.server.CacheControlFilter;
 import com.google.inject.Key;
 import com.google.inject.Provider;
 import com.google.inject.internal.UniqueAnnotations;
@@ -56,8 +55,7 @@
 
   @Override
   protected void configureServlets() {
-    filter("/*").through(Key.get(CacheControlFilter.class));
-    bind(Key.get(CacheControlFilter.class)).in(SINGLETON);
+    filter("/*").through(GwtCacheControlFilter.class);
 
     if (options.enableGwtUi()) {
       filter("/").through(XsrfCookieFilter.class);
diff --git a/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java b/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
index 77c79bb..ea01809 100644
--- a/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
+++ b/java/com/google/gerrit/httpd/auth/become/BecomeAnyAccountLoginServlet.java
@@ -34,7 +34,7 @@
 import com.google.gerrit.server.account.AuthResult;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.query.account.InternalAccountQuery;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java b/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
index c7229bc..0b3c29d 100644
--- a/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
+++ b/java/com/google/gerrit/httpd/auth/container/HttpAuthFilter.java
@@ -28,7 +28,7 @@
 import com.google.gerrit.httpd.raw.HostPageServlet;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.config.AuthConfig;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java b/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
index 6340b22..fd2f628 100644
--- a/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
+++ b/java/com/google/gerrit/httpd/auth/container/HttpLoginServlet.java
@@ -30,7 +30,7 @@
 import com.google.gerrit.server.account.AuthResult;
 import com.google.gerrit.server.account.externalids.ExternalId;
 import com.google.gerrit.server.config.AuthConfig;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/auth/container/HttpsClientSslCertLoginServlet.java b/java/com/google/gerrit/httpd/auth/container/HttpsClientSslCertLoginServlet.java
index e93b0b6..f21c96e 100644
--- a/java/com/google/gerrit/httpd/auth/container/HttpsClientSslCertLoginServlet.java
+++ b/java/com/google/gerrit/httpd/auth/container/HttpsClientSslCertLoginServlet.java
@@ -17,7 +17,7 @@
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.httpd.LoginUrlToken;
 import com.google.gerrit.server.config.CanonicalWebUrl;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java b/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
index 6370476..116ad6d 100644
--- a/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
+++ b/java/com/google/gerrit/httpd/auth/ldap/LdapLoginServlet.java
@@ -33,7 +33,7 @@
 import com.google.gerrit.server.account.AuthResult;
 import com.google.gerrit.server.account.AuthenticationFailedException;
 import com.google.gerrit.server.auth.AuthenticationUnavailableException;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/auth/openid/BUILD b/java/com/google/gerrit/httpd/auth/openid/BUILD
index 9c48832..bfb2551 100644
--- a/java/com/google/gerrit/httpd/auth/openid/BUILD
+++ b/java/com/google/gerrit/httpd/auth/openid/BUILD
@@ -11,7 +11,7 @@
         "//java/com/google/gerrit/extensions:api",
         "//java/com/google/gerrit/httpd",
         "//java/com/google/gerrit/reviewdb:server",
-        "//java/com/google/gwtexpui/server",
+        "//java/com/google/gerrit/util/http",
         "//java/com/google/gerrit/server",
         "//lib:guava",
         "//lib:gwtorm",
diff --git a/java/com/google/gerrit/httpd/auth/openid/OpenIdLoginServlet.java b/java/com/google/gerrit/httpd/auth/openid/OpenIdLoginServlet.java
index a97e8ae..23cf468 100644
--- a/java/com/google/gerrit/httpd/auth/openid/OpenIdLoginServlet.java
+++ b/java/com/google/gerrit/httpd/auth/openid/OpenIdLoginServlet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.auth.openid;
 
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/gitweb/GitLogoServlet.java b/java/com/google/gerrit/httpd/gitweb/GitLogoServlet.java
index af853cc..d57e629 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitLogoServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitLogoServlet.java
@@ -18,7 +18,7 @@
 
 import com.google.common.io.ByteStreams;
 import com.google.gerrit.server.config.GitwebCgiConfig;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/gitweb/GitwebCssServlet.java b/java/com/google/gerrit/httpd/gitweb/GitwebCssServlet.java
index 5e22081..feee3ba 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitwebCssServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitwebCssServlet.java
@@ -20,7 +20,7 @@
 import com.google.gerrit.httpd.HtmlDomUtil;
 import com.google.gerrit.server.config.GitwebCgiConfig;
 import com.google.gerrit.server.config.SitePaths;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/gitweb/GitwebJavaScriptServlet.java b/java/com/google/gerrit/httpd/gitweb/GitwebJavaScriptServlet.java
index 651b582..82dd901 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitwebJavaScriptServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitwebJavaScriptServlet.java
@@ -18,7 +18,7 @@
 
 import com.google.common.io.ByteStreams;
 import com.google.gerrit.server.config.GitwebCgiConfig;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
index 383efd3..5e59c9a 100644
--- a/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
+++ b/java/com/google/gerrit/httpd/gitweb/GitwebServlet.java
@@ -55,7 +55,7 @@
 import com.google.gerrit.server.project.ProjectCache;
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.ssh.SshInfo;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.ProvisionException;
diff --git a/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java b/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
index 63ce211..9a24e47 100644
--- a/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
+++ b/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
@@ -52,8 +52,8 @@
 import com.google.gerrit.server.plugins.ReloadPluginListener;
 import com.google.gerrit.server.plugins.StartPluginListener;
 import com.google.gerrit.server.ssh.SshInfo;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gerrit.util.http.RequestUtil;
-import com.google.gwtexpui.server.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/plugins/LfsPluginServlet.java b/java/com/google/gerrit/httpd/plugins/LfsPluginServlet.java
index 0ee22fa..67ee3ba 100644
--- a/java/com/google/gerrit/httpd/plugins/LfsPluginServlet.java
+++ b/java/com/google/gerrit/httpd/plugins/LfsPluginServlet.java
@@ -25,7 +25,7 @@
 import com.google.gerrit.server.plugins.Plugin;
 import com.google.gerrit.server.plugins.ReloadPluginListener;
 import com.google.gerrit.server.plugins.StartPluginListener;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.google.inject.servlet.GuiceFilter;
diff --git a/java/com/google/gerrit/httpd/raw/BazelBuild.java b/java/com/google/gerrit/httpd/raw/BazelBuild.java
index 92a5aaa..940a51b 100644
--- a/java/com/google/gerrit/httpd/raw/BazelBuild.java
+++ b/java/com/google/gerrit/httpd/raw/BazelBuild.java
@@ -23,7 +23,7 @@
 import com.google.common.html.HtmlEscapers;
 import com.google.common.io.ByteStreams;
 import com.google.gerrit.common.TimeUtil;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InterruptedIOException;
diff --git a/java/com/google/gerrit/httpd/raw/HostPageServlet.java b/java/com/google/gerrit/httpd/raw/HostPageServlet.java
index 74868d7..160732e 100644
--- a/java/com/google/gerrit/httpd/raw/HostPageServlet.java
+++ b/java/com/google/gerrit/httpd/raw/HostPageServlet.java
@@ -39,7 +39,7 @@
 import com.google.gerrit.server.notedb.NotesMigration;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.restapi.account.GetDiffPreferences;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtjsonrpc.server.JsonServlet;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
 import com.google.inject.Inject;
diff --git a/java/com/google/gerrit/httpd/raw/LegacyGerritServlet.java b/java/com/google/gerrit/httpd/raw/LegacyGerritServlet.java
index 10735a5..e12f0a5 100644
--- a/java/com/google/gerrit/httpd/raw/LegacyGerritServlet.java
+++ b/java/com/google/gerrit/httpd/raw/LegacyGerritServlet.java
@@ -15,7 +15,7 @@
 package com.google.gerrit.httpd.raw;
 
 import com.google.gerrit.httpd.HtmlDomUtil;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
diff --git a/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java b/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
index 90aedbe..c6c3367 100644
--- a/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
+++ b/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
@@ -14,7 +14,6 @@
 
 package com.google.gerrit.httpd.raw;
 
-import com.google.gwtexpui.linker.server.UserAgentRule;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/java/com/google/gerrit/httpd/raw/ResourceServlet.java b/java/com/google/gerrit/httpd/raw/ResourceServlet.java
index 035653d..64b5bbb 100644
--- a/java/com/google/gerrit/httpd/raw/ResourceServlet.java
+++ b/java/com/google/gerrit/httpd/raw/ResourceServlet.java
@@ -34,7 +34,7 @@
 import com.google.common.hash.Hashing;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.httpd.HtmlDomUtil;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gwtjsonrpc.server.RPCServletUtils;
 import java.io.IOException;
 import java.io.OutputStream;
diff --git a/java/com/google/gerrit/httpd/raw/SshInfoServlet.java b/java/com/google/gerrit/httpd/raw/SshInfoServlet.java
index 55bc2a6..1d1fe6cc 100644
--- a/java/com/google/gerrit/httpd/raw/SshInfoServlet.java
+++ b/java/com/google/gerrit/httpd/raw/SshInfoServlet.java
@@ -17,7 +17,7 @@
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import com.google.gerrit.server.ssh.SshInfo;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 import com.jcraft.jsch.HostKey;
diff --git a/java/com/google/gwtexpui/linker/server/UserAgentRule.java b/java/com/google/gerrit/httpd/raw/UserAgentRule.java
similarity index 93%
rename from java/com/google/gwtexpui/linker/server/UserAgentRule.java
rename to java/com/google/gerrit/httpd/raw/UserAgentRule.java
index 8f7bede..4aac243 100644
--- a/java/com/google/gwtexpui/linker/server/UserAgentRule.java
+++ b/java/com/google/gerrit/httpd/raw/UserAgentRule.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gwtexpui.linker.server;
+package com.google.gerrit.httpd.raw;
 
 import static java.util.regex.Pattern.compile;
 
@@ -28,15 +28,15 @@
  *
  * <p>Ported from JavaScript in {@code com.google.gwt.user.UserAgent.gwt.xml}.
  */
-public class UserAgentRule {
+class UserAgentRule {
   private static final Pattern msie = compile(".*msie ([0-11]+)\\.([0-11]+).*");
   private static final Pattern gecko = compile(".*rv:([0-9]+)\\.([0-9]+).*");
 
-  public String getName() {
+  String getName() {
     return "user.agent";
   }
 
-  public String select(HttpServletRequest req) {
+  String select(HttpServletRequest req) {
     String ua = req.getHeader("User-Agent");
     if (ua == null) {
       return null;
diff --git a/java/com/google/gerrit/httpd/resources/Resource.java b/java/com/google/gerrit/httpd/resources/Resource.java
index bfa0b95..878912e 100644
--- a/java/com/google/gerrit/httpd/resources/Resource.java
+++ b/java/com/google/gerrit/httpd/resources/Resource.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.httpd.resources;
 
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import java.io.IOException;
 import java.io.Serializable;
 import javax.servlet.http.HttpServletRequest;
diff --git a/java/com/google/gerrit/httpd/restapi/ParameterParser.java b/java/com/google/gerrit/httpd/restapi/ParameterParser.java
index bfaf0c7..2870cd0 100644
--- a/java/com/google/gerrit/httpd/restapi/ParameterParser.java
+++ b/java/com/google/gerrit/httpd/restapi/ParameterParser.java
@@ -38,11 +38,11 @@
 import com.google.gerrit.extensions.restapi.Url;
 import com.google.gerrit.server.DynamicOptions;
 import com.google.gerrit.util.cli.CmdLineParser;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonPrimitive;
-import com.google.gwtexpui.server.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import java.io.IOException;
diff --git a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
index 4c9a035..546bb9f 100644
--- a/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
+++ b/java/com/google/gerrit/httpd/restapi/RestApiServlet.java
@@ -110,6 +110,7 @@
 import com.google.gerrit.server.permissions.PermissionBackend;
 import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.update.UpdateException;
+import com.google.gerrit.util.http.CacheHeaders;
 import com.google.gerrit.util.http.RequestUtil;
 import com.google.gson.ExclusionStrategy;
 import com.google.gson.FieldAttributes;
@@ -123,7 +124,6 @@
 import com.google.gson.stream.JsonToken;
 import com.google.gson.stream.JsonWriter;
 import com.google.gson.stream.MalformedJsonException;
-import com.google.gwtexpui.server.CacheHeaders;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.TypeLiteral;
@@ -846,16 +846,25 @@
     throw new BadRequestException("Expected JSON object");
   }
 
+  @SuppressWarnings("unchecked")
   private static Object createInstance(Type type)
       throws NoSuchMethodException, InstantiationException, IllegalAccessException,
           InvocationTargetException {
     if (type instanceof Class) {
-      @SuppressWarnings("unchecked")
       Class<Object> clazz = (Class<Object>) type;
       Constructor<Object> c = clazz.getDeclaredConstructor();
       c.setAccessible(true);
       return c.newInstance();
     }
+    if (type instanceof ParameterizedType) {
+      Type rawType = ((ParameterizedType) type).getRawType();
+      if (rawType instanceof Class && List.class.isAssignableFrom((Class<Object>) rawType)) {
+        return new ArrayList<>();
+      }
+      if (rawType instanceof Class && Map.class.isAssignableFrom((Class<Object>) rawType)) {
+        return new HashMap<>();
+      }
+    }
     throw new InstantiationException("Cannot make " + type);
   }
 
diff --git a/java/com/google/gerrit/pgm/BUILD b/java/com/google/gerrit/pgm/BUILD
index c83f8af..95570ec 100644
--- a/java/com/google/gerrit/pgm/BUILD
+++ b/java/com/google/gerrit/pgm/BUILD
@@ -42,8 +42,7 @@
         "//java/com/google/gerrit/server/restapi",
         "//java/com/google/gerrit/server/schema",
         "//java/com/google/gerrit/sshd",
-        "//java/com/google/gwtexpui/linker:server",
-        "//java/com/google/gwtexpui/server",
+        "//java/com/google/gerrit/util/http",
         "//lib:args4j",
         "//lib:guava",
         "//lib:gwtorm",
diff --git a/java/com/google/gerrit/pgm/http/jetty/BUILD b/java/com/google/gerrit/pgm/http/jetty/BUILD
index 6dc63658..b1da011 100644
--- a/java/com/google/gerrit/pgm/http/jetty/BUILD
+++ b/java/com/google/gerrit/pgm/http/jetty/BUILD
@@ -10,7 +10,7 @@
         "//java/com/google/gerrit/lifecycle",
         "//java/com/google/gerrit/server",
         "//java/com/google/gerrit/sshd",
-        "//java/com/google/gwtexpui/server",
+        "//java/com/google/gerrit/util/http",
         "//lib:guava",
         "//lib:servlet-api-3_1",
         "//lib/flogger:api",
diff --git a/java/com/google/gerrit/pgm/http/jetty/HiddenErrorHandler.java b/java/com/google/gerrit/pgm/http/jetty/HiddenErrorHandler.java
index 9347171..1c43240 100644
--- a/java/com/google/gerrit/pgm/http/jetty/HiddenErrorHandler.java
+++ b/java/com/google/gerrit/pgm/http/jetty/HiddenErrorHandler.java
@@ -18,7 +18,7 @@
 
 import com.google.common.base.Strings;
 import com.google.common.flogger.FluentLogger;
-import com.google.gwtexpui.server.CacheHeaders;
+import com.google.gerrit.util.http.CacheHeaders;
 import java.io.IOException;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
diff --git a/java/com/google/gerrit/server/ChangeUtil.java b/java/com/google/gerrit/server/ChangeUtil.java
index 56359ce..d90f5d0 100644
--- a/java/com/google/gerrit/server/ChangeUtil.java
+++ b/java/com/google/gerrit/server/ChangeUtil.java
@@ -45,7 +45,7 @@
       Ordering.from(comparingInt(PatchSet::getPatchSetId));
 
   public static String formatChangeUrl(String canonicalWebUrl, Change change) {
-    return canonicalWebUrl + "#/c/" + change.getProject().get() + "/+/" + change.getChangeId();
+    return canonicalWebUrl + "c/" + change.getProject().get() + "/+/" + change.getChangeId();
   }
 
   /** @return a new unique identifier for change message entities. */
diff --git a/java/com/google/gerrit/server/StarredChangesUtil.java b/java/com/google/gerrit/server/StarredChangesUtil.java
index 0d8d7c1..0fbf200 100644
--- a/java/com/google/gerrit/server/StarredChangesUtil.java
+++ b/java/com/google/gerrit/server/StarredChangesUtil.java
@@ -476,6 +476,11 @@
 
   private void deleteRef(Repository repo, String refName, ObjectId oldObjectId)
       throws IOException, OrmException {
+    if (ObjectId.zeroId().equals(oldObjectId)) {
+      // ref doesn't exist
+      return;
+    }
+
     RefUpdate u = repo.updateRef(refName);
     u.setForceUpdate(true);
     u.setExpectedOldObjectId(oldObjectId);
diff --git a/java/com/google/gerrit/server/cache/PerThreadCache.java b/java/com/google/gerrit/server/cache/PerThreadCache.java
index 0881d59..b4f79d1 100644
--- a/java/com/google/gerrit/server/cache/PerThreadCache.java
+++ b/java/com/google/gerrit/server/cache/PerThreadCache.java
@@ -51,11 +51,11 @@
 public class PerThreadCache implements AutoCloseable {
   private static final ThreadLocal<PerThreadCache> CACHE = new ThreadLocal<>();
   /**
-   * Cache at maximum 50 values per thread. This value was chosen arbitrarily. Some endpoints (like
+   * Cache at maximum 25 values per thread. This value was chosen arbitrarily. Some endpoints (like
    * ListProjects) break the assumption that the data cached in a request is limited. To prevent
    * this class from accumulating an unbound number of objects, we enforce this limit.
    */
-  private static final int PER_THREAD_CACHE_SIZE = 50;
+  private static final int PER_THREAD_CACHE_SIZE = 25;
 
   /**
    * Unique key for key-value mappings stored in PerThreadCache. The key is based on the value's
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
index 568b966..a91fac5 100644
--- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
+++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -2942,9 +2942,8 @@
 
                 for (Ref ref : byCommit.get(c.copy())) {
                   PatchSet.Id psId = PatchSet.Id.fromRef(ref.getName());
-                  Optional<ChangeData> cd =
-                      executeIndexQuery(() -> byLegacyId(psId.getParentKey()));
-                  if (cd.isPresent() && cd.get().change().getDest().equals(branch)) {
+                  Optional<ChangeNotes> notes = getChangeNotes(psId.getParentKey());
+                  if (notes.isPresent() && notes.get().getChange().getDest().equals(branch)) {
                     existingPatchSets++;
                     bu.addOp(
                         psId.getParentKey(),
@@ -3007,6 +3006,14 @@
     }
   }
 
+  private Optional<ChangeNotes> getChangeNotes(Change.Id changeId) throws OrmException {
+    try {
+      return Optional.of(notesFactory.createChecked(db, project.getNameKey(), changeId));
+    } catch (NoSuchChangeException e) {
+      return Optional.empty();
+    }
+  }
+
   private <T> T executeIndexQuery(Action<T> action) throws OrmException {
     try {
       return retryHelper.execute(ActionType.INDEX_QUERY, action, OrmException.class::isInstance);
@@ -3069,14 +3076,6 @@
     return r;
   }
 
-  private Optional<ChangeData> byLegacyId(Change.Id legacyId) throws OrmException {
-    List<ChangeData> res = queryProvider.get().byLegacyChangeId(legacyId);
-    if (res.isEmpty()) {
-      return Optional.empty();
-    }
-    return Optional.of(res.get(0));
-  }
-
   private Map<String, Ref> allRefs() {
     return allRefsWatcher.getAllRefs();
   }
diff --git a/java/com/google/gerrit/server/restapi/access/AccessCollection.java b/java/com/google/gerrit/server/restapi/access/AccessCollection.java
index d4528c5..8ae2ce7 100644
--- a/java/com/google/gerrit/server/restapi/access/AccessCollection.java
+++ b/java/com/google/gerrit/server/restapi/access/AccessCollection.java
@@ -30,7 +30,7 @@
   private final DynamicMap<RestView<AccessResource>> views;
 
   @Inject
-  AccessCollection(Provider<ListAccess> list, DynamicMap<RestView<AccessResource>> views) {
+  public AccessCollection(Provider<ListAccess> list, DynamicMap<RestView<AccessResource>> views) {
     this.list = list;
     this.views = views;
   }
diff --git a/java/com/google/gerrit/server/restapi/config/TopMenuCollection.java b/java/com/google/gerrit/server/restapi/config/TopMenuCollection.java
index 36a1b04..cca1475 100644
--- a/java/com/google/gerrit/server/restapi/config/TopMenuCollection.java
+++ b/java/com/google/gerrit/server/restapi/config/TopMenuCollection.java
@@ -25,7 +25,7 @@
 import com.google.inject.Singleton;
 
 @Singleton
-class TopMenuCollection implements ChildCollection<ConfigResource, TopMenuResource> {
+public class TopMenuCollection implements ChildCollection<ConfigResource, TopMenuResource> {
   private final DynamicMap<RestView<TopMenuResource>> views;
   private final ListTopMenus list;
 
diff --git a/java/com/google/gerrit/server/restapi/group/AddMembers.java b/java/com/google/gerrit/server/restapi/group/AddMembers.java
index 9ddafe3..461989d 100644
--- a/java/com/google/gerrit/server/restapi/group/AddMembers.java
+++ b/java/com/google/gerrit/server/restapi/group/AddMembers.java
@@ -211,12 +211,12 @@
     return result;
   }
 
-  static class PutMember implements RestModifyView<GroupResource, Input> {
+  public static class PutMember implements RestModifyView<GroupResource, Input> {
 
     private final AddMembers put;
     private final String id;
 
-    PutMember(AddMembers put, String id) {
+    public PutMember(AddMembers put, String id) {
       this.put = put;
       this.id = id;
     }
@@ -240,11 +240,11 @@
   }
 
   @Singleton
-  static class UpdateMember implements RestModifyView<MemberResource, Input> {
+  public static class UpdateMember implements RestModifyView<MemberResource, Input> {
     private final GetMember get;
 
     @Inject
-    UpdateMember(GetMember get) {
+    public UpdateMember(GetMember get) {
       this.get = get;
     }
 
diff --git a/java/com/google/gerrit/server/restapi/group/AddSubgroups.java b/java/com/google/gerrit/server/restapi/group/AddSubgroups.java
index e11f389..d0be5ac 100644
--- a/java/com/google/gerrit/server/restapi/group/AddSubgroups.java
+++ b/java/com/google/gerrit/server/restapi/group/AddSubgroups.java
@@ -127,12 +127,12 @@
     groupsUpdateProvider.get().updateGroup(parentGroupUuid, groupUpdate);
   }
 
-  static class PutSubgroup implements RestModifyView<GroupResource, Input> {
+  public static class PutSubgroup implements RestModifyView<GroupResource, Input> {
 
     private final AddSubgroups addSubgroups;
     private final String id;
 
-    PutSubgroup(AddSubgroups addSubgroups, String id) {
+    public PutSubgroup(AddSubgroups addSubgroups, String id) {
       this.addSubgroups = addSubgroups;
       this.id = id;
     }
@@ -156,11 +156,11 @@
   }
 
   @Singleton
-  static class UpdateSubgroup implements RestModifyView<SubgroupResource, Input> {
+  public static class UpdateSubgroup implements RestModifyView<SubgroupResource, Input> {
     private final Provider<GetSubgroup> get;
 
     @Inject
-    UpdateSubgroup(Provider<GetSubgroup> get) {
+    public UpdateSubgroup(Provider<GetSubgroup> get) {
       this.get = get;
     }
 
diff --git a/java/com/google/gerrit/server/restapi/group/DeleteMembers.java b/java/com/google/gerrit/server/restapi/group/DeleteMembers.java
index 3685469..bcacb65 100644
--- a/java/com/google/gerrit/server/restapi/group/DeleteMembers.java
+++ b/java/com/google/gerrit/server/restapi/group/DeleteMembers.java
@@ -92,12 +92,12 @@
   }
 
   @Singleton
-  static class DeleteMember implements RestModifyView<MemberResource, Input> {
+  public static class DeleteMember implements RestModifyView<MemberResource, Input> {
 
     private final Provider<DeleteMembers> delete;
 
     @Inject
-    DeleteMember(Provider<DeleteMembers> delete) {
+    public DeleteMember(Provider<DeleteMembers> delete) {
       this.delete = delete;
     }
 
diff --git a/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java b/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
index 0eba8c7..934698b 100644
--- a/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
+++ b/java/com/google/gerrit/server/restapi/group/DeleteSubgroups.java
@@ -96,12 +96,12 @@
   }
 
   @Singleton
-  static class DeleteSubgroup implements RestModifyView<SubgroupResource, Input> {
+  public static class DeleteSubgroup implements RestModifyView<SubgroupResource, Input> {
 
     private final Provider<DeleteSubgroups> delete;
 
     @Inject
-    DeleteSubgroup(Provider<DeleteSubgroups> delete) {
+    public DeleteSubgroup(Provider<DeleteSubgroups> delete) {
       this.delete = delete;
     }
 
diff --git a/java/com/google/gerrit/server/restapi/group/GroupsCollection.java b/java/com/google/gerrit/server/restapi/group/GroupsCollection.java
index 38b22a9..d05194f 100644
--- a/java/com/google/gerrit/server/restapi/group/GroupsCollection.java
+++ b/java/com/google/gerrit/server/restapi/group/GroupsCollection.java
@@ -58,7 +58,7 @@
   private boolean hasQuery2;
 
   @Inject
-  GroupsCollection(
+  public GroupsCollection(
       DynamicMap<RestView<GroupResource>> views,
       Provider<ListGroups> list,
       Provider<QueryGroups> queryGroups,
diff --git a/java/com/google/gwtexpui/server/CacheHeaders.java b/java/com/google/gerrit/util/http/CacheHeaders.java
similarity index 98%
rename from java/com/google/gwtexpui/server/CacheHeaders.java
rename to java/com/google/gerrit/util/http/CacheHeaders.java
index 0e5e425..454587c 100644
--- a/java/com/google/gwtexpui/server/CacheHeaders.java
+++ b/java/com/google/gerrit/util/http/CacheHeaders.java
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gwtexpui.server;
+package com.google.gerrit.util.http;
 
 import static java.util.concurrent.TimeUnit.DAYS;
 import static java.util.concurrent.TimeUnit.SECONDS;
diff --git a/java/com/google/gwtexpui/linker/BUILD b/java/com/google/gwtexpui/linker/BUILD
deleted file mode 100644
index 5c5c600..0000000
--- a/java/com/google/gwtexpui/linker/BUILD
+++ /dev/null
@@ -1,6 +0,0 @@
-java_library(
-    name = "server",
-    srcs = glob(["server/*.java"]),
-    visibility = ["//visibility:public"],
-    deps = ["//lib:servlet-api-3_1"],
-)
diff --git a/java/com/google/gwtexpui/server/BUILD b/java/com/google/gwtexpui/server/BUILD
deleted file mode 100644
index 9b81564..0000000
--- a/java/com/google/gwtexpui/server/BUILD
+++ /dev/null
@@ -1,6 +0,0 @@
-java_library(
-    name = "server",
-    srcs = glob(["**/*.java"]),
-    visibility = ["//visibility:public"],
-    deps = ["//lib:servlet-api-3_1"],
-)
diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
index f17165e..1d0f3ac 100644
--- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java
@@ -728,6 +728,17 @@
   }
 
   @Test
+  public void deleteStarLabelsFromChangeWithoutStarLabels() throws Exception {
+    PushOneCommit.Result r = createChange();
+    String triplet = project.get() + "~master~" + r.getChangeId();
+    assertThat(gApi.accounts().self().getStars(triplet)).isEmpty();
+
+    gApi.accounts().self().setStars(triplet, new StarsInput());
+
+    assertThat(gApi.accounts().self().getStars(triplet)).isEmpty();
+  }
+
+  @Test
   public void starWithDefaultAndIgnoreLabel() throws Exception {
     PushOneCommit.Result r = createChange();
     String triplet = project.get() + "~master~" + r.getChangeId();
diff --git a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
index 1d7f3d9..8cc5c00 100644
--- a/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
+++ b/javatests/com/google/gerrit/acceptance/git/AbstractPushForReview.java
@@ -276,7 +276,7 @@
 
   @Test
   public void output() throws Exception {
-    String url = canonicalWebUrl.get() + "#/c/" + project.get() + "/+/";
+    String url = canonicalWebUrl.get() + "c/" + project.get() + "/+/";
     ObjectId initialHead = testRepo.getRepository().resolve("HEAD");
     PushOneCommit.Result r1 = pushTo("refs/for/master");
     Change.Id id1 = r1.getChange().getId();
@@ -328,7 +328,7 @@
     assertPushOk(pushHead(testRepo, master, false), master);
 
     // Attempt to push amended commit to same change
-    String url = canonicalWebUrl.get() + "#/c/" + project.get() + "/+/" + r.getChange().getId();
+    String url = canonicalWebUrl.get() + "c/" + project.get() + "/+/" + r.getChange().getId();
     r = amendChange(r.getChangeId(), "refs/for/master");
     r.assertErrorStatus("change " + url + " closed");
 
@@ -354,7 +354,7 @@
     assertPushOk(pushHead(testRepo, master, false), master);
 
     // Attempt to push amended commit to same change
-    String url = canonicalWebUrl.get() + "#/c/" + project.get() + "/+/" + r.getChange().getId();
+    String url = canonicalWebUrl.get() + "c/" + project.get() + "/+/" + r.getChange().getId();
     r = amendChange(r.getChangeId(), "refs/for/master");
     r.assertErrorStatus("change " + url + " closed");
 
@@ -700,7 +700,7 @@
     r.assertMessage(
         "Updated Changes:\n  "
             + canonicalWebUrl.get()
-            + "#/c/"
+            + "c/"
             + project.get()
             + "/+/"
             + r.getChange().getId()
diff --git a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
index 9edafb8..bc84593 100644
--- a/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/account/WatchedProjectsIT.java
@@ -235,4 +235,9 @@
     assertThat(persistedWatchedProjects).doesNotContain(pwi);
     assertThat(persistedWatchedProjects).containsAllIn(projectsToWatch);
   }
+
+  @Test
+  public void postWithoutBody() throws Exception {
+    adminRestSession.post("/accounts/" + admin.username + "/watched.projects").assertOK();
+  }
 }
diff --git a/plugins/BUILD b/plugins/BUILD
index 7252f8c..3852bc1 100644
--- a/plugins/BUILD
+++ b/plugins/BUILD
@@ -36,7 +36,7 @@
     "//java/com/google/gerrit/metrics",
     "//java/com/google/gerrit/metrics/dropwizard",
     "//java/com/google/gerrit/reviewdb:server",
-    "//java/com/google/gwtexpui/server",
+    "//java/com/google/gerrit/util/http",
     "//lib/commons:dbcp",
     "//lib/commons:lang",
     "//lib/commons:lang3",
@@ -110,7 +110,7 @@
         "//java/com/google/gerrit/server:libserver-src.jar",
         "//java/com/google/gerrit/server/restapi:librestapi-src.jar",
         "//java/com/google/gerrit/sshd:libsshd-src.jar",
-        "//java/com/google/gwtexpui/server:libserver-src.jar",
+        "//java/com/google/gerrit/util/http:libhttp-src.jar",
     ],
 )
 
@@ -125,8 +125,8 @@
         "//java/com/google/gerrit/common:annotations",
         "//java/com/google/gerrit/common:server",
         "//java/com/google/gerrit/extensions:api",
-        "//java/com/google/gwtexpui/server",
         "//java/com/google/gerrit/reviewdb:server",
+        "//java/com/google/gerrit/util/http",
     ],
     pkgs = ["com.google.gerrit"],
     title = "Gerrit Review Plugin API Documentation",
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index 7ae2ef6..9104cbb 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -1119,8 +1119,7 @@
     _setLabelValuesOnRevert(newChangeId) {
       const labels = this.$.jsAPI.getLabelValuesPostRevert(this.change);
       if (!labels) { return Promise.resolve(); }
-      return this.$.restAPI.getChangeURLAndSend(newChangeId,
-          this.actions.revert.method, 'current', '/review', {labels});
+      return this.$.restAPI.saveChangeReview(newChangeId, 'current', {labels});
     },
 
     _handleResponse(action, response) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
index f8c522d..15284ec 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -401,6 +401,19 @@
       assert.isFalse(element.$.mainContent.classList.contains('overlayOpen'));
     });
 
+    test('_setLabelValuesOnRevert', () => {
+      const labels = {'Foo': 1, 'Bar-Baz': -2};
+      const changeId = 1234;
+      sandbox.stub(element.$.jsAPI, 'getLabelValuesPostRevert').returns(labels);
+      const saveStub = sandbox.stub(element.$.restAPI, 'saveChangeReview')
+          .returns(Promise.resolve());
+      return element._setLabelValuesOnRevert(changeId).then(() => {
+        assert.isTrue(saveStub.calledOnce);
+        assert.equal(saveStub.lastCall.args[0], changeId);
+        assert.deepEqual(saveStub.lastCall.args[2], {labels});
+      });
+    });
+
     suite('change edits', () => {
       test('shows confirm dialog for delete edit', () => {
         element.set('editMode', true);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
index fdf18c1..27f8d39 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-image.js
@@ -52,12 +52,12 @@
     // TODO(kaspern): Support blame for image diffs and remove the hardcoded 4
     // column limit.
     td.setAttribute('colspan', '4');
-
     const endpoint = this._createElement('gr-endpoint-decorator');
-    endpoint.setAttribute('name', 'image-diff');
-    endpoint.appendChild(
+    const endpointDomApi = Polymer.dom(endpoint);
+    endpointDomApi.setAttribute('name', 'image-diff');
+    endpointDomApi.appendChild(
         this._createEndpointParam('baseImage', this._baseImage));
-    endpoint.appendChild(
+    endpointDomApi.appendChild(
         this._createEndpointParam('revisionImage', this._revisionImage));
     td.appendChild(endpoint);
     tr.appendChild(td);