Merge branch 'stable-2.16'

* stable-2.16:
  Make WebSessionManager.Val#getAccountId public
  Bug fixes for gr-group-members
  Fix the position of the gray vertical line for line length limit
  Update rules_closure to latest version
  dev-plugins: Recommend cloning examples project instead of cookbook-plugin

Change-Id: Ib31fd28ab57375174be278ffd5c214f250e2fe58
diff --git a/.gitignore b/.gitignore
index 319b3cf..c0e14ab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,21 +14,36 @@
 /.classpath
 /.factorypath
 /.idea
+/.ijwb
 /.metadata
 /.project
 /.settings/org.eclipse.ltk.core.refactoring.prefs
 /.settings/org.eclipse.m2e.core.prefs
 /.settings/org.maven.ide.eclipse.prefs
+/.vscode
 /bazel-*
 /bin/
+/bower_components/
 /eclipse-out
 /extras
 /gerrit-package-plugins
 /gwt-unitCache
 /infer-out
 /local.properties
-/plugins/cookbook-plugin/
+/node_modules/
+/package-lock.json
+/plugins/*
+!/plugins/BUILD
+!/plugins/codemirror-editor
+!/plugins/commit-message-length-validator
+!/plugins/delete-project
+!/plugins/download-commands
+!/plugins/external_plugin_deps.bzl
+!/plugins/gitiles
+!/plugins/hooks
+!/plugins/replication
+!/plugins/reviewnotes
+!/plugins/singleusergroup
+!/plugins/webhooks
 /test_site
 /tools/format
-/.vscode
-/.ijwb
diff --git a/.gitmodules b/.gitmodules
index 8d75bcc..010b292 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -8,11 +8,21 @@
 	url = ../plugins/commit-message-length-validator
 	branch = .
 
+[submodule "plugins/delete-project"]
+	path = plugins/delete-project
+	url = ../plugins/delete-project
+	branch = .
+
 [submodule "plugins/download-commands"]
 	path = plugins/download-commands
 	url = ../plugins/download-commands
 	branch = .
 
+[submodule "plugins/gitiles"]
+	path = plugins/gitiles
+	url = ../plugins/gitiles
+	branch = .
+
 [submodule "plugins/hooks"]
 	path = plugins/hooks
 	url = ../plugins/hooks
@@ -32,3 +42,8 @@
 	path = plugins/singleusergroup
 	url = ../plugins/singleusergroup
 	branch = .
+
+[submodule "plugins/webhooks"]
+	path = plugins/webhooks
+	url = ../plugins/webhooks
+	branch = .
diff --git a/BUILD b/BUILD
index cedc077..3989a75 100644
--- a/BUILD
+++ b/BUILD
@@ -1,10 +1,8 @@
-load(
-    "@bazel_tools//tools/jdk:default_java_toolchain.bzl",
-    "default_java_toolchain",
-)
 load("//tools/bzl:genrule2.bzl", "genrule2")
 load("//tools/bzl:pkg_war.bzl", "pkg_war")
 
+package(default_visibility = ["//visibility:public"])
+
 config_setting(
     name = "java9",
     values = {
@@ -13,44 +11,12 @@
 )
 
 config_setting(
-    name = "java10",
+    name = "java_next",
     values = {
-        "java_toolchain": ":toolchain_vanilla",
+        "java_toolchain": "@bazel_tools//tools/jdk:toolchain_vanilla",
     },
 )
 
-# TODO(davido): Switch to consuming it from @bazel_tool//tools/jdk:absolute_javabase
-# when new Bazel version is released with this change included:
-# https://github.com/bazelbuild/bazel/issues/6012
-# https://github.com/bazelbuild/bazel/commit/0173bdbf7bdd1874379d4dd3eb70d5321e0f1816
-# As the interim use a hack that works around it by putting the variable reference
-# behind a select
-config_setting(
-    name = "use_absolute_javabase",
-    values = {"define": "USE_ABSOLUTE_JAVABASE=true"},
-)
-
-java_runtime(
-    name = "absolute_javabase",
-    java_home = select({
-        "//conditions:default": "",
-        ":use_absolute_javabase": "$(ABSOLUTE_JAVABASE)",
-    }),
-    visibility = ["//visibility:public"],
-)
-
-# TODO(davido): Switch to consuming it from @bazel_tool//tools/jdk:toolchain_vanilla
-# when my change is included in released Bazel version:
-# https://github.com/bazelbuild/bazel/commit/0bef68e054eccecd690e5d9f46db8a0c4b2d887a
-default_java_toolchain(
-    name = "toolchain_vanilla",
-    forcibly_disable_header_compilation = True,
-    javabuilder = ["@bazel_tools//tools/jdk:VanillaJavaBuilder_deploy.jar"],
-    jvm_opts = [],
-)
-
-package(default_visibility = ["//visibility:public"])
-
 genrule(
     name = "gen_version",
     outs = ["version.txt"],
@@ -77,15 +43,9 @@
 )
 
 pkg_war(
-    name = "polygerrit",
-    ui = "polygerrit",
-)
-
-pkg_war(
     name = "release",
     context = ["//plugins:core"],
     doc = True,
-    ui = "ui_optdbg_r",
 )
 
 pkg_war(
@@ -103,9 +63,6 @@
     "//plugins:plugin-api_deploy.jar",
     "//plugins:plugin-api-sources_deploy.jar",
     "//plugins:plugin-api-javadoc",
-    "//gerrit-plugin-gwtui:gwtui-api_deploy.jar",
-    "//gerrit-plugin-gwtui:gwtui-api-source_deploy.jar",
-    "//gerrit-plugin-gwtui:gwtui-api-javadoc",
 ]
 
 genrule2(
diff --git a/Documentation/BUILD b/Documentation/BUILD
index 79b9e51..368e929 100644
--- a/Documentation/BUILD
+++ b/Documentation/BUILD
@@ -44,7 +44,6 @@
     name = "licenses",
     opts = ["--asciidoctor"],
     targets = [
-        "//gerrit-gwtui:ui_module",
         "//polygerrit-ui/app:polygerrit_ui",
         "//java/com/google/gerrit/pgm",
     ],
@@ -53,7 +52,6 @@
 license_map(
     name = "js_licenses",
     targets = [
-        "//gerrit-gwtui:ui_module",
         "//polygerrit-ui/app:polygerrit_ui",
     ],
 )
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 370a891..2e7cf17 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -5,6 +5,12 @@
 to those groups.  Access rights cannot be granted to individual
 users.
 
+To view/edit the access controls for a specific project, first
+navigate to the projects page: for example,
+https://gerrit-review.googlesource.com/admin/repos/ . Then click on
+the individual project, and then click Access. This will bring you
+to a url that looks like
+https://gerrit-review.googlesource.com/admin/repos/gerrit,access
 
 [[system_groups]]
 == System Groups
@@ -828,7 +834,7 @@
 [[category_view_private_changes]]
 === View Private Changes
 
-This category permits users to view all private changes.
+This category permits users to view all private changes and all change edit refs.
 
 The change owner and any explicitly added reviewers can always see
 private changes (even without having the `View Private Changes` access
@@ -1198,8 +1204,7 @@
 [[capability_accessDatabase]]
 === Access Database
 
-Allow users to access the database using the `gsql` command, and view code
-review metadata refs in repositories.
+Allow users to view code review metadata refs in repositories.
 
 
 [[capability_administrateServer]]
diff --git a/Documentation/cmd-create-project.txt b/Documentation/cmd-create-project.txt
index 026d7b1..9e3d70b 100644
--- a/Documentation/cmd-create-project.txt
+++ b/Documentation/cmd-create-project.txt
@@ -28,9 +28,8 @@
 == DESCRIPTION
 Creates a new bare Git repository under `gerrit.basePath`, using
 the project name supplied.  The newly created repository is empty
-(has no commits), but is registered in the Gerrit database so that
-the initial commit may be uploaded for review, or initial content
-can be pushed directly into a branch.
+(has no commits), and the initial content may either be uploaded for
+review, or pushed directly to a branch.
 
 If replication is enabled, this command also connects to each of
 the configured remote systems over SSH and uses command line git
@@ -119,7 +118,7 @@
 Defaults to MERGE_IF_NECESSARY unless
 link:config-gerrit.html#repository.name.defaultSubmitType[
 repository.<name>.defaultSubmitType] is set to a different value.
-For more details see link:project-configuration.html#submit_type[
+For more details see link:config-project-config.html#submit-type[
 Submit Types].
 
 --use-content-merge::
diff --git a/Documentation/cmd-flush-caches.txt b/Documentation/cmd-flush-caches.txt
index 55d9083..5a84b9d 100644
--- a/Documentation/cmd-flush-caches.txt
+++ b/Documentation/cmd-flush-caches.txt
@@ -16,7 +16,7 @@
 truth when it needs the information again.
 
 Flushing a cache may be necessary if an administrator modifies
-database records directly in the database, rather than going through
+NoteDb metadata directly in a repository, rather than going through
 the Gerrit web interface.
 
 If no options are supplied, defaults to `--all`.
diff --git a/Documentation/cmd-gsql.txt b/Documentation/cmd-gsql.txt
deleted file mode 100644
index 7f2aaf7..0000000
--- a/Documentation/cmd-gsql.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-= gerrit gsql
-
-== NAME
-gerrit gsql - Administrative interface to active database.
-
-== SYNOPSIS
-[verse]
---
-_ssh_ -p <port> <host> _gerrit gsql_
-  [--format {PRETTY | JSON | JSON_SINGLE}]
-  [-c QUERY]
---
-
-== DESCRIPTION
-Provides interactive query support directly against the underlying
-SQL database used by the host Gerrit server.  All SQL statements
-are supported, including SELECT, UPDATE, INSERT, DELETE and ALTER.
-
-== OPTIONS
---format::
-	Set the format records are output in.  In PRETTY (the
-	default) records are displayed in a tabular output suitable
-	for reading by a human on a sufficiently wide terminal.
-	In JSON mode records are output as JSON objects using the
-	column names as the property names, one object per line.
-	In JSON_SINGLE mode the whole result set is output as a
-	single JSON object.
-
--c::
-	Execute the single query statement supplied, and then exit.
-
-== ACCESS
-Caller must have been granted the
-link:access-control.html#capability_accessDatabase[Access Database]
-global capability.
-
-== SCRIPTING
-Intended for interactive use only, unless format is JSON, or
-JSON_SINGLE.
-
-== EXAMPLES
-To manually correct a user's SSH user name:
-
-----
-$ ssh -p 29418 review.example.com gerrit gsql
-Welcome to Gerrit Code Review v2.0.25
-(PostgreSQL 8.3.8)
-
-Type '\h' for help.  Type '\r' to clear the buffer.
-
-gerrit> update accounts set ssh_user_name = 'alice' where account_id=1;
-UPDATE 1; 1 ms
-gerrit> \q
-Bye
-
-$ ssh -p 29418 review.example.com gerrit flush-caches --cache sshkeys --cache accounts
-----
-
-GERRIT
-------
-Part of link:index.html[Gerrit Code Review]
-
-SEARCHBOX
----------
diff --git a/Documentation/cmd-index.txt b/Documentation/cmd-index.txt
index 25099fa..edb54b5 100644
--- a/Documentation/cmd-index.txt
+++ b/Documentation/cmd-index.txt
@@ -71,7 +71,7 @@
 	List projects visible to the caller.
 
 link:cmd-query.html[gerrit query]::
-	Query the change database.
+	Query the change search index.
 
 'gerrit receive-pack'::
 	'Deprecated alias for `git receive-pack`.'
@@ -130,9 +130,6 @@
 link:cmd-gc.html[gerrit gc]::
 	Run the Git garbage collection.
 
-link:cmd-gsql.html[gerrit gsql]::
-	Administrative interface to active database.
-
 link:cmd-index-activate.html[gerrit index activate]::
 	Activate the latest index version available.
 
diff --git a/Documentation/cmd-ls-user-refs.txt b/Documentation/cmd-ls-user-refs.txt
index cba7d1b..0363f60 100644
--- a/Documentation/cmd-ls-user-refs.txt
+++ b/Documentation/cmd-ls-user-refs.txt
@@ -32,8 +32,8 @@
 --user::
 -u::
 	Required; User for which the visible refs should be listed. Gerrit
-	will query the database to find matching users, so the
-	full identity/name does not need to be specified.
+	will query the index to find matching users, so the full
+	identity/name does not need to be specified.
 
 --only-refs-heads::
 	Only list the refs found under refs/heads/*
diff --git a/Documentation/cmd-query.txt b/Documentation/cmd-query.txt
index 79723c5..d0419d7 100644
--- a/Documentation/cmd-query.txt
+++ b/Documentation/cmd-query.txt
@@ -1,7 +1,7 @@
 = gerrit query
 
 == NAME
-gerrit query - Query the change database
+gerrit query - Query the change search index
 
 == SYNOPSIS
 [verse]
@@ -17,6 +17,7 @@
   [--submit-records]
   [--all-reviewers]
   [--start <n> | -S <n>]
+  [--no-limit]
   [--]
   <query>
   [limit:<n>]
@@ -24,7 +25,7 @@
 
 == DESCRIPTION
 
-Queries the change database and returns results describing changes
+Queries the change search index and returns results describing changes
 that match the input query.  More recently updated changes appear
 before older changes, which is the same order presented in the
 web interface.  For each matching change, the result contains data
@@ -101,6 +102,9 @@
 -S::
 	Number of changes to skip.
 
+--no-limit::
+	Return all results, overriding the default limit.
+
 limit:<n>::
 	Maximum number of results to return.  This is actually a
 	query operator, and not a command line option.	If more
diff --git a/Documentation/cmd-review.txt b/Documentation/cmd-review.txt
index 6fe24815..b15aea7 100644
--- a/Documentation/cmd-review.txt
+++ b/Documentation/cmd-review.txt
@@ -27,7 +27,7 @@
 == DESCRIPTION
 Updates the current user's approval status of the specified patch
 sets and/or submits them for merging, sending out email
-notifications and updating the database.
+notifications and updating code review metadata.
 
 Patch sets may be specified in 'CHANGEID,PATCHSET' format, such as
 '8242,2', or 'COMMIT' format.
@@ -144,7 +144,7 @@
 
 Approve the change with commit c0ff33 as "Verified +1"
 ----
-$ ssh -p 29418 review.example.com gerrit review --verified +1 c0ff33
+$ ssh -p 29418 review.example.com gerrit review --verified +1 8242,2
 ----
 
 Approve the change with change number 8242 and patch set 2 as "Code-Review +2"
diff --git a/Documentation/cmd-set-project.txt b/Documentation/cmd-set-project.txt
index 45b31ff..9686230 100644
--- a/Documentation/cmd-set-project.txt
+++ b/Documentation/cmd-set-project.txt
@@ -59,7 +59,7 @@
 
 +
 For more details see
-link:project-configuration.html#submit_type[Submit Types].
+link:config-project-config.html#submit-type[Submit Types].
 
 --content-merge::
     If enabled, Gerrit will try to perform a 3-way merge of text
diff --git a/Documentation/config-auto-site-initialization.txt b/Documentation/config-auto-site-initialization.txt
index 1be0af9..2253ed0 100644
--- a/Documentation/config-auto-site-initialization.txt
+++ b/Documentation/config-auto-site-initialization.txt
@@ -2,74 +2,41 @@
 
 == Description
 
-Gerrit supports automatic site initialization on server startup
-when Gerrit runs in a servlet container. Both creation of a new site
-and upgrade of an existing site are supported. By default, all packaged
-plugins will be installed when Gerrit is deployed in a servlet container
-and the location of the Gerrit distribution can be determined at
-runtime. It is also possible to install only a subset of packaged
-plugins or not install any plugins.
+Gerrit supports automatic site initialization on server startup when Gerrit runs
+in a servlet container. Both creation of a new site and upgrade of an existing
+site are supported. By default, all packaged plugins will be installed when
+Gerrit is deployed in a servlet container and the location of the Gerrit
+distribution can be determined at runtime. It is also possible to install only a
+subset of packaged plugins or not install any plugins.
 
-This feature may be useful for such setups where Gerrit administrators
-don't have direct access to the database and the file system of the
-server where Gerrit should be deployed and, therefore, cannot perform
-the init from their local machine prior to deploying Gerrit on such a
-server. It may also make deployment and testing in a local servlet
-container faster to set up as the init step could be skipped.
+This feature may be useful for such setups where Gerrit administrators don't
+have direct access to the file system of the server where Gerrit should be
+deployed and, therefore, cannot perform the init from their local machine prior
+to deploying Gerrit on such a server. It may also make deployment and testing in
+a local servlet container faster to set up as the init step could be skipped.
 
 == Gerrit Configuration
 
-The site initialization will be performed only if the `gerrit.init`
-system property exists. The value of the property is not used; only the
-existence of the property matters.
+In order to perform site initialization, define `gerrit.site_path` with the path
+to your site. If the site already exists, this is the only required property.
+If your site does not yet exist, set the `gerrit.init` system property to
+automatically initialize the site.
 
-If the `gerrit.site_path` system property is defined then the init is
-run for that site. The database connectivity, in that case, is defined
-in the `etc/gerrit.config`.
+During initialization, if the `gerrit.install_plugins` property is not defined,
+then all packaged plugins will be installed. If it is defined, then it is parsed
+as a comma-separated list of plugin names to install. If the value is an empty
+string then no plugins will be installed.
 
-`gerrit.site_path` system property must be defined to run the init for
-that site.
+=== Example
 
-[WARNING]
-Defining the `jdbc/ReviewDb` JNDI property for an H2 database under the
-path defined by `gerrit.site_path` will cause an incomplete auto
-initialization and Gerrit will fail to start.
-
-Opening a connection to such a database will create a subfolder under the
-site path folder (in order to create the H2 database) and Gerrit will
-no longer consider that site path to be new and, because of that,
-skip some required initialization steps (for example, Lucene index
-creation). In order to auto initialize Gerrit with an embedded H2
-database use the `gerrit.site_path` to define the location of the review
-site and don't define a JNDI resource with a URL under that path.
-
-If the `gerrit.install_plugins` property is not defined then all packaged
-plugins will be installed. If it is defined then it is parsed as a
-comma-separated list of plugin names to install. If the value is an
-empty string then no plugin will be installed.
-
-=== Example 1
-
-Prepare Tomcat so that a site is initialized at a given path using
-the H2 database (if the site doesn't exist yet) or using whatever
-database is defined in `etc/gerrit.config` of that site:
+Prepare Tomcat so that a site is initialized at a given path (if the site
+doesn't exist yet), installing all packaged plugins.
 
 ----
   $ export CATALINA_OPTS='-Dgerrit.init -Dgerrit.site_path=/path/to/site'
   $ catalina.sh start
 ----
 
-=== Example 2
-
-Assuming the database schema doesn't exist in the database defined
-via the `jdbc/ReviewDb` JNDI property, initialize a new site using that
-database and a given path:
-
-----
-  $ export CATALINA_OPTS='-Dgerrit.init -Dgerrit.init_path=/path/to/site'
-  $ catalina.sh start
-----
-
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-cla.txt b/Documentation/config-cla.txt
index 2234808..2c7b194 100644
--- a/Documentation/config-cla.txt
+++ b/Documentation/config-cla.txt
@@ -25,13 +25,15 @@
 ----
 
 Contributor agreements are defined as contributor-agreement sections in
-`project.config`:
+`project.config` of `All-Projects`:
 ----
   [contributor-agreement "Individual"]
     description = If you are going to be contributing code on your own, this is the one you want. You can sign this one online.
     agreementUrl = static/cla_individual.html
     autoVerify = group CLA Accepted - Individual
     accepted = group CLA Accepted - Individual
+    matchProjects = ^/.*$
+    excludeProjects = ^/not/my/project/
 ----
 
 Each `contributor-agreement` section within the `project.config` file must
@@ -75,6 +77,16 @@
 contributor agreement has been accepted. The groups' UUID must also
 appear in the `groups` file.
 
+[[contributor-agreement.name.matchProjects]]contributor-agreement.<name>.matchProjects::
++
+List of project regular expressions identifying projects where the
+agreement is required. Defaults to every project when omitted.
+
+[[contributor-agreement.name.excludeProjects]]contributor-agreement.<name>.excludeProjects::
++
+List of project regular expressions identifying projects where the
+agreement does not apply. Defaults to empty. i.e. no projects excluded.
+
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 7a458f9..c0f195d 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -32,7 +32,7 @@
 === Section accountPatchReviewDb
 
 The AccountPatchReviewDb is a database used to store the user file reviewed
-flags. It co-exists with <<database,ReviewDb>> and link:note-db.html[NoteDb].
+flags.
 
 [[accountPatchReviewDb.url]]accountPatchReviewDb.url::
 +
@@ -46,8 +46,8 @@
 link:pgm-MigrateAccountPatchReviewDb.html[MigrateAccountPatchReviewDb] program.
 Migration cannot be done while the server is running.
 +
-Also note that the db_name has to be a new db and not reusing gerrit's own review database,
-otherwise gerrit's init will remove the table.
+Also note that the db_name has to be a new db and not reusing an old ReviewDb
+database from a former 2.x site, otherwise gerrit's init will remove the table.
 
 ----
 [accountPatchReviewDb]
@@ -273,10 +273,7 @@
 `Become` appears in the top right corner of the page, taking the
 user to a form where they can enter the username of any existing
 user account, and immediately login as that account, without any
-authentication taking place.  This form of authentication is only
-useful for the GWT hosted mode shell, where OpenID authentication
-redirects might be risky to the developer's host computer, and HTTP
-authentication is not possible.
+authentication taking place.
 
 +
 By default, OpenID.
@@ -485,13 +482,12 @@
 +
 When `auth.type` does not normally enable this URL administrators may
 set this to `login/`, allowing users to begin a new web session. This value
-is used as an href in PolyGerrit and the GWT UI, so absolute URLs like
+is used as an href in PolyGerrit, so absolute URLs like
 `https://someotherhost/login` work as well.
 +
 If a ${path} parameter is included, then PolyGerrit will substitute the
 currently viewed path in the link. Be aware that this path will include
 a leading slash, so a value like this might be appropriate: `/login${path}`.
-Note: in the GWT UI this substitution for ${path} is *always* `/`.
 
 [[auth.cookiePath]]auth.cookiePath::
 +
@@ -697,7 +693,9 @@
 allows to limit the memory used by H2 and thus prevent out-of-memory
 caused by the H2 database using too much memory.
 +
-See <<database.h2.cacheSize,database.h2.cacheSize>> for a detailed discussion.
+Technically the H2 cache size is configured using the CACHE_SIZE parameter in
+the H2 JDBC connection URL, as described
+link:http://www.h2database.com/html/features.html#cache_settings[here]
 +
 Default is unset, using up to half of the available memory.
 +
@@ -807,11 +805,10 @@
 +
 Cache entries contain important details of an active user, including
 their display name, preferences, and known email addresses. Entry
-information is obtained from the `accounts` database table.
+information is obtained from NoteDb data in the `All-Users` repo.
 
 +
-If direct updates are made to any of these database tables, this
-cache should be flushed.
+If direct updates are made to `All-Users`, this cache should be flushed.
 
 cache `"adv_bases"`::
 +
@@ -982,6 +979,11 @@
 Caches parsed `rules.pl` contents for each project. This cache uses the same
 size as the `projects` cache, and cannot be configured independently.
 
+cache `"pure_revert"`::
++
+Result of checking if one change or commit is a pure/clean revert of
+another.
+
 cache `"sshkeys"`::
 +
 Caches unpacked versions of user SSH keys, so the internal SSH daemon
@@ -1175,8 +1177,7 @@
 
 [[change.allowBlame]]change.allowBlame::
 +
-Allow blame on side by side diff in the GWT UI. If set to false, blame cannot be
-used.
+Allow blame on side by side diff. If set to false, blame cannot be used.
 +
 Default is true.
 
@@ -1218,6 +1219,15 @@
 +
 Default is true.
 
+[[change.api.excludeMergeableInChangeInfo]]change.api.excludeMergeableInChangeInfo::
++
+If true, the mergeability bit in
+link:rest-api-changes.html#change-info[ChangeInfo] will never be set. It can
+be requested separately through the
+link:rest-api-changes.html#get-mergeable[get-mergeable] endpoint.
++
+Default is false.
+
 [[change.showAssigneeInChangesTable]]change.showAssigneeInChangesTable::
 +
 Show assignee field in changes table. If set to false, assignees will
@@ -1433,13 +1443,10 @@
 example, to match the string `bug` in a case insensitive way the match
 pattern `[bB][uU][gG]` needs to be used.
 +
-Between the GWT UI and PolyGerrit, the commentlink.name.match regular
-expressions are applied differently. Whereas in the GWT UI the
-expressions are applied to the formatted and escaped HTML result, the
-PolyGerrit UI applies them only to the raw, unformatted and unescaped
-text form. PolyGerrit does not support regex matching against HTML.
-Comment link patterns that are written in this style should be updated
-to match text formats.
+The commentlink.name.match regular expressions are applied to the raw,
+unformatted and unescaped text form. Regex matching against HTML is not
+supported. Comment link patterns that are written in this style should
+be updated to match text formats.
 +
 A common pattern to match is `bug\\s+(\\d+)`.
 
@@ -1685,215 +1692,6 @@
 +
 Default is 1 hour.
 
-[[database]]
-=== Section database
-
-The database section configures ReviewDb, where Gerrit stores its metadata
-records about account groups and change reviews. Starting from 2.15, accounts
-are always stored in NoteDb and, optionally, changes too. See the
-link:note-db.html[NoteDb documentation] for more information.
-
-Note that user file reviewed flags are stored in a separate database. See the
-<<accountPatchReviewDb,accountPatchReviewDb>> section for more information.
-
-----
-[database]
-  type = POSTGRESQL
-  hostname = localhost
-  database = reviewdb
-  username = gerrit
-  password = s3kr3t
-----
-
-[[database.type]]database.type::
-+
-Type of database server to connect to.  If set this value will be
-used to automatically create correct database.driver and database.url
-values to open the connection.
-+
-* `DB2`
-+
-Connect to a DB2 database server.
-+
-* `DERBY`
-+
-Connect to an Apache Derby database server.
-+
-* `H2`
-+
-Connect to a local embedded H2 database.
-+
-* `JDBC`
-+
-Connect using a JDBC driver class name and URL.
-+
-* `MAXDB`
-+
-Connect to an SAP MaxDB database server.
-+
-* `MYSQL`
-+
-Connect to a MySQL database server.
-+
-* `MARIADB`
-+
-Connect to a MariaDB database server.
-+
-* `ORACLE`
-+
-Connect to an Oracle database server.
-+
-* `POSTGRESQL`
-+
-Connect to a PostgreSQL database server.
-
-+
-If not specified, database.driver and database.url are used as-is,
-and if they are also not specified, defaults to H2.
-
-[[database.hostname]]database.hostname::
-+
-Hostname of the database server.  Defaults to 'localhost'.
-
-[[database.port]]database.port::
-+
-Port number of the database server.  Defaults to the default port
-of the server named by database.type.
-
-[[database.database]]database.database::
-+
-For POSTGRESQL or MYSQL, the name of the database on the server.
-+
-For H2, this is the path to the database, and if not absolute is
-relative to `'$site_path'`.
-
-[[database.username]]database.username::
-+
-Username to connect to the database server as.
-
-[[database.password]]database.password::
-+
-Password to authenticate to the database server with.
-
-[[database.driver]]database.driver::
-+
-Name of the JDBC driver class to connect to the database with.
-Setting this usually isn't necessary as it can be derived from
-database.type or database.url for any supported database.
-
-[[database.url]]database.url::
-+
-'jdbc:' URL for the database.  Setting this variable usually
-isn't necessary as it can be constructed from the all of the
-above properties.
-
-[[database.connectionPool]]database.connectionPool::
-+
-If true, use connection pooling for database connections. Otherwise, a
-new database connection is opened for each request.
-+
-Default is false for MySQL, and true for other database backends.
-
-[[database.poolLimit]]database.poolLimit::
-+
-Maximum number of open database connections.  If the server needs
-more than this number, request processing threads will wait up
-to <<database.poolMaxWait, poolMaxWait>> seconds for a
-connection to be released before they abort with an exception.
-This limit must be several units higher than the total number of
-httpd and sshd threads as some request processing code paths may
-need multiple connections.
-+
-Default is <<sshd.threads, sshd.threads>>
- + <<httpd.maxThreads, httpd.maxThreads>> + 2.
-+
-This setting only applies if
-<<database.connectionPool,database.connectionPool>> is true.
-
-[[database.poolMinIdle]]database.poolMinIdle::
-+
-Minimum number of connections to keep idle in the pool.
-Default is 4.
-+
-This setting only applies if
-<<database.connectionPool,database.connectionPool>> is true.
-
-[[database.poolMaxIdle]]database.poolMaxIdle::
-+
-Maximum number of connections to keep idle in the pool.  If there
-are more idle connections, connections will be closed instead of
-being returned back to the pool.
-Default is min(<<database.poolLimit, database.poolLimit>>, 16).
-+
-This setting only applies if
-<<database.connectionPool,database.connectionPool>> is true.
-
-[[database.poolMaxWait]]database.poolMaxWait::
-+
-Maximum amount of time a request processing thread will wait to
-acquire a database connection from the pool.  If no connection is
-released within this time period, the processing thread will abort
-its current operations and return an error to the client.
-Values should use common unit suffixes to express their setting:
-+
-* ms, milliseconds
-* s, sec, second, seconds
-* m, min, minute, minutes
-* h, hr, hour, hours
-
-+
---
-If a unit suffix is not specified, `milliseconds` is assumed.
-
-Default is `30 seconds`.
-
-This setting only applies if
-<<database.connectionPool,database.connectionPool>> is true.
---
-
-[[database.dataSourceInterceptorClass]]database.dataSourceInterceptorClass::
-
-Class that implements DataSourceInterceptor interface to monitor SQL activity.
-This class must have default constructor and be available on Gerrit's bootstrap
-classpath, e. g. in `$gerrit_site/lib` directory. Example implementation of
-SQL monitoring can be found in javamelody-plugin.
-
-[[database.h2]]database.h2::
-+
-The settings in this section are used for the reviewdb if the
-<<database.type,database.type>> is H2.
-+
-Additionally gerrit uses H2 for storing reviewed flags on changes.
-
-[[database.h2.cacheSize]]database.h2.cacheSize::
-+
-The size of the H2 internal database cache, in bytes. The H2 internal cache for
-persistent H2-backed caches is controlled by
-<<cache.h2CacheSize,cache.h2CacheSize>>.
-+
-H2 uses memory to cache its database content. The parameter `cacheSize`
-allows to limit the memory used by H2 and thus prevent out-of-memory
-caused by the H2 database using too much memory.
-+
-Technically the H2 cache size is configured using the CACHE_SIZE parameter in
-the H2 JDBC connection URL, as described
-link:http://www.h2database.com/html/features.html#cache_settings[here]
-+
-Default is unset, using up to half of the available memory.
-+
-H2 will persist this value in the database, so to unset explicitly specify 0.
-+
-Common unit suffixes of 'k', 'm', or 'g' are supported.
-
-[[database.h2.autoServer]]database.h2.autoServer::
-+
-If `true` enable the automatic mixed mode
-(see link:http://www.h2database.com/html/features.html#auto_mixed_mode[Automatic Mixed Mode]).
-This enables concurrent access to the embedded H2 database from command line
-utils (e.g. MigrateToNoteDb).
-+
-Default is `false`.
-
 [[download]]
 === Section download
 
@@ -2222,11 +2020,16 @@
 +
 Defaults to "Report Bug".
 
-[[gerrit.disableReverseDnsLookup]]gerrit.disableReverseDnsLookup::
+[[gerrit.enableReverseDnsLookup]]gerrit.enableReverseDnsLookup::
 +
-Disables reverse DNS lookup during computing ref log entry for identified user.
+Enable reverse DNS lookup during computing ref log entry for identified user,
+to record the actual hostname of the user's host in the ref log.
 +
-Defaults to false.
+Enabling reverse DNS lookup can cause performance issues on git push when
+the reverse DNS lookup is slow.
++
+Defaults to false, reverse DNS lookup is disabled. The user's IP address
+will be recorded in the ref log rather than their hostname.
 
 [[gerrit.secureStoreClass]]gerrit.secureStoreClass::
 +
@@ -2866,8 +2669,7 @@
 +
 Maximum number of leaf terms to allow in a query. Too-large queries may
 perform poorly, so setting this option causes query parsing to fail fast
-before attempting to send them to the secondary index. Should this limit
-be reached, database is used instead of index as applicable.
+before attempting to send them to the secondary index.
 +
 When the index type is `LUCENE`, also sets the maximum number of clauses
 permitted per BooleanQuery. This is so that all enforced query limits
@@ -3562,9 +3364,9 @@
 [[note-db]]
 === Section noteDb
 
-NoteDb is the next generation of Gerrit storage backend, currently powering
-`googlesource.com`. For more information, including how to migrate your data,
-see the link:note-db.html[documentation].
+NoteDb is the Git-based database storage backend for Gerrit. For more
+information, including how to migrate data from an older Gerrit version, see the
+link:note-db.html[documentation].
 
 [[notedb.accounts.sequenceBatchSize]]notedb.accounts.sequenceBatchSize::
 +
@@ -3917,9 +3719,9 @@
 are `INHERIT`, `MERGE_IF_NECESSARY`, `FAST_FORWARD_ONLY`, `REBASE_IF_NECESSARY`,
 `REBASE_ALWAYS`, `MERGE_ALWAYS` and `CHERRY_PICK`.
 +
-For more details see link:project-configuration.html#submit_type[Submit Types].
+For more details see link:config-project-config.html#submit-type[Submit Types].
 +
-Default is link:project-configuration.html#submit_type_inherit[`INHERIT`].
+Default is link:config-project-config.html#submit_type_inherit[`INHERIT`].
 +
 This submit type is only applied at project creation time if a submit type is
 omitted from the link:rest-api-projects.html#project-input[ProjectInput]. If the
@@ -4710,103 +4512,6 @@
 +
 By default 0.
 
-[[theme]]
-=== Section theme
-
-[[theme.backgroundColor]]theme.backgroundColor::
-+
-_(GWT UI only)_ Background color for the page, and major data tables like the all
-open changes table or the account dashboard. The value must be a
-valid HTML hex color code, or standard color name.
-+
-By default white, `FFFFFF`.
-
-[[theme.topMenuColor]]theme.topMenuColor::
-+
-_(GWT UI only)_ This is the color of the main menu bar at the top of the page.
-The value must be a valid HTML hex color code, or standard color
-name.
-+
-By default white, `FFFFFF`.
-
-[[theme.textColor]]theme.textColor::
-+
-_(GWT UI only)_ Text color for the page, and major data tables like the all open
-changes table or the account dashboard. The value must be a valid HTML hex color
-code, or standard color name.
-+
-By default dark grey, `353535`.
-
-[[theme.trimColor]]theme.trimColor::
-+
-_(GWT UI only)_ Primary color used as a background color behind text.  This is
-the color of the main menu bar at the top, of table headers, and of major UI
-areas that we want to offset from other portions of the page.  The value must be
-a valid HTML hex color code, or standard color name.
-+
-By default a light grey, `EEEEEE`.
-
-[[theme.selectionColor]]theme.selectionColor::
-+
-_(GWT UI only)_ Background color used within a trimColor area to denote the
-currently selected tab, or the background color used in a table to denote the
-currently selected row.  The value must be a valid HTML hex color code, or
-standard color name.
-+
-By default a pale blue, `D8EDF9`.
-
-[[theme.changeTableOutdatedColor]]theme.changeTableOutdatedColor::
-+
-_(GWT UI only)_ Background color used for patch outdated messages.  The value
-must be a valid HTML hex color code, or standard color name.
-+
-By default a shade of red, `F08080`.
-
-[[theme.tableOddRowColor]]theme.tableOddRowColor::
-+
-_(GWT UI only)_ Background color for tables such as lists of open reviews for
-odd rows.  This is so you can have a different color for odd and even rows of
-the table.  The value must be a valid HTML hex color code, or standard color
-name.
-+
-By default transparent.
-
-[[theme.tableEvenRowColor]]theme.tableEvenRowColor::
-+
-_(GWT UI only)_ Background color for tables such as lists of open reviews for
-even rows.  This is so you can have a different color for odd and even rows of
-the table.  The value must be a valid HTML hex color code, or standard color
-name.
-+
-By default transparent.
-
-A different theme may be used for signed-in vs. signed-out user status
-by using the "signed-in" and "signed-out" theme sections. Variables
-not specified in a section are inherited from the default theme.
-
-----
-[theme]
-  backgroundColor = FFFFFF
-[theme "signed-in"]
-  backgroundColor = C0C0C0
-[theme "signed-out"]
-  backgroundColor = 00FFFF
-----
-
-As example, here is the theme configuration to have the old green look:
-
-----
-[theme]
-  backgroundColor = FCFEEF
-  textColor = 000000
-  trimColor = D4E9A9
-  selectionColor = FFFFCC
-  topMenuColor = D4E9A9
-  changeTableOutdatedColor = F08080
-[theme "signed-in"]
-  backgroundColor = FFFFFF
-----
-
 [[trackingid]]
 === Section trackingid
 
@@ -5112,6 +4817,38 @@
 Assuming that the server is started on `Mon 07:00` then this yields the
 first run on Tuesday at 06:00 and a repetition interval of 1 day.
 
+[[All-Projects-project.config]]
+== File `etc/All-Projects/project.config`
+
+The optional file `'$site_path'/etc/All-Projects/project.config` provides
+defaults for configuration read from
+link:config-project-config.html[`project.config`] in the
+`All-Projects` repo. Unlike `gerrit.config`, this file contains project-type
+configuration rather than server-type configuration.
+
+Most administrators will not need this file, and should instead make commits to
+`All-Projects` to modify global config. However, a separate file can be useful
+when managing multiple Gerrit servers, since pushing changes to defaults using
+Puppet or a similar tool can be easier than scripting git updates to
+`All-Projects`.
+
+The contents of the file are loaded each time the `All-Projects` project is
+reloaded. Updating the file requires either evicting the project cache or
+restarting the server.
+
+Caveats:
+
+* The path from which the file is read corresponds to the name of the repo,
+  which is link:#gerrit.allProjects[configurable].
+* Although the file lives in a directory that shares a name with a repository,
+  this directory is not a Git repository.
+* Only the file `project.config` is read from this directory to provide
+  defaults; any other files in this directory, such as `rules.pl`, are ignored.
+  (This behavior may change in the future.)
+* Group names listed in the access config in this file are resolved to UUIDs
+  using the `groups` file in the repository, not in the config directory. As a
+  result, setting ACLs in this file is not recommended.
+
 [[secure.config]]
 == File `etc/secure.config`
 
@@ -5151,11 +4888,6 @@
 
 The format is one Base-64 encoded public key per line.
 
-
-== Configuring the Polygerrit UI
-
-Please see link:dev-polygerrit.html[UI] on configuring the Polygerrit UI.
-
 === Configurable Parameters
 
 site_path::
diff --git a/Documentation/config-plugins.txt b/Documentation/config-plugins.txt
index 190d003..81c9927 100644
--- a/Documentation/config-plugins.txt
+++ b/Documentation/config-plugins.txt
@@ -9,6 +9,10 @@
 link:config-gerrit.html#plugins.checkFrequency[a few minutes] until
 the server picks up new and updated plugins.
 
+Due to caching, you might need to flush your browser cache after
+installing a plugin. Users will usually see the result within
+several minutes.
+
 Plugins can also be installed via
 link:rest-api-plugins.html#install-plugin[REST] and
 link:cmd-plugin-install.html[SSH].
@@ -61,6 +65,18 @@
 link:https://gerrit.googlesource.com/plugins/commit-message-length-validator/+doc/master/src/main/resources/Documentation/config.md[
 Configuration]
 
+[[delete-project]]
+=== delete-project
+
+Provides the ability to delete a project.
+
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/delete-project[
+Project] |
+link:https://gerrit.googlesource.com/plugins/delete-project/+doc/master/src/main/resources/Documentation/about.md[
+Documentation] |
+link:https://gerrit.googlesource.com/plugins/delete-project/+doc/master/src/main/resources/Documentation/config.md[
+Configuration]
+
 [[download-commands]]
 === download-commands
 
@@ -74,6 +90,14 @@
 link:https://gerrit.googlesource.com/plugins/download-commands/+doc/master/src/main/resources/Documentation/config.md[
 Configuration]
 
+[[gitiles]]
+=== gitiles
+
+Plugin running Gitiles alongside a Gerrit server.
+
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/gitiles[
+Project]
+
 [[hooks]]
 === hooks
 
@@ -189,8 +213,7 @@
 
 This plugin allows the rendering of Git repository branch network in a
 graphical HTML5 Canvas. It is mainly intended to be used as a
-"project link" in a gitweb configuration or by other Gerrit GWT UI
-plugins to be plugged elsewhere in Gerrit.
+"project link" in a gitweb configuration.
 
 link:https://gerrit-review.googlesource.com/admin/repos/plugins/branch-network[
 Project] |
@@ -211,15 +234,16 @@
 link:https://gerrit.googlesource.com/plugins/changemessage/+doc/master/src/main/resources/Documentation/config.md[
 Configuration]
 
-[[delete-project]]
-=== delete-project
+[[checks]]
+=== checks
 
-Provides the ability to delete a project.
+The checks plugin provides a REST API and UI extensions for integrating
+CI systems with Gerrit.
 
-link:https://gerrit-review.googlesource.com/admin/repos/plugins/delete-project[
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/checks[
 Project] |
-link:https://gerrit.googlesource.com/plugins/delete-project/+doc/master/src/main/resources/Documentation/about.md[
-Documentation]
+link:https://gerrit.googlesource.com/plugins/checks/+doc/master/src/main/resources/Documentation/about.md[
+Plugin Documentation]]
 
 [[egit]]
 === egit
@@ -247,6 +271,17 @@
 link:https://gerrit.googlesource.com/plugins/emoticons/+doc/master/src/main/resources/Documentation/config.md[
 Configuration]
 
+[[find-owners]]
+=== find-owners
+This plugin provides (1) a change review action button `[FIND OWNERS]`
+that shows owners of changed files to be included as code reviewers, and
+(2) Prolog predicates to make sure that a CL is submittable
+only with owner Code-Review +1 votes.
+
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/find-owners[Project] |
+link:https://gerrit.googlesource.com/plugins/find-owners/+doc/master/src/main/resources/Documentation/about.md[Documentation] |
+link:https://gerrit.googlesource.com/plugins/find-owners/+doc/master/src/main/resources/Documentation/config.md[Configuration]
+
 [[gitblit]]
 === gitblit
 
@@ -263,14 +298,6 @@
 link:https://gerrit-review.googlesource.com/admin/repos/plugins/github[
 Project]
 
-[[gitiles]]
-=== gitiles
-
-Plugin running Gitiles alongside a Gerrit server.
-
-link:https://gerrit-review.googlesource.com/admin/repos/plugins/gitiles[
-Project]
-
 [[healthcheck]]
 === healthcheck
 
@@ -489,13 +516,21 @@
 [[oauth-authentication-provider]]
 === OAuth authentication provider
 This plugin enables Gerrit to use OAuth2 protocol for authentication.
-Two different OAuth providers are supported:
+Several OAuth2 providers are supported:
 
+* AirVantage
+* Bitbucket
+* CAS
+* CoreOS Dex
+* Facebook
 * GitHub
+* GitLab
 * Google
+* Keycloak
+* Office365
 
-https://github.com/davido/gerrit-oauth-provider[Project] |
-https://github.com/davido/gerrit-oauth-provider/wiki/Getting-Started[Configuration]
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/oauth[Project] |
+link:https://gerrit.googlesource.com/plugins/oauth/+doc/master/src/main/resources/Documentation/config.md[Configuration]
 
 [[owners]]
 === owners
@@ -633,6 +668,13 @@
 link:https://gerrit.googlesource.com/plugins/scripting/groovy-provider/+doc/master/src/main/resources/Documentation/about.md[
 Documentation]
 
+[[saml-authentication-provider]]
+=== SAML2 authentication provider
+
+This plugin enables Gerrit to use SAML2 protocol for authentication.
+
+link:https://gerrit-review.googlesource.com/admin/repos/plugins/saml[Project]
+
 [[scala-provider]]
 === scripting/scala-provider
 
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index 4456484..8962632 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -96,7 +96,41 @@
 
 These are the keys:
 
-- Description
+[[description]]description::
++
+A description for the project.
+
+[[state]]state:
++
+This setting defines the state of the project. A project can have the
+following states:
+
+- `Active`:
++
+The project is active and users can see and modify the project according
+to their access rights on the project.
+
+- `Read Only`:
++
+The project is read only and all modifying operations on it are
+disabled. E.g. this means that pushing to this project fails for all
+users even if they have push permissions assigned on it.
++
+Setting a project to this state is an easy way to temporary close a
+project, as you can keep all write access rights in place and they will
+become active again as soon as the project state is set back to
+`Active`.
++
+This state also makes sense if a project was moved to another location.
+In this case all new development should happen in the new project and
+you want to prevent that somebody accidentally works on the old
+project, while keeping the old project around for old references.
+
+- `Hidden`:
++
+The project is hidden and only visible to project owners. Other users
+are not able to see the project even if they have read permissions
+granted on the project.
 
 
 [[receive-section]]
@@ -125,11 +159,27 @@
 
 [[receive.requireChangeId]]receive.requireChangeId::
 +
-Controls whether or not the Change-Id must be included in the commit message
-in the last paragraph. Default is `INHERIT`, which means that this property
-is inherited from the parent project. The global default for new hosts
-is `true`
-+
+The `Require Change-Id in commit message` option defines whether a
+link:user-changeid.html[Change-Id] in the commit message is required
+for pushing a commit for review. If this option is set, trying to push
+a commit for review that doesn't contain a Change-Id in the commit
+message fails with link:error-missing-changeid.html[missing Change-Id
+in commit message footer].
+
+It is recommended to set this option and use a
+link:user-changeid.html#create[commit-msg hook] (or other client side
+tooling like EGit) to automatically generate Change-Id's for new
+commits. This way the Change-Id is automatically in place when changes
+are reworked or rebased and uploading new patch sets gets easy.
+
+If this option is not set, commits can be uploaded without a Change-Id,
+but then users have to remember to copy the assigned Change-Id from the
+change screen and insert it manually into the commit message when they
+want to upload a second patch set.
+
+Default is `INHERIT`, which means that this property is inherited from
+the parent project. The global default for new hosts is `true`
+
 This option is deprecated and future releases will behave as if this
 is always `true`.
 
@@ -210,6 +260,25 @@
 Default is `INHERIT`, which means that this property is inherited from
 the parent project.
 
+[[receive.createNewChangeForAllNotInTarget]]receive.createNewChangeForAllNotInTarget::
++
+The `create-new-change-for-all-not-in-target` option provides a
+convenience for selecting link:user-upload.html#base[the merge base]
+by setting it automatically to the target branch's tip so you can
+create new changes for all commits not in the target branch.
+
+This option is disabled if the tip of the push is a merge commit.
+
+This option also only works if there are no merge commits in the
+commit chain, in such cases it fails warning the user that such
+pushes can only be performed by manually specifying
+link:user-upload.html#base[bases]
+
+This option is useful if you want to push a change to your personal
+branch first and for review to another branch for example. Or in cases
+where a commit is already merged into a branch and you want to create
+a new open change for that commit on another branch.
+
 [[change-section]]
 === Change section
 
@@ -250,7 +319,7 @@
 - 'mergeContent': Defines whether to automatically merge changes.  Valid values
 are 'true', 'false', or 'INHERIT'.  Default is 'INHERIT'.
 
-- 'action': defines the link:project-configuration.html#submit_type[submit type].  Valid
+- 'action': defines the #submit-type[submit type].  Valid
 values are 'fast forward only', 'merge if necessary', 'rebase if necessary',
 'merge always' and 'cherry pick'.  The default is 'merge if necessary'.
 
@@ -410,3 +479,95 @@
 
 SEARCHBOX
 ---------
+
+[[submit-type]]
+=== Submit Type
+
+The method Gerrit uses to submit a change to a project can be
+modified by any project owner through the project console, `Projects` >
+`List` > my/project. In general, a submitted change is only merged if all
+its dependencies are also submitted, with exceptions documented below.
+The following submit types are supported:
+
+[[submit_type_inherit]]
+* Inherit
++
+This is the default for new projects, unless overridden by a global
+link:config-gerrit.html#repository.name.defaultSubmitType[`defaultSubmitType` option].
++
+Inherit the submit type from the parent project. In `All-Projects`, this
+is equivalent to link:#merge_if_necessary[Merge If Necessary].
+
+[[fast_forward_only]]
+* Fast Forward Only
++
+With this method no merge commits are produced. All merges must
+be handled on the client, prior to uploading to Gerrit for review.
++
+To submit a change, the change must be a strict superset of the
+destination branch.  That is, the change must already contain the
+tip of the destination branch at submit time.
+
+[[merge_if_necessary]]
+* Merge If Necessary
++
+If the change being submitted is a strict superset of the destination
+branch, then the branch is fast-forwarded to the change.  If not,
+then a merge commit is automatically created.  This is identical
+to the classical `git merge` behavior, or `git merge --ff`.
+
+[[always_merge]]
+* Always Merge
++
+Always produce a merge commit, even if the change is a strict
+superset of the destination branch.  This is identical to the
+behavior of `git merge --no-ff`, and may be useful if the
+project needs to follow submits with `git log --first-parent`.
+
+[[cherry_pick]]
+* Cherry Pick
++
+Always cherry pick the patch set, ignoring the parent lineage
+and instead creating a brand new commit on top of the current
+branch head.
++
+When cherry picking a change, Gerrit automatically appends onto the
+end of the commit message a short summary of the change's approvals,
+and a URL link back to the change on the web.  The committer header
+is also set to the submitter, while the author header retains the
+original patch set author.
++
+Note that Gerrit ignores dependencies between changes when using this
+submit type unless
+link:config-gerrit.html#change.submitWholeTopic[`change.submitWholeTopic`]
+is enabled and depending changes share the same topic. So generally
+submitters must remember to submit changes in the right order when using this
+submit type. If all you want is extra information in the commit message,
+consider using the Rebase Always submit strategy.
+
+[[rebase_if_necessary]]
+* Rebase If Necessary
++
+If the change being submitted is a strict superset of the destination
+branch, then the branch is fast-forwarded to the change.  If not,
+then the change is automatically rebased and then the branch is
+fast-forwarded to the change.
+
+When Gerrit tries to do a merge, by default the merge will only
+succeed if there is no path conflict.  A path conflict occurs when
+the same file has also been changed on the other side of the merge.
+
+[[rebase_always]]
+* Rebase Always
++
+Basically, the same as Rebase If Necessary, but it creates a new patchset even
+if fast forward is possible AND like Cherry Pick it ensures footers such as
+Change-Id, Reviewed-On, and others are present in resulting commit that is
+merged.
+
+Thus, Rebase Always can be considered similar to Cherry Pick, but with
+the important distinction that Rebase Always does not ignore dependencies.
+
+[[content_merge]]
+If `Allow content merges` is enabled, Gerrit will try
+to do a content merge when a path conflict occurs.
diff --git a/Documentation/config-robot-comments.txt b/Documentation/config-robot-comments.txt
index cf5de10..0077697 100644
--- a/Documentation/config-robot-comments.txt
+++ b/Documentation/config-robot-comments.txt
@@ -36,7 +36,6 @@
 
 == Limitations
 
-* Robot comments are only supported with NoteDb, but not with ReviewDb.
 * Robot comments are not displayed in the web UI yet.
 * There is no support for draft robot comments, but robot comments are
   always published and visible to everyone who can see the change.
diff --git a/Documentation/config-themes.txt b/Documentation/config-themes.txt
index dcfd711..a83c747 100644
--- a/Documentation/config-themes.txt
+++ b/Documentation/config-themes.txt
@@ -4,34 +4,28 @@
 the browser, allowing organizations to alter the look and
 feel of the application to fit with their general scheme.
 
-Configuration can either be sitewide or per-project. Projects without a
-specified theme inherit from their parents, or from the sitewide theme
-for `All-Projects`.
+== HTML Header/Footer and CSS
 
-Sitewide themes are stored in `'$site_path'/etc`, and per-project
-themes are stored in `'$site_path'/themes/{project-name}`. Files are
-only served from a single theme directory; if you want to modify or
-extend an inherited theme, you must copy it into the appropriate
-per-project directory.
-
-== HTML Header/Footer
+The HTML header, footer and CSS may be customized for login
+screens (LDAP, OAuth, OpenId) and the internally managed
+Gitweb servlet.
 
 At startup Gerrit reads the following files (if they exist) and
 uses them to customize the HTML page it sends to clients:
 
-* `<theme-dir>/GerritSiteHeader.html`
+* `etc/GerritSiteHeader.html`
 +
 HTML is inserted below the menu bar, but above any page content.
 This is a good location for an organizational logo, or links to
 other systems like bug tracking.
 
-* `<theme-dir>/GerritSiteFooter.html`
+* `etc/GerritSiteFooter.html`
 +
 HTML is inserted at the bottom of the page, below all other content,
 but just above the footer rule and the "Powered by Gerrit Code
 Review (v....)" message shown at the extreme bottom.
 
-* `<theme-dir>/GerritSite.css`
+* `etc/GerritSite.css`
 +
 The CSS rules are inlined into the top of the HTML page, inside
 of a `<style>` tag.  These rules can be used to support styling
@@ -129,9 +123,7 @@
 
 The `window.onload` callback is necessary to ensure that the
 `Gerrit.on()` function has actually been defined by the
-page.  Because GWT loads the module asynchronously any `<script>`
-block in the header or footer will execute before Gerrit has defined
-the function and is ready to register the hook callback.
+page.
 
 GERRIT
 ------
diff --git a/Documentation/database-setup.txt b/Documentation/database-setup.txt
deleted file mode 100644
index de4fb20..0000000
--- a/Documentation/database-setup.txt
+++ /dev/null
@@ -1,280 +0,0 @@
-[[createdb]]
-== Database Setup
-
-During the init phase of Gerrit you will need to specify which database to use.
-
-[[createdb_h2]]
-=== H2
-
-If you choose H2, Gerrit will automatically set up the embedded H2 database as
-backend so no set up or configuration is necessary.
-
-Using the embedded H2 database is the easiest way to get a Gerrit
-site up and running, making it ideal for proof of concepts or small team
-servers.  On the flip side, H2 is not the recommended option for large
-corporate installations when using ReviewDb. This is because there is no easy way to interact
-with the database while Gerrit is offline, it's not easy to backup the data,
-and it's not possible to set up H2 in a load balanced/hotswap configuration.
-
-If this option interests you, you might want to consider
-link:linux-quickstart.html[the quick guide].
-
-[[createdb_derby]]
-=== Apache Derby
-
-If Derby is selected, Gerrit will automatically set up the embedded Derby
-database as backend so no set up or configuration is necessary.
-
-Currently only support for embedded mode is added. There are two other
-deployment options for Apache Derby that can be added later:
-
-* link:http://db.apache.org/derby/papers/DerbyTut/ns_intro.html#Network+Server+Options[
-Derby Network Server (standalone mode)]
-
-* link:http://db.apache.org/derby/papers/DerbyTut/ns_intro.html#Embedded+Server[
-Embedded Server (hybrid mode)]
-
-[[createdb_postgres]]
-=== PostgreSQL
-
-This option is more complicated than the H2 option but is recommended
-for larger installations. It's the database backend with the largest userbase
-in the Gerrit community.
-
-Create a user for the web application within PostgreSQL, assign it a
-password, create a database to store the metadata, and grant the user
-full rights on the newly created database:
-
-----
-  $ createuser --username=postgres -RDIElPS gerrit
-  $ createdb --username=postgres -E UTF-8 -O gerrit reviewdb
-----
-
-Visit PostgreSQL's link:http://www.postgresql.org/docs/9.1/interactive/index.html[documentation] for further information regarding
-using PostgreSQL.
-
-[[createdb_mysql]]
-=== MySQL
-
-Requirements: MySQL version 5.1 or later.
-
-This option is also more complicated than the H2 option. Just as with
-PostgreSQL it's also recommended for larger installations.
-
-Create a user for the web application within the database, assign it a
-password, create a database, and give the newly created user full
-rights on it:
-
-----
-  mysql
-
-  CREATE USER 'gerrit'@'localhost' IDENTIFIED BY 'secret';
-  CREATE DATABASE reviewdb DEFAULT CHARACTER SET 'utf8';
-  GRANT ALL ON reviewdb.* TO 'gerrit'@'localhost';
-  FLUSH PRIVILEGES;
-----
-
-Visit MySQL's link:http://dev.mysql.com/doc/[documentation] for further
-information regarding using MySQL.
-
-[[createdb_mariadb]]
-=== MariaDB
-
-Requirements: MariaDB version 5.5 or later.
-
-Refer to MySQL section above how to create MariaDB database.
-
-Visit MariaDB's link:https://mariadb.com/kb/en/mariadb/[documentation] for further
-information regarding using MariaDB.
-
-[[createdb_oracle]]
-=== Oracle
-
-PostgreSQL or H2 is the recommended database for Gerrit Code Review.
-Oracle is supported for environments where running on an existing Oracle
-installation simplifies administrative overheads, such as database backups.
-
-Create a user for the web application within sqlplus, assign it a
-password, and grant the user full rights on the newly created database:
-
-----
-  SQL> create user gerrit identified by secret_password default tablespace users;
-  SQL> grant connect, resources to gerrit;
-----
-
-JDBC driver ojdbc6.jar must be obtained from your Oracle distribution. Gerrit
-initialization process tries to copy it from a known location:
-
-----
-/u01/app/oracle/product/11.2.0/xe/jdbc/lib/ojdbc6.jar
-----
-
-If this file can not be located at this place, then the alternative location
-can be provided.
-
-Instance name is the Oracle SID. Sample database section in
-$site_path/etc/gerrit.config:
-
-----
-[database]
-        type = oracle
-        instance = xe
-        hostname = localhost
-        username = gerrit
-        port = 1521
-----
-
-Sample database section in $site_path/etc/secure.config:
-
-----
-[database]
-        password = secret_password
-----
-
-[[createdb_maxdb]]
-=== SAP MaxDB
-
-SAP MaxDB is a supported database for running Gerrit Code Review. However it is
-recommended only for environments where you intend to run Gerrit on an existing
-MaxDB installation to reduce administrative overhead.
-
-In the MaxDB studio or using the SQLCLI command line interface create a user
-'gerrit' with the user class 'RESOURCE' and a password <secret password>. This
-will also create an associated schema on the database.
-
-To run Gerrit on MaxDB, you need to obtain the MaxDB JDBC driver. It can be
-found in your MaxDB installation at the following location:
-
-- on Windows 64bit at "C:\Program Files\sdb\MaxDB\runtime\jar\sapdbc.jar"
-- on Linux at "/opt/sdb/MaxDB/runtime/jar/sapdbc.jar"
-
-It needs to be stored in the 'lib' folder of the review site.
-
-In the following sample database section it is assumed that the database name is
-'reviewdb' and the database is installed on localhost:
-
-In $site_path/etc/gerrit.config:
-
-----
-[database]
-        type = maxdb
-        database = reviewdb
-        hostname = localhost
-        username = gerrit
-
-----
-
-In $site_path/etc/secure.config:
-
-----
-[database]
-        password = <secret password>
-----
-
-Visit SAP MaxDB's link:http://maxdb.sap.com/documentation/[documentation] for further
-information regarding using SAP MaxDB.
-
-[[createdb_db2]]
-=== DB2
-
-IBM DB2 is a supported database for running Gerrit Code Review. However it is
-recommended only for environments where you intend to run Gerrit on an existing
-DB2 installation to reduce administrative overhead.
-
-Create a system wide user for the Gerrit application, and grant the user
-full rights on the newly created database:
-
-----
-  db2 => create database gerrit
-  db2 => connect to gerrit
-  db2 => grant connect,accessctrl,dataaccess,dbadm,secadm on database to gerrit;
-----
-
-JDBC driver db2jcc4.jar and db2jcc_license_cu.jar must be obtained
-from your DB2 distribution. Gerrit initialization process tries to copy
-it from a known location:
-
-----
-/opt/ibm/db2/V10.5/java/db2jcc4.jar
-/opt/ibm/db2/V10.5/java/db2jcc_license_cu.jar
-----
-
-If these files cannot be located at this place, then an alternative location
-can be provided during init step execution.
-
-Sample database section in $site_path/etc/gerrit.config:
-
-----
-[database]
-        type = db2
-        database = gerrit
-        hostname = localhost
-        username = gerrit
-        port = 50001
-----
-
-Sample database section in $site_path/etc/secure.config:
-
-----
-[database]
-        password = secret_password
-----
-
-[[createdb_hana]]
-=== SAP HANA
-
-SAP HANA is a supported database for running Gerrit Code Review. However it is
-recommended only for environments where you intend to run Gerrit on an existing
-HANA installation to reduce administrative overhead.
-
-In the HANA studio or the SAP HANA Web-based Development Workbench create a user
-'GERRIT2' with the role 'RESTRICTED_USER_JDBC_ACCESS' and a password
-<secret password>. This will also create an associated schema on the database.
-As this user would be required to change the password upon first login you might
-want to to disable the password lifetime check by executing
-'ALTER USER GERRIT2 DISABLE PASSWORD LIFETIME'.
-
-To run Gerrit on HANA, you need to obtain the HANA JDBC driver. It can be found
-as described
-link:http://help.sap.com/saphelp_hanaplatform/helpdata/en/ff/15928cf5594d78b841fbbe649f04b4/frameset.htm[here].
-It needs to be stored in the 'lib' folder of the review site.
-
-In the following sample database section it is assumed that HANA is running on
-the host 'hana.host' and listening on port '4242' where a schema/user GERRIT2
-was created:
-
-In $site_path/etc/gerrit.config:
-
-----
-[database]
-        type = hana
-        hostname = hana.host
-        port = 4242
-        username = GERRIT2
-
-----
-
-In order to configure a specific database in a multi-database environment (MDC)
-the database name has to be specified additionally:
-
-In $site_path/etc/gerrit.config:
-
-----
-[database]
-        type = hana
-        hostname = hana.host
-        database = tdb1
-        port = 4242
-        username = GERRIT2
-
-----
-
-In $site_path/etc/secure.config:
-
-----
-[database]
-        password = <secret password>
-----
-
-Visit SAP HANA's link:http://help.sap.com/hana_appliance/[documentation] for
-further information regarding using SAP HANA.
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index 0ecc820..bec1984 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -6,7 +6,7 @@
 To build Gerrit from source, you need:
 
 * A Linux or macOS system (Windows is not supported at this time)
-* A JDK for Java 8|9|10
+* A JDK for Java 8|9|10|11|...
 * Python 2 or 3
 * Node.js
 * link:https://www.bazel.io/versions/master/docs/install.html[Bazel]
@@ -14,27 +14,55 @@
 * zip, unzip
 * gcc
 
-[[Java 10 support]]
-Java 10 is supported through vanilla java toolchain
+[[Java 10 and newer version support]]
+Java 10 (and newer is) supported through vanilla java toolchain
 link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option].
-To build Gerrit with Java 10, specify vanilla java toolchain and provide
-path to Java 10 home:
+To build Gerrit with Java 10 and newer, specify vanilla java toolchain and
+provide the path to JDK home:
 
 ```
-  $ bazel build --host_javabase=:absolute_javabase \
+  $ bazel build \
     --define=ABSOLUTE_JAVABASE=<path-to-java-10> \
-    --define=USE_ABSOLUTE_JAVABASE=true \
-    --host_java_toolchain=//:toolchain_vanilla \
-    --java_toolchain=//:toolchain_vanilla \
+    --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
+    --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
+    --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
     :release
 ```
 
-Note that the following options must be added to `container.javaOptions`
-in `$gerrit_site/etc/gerrit.config` to run Gerrit with Java 10:
+To run the tests, `--javabase` option must be passed as well, because
+bazel test runs the test using the target javabase:
+
+```
+  $ bazel test \
+    --define=ABSOLUTE_JAVABASE=<path-to-java-10> \
+    --javabase=@bazel_tools//tools/jdk:absolute_javabase \
+    --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
+    --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
+    --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
+    //...
+```
+
+To avoid passing all those options on every Bazel build invocation,
+they could be added to ~/.bazelrc resource file:
+
+```
+$ cat << EOF > ~/.bazelrc
+> build --define=ABSOLUTE_JAVABASE=<path-to-java-10>
+> build --javabase=@bazel_tools//tools/jdk:absolute_javabase
+> build --host_javabase=@bazel_tools//tools/jdk:absolute_javabase
+> build --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla
+> build --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla
+> EOF
+```
+
+Now, invoking Bazel with just `bazel build :release` would include
+all those options.
+
+Note that the follow option must be added to `container.javaOptions`
+in `$gerrit_site/etc/gerrit.config` to run Gerrit with Java 10|11|...:
 
 ```
 [container]
-  javaOptions = --add-modules java.activation
   javaOptions = --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
 ```
 
@@ -51,13 +79,12 @@
       :release
 ```
 
-Note that the following option must be added to `container.javaOptions`
+Note that the follow option must be added to `container.javaOptions`
 in `$gerrit_site/etc/gerrit.config` to run Gerrit with Java 9:
 
 ```
 [container]
-  javaOptions = --add-modules java.activation \
-      --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
+  javaOptions = --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED
 ```
 
 [[build]]
@@ -65,7 +92,7 @@
 
 === Gerrit Development WAR File
 
-To build the Gerrit web application that includes the PolyGerrit UI:
+To build the Gerrit web application:
 
 ----
   bazel build gerrit
@@ -84,8 +111,8 @@
 [[release]]
 === Gerrit Release WAR File
 
-To build the Gerrit web application that includes the GWT UI, the
-PolyGerrit UI, core plugins and documentation:
+To build the Gerrit web application that includes the PolyGerrit UI,
+core plugins and documentation:
 
 ----
   bazel build release
@@ -99,7 +126,7 @@
 
 === Headless Mode
 
-To build Gerrit in headless mode, i.e. without the PolyGerrit and GWT
+To build Gerrit in headless mode, i.e. without the PolyGerrit UI:
 Web UI:
 
 ----
@@ -114,7 +141,7 @@
 
 === Extension and Plugin API JAR Files
 
-To build the extension, plugin and GWT API JAR files:
+To build the extension, plugin and acceptance-framework JAR files:
 
 ----
   bazel build api
@@ -127,7 +154,8 @@
   bazel-genfiles/api.zip
 ----
 
-Install {extension,plugin,gwt}-api to the local maven repository:
+Install {extension,plugin,acceptance-framework}-api to the local
+maven repository:
 
 ----
   tools/maven/api.sh install
@@ -258,31 +286,6 @@
   bazel test //javatests/com/google/gerrit/acceptance/rest/account:rest_account
 ----
 
-To run the tests against NoteDb backend with write
-to NoteDb, but not read from it:
-
-----
-  bazel test --test_env=GERRIT_NOTEDB=WRITE //...
-----
-
-Write and read from NoteDb:
-
-----
-  bazel test --test_env=GERRIT_NOTEDB=READ_WRITE //...
-----
-
-Primary storage NoteDb:
-
-----
-  bazel test --test_env=GERRIT_NOTEDB=PRIMARY //...
-----
-
-Primary storage NoteDb and ReviewDb disabled:
-
-----
-  bazel test --test_env=GERRIT_NOTEDB=ON //...
-----
-
 To run only tests that do not use SSH:
 
 ----
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
index e3ab7ce..e40af24 100644
--- a/Documentation/dev-contributing.txt
+++ b/Documentation/dev-contributing.txt
@@ -250,7 +250,6 @@
 Here are some design level objectives that you should keep in mind
 when coding:
 
-  * ORM entity objects should match exactly one row in the database.
   * Most client pages should perform only one RPC to load so as to
     keep latencies down.  Exceptions would apply to RPCs which need
     to load large data sets if splitting them out will help the
@@ -269,11 +268,11 @@
   * Don't leave repository objects (git or schema) open.  A .close()
     after every open should be placed in a finally{} block.
   * Don't leave UI components, which can cause new actions to occur,
-    enabled during RPCs which update the DB.  This is to prevent
-    people from submitting actions more than once when operating
-    on slow links.  If the action buttons are disabled, they cannot
-    be resubmitted and the user can see that Gerrit is still busy.
-  * GWT EventBus is the new way forward.
+    enabled during RPCs which update Git repositories, including NoteDb.
+    This is to prevent people from submitting actions more than once
+    when operating on slow links.  If the action buttons are disabled,
+    they cannot be resubmitted and the user can see that Gerrit is still
+    busy.
   * ...and so is Guava (previously known as Google Collections).
 
 
@@ -322,31 +321,44 @@
 [[process]]
 == Process
 
+[[dev-in-stable-branches]]
+=== Development in stable branches
+
+As their name suggests stable branches are intended to be stable. This means that generally
+only bug-fixes should be done on stable branches, however this is not strictly enforced and
+exceptions may apply:
+
+  * When a stable branch is initially created to prepare a new release the Gerrit community
+    discusses on the mailing list if there are pending features which should still make it into the
+    release. Those features are blocking the release and should be implemented on the stable
+    branch before the first release candidate is created.
+  * To stabilize the code before doing a major release several release candidates are created. Once
+    the first release candidate was done no more features should be accepted on the stable branch.
+    If more features are found to be required they should be discussed with the Gerrit maintainers
+    and should only be allowed if the risk of breaking things is considered to be low.
+  * Once a major release is done only bug-fixes and documentation updates should be done on the
+    stable branch. These updates will be included in the next minor release.
+  * For minor releases new features are only acceptable if they are important to the Gerrit
+    community, if they are backwards compatible and the risk of breaking things is low and if there
+    are no objections from the Gerrit community.
+  * In cases of doubt it's the responsibility of the release maintainer to evaluate the risk of new
+    features and make a decision based on these rules and opinions from the Gerrit community.
+  * The older a stable branch is the more stable it should be. This means old stable branches
+    should only receive bug-fixes that are either important or low risk. Security fixes, including
+    security updates for third party dependencies, are always considered as important and hence can
+    always be done on stable branches.
+
 === Backporting to stable branches
 
 From time to time bug fix releases are made for existing stable branches.
 
-Developers concerned with stable branches are encouraged to backport or push
-patchsets to these branches, even if no new release is planned.
+Developers concerned with stable branches are encouraged to backport or push fixes to these
+branches, even if no new release is planned. Backporting features is only possible in compliance
+with the rules link:#dev-in-stable-branches[above].
 
-Fixes that are known to be needed for a particular release should be pushed
-for review on that release's stable branch.  It will then be included in
-the master branch when the stable branch is merged back.
-
-=== Updating to new version of GWT
-
-When updating to a new version of GWT, there are several things that also need
-to be updated or at least checked.
-
-* Update common and plugin dependencies in `tools/gwt-constants.defs`.
-* Update to the same GWT version in the cookbook plugin and optionally in other
-plugins that have a dependency on GWT.
-* Update the GWT version in the archetype metadata in the
-`gerrit-plugin-gwt-archetype`.
-* Update the version of `gwt-maven-plugin` in the example pom.xml file in
-link:dev-plugins.html[dev-plugins].
-* Update to the same GWT version in the `gwtjsonrpc` project, and release a
-new version.
+Fixes that are known to be needed for a particular release should be pushed for review on that
+release's stable branch. They will then be included into the master branch when the stable branch
+is merged back.
 
 === Finding starter projects to work on
 
@@ -379,20 +391,21 @@
 developers can agree and rely on.
 
 General process:
-* Make sure that the feature (e.g. a field on the API) is not needed anymore or blocks
-  further development or improvement. If in doubt, consult the mailing list.
-* If you can provide a schema migration that moves users to a comparable feature, do
-  so and stop here.
-* Mark the feature as deprecated in the documentation and release notes.
-* If possible, mark the feature deprecated in any user-visible interface. For example,
-  if you are deprecating a Git push option, add a message to the Git response if
-  the user provided the option informing them about deprecation.
-* Annotate the code with `@Deprecated` and `@RemoveAfter(x.xx)` if applicable.
-  Alternatively, use `// DEPRECATED, remove after x.xx` (where x.xx is the version
-  number that has to be branched off before removing the feature)
-* Gate the feature behind a config that is off by default (forcing admins to turn
-  the deprecated feature on explicitly).
-* After the next release was branched off, remove any code that backed the feature.
+
+  * Make sure that the feature (e.g. a field on the API) is not needed anymore or blocks
+    further development or improvement. If in doubt, consult the mailing list.
+  * If you can provide a schema migration that moves users to a comparable feature, do
+    so and stop here.
+  * Mark the feature as deprecated in the documentation and release notes.
+  * If possible, mark the feature deprecated in any user-visible interface. For example,
+    if you are deprecating a Git push option, add a message to the Git response if
+    the user provided the option informing them about deprecation.
+  * Annotate the code with `@Deprecated` and `@RemoveAfter(x.xx)` if applicable.
+    Alternatively, use `// DEPRECATED, remove after x.xx` (where x.xx is the version
+    number that has to be branched off before removing the feature)
+  * Gate the feature behind a config that is off by default (forcing admins to turn
+    the deprecated feature on explicitly).
+  * After the next release was branched off, remove any code that backed the feature.
 
 You can optionally consult the mailing list to ask if there are users of the feature you
 wish to deprecate. If there are no major users, you can remove the feature without
diff --git a/Documentation/dev-design.txt b/Documentation/dev-design.txt
index bdd2a68..69af18d 100644
--- a/Documentation/dev-design.txt
+++ b/Documentation/dev-design.txt
@@ -65,6 +65,9 @@
 changing the implementation from Python on Google App Engine, to Java
 on a J2EE servlet container and an SQL database.
 
+Since Gerrit 3.x link:note-db.html[NoteDb] replaced the SQL database
+and all metadata is now stored in Git.
+
 * link:http://video.google.com/videoplay?docid=-8502904076440714866[Mondrian Code Review On The Web]
 * link:https://github.com/rietveld-codereview/rietveld[Rietveld - Code Review for Subversion]
 * link:http://eagain.net/gitweb/?p=gitosis.git;a=blob;f=README.rst;hb=HEAD[Gitosis README]
@@ -83,9 +86,7 @@
 
 Each Git commit created on the client desktop system is converted
 into a unique change record which can be reviewed independently.
-Change records are stored in a database: PostgreSQL, MySQL, or the
-built-in H2, where they can be queried to present customized user
-dashboards, enumerating any pending changes.
+Change records are stored in NoteDb.
 
 A summary of each newly uploaded change is automatically emailed
 to reviewers, so they receive a direct hyperlink to review the
@@ -121,9 +122,9 @@
 
 End-user web browsers make HTTP requests directly to Gerrit's
 HTTP server.  As nearly all of the user interface is implemented
-through Google Web Toolkit (GWT), the majority of these requests
-are transmitting compressed JSON payloads, with all HTML being
-generated within the browser.  Most responses are under 1 KB.
+through PolyGerrit, the majority of these requests are transmitting
+compressed JSON payloads, with all HTML being generated within the
+browser.  Most responses are under 1 KB.
 
 Gerrit's HTTP server side component is implemented as a standard
 Java servlet, and thus runs within any J2EE servlet container.
@@ -166,9 +167,7 @@
 requires that the OpenID provider selected by a user must be
 online and operating in order to authenticate that user.
 
-* link:http://www.gwtproject.org/[Google Web Toolkit (GWT)]
 * link:http://www.kernel.org/pub/software/scm/git/docs/gitrepository-layout.html[Git Repository Format]
-* link:http://www.postgresql.org/about/[About PostgreSQL]
 * link:http://openid.net/developers/specs/[OpenID Specifications]
 
 *1  Although an effort is underway to eliminate the use of the
@@ -200,11 +199,6 @@
 and comments in English, and therefore an English user interface
 is usable by the target user base.
 
-Gerrit uses GWT's i18n support to externalize all constant strings
-and messages shown to the user, so that in the future someone who
-really needed a translated version of the UI could contribute new
-string files for their locale(s).
-
 Right-to-left (RTL) support is only barely considered within the
 Gerrit code base.  Some portions of the code have tried to take
 RTL into consideration, while others probably need to be modified
@@ -235,20 +229,11 @@
 
 Supporting non-JavaScript enabled browsers is a non-goal for Gerrit.
 
-As Gerrit is a pure-GWT application with no server side rendering
-fallbacks, the browser must support modern JavaScript semantics in
-order to access the Gerrit web application.  Dumb clients such as
-`lynx`, `wget`, `curl`, or even many search engine spiders are not
-able to access Gerrit content.
-
-As Google Web Toolkit (GWT) is used to generate the browser
-specific versions of the client-side JavaScript code, Gerrit works
-on any JavaScript enabled browser which GWT can produce code for.
-This covers the majority of the popular browsers.
-
-The Gerrit project does not have the development resources necessary
-to support two parallel UI implementations (GWT based JavaScript
-and server-side rendering).  Consequently only one is implemented.
+As Gerrit is a pure JavaScript application on the client side, with
+no server side rendering fallbacks, the browser must support modern
+JavaScript semantics in order to access the Gerrit web application.
+Dumb clients such as `lynx`, `wget`, `curl`, or even many search engine
+spiders are not able to access Gerrit content.
 
 There are number of web browsers available with full JavaScript
 support, and nearly every operating system (including any PDA-like
@@ -317,34 +302,6 @@
 Gerrit does not integrate with any Google service, or any other
 services other than those listed above.
 
-
-== Standards / Developer APIs
-
-Gerrit uses an XSRF protected variant of JSON-RPC 1.1 to communicate
-between the browser client and the server.
-
-As the protocol is not the GWT-RPC protocol, but is instead a
-self-describing standard JSON format it is easily implemented by
-any 3rd party client application, provided the client has a JSON
-parser and HTTP client library available.
-
-As the entire command set necessary for the standard web browser
-based UI is exposed through JSON-RPC over HTTP, there are no other
-data feeds or command interfaces to the server.
-
-Commands requiring user authentication may require the user agent to
-complete a sign-in cycle through the user's OpenID provider in order
-to establish the HTTP cookie Gerrit uses to track user identity.
-Automating this sign-in process for non-web browser agents is
-outside of the scope of Gerrit, as each OpenID provider uses its own
-sign-in sequence.  Use of OpenID providers which have difficult to
-automate interfaces may make it impossible for non-browser agents
-to be used with the JSON-RPC interface.
-
-* link:http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html[JSON-RPC 1.1]
-* link:https://gerrit.googlesource.com/gwtjsonrpc/+/master/README[XSRF JSON-RPC]
-
-
 == Privacy Considerations
 
 Gerrit stores the following information per user account:
@@ -378,7 +335,7 @@
 project's mailing list archives.
 
 The user's name and email address is stored unencrypted in the
-Gerrit metadata store, typically a PostgreSQL database.
+link:config-accounts.html#all-users[All-Users] repository.
 
 The snail-mail mailing address, country, and phone and fax numbers
 are gathered to help project leads contact the user should there
@@ -648,12 +605,6 @@
 
 === Backups
 
-PostgreSQL and MySQL can be configured to replicate their data to
-other systems, where they are applied to a warm-standby backup in
-real time.  Gerrit instances which care about redundancy will setup
-this feature of PostgreSQL or MySQL to ensure the warm-standby is
-reasonably current should the master go offline.
-
 Using the standard replication plugin, Gerrit can be configured
 to replicate changes made to the local Git repositories over any
 standard Git transports. After the plugin is installed, remote
diff --git a/Documentation/dev-eclipse.txt b/Documentation/dev-eclipse.txt
index c335a2d..67ced54 100644
--- a/Documentation/dev-eclipse.txt
+++ b/Documentation/dev-eclipse.txt
@@ -1,11 +1,9 @@
 = Gerrit Code Review - Eclipse Setup
 
 This document is about configuring Gerrit Code Review into an
-Eclipse workspace for development and debugging with GWT.
+Eclipse workspace for development.
 
-Java 8 or later SDK is also required to run GWT's compiler and
-runtime debugging environment.
-
+Java 8 or later SDK is require
 
 [[setup]]
 == Project Setup
@@ -104,61 +102,6 @@
 * Change Save as to be Local file.
 * Close the Debug Configurations dialog and save the changes when prompted.
 
-
-=== Running GWT Debug Mode
-
-The `gerrit_gwt_debug` launch configuration uses GWT's
-link:http://www.gwtproject.org/articles/superdevmode.html[Super Dev Mode].
-
-* Make a local copy of the `gerrit_gwt_debug` configuration, using the
-process described for `gerrit_daemon` above.
-* Launch the local copy of `gerrit_gwt_debug` from the Eclipse debug menu.
-* If debugging GWT for the first time:
-
-** Open the link:http://localhost:9876/[codeserver URL] and add the `Dev Mode On`
-and `Dev Mode Off` bookmarklet to your bookmark bar.
-
-** Activate the source maps feature in your browser. Refer to the
-link:https://developer.chrome.com/devtools/docs/javascript-debugging#source-maps[
-Chrome] and
-link:https://developer.mozilla.org/en-US/docs/Tools/Debugger#Use_a_source_map[
-Firefox] developer documentation.
-
-* Load the link:http://localhost:8080[Gerrit page].
-* Open the source tab in developer tools.
-* Click the `Dev Mode On` bookmark to incrementally recompile changed files.
-* Select the `gerrit_ui` module to compile (the `Compile` button can also be used
-as a bookmarklet).
-* In the developer tools source tab, open a file and set a breakpoint.
-* Navigate to the UI and confirm that the breakpoint is hit.
-* To end the debugging session, click the `Dev Mode Off` bookmark.
-
-.After changing the client side code:
-
-* Hitting `F5` in the browser only reloads the last compile output, without
-recompiling.
-* To reflect your changes in the debug session, click `Dev Mode On` then `Compile`.
-
-
-=== Running GWT Debug Mode for Gerrit plugins
-
-A Gerrit plugin can expose GWT module and its implementation can be inspected
-in the SDM debug session.
-
-`codeserver` needs two additional inputs to expose the plugin module in the SDM
-debug session: the module name and the source folder location. For example the
-module name and source folder of `cookbook-plugin` should be added in the local
-copy of the `gerrit_gwt_debug` configuration:
-
-----
-  com.googlesource.gerrit.plugins.cookbook.HelloForm \
-  -src ${resource_loc:/gerrit}/plugins/cookbook-plugin/src/main/java \
-  -- --console-log [...]
-----
-
-After doing that, both the Gerrit core and plugin GWT modules can be activated
-during SDM (debug session)[http://imgur.com/HFXZ5No].
-
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/dev-inspector.txt b/Documentation/dev-inspector.txt
index 2134f2f..b1559ca 100644
--- a/Documentation/dev-inspector.txt
+++ b/Documentation/dev-inspector.txt
@@ -54,8 +54,6 @@
 ----
 "Shell" is "com.google.gerrit.pgm.shell.JythonShell@61644f2d"
 "m" is "com.google.gerrit.lifecycle.LifecycleManager@6f03b248"
-"ds" is "com.google.gerrit.server.schema.DataSourceProvider@6b3592c"
-"schk" is "com.google.gerrit.server.schema.SchemaVersionCheck@5e8cb9bd"
 
 Welcome to the Gerrit Inspector
 Enter help() to see the above again, EOF to quit and stop Gerrit
@@ -109,71 +107,11 @@
 'registerNatives', 'toString', 'wait']
 ----
 
-Startup script provides some convenient variables to access some global Gerrit components,
-for example a connection to the review database is kept open:
-
-----
->>> ds
-org.apache.commons.dbcp.BasicDataSource@61db2215
->>> ds.driverClassName
-u'org.postgresql.Driver'
->>> ds.dataSource
-org.apache.commons.dbcp.PoolingDataSource@23226fe1
->>> ds.dataSource.connection
-jdbc:postgresql://localhost/reviewdb, UserName=rv, PostgreSQL Native Driver
-----
-
-It is also possible to interact with the ORM layer:
-
-----
->>> db = schk.schema.open()
->>> db
-com.google.gerrit.reviewdb.server.ReviewDb_Schema_GwtOrm$$28@24cbbdf3
->>> db.getDialect()
-com.google.gwtorm.schema.sql.DialectPostgreSQL@4de07d3e
->>> for x in db.patchSets().iterateAllEntities():
-...     print x
-...
-[PatchSet 1,1]
-[PatchSet 2,1]
-[PatchSet 3,1]
-[PatchSet 4,1]
-[PatchSet 5,1]
-[PatchSet 6,1]
-[PatchSet 7,1]
-[PatchSet 8,1]
-[PatchSet 6,2]
->>> for x in db.patchComments().iterateAllEntities():
-...     print x
-com.google.gerrit.reviewdb.client.PatchLineComment@5381298a
-com.google.gerrit.reviewdb.client.PatchLineComment@44ce4dda
-com.google.gerrit.reviewdb.client.PatchLineComment@44594680
->>> dir(com.google.gerrit.reviewdb.client.PatchLineComment)
-['Key', 'STATUS_DRAFT', 'STATUS_PUBLISHED', 'Status', '__class__',
-'__copy__', '__deepcopy__', '__delattr__', '__doc__', '__eq__',
-'__getattribute__', '__hash__', '__init__', '__ne__', '__new__',
-'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
-'__unicode__', 'author', 'class', 'clone', 'equals', 'finalize',
-'getAuthor', 'getClass', 'getKey', 'getLine', 'getMessage',
-'getParentUuid', 'getSide', 'getStatus', 'getWrittenOn', 'hashCode',
-'key', 'line', 'lineNbr', 'message', 'notify', 'notifyAll',
-'parentUuid', 'registerNatives', 'setMessage', 'setSide', 'setStatus',
-'side', 'status', 'toString', 'updated', 'wait', 'writtenOn']
->>> for x in db.patchComments().iterateAllEntities():
-...     print x.status, x.line, x.message
-...
-P 2 I like it!
-P 2 more
-P 1 better
-----
-
 A built-in *help()* function provides values of global variables
 defined in the interpreter:
 
 ----
 >>> help()
-"schk" is "com.google.gerrit.server.schema.SchemaVersionCheck@5e8cb9bd"
-"ds" is "com.google.gerrit.server.schema.DataSourceProvider@6b3592c"
 "m" is "com.google.gerrit.lifecycle.LifecycleManager@6f03b248"
 "Shell" is "com.google.gerrit.pgm.shell.JythonShell@61644f2d"
 "d" is "com.google.gerrit.pgm.Daemon@28a3f689"
diff --git a/Documentation/dev-intellij.txt b/Documentation/dev-intellij.txt
index 8bedd08..b87cbf4 100644
--- a/Documentation/dev-intellij.txt
+++ b/Documentation/dev-intellij.txt
@@ -24,6 +24,13 @@
 . Install it.
 . Restart IntelliJ.
 
+TIP: If your project's Bazel build fails with **Cannot run program "bazel": No
+such file or directory**, then you may have to set the binary location in the
+Bazel plugin settings:
+
+. Go to Preferences -> Other Settings -> Bazel Settings.
+. Set the Bazel binary location.
+
 == Creation of IntelliJ project
 
 . Go to *File -> Import Bazel Project*.
@@ -100,7 +107,9 @@
 === Copyright
 Copy the folder `$(gerrit_source_code)/tools/intellij/copyright` (not just the
 contents) to `$(project_data_directory)/.idea`. If it already exists, replace
-it.
+it. Then go to *File -> Settings -> Editor -> Copyright -> Copyright Profiles*,
+and import `Gerrit_Copyright.xml` to IntelliJ in case it doesn't pick the
+copyright up automatically.
 
 === File header
 By default, IntelliJ adds a file header containing the name of the author and
@@ -177,10 +186,6 @@
 plugin manages a project, it intercepts the creation and creates a Bazel test
 run configuration instead, which can be used just like the standard ones.
 
-TIP: If you would like to execute a test in NoteDb mode, add
-`--test_env=GERRIT_NOTEDB=READ_WRITE` to the *Bazel flags* of your run
-configuration.
-
 [[remote-debug]]
 === Debugging a remote Gerrit server
 If a remote Gerrit server is running and has opened a debug port, you can attach
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index c65acb7..a3166b7 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -325,10 +325,10 @@
 
 Plugins' InitSteps are executed during the "Gerrit Plugin init" phase, after
 the extraction of the plugins embedded in the distribution .war file into
-`$GERRIT_SITE/plugins` and before the DB Schema initialization or upgrade.
+`$GERRIT_SITE/plugins` and before the site initialization or upgrade.
 
-A plugin's InitStep cannot refer to Gerrit's DB Schema or any other Gerrit
-runtime objects injected at startup.
+A plugin's InitStep cannot refer to any Gerrit runtime objects injected at
+startup.
 
 [source,java]
 ----
@@ -718,7 +718,6 @@
 
 [source,java]
 ----
-@Singleton
 public class SampleOperator
     implements ChangeQueryBuilder.ChangeOperatorFactory {
   public static class MyPredicate extends OperatorChangePredicate<ChangeData> {
@@ -751,7 +750,6 @@
 new `has:sample_pluginName` operand is shown below:
 
 ====
-  @Singleton
   public class SampleHasOperand implements ChangeHasOperandFactory {
     public static class Module extends AbstractModule {
       @Override
@@ -801,56 +799,112 @@
   }
 ----
 
+=== Calling Command Options ===
+
+Within an OptionHandler, during the processing of an option, plugins can
+provide and call extra parameters on the current command during parsing
+simulating as if they had been passed from the command line originally.
+
+To call additional parameters from within an option handler, instantiate
+the com.google.gerrit.util.cli.CmdLineParser.Parameters class with the
+existing parameters, and then call callParameters() with the additional
+parameters to be parsed. OptionHandlers may optionally pass this class to
+other methods which may then both parse/consume more parameters and call
+additional parameters.
+
+When calling command options not provided by your plugin, there is always
+a risk that the options may not exist, perhaps because the options being
+called are to be provided by another plugin, and said plugin is not
+currently installed. To protect againt this situation, it is possible to
+define an option as being dependent on other options using the
+@RequiresOptions() annotation. If the required options are not all not
+currently present, then the dependent option will not be available or
+visible in the help.
+
+The example below shows a plugin that adds a "--special" option (perhaps
+for use with the Query command) that calls (and requires) the
+"--format json" option.
+
+[source, java]
+----
+public class JsonOutputOptionHandler<T> extends OptionHandler<T> {
+  protected com.google.gerrit.util.cli.CmdLineParser.MyParser myParser;
+
+  public JsonOutputOptionHandler(CmdLineParser parser, OptionDef option, Setter<? super T> setter) {
+    super(parser, option, setter);
+    myParser = (com.google.gerrit.util.cli.CmdLineParser.MyParser) owner;
+  }
+
+  @Override
+  public int parseArguments(org.kohsuke.args4j.spi.Parameters params) throws CmdLineException {
+    new Parameters(params, myParser).callParameters("--format", "json");
+    setter.addValue(true);
+    return 0; // we didn't consume any additional args
+  }
+
+  @Override
+  public String getDefaultMetaVariable() {
+   ...
+  }
+}
+
+@RequiresOptions("--format")
+@Option(
+  name = "--special",
+  usage = "ouptut results using json",
+  handler = JsonOutputOptionHandler.class
+)
+boolean json;
+----
+
 [[query_attributes]]
-=== Query Attributes ===
+=== Change Attributes ===
 
-Plugins can provide additional attributes to be returned in Gerrit queries by
-implementing the ChangeAttributeFactory interface and registering it to the
-ChangeQueryProcessor.ChangeAttributeFactory class in the plugin module's
-'configure()' method. The new attribute(s) will be output under a "plugin"
-attribute in the change query output. This can be further controlled with an
-option registered in the Http and Ssh modules' 'configure*()' methods.
+Plugins can provide additional attributes to be returned from the Get Change and
+Query Change APIs by implementing implementing the `ChangeAttributeFactory`
+interface and adding it to the `DynamicSet` in the plugin module's `configure()`
+method. The new attribute(s) will be output under a `plugin` attribute in the
+change output. This can be further controlled by registering a class containing
+@Option declarations as a `DynamicBean`, annotated with the with HTTP/SSH
+commands on which the options should be available.
 
-The example below shows a plugin that adds two attributes ('exampleName' and
-'changeValue'), to the change query output, when the query command is provided
-the --myplugin-name--all option.
+The example below shows a plugin that adds two attributes (`exampleName` and
+`changeValue`), to the change query output, when the query command is provided
+the `--myplugin-name--all` option.
 
 [source, java]
 ----
 public class Module extends AbstractModule {
   @Override
   protected void configure() {
-    bind(ChangeAttributeFactory.class)
-        .annotatedWith(Exports.named("example"))
+    // Register attribute factory.
+    DynamicSet.bind(binder(), ChangeAttributeFactory.class)
         .to(AttributeFactory.class);
+
+    // Register options for GET /changes/X/change and /changes/X/detail.
+    bind(DynamicBean.class)
+        .annotatedWith(Exports.named(GetChange.class))
+        .to(MyChangeOptions.class);
+
+    // Register options for GET /changes/?q=...
+    bind(DynamicBean.class)
+        .annotatedWith(Exports.named(QueryChanges.class))
+        .to(MyChangeOptions.class);
+
+    // Register options for ssh gerrit query.
+    bind(DynamicBean.class)
+        .annotatedWith(Exports.named(Query.class))
+        .to(MyChangeOptions.class);
   }
 }
 
-public class MyQueryOptions implements DynamicBean {
+public class MyChangeOptions implements DynamicBean {
   @Option(name = "--all", usage = "Include plugin output")
   public boolean all = false;
 }
 
-public static class HttpModule extends HttpPluginModule {
-  @Override
-  protected void configureServlets() {
-    bind(DynamicBean.class)
-        .annotatedWith(Exports.named(QueryChanges.class))
-        .to(MyQueryOptions.class);
-  }
-}
-
-public static class SshModule extends PluginCommandModule {
-  @Override
-  protected void configureCommands() {
-    bind(DynamicBean.class)
-        .annotatedWith(Exports.named(Query.class))
-        .to(MyQueryOptions.class);
-  }
-}
-
 public class AttributeFactory implements ChangeAttributeFactory {
-  protected MyQueryOptions options;
+  protected MyChangeOptions options;
 
   public class PluginAttribute extends PluginDefinedInfo {
     public String exampleName;
@@ -863,9 +917,9 @@
   }
 
   @Override
-  public PluginDefinedInfo create(ChangeData c, ChangeQueryProcessor qp, String plugin) {
+  public PluginDefinedInfo create(ChangeData c, BeanProvider bp, String plugin) {
     if (options == null) {
-      options = (MyQueryOptions) qp.getDynamicBean(plugin);
+      options = (MyChangeOptions) bp.getDynamicBean(plugin);
     }
     if (options.all) {
       return new PluginAttribute(c);
@@ -893,6 +947,23 @@
    ],
     ...
 }
+
+curl http://localhost:8080/changes/1?myplugin-name--all
+
+Output:
+
+{
+  "_number": 1,
+  ...
+  "plugins": [
+    {
+      "name": "myplugin-name",
+      "example_name": "Attribute Example",
+      "change_value": "1"
+    }
+  ],
+  ...
+}
 ----
 
 [[simple-configuration]]
@@ -1302,7 +1373,7 @@
 [[panels]]
 === Panels
 
-GWT plugins can contribute panels to Gerrit screens.
+UI plugins can contribute panels to Gerrit screens.
 
 Gerrit screens define extension points where plugins can add GWT
 panels with custom controls:
@@ -1515,9 +1586,8 @@
   // schedule a build
   [...]
   // update change
-  ReviewDb db = dbProvider.get();
   try (BatchUpdate bu = batchUpdateFactory.create(
-      db, project.getNameKey(), user, TimeUtil.nowTs())) {
+      project.getNameKey(), user, TimeUtil.nowTs())) {
     bu.addOp(change.getId(), new BatchUpdate.Op() {
       @Override
       public boolean updateChange(ChangeContext ctx) {
@@ -1878,317 +1948,6 @@
 ----
 
 
-[[gwt_ui_extension]]
-== GWT UI Extension
-Plugins can extend the Gerrit UI with own GWT code.
-
-A GWT plugin must contain a GWT module file, e.g. `HelloPlugin.gwt.xml`,
-that bundles together all the configuration settings of the GWT plugin:
-
-[source,xml]
-----
-<?xml version="1.0" encoding="UTF-8"?>
-<module rename-to="hello_gwt_plugin">
-  <!-- Inherit the core Web Toolkit stuff. -->
-  <inherits name="com.google.gwt.user.User"/>
-  <!-- Other module inherits -->
-  <inherits name="com.google.gerrit.Plugin"/>
-  <inherits name="com.google.gwt.http.HTTP"/>
-  <!-- Using GWT built-in themes adds a number of static -->
-  <!-- resources to the plugin. No theme inherits lines were -->
-  <!-- added in order to make this plugin as simple as possible -->
-  <!-- Specify the app entry point class. -->
-  <entry-point class="${package}.client.HelloPlugin"/>
-  <stylesheet src="hello.css"/>
-</module>
-----
-
-The GWT module must inherit `com.google.gerrit.Plugin` and
-`com.google.gwt.http.HTTP`.
-
-To register the GWT module a `GwtPlugin` needs to be bound.
-
-If no Guice modules are declared in the manifest, the GWT plugin may
-use auto-registration by using the `@Listen` annotation:
-
-[source,java]
-----
-@Listen
-public class MyExtension extends GwtPlugin {
-  public MyExtension() {
-    super("hello_gwt_plugin");
-  }
-}
-----
-
-Otherwise the binding must be done in an `HttpModule`:
-
-[source,java]
-----
-public class HttpModule extends ServletModule {
-
-  @Override
-  protected void configureServlets() {
-    DynamicSet.bind(binder(), WebUiPlugin.class)
-        .toInstance(new GwtPlugin("hello_gwt_plugin"));
-  }
-}
-----
-
-The HTTP module above must be declared in the `pom.xml` for Maven
-driven plugins:
-
-[source,xml]
-----
-<manifestEntries>
-  <Gerrit-HttpModule>com.googlesource.gerrit.plugins.myplugin.HttpModule</Gerrit-HttpModule>
-</manifestEntries>
-----
-
-The name that is provided to the `GwtPlugin` must match the GWT
-module name compiled into the plugin. The name of the GWT module
-can be explicitly set in the GWT module XML file by specifying
-the `rename-to` attribute on the module. It is important that the
-module name be unique across all plugins installed on the server,
-as the module name determines the JavaScript namespace used by the
-compiled plugin code.
-
-[source,xml]
-----
-<module rename-to="hello_gwt_plugin">
-----
-
-The actual GWT code must be implemented in a class that extends
-`com.google.gerrit.plugin.client.PluginEntryPoint`:
-
-[source,java]
-----
-public class HelloPlugin extends PluginEntryPoint {
-
-  @Override
-  public void onPluginLoad() {
-    // Create the dialog box
-    final DialogBox dialogBox = new DialogBox();
-
-    // The content of the dialog comes from a User specified Preference
-    dialogBox.setText("Hello from GWT Gerrit UI plugin");
-    dialogBox.setAnimationEnabled(true);
-    Button closeButton = new Button("Close");
-    VerticalPanel dialogVPanel = new VerticalPanel();
-    dialogVPanel.setWidth("100%");
-    dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
-    dialogVPanel.add(closeButton);
-
-    closeButton.addClickHandler(new ClickHandler() {
-      public void onClick(ClickEvent event) {
-        dialogBox.hide();
-      }
-    });
-
-    // Set the contents of the Widget
-    dialogBox.setWidget(dialogVPanel);
-
-    RootPanel rootPanel = RootPanel.get(HelloMenu.MENU_ID);
-    rootPanel.getElement().removeAttribute("href");
-    rootPanel.addDomHandler(new ClickHandler() {
-        @Override
-        public void onClick(ClickEvent event) {
-          dialogBox.center();
-          dialogBox.show();
-        }
-    }, ClickEvent.getType());
-  }
-}
-----
-
-This class must be set as entry point in the GWT module:
-
-[source,xml]
-----
-<entry-point class="${package}.client.HelloPlugin"/>
-----
-
-In addition this class must be defined as module in the `pom.xml` for the
-`gwt-maven-plugin` and the `webappDirectory` option of `gwt-maven-plugin`
-must be set to `${project.build.directory}/classes/static`:
-
-[source,xml]
-----
-<plugin>
-  <groupId>org.codehaus.mojo</groupId>
-  <artifactId>gwt-maven-plugin</artifactId>
-  <version>2.7.0</version>
-  <configuration>
-    <module>com.googlesource.gerrit.plugins.myplugin.HelloPlugin</module>
-    <disableClassMetadata>true</disableClassMetadata>
-    <disableCastChecking>true</disableCastChecking>
-    <webappDirectory>${project.build.directory}/classes/static</webappDirectory>
-  </configuration>
-  <executions>
-    <execution>
-      <goals>
-        <goal>compile</goal>
-      </goals>
-    </execution>
-  </executions>
-</plugin>
-----
-
-To attach a GWT widget defined by the plugin to the Gerrit core UI
-`com.google.gwt.user.client.ui.RootPanel` can be used to manipulate the
-Gerrit core widgets:
-
-[source,java]
-----
-RootPanel rootPanel = RootPanel.get(HelloMenu.MENU_ID);
-rootPanel.getElement().removeAttribute("href");
-rootPanel.addDomHandler(new ClickHandler() {
-  @Override
-  public void onClick(ClickEvent event) {
-    dialogBox.center();
-    dialogBox.show();
-  }
-}, ClickEvent.getType());
-----
-
-GWT plugins can come with their own css file. This css file must have a
-unique name and must be registered in the GWT module:
-
-[source,xml]
-----
-<stylesheet src="hello.css"/>
-----
-
-If a GWT plugin wants to invoke the Gerrit REST API it can use
-`com.google.gerrit.plugin.client.rpc.RestApi` to construct the URL
-path and to trigger the REST calls.
-
-Example for invoking a Gerrit core REST endpoint:
-
-[source,java]
-----
-new RestApi("projects").id(projectName).view("description")
-    .put("new description", new AsyncCallback<JavaScriptObject>() {
-
-  @Override
-  public void onSuccess(JavaScriptObject result) {
-    // TODO
-  }
-
-  @Override
-  public void onFailure(Throwable caught) {
-    // never invoked
-  }
-});
-----
-
-Example for invoking a REST endpoint defined by a plugin:
-
-[source,java]
-----
-new RestApi("projects").id(projectName).view("myplugin", "myview")
-    .get(new AsyncCallback<JavaScriptObject>() {
-
-  @Override
-  public void onSuccess(JavaScriptObject result) {
-    // TODO
-  }
-
-  @Override
-  public void onFailure(Throwable caught) {
-    // never invoked
-  }
-});
-----
-
-The `onFailure(Throwable)` of the provided callback is never invoked.
-If an error occurs, it is shown in an error dialog.
-
-In order to be able to do REST calls the GWT module must inherit
-`com.google.gwt.json.JSON`:
-
-[source,xml]
-----
-<inherits name="com.google.gwt.json.JSON"/>
-----
-
-[[screen]]
-== Add Screen
-A link:#gwt_ui_extension[GWT plugin] can link:#top-menu-extensions[add
-a menu item] that opens a screen that is implemented by the plugin.
-This way plugin screens can be fully integrated into the Gerrit UI.
-
-Example menu item:
-[source,java]
-----
-public class MyMenu implements TopMenu {
-  private final List<MenuEntry> menuEntries;
-
-  @Inject
-  public MyMenu(@PluginName String name) {
-    menuEntries = new ArrayList<>();
-    menuEntries.add(new MenuEntry("My Menu", Collections.singletonList(
-      new MenuItem("My Screen", "#/x/" + name + "/my-screen", ""))));
-  }
-
-  @Override
-  public List<MenuEntry> getEntries() {
-    return menuEntries;
-  }
-}
-----
-
-Example screen:
-[source,java]
-----
-public class MyPlugin extends PluginEntryPoint {
-  @Override
-  public void onPluginLoad() {
-    Plugin.get().screen("my-screen", new Screen.EntryPoint() {
-      @Override
-      public void onLoad(Screen screen) {
-        screen.add(new InlineLabel("My Screen");
-        screen.show();
-      }
-    });
-  }
-}
-----
-
-[[user-settings-screen]]
-== Add User Settings Screen
-
-A link:#gwt_ui_extension[GWT plugin] can implement a user settings
-screen that is integrated into the Gerrit user settings menu.
-
-Example settings screen:
-[source,java]
-----
-public class MyPlugin extends PluginEntryPoint {
-  @Override
-  public void onPluginLoad() {
-    Plugin.get().settingsScreen("my-preferences", "My Preferences",
-        new Screen.EntryPoint() {
-          @Override
-          public void onLoad(Screen screen) {
-            screen.setPageTitle("Settings");
-            screen.add(new InlineLabel("My Preferences"));
-            screen.show();
-          }
-    });
-  }
-}
-----
-
-By defining an link:config-gerrit.html#urlAlias[urlAlias] Gerrit
-administrators can map plugin screens into the Gerrit URL namespace or
-even replace Gerrit screens by plugin screens.
-
-Plugins may also programatically add URL aliases in the preferences of
-of a user. This way certain screens can be replaced for certain users.
-E.g. the plugin may offer a user preferences setting for choosing a
-screen that then sets/unsets a URL alias for the user.
-
 [[settings-screen]]
 == Plugin Settings Screen
 
@@ -2923,6 +2682,94 @@
 are met, but marked as `OK`. If the requirements were not displayed, reviewers
 would need to use their precious time to manually check that they were met.
 
+[[quota-enforcer]]
+== Quota Enforcer
+
+Gerrit provides an extension point that allows a plugin to enforce quota.
+link:quota.html[This documentation page] has a list of all quota requests that
+Gerrit core issues. Plugins can choose to respond to all or just a subset of
+requests. Some implementations might want to keep track of user quota in buckets,
+others might just check against instance or project state to enforce limits on how
+many projects can be created or how large a repository can become.
+
+Checking against instance state can be racy for concurrent requests as the server does not
+refill tokens if the action fails in a later stage (e.g. database failure). If
+plugins want to guarantee an absolute maximum on a resource, they have to do their own
+book-keeping.
+
+[source, java]
+----
+import com.google.server.quota.QuotaEnforcer;
+
+class ProjectLimiter implements QuotaEnforcer {
+  private final long maxNumberOfProjects = 100;
+  @Override
+  QuotaResponse requestTokens(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    if (!"/projects/create".equals(quotaGroup)) {
+      return QuotaResponse.noOp();
+    }
+    // No deduction because we always check against the instance state (racy but fine for
+    // this plugin)
+    if (currentNumberOfProjects() + numTokens > maxNumberOfProjects) {
+      return QuotaResponse.error("too many projects");
+    }
+    return QuotaResponse.ok();
+  }
+
+  @Override
+  QuotaResponse dryRun(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    // Since we are not keeping any state in this enforcer, we can simply call requestTokens().
+    return requestTokens(quotaGroup, ctx, numTokens);
+  }
+
+  void refill(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    // No-op
+  }
+}
+----
+
+[source, java]
+----
+import com.google.server.quota.QuotaEnforcer;
+
+class ApiQpsEnforcer implements QuotaEnforcer {
+  // AutoRefillingPerUserBuckets is a imaginary bucket implementation that could be based on
+  // a loading cache or a commonly used bucketing algorithm.
+  private final AutoRefillingPerUserBuckets<CurrentUser, Long> buckets;
+  @Override
+  QuotaResponse requestTokens(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    if (!quotaGroup.startsWith("/restapi/")) {
+      return QuotaResponse.noOp();
+    }
+    boolean success = buckets.deduct(ctx.user(), numTokens);
+    if (!success) {
+      return QuotaResponse.error("user sent too many qps, please wait for 5 minutes");
+    }
+    return QuotaResponse.ok();
+  }
+
+  @Override
+  QuotaResponse dryRun(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    if (!quotaGroup.startsWith("/restapi/")) {
+      return QuotaResponse.noOp();
+    }
+    boolean success = buckets.checkOnly(ctx.user(), numTokens);
+    if (!success) {
+      return QuotaResponse.error("user sent too many qps, please wait for 5 minutes");
+    }
+    return QuotaResponse.ok();
+  }
+
+  @Override
+  void refill(String quotaGroup, QuotaRequestContext ctx, long numTokens) {
+    if (!quotaGroup.startsWith("/restapi/")) {
+      return;
+    }
+    buckets.add(ctx.user(), numTokens);
+  }
+}
+----
+
 
 == SEE ALSO
 
diff --git a/Documentation/dev-polygerrit.txt b/Documentation/dev-polygerrit.txt
deleted file mode 100644
index 5621d32..0000000
--- a/Documentation/dev-polygerrit.txt
+++ /dev/null
@@ -1,34 +0,0 @@
-= PolyGerrit - GUI
-
-== Configuring
-
-By default both GWT and PolyGerrit UI are available to users.
-
-To make PolyGerrit the default UI but keep GWT as a secondary UI:
-----
-[gerrit]
-        ui = POLYGERRIT
-----
-
-To disable GWT but not PolyGerrit:
-----
-[gerrit]
-        enableGwtUi = false
-        enablePolyGerrit = true
-----
-
-To enable GWT but not PolyGerrit:
-----
-[gerrit]
-        enableGwtUi = true
-        enablePolyGerrit = false
-----
-
-To switch to the PolyGerrit UI you have to add `?polygerrit=1` in the URL.
-
-for example https://gerrit.example.org/?polygerrit=1
-
-To disable PolyGerrit UI, change 1 to 0, which will take you back to GWT UI.
-
-
-More information can be found in the link:https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/[README]
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index 92d080b..8bf4814 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -93,6 +93,7 @@
 .  Click 'become' in the upper right corner.
 .  Select 'Switch User'.
 .  Register a new account.
+.  link:user-upload.html#ssh[Configure your SSH key].
 
 Use the `ssh` protocol to clone from and push to the local server. For
 example, to clone a repository that you've created through the admin
@@ -187,27 +188,6 @@
 CAUTION: When using the Inspector, be careful not to modify the internal state
 of the system.
 
-=== Querying the database
-
-The embedded H2 database can be queried and updated from the command line. If
-the daemon is not running, run:
-
-----
-  $(bazel info output_base)/external/local_jdk/bin/java \
-     -jar bazel-bin/gerrit.war gsql -d ../gerrit_testsite -s
-----
-
-NOTE: To learn why using `java -jar` isn't sufficient, see
-<<special_bazel_java_version,this explanation>>.
-
-Alternatively, if the daemon is running and the database is in use, use an
-administrator user account to connect over SSH:
-
-----
-  ssh -p 29418 user@localhost gerrit gsql
-----
-
-
 == Switching between branches
 
 When using `git checkout` without `--recurse-submodules` to switch between
diff --git a/Documentation/dev-release-deploy-config.txt b/Documentation/dev-release-deploy-config.txt
index 5f95cb3..5411927 100644
--- a/Documentation/dev-release-deploy-config.txt
+++ b/Documentation/dev-release-deploy-config.txt
@@ -91,7 +91,7 @@
 
 * `gerrit-maven`:
 +
-Bucket to store Gerrit Subproject Artifacts (e.g. `gwtjsonrpc` etc.).
+Bucket to store Gerrit Subproject Artifacts (e.g. `gwtorm` etc.).
 
 To upload artifacts to a bucket the user must authenticate with a
 username and password. The username and password need to be retrieved
diff --git a/Documentation/dev-release-subproject.txt b/Documentation/dev-release-subproject.txt
index 4886849..c9369b9 100644
--- a/Documentation/dev-release-subproject.txt
+++ b/Documentation/dev-release-subproject.txt
@@ -73,7 +73,7 @@
 * Deploy the new release:
 +
 ----
-  mvn deploy
+  mvn deploy -DperformRelease=true
 ----
 
 * Push the pom change(s) to the project's repository
diff --git a/Documentation/index.txt b/Documentation/index.txt
index 6011158..557cf90 100644
--- a/Documentation/index.txt
+++ b/Documentation/index.txt
@@ -85,6 +85,7 @@
 .. link:js-api.html[JavaScript Plugin API]
 .. link:config-validation.html[Validation Interfaces]
 .. link:dev-stars.html[Starring Changes]
+.. link:quota.html[Quota Enforcement]
 . link:dev-design.html[System Design]
 . link:i18n-readme.html[i18n Support]
 
diff --git a/Documentation/install-j2ee.txt b/Documentation/install-j2ee.txt
index 91d73cc..48751b7 100644
--- a/Documentation/install-j2ee.txt
+++ b/Documentation/install-j2ee.txt
@@ -14,9 +14,8 @@
 
 == Installation
 
-* Complete the link:install.html#createdb[database setup] and
-  link:install.html#init[site initialization] tasks described
-  in the standard installation documentation.
+* Complete the link:install.html#init[site initialization] task
+  described in the standard installation documentation.
 
 * Stop the embedded daemon that was automatically started by 'init':
 +
@@ -24,13 +23,6 @@
   review_site/bin/gerrit.sh stop
 ----
 
-* Configure JNDI DataSource 'jdbc/ReviewDb'.
-+
-This DataSource must point to the database you created above.
-Don't forget to ensure your JNDI configuration can load the
-necessary JDBC drivers.  You may wish to ensure connection pooling
-is configured and enabled within the DataSource.
-
 * Deploy the 'gerrit.war' file to your application server.
 +
 The deployment process differs between servers, but typically this
@@ -70,20 +62,8 @@
   java -jar webapps/gerrit.war cat extra/jetty7/gerrit.xml >contexts/gerrit.xml
 ----
 
-Install the required additional libraries by copying them into the
-`'$JETTY_HOME'/lib/ext` directory:
-
-----
-  cp ../review_db/lib/* lib/ext/
-  java -jar webapps/gerrit.war cat lib/commons-dbcp-1.2.2.jar >lib/ext/commons-dbcp-1.2.2.jar
-  java -jar webapps/gerrit.war cat lib/commons-pool-1.5.4.jar >lib/ext/commons-pool-1.5.4.jar
-  java -jar webapps/gerrit.war cat lib/h2-1.2.128.jar >lib/ext/h2-1.2.128.jar
-  java -jar webapps/gerrit.war cat lib/postgresql-8.4-701.jdbc4.jar >lib/ext/postgresql-8.4-701.jdbc4.jar
-----
-
 Edit `'$JETTY_HOME'/contexts/gerrit.xml` to correctly configure
-the database and outgoing SMTP connections, especially the user
-and password fields.
+outgoing SMTP connections.
 
 If OpenID authentication (or certain enterprise single-sign-on
 solutions) is being used, you may need to increase the
diff --git a/Documentation/install.txt b/Documentation/install.txt
index dbca368..0885da1 100644
--- a/Documentation/install.txt
+++ b/Documentation/install.txt
@@ -9,10 +9,6 @@
 +
 Gerrit is not yet compatible with Java 9 or newer at this time.
 
-By default, Gerrit uses link:note-db.html[NoteDB] as the storage backend. (If
-desired, you can _optionally_ use an external database such as MySQL or
-PostgreSQL.)
-
 [[cryptography]]
 == Configure Java for Strong Cryptography
 
@@ -60,15 +56,12 @@
 If you would prefer to build Gerrit directly from source, review
 the notes under link:dev-readme.html[developer setup].
 
-include::database-setup.txt[]
-
 [[init]]
 == Initialize the Site
 
 Gerrit stores configuration files, the server's SSH keys, and the
 managed Git repositories under a local directory, typically referred
-to as `'$site_path'`.  If the embedded H2 database is being used,
-its data files will also be stored under this directory.
+to as `'$site_path'`.
 
 You also have to decide where to store your server side git repositories. This
 can either be a relative path under `'$site_path'` or an absolute path
@@ -93,11 +86,10 @@
 then give ownership of that location to the `'gerrit'` user.
 
 If run from an interactive terminal, the init command will prompt through a
-series of configuration questions, including gathering information
-about the database created above.  If the terminal is not interactive,
-running the init command will choose some reasonable default selections,
-and will use the embedded H2 database. Once the init phase is complete,
-you can review your settings in the file `'$site_path/etc/gerrit.config'`.
+series of configuration questions.  If the terminal is not interactive,
+running the init command will choose some reasonable default selections.
+Once the init phase is complete, you can review your settings in the file
+`'$site_path/etc/gerrit.config'`.
 
 When running the init command, additional JARs might be downloaded to
 support optional selected functionality.  If a download fails a URL will
@@ -217,8 +209,7 @@
         --StartPath=C:\MY\GERRIT\SITE ^
         --StartMode=jvm --StopMode=jvm ^
         --StartClass=com.google.gerrit.launcher.GerritLauncher --StartMethod=daemonStart ^
-        --StopClass=com.google.gerrit.launcher.GerritLauncher --StopMethod=daemonStop ^
-        ++DependsOn=postgresql-x64-9.4
+        --StopClass=com.google.gerrit.launcher.GerritLauncher --StopMethod=daemonStop
 ====
 
 [[customize]]
@@ -255,8 +246,6 @@
 
 == External Documentation Links
 
-* http://www.postgresql.org/docs/[PostgreSQL Documentation]
-* http://dev.mysql.com/doc/[MySQL Documentation]
 * http://www.kernel.org/pub/software/scm/git/docs/git-daemon.html[git-daemon]
 
 
diff --git a/Documentation/intro-project-owner.txt b/Documentation/intro-project-owner.txt
index a5895c5..1f98291 100644
--- a/Documentation/intro-project-owner.txt
+++ b/Documentation/intro-project-owner.txt
@@ -123,6 +123,13 @@
 are a number of link:access-control.html#references_special[special refs]
 and link:access-control.html#references_magic[magic refs].
 
+Gerrit only supports tags that are reachable by any ref not owned by
+Gerrit. This includes branches (refs/heads/*) or custom ref namespaces
+(refs/my-company/*). Tagging a change ref is not supported.
+When filtering tags by visibility, Gerrit performs a reachability check
+and will present the user ony with tags that are reachable by any ref
+they can see.
+
 Access rights can be assigned on a concrete ref, e.g.
 `refs/heads/master` but also on ref patterns and regular expressions
 for ref names.
@@ -209,7 +216,7 @@
 addition you can benefit from Gerrit's merge strategies that can
 automatically merge/rebase commits on server side if necessary. You can
 control the merge strategy by configuring the
-link:project-configuration.html#submit_type[submit type] on the project. If you
+link:config-project-config.html#submit-type[submit type] on the project. If you
 bypass code review you always need to merge/rebase manually if the tip
 of the destination branch has moved. Please keep this in mind if you
 choose to not work with code review because you think it's easier to
@@ -239,7 +246,7 @@
 
 An important decision for a project is the choice of the submit type
 and the content merge setting (see the `Allow content merges` option).
-The link:project-configuration.html#submit_type[submit type] is the method
+The link:config-project-config.html#submit-type[submit type] is the method
 Gerrit uses to submit a change to the project. The submit type defines
 what Gerrit should do on submit of a change if the destination branch
 has moved while the change was in review. The
@@ -281,7 +288,7 @@
 types for different branches.
 
 Please note that there are other submit types available; they are
-described in the link:project-configuration.html#submit_type[Submit Type]
+described in the link:config-project-config.html#submit-type[Submit Type]
 section.
 
 [[labels]]
@@ -607,18 +614,6 @@
 are inherited by the child projects. A child project can overwrite an
 inherited download command, or remove it by assigning no value to it.
 
-[[theme]]
-== Theme
-
-Gerrit supports project-specific themes for customizing the appearance
-of the change screen and the diff screens. It is possible to define an
-HTML header and footer and to adapt Gerrit's CSS. Details about themes
-are explained in the link:config-themes.html[Themes] section.
-
-Project-specific themes can only be installed by Gerrit administrators
-since the theme files must be copied into the Gerrit installation
-folder.
-
 [[tool-integration]]
 == Integration with other tools
 
diff --git a/Documentation/intro-user.txt b/Documentation/intro-user.txt
index 2a877ec..17c9a61 100644
--- a/Documentation/intro-user.txt
+++ b/Documentation/intro-user.txt
@@ -383,7 +383,7 @@
 
 How the code modification is applied to the target branch when a change
 is submitted is controlled by the
-link:project-configuration.html#submit_type[submit type] which can be
+link:config-project-config.html#submit-type[submit type] which can be
 link:intro-project-owner.html#submit-type[configured on project-level].
 
 Submitting a change may fail with conflicts. In this case you need to
@@ -548,7 +548,8 @@
 ----
 Alternatively, click *Ready* from the Change screen.
 
-Only change owners, project owners and site administrators can mark changes as
+Change owners, project owners, site administrators and members of a group that
+was granted "Toggle Work In Progress state" permission can mark changes as
 `work-in-progress` and `ready`.
 
 [[wip-polygerrit]]
diff --git a/Documentation/js-api.txt b/Documentation/js-api.txt
index 96b5107..4ef2a6c 100644
--- a/Documentation/js-api.txt
+++ b/Documentation/js-api.txt
@@ -188,6 +188,12 @@
   comments, file-level comments and summary comments, and it may change
   with new Gerrit versions.
 
+* `highlightjs-loaded`: Invoked when the highlight.js library has
+  finished loading. The global `hljs` object (also now accessible via
+  `window.hljs`) is passed as an argument to the callback function.
+  This event can be used to register a new language highlighter with
+  the highlight.js library before syntax highlighting begins.
+
 [[self_onAction]]
 === self.onAction()
 Register a JavaScript callback to be invoked when the user clicks
diff --git a/Documentation/metrics.txt b/Documentation/metrics.txt
index 37d6d01..064859d 100644
--- a/Documentation/metrics.txt
+++ b/Documentation/metrics.txt
@@ -23,10 +23,12 @@
 === Pushes
 
 * `receivecommits/changes`: histogram of number of changes processed
-in a single upload, split up by update type (new change created,
-existing changed updated, change autoclosed).
+in a single upload, split up by update type (change created/updated,
+change autoclosed).
 * `receivecommits/latency`: latency per change for processing a push,
 split up by update type (create+replace, and autoclose)
+* `receivecommits/push_latency`: total latency for processing a push,
+split up by update type (create+replace, autoclose, normal)
 * `receivecommits/timeout`: number of timeouts during push processing.
 
 === Process
@@ -106,10 +108,6 @@
 * `sshd/sessions/created`: Rate of new SSH sessions.
 * `sshd/sessions/authentication_failures`: Rate of SSH authentication failures.
 
-=== SQL connections
-
-* `sql/connection_pool/connections`: SQL database connections.
-
 === Topics
 
 * `topic/cross_project_submit`: number of cross-project topic submissions.
@@ -140,9 +138,6 @@
 * `notedb/stage_update_latency`: Latency for staging updates to NoteDb by table.
 * `notedb/read_latency`: NoteDb read latency by table.
 * `notedb/parse_latency`: NoteDb parse latency by table.
-* `notedb/auto_rebuild_latency`: NoteDb auto-rebuilding latency by table.
-* `notedb/auto_rebuild_failure_count`: NoteDb auto-rebuilding attempts that
-failed by table.
 * `notedb/external_id_update_count`: Total number of external ID updates.
 * `notedb/read_all_external_ids_latency`: Latency for reading all
 external ID's from NoteDb.
@@ -177,6 +172,10 @@
 * `plugin/latency`: Latency for plugin invocation.
 * `plugin/error_count`: Number of plugin errors.
 
+=== Group
+
+* `group/guess_relevant_groups_latency`: Latency for guessing relevant groups.
+
 === Replication Plugin
 
 * `plugins/replication/replication_latency`: Time spent pushing to remote
diff --git a/Documentation/pg-plugin-dev.txt b/Documentation/pg-plugin-dev.txt
index c7aa57c..8fb5655 100644
--- a/Documentation/pg-plugin-dev.txt
+++ b/Documentation/pg-plugin-dev.txt
@@ -177,6 +177,14 @@
 
 Note: TODO
 
+=== registerDynamicCustomComponent
+`plugin.registerDynamicCustomComponent(dynamicEndpointName, opt_moduleName,
+opt_options)`
+
+See list of supported link:pg-plugin-endpoints.html[endpoints].
+
+Note: TODO
+
 === registerStyleModule
 `plugin.registerStyleModule(endpointName, moduleName)`
 
diff --git a/Documentation/pg-plugin-endpoints.txt b/Documentation/pg-plugin-endpoints.txt
index ad613a5..cb80c74 100644
--- a/Documentation/pg-plugin-endpoints.txt
+++ b/Documentation/pg-plugin-endpoints.txt
@@ -141,3 +141,52 @@
 +
 The submit action, including the title and label, an instance of
 link:rest-api-changes.html#action-info[ActionInfo]
+
+== Dynamic Plugin endpoints
+
+The following endpoints are available to plugins.
+
+=== change-list-header
+The `change-list-header` extension point adds a header to the change list view.
+
+=== change-list-item-cell
+The `change-list-item-cell` extension point adds a cell to the change list item.
+
+In addition to default parameters, the following are available:
+
+* `change`
++
+current change of the row, an instance of
+link:rest-api-changes.html#change-info[ChangeInfo]
+
+=== change-view-tab-header
+The `change-view-tab-header` extension point adds a primary tab to the change
+view. This must be used in conjunction with `change-view-tab-content`.
+
+In addition to default parameters, the following are available:
+
+* `change`
++
+current change displayed, an instance of
+link:rest-api-changes.html#change-info[ChangeInfo]
+
+* `revision`
++
+current revision displayed, an instance of
+link:rest-api-changes.html#revision-info[RevisionInfo]
+
+=== change-view-tab-content
+The `change-view-tab-content` extension point adds primary tab content to
+the change view. This must be used in conjunction with `change-view-tab-header`.
+
+In addition to default parameters, the following are available:
+
+* `change`
++
+current change displayed, an instance of
+link:rest-api-changes.html#change-info[ChangeInfo]
+
+* `revision`
++
+current revision displayed, an instance of
+link:rest-api-changes.html#revision-info[RevisionInfo]
diff --git a/Documentation/pgm-LocalUsernamesToLowerCase.txt b/Documentation/pgm-LocalUsernamesToLowerCase.txt
index 4b50961..53081a1 100644
--- a/Documentation/pgm-LocalUsernamesToLowerCase.txt
+++ b/Documentation/pgm-LocalUsernamesToLowerCase.txt
@@ -47,7 +47,7 @@
 
 == CONTEXT
 This command can only be run on a server which has direct
-connectivity to the metadata database.
+connectivity to the managed Git repositories.
 
 == EXAMPLES
 To convert the local username of every account to lower case:
diff --git a/Documentation/pgm-daemon.txt b/Documentation/pgm-daemon.txt
index 0b1a3e5..ad07cfa 100644
--- a/Documentation/pgm-daemon.txt
+++ b/Documentation/pgm-daemon.txt
@@ -19,14 +19,8 @@
 
 == DESCRIPTION
 Runs the Gerrit network daemon on the local system, configured as
-per the local copy of link:config-gerrit.html[gerrit.config].
-
-The path to gerrit.config is read from the metadata database,
-which requires that all slaves (and master) reading from the same
-database must place gerrit.config at the same location on the local
-filesystem.  However, any option within gerrit.config, including
-link:config-gerrit.html#gerrit.basePath[gerrit.basePath] may be set
-to different values.
+per the local copy of link:config-gerrit.html[gerrit.config] located under
+`<SITE_PATH>/etc`.
 
 == OPTIONS
 
diff --git a/Documentation/pgm-gsql.txt b/Documentation/pgm-gsql.txt
deleted file mode 100644
index 4986522..0000000
--- a/Documentation/pgm-gsql.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-= gsql
-
-== NAME
-gsql - Administrative interface to idle database
-
-== SYNOPSIS
-[verse]
---
-_java_ -jar gerrit.war _gsql_
-  -d <SITE_PATH>
---
-
-== DESCRIPTION
-Interactive query support against the configured SQL database.
-All SQL statements are supported, including SELECT, UPDATE, INSERT,
-DELETE and ALTER.
-
-This command is primarily intended to access a local H2 database
-which is not currently open by a Gerrit daemon.  To access an open
-database use link:cmd-gsql.html[gerrit gsql] over SSH.
-
-== OPTIONS
-
--d::
---site-path::
-	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libraries and log files.
-
-== CONTEXT
-This command can only be run on a server which has direct
-connectivity to the metadata database, and local access to the
-managed Git repositories.
-
-== EXAMPLES
-To manually correct a user's SSH user name:
-
-----
-	$ java -jar gerrit.war gsql
-	Welcome to Gerrit Code Review v2.0.25
-	(PostgreSQL 8.3.8)
-
-	Type '\h' for help.  Type '\r' to clear the buffer.
-
-	gerrit> update accounts set ssh_user_name = 'alice' where account_id=1;
-	UPDATE 1; 1 ms
-	gerrit> \q
-	Bye
-----
-
-GERRIT
-------
-Part of link:index.html[Gerrit Code Review]
-
-SEARCHBOX
----------
diff --git a/Documentation/pgm-index.txt b/Documentation/pgm-index.txt
index d61cc0b..dde0231 100644
--- a/Documentation/pgm-index.txt
+++ b/Documentation/pgm-index.txt
@@ -15,9 +15,6 @@
 link:pgm-daemon.html[daemon]::
 	Gerrit HTTP, SSH network server.
 
-link:pgm-gsql.html[gsql]::
-	Administrative interface to idle database.
-
 link:pgm-prolog-shell.html[prolog-shell]::
 	Simple interactive Prolog interpreter.
 
diff --git a/Documentation/pgm-init.txt b/Documentation/pgm-init.txt
index 9a16cdf..f6c3c85 100644
--- a/Documentation/pgm-init.txt
+++ b/Documentation/pgm-init.txt
@@ -28,7 +28,7 @@
 into a newly created `$site_path`.
 
 If run in an existing `$site_path`, init upgrades existing resources
-(e.g. DB schema, plugins) as necessary.
+(e.g. NoteDb schema, plugins) as necessary.
 
 == OPTIONS
 -b::
@@ -100,8 +100,7 @@
 	folder.
 
 == CONTEXT
-This command can only be run on a server which has direct
-connectivity to the metadata database, and local access to the
+This command can only be run on a server which has direct local access to the
 managed Git repositories.
 
 GERRIT
diff --git a/Documentation/pgm-rulec.txt b/Documentation/pgm-rulec.txt
index 1b50812..2a987205 100644
--- a/Documentation/pgm-rulec.txt
+++ b/Documentation/pgm-rulec.txt
@@ -33,8 +33,7 @@
 	Compile rules for the specified project.
 
 == CONTEXT
-This command can only be run on a server which has direct
-connectivity to the metadata database, and local access to the
+This command can only be run on a server which has local access to the
 managed Git repositories.
 
 Caching needs to be enabled. See
diff --git a/Documentation/project-configuration.txt b/Documentation/project-configuration.txt
index f76b5e4..23030a4 100644
--- a/Documentation/project-configuration.txt
+++ b/Documentation/project-configuration.txt
@@ -48,198 +48,7 @@
 [[project_options]]
 == Project Options
 
-[[submit_type]]
-=== Submit Type
-
-The method Gerrit uses to submit a change to a project can be
-modified by any project owner through the project console, `Projects` >
-`List` > my/project. In general, a submitted change is only merged if all
-its dependencies are also submitted, with exceptions documented below.
-The following submit types are supported:
-
-[[submit_type_inherit]]
-* Inherit
-+
-This is the default for new projects, unless overridden by a global
-link:config-gerrit.html#repository.name.defaultSubmitType[`defaultSubmitType` option].
-+
-Inherit the submit type from the parent project. In `All-Projects`, this
-is equivalent to link:#merge_if_necessary[Merge If Necessary].
-
-[[fast_forward_only]]
-* Fast Forward Only
-+
-With this method no merge commits are produced. All merges must
-be handled on the client, prior to uploading to Gerrit for review.
-+
-To submit a change, the change must be a strict superset of the
-destination branch.  That is, the change must already contain the
-tip of the destination branch at submit time.
-
-[[merge_if_necessary]]
-* Merge If Necessary
-+
-If the change being submitted is a strict superset of the destination
-branch, then the branch is fast-forwarded to the change.  If not,
-then a merge commit is automatically created.  This is identical
-to the classical `git merge` behavior, or `git merge --ff`.
-
-[[always_merge]]
-* Always Merge
-+
-Always produce a merge commit, even if the change is a strict
-superset of the destination branch.  This is identical to the
-behavior of `git merge --no-ff`, and may be useful if the
-project needs to follow submits with `git log --first-parent`.
-
-[[cherry_pick]]
-* Cherry Pick
-+
-Always cherry pick the patch set, ignoring the parent lineage
-and instead creating a brand new commit on top of the current
-branch head.
-+
-When cherry picking a change, Gerrit automatically appends onto the
-end of the commit message a short summary of the change's approvals,
-and a URL link back to the change on the web.  The committer header
-is also set to the submitter, while the author header retains the
-original patch set author.
-+
-Note that Gerrit ignores dependencies between changes when using this
-submit type unless
-link:config-gerrit.html#change.submitWholeTopic[`change.submitWholeTopic`]
-is enabled and depending changes share the same topic. So generally
-submitters must remember to submit changes in the right order when using this
-submit type. If all you want is extra information in the commit message,
-consider using the Rebase Always submit strategy.
-
-[[rebase_if_necessary]]
-* Rebase If Necessary
-+
-If the change being submitted is a strict superset of the destination
-branch, then the branch is fast-forwarded to the change.  If not,
-then the change is automatically rebased and then the branch is
-fast-forwarded to the change.
-
-When Gerrit tries to do a merge, by default the merge will only
-succeed if there is no path conflict.  A path conflict occurs when
-the same file has also been changed on the other side of the merge.
-
-[[rebase_always]]
-* Rebase Always
-+
-Basically, the same as Rebase If Necessary, but it creates a new patchset even
-if fast forward is possible AND like Cherry Pick it ensures footers such as
-Change-Id, Reviewed-On, and others are present in resulting commit that is
-merged.
-
-Thus, Rebase Always can be considered similar to Cherry Pick, but with
-the important distinction that Rebase Always does not ignore dependencies.
-
-[[content_merge]]
-If `Allow content merges` is enabled, Gerrit will try
-to do a content merge when a path conflict occurs.
-
-[[project-state]]
-=== State
-
-This setting defines the state of the project. A project can have the
-following states:
-
-- `Active`:
-+
-The project is active and users can see and modify the project according
-to their access rights on the project.
-
-- `Read Only`:
-+
-The project is read only and all modifying operations on it are
-disabled. E.g. this means that pushing to this project fails for all
-users even if they have push permissions assigned on it.
-+
-Setting a project to this state is an easy way to temporary close a
-project, as you can keep all write access rights in place and they will
-become active again as soon as the project state is set back to
-`Active`.
-+
-This state also makes sense if a project was moved to another location.
-In this case all new development should happen in the new project and
-you want to prevent that somebody accidentally works on the old
-project, while keeping the old project around for old references.
-
-- `Hidden`:
-+
-The project is hidden and only visible to project owners. Other users
-are not able to see the project even if they have read permissions
-granted on the project.
-
-=== Use target branch when determining new changes to open
-
-The `create-new-change-for-all-not-in-target` option provides a
-convenience for selecting link:user-upload.html#base[the merge base]
-by setting it automatically to the target branch's tip so you can
-create new changes for all commits not in the target branch.
-
-This option is disabled if the tip of the push is a merge commit.
-
-This option also only works if there are no merge commits in the
-commit chain, in such cases it fails warning the user that such
-pushes can only be performed by manually specifying
-link:user-upload.html#base[bases]
-
-This option is useful if you want to push a change to your personal
-branch first and for review to another branch for example. Or in cases
-where a commit is already merged into a branch and you want to create
-a new open change for that commit on another branch.
-
-[[require-change-id]]
-=== Require Change-Id
-
-The `Require Change-Id in commit message` option defines whether a
-link:user-changeid.html[Change-Id] in the commit message is required
-for pushing a commit for review. If this option is set, trying to push
-a commit for review that doesn't contain a Change-Id in the commit
-message fails with link:error-missing-changeid.html[missing Change-Id
-in commit message footer].
-
-It is recommended to set this option and use a
-link:user-changeid.html#create[commit-msg hook] (or other client side
-tooling like EGit) to automatically generate Change-Id's for new
-commits. This way the Change-Id is automatically in place when changes
-are reworked or rebased and uploading new patch sets gets easy.
-
-If this option is not set, commits can be uploaded without a Change-Id,
-but then users have to remember to copy the assigned Change-Id from the
-change screen and insert it manually into the commit message when they
-want to upload a second patch set.
-
-=== Maximum Git Object Size Limit
-
-This option defines the maximum allowed Git object size that
-receive-pack will accept. If an object is larger than the given size
-the pack-parsing will abort and the push operation will fail.
-
-With this option users can be prevented from uploading commits that
-contain files which are too large.
-
-Normally the link:config-gerrit.html#receive.maxObjectSizeLimit[maximum
-Git object size limit] is configured globally for a Gerrit server. At
-the project level, the maximum Git object size limit can be further
-reduced, but not extended. The displayed effective limit shows the
-maximum Git object size limit that is actually used on the project.
-
-The defined maximum Git object size limit is inherited by any child
-project.
-
-[[require-signed-off-by]]
-=== Require Signed-off-by
-
-The `Require Signed-off-by in commit message` option defines whether a
-link:user-signedoffby.html[Signed-off-by] line in the commit message is
-required for pushing a commit. If this option is set, trying to push a
-commit that doesn't contain a Signed-off-by line in the commit message
-fails with link:error-not-signed-off-by.html[not Signed-off-by
-author/committer/uploader in commit message footer].
+See details at link:config-project-config.html#project-section[project section].
 
 [[branch-admin]]
 == Branch Administration
diff --git a/Documentation/prolog-cookbook.txt b/Documentation/prolog-cookbook.txt
index 19ed98a..e6cd822 100644
--- a/Documentation/prolog-cookbook.txt
+++ b/Documentation/prolog-cookbook.txt
@@ -1044,10 +1044,7 @@
     gerrit:uploader(U),
     R = label('Is-Pure-Revert', ok(U)).
 
-submit_rule(submit(R)) :-
-    gerrit:pure_revert(U),
-    U /= 1,
-    R = label('Is-Pure-Revert', need(_)).
+submit_rule(submit(label('Is-Pure-Revert', need(_)))).
 ----
 
 Suppose currently a change is submittable if it gets `+2` for `Code-Review`
@@ -1058,21 +1055,20 @@
 [source,prolog]
 ----
 submit_rule(submit(CR, V, R)) :-
-    base(CR, V),
-    gerrit:pure_revert(1),
-    !,
-    gerrit:uploader(U),
-    R = label('Is-Pure-Revert', ok(U)).
-
-submit_rule(submit(CR, V, R)) :-
-    base(CR, V),
-    gerrit:pure_revert(U),
-    U /= 1,
-    R = label('Is-Pure-Revert', need(_)).
+  base(CR, V),
+  set_pure_revert_label(R).
 
 base(CR, V) :-
-    gerrit:max_with_block(-2, 2, 'Code-Review', CR),
-    gerrit:max_with_block(-1, 1, 'Verified', V).
+  gerrit:max_with_block(-2, 2, 'Code-Review', CR),
+  gerrit:max_with_block(-1, 1, 'Verified', V).
+
+set_pure_revert_label(R) :-
+  gerrit:pure_revert(1),
+  !,
+  gerrit:uploader(U),
+  R = label('Is-Pure-Revert', ok(U)).
+
+set_pure_revert_label(label('Is-Pure-Revert', need(_))).
 ----
 
 Note that a new label as `Is-Pure-Revert` should not be configured.
diff --git a/Documentation/quota.txt b/Documentation/quota.txt
new file mode 100644
index 0000000..a647e33
--- /dev/null
+++ b/Documentation/quota.txt
@@ -0,0 +1,50 @@
+= Gerrit Code Review - Quota
+
+Gerrit does not provide out of the box quota enforcement. However, it does
+support an extension mechanism for plugins to hook into to provide this
+functionality. The most prominent plugin is the
+link:https://gerrit.googlesource.com/plugins/quota/[Quota Plugin].
+
+This documentation is intended to be read by plugin developers. It contains all
+quota requests implemented in Gerrit-core as well as the metadata that they have
+associated.
+
+== Quota Groups
+
+The following quota groups are defined in core Gerrit:
+
+=== REST API
+[[rest-api]]
+
+The REST API enforces quota after the resource was parsed (if applicable) and before the
+endpoint's logic is executed. This enables quota enforcer implementations to throttle calls
+to specific endpoints while knowing the general context (user and top-level entity such as
+change, project or account).
+
+If the quota enforcer wants to throttle HTTP requests, they should use
+link:quota.html#http-requests[HTTP Requests] instead.
+
+The quota groups used for checking follow the exact definition of the endoint in the REST
+API, but remove all IDs. The schema is:
+
+/restapi/<ENDPOINT>:<HTTP-METHOD>
+
+Examples:
+
+[options="header",cols="1,6"]
+|=======================
+|HTTP call                                 |Quota Group                    |Metadata
+|GET /a/changes/1/revisions/current/detail |/changes/revisions/detail:GET  |CurrentUser, Change.Id, Project.NameKey
+|POST /a/changes/                          |/changes/:POST                 |CurrentUser
+|GET /a/accounts/self/detail               |/accounts/detail:GET           |CurrentUser, Account.Id
+|=======================
+
+The user provided in the check's metadata is always the calling user (having the
+impersonation bit and real user set in case the user is impersonating another user).
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
+
+SEARCHBOX
+---------
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt
index de5f278..c326b66 100644
--- a/Documentation/rest-api-accounts.txt
+++ b/Documentation/rest-api-accounts.txt
@@ -2141,12 +2141,37 @@
 
 This can be:
 
+* `self` or `me` for the calling user
+* a bare account ID ("18419")
+* an account ID following a name in parentheses ("Full Name (18419)")
 * a string of the format "Full Name <email@example.com>"
 * just the email address ("email@example")
-* a full name if it is unique ("Full Name")
-* an account ID ("18419")
+* a full name ("Full Name")
 * a user name ("username")
-* `self` for the calling user
+
+In all cases, accounts that are not
+link:config-gerrit.txt#accounts.visibility[visible] to the calling user are not
+considered.
+
+In all cases _except_ a bare account ID and `self`/`me`, inactive accounts are
+not considered. Inactive accounts should only be referenced by bare ID.
+
+If the input is a bare account ID, this will always resolve to exactly
+one account if there is a visible account with that ID, and zero accounts
+otherwise. (This is true even in corner cases like a user having a full name
+which is exactly a numeric account ID belonging to a different user; such a user
+cannot be identified by this number.)
+
+If the identifier is ambiguous or only refers to inactive accounts, the error
+message from the API should contain a human-readable description of how to
+disambiguate the request.
+
+*Note*: Except as noted above, callers should not rely on the particular
+priorities of any of the identifiers in the account resolution algorithm. Any
+other formats may be subject to future deprecation. If callers require specific
+searching semantics, they should use the link:#query-account[Query Account]
+endpoint to resolve a string to one or more accounts, then access the API using
+the account ID.
 
 [[capability-id]]
 === \{capability-id\}
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index d500480..a994711 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -309,6 +309,14 @@
 * `SKIP_MERGEABLE`: skip the `mergeable` field in
 link:#change-info[ChangeInfo]. For fast moving projects, this field must
 be recomputed often, which is slow for projects with big trees.
++
+When link:config-gerrit.html#change.api.excludeMergeableInChangeInfo[
+`change.api.excludeMergeableInChangeInfo`] is set in the `gerrit.config`,
+the `mergeable` field will always be omitted and `SKIP_MERGEABLE` has no
+effect.
++
+A change's mergeability can be requested separately by calling the
+link:#get-mergeable[get-mergeable] endpoint.
 --
 
 [[submittable]]
@@ -350,6 +358,11 @@
   as link:#tracking-id-info[TrackingIdInfo].
 --
 
+[[no-limit]]
+--
+* `NO-LIMIT`: Return all results
+--
+
 .Request
 ----
   GET /changes/?q=97&o=CURRENT_REVISION&o=CURRENT_COMMIT&o=CURRENT_FILES&o=DOWNLOAD_COMMANDS HTTP/1.0
@@ -2200,8 +2213,8 @@
 'POST /changes/link:#change-id[\{change-id\}]/private'
 --
 
-Marks the change to be private. Changes may only be marked private by the
-owner or site administrators.
+Marks the change to be private. Only open changes can be marked private.
+Changes may only be marked private by the owner or site administrators.
 
 A message can be specified in the request body inside a
 link:#private-input[PrivateInput] entity.
@@ -5760,12 +5773,14 @@
 Whether the change was reviewed by the calling user.
 Only set if link:#reviewed[reviewed] is requested.
 |`submit_type`        |optional|
-The link:project-configuration.html#submit_type[submit type] of the change. +
+The link:config-project-config.html#submit-type[submit type] of the change. +
 Not set for merged changes.
 |`mergeable`          |optional|
 Whether the change is mergeable. +
 Not set for merged changes, if the change has not yet been tested, or
-if the link:#skip_mergeable[skip_mergeable] option is set.
+if the link:#skip_mergeable[skip_mergeable] option is set or when
+link:config-gerrit.html#change.api.excludeMergeableInChangeInfo[change.api.excludeMergeableInChangeInfo]
+is set.
 |`submittable`        |optional|
 Whether the change has been approved by the project submit rules. +
 Only set if link:#submittable[requested].
@@ -5773,8 +5788,12 @@
 Number of inserted lines.
 |`deletions`          ||
 Number of deleted lines.
+|`total_comment_count`  |optional|
+Total number of inline comments across all patch sets. Not set if the current
+change index doesn't have the data.
 |`unresolved_comment_count`  |optional|
-Number of unresolved comments. Not set if the current change index doesn't have the data.
+Number of unresolved inline comment threads across all patch sets. Not set if
+the current change index doesn't have the data.
 |`_number`            ||The legacy numeric ID of the change.
 |`owner`              ||
 The owner of the change as an link:rest-api-accounts.html#account-info[
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index 3ec989e..3ea3ba1 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -126,10 +126,7 @@
     "gerrit": {
       "all_projects": "All-Projects",
       "all_users": "All-Users"
-      "doc_search": true,
-      "web_uis": [
-        "gwt"
-      ]
+      "doc_search": true
     },
     "sshd": {},
     "suggest": {
@@ -1805,9 +1802,6 @@
 |`report_bug_text`   |optional, not set if default|
 link:config-gerrit.html#gerrit.reportBugText[Display text for report
 bugs link].
-|`web_uis`           ||
-List of web UIs supported by the HTTP server. Possible values are `GWT`
-and `POLYGERRIT`.
 |=================================
 
 [[hit-ration-info]]
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt
index a36947b..f69c4ae 100644
--- a/Documentation/rest-api-projects.txt
+++ b/Documentation/rest-api-projects.txt
@@ -1356,25 +1356,6 @@
 Ref(ref)::
 The branch for which to check access. This must be given if `perm` is specified.
 
-[[check-access-post]]
-=== Check Access (POST)
-
-This endpoint can also be accessed as a POST request (deprecated). In
-this case, the input for the access checks must be provided in the
-request body inside a link:#access-check-input[AccessCheckInput]
-entity.
-
-.Request
-----
-  POST /projects/MyProject/check.access HTTP/1.0
-  Content-Type: application/json; charset=UTF-8
-
-  {
-    "account": "Kristen.Burns@gerritcodereview.com",
-    "ref": "refs/heads/secret/bla"
-  }
-----
-
 [[index]]
 === Index project
 
@@ -2934,21 +2915,6 @@
 |`message`                   |optional|A clarifying message if `status` is not 200.
 |=========================================
 
-[[access-check-input]]
-=== AccessCheckInput
-The `AccessCheckInput` entity is either an account or
-(account, ref) tuple for which we want to check access.
-
-[options="header",cols="1,^1,5"]
-|=========================================
-|Field Name                  ||Description
-|`account`                   ||The account for which to check access
-|`ref`                       |optional|The refname for which to check
-access
-|`permission`                |optional|The ref permission for which to
-check. This defaults to `read`. If given, it `ref` must be given too.
-|=========================================
-
 [[auto_closeable_changes_check_input]]
 === AutoCloseableChangesCheckInput
 The `AutoCloseableChangesCheckInput` entity contains options for running
@@ -3169,9 +3135,6 @@
 Map with the comment link configurations of the project. The name of
 the comment link configuration is mapped to a link:#commentlink-info[
 CommentlinkInfo] entity.
-|`theme`                                   |optional|
-The theme that is configured for the project as a link:#theme-info[
-ThemeInfo] entity.
 |`plugin_config`                           |optional|
 Plugin configuration as map which maps the plugin name to a map of
 parameter names to link:#config-parameter-info[ConfigParameterInfo]
@@ -3660,7 +3623,7 @@
 
 [[submit-type-info]]
 === SubmitTypeInfo
-Information about the link:project-configuration.html#submit_type[default submit
+Information about the link:config-project-config.html#submit-type[default submit
 type of a project], taking into account project inheritance.
 
 Valid values for each field are `MERGE_IF_NECESSARY`, `FAST_FORWARD_ONLY`,
@@ -3723,21 +3686,6 @@
 |=========================
 
 
-[[theme-info]]
-=== ThemeInfo
-The `ThemeInfo` entity describes a theme.
-
-[options="header",cols="1,^2,4"]
-|=============================
-|Field Name      ||Description
-|`css`           |optional|
-The path to the `GerritSite.css` file.
-|`header`        |optional|
-The path to the `GerritSiteHeader.html` file.
-|`footer`        |optional|
-The path to the `GerritSiteFooter.html` file.
-|=============================
-
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/rest-api.txt b/Documentation/rest-api.txt
index 8f6a47b..a8ab353 100644
--- a/Documentation/rest-api.txt
+++ b/Documentation/rest-api.txt
@@ -191,6 +191,11 @@
 "`422 Unprocessable Entity`" is returned if the ID of a resource that is
 specified in the request body cannot be resolved.
 
+==== 429 Too Many Requests
+"`429 Too Many Requests`" is returned if the request exhausted any set
+quota limits. Depending on the exhausted quota, the request may be retried
+with exponential backoff.
+
 [[tracing]]
 === Request Tracing
 For each REST endpoint tracing can be enabled by setting the
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index 48d331b..cafd5ca 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -277,6 +277,8 @@
 ones using a bracket expression). For example, to match all XML
 files named like 'name1.xml', 'name2.xml', and 'name3.xml' use
 `file:"^name[1-3].xml"`.
++
+Slash ('/') is used path separator.
 
 [[file]]
 file:'NAME', f:'NAME'::
@@ -290,6 +292,46 @@
 Regular expression matching can be enabled by starting the string
 with `^`. In this mode `file:` is an alias of `path:` (see above).
 
+[[extension]]
+extension:'EXT', ext:'EXT'::
++
+Matches any change touching a file with extension 'EXT', case-insensitive. The
+extension is defined as the portion of the filename following the final `.`.
+Files with no `.` in their name have no extension and can be matched by an
+empty string.
+
+[[onlyextensions]]
+onlyextensions:'EXT_LIST', onlyexts:'EXT_LIST'::
++
+Matches any change touching only files with extensions that are listed in
+'EXT_LIST' (comma-separated list). The matching is done case-insensitive.
+An extension is defined as the portion of the filename following the final `.`.
+Files with no `.` in their name have no extension and can be matched by an
+empty string.
+
+[[directory]]
+directory:'DIR', dir:'DIR'::
++
+Matches any change where the current patch set touches a file in the directory
+'DIR'. The matching is done case-insensitive. 'DIR' can be a full directory
+name, a directory prefix or any combination of intermediate directory segments.
+E.g. a change that touches a file in the directory 'a/b/c' matches for 'a/b/c',
+'a', 'a/b', 'b', 'b/c' and 'c'.
++
+Slash ('/') is used path separator. Leading and trailing slashes are allowed
+but are not mandatory.
++
+If 'DIR' starts with `^` it matches directories and directory segments by
+regular expression. The link:http://www.brics.dk/automaton/[dk.brics.automaton
+library] is used for evaluation of such patterns.
+
+[[footer]]
+footer:'FOOTER'::
++
+Matches any change that has 'FOOTER' as footer in the commit message of the
+current patch set. 'FOOTER' can be specified verbatim ('<key>: <value>', must
+be quoted) or as '<key>=<value>'. The matching is done case-insensitive.
+
 [[star]]
 star:'LABEL'::
 +
diff --git a/Documentation/user-upload.txt b/Documentation/user-upload.txt
index 751e886..56602e2 100644
--- a/Documentation/user-upload.txt
+++ b/Documentation/user-upload.txt
@@ -732,7 +732,7 @@
 Gerrit to provide magical refs, such as `+refs/for/*+` for new
 change submission and `+refs/changes/*+` for change replacement.
 When a push request is received to create a ref in one of these
-namespaces Gerrit performs its own logic to update the database,
+namespaces Gerrit performs its own logic to update the review metadata,
 and then lies to the client about the result of the operation.
 A successful result causes the client to believe that Gerrit has
 created the ref, but in reality Gerrit hasn't created the ref at all.
diff --git a/WORKSPACE b/WORKSPACE
index 5eab921..0aa31f6 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,6 @@
 load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
 load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
 load("//tools/bzl:maven_jar.bzl", "GERRIT", "MAVEN_LOCAL", "maven_jar")
-load("//lib/codemirror:cm.bzl", "CM_VERSION", "DIFF_MATCH_PATCH_VERSION")
 load("//plugins:external_plugin_deps.bzl", "external_plugin_deps")
 
 http_archive(
@@ -70,12 +69,6 @@
 
 # Dependencies for PolyGerrit local dev server.
 go_repository(
-    name = "com_github_robfig_soy",
-    commit = "82face14ebc0883b4ca9c901b5aaf3738b9f6a24",
-    importpath = "github.com/robfig/soy",
-)
-
-go_repository(
     name = "com_github_howeyc_fsnotify",
     commit = "441bbc86b167f3c1f4786afae9931403b99fdacf",
     importpath = "github.com/howeyc/fsnotify",
@@ -108,24 +101,24 @@
     sha1 = "83cd2cd674a217ade95a4bb83a8a14f351f48bd0",
 )
 
-GUICE_VERS = "4.2.1"
+GUICE_VERS = "4.2.2"
 
 maven_jar(
     name = "guice-library",
     artifact = "com.google.inject:guice:" + GUICE_VERS,
-    sha1 = "f77dfd89318fe3ff293bafceaa75fbf66e4e4b10",
+    sha1 = "6dacbe18e5eaa7f6c9c36db33b42e7985e94ce77",
 )
 
 maven_jar(
     name = "guice-assistedinject",
     artifact = "com.google.inject.extensions:guice-assistedinject:" + GUICE_VERS,
-    sha1 = "d327e4aee7c96f08cd657c17da231a1f4a8999ac",
+    sha1 = "c33fb10080d58446f752b4fcfff8a5fabb80a449",
 )
 
 maven_jar(
     name = "guice-servlet",
     artifact = "com.google.inject.extensions:guice-servlet:" + GUICE_VERS,
-    sha1 = "3927e462f923b0c672fdb045c5645bca4beab5c0",
+    sha1 = "0d0054bdd812224078357a9b11409e43d182a046",
 )
 
 maven_jar(
@@ -146,61 +139,6 @@
     sha1 = "021a212688ec94fe77aff74ab34cc74f6f940e60",
 )
 
-GWT_VERS = "2.8.2"
-
-maven_jar(
-    name = "user",
-    artifact = "com.google.gwt:gwt-user:" + GWT_VERS,
-    sha1 = "a2b9be2c996a658c4e009ba652a9c6a81c88a797",
-)
-
-maven_jar(
-    name = "dev",
-    artifact = "com.google.gwt:gwt-dev:" + GWT_VERS,
-    sha1 = "7a87e060bbf129386b7ae772459fb9f87297c332",
-)
-
-maven_jar(
-    name = "javax-validation",
-    artifact = "javax.validation:validation-api:1.0.0.GA",
-    sha1 = "b6bd7f9d78f6fdaa3c37dae18a4bd298915f328e",
-    src_sha1 = "7a561191db2203550fbfa40d534d4997624cd369",
-)
-
-maven_jar(
-    name = "jsinterop-annotations",
-    artifact = "com.google.jsinterop:jsinterop-annotations:1.0.2",
-    sha1 = "abd7319f53d018e11108a88f599bd16492448dd2",
-    src_sha1 = "33716f8aef043f2f02b78ab4a1acda6cd90a7602",
-)
-
-maven_jar(
-    name = "ant",
-    artifact = "ant:ant:1.6.5",
-    attach_source = False,
-    sha1 = "7d18faf23df1a5c3a43613952e0e8a182664564b",
-)
-
-maven_jar(
-    name = "colt",
-    artifact = "colt:colt:1.2.0",
-    attach_source = False,
-    sha1 = "0abc984f3adc760684d49e0f11ddf167ba516d4f",
-)
-
-maven_jar(
-    name = "tapestry",
-    artifact = "tapestry:tapestry:4.0.2",
-    attach_source = False,
-    sha1 = "e855a807425d522e958cbce8697f21e9d679b1f7",
-)
-
-maven_jar(
-    name = "w3c-css-sac",
-    artifact = "org.w3c.css:sac:1.3",
-    sha1 = "cdb2dcb4e22b83d6b32b93095f644c3462739e82",
-)
-
 load("//lib/jgit:jgit.bzl", "jgit_repos")
 
 jgit_repos()
@@ -233,13 +171,6 @@
 )
 
 maven_jar(
-    name = "gwtjsonrpc",
-    artifact = "com.google.gerrit:gwtjsonrpc:1.11",
-    sha1 = "0990e7eec9eec3a15661edcf9232acbac4aeacec",
-    src_sha1 = "a682afc46284fb58197a173cb5818770a1e7834a",
-)
-
-maven_jar(
     name = "gson",
     artifact = "com.google.code.gson:gson:2.8.5",
     sha1 = "f645ed69d595b24d4cf8b3fbb64cc505bede8829",
@@ -247,9 +178,9 @@
 
 maven_jar(
     name = "gwtorm-client",
-    artifact = "com.google.gerrit:gwtorm:1.18",
-    sha1 = "f326dec463439a92ccb32f05b38345e21d0b5ecf",
-    src_sha1 = "e0b973d5cafef3d145fa80cdf032fcead1186d29",
+    artifact = "com.google.gerrit:gwtorm:1.20",
+    sha1 = "a4809769b710bc8ce3f203125630b8419f0e58b0",
+    src_sha1 = "cb63296276ce3228b2d83a37017a99e38ad8ed42",
 )
 
 maven_jar(
@@ -267,6 +198,12 @@
 )
 
 maven_jar(
+    name = "guava-failureaccess",
+    artifact = "com.google.guava:failureaccess:1.0.1",
+    sha1 = "1dcf1de382a0bf95a3d8b0849546c88bac1292c9",
+)
+
+maven_jar(
     name = "j2objc",
     artifact = "com.google.j2objc:j2objc-annotations:1.1",
     sha1 = "ed28ded51a8b1c6b112568def5f4b455e6809019",
@@ -355,8 +292,14 @@
 
 maven_jar(
     name = "commons-lang3",
-    artifact = "org.apache.commons:commons-lang3:3.6",
-    sha1 = "9d28a6b23650e8a7e9063c04588ace6cf7012c17",
+    artifact = "org.apache.commons:commons-lang3:3.8.1",
+    sha1 = "6505a72a097d9270f7a9e7bf42c4238283247755",
+)
+
+maven_jar(
+    name = "commons-text",
+    artifact = "org.apache.commons:commons-text:1.2",
+    sha1 = "74acdec7237f576c4803fff0c1008ab8a3808b2b",
 )
 
 maven_jar(
@@ -391,6 +334,33 @@
     sha1 = "959a0c62f9a5c2309e0ad0b0589c74d69e101241",
 )
 
+COMMONMARK_VERS = "0.10.0"
+
+# commonmark must match the version used in Gitiles
+maven_jar(
+    name = "commonmark",
+    artifact = "com.atlassian.commonmark:commonmark:" + COMMONMARK_VERS,
+    sha1 = "119cb7bedc3570d9ecb64ec69ab7686b5c20559b",
+)
+
+maven_jar(
+    name = "cm-autolink",
+    artifact = "com.atlassian.commonmark:commonmark-ext-autolink:" + COMMONMARK_VERS,
+    sha1 = "a6056a5efbd68f57d420bc51bbc54b28a5d3c56b",
+)
+
+maven_jar(
+    name = "gfm-strikethrough",
+    artifact = "com.atlassian.commonmark:commonmark-ext-gfm-strikethrough:" + COMMONMARK_VERS,
+    sha1 = "40837da951b421b545edddac57012e15fcc9e63c",
+)
+
+maven_jar(
+    name = "gfm-tables",
+    artifact = "com.atlassian.commonmark:commonmark-ext-gfm-tables:" + COMMONMARK_VERS,
+    sha1 = "c075db2a3301100cf70c7dced8ecf86b494458a2",
+)
+
 FLEXMARK_VERS = "0.34.18"
 
 maven_jar(
@@ -543,7 +513,7 @@
     sha1 = "31e2e1fbe8273d7c913506eafeb06b1a7badb062",
 )
 
-# Transitive dependency of flexmark
+# Transitive dependency of flexmark and gitiles
 maven_jar(
     name = "autolink",
     artifact = "org.nibor.autolink:autolink:0.7.0",
@@ -586,50 +556,50 @@
     sha1 = "5e3bda828a80c7a21dfbe2308d1755759c2fd7b4",
 )
 
-OW2_VERS = "6.2.1"
+OW2_VERS = "7.0"
 
 maven_jar(
     name = "ow2-asm",
     artifact = "org.ow2.asm:asm:" + OW2_VERS,
-    sha1 = "c01b6798f81b0fc2c5faa70cbe468c275d4b50c7",
+    sha1 = "d74d4ba0dee443f68fb2dcb7fcdb945a2cd89912",
 )
 
 maven_jar(
     name = "ow2-asm-analysis",
     artifact = "org.ow2.asm:asm-analysis:" + OW2_VERS,
-    sha1 = "e8b876c5ccf226cae2f44ed2c436ad3407d0ec1d",
+    sha1 = "4b310d20d6f1c6b7197a75f1b5d69f169bc8ac1f",
 )
 
 maven_jar(
     name = "ow2-asm-commons",
     artifact = "org.ow2.asm:asm-commons:" + OW2_VERS,
-    sha1 = "eaf31376d741a3e2017248a4c759209fe25c77d3",
+    sha1 = "478006d07b7c561ae3a92ddc1829bca81ae0cdd1",
 )
 
 maven_jar(
     name = "ow2-asm-tree",
     artifact = "org.ow2.asm:asm-tree:" + OW2_VERS,
-    sha1 = "332b022092ecec53cdb6272dc436884b2d940615",
+    sha1 = "29bc62dcb85573af6e62e5b2d735ef65966c4180",
 )
 
 maven_jar(
     name = "ow2-asm-util",
     artifact = "org.ow2.asm:asm-util:" + OW2_VERS,
-    sha1 = "400d664d7c92a659d988c00cb65150d1b30cf339",
+    sha1 = "18d4d07010c24405129a6dbb0e92057f8779fb9d",
 )
 
-AUTO_VALUE_VERSION = "1.6.2"
+AUTO_VALUE_VERSION = "1.6.3"
 
 maven_jar(
     name = "auto-value",
     artifact = "com.google.auto.value:auto-value:" + AUTO_VALUE_VERSION,
-    sha1 = "e7eae562942315a983eea3e191b72d755c153620",
+    sha1 = "8edb6675b9c09ffdcc19937428e7ef1e3d066e12",
 )
 
 maven_jar(
     name = "auto-value-annotations",
     artifact = "com.google.auto.value:auto-value-annotations:" + AUTO_VALUE_VERSION,
-    sha1 = "ed193d86e0af90cc2342aedbe73c5d86b03fa09b",
+    sha1 = "b88c1bb7f149f6d2cc03898359283e57b08f39cc",
 )
 
 # Transitive dependency of commons-compress
@@ -726,14 +696,30 @@
     sha1 = "f7be08ec23c21485b9b5a1cf1654c2ec8c58168d",
 )
 
+GITILES_VERS = "0.2-7"
+
 maven_jar(
     name = "blame-cache",
-    artifact = "com/google/gitiles:blame-cache:0.2-7",
+    artifact = "com.google.gitiles:blame-cache:" + GITILES_VERS,
     attach_source = False,
     repository = GERRIT,
     sha1 = "8170f33b8b1db6f55e41d7069fa050a4d102a62b",
 )
 
+maven_jar(
+    name = "gitiles-servlet",
+    artifact = "com.google.gitiles:gitiles-servlet:" + GITILES_VERS,
+    repository = GERRIT,
+    sha1 = "f23b22cb27fe5c4a78f761492082159d17873f57",
+)
+
+# prettify must match the version used in Gitiles
+maven_jar(
+    name = "prettify",
+    artifact = "com.github.twalcari:java-prettify:1.2.2",
+    sha1 = "b8ba1c1eb8b2e45cfd465d01218c6060e887572e",
+)
+
 # Keep this version of Soy synchronized with the version used in Gitiles.
 maven_jar(
     name = "soy",
@@ -867,30 +853,30 @@
     sha1 = "42a25dc3219429f0e5d060061f71acb49bf010a0",
 )
 
-TRUTH_VERS = "0.42"
+TRUTH_VERS = "0.43"
 
 maven_jar(
     name = "truth",
     artifact = "com.google.truth:truth:" + TRUTH_VERS,
-    sha1 = "b5768f644b114e6cf5c3962c2ebcb072f788dcbb",
+    sha1 = "0cb9105957368f68d5fd771045bfa27d4a534836",
 )
 
 maven_jar(
     name = "truth-java8-extension",
     artifact = "com.google.truth.extensions:truth-java8-extension:" + TRUTH_VERS,
-    sha1 = "4d01dfa5b3780632a3d109e14e101f01d10cce2c",
+    sha1 = "0707dd0b4eb2101aa85c4bb7caf52d9ae32f0a43",
 )
 
 maven_jar(
     name = "truth-liteproto-extension",
     artifact = "com.google.truth.extensions:truth-liteproto-extension:" + TRUTH_VERS,
-    sha1 = "c231e6735aa6c133c7e411ae1c1c90b124900a8b",
+    sha1 = "67d833098345fc744c6fb2c38c739557b2d73742",
 )
 
 maven_jar(
     name = "truth-proto-extension",
     artifact = "com.google.truth.extensions:truth-proto-extension:" + TRUTH_VERS,
-    sha1 = "c41d22e8b4a61b4171e57c44a2959ebee0091a14",
+    sha1 = "b9641436e7b48b3642ac7aa7b8f3d1b9d04bc44b",
 )
 
 maven_jar(
@@ -1045,31 +1031,6 @@
 )
 
 maven_jar(
-    name = "postgresql",
-    artifact = "org.postgresql:postgresql:42.2.5",
-    sha1 = "951b7eda125f3137538a94e2cbdcf744088ad4c2",
-)
-
-maven_jar(
-    name = "codemirror-minified-gwt",
-    artifact = "org.webjars.npm:codemirror-minified:" + CM_VERSION,
-    sha1 = "36558ea3b8e30782e1e09c0e7bd781e09614f139",
-)
-
-maven_jar(
-    name = "codemirror-original-gwt",
-    artifact = "org.webjars.npm:codemirror:" + CM_VERSION,
-    sha1 = "f1f8fbbc3e2d224fdccc43d2f4180658a92320f9",
-)
-
-maven_jar(
-    name = "diff-match-patch",
-    artifact = "org.webjars:google-diff-match-patch:" + DIFF_MATCH_PATCH_VERSION,
-    attach_source = False,
-    sha1 = "0cf1782dbcb8359d95070da9176059a5a9d37709",
-)
-
-maven_jar(
     name = "commons-io",
     artifact = "commons-io:commons-io:2.2",
     sha1 = "83b5b8a7ba1c08f9e8c8ff2373724e33d3c1e22a",
@@ -1135,6 +1096,38 @@
     sha1 = "65bd0cacc9c79a21c6ed8e9f588577cd3c2f85b9",
 )
 
+maven_jar(
+    name = "javax-activation",
+    artifact = "javax.activation:activation:1.1.1",
+    sha1 = "485de3a253e23f645037828c07f1d7f1af40763a",
+)
+
+maven_jar(
+    name = "mockito",
+    artifact = "org.mockito:mockito-core:2.24.0",
+    sha1 = "969a7bcb6f16e076904336ebc7ca171d412cc1f9",
+)
+
+BYTE_BUDDY_VERSION = "1.9.7"
+
+maven_jar(
+    name = "byte-buddy",
+    artifact = "net.bytebuddy:byte-buddy:" + BYTE_BUDDY_VERSION,
+    sha1 = "8fea78fea6449e1738b675cb155ce8422661e237",
+)
+
+maven_jar(
+    name = "byte-buddy-agent",
+    artifact = "net.bytebuddy:byte-buddy-agent:" + BYTE_BUDDY_VERSION,
+    sha1 = "8e7d1b599f4943851ffea125fd9780e572727fc0",
+)
+
+maven_jar(
+    name = "objenesis",
+    artifact = "org.objenesis:objenesis:2.6",
+    sha1 = "639033469776fd37c08358c6b92a4761feb2af4b",
+)
+
 load("//tools/bzl:js.bzl", "bower_archive", "npm_binary")
 
 # NPM binaries bundled along with their dependencies.
@@ -1306,8 +1299,8 @@
 bower_archive(
     name = "codemirror-minified",
     package = "Dominator008/codemirror-minified",
-    sha1 = "1524e19087d8223edfe4a5b1ccf04c1e3707235d",
-    version = "5.37.0",
+    sha1 = "e6bda82afc7cf3493f4282c6f17265d40e1485e5",
+    version = "5.43.0",
 )
 
 # bower test stuff
diff --git a/contrib/mitm-ui/README.md b/contrib/mitm-ui/README.md
new file mode 100644
index 0000000..ad23140
--- /dev/null
+++ b/contrib/mitm-ui/README.md
@@ -0,0 +1,58 @@
+# Scripts for PolyGerrit local development against prod using MitmProxy.
+
+## Installation (OSX)
+
+1. Install Docker from http://docker.com
+2. Start the proxy and create a new proxied browser instance
+   ```
+   cd ~/gerrit
+   ~/mitm-gerrit/mitm-serve-app-dev.sh
+   ```
+3. Install MITM certificates
+   - Open http://mitm.it in the proxied browser window
+   - Follow the instructions to install MITM certs
+
+## Usage
+
+### Add or replace a single plugin containing static content
+
+To develop unminified plugin that loads multiple files, use this.
+
+1. Create a new proxied browser window and start mitmproxy via Docker:
+   ```
+   ~/mitm-gerrit/mitm-single-plugin.sh ./path/to/static/plugin.html
+   ```
+2. Open any *.googlesource.com domain in proxied window
+3. plugin.html and ./path/to/static/* will be served
+
+### Add or replace a minified plugin for *.googlesource.com
+
+This flow assumes no additional .html/.js are needed, i.e. the plugin is a single file.
+
+1. Create a new proxied browser window and start mitmproxy via Docker:
+   ```
+   ~/mitm-gerrit/mitm-plugins.sh ./path/to/plugin.html,./maybe/one/more.js
+   ```
+2. Open any *.googlesource.com domain in proxied window
+3. plugin.html and more.js are served
+
+### Force or replace default site theme for *.googlesource.com
+
+1. Create a new proxied browser window and start mitmproxy via Docker:
+   ```
+   ~/mitm-gerrit/mitm-theme.sh ./path/to/theme.html
+   ```
+2. Open any *.googlesource.com domain in proxied window
+3. Default site themes are enabled.
+4. Local `theme.html` content replaces `/static/gerrit-theme.html`
+5. `/static/*` URLs are served from local theme directory, i.e. `./path/to/`
+
+### Serve uncompiled PolyGerrit
+
+1. Create a new proxied browser window and start mitmproxy via Docker:
+   ```
+   cd ~/gerrit
+   ~/mitm-gerrit/mitm-serve-app-dev.sh
+   ```
+2. Open any *.googlesource.com domain in proxied window
+3. Instead of prod UI (gr-app.html, gr-app.js), local source files will be served
diff --git a/contrib/mitm-ui/add-header.py b/contrib/mitm-ui/add-header.py
new file mode 100644
index 0000000..f9b2b12
--- /dev/null
+++ b/contrib/mitm-ui/add-header.py
@@ -0,0 +1,5 @@
+# mitmdump -s add-header.py
+def response(flow):
+    if flow.request.host == 'gerrit-review.googlesource.com' and flow.request.path == "/c/92000?1":
+        #flow.response.headers['any'] = '<meta.rdf>; rel=meta'
+        flow.response.headers['Link'] = '</changes/98000/detail?O=11640c>;rel="preload";crossorigin;'
diff --git a/contrib/mitm-ui/dev-chrome.sh b/contrib/mitm-ui/dev-chrome.sh
new file mode 100755
index 0000000..adcb296
--- /dev/null
+++ b/contrib/mitm-ui/dev-chrome.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+if [[ "$OSTYPE" != "darwin"* ]]; then
+    echo Only works on OSX.
+    exit 1
+fi
+
+/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --user-data-dir=${HOME}/devchrome --proxy-server="127.0.0.1:8888"
diff --git a/contrib/mitm-ui/force-version.py b/contrib/mitm-ui/force-version.py
new file mode 100644
index 0000000..a69c885
--- /dev/null
+++ b/contrib/mitm-ui/force-version.py
@@ -0,0 +1,22 @@
+# mitmdump -q -p 8888 -s "force-version.py --version $1"
+# Request URL is not changed, only the response context
+from mitmproxy import http
+import argparse
+import re
+
+class Server:
+    def __init__(self, version):
+        self.version = version
+
+    def request(self, flow: http.HTTPFlow) -> None:
+        if "gr-app." in flow.request.pretty_url:
+            flow.request.url = re.sub(
+                r"polygerrit_ui/([\d.]+)/elements",
+                "polygerrit_ui/" + self.version + "/elements",
+                flow.request.url)
+
+def start():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("--version", type=str, help="Rapid release version, e.g. 432.0")
+    args = parser.parse_args()
+    return Server(args.version)
diff --git a/contrib/mitm-ui/mitm-docker.sh b/contrib/mitm-ui/mitm-docker.sh
new file mode 100755
index 0000000..77f209e
--- /dev/null
+++ b/contrib/mitm-ui/mitm-docker.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+extra_volume='/tmp:/tmp'
+
+POSITIONAL=()
+while [[ $# -gt 0 ]]
+do
+key="$1"
+
+case $key in
+    -v|--volume)
+    extra_volume="$2"
+    shift # past argument
+    shift # past value
+    ;;
+    *)    # unknown option
+    POSITIONAL+=("$1") # save it in an array for later
+    shift # past argument
+    ;;
+esac
+done
+set -- "${POSITIONAL[@]}" # restore positional parameters
+
+if [[ -z "$1" ]]; then
+    echo This is a runner for higher-level scripts, e.g. mitm-serve-app-dev.sh
+    echo Alternatively, pass mitmproxy script from the same dir as a parameter, e.g. serve-app-dev.py
+    exit 1
+fi
+
+gerrit_dir=$(pwd)
+mitm_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+CMD="${mitm_dir}/$1"
+
+docker run --rm -it \
+       -v ~/.mitmproxy:/home/mitmproxy/.mitmproxy \
+       -v ${mitm_dir}:${mitm_dir} \
+       -v ${gerrit_dir}:${gerrit_dir} \
+       -v ${extra_volume} \
+       -p 8888:8888 \
+       mitmproxy/mitmproxy:2.0.2 \
+       mitmdump -q -p 8888 -s "${CMD}"
diff --git a/contrib/mitm-ui/mitm-plugins.sh b/contrib/mitm-ui/mitm-plugins.sh
new file mode 100755
index 0000000..992ef07
--- /dev/null
+++ b/contrib/mitm-ui/mitm-plugins.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+if [[ -z "$1" ]]; then
+    echo This script injects plugins for *.googlesource.com.
+    echo Provide plugin paths, comma-separated, as a parameter.
+    echo This script assumes files do not have dependencies, i.e. minified.
+    exit 1
+fi
+
+realpath() {
+    [[ $1 = /* ]] && echo "$1" || echo "$PWD/${1#./}"
+}
+
+join () {
+  local IFS="$1"
+  shift
+  echo "$*"
+}
+
+plugins=$1
+plugin_paths=()
+for plugin in $(echo ${plugins} | sed "s/,/ /g")
+do
+    plugin_paths+=($(realpath ${plugin}))
+done
+
+absolute_plugin_paths=$(join , "${plugin_paths[@]}")
+
+mitm_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+${mitm_dir}/dev-chrome.sh &
+
+${mitm_dir}/mitm-docker.sh "serve-app-dev.py --plugins ${absolute_plugin_paths} --strip_assets"
diff --git a/contrib/mitm-ui/mitm-serve-app-dev.sh b/contrib/mitm-ui/mitm-serve-app-dev.sh
new file mode 100755
index 0000000..4fa8958
--- /dev/null
+++ b/contrib/mitm-ui/mitm-serve-app-dev.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+workspace="./WORKSPACE"
+if [[ ! -f ${workspace} ]] || [[ ! $(head -n 1 ${workspace}) == *"gerrit"* ]]; then
+    echo Please change to cloned Gerrit repo from https://gerrit.googlesource.com/gerrit/
+    exit 1
+fi
+
+mitm_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+${mitm_dir}/dev-chrome.sh &
+
+${mitm_dir}/mitm-docker.sh "serve-app-dev.py --app $(pwd)/polygerrit-ui/app/"
diff --git a/contrib/mitm-ui/mitm-single-plugin.sh b/contrib/mitm-ui/mitm-single-plugin.sh
new file mode 100755
index 0000000..4acae7f
--- /dev/null
+++ b/contrib/mitm-ui/mitm-single-plugin.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+if [[ -z "$1" ]]; then
+    echo This script serves one plugin with the rest of static content.
+    echo Provide path to index plugin file, e.g. buildbucket.html for buildbucket plugin
+    exit 1
+fi
+
+realpath() {
+  OURPWD=$PWD
+  cd "$(dirname "$1")"
+  LINK=$(basename "$1")
+  while [ -L "$LINK" ]; do
+      LINK=$(readlink "$LINK")
+      cd "$(dirname "$LINK")"
+      LINK="$(basename "$1")"
+  done
+  REAL_DIR=`pwd -P`
+  RESULT=$REAL_DIR/$LINK
+  cd "$OURPWD"
+  echo "$RESULT"
+}
+
+plugin=$(realpath $1)
+plugin_root=$(dirname ${plugin})
+
+mitm_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+${mitm_dir}/dev-chrome.sh &
+
+${mitm_dir}/mitm-docker.sh -v ${plugin_root}:${plugin_root} "serve-app-dev.py --plugins ${plugin} --strip_assets --plugin_root ${plugin_root}"
diff --git a/contrib/mitm-ui/mitm-theme.sh b/contrib/mitm-ui/mitm-theme.sh
new file mode 100755
index 0000000..9290235
--- /dev/null
+++ b/contrib/mitm-ui/mitm-theme.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+if [[ -z "$1" ]]; then
+    echo This script forces or replaces default site theme on *.googlesource.com
+    echo Provide path to the theme.html as a parameter.
+    exit 1
+fi
+
+realpath() {
+  OURPWD=$PWD
+  cd "$(dirname "$1")"
+  LINK=$(basename "$1")
+  while [ -L "$LINK" ]; do
+      LINK=$(readlink "$LINK")
+      cd "$(dirname "$LINK")"
+      LINK="$(basename "$1")"
+  done
+  REAL_DIR=`pwd -P`
+  RESULT=$REAL_DIR/$LINK
+  cd "$OURPWD"
+  echo "$RESULT"
+}
+
+theme=$(realpath "$1")
+theme_dir=$(dirname "${theme}")
+
+mitm_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
+
+"${mitm_dir}"/dev-chrome.sh &
+
+"${mitm_dir}"/mitm-docker.sh -v "${theme_dir}":"${theme_dir}" "serve-app-dev.py --strip_assets --theme \"${theme}\""
diff --git a/contrib/mitm-ui/serve-app-dev.py b/contrib/mitm-ui/serve-app-dev.py
new file mode 100644
index 0000000..18e9de1
--- /dev/null
+++ b/contrib/mitm-ui/serve-app-dev.py
@@ -0,0 +1,156 @@
+# 1. install and setup mitmproxy v2.0.2: https://mitmproxy.readthedocs.io/en/v2.0.2/install.html
+#   (In case of python versions trouble, use https://www.anaconda.com/)
+# 2. mitmdump -q -s -p 8888 \
+#   "serve-app-dev.py --app /path/to/polygerrit-ui/app/"
+# 3. start Chrome with --proxy-server="127.0.0.1:8888" --user-data-dir=/tmp/devchrome
+# 4. open, say, gerrit-review.googlesource.com. Or chromium-review.googlesource.com. Any.
+# 5. uncompiled source files are served and you can log in, too.
+# 6. enjoy!
+#
+# P.S. For replacing plugins, use --plugins or --plugin_root
+#
+# --plugin takes comma-separated list of plugins to add or replace.
+#
+# Example: Adding a new plugin to the server response:
+# --plugins ~/gerrit-testsite/plugins/myplugin.html
+#
+# Example: Replace all matching plugins with local versions:
+# --plugins ~/gerrit-testsite/plugins/
+# Following files will be served if they exist for /plugins/tricium/static/tricium.html:
+#  ~/gerrit-testsite/plugins/tricium.html
+#  ~/gerrit-testsite/plugins/tricium/static/tricium.html
+#
+# --assets takes assets bundle.html, expecting rest of the assets files to be in the same folder
+#
+# Example:
+#  --assets ~/gerrit-testsite/assets/a3be19f.html
+#
+
+from mitmproxy import http
+from mitmproxy.script import concurrent
+import re
+import argparse
+import os.path
+import json
+import mimetypes
+
+class Server:
+    def __init__(self, devpath, plugins, pluginroot, assets, strip_assets, theme):
+        if devpath:
+            print("Serving app from " + devpath)
+        if pluginroot:
+            print("Serving plugins from " + pluginroot)
+        if assets:
+            self.assets_root, self.assets_file = os.path.split(assets)
+            print("Assets: using " + self.assets_file + " from " + self.assets_root)
+        else:
+            self.assets_root = None
+        if plugins:
+            self.plugins = {path.split("/")[-1:][0]: path for path in map(expandpath, plugins.split(","))}
+            for filename, path in self.plugins.items():
+                print("Serving " + filename + " from " + path)
+        else:
+            self.plugins = {}
+        self.devpath = devpath
+        self.pluginroot = pluginroot
+        self.strip_assets = strip_assets
+        self.theme = theme
+
+    def readfile(self, path):
+        with open(path, 'rb') as contentfile:
+            return contentfile.read()
+
+@concurrent
+def response(flow: http.HTTPFlow) -> None:
+    if server.strip_assets:
+        assets_bundle = 'googlesource.com/polygerrit_assets'
+        assets_pos = flow.response.text.find(assets_bundle)
+        if assets_pos != -1:
+            t = flow.response.text
+            flow.response.text = t[:t.rfind('<', 0, assets_pos)] + t[t.find('>', assets_pos) + 1:]
+            return
+
+    if server.assets_root:
+        marker = 'webcomponents-lite.js"></script>'
+        pos = flow.response.text.find(marker)
+        if pos != -1:
+            pos += len(marker)
+            flow.response.text = ''.join([
+                flow.response.text[:pos],
+                '<link rel="import" href="/gerrit_assets/123.0/' + server.assets_file + '">',
+                flow.response.text[pos:]
+            ])
+
+        assets_prefix = "/gerrit_assets/123.0/"
+        if flow.request.path.startswith(assets_prefix):
+            assets_file = flow.request.path[len(assets_prefix):]
+            flow.response.content = server.readfile(server.assets_root + '/' + assets_file)
+            flow.response.status_code = 200
+            if assets_file.endswith('.js'):
+                flow.response.headers['Content-type'] = 'text/javascript'
+            return
+    m = re.match(".+polygerrit_ui/\d+\.\d+/(.+)", flow.request.path)
+    pluginmatch = re.match("^/plugins/(.+)", flow.request.path)
+    localfile = ""
+    if flow.request.path == "/config/server/info":
+        config = json.loads(flow.response.content[5:].decode('utf8'))
+        if server.theme:
+            config['default_theme'] = '/static/gerrit-theme.html'
+        for filename, path in server.plugins.items():
+            pluginname = filename.split(".")[0]
+            payload = config["plugin"]["js_resource_paths" if filename.endswith(".js") else "html_resource_paths"]
+            if list(filter(lambda url: filename in url, payload)):
+                continue
+            payload.append("plugins/" + pluginname + "/static/" + filename)
+        flow.response.content = str.encode(")]}'\n" + json.dumps(config))
+    if m is not None:
+        filepath = m.groups()[0]
+        localfile = server.devpath + filepath
+    elif pluginmatch is not None:
+        pluginfile = flow.request.path_components[-1]
+        if server.plugins and pluginfile in server.plugins:
+            if os.path.isfile(server.plugins[pluginfile]):
+                localfile = server.plugins[pluginfile]
+            else:
+                print("Can't find file " + server.plugins[pluginfile] + " for " + flow.request.path)
+        elif server.pluginroot:
+            pluginurl = pluginmatch.groups()[0]
+            if os.path.isfile(server.pluginroot + pluginfile):
+                localfile = server.pluginroot + pluginfile
+            elif os.path.isfile(server.pluginroot + pluginurl):
+                localfile = server.pluginroot + pluginurl
+
+    if server.theme:
+        if flow.request.path.endswith('/gerrit-theme.html'):
+            localfile = server.theme
+        else:
+            match = re.match("^/static(/[\w\.]+)$", flow.request.path)
+            if match is not None:
+                localfile = os.path.dirname(server.theme) + match.group(1)
+
+    if localfile and os.path.isfile(localfile):
+        if pluginmatch is not None:
+            print("Serving " + flow.request.path + " from " + localfile)
+        flow.response.content = server.readfile(localfile)
+        flow.response.status_code = 200
+        localtype = mimetypes.guess_type(localfile)
+        if localtype and localtype[0]:
+            flow.response.headers['Content-type'] = localtype[0]
+
+def expandpath(path):
+    return os.path.realpath(os.path.expanduser(path))
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--app", type=str, default="", help="Path to /polygerrit-ui/app/")
+parser.add_argument("--plugins", type=str, default="", help="Comma-separated list of plugin files to add/replace")
+parser.add_argument("--plugin_root", type=str, default="", help="Path containing individual plugin files to replace")
+parser.add_argument("--assets", type=str, default="", help="Path containing assets file to import.")
+parser.add_argument("--strip_assets", action="store_true", help="Strip plugin bundles from the response.")
+parser.add_argument("--theme", type=str, help="Path to the default site theme to be used.")
+args = parser.parse_args()
+server = Server(expandpath(args.app) + '/',
+                args.plugins,
+                expandpath(args.plugin_root) + '/',
+                args.assets and expandpath(args.assets),
+                args.strip_assets,
+                expandpath(args.theme))
diff --git a/contrib/mitm-ui/serve-app-locally.py b/contrib/mitm-ui/serve-app-locally.py
new file mode 100644
index 0000000..636c684
--- /dev/null
+++ b/contrib/mitm-ui/serve-app-locally.py
@@ -0,0 +1,46 @@
+# bazel build polygerrit-ui/app:gr-app
+# mitmdump -s "serve-app-locally.py ~/gerrit/bazel-bin/polygerrit-ui/app"
+from mitmproxy import http
+import argparse
+import os
+import zipfile
+
+class Server:
+    def __init__(self, bundle):
+        self.bundle = bundle
+        self.bundlemtime = 0
+        self.files = {
+            'polygerrit_ui/elements/gr-app.js': '',
+            'polygerrit_ui/elements/gr-app.html': '',
+            'polygerrit_ui/styles/main.css': '',
+        }
+        self.read_files()
+
+    def read_files(self):
+        if not os.path.isfile(self.bundle):
+            print("bundle not found!")
+            return
+        mtime = os.stat(self.bundle).st_mtime
+        if mtime <= self.bundlemtime:
+            return
+        self.bundlemtime = mtime
+        with zipfile.ZipFile(self.bundle) as z:
+            for fname in self.files:
+                print('Reading new content for ' + fname)
+                with z.open(fname, 'r') as content_file:
+                    self.files[fname] = content_file.read()
+
+    def response(self, flow: http.HTTPFlow) -> None:
+        self.read_files()
+        for name in self.files:
+            if name.rsplit('/', 1)[1] in flow.request.pretty_url:
+                flow.response.content = self.files[name]
+
+def expandpath(path):
+    return os.path.expanduser(path)
+
+def start():
+    parser = argparse.ArgumentParser()
+    parser.add_argument("bundle", type=str)
+    args = parser.parse_args()
+    return Server(expandpath(args.bundle))
diff --git a/gerrit-gwtdebug/BUILD b/gerrit-gwtdebug/BUILD
deleted file mode 100644
index f564745..0000000
--- a/gerrit-gwtdebug/BUILD
+++ /dev/null
@@ -1,16 +0,0 @@
-java_library(
-    name = "gwtdebug",
-    srcs = glob(["src/main/java/**/*.java"]),
-    visibility = ["//visibility:public"],
-    deps = [
-        "//java/com/google/gerrit/pgm",
-        "//java/com/google/gerrit/pgm/util",
-        "//java/com/google/gerrit/util/cli",
-        "//lib/flogger:api",
-        "//lib/gwt:dev",
-        "//lib/jetty:server",
-        "//lib/jetty:servlet",
-        "//lib/jetty:servlets",
-        "//lib/log:log4j",
-    ],
-)
diff --git a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritGwtDebugLauncher.java b/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritGwtDebugLauncher.java
deleted file mode 100644
index cf84919..0000000
--- a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritGwtDebugLauncher.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (C) 2014 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.gwtdebug;
-
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.pgm.Daemon;
-import com.google.gwt.dev.codeserver.CodeServer;
-import com.google.gwt.dev.codeserver.Options;
-import java.util.ArrayList;
-import java.util.List;
-
-class GerritGwtDebugLauncher {
-  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
-  public static void main(String[] argv) throws Exception {
-    GerritGwtDebugLauncher launcher = new GerritGwtDebugLauncher();
-    launcher.mainImpl(argv);
-  }
-
-  private int mainImpl(String[] argv) {
-    List<String> sdmLauncherOptions = new ArrayList<>();
-    List<String> daemonLauncherOptions = new ArrayList<>();
-
-    // Separator between Daemon and Codeserver parameters is "--"
-    boolean daemonArgumentSeparator = false;
-    int i = 0;
-    for (; i < argv.length; i++) {
-      if (!argv[i].equals("--")) {
-        sdmLauncherOptions.add(argv[i]);
-      } else {
-        daemonArgumentSeparator = true;
-        break;
-      }
-    }
-    if (daemonArgumentSeparator) {
-      ++i;
-      for (; i < argv.length; i++) {
-        daemonLauncherOptions.add(argv[i]);
-      }
-    }
-
-    Options options = new Options();
-    if (!options.parseArgs(sdmLauncherOptions.toArray(new String[sdmLauncherOptions.size()]))) {
-      logger.atSevere().log("Failed to parse codeserver arguments");
-      return 1;
-    }
-
-    CodeServer.main(options);
-
-    try {
-      int r =
-          new Daemon()
-              .main(daemonLauncherOptions.toArray(new String[daemonLauncherOptions.size()]));
-      if (r != 0) {
-        logger.atSevere().log("Daemon exited with return code: %d", r);
-        return 1;
-      }
-    } catch (Exception e) {
-      logger.atSevere().withCause(e).log("Cannot start daemon");
-      return 1;
-    }
-
-    return 0;
-  }
-}
diff --git a/gerrit-gwtui-common/BUILD b/gerrit-gwtui-common/BUILD
deleted file mode 100644
index c644b85..0000000
--- a/gerrit-gwtui-common/BUILD
+++ /dev/null
@@ -1,62 +0,0 @@
-load("//tools/bzl:gwt.bzl", "gwt_module")
-load("//tools/bzl:java.bzl", "java_library2")
-load("//tools/bzl:junit.bzl", "junit_tests")
-
-EXPORTED_DEPS = [
-    "//java/com/google/gerrit/common:client",
-    "//java/com/google/gwtexpui/clippy",
-    "//java/com/google/gwtexpui/globalkey",
-    "//java/com/google/gwtexpui/progress",
-    "//java/com/google/gwtexpui/safehtml",
-    "//java/com/google/gwtexpui/user:agent",
-]
-
-DEPS = ["//lib/gwt:user-neverlink"]
-
-SRC = "src/main/java/com/google/gerrit/"
-
-gwt_module(
-    name = "client",
-    srcs = glob(["src/main/**/*.java"]),
-    exported_deps = EXPORTED_DEPS,
-    gwt_xml = SRC + "GerritGwtUICommon.gwt.xml",
-    resources = glob(
-        ["src/main/**/*"],
-        exclude = [SRC + "client/**/*.java"] + [
-            SRC + "GerritGwtUICommon.gwt.xml",
-        ],
-    ),
-    visibility = ["//visibility:public"],
-    deps = DEPS,
-)
-
-java_library2(
-    name = "client-lib",
-    srcs = glob(["src/main/**/*.java"]),
-    exported_deps = EXPORTED_DEPS,
-    resources = glob(["src/main/**/*"]),
-    visibility = ["//visibility:public"],
-    deps = DEPS,
-)
-
-java_library(
-    name = "diffy_logo",
-    data = [
-        "//lib:LICENSE-CC-BY3.0-unported",
-        "//lib:LICENSE-diffy",
-    ],
-    resources = glob(["src/main/resources/com/google/gerrit/client/diffy*.png"]),
-    visibility = ["//visibility:public"],
-)
-
-junit_tests(
-    name = "client_tests",
-    srcs = glob(["src/test/java/**/*.java"]),
-    visibility = ["//visibility:public"],
-    deps = [
-        ":client",
-        "//lib:junit",
-        "//lib/gwt:dev",
-        "//lib/jgit/org.eclipse.jgit:jgit",
-    ],
-)
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/GerritGwtUICommon.gwt.xml b/gerrit-gwtui-common/src/main/java/com/google/gerrit/GerritGwtUICommon.gwt.xml
deleted file mode 100644
index dc478fc..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/GerritGwtUICommon.gwt.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<!--
- Copyright (C) 2014 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.
--->
-<module>
-  <inherits name='org.eclipse.jgit.JGit'/>
-  <inherits name='com.google.gerrit.common.Common'/>
-  <inherits name='com.google.gerrit.extensions.Extensions'/>
-  <inherits name='com.google.gerrit.prettify.PrettyFormatter'/>
-  <inherits name='com.google.gwtexpui.clippy.Clippy'/>
-  <inherits name='com.google.gwtexpui.globalkey.GlobalKey'/>
-  <inherits name='com.google.gwtexpui.progress.Progress'/>
-  <inherits name='com.google.gwtexpui.safehtml.SafeHtml'/>
-  <source path='client'>
-    <include name='AccountFormatter.java'/>
-    <include name='CommonConstants.java'/>
-    <include name='CommonMessages.java'/>
-    <include name='DateFormatter.java'/>
-    <include name='GerritUiExtensionPoint.java'/>
-    <include name='RelativeDateFormatter.java'/>
-    <include name='Resources.java'/>
-    <include name='CommonConstants.properties'/>
-    <include name='CommonMessages.properties'/>
-    <include name='info/*.java'/>
-    <include name='rpc/NativeMap.java'/>
-    <include name='rpc/Natives.java'/>
-    <include name='rpc/NativeString.java'/>
-    <include name='rpc/TransformCallback.java'/>
-    <include name='ui/HighlightSuggestion.java'/>
-    <include name='ui/RemoteSuggestOracle.java'/>
-  </source>
-</module>
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/AccountFormatter.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/AccountFormatter.java
deleted file mode 100644
index 3058971..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/AccountFormatter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-import com.google.gerrit.client.info.AccountInfo;
-
-public class AccountFormatter {
-  private final String anonymousCowardName;
-
-  public AccountFormatter(String anonymousCowardName) {
-    this.anonymousCowardName = anonymousCowardName;
-  }
-
-  /**
-   * Formats an account as a name and an email address.
-   *
-   * <p>Example output:
-   *
-   * <ul>
-   *   <li>{@code A U. Thor &lt;author@example.com&gt;}: full populated
-   *   <li>{@code A U. Thor (12)}: missing email address
-   *   <li>{@code Anonymous Coward &lt;author@example.com&gt;}: missing name
-   *   <li>{@code Anonymous Coward (12)}: missing name and email address
-   * </ul>
-   */
-  public String nameEmail(AccountInfo info) {
-    String name = info.name();
-    if (name == null || name.trim().isEmpty()) {
-      name = anonymousCowardName;
-    }
-
-    StringBuilder b = new StringBuilder().append(name);
-    if (info.email() != null) {
-      b.append(" <").append(info.email()).append(">");
-    } else if (info._accountId() > 0) {
-      b.append(" (").append(info._accountId()).append(")");
-    }
-    return b.toString();
-  }
-
-  /**
-   * Formats an account name.
-   *
-   * <p>If the account has a full name, it returns only the full name. Otherwise it returns a longer
-   * form that includes the email address.
-   */
-  public String name(AccountInfo ai) {
-    if (ai.name() != null && !ai.name().trim().isEmpty()) {
-      return ai.name();
-    }
-    String email = ai.email();
-    if (email != null) {
-      int at = email.indexOf('@');
-      return 0 < at ? email.substring(0, at) : email;
-    }
-    return nameEmail(ai);
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.java
deleted file mode 100644
index e769730..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.i18n.client.Constants;
-
-public interface CommonConstants extends Constants {
-  CommonConstants C = GWT.create(CommonConstants.class);
-
-  String inTheFuture();
-
-  String month();
-
-  String months();
-
-  String year();
-
-  String years();
-
-  String oneSecondAgo();
-
-  String oneMinuteAgo();
-
-  String oneHourAgo();
-
-  String oneDayAgo();
-
-  String oneWeekAgo();
-
-  String oneMonthAgo();
-
-  String oneYearAgo();
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.properties b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.properties
deleted file mode 100644
index 3202bfc..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonConstants.properties
+++ /dev/null
@@ -1,13 +0,0 @@
-inTheFuture = in the future
-month = month
-months = months
-years = years
-year = year
-
-oneSecondAgo = 1 second ago
-oneMinuteAgo = 1 minute ago
-oneHourAgo = 1 hour ago
-oneDayAgo = 1 day ago
-oneWeekAgo = 1 week ago
-oneMonthAgo = 1 month ago
-oneYearAgo = 1 year ago
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.java
deleted file mode 100644
index 5314254..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.i18n.client.Messages;
-
-public interface CommonMessages extends Messages {
-  CommonMessages M = GWT.create(CommonMessages.class);
-
-  String secondsAgo(long seconds);
-
-  String minutesAgo(long minutes);
-
-  String hoursAgo(long hours);
-
-  String daysAgo(long days);
-
-  String weeksAgo(long weeks);
-
-  String monthsAgo(long months);
-
-  String yearsAgo(long years);
-
-  String years0MonthsAgo(long years, String yearLabel);
-
-  String yearsMonthsAgo(long years, String yearLabel, long months, String monthLabel);
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.properties b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.properties
deleted file mode 100644
index 738602e..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/CommonMessages.properties
+++ /dev/null
@@ -1,9 +0,0 @@
-secondsAgo = {0} seconds ago
-minutesAgo = {0} minutes ago
-hoursAgo = {0} hours ago
-daysAgo = {0} days ago
-weeksAgo = {0} weeks ago
-monthsAgo = {0} months ago
-years0MonthsAgo = {0} {1} ago
-yearsMonthsAgo = {0} {1}, {2} {3} ago
-yearsAgo = {0} years ago
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/DateFormatter.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/DateFormatter.java
deleted file mode 100644
index 4df2f5f..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/DateFormatter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-import com.google.gerrit.client.info.GeneralPreferences;
-import com.google.gwt.i18n.client.DateTimeFormat;
-import java.util.Date;
-
-public class DateFormatter {
-  private static final long ONE_YEAR = 182L * 24 * 60 * 60 * 1000;
-
-  private final DateTimeFormat sTime;
-  private final DateTimeFormat sDate;
-  private final DateTimeFormat sdtFmt;
-  private final DateTimeFormat mDate;
-  private final DateTimeFormat dtfmt;
-
-  public DateFormatter(GeneralPreferences prefs) {
-    String fmt_sTime = prefs.timeFormat().getFormat();
-    String fmt_sDate = prefs.dateFormat().getShortFormat();
-    String fmt_mDate = prefs.dateFormat().getLongFormat();
-
-    sTime = DateTimeFormat.getFormat(fmt_sTime);
-    sDate = DateTimeFormat.getFormat(fmt_sDate);
-    sdtFmt = DateTimeFormat.getFormat(fmt_sDate + " " + fmt_sTime);
-    mDate = DateTimeFormat.getFormat(fmt_mDate);
-    dtfmt = DateTimeFormat.getFormat(fmt_mDate + " " + fmt_sTime);
-  }
-
-  /** Format a date using a really short format. */
-  public String shortFormat(Date dt) {
-    if (dt == null) {
-      return "";
-    }
-
-    Date now = new Date();
-    dt = new Date(dt.getTime());
-    if (mDate.format(now).equals(mDate.format(dt))) {
-      // Same day as today, report only the time.
-      //
-      return sTime.format(dt);
-
-    } else if (Math.abs(now.getTime() - dt.getTime()) < ONE_YEAR) {
-      // Within the last year, show a shorter date.
-      //
-      return sDate.format(dt);
-
-    } else {
-      // Report only date and year, its far away from now.
-      //
-      return mDate.format(dt);
-    }
-  }
-
-  /** Format a date using a really short format. */
-  public String shortFormatDayTime(Date dt) {
-    if (dt == null) {
-      return "";
-    }
-
-    Date now = new Date();
-    dt = new Date(dt.getTime());
-    if (mDate.format(now).equals(mDate.format(dt))) {
-      // Same day as today, report only the time.
-      //
-      return sTime.format(dt);
-
-    } else if (Math.abs(now.getTime() - dt.getTime()) < ONE_YEAR) {
-      // Within the last year, show a shorter date.
-      //
-      return sdtFmt.format(dt);
-
-    } else {
-      // Report only date and year, its far away from now.
-      //
-      return mDate.format(dt);
-    }
-  }
-
-  /** Format a date using the locale's medium length format. */
-  public String mediumFormat(Date dt) {
-    if (dt == null) {
-      return "";
-    }
-    return dtfmt.format(new Date(dt.getTime()));
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java
deleted file mode 100644
index 66a3b6b..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/GerritUiExtensionPoint.java
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-public enum GerritUiExtensionPoint {
-  /* ChangeScreen */
-  CHANGE_SCREEN_HEADER,
-  CHANGE_SCREEN_HEADER_RIGHT_OF_BUTTONS,
-  CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
-  CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
-  CHANGE_SCREEN_BELOW_RELATED_INFO_BLOCK,
-  CHANGE_SCREEN_BELOW_COMMIT_INFO_BLOCK,
-  CHANGE_SCREEN_HISTORY_RIGHT_OF_BUTTONS,
-
-  /* MyPasswordScreen */
-  PASSWORD_SCREEN_BOTTOM,
-
-  /* MyPreferencesScreen */
-  PREFERENCES_SCREEN_BOTTOM,
-
-  /* MyProfileScreen */
-  PROFILE_SCREEN_BOTTOM,
-
-  /* ProjectInfoScreen */
-  PROJECT_INFO_SCREEN_TOP,
-  PROJECT_INFO_SCREEN_BOTTOM;
-
-  public enum Key {
-    ACCOUNT_INFO,
-    CHANGE_INFO,
-    PROJECT_NAME,
-    REVISION_INFO
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/RelativeDateFormatter.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/RelativeDateFormatter.java
deleted file mode 100644
index e0cc9ca..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/RelativeDateFormatter.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (C) 2013 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.client;
-
-import java.util.Date;
-
-/**
- * Formatter to format timestamps relative to the current time using time units in the format
- * defined by {@code git log --relative-date}.
- */
-public class RelativeDateFormatter {
-  private static CommonConstants constants;
-  private static CommonMessages messages;
-
-  static final long SECOND_IN_MILLIS = 1000;
-  static final long MINUTE_IN_MILLIS = 60 * SECOND_IN_MILLIS;
-  static final long HOUR_IN_MILLIS = 60 * MINUTE_IN_MILLIS;
-  static final long DAY_IN_MILLIS = 24 * HOUR_IN_MILLIS;
-  static final long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS;
-  static final long MONTH_IN_MILLIS = 30 * DAY_IN_MILLIS;
-  static final long YEAR_IN_MILLIS = 365 * DAY_IN_MILLIS;
-
-  static void setConstants(CommonConstants c, CommonMessages m) {
-    constants = c;
-    messages = m;
-  }
-
-  private static CommonConstants c() {
-    return constants != null ? constants : CommonConstants.C;
-  }
-
-  private static CommonMessages m() {
-    return messages != null ? messages : CommonMessages.M;
-  }
-
-  /**
-   * @param when {@link Date} to format
-   * @return age of given {@link Date} compared to now formatted in the same relative format as
-   *     returned by {@code git log --relative-date}
-   */
-  public static String format(Date when) {
-    long ageMillis = (new Date()).getTime() - when.getTime();
-
-    // shouldn't happen in a perfect world
-    if (ageMillis < 0) {
-      return c().inTheFuture();
-    }
-
-    // seconds
-    if (ageMillis < upperLimit(MINUTE_IN_MILLIS)) {
-      long seconds = round(ageMillis, SECOND_IN_MILLIS);
-      if (seconds == 1) {
-        return c().oneSecondAgo();
-      }
-      return m().secondsAgo(seconds);
-    }
-
-    // minutes
-    if (ageMillis < upperLimit(HOUR_IN_MILLIS)) {
-      long minutes = round(ageMillis, MINUTE_IN_MILLIS);
-      if (minutes == 1) {
-        return c().oneMinuteAgo();
-      }
-      return m().minutesAgo(minutes);
-    }
-
-    // hours
-    if (ageMillis < upperLimit(DAY_IN_MILLIS)) {
-      long hours = round(ageMillis, HOUR_IN_MILLIS);
-      if (hours == 1) {
-        return c().oneHourAgo();
-      }
-      return m().hoursAgo(hours);
-    }
-
-    // up to 14 days use days
-    if (ageMillis < 14 * DAY_IN_MILLIS) {
-      long days = round(ageMillis, DAY_IN_MILLIS);
-      if (days == 1) {
-        return c().oneDayAgo();
-      }
-      return m().daysAgo(days);
-    }
-
-    // up to 10 weeks use weeks
-    if (ageMillis < 10 * WEEK_IN_MILLIS) {
-      long weeks = round(ageMillis, WEEK_IN_MILLIS);
-      if (weeks == 1) {
-        return c().oneWeekAgo();
-      }
-      return m().weeksAgo(weeks);
-    }
-
-    // months
-    if (ageMillis < YEAR_IN_MILLIS) {
-      long months = round(ageMillis, MONTH_IN_MILLIS);
-      if (months == 1) {
-        return c().oneMonthAgo();
-      }
-      return m().monthsAgo(months);
-    }
-
-    // up to 5 years use "year, months" rounded to months
-    if (ageMillis < 5 * YEAR_IN_MILLIS) {
-      long years = round(ageMillis, MONTH_IN_MILLIS) / 12;
-      String yearLabel = (years > 1) ? c().years() : c().year();
-      long months = round(ageMillis - years * YEAR_IN_MILLIS, MONTH_IN_MILLIS);
-      String monthLabel = (months > 1) ? c().months() : (months == 1 ? c().month() : "");
-      if (months == 0) {
-        return m().years0MonthsAgo(years, yearLabel);
-      }
-      return m().yearsMonthsAgo(years, yearLabel, months, monthLabel);
-    }
-
-    // years
-    long years = round(ageMillis, YEAR_IN_MILLIS);
-    if (years == 1) {
-      return c().oneYearAgo();
-    }
-    return m().yearsAgo(years);
-  }
-
-  private static long upperLimit(long unit) {
-    return unit + unit / 2;
-  }
-
-  private static long round(long n, long unit) {
-    return (n + unit / 2) / unit;
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java
deleted file mode 100644
index 67627c3..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/Resources.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gwt.resources.client.ClientBundle;
-import com.google.gwt.resources.client.ImageResource;
-
-public interface Resources extends ClientBundle {
-  /** silk icons (CC-BY3.0): http://famfamfam.com/lab/icons/silk/ */
-  @Source("note_add.png")
-  ImageResource addFileComment();
-
-  @Source("tag_blue_add.png")
-  ImageResource addHashtag();
-
-  @Source("user_add.png")
-  ImageResource addUser();
-
-  @Source("user_edit.png")
-  ImageResource editUser();
-
-  // derived from resultset_next.png
-  @Source("resultset_down_gray.png")
-  ImageResource arrowDown();
-
-  // derived from resultset_next.png
-  @Source("resultset_next_gray.png")
-  ImageResource arrowRight();
-
-  // derived from resultset_next.png
-  @Source("resultset_up_gray.png")
-  ImageResource arrowUp();
-
-  @Source("lightbulb.png")
-  ImageResource blame();
-
-  @Source("page_white_put.png")
-  ImageResource downloadIcon();
-
-  // derived from comment.png
-  @Source("comment_draft.png")
-  ImageResource draftComments();
-
-  @Source("page_edit.png")
-  ImageResource edit();
-
-  @Source("arrow_undo.png")
-  ImageResource editUndo();
-
-  @Source("cog.png")
-  ImageResource gear();
-
-  @Source("tick.png")
-  ImageResource greenCheck();
-
-  @Source("tag_blue.png")
-  ImageResource hashtag();
-
-  @Source("lightbulb.png")
-  ImageResource info();
-
-  @Source("find.png")
-  ImageResource queryIcon();
-
-  @Source("lock.png")
-  ImageResource readOnly();
-
-  @Source("cross.png")
-  ImageResource redNot();
-
-  @Source("disk.png")
-  ImageResource save();
-
-  @Source("star.png")
-  ImageResource starFilled();
-
-  // derived from star.png
-  @Source("star-open.png")
-  ImageResource starOpen();
-
-  @Source("exclamation.png")
-  ImageResource warning();
-
-  @Source("help.png")
-  ImageResource question();
-
-  /** tango icon library (public domain): http://tango.freedesktop.org/Tango_Icon_Library */
-  @Source("goNext.png")
-  ImageResource goNext();
-
-  @Source("goPrev.png")
-  ImageResource goPrev();
-
-  @Source("goUp.png")
-  ImageResource goUp();
-
-  @Source("listAdd.png")
-  ImageResource listAdd();
-
-  // derived from important.png
-  @Source("merge.png")
-  ImageResource merge();
-
-  /** contributed by the artist under Apache2.0 */
-  @Source("sideBySideDiff.png")
-  ImageResource sideBySideDiff();
-
-  @Source("unifiedDiff.png")
-  ImageResource unifiedDiff();
-
-  /** contributed by the artist under CC-BY3.0 */
-  @Source("diffy26.png")
-  ImageResource gerritAvatar26();
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java
deleted file mode 100644
index e4c008c..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AccountInfo.java
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwtjsonrpc.client.impl.ser.JavaSqlTimestamp_JsonSerializer;
-import java.sql.Timestamp;
-
-public class AccountInfo extends JavaScriptObject {
-  public final native int _accountId() /*-{ return this._account_id || 0; }-*/;
-
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String email() /*-{ return this.email; }-*/;
-
-  public final native JsArrayString secondaryEmails() /*-{ return this.secondary_emails; }-*/;
-
-  public final native String username() /*-{ return this.username; }-*/;
-
-  public final Timestamp registeredOn() {
-    Timestamp ts = _getRegisteredOn();
-    if (ts == null) {
-      ts = JavaSqlTimestamp_JsonSerializer.parseTimestamp(registeredOnRaw());
-      _setRegisteredOn(ts);
-    }
-    return ts;
-  }
-
-  private native String registeredOnRaw() /*-{ return this.registered_on; }-*/;
-
-  private native Timestamp _getRegisteredOn() /*-{ return this._cts; }-*/;
-
-  private native void _setRegisteredOn(Timestamp ts) /*-{ this._cts = ts; }-*/;
-
-  /**
-   * @return true if the server supplied avatar information about this account. The information may
-   *     be an empty list, indicating no avatars are available, such as when no plugin is installed.
-   *     This method returns false if the server did not check on avatars for the account.
-   */
-  public final native boolean hasAvatarInfo() /*-{ return this.hasOwnProperty('avatars') }-*/;
-
-  public final AvatarInfo avatar(int sz) {
-    JsArray<AvatarInfo> a = avatars();
-    for (int i = 0; a != null && i < a.length(); i++) {
-      AvatarInfo r = a.get(i);
-      if (r.height() == sz) {
-        return r;
-      }
-    }
-    return null;
-  }
-
-  private native JsArray<AvatarInfo> avatars() /*-{ return this.avatars }-*/;
-
-  public final native void name(String n) /*-{ this.name = n }-*/;
-
-  public final native void email(String e) /*-{ this.email = e }-*/;
-
-  public final native void username(String n) /*-{ this.username = n }-*/;
-
-  public static native AccountInfo create(int id, String name, String email, String username) /*-{
-    return {'_account_id': id, 'name': name, 'email': email,
-        'username': username};
-  }-*/;
-
-  protected AccountInfo() {}
-
-  public static class AvatarInfo extends JavaScriptObject {
-    public static final int DEFAULT_SIZE = 26;
-
-    public final native String url() /*-{ return this.url }-*/;
-
-    public final native int height() /*-{ return this.height || 0 }-*/;
-
-    public final native int width() /*-{ return this.width || 0 }-*/;
-
-    protected AvatarInfo() {}
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ActionInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ActionInfo.java
deleted file mode 100644
index d09d5b7..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ActionInfo.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class ActionInfo extends JavaScriptObject {
-
-  public final native String id() /*-{ return this.id; }-*/;
-
-  public final native String method() /*-{ return this.method; }-*/;
-
-  public final native String label() /*-{ return this.label; }-*/;
-
-  public final native String title() /*-{ return this.title; }-*/;
-
-  public final native boolean enabled() /*-{ return this.enabled || false; }-*/;
-
-  protected ActionInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AgreementInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AgreementInfo.java
deleted file mode 100644
index 04fba4f..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AgreementInfo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2016 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class AgreementInfo extends JavaScriptObject {
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String description() /*-{ return this.description; }-*/;
-
-  public final native String url() /*-{ return this.url; }-*/;
-
-  public final native GroupInfo autoVerifyGroup() /*-{ return this.auto_verify_group; }-*/;
-
-  protected AgreementInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AuthInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AuthInfo.java
deleted file mode 100644
index 43281bd..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/AuthInfo.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.extensions.client.AccountFieldName;
-import com.google.gerrit.extensions.client.AuthType;
-import com.google.gerrit.extensions.client.GitBasicAuthPolicy;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import java.util.ArrayList;
-import java.util.List;
-
-public class AuthInfo extends JavaScriptObject {
-  public final AuthType authType() {
-    return AuthType.valueOf(authTypeRaw());
-  }
-
-  public final boolean isLdap() {
-    return authType() == AuthType.LDAP || authType() == AuthType.LDAP_BIND;
-  }
-
-  public final boolean isOpenId() {
-    return authType() == AuthType.OPENID;
-  }
-
-  public final boolean isOAuth() {
-    return authType() == AuthType.OAUTH;
-  }
-
-  public final boolean isDev() {
-    return authType() == AuthType.DEVELOPMENT_BECOME_ANY_ACCOUNT;
-  }
-
-  public final boolean isClientSslCertLdap() {
-    return authType() == AuthType.CLIENT_SSL_CERT_LDAP;
-  }
-
-  public final boolean isCustomExtension() {
-    return authType() == AuthType.CUSTOM_EXTENSION;
-  }
-
-  public final boolean canEdit(AccountFieldName f) {
-    return editableAccountFields().contains(f);
-  }
-
-  public final List<AccountFieldName> editableAccountFields() {
-    List<AccountFieldName> fields = new ArrayList<>();
-    for (String f : Natives.asList(_editableAccountFields())) {
-      fields.add(AccountFieldName.valueOf(f));
-    }
-    return fields;
-  }
-
-  public final List<AgreementInfo> contributorAgreements() {
-    List<AgreementInfo> agreements = new ArrayList<>();
-    JsArray<AgreementInfo> contributorAgreements = _contributorAgreements();
-    if (contributorAgreements != null) {
-      agreements.addAll(Natives.asList(contributorAgreements));
-    }
-    return agreements;
-  }
-
-  public final boolean siteHasUsernames() {
-    if (isCustomExtension() && httpPasswordUrl() != null && !canEdit(AccountFieldName.USER_NAME)) {
-      return false;
-    }
-    return true;
-  }
-
-  public final boolean isHttpPasswordSettingsEnabled() {
-    return gitBasicAuthPolicy() == GitBasicAuthPolicy.HTTP
-        || gitBasicAuthPolicy() == GitBasicAuthPolicy.HTTP_LDAP;
-  }
-
-  public final GitBasicAuthPolicy gitBasicAuthPolicy() {
-    return GitBasicAuthPolicy.valueOf(gitBasicAuthPolicyRaw());
-  }
-
-  public final native boolean useContributorAgreements()
-      /*-{ return this.use_contributor_agreements || false; }-*/ ;
-
-  public final native String loginUrl() /*-{ return this.login_url; }-*/;
-
-  public final native String loginText() /*-{ return this.login_text; }-*/;
-
-  public final native String switchAccountUrl() /*-{ return this.switch_account_url; }-*/;
-
-  public final native String registerUrl() /*-{ return this.register_url; }-*/;
-
-  public final native String registerText() /*-{ return this.register_text; }-*/;
-
-  public final native String editFullNameUrl() /*-{ return this.edit_full_name_url; }-*/;
-
-  public final native String httpPasswordUrl() /*-{ return this.http_password_url; }-*/;
-
-  private native String gitBasicAuthPolicyRaw() /*-{ return this.git_basic_auth_policy; }-*/;
-
-  private native String authTypeRaw() /*-{ return this.auth_type; }-*/;
-
-  private native JsArrayString _editableAccountFields()
-      /*-{ return this.editable_account_fields; }-*/ ;
-
-  private native JsArray<AgreementInfo> _contributorAgreements()
-      /*-{ return this.contributor_agreements; }-*/ ;
-
-  protected AuthInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java
deleted file mode 100644
index 0f786a6..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ChangeInfo.java
+++ /dev/null
@@ -1,575 +0,0 @@
-// Copyright (C) 2012 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.client.info;
-
-import static java.util.Comparator.comparing;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.common.data.LabelValue;
-import com.google.gerrit.common.data.SubmitRecord;
-import com.google.gerrit.extensions.client.ReviewerState;
-import com.google.gerrit.extensions.client.SubmitType;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwtjsonrpc.client.impl.ser.JavaSqlTimestamp_JsonSerializer;
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-public class ChangeInfo extends JavaScriptObject {
-  public final void init() {
-    if (allLabels() != null) {
-      allLabels().copyKeysIntoChildren("_name");
-    }
-  }
-
-  public final Project.NameKey projectNameKey() {
-    return new Project.NameKey(project());
-  }
-
-  public final Change.Id legacyId() {
-    return new Change.Id(_number());
-  }
-
-  public final Timestamp created() {
-    Timestamp ts = _getCts();
-    if (ts == null) {
-      ts = JavaSqlTimestamp_JsonSerializer.parseTimestamp(createdRaw());
-      _setCts(ts);
-    }
-    return ts;
-  }
-
-  public final boolean hasEditBasedOnCurrentPatchSet() {
-    JsArray<RevisionInfo> revList = revisions().values();
-    RevisionInfo.sortRevisionInfoByNumber(revList);
-    return revList.get(revList.length() - 1).isEdit();
-  }
-
-  private native Timestamp _getCts() /*-{ return this._cts; }-*/;
-
-  private native void _setCts(Timestamp ts) /*-{ this._cts = ts; }-*/;
-
-  public final Timestamp updated() {
-    return JavaSqlTimestamp_JsonSerializer.parseTimestamp(updatedRaw());
-  }
-
-  public final Timestamp submitted() {
-    return JavaSqlTimestamp_JsonSerializer.parseTimestamp(submittedRaw());
-  }
-
-  public final String idAbbreviated() {
-    return new Change.Key(changeId()).abbreviate();
-  }
-
-  public final Change.Status status() {
-    return Change.Status.valueOf(statusRaw());
-  }
-
-  public final Set<String> labels() {
-    return allLabels().keySet();
-  }
-
-  public final Set<Integer> removableReviewerIds() {
-    Set<Integer> removable = new HashSet<>();
-    if (removableReviewers() != null) {
-      for (AccountInfo a : Natives.asList(removableReviewers())) {
-        removable.add(a._accountId());
-      }
-    }
-    return removable;
-  }
-
-  public final native String id() /*-{ return this.id; }-*/;
-
-  public final native String project() /*-{ return this.project; }-*/;
-
-  public final native String branch() /*-{ return this.branch; }-*/;
-
-  public final native String topic() /*-{ return this.topic; }-*/;
-
-  public final native String changeId() /*-{ return this.change_id; }-*/;
-
-  public final native boolean mergeable() /*-{ return this.mergeable ? true : false; }-*/;
-
-  public final native int insertions() /*-{ return this.insertions; }-*/;
-
-  public final native int deletions() /*-{ return this.deletions; }-*/;
-
-  private native String statusRaw() /*-{ return this.status; }-*/;
-
-  public final native String subject() /*-{ return this.subject; }-*/;
-
-  public final native AccountInfo owner() /*-{ return this.owner; }-*/;
-
-  public final native AccountInfo assignee() /*-{ return this.assignee; }-*/;
-
-  private native String createdRaw() /*-{ return this.created; }-*/;
-
-  private native String updatedRaw() /*-{ return this.updated; }-*/;
-
-  private native String submittedRaw() /*-{ return this.submitted; }-*/;
-
-  public final native AccountInfo submitter() /*-{ return this.submitter; }-*/;
-
-  public final native boolean starred() /*-{ return this.starred ? true : false; }-*/;
-
-  public final native boolean reviewed() /*-{ return this.reviewed ? true : false; }-*/;
-
-  public final native boolean isPrivate() /*-{ return this.is_private ? true : false; }-*/;
-
-  public final native boolean
-      isWorkInProgress() /*-{ return this.work_in_progress ? true : false; }-*/;
-
-  public final native NativeMap<LabelInfo> allLabels() /*-{ return this.labels; }-*/;
-
-  public final native LabelInfo label(String n) /*-{ return this.labels[n]; }-*/;
-
-  public final native String currentRevision() /*-{ return this.current_revision; }-*/;
-
-  public final native void setCurrentRevision(String r) /*-{ this.current_revision = r; }-*/;
-
-  public final native NativeMap<RevisionInfo> revisions() /*-{ return this.revisions; }-*/;
-
-  public final native RevisionInfo revision(String n) /*-{ return this.revisions[n]; }-*/;
-
-  public final native JsArray<MessageInfo> messages() /*-{ return this.messages; }-*/;
-
-  public final native void setEdit(EditInfo edit) /*-{ this.edit = edit; }-*/;
-
-  public final native EditInfo edit() /*-{ return this.edit; }-*/;
-
-  public final native boolean hasEdit() /*-{ return this.hasOwnProperty('edit') }-*/;
-
-  public final native JsArrayString hashtags() /*-{ return this.hashtags; }-*/;
-
-  public final native boolean hasPermittedLabels()
-      /*-{ return this.hasOwnProperty('permitted_labels') }-*/ ;
-
-  public final native NativeMap<JsArrayString> permittedLabels()
-      /*-{ return this.permitted_labels; }-*/ ;
-
-  public final native JsArrayString permittedValues(String n)
-      /*-{ return this.permitted_labels[n]; }-*/ ;
-
-  public final native JsArray<AccountInfo> removableReviewers()
-      /*-{ return this.removable_reviewers; }-*/ ;
-
-  private native NativeMap<JsArray<AccountInfo>> _reviewers() /*-{ return this.reviewers; }-*/;
-
-  public final Map<ReviewerState, List<AccountInfo>> reviewers() {
-    NativeMap<JsArray<AccountInfo>> reviewers = _reviewers();
-    Map<ReviewerState, List<AccountInfo>> result = new HashMap<>();
-    for (String k : reviewers.keySet()) {
-      ReviewerState state = ReviewerState.valueOf(k.toUpperCase());
-      List<AccountInfo> accounts = result.get(state);
-      if (accounts == null) {
-        accounts = new ArrayList<>();
-        result.put(state, accounts);
-      }
-      accounts.addAll(Natives.asList(reviewers.get(k)));
-    }
-    return result;
-  }
-
-  public final native boolean hasActions() /*-{ return this.hasOwnProperty('actions') }-*/;
-
-  public final native NativeMap<ActionInfo> actions() /*-{ return this.actions; }-*/;
-
-  public final native int _number() /*-{ return this._number; }-*/;
-
-  public final native boolean _more_changes() /*-{ return this._more_changes ? true : false; }-*/;
-
-  public final SubmitType submitType() {
-    String submitType = _submitType();
-    if (submitType == null) {
-      return null;
-    }
-    return SubmitType.valueOf(submitType);
-  }
-
-  private native String _submitType() /*-{ return this.submit_type; }-*/;
-
-  public final boolean submittable() {
-    init();
-    return _submittable();
-  }
-
-  private native boolean _submittable() /*-{ return this.submittable ? true : false; }-*/;
-
-  /**
-   * @return the index of the missing label or -1 if no label is missing, or if more than one label
-   *     is missing.
-   */
-  public final int getMissingLabelIndex() {
-    int i = -1;
-    int ret = -1;
-    List<LabelInfo> labels = Natives.asList(allLabels().values());
-    for (LabelInfo label : labels) {
-      i++;
-      if (!permittedLabels().containsKey(label.name())) {
-        continue;
-      }
-
-      JsArrayString values = permittedValues(label.name());
-      if (values.length() == 0) {
-        continue;
-      }
-
-      switch (label.status()) {
-        case NEED: // Label is required for submit.
-          if (ret != -1) {
-            // more than one label is missing, so it's unclear which to quick
-            // approve, return -1
-            return -1;
-          }
-          ret = i;
-          continue;
-
-        case OK: // Label already applied.
-        case MAY: // Label is not required.
-          continue;
-
-        case REJECT: // Submit cannot happen, do not quick approve.
-        case IMPOSSIBLE:
-          return -1;
-      }
-    }
-    return ret;
-  }
-
-  protected ChangeInfo() {}
-
-  public static class LabelInfo extends JavaScriptObject {
-    public final SubmitRecord.Label.Status status() {
-      if (approved() != null) {
-        return SubmitRecord.Label.Status.OK;
-      } else if (rejected() != null) {
-        return SubmitRecord.Label.Status.REJECT;
-      } else if (optional()) {
-        return SubmitRecord.Label.Status.MAY;
-      } else {
-        return SubmitRecord.Label.Status.NEED;
-      }
-    }
-
-    public final native String name() /*-{ return this._name; }-*/;
-
-    public final native AccountInfo approved() /*-{ return this.approved; }-*/;
-
-    public final native AccountInfo rejected() /*-{ return this.rejected; }-*/;
-
-    public final native AccountInfo recommended() /*-{ return this.recommended; }-*/;
-
-    public final native AccountInfo disliked() /*-{ return this.disliked; }-*/;
-
-    public final native JsArray<ApprovalInfo> all() /*-{ return this.all; }-*/;
-
-    public final ApprovalInfo forUser(int user) {
-      JsArray<ApprovalInfo> all = all();
-      for (int i = 0; all != null && i < all.length(); i++) {
-        if (all.get(i)._accountId() == user) {
-          return all.get(i);
-        }
-      }
-      return null;
-    }
-
-    private native NativeMap<NativeString> _values() /*-{ return this.values; }-*/;
-
-    public final Set<String> values() {
-      return Natives.keys(_values());
-    }
-
-    public final native String valueText(String n) /*-{ return this.values[n]; }-*/;
-
-    public final native boolean optional() /*-{ return this.optional ? true : false; }-*/;
-
-    public final native boolean blocking() /*-{ return this.blocking ? true : false; }-*/;
-
-    public final native short defaultValue() /*-{ return this.default_value; }-*/;
-
-    public final native short _value() /*-{
-      if (this.value) return this.value;
-      if (this.disliked) return -1;
-      if (this.recommended) return 1;
-      return 0;
-    }-*/;
-
-    public final String maxValue() {
-      return LabelValue.formatValue(valueSet().last());
-    }
-
-    public final SortedSet<Short> valueSet() {
-      SortedSet<Short> values = new TreeSet<>();
-      for (String v : values()) {
-        values.add(parseValue(v));
-      }
-      return values;
-    }
-
-    public static final short parseValue(String formatted) {
-      if (formatted.startsWith("+")) {
-        formatted = formatted.substring(1);
-      } else if (formatted.startsWith(" ")) {
-        formatted = formatted.trim();
-      }
-      return Short.parseShort(formatted);
-    }
-
-    protected LabelInfo() {}
-  }
-
-  public static class ApprovalInfo extends AccountInfo {
-    public final native boolean hasValue() /*-{ return this.hasOwnProperty('value'); }-*/;
-
-    public final native short value() /*-{ return this.value || 0; }-*/;
-
-    public final native VotingRangeInfo
-        permittedVotingRange() /*-{ return this.permitted_voting_range; }-*/;
-
-    protected ApprovalInfo() {}
-  }
-
-  public static class VotingRangeInfo extends AccountInfo {
-    public final native short min() /*-{ return this.min || 0; }-*/;
-
-    public final native short max() /*-{ return this.max || 0; }-*/;
-
-    protected VotingRangeInfo() {}
-  }
-
-  public static class EditInfo extends JavaScriptObject {
-    public final native String name() /*-{ return this.name; }-*/;
-
-    public final native String setName(String n) /*-{ this.name = n; }-*/;
-
-    public final native String baseRevision() /*-{ return this.base_revision; }-*/;
-
-    public final native CommitInfo commit() /*-{ return this.commit; }-*/;
-
-    public final native boolean hasActions() /*-{ return this.hasOwnProperty('actions') }-*/;
-
-    public final native NativeMap<ActionInfo> actions() /*-{ return this.actions; }-*/;
-
-    public final native boolean hasFetch() /*-{ return this.hasOwnProperty('fetch') }-*/;
-
-    public final native NativeMap<FetchInfo> fetch() /*-{ return this.fetch; }-*/;
-
-    public final native boolean hasFiles() /*-{ return this.hasOwnProperty('files') }-*/;
-
-    public final native NativeMap<FileInfo> files() /*-{ return this.files; }-*/;
-
-    protected EditInfo() {}
-  }
-
-  public static class RevisionInfo extends JavaScriptObject {
-    public static RevisionInfo fromEdit(EditInfo edit) {
-      RevisionInfo revisionInfo = createObject().cast();
-      revisionInfo.takeFromEdit(edit);
-      return revisionInfo;
-    }
-
-    public static RevisionInfo forParent(int number, CommitInfo commit) {
-      RevisionInfo revisionInfo = createObject().cast();
-      revisionInfo.takeFromParent(number, commit);
-      return revisionInfo;
-    }
-
-    private native void takeFromEdit(EditInfo edit) /*-{
-      this._number = 0;
-      this.name = edit.name;
-      this.commit = edit.commit;
-      this.edit_base = edit.base_revision;
-    }-*/;
-
-    private native void takeFromParent(int number, CommitInfo commit) /*-{
-      this._number = number;
-      this.commit = commit;
-      this.name = this._number;
-    }-*/;
-
-    public final native int _number() /*-{ return this._number; }-*/;
-
-    public final native String name() /*-{ return this.name; }-*/;
-
-    public final native AccountInfo uploader() /*-{ return this.uploader; }-*/;
-
-    public final native boolean isEdit() /*-{ return this._number == 0; }-*/;
-
-    public final native CommitInfo commit() /*-{ return this.commit; }-*/;
-
-    public final native void setCommit(CommitInfo c) /*-{ this.commit = c; }-*/;
-
-    public final native String editBase() /*-{ return this.edit_base; }-*/;
-
-    public final native boolean hasFiles() /*-{ return this.hasOwnProperty('files') }-*/;
-
-    public final native NativeMap<FileInfo> files() /*-{ return this.files; }-*/;
-
-    public final native boolean hasActions() /*-{ return this.hasOwnProperty('actions') }-*/;
-
-    public final native NativeMap<ActionInfo> actions() /*-{ return this.actions; }-*/;
-
-    public final native boolean hasFetch() /*-{ return this.hasOwnProperty('fetch') }-*/;
-
-    public final native NativeMap<FetchInfo> fetch() /*-{ return this.fetch; }-*/;
-
-    public final native boolean
-        hasPushCertificate() /*-{ return this.hasOwnProperty('push_certificate'); }-*/;
-
-    public final native PushCertificateInfo
-        pushCertificate() /*-{ return this.push_certificate; }-*/;
-
-    public static void sortRevisionInfoByNumber(JsArray<RevisionInfo> list) {
-      final int editParent = findEditParent(list);
-      Natives.asList(list)
-          .sort(comparing(r -> !r.isEdit() ? 2 * (r._number() - 1) + 1 : 2 * editParent));
-    }
-
-    public static int findEditParent(JsArray<RevisionInfo> list) {
-      RevisionInfo r = findEditParentRevision(list);
-      return r == null ? -1 : r._number();
-    }
-
-    public static RevisionInfo findEditParentRevision(JsArray<RevisionInfo> list) {
-      for (int i = 0; i < list.length(); i++) {
-        // edit under revisions?
-        RevisionInfo editInfo = list.get(i);
-        if (editInfo.isEdit()) {
-          String parentRevision = editInfo.editBase();
-          // find parent
-          for (int j = 0; j < list.length(); j++) {
-            RevisionInfo parentInfo = list.get(j);
-            String name = parentInfo.name();
-            if (name.equals(parentRevision)) {
-              // found parent pacth set number
-              return parentInfo;
-            }
-          }
-        }
-      }
-      return null;
-    }
-
-    public final String id() {
-      return PatchSet.Id.toId(_number());
-    }
-
-    public final boolean isMerge() {
-      return commit().parents().length() > 1;
-    }
-
-    protected RevisionInfo() {}
-  }
-
-  public static class FetchInfo extends JavaScriptObject {
-    public final native String url() /*-{ return this.url }-*/;
-
-    public final native String ref() /*-{ return this.ref }-*/;
-
-    public final native NativeMap<NativeString> commands() /*-{ return this.commands }-*/;
-
-    public final native String command(String n) /*-{ return this.commands[n]; }-*/;
-
-    protected FetchInfo() {}
-  }
-
-  public static class CommitInfo extends JavaScriptObject {
-    public final native String commit() /*-{ return this.commit; }-*/;
-
-    public final native JsArray<CommitInfo> parents() /*-{ return this.parents; }-*/;
-
-    public final native GitPerson author() /*-{ return this.author; }-*/;
-
-    public final native GitPerson committer() /*-{ return this.committer; }-*/;
-
-    public final native String subject() /*-{ return this.subject; }-*/;
-
-    public final native String message() /*-{ return this.message; }-*/;
-
-    public final native JsArray<WebLinkInfo> webLinks() /*-{ return this.web_links; }-*/;
-
-    protected CommitInfo() {}
-  }
-
-  public static class GitPerson extends JavaScriptObject {
-    public final native String name() /*-{ return this.name; }-*/;
-
-    public final native String email() /*-{ return this.email; }-*/;
-
-    private native String dateRaw() /*-{ return this.date; }-*/;
-
-    public final Timestamp date() {
-      return JavaSqlTimestamp_JsonSerializer.parseTimestamp(dateRaw());
-    }
-
-    protected GitPerson() {}
-  }
-
-  public static class MessageInfo extends JavaScriptObject {
-    public final native AccountInfo author() /*-{ return this.author; }-*/;
-
-    public final native String message() /*-{ return this.message; }-*/;
-
-    public final native int _revisionNumber() /*-{ return this._revision_number || 0; }-*/;
-
-    public final native String tag() /*-{ return this.tag; }-*/;
-
-    private native String dateRaw() /*-{ return this.date; }-*/;
-
-    public final Timestamp date() {
-      return JavaSqlTimestamp_JsonSerializer.parseTimestamp(dateRaw());
-    }
-
-    protected MessageInfo() {}
-  }
-
-  public static class MergeableInfo extends JavaScriptObject {
-    public final native String submitType() /*-{ return this.submit_type }-*/;
-
-    public final native boolean mergeable() /*-{ return this.mergeable }-*/;
-
-    protected MergeableInfo() {}
-  }
-
-  public static class IncludedInInfo extends JavaScriptObject {
-    public final Set<String> externalNames() {
-      return Natives.keys(external());
-    }
-
-    public final native JsArrayString branches() /*-{ return this.branches; }-*/;
-
-    public final native JsArrayString tags() /*-{ return this.tags; }-*/;
-
-    public final native JsArrayString external(String n) /*-{ return this.external[n]; }-*/;
-
-    private native NativeMap<JsArrayString> external() /*-{ return this.external; }-*/;
-
-    protected IncludedInInfo() {}
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/DownloadInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/DownloadInfo.java
deleted file mode 100644
index a22a1e8..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/DownloadInfo.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArrayString;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class DownloadInfo extends JavaScriptObject {
-  public final List<String> schemes() {
-    return _schemes().sortedKeys();
-  }
-
-  public final List<String> archives() {
-    List<String> archives = new ArrayList<>();
-    archives.addAll(Natives.asList(_archives()));
-    return archives;
-  }
-
-  public final native DownloadSchemeInfo scheme(String n) /*-{ return this.schemes[n]; }-*/;
-
-  private native NativeMap<DownloadSchemeInfo> _schemes() /*-{ return this.schemes; }-*/;
-
-  private native JsArrayString _archives() /*-{ return this.archives; }-*/;
-
-  protected DownloadInfo() {}
-
-  public static class DownloadSchemeInfo extends JavaScriptObject {
-    public final List<String> commandNames() {
-      return _commands().sortedKeys();
-    }
-
-    public final Set<DownloadCommandInfo> commands(String project) {
-      Set<DownloadCommandInfo> commands = new HashSet<>();
-      for (String commandName : commandNames()) {
-        commands.add(new DownloadCommandInfo(commandName, command(commandName, project)));
-      }
-      return commands;
-    }
-
-    public final String command(String commandName, String project) {
-      return command(commandName).replaceAll("\\$\\{project\\}", project);
-    }
-
-    private static String projectBaseName(String project) {
-      return project.substring(project.lastIndexOf('/') + 1);
-    }
-
-    public final List<String> cloneCommandNames() {
-      return _cloneCommands().sortedKeys();
-    }
-
-    public final List<DownloadCommandInfo> cloneCommands(String project) {
-      List<String> commandNames = cloneCommandNames();
-      List<DownloadCommandInfo> commands = new ArrayList<>(commandNames.size());
-      for (String commandName : commandNames) {
-        commands.add(new DownloadCommandInfo(commandName, cloneCommand(commandName, project)));
-      }
-      return commands;
-    }
-
-    public final String cloneCommand(String commandName, String project) {
-      return cloneCommand(commandName)
-          .replaceAll("\\$\\{project\\}", project)
-          .replaceAll("\\$\\{project-base-name\\}", projectBaseName(project));
-    }
-
-    public final String getUrl(String project) {
-      return url().replaceAll("\\$\\{project\\}", project);
-    }
-
-    public final native String name() /*-{ return this.name; }-*/;
-
-    public final native String url() /*-{ return this.url; }-*/;
-
-    public final native boolean isAuthRequired() /*-{ return this.is_auth_required || false; }-*/;
-
-    public final native boolean isAuthSupported() /*-{ return this.is_auth_supported || false; }-*/;
-
-    public final native String command(String n) /*-{ return this.commands[n]; }-*/;
-
-    public final native String cloneCommand(String n) /*-{ return this.clone_commands[n]; }-*/;
-
-    private native NativeMap<NativeString> _commands() /*-{ return this.commands; }-*/;
-
-    private native NativeMap<NativeString> _cloneCommands() /*-{ return this.clone_commands; }-*/;
-
-    protected DownloadSchemeInfo() {}
-  }
-
-  public static class DownloadCommandInfo {
-    private final String name;
-    private final String command;
-
-    DownloadCommandInfo(String name, String command) {
-      this.name = name;
-      this.command = command;
-    }
-
-    public String name() {
-      return name;
-    }
-
-    public String command() {
-      return command;
-    }
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/FileInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/FileInfo.java
deleted file mode 100644
index fc3dbf1..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/FileInfo.java
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.common.data.FilenameComparator;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import java.util.Comparator;
-
-public class FileInfo extends JavaScriptObject {
-  public final native String path() /*-{ return this.path; }-*/;
-
-  public final native String oldPath() /*-{ return this.old_path; }-*/;
-
-  public final native int linesInserted() /*-{ return this.lines_inserted || 0; }-*/;
-
-  public final native int linesDeleted() /*-{ return this.lines_deleted || 0; }-*/;
-
-  public final native boolean binary() /*-{ return this.binary || false; }-*/;
-
-  public final native String status() /*-{ return this.status; }-*/;
-
-  // JSNI methods cannot have 'long' as a parameter type or a return type and
-  // it's suggested to use double in this case:
-  // http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html#important
-  public final long size() {
-    return (long) _size();
-  }
-
-  private native double _size() /*-{ return this.size || 0; }-*/;
-
-  public final long sizeDelta() {
-    return (long) _sizeDelta();
-  }
-
-  private native double _sizeDelta() /*-{ return this.size_delta || 0; }-*/;
-
-  public final native int _row() /*-{ return this._row }-*/;
-
-  public final native void _row(int r) /*-{ this._row = r }-*/;
-
-  public static void sortFileInfoByPath(JsArray<FileInfo> list) {
-    Natives.asList(list).sort(Comparator.comparing(FileInfo::path, FilenameComparator.INSTANCE));
-  }
-
-  public static String getFileName(String path) {
-    String fileName;
-    if (Patch.COMMIT_MSG.equals(path)) {
-      fileName = "Commit Message";
-    } else if (Patch.MERGE_LIST.equals(path)) {
-      fileName = "Merge List";
-    } else {
-      fileName = path;
-    }
-
-    int s = fileName.lastIndexOf('/');
-    return s >= 0 ? fileName.substring(s + 1) : fileName;
-  }
-
-  protected FileInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
deleted file mode 100644
index fbdf52c..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright (C) 2014 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.client.info;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DateFormat;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DefaultBase;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DownloadCommand;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailFormat;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.ReviewCategoryStrategy;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.TimeFormat;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class GeneralPreferences extends JavaScriptObject {
-  public static GeneralPreferences create() {
-    return createObject().cast();
-  }
-
-  public static GeneralPreferences createDefault() {
-    GeneralPreferencesInfo d = GeneralPreferencesInfo.defaults();
-    GeneralPreferences p = createObject().cast();
-    p.changesPerPage(d.changesPerPage);
-    p.showSiteHeader(d.showSiteHeader);
-    p.useFlashClipboard(d.useFlashClipboard);
-    p.downloadScheme(d.downloadScheme);
-    p.downloadCommand(d.downloadCommand);
-    p.dateFormat(d.getDateFormat());
-    p.timeFormat(d.getTimeFormat());
-    p.highlightAssigneeInChangeTable(d.highlightAssigneeInChangeTable);
-    p.relativeDateInChangeTable(d.relativeDateInChangeTable);
-    p.sizeBarInChangeTable(d.sizeBarInChangeTable);
-    p.legacycidInChangeTable(d.legacycidInChangeTable);
-    p.muteCommonPathPrefixes(d.muteCommonPathPrefixes);
-    p.signedOffBy(d.signedOffBy);
-    p.emailFormat(d.emailFormat);
-    p.reviewCategoryStrategy(d.getReviewCategoryStrategy());
-    p.diffView(d.getDiffView());
-    p.emailStrategy(d.emailStrategy);
-    p.defaultBaseForMerges(d.defaultBaseForMerges);
-    return p;
-  }
-
-  public final int changesPerPage() {
-    int changesPerPage = get("changes_per_page", GeneralPreferencesInfo.DEFAULT_PAGESIZE);
-    return 0 < changesPerPage ? changesPerPage : GeneralPreferencesInfo.DEFAULT_PAGESIZE;
-  }
-
-  private native short get(String n, int d) /*-{ return this.hasOwnProperty(n) ? this[n] : d }-*/;
-
-  public final native boolean showSiteHeader() /*-{ return this.show_site_header || false }-*/;
-
-  public final native boolean useFlashClipboard()
-      /*-{ return this.use_flash_clipboard || false }-*/ ;
-
-  public final native String downloadScheme() /*-{ return this.download_scheme }-*/;
-
-  public final DownloadCommand downloadCommand() {
-    String s = downloadCommandRaw();
-    return s != null ? DownloadCommand.valueOf(s) : null;
-  }
-
-  private native String downloadCommandRaw() /*-{ return this.download_command }-*/;
-
-  public final DateFormat dateFormat() {
-    String s = dateFormatRaw();
-    return s != null ? DateFormat.valueOf(s) : null;
-  }
-
-  private native String dateFormatRaw() /*-{ return this.date_format }-*/;
-
-  public final TimeFormat timeFormat() {
-    String s = timeFormatRaw();
-    return s != null ? TimeFormat.valueOf(s) : null;
-  }
-
-  private native String timeFormatRaw() /*-{ return this.time_format }-*/;
-
-  public final native boolean highlightAssigneeInChangeTable()
-      /*-{ return this.highlight_assignee_in_change_table || false }-*/ ;
-
-  public final native boolean relativeDateInChangeTable()
-      /*-{ return this.relative_date_in_change_table || false }-*/ ;
-
-  public final native boolean sizeBarInChangeTable()
-      /*-{ return this.size_bar_in_change_table || false }-*/ ;
-
-  public final native boolean legacycidInChangeTable()
-      /*-{ return this.legacycid_in_change_table || false }-*/ ;
-
-  public final native boolean muteCommonPathPrefixes()
-      /*-{ return this.mute_common_path_prefixes || false }-*/ ;
-
-  public final native boolean signedOffBy() /*-{ return this.signed_off_by || false }-*/;
-
-  public final ReviewCategoryStrategy reviewCategoryStrategy() {
-    String s = reviewCategeoryStrategyRaw();
-    return s != null ? ReviewCategoryStrategy.valueOf(s) : ReviewCategoryStrategy.NONE;
-  }
-
-  private native String reviewCategeoryStrategyRaw() /*-{ return this.review_category_strategy }-*/;
-
-  public final DiffView diffView() {
-    String s = diffViewRaw();
-    return s != null ? DiffView.valueOf(s) : null;
-  }
-
-  private native String diffViewRaw() /*-{ return this.diff_view }-*/;
-
-  public final EmailStrategy emailStrategy() {
-    String s = emailStrategyRaw();
-    return s != null ? EmailStrategy.valueOf(s) : null;
-  }
-
-  private native String emailStrategyRaw() /*-{ return this.email_strategy }-*/;
-
-  public final EmailFormat emailFormat() {
-    String s = emailFormatRaw();
-    return s != null ? EmailFormat.valueOf(s) : null;
-  }
-
-  private native String emailFormatRaw() /*-{ return this.email_format }-*/;
-
-  public final DefaultBase defaultBaseForMerges() {
-    String s = defaultBaseForMergesRaw();
-    return s != null ? DefaultBase.valueOf(s) : null;
-  }
-
-  private native String defaultBaseForMergesRaw() /*-{ return this.default_base_for_merges }-*/;
-
-  public final native boolean
-      publishCommentsOnPush() /*-{ return this.publish_comments_on_push || false }-*/;
-
-  public final native boolean
-      workInProgressByDefault() /*-{ return this.work_in_progress_by_default || false }-*/;
-
-  public final native JsArray<TopMenuItem> my() /*-{ return this.my; }-*/;
-
-  public final native void changesPerPage(int n) /*-{ this.changes_per_page = n }-*/;
-
-  public final native void showSiteHeader(boolean s) /*-{ this.show_site_header = s }-*/;
-
-  public final native void useFlashClipboard(boolean u) /*-{ this.use_flash_clipboard = u }-*/;
-
-  public final native void downloadScheme(String d) /*-{ this.download_scheme = d }-*/;
-
-  public final void downloadCommand(DownloadCommand d) {
-    downloadCommandRaw(d != null ? d.toString() : null);
-  }
-
-  public final native void downloadCommandRaw(String d) /*-{ this.download_command = d }-*/;
-
-  public final void dateFormat(DateFormat f) {
-    dateFormatRaw(f != null ? f.toString() : null);
-  }
-
-  private native void dateFormatRaw(String f) /*-{ this.date_format = f }-*/;
-
-  public final void timeFormat(TimeFormat f) {
-    timeFormatRaw(f != null ? f.toString() : null);
-  }
-
-  private native void timeFormatRaw(String f) /*-{ this.time_format = f }-*/;
-
-  public final native void highlightAssigneeInChangeTable(boolean d)
-      /*-{ this.highlight_assignee_in_change_table = d }-*/ ;
-
-  public final native void relativeDateInChangeTable(boolean d)
-      /*-{ this.relative_date_in_change_table = d }-*/ ;
-
-  public final native void sizeBarInChangeTable(boolean s)
-      /*-{ this.size_bar_in_change_table = s }-*/ ;
-
-  public final native void legacycidInChangeTable(boolean s)
-      /*-{ this.legacycid_in_change_table = s }-*/ ;
-
-  public final native void muteCommonPathPrefixes(boolean s)
-      /*-{ this.mute_common_path_prefixes = s }-*/ ;
-
-  public final native void signedOffBy(boolean s) /*-{ this.signed_off_by = s }-*/;
-
-  public final void reviewCategoryStrategy(ReviewCategoryStrategy s) {
-    reviewCategoryStrategyRaw(s != null ? s.toString() : null);
-  }
-
-  private native void reviewCategoryStrategyRaw(String s)
-      /*-{ this.review_category_strategy = s }-*/ ;
-
-  public final void diffView(DiffView d) {
-    diffViewRaw(d != null ? d.toString() : null);
-  }
-
-  private native void diffViewRaw(String d) /*-{ this.diff_view = d }-*/;
-
-  public final void emailStrategy(EmailStrategy s) {
-    emailStrategyRaw(s != null ? s.toString() : null);
-  }
-
-  private native void emailStrategyRaw(String s) /*-{ this.email_strategy = s }-*/;
-
-  public final void emailFormat(EmailFormat f) {
-    emailFormatRaw(f != null ? f.toString() : null);
-  }
-
-  private native void emailFormatRaw(String s) /*-{ this.email_format = s }-*/;
-
-  public final void defaultBaseForMerges(DefaultBase b) {
-    defaultBaseForMergesRaw(b != null ? b.toString() : null);
-  }
-
-  private native void defaultBaseForMergesRaw(String b) /*-{ this.default_base_for_merges = b }-*/;
-
-  public final native void publishCommentsOnPush(
-      boolean p) /*-{ this.publish_comments_on_push = p }-*/;
-
-  public final native void workInProgressByDefault(
-      boolean p) /*-{ this.work_in_progress_by_default = p }-*/;
-
-  public final void setMyMenus(List<TopMenuItem> myMenus) {
-    initMy();
-    for (TopMenuItem n : myMenus) {
-      addMy(n);
-    }
-  }
-
-  final native void initMy() /*-{ this.my = []; }-*/;
-
-  final native void addMy(TopMenuItem m) /*-{ this.my.push(m); }-*/;
-
-  public final Map<String, String> urlAliases() {
-    Map<String, String> urlAliases = new HashMap<>();
-    for (String k : Natives.keys(_urlAliases())) {
-      urlAliases.put(k, urlAliasToken(k));
-    }
-    return urlAliases;
-  }
-
-  private native String urlAliasToken(String m) /*-{ return this.url_aliases[m]; }-*/;
-
-  private native NativeMap<NativeString> _urlAliases() /*-{ return this.url_aliases; }-*/;
-
-  public final void setUrlAliases(Map<String, String> urlAliases) {
-    initUrlAliases();
-    for (Map.Entry<String, String> e : urlAliases.entrySet()) {
-      putUrlAlias(e.getKey(), e.getValue());
-    }
-  }
-
-  private native void putUrlAlias(String m, String t) /*-{ this.url_aliases[m] = t; }-*/;
-
-  private native void initUrlAliases() /*-{ this.url_aliases = {}; }-*/;
-
-  protected GeneralPreferences() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GerritInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GerritInfo.java
deleted file mode 100644
index 78ca417..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GerritInfo.java
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gerrit.extensions.client.UiType;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArrayString;
-import java.util.ArrayList;
-import java.util.List;
-
-public class GerritInfo extends JavaScriptObject {
-  public final Project.NameKey allProjectsNameKey() {
-    return new Project.NameKey(allProjects());
-  }
-
-  public final boolean isAllProjects(Project.NameKey p) {
-    return allProjectsNameKey().equals(p);
-  }
-
-  public final Project.NameKey allUsersNameKey() {
-    return new Project.NameKey(allUsers());
-  }
-
-  public final boolean isAllUsers(Project.NameKey p) {
-    return allUsersNameKey().equals(p);
-  }
-
-  public final native String allProjects() /*-{ return this.all_projects; }-*/;
-
-  public final native String allUsers() /*-{ return this.all_users; }-*/;
-
-  public final native boolean docSearch() /*-{ return this.doc_search; }-*/;
-
-  public final native String docUrl() /*-{ return this.doc_url; }-*/;
-
-  public final native boolean editGpgKeys() /*-{ return this.edit_gpg_keys || false; }-*/;
-
-  public final native String reportBugUrl() /*-{ return this.report_bug_url; }-*/;
-
-  public final native String reportBugText() /*-{ return this.report_bug_text; }-*/;
-
-  private native JsArrayString _webUis() /*-{ return this.web_uis; }-*/;
-
-  public final List<UiType> webUis() {
-    JsArrayString webUis = _webUis();
-    List<UiType> result = new ArrayList<>(webUis.length());
-    for (int i = 0; i < webUis.length(); i++) {
-      UiType t = UiType.parse(webUis.get(i));
-      if (t != null) {
-        result.add(t);
-      }
-    }
-    return result;
-  }
-
-  protected GerritInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java
deleted file mode 100644
index fd4fde7..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GpgKeyInfo.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArrayString;
-
-public class GpgKeyInfo extends JavaScriptObject {
-  public enum Status {
-    BAD,
-    OK,
-    TRUSTED;
-  }
-
-  public final native String id() /*-{ return this.id; }-*/;
-
-  public final native String fingerprint() /*-{ return this.fingerprint; }-*/;
-
-  public final native JsArrayString userIds() /*-{ return this.user_ids; }-*/;
-
-  public final native String key() /*-{ return this.key; }-*/;
-
-  private native String statusRaw() /*-{ return this.status; }-*/;
-
-  public final Status status() {
-    String s = statusRaw();
-    if (s == null) {
-      return null;
-    }
-    return Status.valueOf(s);
-  }
-
-  public final native boolean hasProblems() /*-{ return this.hasOwnProperty('problems'); }-*/;
-
-  public final native JsArrayString problems() /*-{ return this.problems; }-*/;
-
-  protected GpgKeyInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupBaseInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupBaseInfo.java
deleted file mode 100644
index 94905c0..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupBaseInfo.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.http.client.URL;
-
-public class GroupBaseInfo extends JavaScriptObject {
-  public final AccountGroup.UUID getGroupUUID() {
-    return new AccountGroup.UUID(URL.decodeQueryString(id()));
-  }
-
-  public final native String id() /*-{ return this.id; }-*/;
-
-  public final native String name() /*-{ return this.name; }-*/;
-
-  protected GroupBaseInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupInfo.java
deleted file mode 100644
index 9bf3411a..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GroupInfo.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.http.client.URL;
-
-public class GroupInfo extends GroupBaseInfo {
-  public final AccountGroup.Id getGroupId() {
-    return new AccountGroup.Id(group_id());
-  }
-
-  public final native GroupOptionsInfo options() /*-{ return this.options; }-*/;
-
-  public final native String description() /*-{ return this.description; }-*/;
-
-  public final native String url() /*-{ return this.url; }-*/;
-
-  public final native String owner() /*-{ return this.owner; }-*/;
-
-  public final native void owner(String o) /*-{ if(o)this.owner=o; }-*/;
-
-  public final native JsArray<AccountInfo> members() /*-{ return this.members; }-*/;
-
-  public final native JsArray<GroupInfo> includes() /*-{ return this.includes; }-*/;
-
-  private native int group_id() /*-{ return this.group_id; }-*/;
-
-  private native String owner_id() /*-{ return this.owner_id; }-*/;
-
-  private native void owner_id(String o) /*-{ if(o)this.owner_id=o; }-*/;
-
-  public final AccountGroup.UUID getOwnerUUID() {
-    String owner = owner_id();
-    if (owner != null) {
-      return new AccountGroup.UUID(URL.decodeQueryString(owner));
-    }
-    return null;
-  }
-
-  public final void setOwnerUUID(AccountGroup.UUID uuid) {
-    owner_id(URL.encodeQueryString(uuid.get()));
-  }
-
-  protected GroupInfo() {}
-
-  public static class GroupOptionsInfo extends JavaScriptObject {
-    public final native boolean
-        isVisibleToAll() /*-{ return this['visible_to_all'] ? true : false; }-*/;
-
-    protected GroupOptionsInfo() {}
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/OAuthTokenInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/OAuthTokenInfo.java
deleted file mode 100644
index d96adaa..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/OAuthTokenInfo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2016 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class OAuthTokenInfo extends JavaScriptObject {
-
-  protected OAuthTokenInfo() {}
-
-  public final native String username() /*-{ return this.username; }-*/;
-
-  public final native String resourceHost() /*-{ return this.resource_host; }-*/;
-
-  public final native String accessToken() /*-{ return this.access_token; }-*/;
-
-  public final native String providerId() /*-{ return this.provider_id; }-*/;
-
-  public final native String expiresAt() /*-{ return this.expires_at; }-*/;
-
-  public final native String type() /*-{ return this.type; }-*/;
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java
deleted file mode 100644
index fb5d932..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/PushCertificateInfo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class PushCertificateInfo extends JavaScriptObject {
-  public final native String certificate() /*-{ return this.certificate; }-*/;
-
-  public final native GpgKeyInfo key() /*-{ return this.key; }-*/;
-
-  protected PushCertificateInfo() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ServerInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ServerInfo.java
deleted file mode 100644
index d3274e6..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/ServerInfo.java
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (C) 2015 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.client.info;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArrayString;
-import java.util.HashMap;
-import java.util.Map;
-
-public class ServerInfo extends JavaScriptObject {
-  public final native AuthInfo auth() /*-{ return this.auth; }-*/;
-
-  public final native ChangeConfigInfo change() /*-{ return this.change; }-*/;
-
-  public final native DownloadInfo download() /*-{ return this.download; }-*/;
-
-  public final native GerritInfo gerrit() /*-{ return this.gerrit; }-*/;
-
-  public final native PluginConfigInfo plugin() /*-{ return this.plugin; }-*/;
-
-  public final native SshdInfo sshd() /*-{ return this.sshd; }-*/;
-
-  public final native SuggestInfo suggest() /*-{ return this.suggest; }-*/;
-
-  public final native UserConfigInfo user() /*-{ return this.user; }-*/;
-
-  public final native ReceiveInfo receive() /*-{ return this.receive; }-*/;
-
-  public final Map<String, String> urlAliases() {
-    Map<String, String> urlAliases = new HashMap<>();
-    for (String k : Natives.keys(_urlAliases())) {
-      urlAliases.put(k, urlAliasToken(k));
-    }
-    return urlAliases;
-  }
-
-  public final native String urlAliasToken(String n) /*-{ return this.url_aliases[n]; }-*/;
-
-  private native NativeMap<NativeString> _urlAliases() /*-{ return this.url_aliases; }-*/;
-
-  public final boolean hasSshd() {
-    return sshd() != null;
-  }
-
-  protected ServerInfo() {}
-
-  public static class ChangeConfigInfo extends JavaScriptObject {
-    public final native boolean allowBlame() /*-{ return this.allow_blame || false; }-*/;
-
-    public final native int largeChange() /*-{ return this.large_change || 0; }-*/;
-
-    public final native String replyLabel() /*-{ return this.reply_label; }-*/;
-
-    public final native String replyTooltip() /*-{ return this.reply_tooltip; }-*/;
-
-    public final native boolean
-        showAssigneeInChangesTable() /*-{ return this.show_assignee_in_changes_table || false; }-*/;
-
-    public final native int updateDelay() /*-{ return this.update_delay || 0; }-*/;
-
-    public final native boolean isSubmitWholeTopicEnabled() /*-{
-        return this.submit_whole_topic; }-*/;
-
-    protected ChangeConfigInfo() {}
-  }
-
-  public static class PluginConfigInfo extends JavaScriptObject {
-    public final native boolean hasAvatars() /*-{ return this.has_avatars || false; }-*/;
-
-    public final native JsArrayString jsResourcePaths() /*-{
-        return this.js_resource_paths || []; }-*/;
-
-    protected PluginConfigInfo() {}
-  }
-
-  public static class SshdInfo extends JavaScriptObject {
-    protected SshdInfo() {}
-  }
-
-  public static class SuggestInfo extends JavaScriptObject {
-    public final native int from() /*-{ return this.from || 0; }-*/;
-
-    protected SuggestInfo() {}
-  }
-
-  public static class UserConfigInfo extends JavaScriptObject {
-    public final native String anonymousCowardName() /*-{ return this.anonymous_coward_name; }-*/;
-
-    protected UserConfigInfo() {}
-  }
-
-  public static class ReceiveInfo extends JavaScriptObject {
-    public final native boolean enableSignedPush()
-        /*-{ return this.enable_signed_push || false; }-*/ ;
-
-    protected ReceiveInfo() {}
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenu.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenu.java
deleted file mode 100644
index 7e25af2..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenu.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-
-public class TopMenu extends JavaScriptObject {
-
-  protected TopMenu() {}
-
-  public final native String getName() /*-{ return this.name; }-*/;
-
-  public final native JsArray<TopMenuItem> getItems() /*-{ return this.items; }-*/;
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuItem.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuItem.java
deleted file mode 100644
index 3a286a2..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuItem.java
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class TopMenuItem extends JavaScriptObject {
-  public static TopMenuItem create(String name, String url) {
-    TopMenuItem i = createObject().cast();
-    i.name(name);
-    i.url(url);
-    return i;
-  }
-
-  public final native String getName() /*-{ return this.name; }-*/;
-
-  public final native String getUrl() /*-{ return this.url; }-*/;
-
-  public final native String getTarget() /*-{ return this.target; }-*/;
-
-  public final native String getId() /*-{ return this.id; }-*/;
-
-  public final native void name(String n) /*-{ this.name = n }-*/;
-
-  public final native void url(String u) /*-{ this.url = u }-*/;
-
-  protected TopMenuItem() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuList.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuList.java
deleted file mode 100644
index d7df1f7..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/TopMenuList.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (C) 2013 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.client.info;
-
-import com.google.gwt.core.client.JsArray;
-
-public class TopMenuList extends JsArray<TopMenu> {
-
-  protected TopMenuList() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/WebLinkInfo.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/WebLinkInfo.java
deleted file mode 100644
index bcf3dde..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/WebLinkInfo.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2014 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.client.info;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.Image;
-
-public class WebLinkInfo extends JavaScriptObject {
-
-  public final native String name() /*-{ return this.name; }-*/;
-
-  public final native String imageUrl() /*-{ return this.image_url; }-*/;
-
-  public final native String url() /*-{ return this.url; }-*/;
-
-  public final native String target() /*-{ return this.target; }-*/;
-
-  protected WebLinkInfo() {}
-
-  public final Anchor toAnchor() {
-    Anchor a = new Anchor();
-    a.setHref(url());
-    if (target() != null && !target().isEmpty()) {
-      a.setTarget(target());
-    }
-    if (imageUrl() != null && !imageUrl().isEmpty()) {
-      Image img = new Image();
-      img.setAltText(name());
-      img.setUrl(imageUrl());
-      img.setTitle(name());
-      a.getElement().appendChild(img.getElement());
-    } else {
-      a.setText("(" + name() + ")");
-    }
-    return a;
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeMap.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeMap.java
deleted file mode 100644
index 41306ff..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeMap.java
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright (C) 2012 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.client.rpc;
-
-import static java.util.stream.Collectors.toCollection;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-/** A map of native JSON objects, keyed by a string. */
-public class NativeMap<T extends JavaScriptObject> extends JavaScriptObject {
-  public static <T extends JavaScriptObject> NativeMap<T> create() {
-    return createObject().cast();
-  }
-
-  /**
-   * Loop through the result map's entries and copy the key strings into the "name" property of the
-   * corresponding child object. This only runs on the top level map of the result, and requires the
-   * children to be JSON objects and not a JSON primitive (e.g. boolean or string).
-   */
-  public static <T extends JavaScriptObject, M extends NativeMap<T>>
-      AsyncCallback<M> copyKeysIntoChildren(AsyncCallback<M> callback) {
-    return copyKeysIntoChildren("name", callback);
-  }
-
-  /** Loop through the result map and set asProperty on the children. */
-  public static <T extends JavaScriptObject, M extends NativeMap<T>>
-      AsyncCallback<M> copyKeysIntoChildren(String asProperty, AsyncCallback<M> callback) {
-    return new TransformCallback<M, M>(callback) {
-      @Override
-      protected M transform(M result) {
-        result.copyKeysIntoChildren(asProperty);
-        return result;
-      }
-    };
-  }
-
-  protected NativeMap() {}
-
-  public final Set<String> keySet() {
-    return Natives.keys(this);
-  }
-
-  public final List<String> sortedKeys() {
-    return keySet().stream().sorted().collect(toCollection(ArrayList::new));
-  }
-
-  public final native JsArray<T> values() /*-{
-    var s = this;
-    var v = [];
-    var i = 0;
-    for (var k in s) {
-      if (s.hasOwnProperty(k)) {
-        v[i++] = s[k];
-      }
-    }
-    return v;
-  }-*/;
-
-  public final int size() {
-    return keySet().size();
-  }
-
-  public final boolean isEmpty() {
-    return size() == 0;
-  }
-
-  public final boolean containsKey(String n) {
-    return get(n) != null;
-  }
-
-  public final native T get(String n) /*-{ return this[n]; }-*/;
-
-  public final native void put(String n, T v) /*-{ this[n] = v; }-*/;
-
-  public final native void copyKeysIntoChildren(String p) /*-{
-    var s = this;
-    for (var k in s) {
-      if (s.hasOwnProperty(k)) {
-        var c = s[k];
-        c[p] = k;
-      }
-    }
-  }-*/;
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeString.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeString.java
deleted file mode 100644
index e0bca0e..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/NativeString.java
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2012 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.client.rpc;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-/** Wraps a String that was returned from a JSON API. */
-public final class NativeString extends JavaScriptObject {
-  public static final JavaScriptObject TYPE = init();
-
-  // Used from core and plugins
-  private static native JavaScriptObject init() /*-{
-    if ($wnd.Gerrit === undefined || $wnd.Gerrit.JsonString === undefined) {
-      return function(s){this.s=s};
-    } else {
-      return $wnd.Gerrit.JsonString;
-    }
-  }-*/;
-
-  static NativeString wrap(String s) {
-    return wrap0(TYPE, s);
-  }
-
-  private static native NativeString wrap0(JavaScriptObject T, String s) /*-{ return new T(s) }-*/;
-
-  public native String asString() /*-{ return this.s; }-*/;
-
-  public static AsyncCallback<NativeString> unwrap(AsyncCallback<String> cb) {
-    return new AsyncCallback<NativeString>() {
-      @Override
-      public void onSuccess(NativeString result) {
-        cb.onSuccess(result != null ? result.asString() : null);
-      }
-
-      @Override
-      public void onFailure(Throwable caught) {
-        cb.onFailure(caught);
-      }
-    };
-  }
-
-  public static boolean is(JavaScriptObject o) {
-    return is(TYPE, o);
-  }
-
-  private static native boolean is(JavaScriptObject T, JavaScriptObject o)
-      /*-{ return o instanceof T }-*/ ;
-
-  protected NativeString() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/Natives.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/Natives.java
deleted file mode 100644
index 1421386..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/Natives.java
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright (C) 2012 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.client.rpc;
-
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.json.client.JSONObject;
-import java.util.AbstractList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-public class Natives {
-  /**
-   * Get the names of defined properties on the object. The returned set iterates in the native
-   * iteration order, which may match the source order.
-   */
-  public static Set<String> keys(JavaScriptObject obj) {
-    if (obj != null) {
-      return new JSONObject(obj).keySet();
-    }
-    return Collections.emptySet();
-  }
-
-  public static List<String> asList(JsArrayString arr) {
-    if (arr == null) {
-      return null;
-    }
-    return new AbstractList<String>() {
-      @Override
-      public String set(int index, String element) {
-        String old = arr.get(index);
-        arr.set(index, element);
-        return old;
-      }
-
-      @Override
-      public String get(int index) {
-        return arr.get(index);
-      }
-
-      @Override
-      public int size() {
-        return arr.length();
-      }
-    };
-  }
-
-  public static <T extends JavaScriptObject> List<T> asList(JsArray<T> arr) {
-    if (arr == null) {
-      return null;
-    }
-    return new AbstractList<T>() {
-      @Override
-      public T set(int index, T element) {
-        T old = arr.get(index);
-        arr.set(index, element);
-        return old;
-      }
-
-      @Override
-      public T get(int index) {
-        return arr.get(index);
-      }
-
-      @Override
-      public int size() {
-        return arr.length();
-      }
-    };
-  }
-
-  public static <T extends JavaScriptObject> JsArray<T> arrayOf(T element) {
-    JsArray<T> arr = JavaScriptObject.createArray().cast();
-    arr.push(element);
-    return arr;
-  }
-
-  public static JsArrayString arrayOf(Iterable<String> elements) {
-    JsArrayString arr = JavaScriptObject.createArray().cast();
-    for (String elem : elements) {
-      arr.push(elem);
-    }
-    return arr;
-  }
-
-  public static JsArrayString arrayOf(String element) {
-    JsArrayString arr = JavaScriptObject.createArray().cast();
-    arr.push(element);
-    return arr;
-  }
-
-  private Natives() {}
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/TransformCallback.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/TransformCallback.java
deleted file mode 100644
index 00e6bb1..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/rpc/TransformCallback.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2012 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.client.rpc;
-
-import com.google.gwt.user.client.rpc.AsyncCallback;
-
-/** Transforms a value and passes it on to another callback. */
-public abstract class TransformCallback<I, O> implements AsyncCallback<I> {
-  private final AsyncCallback<O> callback;
-
-  protected TransformCallback(AsyncCallback<O> callback) {
-    this.callback = callback;
-  }
-
-  @Override
-  public void onSuccess(I result) {
-    callback.onSuccess(transform(result));
-  }
-
-  @Override
-  public void onFailure(Throwable caught) {
-    callback.onFailure(caught);
-  }
-
-  protected abstract O transform(I result);
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/HighlightSuggestion.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/HighlightSuggestion.java
deleted file mode 100644
index 513f570..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/HighlightSuggestion.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (C) 2015 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.client.ui;
-
-import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
-import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
-
-/** A {@code Suggestion} with highlights. */
-public class HighlightSuggestion implements Suggestion {
-
-  private final String keyword;
-  private final String value;
-
-  public HighlightSuggestion(String keyword, String value) {
-    this.keyword = keyword;
-    this.value = value;
-  }
-
-  @Override
-  public String getDisplayString() {
-    int start = 0;
-    int keyLen = keyword.length();
-    SafeHtmlBuilder builder = new SafeHtmlBuilder();
-    for (; ; ) {
-      int index = value.indexOf(keyword, start);
-      if (index == -1) {
-        builder.appendEscaped(value.substring(start));
-        break;
-      }
-      builder.appendEscaped(value.substring(start, index));
-      builder.appendHtmlConstant("<strong>");
-      start = index + keyLen;
-      builder.appendEscaped(value.substring(index, start));
-      builder.appendHtmlConstant("</strong>");
-    }
-    return builder.toSafeHtml().asString();
-  }
-
-  @Override
-  public String getReplacementString() {
-    return value;
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java
deleted file mode 100644
index d66d6a6..0000000
--- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/ui/RemoteSuggestOracle.java
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright (C) 2010 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.client.ui;
-
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.SuggestOracle;
-
-/**
- * Delegates to a slow SuggestOracle, such as a remote server API.
- *
- * <p>A response is only supplied to the UI if no requests were made after the oracle begin that
- * request.
- *
- * <p>When a request is made while the delegate is still processing a prior request all intermediate
- * requests are discarded and the most recent request is queued. The pending request's response is
- * discarded and the most recent request is started.
- */
-public class RemoteSuggestOracle extends SuggestOracle {
-  private final SuggestOracle oracle;
-  private Query query;
-  private String last;
-  private Timer requestRetentionTimer;
-  private boolean cancelOutstandingRequest;
-
-  private boolean serveSuggestions;
-
-  public RemoteSuggestOracle(SuggestOracle src) {
-    oracle = src;
-  }
-
-  public String getLast() {
-    return last;
-  }
-
-  @Override
-  public void requestSuggestions(Request req, Callback cb) {
-    if (!serveSuggestions) {
-      return;
-    }
-
-    // Use a timer for key stroke retention, such that we don't query the
-    // backend for each and every keystroke we receive.
-    if (requestRetentionTimer != null) {
-      requestRetentionTimer.cancel();
-    }
-    requestRetentionTimer =
-        new Timer() {
-          @Override
-          public void run() {
-            Query q = new Query(req, cb);
-            if (query == null) {
-              query = q;
-              q.start();
-            } else {
-              query = q;
-            }
-          }
-        };
-    requestRetentionTimer.schedule(200);
-  }
-
-  @Override
-  public void requestDefaultSuggestions(Request req, Callback cb) {
-    requestSuggestions(req, cb);
-  }
-
-  @Override
-  public boolean isDisplayStringHTML() {
-    return oracle.isDisplayStringHTML();
-  }
-
-  public void cancelOutstandingRequest() {
-    if (requestRetentionTimer != null) {
-      requestRetentionTimer.cancel();
-    }
-    if (query != null) {
-      cancelOutstandingRequest = true;
-    }
-  }
-
-  public void setServeSuggestions(boolean serveSuggestions) {
-    this.serveSuggestions = serveSuggestions;
-  }
-
-  private class Query implements Callback {
-    final Request request;
-    final Callback callback;
-
-    Query(Request req, Callback cb) {
-      request = req;
-      callback = cb;
-    }
-
-    void start() {
-      oracle.requestSuggestions(request, this);
-    }
-
-    @Override
-    public void onSuggestionsReady(Request req, Response res) {
-      if (cancelOutstandingRequest || !serveSuggestions) {
-        // If cancelOutstandingRequest() was called, we ignore this response
-        cancelOutstandingRequest = false;
-        query = null;
-      } else if (query == this) {
-        // No new request was started while this query was running.
-        // Propose this request's response as the suggestions.
-        query = null;
-        last = request.getQuery();
-        callback.onSuggestionsReady(req, res);
-      } else {
-        // Another query came in while this one was running. Skip
-        // this response and start the most recent query.
-        query.start();
-      }
-    }
-  }
-}
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/arrow_undo.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/arrow_undo.png
deleted file mode 100644
index 6972c5e..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/arrow_undo.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cog.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cog.png
deleted file mode 100644
index 67de2c6..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cog.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/comment_draft.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/comment_draft.png
deleted file mode 100644
index 3408ddf..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/comment_draft.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cross.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cross.png
deleted file mode 100644
index 1514d51..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/cross.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/diffy26.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/diffy26.png
deleted file mode 100644
index 88b59d8..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/diffy26.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/disk.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/disk.png
deleted file mode 100644
index 99d532e..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/disk.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/exclamation.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/exclamation.png
deleted file mode 100644
index c37bd06..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/exclamation.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/find.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/find.png
deleted file mode 100644
index 1547479..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/find.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goDown.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goDown.png
deleted file mode 100644
index 5d87e45..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goDown.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goNext.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goNext.png
deleted file mode 100644
index 872c197..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goNext.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goPrev.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goPrev.png
deleted file mode 100644
index d68f29b..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goPrev.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goUp.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goUp.png
deleted file mode 100644
index f75bed4..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/goUp.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/help.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/help.png
deleted file mode 100644
index 5c87017..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/help.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lightbulb.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lightbulb.png
deleted file mode 100644
index d22fde8..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lightbulb.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/listAdd.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/listAdd.png
deleted file mode 100644
index 1aa7f09..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/listAdd.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lock.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lock.png
deleted file mode 100644
index 2ebc4f6..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/lock.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/merge.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/merge.png
deleted file mode 100644
index 9c892db..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/merge.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/note_add.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/note_add.png
deleted file mode 100644
index abdad91..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/note_add.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_edit.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_edit.png
deleted file mode 100644
index 046811e..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_edit.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_white_put.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_white_put.png
deleted file mode 100644
index 884ffd6..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/page_white_put.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_down_gray.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_down_gray.png
deleted file mode 100644
index 7bdd8ea..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_down_gray.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_next_gray.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_next_gray.png
deleted file mode 100644
index 3049ef4..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_next_gray.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_up_gray.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_up_gray.png
deleted file mode 100644
index 966a25e..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/resultset_up_gray.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/sideBySideDiff.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/sideBySideDiff.png
deleted file mode 100755
index ee70080..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/sideBySideDiff.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star-open.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star-open.png
deleted file mode 100644
index edd577c..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star-open.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star.png
deleted file mode 100644
index b88c857..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/star.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue.png
deleted file mode 100644
index 9757fc6..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue_add.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue_add.png
deleted file mode 100644
index f135248..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tag_blue_add.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tick.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tick.png
deleted file mode 100644
index a9925a0..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/tick.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/unifiedDiff.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/unifiedDiff.png
deleted file mode 100755
index ec5f97a..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/unifiedDiff.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_add.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_add.png
deleted file mode 100644
index deae99b..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_add.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_edit.png b/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_edit.png
deleted file mode 100644
index c1974cd..0000000
--- a/gerrit-gwtui-common/src/main/resources/com/google/gerrit/client/user_edit.png
+++ /dev/null
Binary files differ
diff --git a/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/RelativeDateFormatterTest.java b/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/RelativeDateFormatterTest.java
deleted file mode 100644
index 6915ba7..0000000
--- a/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/RelativeDateFormatterTest.java
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright (C) 2013 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.client;
-
-import static com.google.gerrit.client.RelativeDateFormatter.DAY_IN_MILLIS;
-import static com.google.gerrit.client.RelativeDateFormatter.HOUR_IN_MILLIS;
-import static com.google.gerrit.client.RelativeDateFormatter.MINUTE_IN_MILLIS;
-import static com.google.gerrit.client.RelativeDateFormatter.SECOND_IN_MILLIS;
-import static com.google.gerrit.client.RelativeDateFormatter.YEAR_IN_MILLIS;
-import static org.junit.Assert.assertEquals;
-
-import java.util.Date;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class RelativeDateFormatterTest {
-
-  @BeforeClass
-  public static void setConstants() {
-    Constants c = new Constants();
-    RelativeDateFormatter.setConstants(c, c);
-  }
-
-  @AfterClass
-  public static void unsetConstants() {
-    RelativeDateFormatter.setConstants(null, null);
-  }
-
-  private static void assertFormat(long ageFromNow, long timeUnit, String expectedFormat) {
-    Date d = new Date(System.currentTimeMillis() - ageFromNow * timeUnit);
-    String s = RelativeDateFormatter.format(d);
-    assertEquals(expectedFormat, s);
-  }
-
-  @Test
-  public void future() {
-    assertFormat(-100, YEAR_IN_MILLIS, "in the future");
-    assertFormat(-1, SECOND_IN_MILLIS, "in the future");
-  }
-
-  @Test
-  public void formatSeconds() {
-    assertFormat(1, SECOND_IN_MILLIS, "1 second ago");
-    assertFormat(89, SECOND_IN_MILLIS, "89 seconds ago");
-  }
-
-  @Test
-  public void formatMinutes() {
-    assertFormat(90, SECOND_IN_MILLIS, "2 minutes ago");
-    assertFormat(3, MINUTE_IN_MILLIS, "3 minutes ago");
-    assertFormat(60, MINUTE_IN_MILLIS, "60 minutes ago");
-    assertFormat(89, MINUTE_IN_MILLIS, "89 minutes ago");
-  }
-
-  @Test
-  public void formatHours() {
-    assertFormat(90, MINUTE_IN_MILLIS, "2 hours ago");
-    assertFormat(149, MINUTE_IN_MILLIS, "2 hours ago");
-    assertFormat(35, HOUR_IN_MILLIS, "35 hours ago");
-  }
-
-  @Test
-  public void formatDays() {
-    assertFormat(36, HOUR_IN_MILLIS, "2 days ago");
-    assertFormat(13, DAY_IN_MILLIS, "13 days ago");
-  }
-
-  @Test
-  public void formatWeeks() {
-    assertFormat(14, DAY_IN_MILLIS, "2 weeks ago");
-    assertFormat(69, DAY_IN_MILLIS, "10 weeks ago");
-  }
-
-  @Test
-  public void formatMonths() {
-    assertFormat(70, DAY_IN_MILLIS, "2 months ago");
-    assertFormat(75, DAY_IN_MILLIS, "3 months ago");
-    assertFormat(364, DAY_IN_MILLIS, "12 months ago");
-  }
-
-  @Test
-  public void formatYearsMonths() {
-    assertFormat(366, DAY_IN_MILLIS, "1 year ago");
-    assertFormat(380, DAY_IN_MILLIS, "1 year, 1 month ago");
-    assertFormat(410, DAY_IN_MILLIS, "1 year, 2 months ago");
-    assertFormat(2, YEAR_IN_MILLIS, "2 years ago");
-    assertFormat(1824, DAY_IN_MILLIS, "5 years ago");
-    assertFormat(2 * 365 - 10, DAY_IN_MILLIS, "2 years ago");
-  }
-
-  @Test
-  public void formatYears() {
-    assertFormat(5, YEAR_IN_MILLIS, "5 years ago");
-    assertFormat(60, YEAR_IN_MILLIS, "60 years ago");
-  }
-
-  private static class Constants implements CommonConstants, CommonMessages {
-    @Override
-    public String inTheFuture() {
-      return "in the future";
-    }
-
-    @Override
-    public String month() {
-      return "month";
-    }
-
-    @Override
-    public String months() {
-      return "months";
-    }
-
-    @Override
-    public String year() {
-      return "year";
-    }
-
-    @Override
-    public String years() {
-      return "years";
-    }
-
-    @Override
-    public String oneSecondAgo() {
-      return "1 second ago";
-    }
-
-    @Override
-    public String oneMinuteAgo() {
-      return "1 minute ago";
-    }
-
-    @Override
-    public String oneHourAgo() {
-      return "1 hour ago";
-    }
-
-    @Override
-    public String oneDayAgo() {
-      return "1 day ago";
-    }
-
-    @Override
-    public String oneWeekAgo() {
-      return "1 week ago";
-    }
-
-    @Override
-    public String oneMonthAgo() {
-      return "1 month ago";
-    }
-
-    @Override
-    public String oneYearAgo() {
-      return "1 year ago";
-    }
-
-    @Override
-    public String secondsAgo(long seconds) {
-      return seconds + " seconds ago";
-    }
-
-    @Override
-    public String minutesAgo(long minutes) {
-      return minutes + " minutes ago";
-    }
-
-    @Override
-    public String hoursAgo(long hours) {
-      return hours + " hours ago";
-    }
-
-    @Override
-    public String daysAgo(long days) {
-      return days + " days ago";
-    }
-
-    @Override
-    public String weeksAgo(long weeks) {
-      return weeks + " weeks ago";
-    }
-
-    @Override
-    public String monthsAgo(long months) {
-      return months + " months ago";
-    }
-
-    @Override
-    public String yearsAgo(long years) {
-      return years + " years ago";
-    }
-
-    @Override
-    public String years0MonthsAgo(long years, String yearLabel) {
-      return years + " " + yearLabel + " ago";
-    }
-
-    @Override
-    public String yearsMonthsAgo(long years, String yearLabel, long months, String monthLabel) {
-      return years + " " + yearLabel + ", " + months + " " + monthLabel + " ago";
-    }
-  }
-}
diff --git a/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/ui/HighlightSuggestionTest.java b/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/ui/HighlightSuggestionTest.java
deleted file mode 100644
index 9bf2d95..0000000
--- a/gerrit-gwtui-common/src/test/java/com/google/gerrit/client/ui/HighlightSuggestionTest.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2015 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.client.ui;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class HighlightSuggestionTest {
-
-  @Test
-  public void singleHighlight() throws Exception {
-    String keyword = "key";
-    String value = "somethingkeysomething";
-    HighlightSuggestion suggestion = new HighlightSuggestion(keyword, value);
-    assertEquals("something<strong>key</strong>something", suggestion.getDisplayString());
-    assertEquals(value, suggestion.getReplacementString());
-  }
-
-  @Test
-  public void noHighlight() throws Exception {
-    String keyword = "key";
-    String value = "something";
-    HighlightSuggestion suggestion = new HighlightSuggestion(keyword, value);
-    assertEquals(value, suggestion.getDisplayString());
-    assertEquals(value, suggestion.getReplacementString());
-  }
-
-  @Test
-  public void doubleHighlight() throws Exception {
-    String keyword = "key";
-    String value = "somethingkeysomethingkeysomething";
-    HighlightSuggestion suggestion = new HighlightSuggestion(keyword, value);
-    assertEquals(
-        "something<strong>key</strong>something<strong>key</strong>something",
-        suggestion.getDisplayString());
-    assertEquals(value, suggestion.getReplacementString());
-  }
-}
diff --git a/gerrit-gwtui/BUILD b/gerrit-gwtui/BUILD
deleted file mode 100644
index 9deed9b..0000000
--- a/gerrit-gwtui/BUILD
+++ /dev/null
@@ -1,41 +0,0 @@
-load(
-    "//tools/bzl:gwt.bzl",
-    "gen_ui_module",
-    "gwt_genrule",
-    "gwt_user_agent_permutations",
-)
-load("//tools/bzl:junit.bzl", "junit_tests")
-load("//tools/bzl:license.bzl", "license_test")
-
-gwt_genrule()
-
-gwt_genrule(suffix = "_r")
-
-gen_ui_module(name = "ui_module")
-
-gen_ui_module(
-    name = "ui_module",
-    suffix = "_r",
-)
-
-gwt_user_agent_permutations()
-
-license_test(
-    name = "ui_module_license_test",
-    target = ":ui_module",
-)
-
-junit_tests(
-    name = "ui_tests",
-    srcs = glob(["src/test/java/**/*.java"]),
-    visibility = ["//visibility:public"],
-    deps = [
-        ":ui_module",
-        "//java/com/google/gerrit/common:client",
-        "//java/com/google/gerrit/extensions:client",
-        "//lib:junit",
-        "//lib/gwt:dev",
-        "//lib/gwt:user",
-        "//lib/truth",
-    ],
-)
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml
deleted file mode 100644
index 9ac919b..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<!--
- Copyright (C) 2008 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.
--->
-<module rename-to="gerrit_ui">
-  <inherits name='com.google.gwt.editor.Editor'/>
-  <inherits name='com.google.gwt.user.User'/>
-  <inherits name='com.google.gwt.resources.Resources'/>
-  <inherits name='com.google.gwt.user.theme.chrome.Chrome'/>
-  <inherits name='com.google.gwtexpui.css.CSS'/>
-  <inherits name='com.google.gerrit.GerritGwtUICommon'/>
-  <inherits name='com.google.gerrit.UserAgent'/>
-  <inherits name='net.codemirror.CodeMirror'/>
-
-  <extend-property name='locale' values='en'/>
-  <set-property-fallback name='locale' value='en'/>
-  <set-property name='locale' value='en'/>
-  <set-configuration-property name='UiBinder.useSafeHtmlTemplates' value='true'/>
-  <set-configuration-property name='CssResource.style' value='stable'/>
-  <add-linker name='xsiframe'/>
-
-  <set-property name='gwt.logging.logLevel' value='SEVERE'/>
-
-  <!-- Disable GSS -->
-  <set-configuration-property name='CssResource.enableGss' value='false'/>
-
-  <entry-point class='com.google.gerrit.client.Gerrit'/>
-</module>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/UserAgent.gwt.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/UserAgent.gwt.xml
deleted file mode 100644
index 9644093..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/UserAgent.gwt.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- Copyright (C) 2009 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.
--->
-<module>
-  <replace-with class="com.google.gerrit.client.api.PluginName.PluginNameMoz">
-    <when-type-is class="com.google.gerrit.client.api.PluginName" />
-    <when-property-is name="compiler.stackMode" value="native" />
-    <when-property-is name="user.agent" value="safari" />
-    <when-property-is name="user.agent" value="gecko1_8" />
-  </replace-with>
-
-  <replace-with class="com.google.gerrit.client.ui.FancyFlexTableImplIE8">
-    <when-type-is class="com.google.gerrit.client.ui.FancyFlexTableImpl" />
-    <any>
-      <when-property-is name="user.agent" value="ie8"/>
-    </any>
-  </replace-with>
-
-  <replace-with class="com.google.gerrit.client.Themer.ThemerIE">
-    <when-type-is class="com.google.gerrit.client.Themer" />
-    <any>
-      <when-property-is name="user.agent" value="ie8"/>
-      <when-property-is name="user.agent" value="ie9"/>
-      <when-property-is name="user.agent" value="ie10"/>
-      <when-property-is name="user.agent" value="ie11"/>
-      <when-property-is name="user.agent" value="edge"/>
-    </any>
-  </replace-with>
-</module>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java
deleted file mode 100644
index 107d663..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/AvatarImage.java
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright (C) 2013 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.client;
-
-import com.google.gerrit.client.changes.Util;
-import com.google.gerrit.client.info.AccountInfo;
-import com.google.gerrit.client.info.AccountInfo.AvatarInfo;
-import com.google.gerrit.client.rpc.RestApi;
-import com.google.gwt.event.dom.client.LoadEvent;
-import com.google.gwt.event.dom.client.LoadHandler;
-import com.google.gwt.event.dom.client.MouseOutEvent;
-import com.google.gwt.event.dom.client.MouseOutHandler;
-import com.google.gwt.event.dom.client.MouseOverEvent;
-import com.google.gwt.event.dom.client.MouseOverHandler;
-import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.UIObject;
-
-public class AvatarImage extends Image implements LoadHandler {
-  public AvatarImage() {
-    setVisible(false);
-    addLoadHandler(this);
-  }
-
-  /** A default sized avatar image. */
-  public AvatarImage(AccountInfo account) {
-    this(account, AccountInfo.AvatarInfo.DEFAULT_SIZE, true);
-  }
-
-  /**
-   * An avatar image for the given account using the requested size.
-   *
-   * @param account The account in which we are interested
-   * @param size A requested size. Note that the size can be ignored depending on the avatar
-   *     provider. A size <= 0 indicates to let the provider decide a default size.
-   * @param addPopup show avatar popup with user info on hovering over the avatar image
-   */
-  public AvatarImage(AccountInfo account, int size, boolean addPopup) {
-    addLoadHandler(this);
-    setAccount(account, size, addPopup);
-  }
-
-  public void setAccount(AccountInfo account, int size, boolean addPopup) {
-    if (account == null) {
-      setVisible(false);
-    } else if (isGerritServer(account)) {
-      setVisible(true);
-      setResource(Gerrit.RESOURCES.gerritAvatar26());
-    } else if (account.hasAvatarInfo()) {
-      setVisible(false);
-      AvatarInfo info = account.avatar(size);
-      if (info != null) {
-        setWidth(info.width() > 0 ? info.width() + "px" : "");
-        setHeight(info.height() > 0 ? info.height() + "px" : "");
-        setUrl(info.url());
-        popup(account, addPopup);
-      } else if (account.email() != null) {
-        loadAvatar(account, size, addPopup);
-      }
-    } else if (account.email() != null) {
-      loadAvatar(account, size, addPopup);
-    } else {
-      setVisible(false);
-    }
-  }
-
-  private void loadAvatar(AccountInfo account, int size, boolean addPopup) {
-    if (!Gerrit.info().plugin().hasAvatars()) {
-      setVisible(false);
-      return;
-    }
-
-    // TODO Kill /accounts/*/avatar URL.
-    String u = account.email();
-    if (Gerrit.isSignedIn() && u.equals(Gerrit.getUserAccount().email())) {
-      u = "self";
-    }
-    RestApi api = new RestApi("/accounts/").id(u).view("avatar");
-    if (size > 0) {
-      api.addParameter("s", size);
-      setSize("", size + "px");
-    }
-    setVisible(false);
-    setUrl(api.url());
-    popup(account, addPopup);
-  }
-
-  private void popup(AccountInfo account, boolean addPopup) {
-    if (addPopup) {
-      PopupHandler popupHandler = new PopupHandler(account, this);
-      addMouseOverHandler(popupHandler);
-      addMouseOutHandler(popupHandler);
-    }
-  }
-
-  @Override
-  public void onLoad(LoadEvent event) {
-    setVisible(true);
-  }
-
-  private static boolean isGerritServer(AccountInfo account) {
-    return account._accountId() == 0 && Util.C.messageNoAuthor().equals(account.name());
-  }
-
-  private static class PopupHandler implements MouseOverHandler, MouseOutHandler {
-    private final AccountInfo account;
-    private final UIObject target;
-
-    private UserPopupPanel popup;
-    private Timer showTimer;
-    private Timer hideTimer;
-
-    PopupHandler(AccountInfo account, UIObject target) {
-      this.account = account;
-      this.target = target;
-    }
-
-    private UserPopupPanel createPopupPanel(AccountInfo account) {
-      UserPopupPanel popup = new UserPopupPanel(account, false, false);
-      popup.addDomHandler(
-          new MouseOverHandler() {
-            @Override
-            public void onMouseOver(MouseOverEvent event) {
-              scheduleShow();
-            }
-          },
-          MouseOverEvent.getType());
-      popup.addDomHandler(
-          new MouseOutHandler() {
-            @Override
-            public void onMouseOut(MouseOutEvent event) {
-              scheduleHide();
-            }
-          },
-          MouseOutEvent.getType());
-      return popup;
-    }
-
-    @Override
-    public void onMouseOver(MouseOverEvent event) {
-      scheduleShow();
-    }
-
-    @Override
-    public void onMouseOut(MouseOutEvent event) {
-      scheduleHide();
-    }
-
-    private void scheduleShow() {
-      if (hideTimer != null) {
-        hideTimer.cancel();
-        hideTimer = null;
-      }
-      if ((popup != null && popup.isShowing() && popup.isVisible()) || showTimer != null) {
-        return;
-      }
-      showTimer =
-          new Timer() {
-            @Override
-            public void run() {
-              if (popup == null) {
-                popup = createPopupPanel(account);
-              }
-              if (!popup.isShowing() || !popup.isVisible()) {
-                popup.showRelativeTo(target);
-              }
-            }
-          };
-      showTimer.schedule(600);
-    }
-
-    private void scheduleHide() {
-      if (showTimer != null) {
-        showTimer.cancel();
-        showTimer = null;
-      }
-      if (popup == null || !popup.isShowing() || !popup.isVisible() || hideTimer != null) {
-        return;
-      }
-      hideTimer =
-          new Timer() {
-            @Override
-            public void run() {
-              popup.hide();
-            }
-          };
-      hideTimer.schedule(50);
-    }
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationCallback.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationCallback.java
deleted file mode 100644
index cc30873..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationCallback.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (C) 2010 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.client;
-
-/**
- * Interface that a caller must implement to react on the result of a {@link ConfirmationDialog}.
- */
-public abstract class ConfirmationCallback {
-
-  /**
-   * Called when the {@link ConfirmationDialog} is finished with OK. To be overwritten by
-   * subclasses.
-   */
-  public abstract void onOk();
-
-  /**
-   * Called when the {@link ConfirmationDialog} is finished with Cancel. To be overwritten by
-   * subclasses.
-   */
-  public void onCancel() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java
deleted file mode 100644
index 438df34..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright (C) 2010 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.client;
-
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Widget;
-import com.google.gwtexpui.globalkey.client.GlobalKey;
-import com.google.gwtexpui.safehtml.client.SafeHtml;
-import com.google.gwtexpui.user.client.AutoCenterDialogBox;
-
-public class ConfirmationDialog extends AutoCenterDialogBox {
-
-  private Button cancelButton;
-  private Button okButton;
-
-  public ConfirmationDialog(
-      final String dialogTitle, SafeHtml message, ConfirmationCallback callback) {
-    super(/* auto hide */ false, /* modal */ true);
-    setGlassEnabled(true);
-    setText(dialogTitle);
-
-    final FlowPanel buttons = new FlowPanel();
-
-    okButton = new Button();
-    okButton.setText(Gerrit.C.confirmationDialogOk());
-    okButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            hide();
-            callback.onOk();
-          }
-        });
-    buttons.add(okButton);
-
-    cancelButton = new Button();
-    cancelButton.getElement().getStyle().setProperty("marginLeft", "300px");
-    cancelButton.setText(Gerrit.C.confirmationDialogCancel());
-    cancelButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            hide();
-            callback.onCancel();
-          }
-        });
-    buttons.add(cancelButton);
-
-    final FlowPanel center = new FlowPanel();
-    final Widget msgWidget = message.toBlockWidget();
-    center.add(msgWidget);
-    center.add(buttons);
-    add(center);
-
-    msgWidget.setWidth("400px");
-
-    setWidget(center);
-  }
-
-  @Override
-  public void center() {
-    super.center();
-    GlobalKey.dialog(this);
-    cancelButton.setFocus(true);
-  }
-
-  public void setCancelVisible(boolean visible) {
-    cancelButton.setVisible(visible);
-    if (!visible) {
-      okButton.setFocus(true);
-    }
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffObject.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffObject.java
deleted file mode 100644
index 21ced4c..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffObject.java
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright (C) 2016 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.client;
-
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DefaultBase;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.PatchSet;
-
-/**
- * Represent an object that can be diffed. This can be either a regular patch set, the base of a
- * patch set, the parent of a merge, the auto-merge of a merge or an edit patch set.
- */
-public class DiffObject {
-  public static final String AUTO_MERGE = "AutoMerge";
-
-  /**
-   * Parses a string that represents a diff object.
-   *
-   * <p>The following string representations are supported:
-   *
-   * <ul>
-   *   <li>a positive integer: represents a patch set
-   *   <li>a negative integer: represents a parent of a merge patch set
-   *   <li>'0': represents the edit patch set
-   *   <li>empty string or null: represents the parent of a 1-parent patch set, also called base
-   *   <li>'AutoMerge': represents the auto-merge of a merge patch set
-   * </ul>
-   *
-   * @param changeId the ID of the change to which the diff object belongs
-   * @param str the string representation of the diff object
-   * @return the parsed diff object, {@code null} if str cannot be parsed as diff object
-   */
-  public static DiffObject parse(Change.Id changeId, String str) {
-    if (str == null || str.isEmpty()) {
-      return new DiffObject(false);
-    }
-
-    if (AUTO_MERGE.equals(str)) {
-      return new DiffObject(true);
-    }
-
-    return new DiffObject(Dispatcher.toPsId(changeId, str));
-  }
-
-  /** Create a DiffObject that represents the parent of a 1-parent patch set. */
-  public static DiffObject base() {
-    return new DiffObject(false);
-  }
-
-  /** Create a DiffObject that represents the auto-merge for a merge patch set. */
-  public static DiffObject autoMerge() {
-    return new DiffObject(true);
-  }
-
-  /** Create a DiffObject that represents a patch set. */
-  public static DiffObject patchSet(PatchSet.Id psId) {
-    return new DiffObject(psId);
-  }
-
-  private final PatchSet.Id psId;
-  private final boolean autoMerge;
-
-  private DiffObject(PatchSet.Id psId) {
-    this.psId = psId;
-    this.autoMerge = false;
-  }
-
-  private DiffObject(boolean autoMerge) {
-    this.psId = null;
-    this.autoMerge = autoMerge;
-  }
-
-  public boolean isBase() {
-    return psId == null && !autoMerge;
-  }
-
-  public boolean isAutoMerge() {
-    return psId == null && autoMerge;
-  }
-
-  public boolean isBaseOrAutoMerge() {
-    return psId == null;
-  }
-
-  public boolean isPatchSet() {
-    return psId != null && psId.get() > 0;
-  }
-
-  public boolean isParent() {
-    return psId != null && psId.get() < 0;
-  }
-
-  public boolean isEdit() {
-    return psId != null && psId.get() == 0;
-  }
-
-  /**
-   * Returns the DiffObject as PatchSet.Id.
-   *
-   * @return PatchSet.Id with an id > 0 for a regular patch set; PatchSet.Id with an id < 0 for a
-   *     parent of a merge; PatchSet.Id with id == 0 for an edit patch set; {@code null} for the
-   *     base of a 1-parent patch set and for the auto-merge of a merge patch set
-   */
-  public PatchSet.Id asPatchSetId() {
-    return psId;
-  }
-
-  /**
-   * Returns the parent number for a parent of a merge.
-   *
-   * @return 1-based parent number, 0 if this DiffObject is not a parent of a merge
-   */
-  public int getParentNum() {
-    if (!isParent()) {
-      return 0;
-    }
-
-    return -psId.get();
-  }
-
-  /**
-   * Returns a string representation of this DiffObject that can be used in URLs.
-   *
-   * <p>The following string representations are returned:
-   *
-   * <ul>
-   *   <li>a positive integer for a patch set
-   *   <li>a negative integer for a parent of a merge patch set
-   *   <li>'0' for the edit patch set
-   *   <li>{@code null} for the parent of a 1-parent patch set, also called base
-   *   <li>'AutoMerge' for the auto-merge of a merge patch set
-   * </ul>
-   *
-   * @return string representation of this DiffObject
-   */
-  public String asString() {
-    if (autoMerge) {
-      if (Gerrit.getUserPreferences().defaultBaseForMerges() != DefaultBase.AUTO_MERGE) {
-        return AUTO_MERGE;
-      }
-      return null;
-    }
-
-    if (psId != null) {
-      return psId.getId();
-    }
-
-    return null;
-  }
-
-  @Override
-  public String toString() {
-    if (isPatchSet()) {
-      return "Patch Set " + psId.getId();
-    }
-
-    if (isParent()) {
-      return "Parent " + psId.getId();
-    }
-
-    if (isEdit()) {
-      return "Edit Patch Set";
-    }
-
-    if (isAutoMerge()) {
-      return "Auto Merge";
-    }
-
-    return "Base";
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffWebLinkInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffWebLinkInfo.java
deleted file mode 100644
index fe7016f..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/DiffWebLinkInfo.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2014 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.client;
-
-import com.google.gerrit.client.info.WebLinkInfo;
-
-public class DiffWebLinkInfo extends WebLinkInfo {
-  public final native boolean showOnSideBySideDiffView()
-      /*-{ return this.show_on_side_by_side_diff_view || false; }-*/ ;
-
-  public final native boolean showOnUnifiedDiffView()
-      /*-{ return this.show_on_unified_diff_view || false; }-*/ ;
-
-  protected DiffWebLinkInfo() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
deleted file mode 100644
index 4b84864..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ /dev/null
@@ -1,879 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_GROUP;
-import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
-import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
-import static com.google.gerrit.common.PageLinks.ADMIN_PLUGINS;
-import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
-import static com.google.gerrit.common.PageLinks.DASHBOARDS;
-import static com.google.gerrit.common.PageLinks.MINE;
-import static com.google.gerrit.common.PageLinks.MY_GROUPS;
-import static com.google.gerrit.common.PageLinks.PROJECTS;
-import static com.google.gerrit.common.PageLinks.QUERY;
-import static com.google.gerrit.common.PageLinks.REGISTER;
-import static com.google.gerrit.common.PageLinks.SETTINGS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_AGREEMENTS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_CONTACT;
-import static com.google.gerrit.common.PageLinks.SETTINGS_DIFF_PREFERENCES;
-import static com.google.gerrit.common.PageLinks.SETTINGS_EDIT_PREFERENCES;
-import static com.google.gerrit.common.PageLinks.SETTINGS_EXTENSION;
-import static com.google.gerrit.common.PageLinks.SETTINGS_GPGKEYS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_HTTP_PASSWORD;
-import static com.google.gerrit.common.PageLinks.SETTINGS_MYGROUPS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_NEW_AGREEMENT;
-import static com.google.gerrit.common.PageLinks.SETTINGS_OAUTH_TOKEN;
-import static com.google.gerrit.common.PageLinks.SETTINGS_PREFERENCES;
-import static com.google.gerrit.common.PageLinks.SETTINGS_PROJECTS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_SSHKEYS;
-import static com.google.gerrit.common.PageLinks.SETTINGS_WEBIDENT;
-
-import com.google.gerrit.client.account.MyAgreementsScreen;
-import com.google.gerrit.client.account.MyContactInformationScreen;
-import com.google.gerrit.client.account.MyDiffPreferencesScreen;
-import com.google.gerrit.client.account.MyEditPreferencesScreen;
-import com.google.gerrit.client.account.MyGpgKeysScreen;
-import com.google.gerrit.client.account.MyGroupsScreen;
-import com.google.gerrit.client.account.MyIdentitiesScreen;
-import com.google.gerrit.client.account.MyOAuthTokenScreen;
-import com.google.gerrit.client.account.MyPasswordScreen;
-import com.google.gerrit.client.account.MyPreferencesScreen;
-import com.google.gerrit.client.account.MyProfileScreen;
-import com.google.gerrit.client.account.MySshKeysScreen;
-import com.google.gerrit.client.account.MyWatchedProjectsScreen;
-import com.google.gerrit.client.account.NewAgreementScreen;
-import com.google.gerrit.client.account.RegisterScreen;
-import com.google.gerrit.client.account.ValidateEmailScreen;
-import com.google.gerrit.client.admin.AccountGroupAuditLogScreen;
-import com.google.gerrit.client.admin.AccountGroupInfoScreen;
-import com.google.gerrit.client.admin.AccountGroupMembersScreen;
-import com.google.gerrit.client.admin.AccountGroupScreen;
-import com.google.gerrit.client.admin.CreateGroupScreen;
-import com.google.gerrit.client.admin.CreateProjectScreen;
-import com.google.gerrit.client.admin.GroupListScreen;
-import com.google.gerrit.client.admin.PluginListScreen;
-import com.google.gerrit.client.admin.ProjectAccessScreen;
-import com.google.gerrit.client.admin.ProjectBranchesScreen;
-import com.google.gerrit.client.admin.ProjectDashboardsScreen;
-import com.google.gerrit.client.admin.ProjectInfoScreen;
-import com.google.gerrit.client.admin.ProjectListScreen;
-import com.google.gerrit.client.admin.ProjectScreen;
-import com.google.gerrit.client.admin.ProjectTagsScreen;
-import com.google.gerrit.client.api.ExtensionScreen;
-import com.google.gerrit.client.api.ExtensionSettingsScreen;
-import com.google.gerrit.client.change.ChangeScreen;
-import com.google.gerrit.client.change.FileTable;
-import com.google.gerrit.client.change.ProjectChangeId;
-import com.google.gerrit.client.changes.AccountDashboardScreen;
-import com.google.gerrit.client.changes.CustomDashboardScreen;
-import com.google.gerrit.client.changes.ProjectDashboardScreen;
-import com.google.gerrit.client.changes.QueryScreen;
-import com.google.gerrit.client.dashboards.DashboardInfo;
-import com.google.gerrit.client.dashboards.DashboardList;
-import com.google.gerrit.client.diff.DisplaySide;
-import com.google.gerrit.client.diff.SideBySide;
-import com.google.gerrit.client.diff.Unified;
-import com.google.gerrit.client.documentation.DocScreen;
-import com.google.gerrit.client.editor.EditScreen;
-import com.google.gerrit.client.groups.GroupApi;
-import com.google.gerrit.client.info.GroupInfo;
-import com.google.gerrit.client.rpc.GerritCallback;
-import com.google.gerrit.client.rpc.RestApi;
-import com.google.gerrit.client.ui.Screen;
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.common.PageLinks;
-import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.core.client.RunAsyncCallback;
-import com.google.gwt.http.client.URL;
-import com.google.gwtexpui.user.client.UserAgent;
-import com.google.gwtorm.client.KeyUtil;
-
-public class Dispatcher {
-  public static String toPatch(
-      @Nullable Project.NameKey project,
-      DiffObject diffBase,
-      PatchSet.Id revision,
-      String fileName) {
-    return toPatch("", project, diffBase, revision, fileName, null, 0);
-  }
-
-  public static String toPatch(
-      @Nullable Project.NameKey project,
-      DiffObject diffBase,
-      PatchSet.Id revision,
-      String fileName,
-      DisplaySide side,
-      int line) {
-    return toPatch("", project, diffBase, revision, fileName, side, line);
-  }
-
-  public static String toSideBySide(
-      @Nullable Project.NameKey project,
-      DiffObject diffBase,
-      PatchSet.Id revision,
-      String fileName) {
-    return toPatch("sidebyside", project, diffBase, revision, fileName, null, 0);
-  }
-
-  public static String toUnified(
-      @Nullable Project.NameKey project,
-      DiffObject diffBase,
-      PatchSet.Id revision,
-      String fileName) {
-    return toPatch("unified", project, diffBase, revision, fileName, null, 0);
-  }
-
-  public static String toPatch(
-      @Nullable Project.NameKey project, String type, DiffObject diffBase, Patch.Key id) {
-    return toPatch(type, project, diffBase, id.getParentKey(), id.get(), null, 0);
-  }
-
-  public static String toEditScreen(
-      @Nullable Project.NameKey project, PatchSet.Id revision, String fileName) {
-    return toEditScreen(project, revision, fileName, 0);
-  }
-
-  public static String toEditScreen(
-      @Nullable Project.NameKey project, PatchSet.Id revision, String fileName, int line) {
-    return toPatch("edit", project, DiffObject.base(), revision, fileName, null, line);
-  }
-
-  private static String toPatch(
-      String type,
-      @Nullable Project.NameKey project,
-      DiffObject diffBase,
-      PatchSet.Id revision,
-      String fileName,
-      DisplaySide side,
-      int line) {
-    Change.Id c = revision.getParentKey();
-    StringBuilder p = new StringBuilder(PageLinks.toChange(project, c));
-    if (diffBase != null && diffBase.asString() != null) {
-      p.append(diffBase.asString()).append("..");
-    }
-    p.append(revision.getId()).append("/").append(KeyUtil.encode(fileName));
-    if (type != null && !type.isEmpty() && (!"sidebyside".equals(type) || preferUnified())) {
-      p.append(",").append(type);
-    }
-    if (side == DisplaySide.A && line > 0) {
-      p.append("@a").append(line);
-    } else if (line > 0) {
-      p.append("@").append(line);
-    }
-    return p.toString();
-  }
-
-  public static String toGroup(AccountGroup.Id id) {
-    return ADMIN_GROUPS + id.toString();
-  }
-
-  public static String toGroup(AccountGroup.Id id, String panel) {
-    return ADMIN_GROUPS + id.toString() + "," + panel;
-  }
-
-  public static String toGroup(AccountGroup.UUID uuid) {
-    return PageLinks.toGroup(uuid);
-  }
-
-  public static String toGroup(AccountGroup.UUID uuid, String panel) {
-    return toGroup(uuid) + "," + panel;
-  }
-
-  public static String toProject(Project.NameKey n) {
-    return toProjectAdmin(n, ProjectScreen.getSavedPanel());
-  }
-
-  public static String toProjectAdmin(Project.NameKey n, String panel) {
-    if (panel == null || ProjectScreen.INFO.equals(panel)) {
-      return ADMIN_PROJECTS + n.toString();
-    }
-    return ADMIN_PROJECTS + n.toString() + "," + panel;
-  }
-
-  static final String RELOAD_UI = "/reload-ui/";
-  private static boolean wasStartedByReloadUI;
-
-  void display(String token) {
-    assert token != null;
-    try {
-      try {
-        if (matchPrefix(RELOAD_UI, token)) {
-          wasStartedByReloadUI = true;
-          token = skip(token);
-        }
-        select(token);
-      } finally {
-        wasStartedByReloadUI = false;
-      }
-    } catch (RuntimeException err) {
-      GWT.log("Error parsing history token: " + token, err);
-      Gerrit.display(token, new NotFoundScreen());
-    }
-  }
-
-  private static void select(String token) {
-    token = Gerrit.getUrlAliasMatcher().replace(token);
-
-    if (matchPrefix(QUERY, token)) {
-      query(token);
-
-    } else if (matchPrefix("/Documentation/q/", token)) {
-      docSearch(token);
-
-    } else if (matchPrefix("/c/", token)) {
-      change(token);
-
-    } else if (matchPrefix("/x/", token)) {
-      extension(token);
-
-    } else if (matchExact(MINE, token)) {
-      String defaultScreenToken = Gerrit.getDefaultScreenToken();
-      if (defaultScreenToken != null && !MINE.equals(defaultScreenToken)) {
-        select(defaultScreenToken);
-      } else {
-        Gerrit.display(token, mine());
-      }
-
-    } else if (matchPrefix("/dashboard/", token)) {
-      dashboard(token);
-
-    } else if (matchPrefix(PROJECTS, token)) {
-      projects(token);
-
-    } else if (matchExact(SETTINGS, token)
-        || matchPrefix("/settings/", token)
-        || matchExact(MY_GROUPS, token)
-        || matchExact("register", token)
-        || matchExact(REGISTER, token)
-        || matchPrefix("/register/", token)
-        || matchPrefix("/VE/", token)
-        || matchPrefix("VE,", token)
-        || matchPrefix("/SignInFailure,", token)) {
-      settings(token);
-
-    } else if (matchPrefix("/admin/", token)) {
-      admin(token);
-
-    } else {
-      Gerrit.display(token, new NotFoundScreen());
-    }
-  }
-
-  private static void query(String token) {
-    String s = skip(token);
-    int c = s.indexOf(',');
-    Screen screen;
-    if (c >= 0) {
-      String prefix = s.substring(0, c);
-      if (s.substring(c).equals(",n,z")) {
-        // Respect legacy token with max sortkey.
-        screen = new QueryScreen(prefix, 0);
-      } else {
-        screen = new QueryScreen(prefix, Integer.parseInt(s.substring(c + 1)));
-      }
-    } else {
-      screen = new QueryScreen(s, 0);
-    }
-    Gerrit.display(token, screen);
-  }
-
-  private static Screen mine() {
-    if (Gerrit.isSignedIn()) {
-      return new AccountDashboardScreen(Gerrit.getUserAccount()._accountId());
-    }
-    Screen r = new AccountDashboardScreen(null);
-    r.setRequiresSignIn(true);
-    return r;
-  }
-
-  private static void dashboard(String token) {
-    String rest = skip(token);
-    if (rest.matches("[0-9]+")) {
-      int accountId = Integer.parseInt(rest);
-      Gerrit.display(token, new AccountDashboardScreen(accountId));
-      return;
-    }
-
-    if (rest.equals("self")) {
-      if (Gerrit.isSignedIn()) {
-        Gerrit.display(token, new AccountDashboardScreen(Gerrit.getUserAccount()._accountId()));
-      } else {
-        Screen s = new AccountDashboardScreen(null);
-        s.setRequiresSignIn(true);
-        Gerrit.display(token, s);
-      }
-      return;
-    }
-
-    if (rest.startsWith("?")) {
-      Gerrit.display(token, new CustomDashboardScreen(rest.substring(1)));
-      return;
-    }
-
-    Gerrit.display(token, new NotFoundScreen());
-  }
-
-  private static void projects(String token) {
-    String rest = skip(token);
-    int c = rest.indexOf(DASHBOARDS);
-    if (0 <= c) {
-      final String project = URL.decodePathSegment(rest.substring(0, c));
-      rest = rest.substring(c);
-      if (matchPrefix(DASHBOARDS, rest)) {
-        final String dashboardId = skip(rest);
-        GerritCallback<DashboardInfo> cb =
-            new GerritCallback<DashboardInfo>() {
-              @Override
-              public void onSuccess(DashboardInfo result) {
-                if (matchPrefix("/dashboard/", result.url())) {
-                  String params = skip(result.url()).substring(1);
-                  ProjectDashboardScreen dash =
-                      new ProjectDashboardScreen(new Project.NameKey(project), params);
-                  Gerrit.display(token, dash);
-                }
-              }
-
-              @Override
-              public void onFailure(Throwable caught) {
-                if ("default".equals(dashboardId) && RestApi.isNotFound(caught)) {
-                  Gerrit.display(
-                      PageLinks.toChangeQuery(
-                          PageLinks.projectQuery(new Project.NameKey(project))));
-                } else {
-                  super.onFailure(caught);
-                }
-              }
-            };
-        if ("default".equals(dashboardId)) {
-          DashboardList.getDefault(new Project.NameKey(project), cb);
-          return;
-        }
-        c = dashboardId.indexOf(":");
-        if (0 <= c) {
-          final String ref = URL.decodeQueryString(dashboardId.substring(0, c));
-          final String path = URL.decodeQueryString(dashboardId.substring(c + 1));
-          DashboardList.get(new Project.NameKey(project), ref + ":" + path, cb);
-          return;
-        }
-      }
-    }
-
-    Gerrit.display(token, new NotFoundScreen());
-  }
-
-  private static void change(String token) {
-    String rest = skip(token);
-    int c = rest.lastIndexOf(',');
-    String panel = null;
-    if (0 <= c) {
-      panel = rest.substring(c + 1);
-      rest = rest.substring(0, c);
-      int at = panel.lastIndexOf('@');
-      if (at > 0) {
-        rest += panel.substring(at);
-        panel = panel.substring(0, at);
-      }
-    }
-
-    ProjectChangeId id = ProjectChangeId.create(rest);
-    rest = rest.length() > id.identifierLength() ? rest.substring(id.identifierLength() + 1) : "";
-
-    if (rest.isEmpty()) {
-      FileTable.Mode mode = FileTable.Mode.REVIEW;
-      if (panel != null && (panel.equals("edit") || panel.startsWith("edit/"))) {
-        mode = FileTable.Mode.EDIT;
-        panel = null;
-      }
-      Gerrit.display(
-          token,
-          panel == null
-              ? new ChangeScreen(
-                  id.getProject(), id.getChangeId(), DiffObject.base(), null, false, mode)
-              : new NotFoundScreen());
-      return;
-    }
-
-    String psIdStr;
-    int s = rest.indexOf('/');
-    if (0 <= s) {
-      psIdStr = rest.substring(0, s);
-      rest = rest.substring(s + 1);
-    } else {
-      psIdStr = rest;
-      rest = "";
-    }
-
-    DiffObject base = DiffObject.base();
-    PatchSet.Id ps;
-    int dotdot = psIdStr.indexOf("..");
-    if (1 <= dotdot) {
-      base = DiffObject.parse(id.getChangeId(), psIdStr.substring(0, dotdot));
-      if (base == null) {
-        Gerrit.display(token, new NotFoundScreen());
-      }
-      psIdStr = psIdStr.substring(dotdot + 2);
-    }
-    ps = toPsId(id.getChangeId(), psIdStr);
-
-    if (!rest.isEmpty()) {
-      DisplaySide side = DisplaySide.B;
-      int line = 0;
-      int at = rest.lastIndexOf('@');
-      if (at > 0) {
-        String l = rest.substring(at + 1);
-        if (l.startsWith("a")) {
-          side = DisplaySide.A;
-          l = l.substring(1);
-        }
-        line = Integer.parseInt(l);
-        rest = rest.substring(0, at);
-      }
-      Patch.Key p = new Patch.Key(ps, KeyUtil.decode(rest));
-      patch(token, id.getProject(), base, p, side, line, panel);
-    } else {
-      if (panel == null) {
-        Gerrit.display(
-            token,
-            new ChangeScreen(
-                id.getProject(),
-                id.getChangeId(),
-                base,
-                String.valueOf(ps.get()),
-                false,
-                FileTable.Mode.REVIEW));
-      } else {
-        Gerrit.display(token, new NotFoundScreen());
-      }
-    }
-  }
-
-  public static PatchSet.Id toPsId(Change.Id id, String psIdStr) {
-    return new PatchSet.Id(id, psIdStr.equals("edit") ? 0 : Integer.parseInt(psIdStr));
-  }
-
-  private static void extension(String token) {
-    ExtensionScreen view = new ExtensionScreen(skip(token));
-    if (view.isFound()) {
-      Gerrit.display(token, view);
-    } else {
-      Gerrit.display(token, new NotFoundScreen());
-    }
-  }
-
-  private static void patch(
-      String token,
-      @Nullable Project.NameKey project,
-      DiffObject base,
-      Patch.Key id,
-      DisplaySide side,
-      int line,
-      String panelType) {
-    String panel = panelType;
-    if (panel == null) {
-      int c = token.lastIndexOf(',');
-      panel = 0 <= c ? token.substring(c + 1) : "";
-    }
-
-    if ("".equals(panel) || /* DEPRECATED URL */ "cm".equals(panel)) {
-      if (preferUnified()) {
-        unified(token, project, base, id, side, line);
-      } else {
-        codemirror(token, base, project, id, side, line);
-      }
-    } else if ("sidebyside".equals(panel)) {
-      codemirror(token, base, project, id, side, line);
-    } else if ("unified".equals(panel)) {
-      unified(token, project, base, id, side, line);
-    } else if ("edit".equals(panel)) {
-      if (!Patch.isMagic(id.get()) || Patch.COMMIT_MSG.equals(id.get())) {
-        codemirrorForEdit(token, project, id, line);
-      } else {
-        Gerrit.display(token, new NotFoundScreen());
-      }
-    } else {
-      Gerrit.display(token, new NotFoundScreen());
-    }
-  }
-
-  private static boolean preferUnified() {
-    return DiffView.UNIFIED_DIFF.equals(Gerrit.getUserPreferences().diffView())
-        || (UserAgent.isPortrait() && UserAgent.isMobile());
-  }
-
-  private static void unified(
-      final String token,
-      final Project.NameKey project,
-      final DiffObject base,
-      final Patch.Key id,
-      final DisplaySide side,
-      final int line) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            Gerrit.display(
-                token,
-                new Unified(
-                    project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
-          }
-        });
-  }
-
-  private static void codemirror(
-      final String token,
-      final DiffObject base,
-      @Nullable final Project.NameKey project,
-      final Patch.Key id,
-      final DisplaySide side,
-      final int line) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            Gerrit.display(
-                token,
-                new SideBySide(
-                    project, base, DiffObject.patchSet(id.getParentKey()), id.get(), side, line));
-          }
-        });
-  }
-
-  private static void codemirrorForEdit(
-      final String token,
-      @Nullable final Project.NameKey project,
-      final Patch.Key id,
-      final int line) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            Gerrit.display(token, new EditScreen(project, id, line));
-          }
-        });
-  }
-
-  private static void settings(String token) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            Gerrit.display(token, select());
-          }
-
-          private Screen select() {
-            if (matchExact(SETTINGS, token)) {
-              return new MyProfileScreen();
-            }
-
-            if (matchExact(SETTINGS_PREFERENCES, token)) {
-              return new MyPreferencesScreen();
-            }
-
-            if (matchExact(SETTINGS_DIFF_PREFERENCES, token)) {
-              return new MyDiffPreferencesScreen();
-            }
-
-            if (matchExact(SETTINGS_EDIT_PREFERENCES, token)) {
-              return new MyEditPreferencesScreen();
-            }
-
-            if (matchExact(SETTINGS_PROJECTS, token)) {
-              return new MyWatchedProjectsScreen();
-            }
-
-            if (matchExact(SETTINGS_CONTACT, token)) {
-              return new MyContactInformationScreen();
-            }
-
-            if (matchExact(SETTINGS_SSHKEYS, token)) {
-              return new MySshKeysScreen();
-            }
-
-            if (matchExact(SETTINGS_GPGKEYS, token) && Gerrit.info().gerrit().editGpgKeys()) {
-              return new MyGpgKeysScreen();
-            }
-
-            if (matchExact(SETTINGS_WEBIDENT, token)) {
-              return new MyIdentitiesScreen();
-            }
-
-            if (matchExact(SETTINGS_HTTP_PASSWORD, token)) {
-              return new MyPasswordScreen();
-            }
-
-            if (matchExact(SETTINGS_OAUTH_TOKEN, token) && Gerrit.info().auth().isOAuth()) {
-              return new MyOAuthTokenScreen();
-            }
-
-            if (matchExact(MY_GROUPS, token) || matchExact(SETTINGS_MYGROUPS, token)) {
-              return new MyGroupsScreen();
-            }
-
-            if (matchExact(SETTINGS_AGREEMENTS, token)
-                && Gerrit.info().auth().useContributorAgreements()) {
-              return new MyAgreementsScreen();
-            }
-
-            if (matchExact(REGISTER, token)
-                || matchExact("/register/", token)
-                || matchExact("register", token)) {
-              return new RegisterScreen(MINE);
-            } else if (matchPrefix("/register/", token)) {
-              return new RegisterScreen("/" + skip(token));
-            }
-
-            if (matchPrefix("/VE/", token) || matchPrefix("VE,", token)) {
-              return new ValidateEmailScreen(skip(token));
-            }
-
-            if (matchExact(SETTINGS_NEW_AGREEMENT, token)) {
-              return new NewAgreementScreen();
-            }
-
-            if (matchPrefix(SETTINGS_NEW_AGREEMENT + "/", token)) {
-              return new NewAgreementScreen(skip(token));
-            }
-
-            if (matchPrefix(SETTINGS_EXTENSION, token)) {
-              ExtensionSettingsScreen view = new ExtensionSettingsScreen(skip(token));
-              if (view.isFound()) {
-                return view;
-              }
-              return new NotFoundScreen();
-            }
-
-            return new NotFoundScreen();
-          }
-        });
-  }
-
-  private static void admin(String token) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            if (matchExact(ADMIN_GROUPS, token) || matchExact("/admin/groups", token)) {
-              Gerrit.display(token, new GroupListScreen());
-
-            } else if (matchPrefix(ADMIN_GROUPS, token)) {
-              String rest = skip(token);
-              if (rest.startsWith("?")) {
-                Gerrit.display(token, new GroupListScreen(rest.substring(1)));
-              } else {
-                group();
-              }
-
-            } else if (matchPrefix("/admin/groups", token)) {
-              String rest = skip(token);
-              if (rest.startsWith("?")) {
-                Gerrit.display(token, new GroupListScreen(rest.substring(1)));
-              }
-
-            } else if (matchExact(ADMIN_PROJECTS, token) || matchExact("/admin/projects", token)) {
-              Gerrit.display(token, new ProjectListScreen());
-
-            } else if (matchPrefix(ADMIN_PROJECTS, token)) {
-              String rest = skip(token);
-              if (rest.startsWith("?")) {
-                Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
-              } else {
-                Gerrit.display(token, selectProject());
-              }
-
-            } else if (matchPrefix("/admin/projects", token)) {
-              String rest = skip(token);
-              if (rest.startsWith("?")) {
-                Gerrit.display(token, new ProjectListScreen(rest.substring(1)));
-              }
-
-            } else if (matchPrefix(ADMIN_PLUGINS, token) || matchExact("/admin/plugins", token)) {
-              Gerrit.display(token, new PluginListScreen());
-
-            } else if (matchExact(ADMIN_CREATE_PROJECT, token)
-                || matchExact("/admin/create-project", token)) {
-              Gerrit.display(token, new CreateProjectScreen());
-
-            } else if (matchExact(ADMIN_CREATE_GROUP, token)
-                || matchExact("/admin/create-group", token)) {
-              Gerrit.display(token, new CreateGroupScreen());
-
-            } else {
-              Gerrit.display(token, new NotFoundScreen());
-            }
-          }
-
-          private void group() {
-            final String panel;
-            final String group;
-
-            if (matchPrefix("/admin/groups/uuid-", token)) {
-              String p = skip(token);
-              int c = p.indexOf(',');
-              if (c < 0) {
-                group = p;
-                panel = null;
-              } else {
-                group = p.substring(0, c);
-                panel = p.substring(c + 1);
-              }
-            } else if (matchPrefix(ADMIN_GROUPS, token)) {
-              String p = skip(token);
-              int c = p.indexOf(',');
-              if (c < 0) {
-                group = p;
-                panel = null;
-              } else {
-                group = p.substring(0, c);
-                panel = p.substring(c + 1);
-              }
-            } else {
-              Gerrit.display(token, new NotFoundScreen());
-              return;
-            }
-
-            GroupApi.getGroupDetail(
-                group,
-                new GerritCallback<GroupInfo>() {
-                  @Override
-                  public void onSuccess(GroupInfo group) {
-                    if (panel == null || panel.isEmpty()) {
-                      // The token does not say which group screen should be shown,
-                      // as default for internal groups show the members, as default
-                      // for external and system groups show the info screen (since
-                      // for external and system groups the members cannot be
-                      // shown in the web UI).
-                      //
-                      if (AccountGroup.isInternalGroup(group.getGroupUUID())) {
-                        String newToken = toGroup(group.getGroupId(), AccountGroupScreen.MEMBERS);
-                        Gerrit.display(newToken, new AccountGroupMembersScreen(group, newToken));
-                      } else {
-                        String newToken = toGroup(group.getGroupId(), AccountGroupScreen.INFO);
-                        Gerrit.display(newToken, new AccountGroupInfoScreen(group, newToken));
-                      }
-                    } else if (AccountGroupScreen.INFO.equals(panel)) {
-                      Gerrit.display(token, new AccountGroupInfoScreen(group, token));
-                    } else if (AccountGroupScreen.MEMBERS.equals(panel)) {
-                      Gerrit.display(token, new AccountGroupMembersScreen(group, token));
-                    } else if (AccountGroupScreen.AUDIT_LOG.equals(panel)) {
-                      Gerrit.display(token, new AccountGroupAuditLogScreen(group, token));
-                    } else {
-                      Gerrit.display(token, new NotFoundScreen());
-                    }
-                  }
-                });
-          }
-
-          private Screen selectProject() {
-            if (matchPrefix(ADMIN_PROJECTS, token)) {
-              String rest = skip(token);
-              int c = rest.lastIndexOf(',');
-              if (c < 0) {
-                return new ProjectInfoScreen(Project.NameKey.parse(rest));
-              } else if (c == 0) {
-                return new NotFoundScreen();
-              }
-
-              int q = rest.lastIndexOf('?');
-              if (q > 0 && rest.lastIndexOf(',', q) > 0) {
-                c = rest.substring(0, q - 1).lastIndexOf(',');
-              }
-
-              Project.NameKey k = Project.NameKey.parse(rest.substring(0, c));
-              String panel = rest.substring(c + 1);
-
-              if (ProjectScreen.INFO.equals(panel)) {
-                return new ProjectInfoScreen(k);
-              }
-
-              if (ProjectScreen.BRANCHES.equals(panel)
-                  || matchPrefix(ProjectScreen.BRANCHES, panel)) {
-                return new ProjectBranchesScreen(k);
-              }
-
-              if (ProjectScreen.TAGS.equals(panel) || matchPrefix(ProjectScreen.TAGS, panel)) {
-                return new ProjectTagsScreen(k);
-              }
-
-              if (ProjectScreen.ACCESS.equals(panel)) {
-                return new ProjectAccessScreen(k);
-              }
-
-              if (ProjectScreen.DASHBOARDS.equals(panel)) {
-                return new ProjectDashboardsScreen(k);
-              }
-            }
-            return new NotFoundScreen();
-          }
-        });
-  }
-
-  private static boolean matchExact(String want, String token) {
-    return token.equals(want);
-  }
-
-  private static int prefixlen;
-
-  private static boolean matchPrefix(String want, String token) {
-    if (token.startsWith(want)) {
-      prefixlen = want.length();
-      return true;
-    }
-    return false;
-  }
-
-  private static String skip(String token) {
-    return token.substring(prefixlen);
-  }
-
-  private abstract static class AsyncSplit implements RunAsyncCallback {
-    private final boolean isReloadUi;
-    protected final String token;
-
-    protected AsyncSplit(String token) {
-      this.isReloadUi = wasStartedByReloadUI;
-      this.token = token;
-    }
-
-    @Override
-    public final void onFailure(Throwable reason) {
-      if (!isReloadUi && "HTTP download failed with status 404".equals(reason.getMessage())) {
-        // The server was upgraded since we last download the main script,
-        // so the pointers to the splits aren't valid anymore.  Force the
-        // page to reload itself and pick up the new code.
-        //
-        Gerrit.upgradeUI(token);
-      } else {
-        new ErrorDialog(reason).center();
-      }
-    }
-  }
-
-  private static void docSearch(String token) {
-    GWT.runAsync(
-        new AsyncSplit(token) {
-          @Override
-          public void onSuccess() {
-            Gerrit.display(token, new DocScreen(skip(token)));
-          }
-        });
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ErrorDialog.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ErrorDialog.java
deleted file mode 100644
index c116d76..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ErrorDialog.java
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gerrit.client.rpc.RestApi;
-import com.google.gerrit.client.rpc.RpcConstants;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.http.client.Response;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.rpc.StatusCodeException;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwtexpui.safehtml.client.SafeHtml;
-import com.google.gwtjsonrpc.client.RemoteJsonException;
-
-/** A dialog box showing an error message, when bad things happen. */
-public class ErrorDialog extends PopupPanel {
-  private final Label text;
-  private final FlowPanel body;
-  private final Button closey;
-
-  protected ErrorDialog() {
-    super(/* auto hide */ false, /* modal */ true);
-    setGlassEnabled(true);
-    getGlassElement().addClassName(Gerrit.RESOURCES.css().errorDialogGlass());
-
-    text = new Label();
-    text.setStyleName(Gerrit.RESOURCES.css().errorDialogTitle());
-
-    body = new FlowPanel();
-
-    final FlowPanel buttons = new FlowPanel();
-    buttons.setStyleName(Gerrit.RESOURCES.css().errorDialogButtons());
-
-    closey = new Button();
-    closey.setText(Gerrit.C.errorDialogContinue());
-    closey.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            hide();
-          }
-        });
-    closey.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            // if the close button is triggered by a key we need to consume the key
-            // event, otherwise the key event would be propagated to the parent
-            // screen and eventually trigger some unwanted action there after the
-            // error dialog was closed
-            event.stopPropagation();
-          }
-        });
-    buttons.add(closey);
-
-    final FlowPanel center = new FlowPanel();
-    center.add(text);
-    center.add(body);
-    center.add(buttons);
-
-    setText(Gerrit.C.errorTitle());
-    addStyleName(Gerrit.RESOURCES.css().errorDialog());
-    add(center);
-
-    int l = Window.getScrollLeft() + 20;
-    int t = Window.getScrollTop() + 20;
-    setPopupPosition(l, t);
-  }
-
-  /** Create a dialog box to show a single message string. */
-  public ErrorDialog(String message) {
-    this();
-    body.add(createErrorMsgLabel(message));
-  }
-
-  /** Create a dialog box to show a single message string. */
-  public ErrorDialog(SafeHtml message) {
-    this();
-    body.add(message.toBlockWidget());
-  }
-
-  /** Create a dialog box to nicely format an exception. */
-  public ErrorDialog(Throwable what) {
-    this();
-
-    String hdr;
-    String msg;
-
-    if (what instanceof StatusCodeException) {
-      StatusCodeException sc = (StatusCodeException) what;
-      if (RestApi.isExpected(sc.getStatusCode())) {
-        hdr = null;
-        msg = sc.getEncodedResponse();
-      } else if (sc.getStatusCode() == Response.SC_INTERNAL_SERVER_ERROR) {
-        hdr = null;
-        msg = what.getMessage();
-      } else {
-        hdr = RpcConstants.C.errorServerUnavailable();
-        msg = what.getMessage();
-      }
-
-    } else if (what instanceof RemoteJsonException) {
-      // TODO Remove RemoteJsonException from Gerrit sources.
-      hdr = RpcConstants.C.errorRemoteJsonException();
-      msg = what.getMessage();
-
-    } else {
-      // TODO Fix callers of ErrorDialog to stop passing random types.
-      hdr = what.getClass().getName();
-      if (hdr.startsWith("java.lang.")) {
-        hdr = hdr.substring("java.lang.".length());
-      } else if (hdr.startsWith("com.google.gerrit.")) {
-        hdr = hdr.substring(hdr.lastIndexOf('.') + 1);
-      }
-      if (hdr.endsWith("Exception")) {
-        hdr = hdr.substring(0, hdr.length() - "Exception".length());
-      } else if (hdr.endsWith("Error")) {
-        hdr = hdr.substring(0, hdr.length() - "Error".length());
-      }
-      msg = what.getMessage();
-    }
-
-    if (hdr != null) {
-      final Label r = new Label(hdr);
-      r.setStyleName(Gerrit.RESOURCES.css().errorDialogErrorType());
-      body.add(r);
-    }
-
-    if (msg != null) {
-      body.add(createErrorMsgLabel(msg));
-    }
-  }
-
-  private Label createErrorMsgLabel(String message) {
-    Label m = new Label(message);
-    m.getElement().getStyle().setProperty("white-space", "pre");
-    return m;
-  }
-
-  public ErrorDialog setText(String t) {
-    text.setText(t);
-    return this;
-  }
-
-  @Override
-  public void center() {
-    show();
-    closey.setFocus(true);
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java
deleted file mode 100644
index c8d052e..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/FormatUtil.java
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gerrit.client.change.Resources;
-import com.google.gerrit.client.info.AccountInfo;
-import com.google.gerrit.client.info.GeneralPreferences;
-import com.google.gwt.i18n.client.NumberFormat;
-import java.util.Date;
-
-/** Misc. formatting functions. */
-public class FormatUtil {
-  private static DateFormatter dateFormatter;
-
-  public static void setPreferences(GeneralPreferences prefs) {
-    dateFormatter = new DateFormatter(prefs);
-  }
-
-  /** Format a date using a really short format. */
-  public static String shortFormat(Date dt) {
-    ensureInited();
-    return dateFormatter.shortFormat(dt);
-  }
-
-  /** Format a date using a really short format. */
-  public static String shortFormatDayTime(Date dt) {
-    ensureInited();
-    return dateFormatter.shortFormatDayTime(dt);
-  }
-
-  /** Format a date using the locale's medium length format. */
-  public static String mediumFormat(Date dt) {
-    ensureInited();
-    return dateFormatter.mediumFormat(dt);
-  }
-
-  private static void ensureInited() {
-    if (dateFormatter == null) {
-      setPreferences(Gerrit.getUserPreferences());
-    }
-  }
-
-  /** Format a date using git log's relative date format. */
-  public static String relativeFormat(Date dt) {
-    return RelativeDateFormatter.format(dt);
-  }
-
-  /**
-   * Formats an account as a name and an email address.
-   *
-   * <p>Example output:
-   *
-   * <ul>
-   *   <li>{@code A U. Thor &lt;author@example.com&gt;}: full populated
-   *   <li>{@code A U. Thor (12)}: missing email address
-   *   <li>{@code Anonymous Coward &lt;author@example.com&gt;}: missing name
-   *   <li>{@code Anonymous Coward (12)}: missing name and email address
-   * </ul>
-   */
-  public static String nameEmail(AccountInfo info) {
-    return createAccountFormatter().nameEmail(info);
-  }
-
-  /**
-   * Formats an account name.
-   *
-   * <p>If the account has a full name, it returns only the full name. Otherwise it returns a longer
-   * form that includes the email address.
-   */
-  public static String name(AccountInfo info) {
-    return createAccountFormatter().name(info);
-  }
-
-  private static AccountFormatter createAccountFormatter() {
-    return new AccountFormatter(Gerrit.info().user().anonymousCowardName());
-  }
-
-  /** The returned format string doesn't contain any +/- sign. */
-  public static String formatAbsBytes(long bytes) {
-    return formatBytes(bytes, true);
-  }
-
-  public static String formatBytes(long bytes) {
-    return formatBytes(bytes, false);
-  }
-
-  private static String formatBytes(long bytes, boolean abs) {
-    bytes = abs ? Math.abs(bytes) : bytes;
-
-    if (bytes == 0) {
-      return abs ? "0 B" : "+/- 0 B";
-    }
-
-    if (Math.abs(bytes) < 1024) {
-      return (bytes > 0 && !abs ? "+" : "") + bytes + " B";
-    }
-
-    int exp = (int) (Math.log(Math.abs(bytes)) / Math.log(1024));
-    return (bytes > 0 && !abs ? "+" : "")
-        + NumberFormat.getFormat("#.0").format(bytes / Math.pow(1024, exp))
-        + " "
-        + "KMGTPE".charAt(exp - 1)
-        + "iB";
-  }
-
-  public static String formatPercentage(long size, long delta) {
-    if (size == 0) {
-      return Resources.C.notAvailable();
-    }
-    return (delta > 0 ? "+" : "-") + formatAbsPercentage(size, delta);
-  }
-
-  public static String formatAbsPercentage(long size, long delta) {
-    if (size == 0) {
-      return Resources.C.notAvailable();
-    }
-    long percentage = Math.abs(Math.round(delta * 100.0 / size));
-    return percentage + "%";
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
deleted file mode 100644
index afc65c9..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ /dev/null
@@ -1,1134 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import static com.google.gerrit.common.data.GlobalCapability.CREATE_GROUP;
-import static com.google.gerrit.common.data.GlobalCapability.CREATE_PROJECT;
-import static com.google.gerrit.common.data.GlobalCapability.VIEW_PLUGINS;
-import static com.google.gerrit.common.data.HostPageData.XSRF_COOKIE_NAME;
-
-import com.google.gerrit.client.account.AccountApi;
-import com.google.gerrit.client.account.AccountCapabilities;
-import com.google.gerrit.client.account.EditPreferences;
-import com.google.gerrit.client.admin.ProjectScreen;
-import com.google.gerrit.client.api.ApiGlue;
-import com.google.gerrit.client.api.PluginLoader;
-import com.google.gerrit.client.change.LocalComments;
-import com.google.gerrit.client.changes.ChangeListScreen;
-import com.google.gerrit.client.config.ConfigServerApi;
-import com.google.gerrit.client.documentation.DocInfo;
-import com.google.gerrit.client.info.AccountInfo;
-import com.google.gerrit.client.info.AuthInfo;
-import com.google.gerrit.client.info.GeneralPreferences;
-import com.google.gerrit.client.info.ServerInfo;
-import com.google.gerrit.client.info.TopMenu;
-import com.google.gerrit.client.info.TopMenuItem;
-import com.google.gerrit.client.info.TopMenuList;
-import com.google.gerrit.client.rpc.CallbackGroup;
-import com.google.gerrit.client.rpc.GerritCallback;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.client.ui.LinkMenuBar;
-import com.google.gerrit.client.ui.LinkMenuItem;
-import com.google.gerrit.client.ui.MorphingTabPanel;
-import com.google.gerrit.client.ui.ProjectLinkMenuItem;
-import com.google.gerrit.client.ui.Screen;
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.common.PageLinks;
-import com.google.gerrit.common.data.HostPageData;
-import com.google.gerrit.common.data.SystemInfoService;
-import com.google.gerrit.extensions.client.DiffPreferencesInfo;
-import com.google.gerrit.extensions.client.EditPreferencesInfo;
-import com.google.gerrit.extensions.client.GerritTopMenu;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gwt.aria.client.Roles;
-import com.google.gwt.core.client.EntryPoint;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.Document;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyDownEvent;
-import com.google.gwt.event.dom.client.KeyDownHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.event.shared.EventBus;
-import com.google.gwt.event.shared.SimpleEventBus;
-import com.google.gwt.http.client.Request;
-import com.google.gwt.http.client.RequestBuilder;
-import com.google.gwt.http.client.RequestCallback;
-import com.google.gwt.http.client.RequestException;
-import com.google.gwt.http.client.Response;
-import com.google.gwt.http.client.URL;
-import com.google.gwt.http.client.UrlBuilder;
-import com.google.gwt.user.client.Command;
-import com.google.gwt.user.client.Cookies;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.Window.Location;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.FocusPanel;
-import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;
-import com.google.gwt.user.client.ui.InlineHTML;
-import com.google.gwt.user.client.ui.InlineLabel;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwtexpui.clippy.client.CopyableLabel;
-import com.google.gwtexpui.user.client.UserAgent;
-import com.google.gwtexpui.user.client.ViewSite;
-import com.google.gwtjsonrpc.client.JsonDefTarget;
-import com.google.gwtjsonrpc.client.JsonUtil;
-import com.google.gwtjsonrpc.client.XsrfManager;
-import com.google.gwtorm.client.KeyUtil;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class Gerrit implements EntryPoint {
-  public static final GerritConstants C = GWT.create(GerritConstants.class);
-  public static final GerritMessages M = GWT.create(GerritMessages.class);
-  public static final GerritResources RESOURCES = GWT.create(GerritResources.class);
-  public static final SystemInfoService SYSTEM_SVC;
-  public static final EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);
-  public static final Themer THEMER = GWT.create(Themer.class);
-  public static final String PROJECT_NAME_MENU_VAR = "${projectName}";
-  public static final String INDEX = "Documentation/index.html";
-
-  private static String myHost;
-  private static ServerInfo myServerInfo;
-  private static AccountInfo myAccount;
-  private static GeneralPreferences myPrefs;
-  private static UrlAliasMatcher urlAliasMatcher;
-  private static boolean hasDocumentation;
-  private static boolean docSearch;
-  private static String docUrl;
-  private static HostPageData.Theme myTheme;
-  private static String defaultScreenToken;
-  private static DiffPreferencesInfo myAccountDiffPref;
-  private static EditPreferencesInfo editPrefs;
-  private static String xGerritAuth;
-  private static boolean isNoteDbEnabled;
-
-  private static Map<String, LinkMenuBar> menuBars;
-
-  private static MorphingTabPanel menuLeft;
-  private static LinkMenuBar menuRight;
-  private static RootPanel topMenu;
-  private static RootPanel siteHeader;
-  private static RootPanel siteFooter;
-  private static RootPanel bottomMenu;
-  private static SearchPanel searchPanel;
-  private static final Dispatcher dispatcher = new Dispatcher();
-  private static ViewSite<Screen> body;
-  private static String lastChangeListToken;
-  private static String lastViewToken;
-  private static Anchor uiSwitcherLink;
-
-  static {
-    SYSTEM_SVC = GWT.create(SystemInfoService.class);
-    JsonUtil.bind(SYSTEM_SVC, "rpc/SystemInfoService");
-  }
-
-  static void upgradeUI(String token) {
-    History.newItem(Dispatcher.RELOAD_UI + token, false);
-    Window.Location.reload();
-  }
-
-  public static void displayLastChangeList() {
-    if (lastChangeListToken != null) {
-      display(lastChangeListToken);
-    } else if (isSignedIn()) {
-      display(PageLinks.MINE);
-    } else {
-      display(PageLinks.toChangeQuery("status:open"));
-    }
-  }
-
-  public static String getPriorView() {
-    return lastViewToken;
-  }
-
-  /**
-   * Load the screen at the given location, displaying when ready.
-   *
-   * <p>If the URL is not already pointing at this location, a new item will be added to the
-   * browser's history when the screen is fully loaded and displayed on the UI.
-   *
-   * @param token location to parse, load, and render.
-   */
-  public static void display(String token) {
-    if (body.getView() == null || !body.getView().displayToken(token)) {
-      dispatcher.display(token);
-      updateUiLink(token);
-    }
-  }
-
-  /**
-   * Load the screen passed, assuming token can be used to locate it.
-   *
-   * <p>The screen is loaded in the background. When it is ready to be visible a new item will be
-   * added to the browser's history, the screen will be made visible, and the window title may be
-   * updated.
-   *
-   * <p>If {@link Screen#isRequiresSignIn()} is true and the user is not signed in yet the screen
-   * instance will be discarded, sign-in will take place, and will redirect to this location upon
-   * success.
-   *
-   * @param token location that refers to {@code view}.
-   * @param view the view to load.
-   */
-  public static void display(String token, Screen view) {
-    if (view.isRequiresSignIn() && !isSignedIn()) {
-      doSignIn(token);
-    } else {
-      view.setToken(token);
-      if (isSignedIn()) {
-        LocalComments.saveInlineComments();
-      }
-      body.setView(view);
-      updateUiLink(token);
-    }
-  }
-
-  public static void selectMenu(LinkMenuBar bar) {
-    menuLeft.selectTab(menuLeft.getWidgetIndex(bar));
-  }
-
-  /**
-   * Update the current history token after a screen change.
-   *
-   * <p>The caller has already updated the UI, but wants to publish a different history token for
-   * the current browser state. This really only makes sense if the caller is a {@code TabPanel} and
-   * is firing an event when the tab changed to a different part.
-   *
-   * @param token new location that is already visible.
-   */
-  public static void updateImpl(String token) {
-    History.newItem(token, false);
-    dispatchHistoryHooks(token);
-  }
-
-  public static void setQueryString(String query) {
-    searchPanel.setText(query);
-  }
-
-  public static void setWindowTitle(Screen screen, String text) {
-    if (screen == body.getView()) {
-      if (text == null || text.length() == 0) {
-        Window.setTitle(M.windowTitle1(myHost));
-      } else {
-        Window.setTitle(M.windowTitle2(text, myHost));
-      }
-    }
-  }
-
-  public static int getHeaderFooterHeight() {
-    int h = bottomMenu.getOffsetHeight();
-    if (topMenu.isVisible()) {
-      h += topMenu.getOffsetHeight();
-    }
-    if (siteHeader.isVisible()) {
-      h += siteHeader.getOffsetHeight();
-    }
-    if (siteFooter.isVisible()) {
-      h += siteFooter.getOffsetHeight();
-    }
-    return h;
-  }
-
-  public static void setHeaderVisible(boolean visible) {
-    topMenu.setVisible(visible);
-    siteHeader.setVisible(visible && getUserPreferences().showSiteHeader());
-  }
-
-  public static boolean isHeaderVisible() {
-    return topMenu.isVisible();
-  }
-
-  public static String getDefaultScreenToken() {
-    return defaultScreenToken;
-  }
-
-  public static RootPanel getBottomMenu() {
-    return bottomMenu;
-  }
-
-  /** Get the public configuration data used by this Gerrit instance. */
-  public static ServerInfo info() {
-    return myServerInfo;
-  }
-
-  public static UrlAliasMatcher getUrlAliasMatcher() {
-    return urlAliasMatcher;
-  }
-
-  /** Site theme information (site specific colors)/ */
-  public static HostPageData.Theme getTheme() {
-    return myTheme;
-  }
-
-  /** @return the currently signed in user's account data; empty account data if no account */
-  public static AccountInfo getUserAccount() {
-    return myAccount;
-  }
-
-  /** @return access token to prove user identity during REST API calls. */
-  @Nullable
-  public static String getXGerritAuth() {
-    return xGerritAuth;
-  }
-
-  /**
-   * @return the preferences of the currently signed in user, the default preferences if not signed
-   *     in
-   */
-  public static GeneralPreferences getUserPreferences() {
-    return myPrefs;
-  }
-
-  /** @return the currently signed in users's diff preferences, or default values */
-  public static DiffPreferencesInfo getDiffPreferences() {
-    return myAccountDiffPref;
-  }
-
-  public static void setDiffPreferences(DiffPreferencesInfo accountDiffPref) {
-    myAccountDiffPref = accountDiffPref;
-  }
-
-  /** @return the edit preferences of the current user, null if not signed-in */
-  public static EditPreferencesInfo getEditPreferences() {
-    return editPrefs;
-  }
-
-  public static void setEditPreferences(EditPreferencesInfo p) {
-    editPrefs = p;
-  }
-
-  /** @return true if the user is currently authenticated */
-  public static boolean isSignedIn() {
-    return xGerritAuth != null;
-  }
-
-  /** Sign the user into the application. */
-  public static void doSignIn(String token) {
-    Location.assign(loginRedirect(token));
-  }
-
-  public static boolean isNoteDbEnabled() {
-    return isNoteDbEnabled;
-  }
-
-  public static String loginRedirect(String token) {
-    if (token == null) {
-      token = "";
-    } else if (token.startsWith("/")) {
-      token = token.substring(1);
-    }
-
-    return selfRedirect("login/") + URL.encodePathSegment("#/" + token);
-  }
-
-  public static String selfRedirect(String suffix) {
-    // Clean up the path. Users seem to like putting extra slashes into the URL
-    // which can break redirections by misinterpreting at either client or server.
-    String path = Location.getPath();
-    if (path == null || path.isEmpty()) {
-      path = "/";
-    } else {
-      while (path.startsWith("//")) {
-        path = path.substring(1);
-      }
-      while (path.endsWith("//")) {
-        path = path.substring(0, path.length() - 1);
-      }
-      if (!path.endsWith("/")) {
-        path = path + "/";
-      }
-    }
-
-    if (suffix != null) {
-      while (suffix.startsWith("/")) {
-        suffix = suffix.substring(1);
-      }
-      path += suffix;
-    }
-
-    UrlBuilder builder = new UrlBuilder();
-    builder.setProtocol(Location.getProtocol());
-    builder.setHost(Location.getHost());
-    String port = Location.getPort();
-    if (port != null && !port.isEmpty()) {
-      builder.setPort(Integer.parseInt(port));
-    }
-    builder.setPath(path);
-    return builder.buildString();
-  }
-
-  static void deleteSessionCookie() {
-    myAccount = AccountInfo.create(0, null, null, null);
-    myAccountDiffPref = null;
-    editPrefs = null;
-    myPrefs = GeneralPreferences.createDefault();
-    urlAliasMatcher.clearUserAliases();
-    xGerritAuth = null;
-    refreshMenuBar();
-
-    // If the cookie was HttpOnly, this request to delete it will
-    // most likely not be successful.  We can try anyway though.
-    //
-    Cookies.removeCookie("GerritAccount");
-  }
-
-  private void setXsrfToken() {
-    xGerritAuth = Cookies.getCookie(XSRF_COOKIE_NAME);
-    JsonUtil.setDefaultXsrfManager(
-        new XsrfManager() {
-          @Override
-          public String getToken(JsonDefTarget proxy) {
-            return xGerritAuth;
-          }
-
-          @Override
-          public void setToken(JsonDefTarget proxy, String token) {
-            // Ignore the request, we always rely upon the cookie.
-          }
-        });
-  }
-
-  @Override
-  public void onModuleLoad() {
-    if (!canLoadInIFrame()) {
-      UserAgent.assertNotInIFrame();
-    }
-    setXsrfToken();
-
-    KeyUtil.setEncoderImpl(
-        new KeyUtil.Encoder() {
-          @Override
-          public String encode(String e) {
-            e = URL.encodeQueryString(e);
-            e = fixPathImpl(e);
-            e = fixColonImpl(e);
-            e = fixDoubleQuote(e);
-            return e;
-          }
-
-          @Override
-          public String decode(String e) {
-            return URL.decodeQueryString(e);
-          }
-
-          private native String fixPathImpl(String path)
-              /*-{ return path.replace(/%2F/g, "/"); }-*/ ;
-
-          private native String fixColonImpl(String path)
-              /*-{ return path.replace(/%3A/g, ":"); }-*/ ;
-
-          private native String fixDoubleQuote(String path)
-              /*-{ return path.replace(/%22/g, '"'); }-*/ ;
-        });
-
-    initHostname();
-    Window.setTitle(M.windowTitle1(myHost));
-
-    RpcStatus.INSTANCE = new RpcStatus();
-    CallbackGroup cbg = new CallbackGroup();
-    getDocIndex(
-        cbg.add(
-            new GerritCallback<DocInfo>() {
-              @Override
-              public void onSuccess(DocInfo indexInfo) {
-                hasDocumentation = indexInfo != null;
-                docUrl = selfRedirect("/Documentation/");
-              }
-            }));
-    ConfigServerApi.serverInfo(
-        cbg.add(
-            new GerritCallback<ServerInfo>() {
-              @Override
-              public void onSuccess(ServerInfo info) {
-                myServerInfo = info;
-                urlAliasMatcher = new UrlAliasMatcher(info.urlAliases());
-                String du = info.gerrit().docUrl();
-                if (du != null && !du.isEmpty()) {
-                  hasDocumentation = true;
-                  docUrl = du;
-                }
-                docSearch = info.gerrit().docSearch();
-              }
-            }));
-    HostPageDataService hpd = GWT.create(HostPageDataService.class);
-    hpd.load(
-        cbg.addFinal(
-            new GerritCallback<HostPageData>() {
-              @Override
-              public void onSuccess(HostPageData result) {
-                Document.get().getElementById("gerrit_hostpagedata").removeFromParent();
-                myTheme = result.theme;
-                isNoteDbEnabled = result.isNoteDbEnabled;
-                if (result.accountDiffPref != null) {
-                  myAccountDiffPref = result.accountDiffPref;
-                }
-                if (result.accountDiffPref != null) {
-                  // TODO: Support options on the GetDetail REST endpoint so that it can
-                  // also return the preferences. Then we can fetch everything with a
-                  // single request and we don't need the callback group anymore.
-                  CallbackGroup cbg = new CallbackGroup();
-                  AccountApi.self()
-                      .view("detail")
-                      .get(
-                          cbg.add(
-                              new GerritCallback<AccountInfo>() {
-                                @Override
-                                public void onSuccess(AccountInfo result) {
-                                  myAccount = result;
-                                }
-                              }));
-                  AccountApi.self()
-                      .view("preferences")
-                      .get(
-                          cbg.add(
-                              new GerritCallback<GeneralPreferences>() {
-                                @Override
-                                public void onSuccess(GeneralPreferences prefs) {
-                                  myPrefs = prefs;
-                                  onModuleLoad2(result);
-                                }
-                              }));
-                  AccountApi.getEditPreferences(
-                      cbg.addFinal(
-                          new GerritCallback<EditPreferences>() {
-                            @Override
-                            public void onSuccess(EditPreferences prefs) {
-                              EditPreferencesInfo prefsInfo = new EditPreferencesInfo();
-                              prefs.copyTo(prefsInfo);
-                              editPrefs = prefsInfo;
-                            }
-                          }));
-                } else {
-                  myAccount = AccountInfo.create(0, null, null, null);
-                  myPrefs = GeneralPreferences.createDefault();
-                  editPrefs = null;
-                  onModuleLoad2(result);
-                }
-              }
-            }));
-  }
-
-  private native boolean canLoadInIFrame() /*-{
-    return $wnd.gerrit_hostpagedata.canLoadInIFrame || false;
-  }-*/;
-
-  private static void initHostname() {
-    myHost = Location.getHostName();
-    final int d1 = myHost.indexOf('.');
-    if (d1 < 0) {
-      return;
-    }
-    final int d2 = myHost.indexOf('.', d1 + 1);
-    if (d2 >= 0) {
-      myHost = myHost.substring(0, d2);
-    }
-  }
-
-  private static void dispatchHistoryHooks(String token) {
-    ApiGlue.fireEvent("history", token);
-  }
-
-  private static String getUiSwitcherUrl(String token) {
-    UrlBuilder builder = new UrlBuilder();
-    builder.setProtocol(Location.getProtocol());
-    builder.setHost(Location.getHost());
-    String port = Location.getPort();
-    if (port != null && !port.isEmpty()) {
-      builder.setPort(Integer.parseInt(port));
-    }
-    String[] tokens = token.split("@", 2);
-    if (Location.getPath().endsWith("/") && tokens[0].startsWith("/")) {
-      tokens[0] = tokens[0].substring(1);
-    }
-    if (tokens[0].startsWith("projects/") && tokens[0].contains(",dashboards/")) {
-      // Rewrite project dashboard URIs to a new format, because otherwise
-      // "/projects/..." would be served as an API request.
-      tokens[0] = "p/" + tokens[0].substring("projects/".length());
-      tokens[0] = tokens[0].replace(",dashboards/", "/+/dashboard/");
-    }
-    builder.setPath(Location.getPath() + tokens[0]);
-    if (tokens.length == 2) {
-      builder.setHash(tokens[1]);
-    }
-    builder.setParameter("polygerrit", "1");
-    return builder.buildString();
-  }
-
-  private static void populateBottomMenu(RootPanel btmmenu, HostPageData hpd) {
-    String vs = hpd.version;
-    if (vs == null || vs.isEmpty()) {
-      vs = "dev";
-    }
-
-    btmmenu.add(new InlineHTML(M.poweredBy(vs)));
-
-    btmmenu.add(new InlineLabel(" | "));
-    uiSwitcherLink = new Anchor(C.newUi(), getUiSwitcherUrl(History.getToken()));
-    uiSwitcherLink.setStyleName("");
-    btmmenu.add(uiSwitcherLink);
-
-    String reportBugUrl = info().gerrit().reportBugUrl();
-    if (reportBugUrl != null) {
-      String reportBugText = info().gerrit().reportBugText();
-      Anchor a = new Anchor(reportBugText == null ? C.reportBug() : reportBugText, reportBugUrl);
-      a.setTarget("_blank");
-      a.setStyleName("");
-      btmmenu.add(new InlineLabel(" | "));
-      btmmenu.add(a);
-    }
-    btmmenu.add(new InlineLabel(" | "));
-    btmmenu.add(new InlineLabel(C.keyHelp()));
-  }
-
-  private static void updateUiLink(String token) {
-    if (uiSwitcherLink != null) {
-      uiSwitcherLink.setHref(getUiSwitcherUrl(token));
-    }
-  }
-
-  private void onModuleLoad2(HostPageData hpd) {
-    RESOURCES.gwt_override().ensureInjected();
-    RESOURCES.css().ensureInjected();
-
-    topMenu = RootPanel.get("gerrit_topmenu");
-    final RootPanel gStarting = RootPanel.get("gerrit_startinggerrit");
-    final RootPanel gBody = RootPanel.get("gerrit_body");
-    bottomMenu = RootPanel.get("gerrit_btmmenu");
-
-    topMenu.setStyleName(RESOURCES.css().gerritTopMenu());
-    gBody.setStyleName(RESOURCES.css().gerritBody());
-
-    final Grid menuLine = new Grid(1, 3);
-    menuLeft = new MorphingTabPanel();
-    menuRight = new LinkMenuBar();
-    searchPanel = new SearchPanel();
-    menuLeft.setStyleName(RESOURCES.css().topmenuMenuLeft());
-    menuLine.setStyleName(RESOURCES.css().topmenu());
-    topMenu.add(menuLine);
-    final FlowPanel menuRightPanel = new FlowPanel();
-    menuRightPanel.setStyleName(RESOURCES.css().topmenuMenuRight());
-    menuRightPanel.add(searchPanel);
-    menuRightPanel.add(menuRight);
-    menuLine.setWidget(0, 0, menuLeft);
-    menuLine.setWidget(0, 1, new FlowPanel());
-    menuLine.setWidget(0, 2, menuRightPanel);
-    final CellFormatter fmt = menuLine.getCellFormatter();
-    fmt.setStyleName(0, 0, RESOURCES.css().topmenuTDmenu());
-    fmt.setStyleName(0, 1, RESOURCES.css().topmenuTDglue());
-    fmt.setStyleName(0, 2, RESOURCES.css().topmenuTDmenu());
-
-    siteHeader = RootPanel.get("gerrit_header");
-    siteFooter = RootPanel.get("gerrit_footer");
-
-    body =
-        new ViewSite<Screen>() {
-          @Override
-          protected void onShowView(Screen view) {
-            String token = view.getToken();
-            History.newItem(token, false);
-            dispatchHistoryHooks(token);
-
-            if (view instanceof ChangeListScreen) {
-              lastChangeListToken = token;
-            }
-
-            super.onShowView(view);
-            view.onShowView();
-            lastViewToken = token;
-          }
-        };
-    gBody.add(body);
-
-    JsonUtil.addRpcStartHandler(RpcStatus.INSTANCE);
-    JsonUtil.addRpcCompleteHandler(RpcStatus.INSTANCE);
-
-    gStarting.getElement().getParentElement().removeChild(gStarting.getElement());
-    RootPanel.detachNow(gStarting);
-    ApiGlue.init();
-
-    applyUserPreferences();
-    populateBottomMenu(bottomMenu, hpd);
-    refreshMenuBar();
-
-    History.addValueChangeHandler(
-        new ValueChangeHandler<String>() {
-          @Override
-          public void onValueChange(ValueChangeEvent<String> event) {
-            display(event.getValue());
-          }
-        });
-    JumpKeys.register(body);
-
-    saveDefaultTheme();
-    if (hpd.messages != null) {
-      new MessageOfTheDayBar(hpd.messages).show();
-    }
-    PluginLoader.load(
-        hpd.plugins,
-        hpd.pluginsLoadTimeout,
-        new GerritCallback<VoidResult>() {
-          @Override
-          public void onSuccess(VoidResult result) {
-            String token = History.getToken();
-            if (token.isEmpty()) {
-              token = isSignedIn() ? PageLinks.MINE : PageLinks.toChangeQuery("status:open");
-            }
-            display(token);
-          }
-        });
-  }
-
-  private void saveDefaultTheme() {
-    THEMER.init(
-        Document.get().getElementById("gerrit_sitecss"),
-        Document.get().getElementById("gerrit_header"),
-        Document.get().getElementById("gerrit_footer"));
-  }
-
-  public static void refreshMenuBar() {
-    menuLeft.clear();
-    menuRight.clear();
-
-    menuBars = new HashMap<>();
-
-    boolean signedIn = isSignedIn();
-    AuthInfo authInfo = info().auth();
-    LinkMenuBar m;
-
-    m = new LinkMenuBar();
-    menuBars.put(GerritTopMenu.ALL.menuName, m);
-    addLink(m, C.menuAllOpen(), PageLinks.toChangeQuery("status:open"));
-    addLink(m, C.menuAllMerged(), PageLinks.toChangeQuery("status:merged"));
-    addLink(m, C.menuAllAbandoned(), PageLinks.toChangeQuery("status:abandoned"));
-    menuLeft.add(m, C.menuAll());
-
-    if (signedIn) {
-      LinkMenuBar myBar = new LinkMenuBar();
-      menuBars.put(GerritTopMenu.MY.menuName, myBar);
-
-      if (myPrefs.my() != null) {
-        myBar.clear();
-        String url = null;
-        List<TopMenuItem> myMenuItems = Natives.asList(myPrefs.my());
-        if (!myMenuItems.isEmpty()) {
-          if (myMenuItems.get(0).getUrl().startsWith("#")) {
-            url = myMenuItems.get(0).getUrl().substring(1);
-          }
-          for (TopMenuItem item : myMenuItems) {
-            addExtensionLink(myBar, item);
-          }
-        }
-        defaultScreenToken = url;
-      }
-
-      menuLeft.add(myBar, C.menuMine());
-      menuLeft.selectTab(1);
-    } else {
-      menuLeft.selectTab(0);
-    }
-
-    final LinkMenuBar projectsBar = new LinkMenuBar();
-    menuBars.put(GerritTopMenu.PROJECTS.menuName, projectsBar);
-    addLink(projectsBar, C.menuProjectsList(), PageLinks.ADMIN_PROJECTS);
-    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsInfo(), ProjectScreen.INFO));
-    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsBranches(), ProjectScreen.BRANCHES));
-    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsTags(), ProjectScreen.TAGS));
-    projectsBar.addItem(new ProjectLinkMenuItem(C.menuProjectsAccess(), ProjectScreen.ACCESS));
-    final LinkMenuItem dashboardsMenuItem =
-        new ProjectLinkMenuItem(C.menuProjectsDashboards(), ProjectScreen.DASHBOARDS) {
-          @Override
-          protected boolean match(String token) {
-            return super.match(token)
-                || (!getTargetHistoryToken().isEmpty()
-                    && ("/admin" + token).startsWith(getTargetHistoryToken()));
-          }
-        };
-    projectsBar.addItem(dashboardsMenuItem);
-    menuLeft.add(projectsBar, C.menuProjects());
-
-    if (signedIn) {
-      final LinkMenuBar peopleBar = new LinkMenuBar();
-      menuBars.put(GerritTopMenu.PEOPLE.menuName, peopleBar);
-      final LinkMenuItem groupsListMenuItem =
-          addLink(peopleBar, C.menuPeopleGroupsList(), PageLinks.ADMIN_GROUPS);
-      menuLeft.add(peopleBar, C.menuPeople());
-
-      final LinkMenuBar pluginsBar = new LinkMenuBar();
-      menuBars.put(GerritTopMenu.PLUGINS.menuName, pluginsBar);
-      AccountCapabilities.all(
-          new GerritCallback<AccountCapabilities>() {
-            @Override
-            public void onSuccess(AccountCapabilities result) {
-              if (result.canPerform(CREATE_PROJECT)) {
-                insertLink(
-                    projectsBar,
-                    C.menuProjectsCreate(),
-                    PageLinks.ADMIN_CREATE_PROJECT,
-                    projectsBar.getWidgetIndex(dashboardsMenuItem) + 1);
-              }
-              if (result.canPerform(CREATE_GROUP)) {
-                insertLink(
-                    peopleBar,
-                    C.menuPeopleGroupsCreate(),
-                    PageLinks.ADMIN_CREATE_GROUP,
-                    peopleBar.getWidgetIndex(groupsListMenuItem) + 1);
-              }
-              if (result.canPerform(VIEW_PLUGINS)) {
-                insertLink(pluginsBar, C.menuPluginsInstalled(), PageLinks.ADMIN_PLUGINS, 0);
-                menuLeft.insert(
-                    pluginsBar, C.menuPlugins(), menuLeft.getWidgetIndex(peopleBar) + 1);
-              }
-            }
-          },
-          CREATE_PROJECT,
-          CREATE_GROUP,
-          VIEW_PLUGINS);
-    }
-
-    if (hasDocumentation) {
-      m = new LinkMenuBar();
-      menuBars.put(GerritTopMenu.DOCUMENTATION.menuName, m);
-      addDocLink(m, C.menuDocumentationTOC(), "index.html");
-      addDocLink(m, C.menuDocumentationSearch(), "user-search.html");
-      addDocLink(m, C.menuDocumentationUpload(), "user-upload.html");
-      addDocLink(m, C.menuDocumentationAccess(), "access-control.html");
-      addDocLink(m, C.menuDocumentationAPI(), "rest-api.html");
-      addDocLink(m, C.menuDocumentationProjectOwnerGuide(), "intro-project-owner.html");
-      menuLeft.add(m, C.menuDocumentation());
-    }
-
-    if (signedIn) {
-      whoAmI(!authInfo.isClientSslCertLdap());
-    } else {
-      switch (authInfo.authType()) {
-        case CLIENT_SSL_CERT_LDAP:
-          break;
-
-        case OPENID:
-          menuRight.addItem(
-              C.menuRegister(),
-              new Command() {
-                @Override
-                public void execute() {
-                  String t = History.getToken();
-                  if (t == null) {
-                    t = "";
-                  }
-                  doSignIn(PageLinks.REGISTER + t);
-                }
-              });
-          menuRight.addItem(
-              C.menuSignIn(),
-              new Command() {
-                @Override
-                public void execute() {
-                  doSignIn(History.getToken());
-                }
-              });
-          break;
-
-        case OAUTH:
-          menuRight.addItem(
-              C.menuSignIn(),
-              new Command() {
-                @Override
-                public void execute() {
-                  doSignIn(History.getToken());
-                }
-              });
-          break;
-
-        case OPENID_SSO:
-          menuRight.addItem(
-              C.menuSignIn(),
-              new Command() {
-                @Override
-                public void execute() {
-                  doSignIn(History.getToken());
-                }
-              });
-          break;
-
-        case HTTP:
-        case HTTP_LDAP:
-          if (authInfo.loginUrl() != null) {
-            String signinText =
-                authInfo.loginText() == null ? C.menuSignIn() : authInfo.loginText();
-            menuRight.add(anchor(signinText, authInfo.loginUrl()));
-          }
-          break;
-
-        case LDAP:
-        case LDAP_BIND:
-        case CUSTOM_EXTENSION:
-          if (authInfo.registerUrl() != null) {
-            String registerText =
-                authInfo.registerText() == null ? C.menuRegister() : authInfo.registerText();
-            menuRight.add(anchor(registerText, authInfo.registerUrl()));
-          }
-          menuRight.addItem(
-              C.menuSignIn(),
-              new Command() {
-                @Override
-                public void execute() {
-                  doSignIn(History.getToken());
-                }
-              });
-          break;
-
-        case DEVELOPMENT_BECOME_ANY_ACCOUNT:
-          menuRight.add(anchor("Become", loginRedirect("")));
-          break;
-      }
-    }
-    ConfigServerApi.topMenus(
-        new GerritCallback<TopMenuList>() {
-          @Override
-          public void onSuccess(TopMenuList result) {
-            List<TopMenu> topMenuExtensions = Natives.asList(result);
-            for (TopMenu menu : topMenuExtensions) {
-              String name = menu.getName();
-              LinkMenuBar existingBar = menuBars.get(name);
-              LinkMenuBar bar = existingBar != null ? existingBar : new LinkMenuBar();
-              for (TopMenuItem item : Natives.asList(menu.getItems())) {
-                addMenuLink(bar, item);
-              }
-              if (existingBar == null) {
-                menuBars.put(name, bar);
-                menuLeft.add(bar, name);
-              }
-            }
-          }
-        });
-  }
-
-  public static void refreshUserPreferences() {
-    if (isSignedIn()) {
-      AccountApi.self()
-          .view("preferences")
-          .get(
-              new GerritCallback<GeneralPreferences>() {
-                @Override
-                public void onSuccess(GeneralPreferences prefs) {
-                  setUserPreferences(prefs);
-                }
-              });
-    } else {
-      setUserPreferences(GeneralPreferences.createDefault());
-    }
-  }
-
-  public static void setUserPreferences(GeneralPreferences prefs) {
-    myPrefs = prefs;
-    applyUserPreferences();
-    refreshMenuBar();
-  }
-
-  private static void applyUserPreferences() {
-    CopyableLabel.setFlashEnabled(myPrefs.useFlashClipboard());
-    if (siteHeader != null) {
-      siteHeader.setVisible(myPrefs.showSiteHeader());
-    }
-    if (siteFooter != null) {
-      siteFooter.setVisible(myPrefs.showSiteHeader());
-    }
-    FormatUtil.setPreferences(myPrefs);
-    urlAliasMatcher.updateUserAliases(myPrefs.urlAliases());
-  }
-
-  public static boolean hasDocSearch() {
-    return docSearch;
-  }
-
-  private static void getDocIndex(AsyncCallback<DocInfo> cb) {
-    RequestBuilder req = new RequestBuilder(RequestBuilder.HEAD, GWT.getHostPageBaseURL() + INDEX);
-    req.setCallback(
-        new RequestCallback() {
-          @Override
-          public void onResponseReceived(Request req, Response resp) {
-            switch (resp.getStatusCode()) {
-              case Response.SC_OK:
-              case Response.SC_MOVED_PERMANENTLY:
-              case Response.SC_MOVED_TEMPORARILY:
-                cb.onSuccess(DocInfo.create());
-                break;
-              default:
-                cb.onSuccess(null);
-                break;
-            }
-          }
-
-          @Override
-          public void onError(Request request, Throwable e) {
-            cb.onFailure(e);
-          }
-        });
-    try {
-      req.send();
-    } catch (RequestException e) {
-      cb.onFailure(e);
-    }
-  }
-
-  private static void whoAmI(boolean canLogOut) {
-    AccountInfo account = getUserAccount();
-    final UserPopupPanel userPopup = new UserPopupPanel(account, canLogOut, true);
-    final FlowPanel userSummaryPanel = new FlowPanel();
-    class PopupHandler implements KeyDownHandler, ClickHandler {
-      private void showHidePopup() {
-        if (userPopup.isShowing() && userPopup.isVisible()) {
-          userPopup.hide();
-        } else {
-          userPopup.showRelativeTo(userSummaryPanel);
-        }
-      }
-
-      @Override
-      public void onClick(ClickEvent event) {
-        showHidePopup();
-      }
-
-      @Override
-      public void onKeyDown(KeyDownEvent event) {
-        if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
-          showHidePopup();
-          event.preventDefault();
-        }
-      }
-    }
-    final PopupHandler popupHandler = new PopupHandler();
-    final InlineLabel l = new InlineLabel(FormatUtil.name(account));
-    l.setStyleName(RESOURCES.css().menuBarUserName());
-    final AvatarImage avatar = new AvatarImage(account, 26, false);
-    avatar.setStyleName(RESOURCES.css().menuBarUserNameAvatar());
-    userSummaryPanel.setStyleName(RESOURCES.css().menuBarUserNamePanel());
-    userSummaryPanel.add(l);
-    userSummaryPanel.add(avatar);
-    // "BLACK DOWN-POINTING SMALL TRIANGLE"
-    userSummaryPanel.add(new InlineLabel(" \u25be"));
-    userPopup.addAutoHidePartner(userSummaryPanel.getElement());
-    FocusPanel fp = new FocusPanel(userSummaryPanel);
-    fp.setStyleName(RESOURCES.css().menuBarUserNameFocusPanel());
-    fp.addKeyDownHandler(popupHandler);
-    fp.addClickHandler(popupHandler);
-    menuRight.add(fp);
-  }
-
-  private static Anchor anchor(String text, String to) {
-    final Anchor a = new Anchor(text, to);
-    a.setStyleName(RESOURCES.css().menuItem());
-    Roles.getMenuitemRole().set(a.getElement());
-    return a;
-  }
-
-  private static LinkMenuItem addLink(final LinkMenuBar m, String text, String historyToken) {
-    LinkMenuItem i = new LinkMenuItem(text, historyToken);
-    m.addItem(i);
-    return i;
-  }
-
-  private static void insertLink(
-      final LinkMenuBar m, String text, String historyToken, int beforeIndex) {
-    m.insertItem(new LinkMenuItem(text, historyToken), beforeIndex);
-  }
-
-  private static LinkMenuItem addProjectLink(LinkMenuBar m, TopMenuItem item) {
-    LinkMenuItem i =
-        new ProjectLinkMenuItem(item.getName(), item.getUrl()) {
-          @Override
-          protected void onScreenLoad(Project.NameKey project) {
-            String p = panel.replace(PROJECT_NAME_MENU_VAR, URL.encodeQueryString(project.get()));
-            if (!panel.startsWith("/x/") && !isAbsolute(panel)) {
-              UrlBuilder builder = new UrlBuilder();
-              builder.setProtocol(Location.getProtocol());
-              builder.setHost(Location.getHost());
-              String port = Location.getPort();
-              if (port != null && !port.isEmpty()) {
-                builder.setPort(Integer.parseInt(port));
-              }
-              builder.setPath(Location.getPath());
-              p = builder.buildString() + p;
-            }
-            getElement().setPropertyString("href", p);
-          }
-
-          @Override
-          public void go() {
-            String href = getElement().getPropertyString("href");
-            if (href.startsWith("#")) {
-              super.go();
-            } else {
-              Window.open(href, getElement().getPropertyString("target"), "");
-            }
-          }
-        };
-    if (item.getTarget() != null && !item.getTarget().isEmpty()) {
-      i.getElement().setAttribute("target", item.getTarget());
-    }
-    if (item.getId() != null) {
-      i.getElement().setAttribute("id", item.getId());
-    }
-    m.addItem(i);
-    return i;
-  }
-
-  private static void addDocLink(LinkMenuBar m, String text, String href) {
-    final Anchor atag = anchor(text, docUrl + href);
-    atag.setTarget("_blank");
-    m.add(atag);
-  }
-
-  private static void addMenuLink(LinkMenuBar m, TopMenuItem item) {
-    if (item.getUrl().contains(PROJECT_NAME_MENU_VAR)) {
-      addProjectLink(m, item);
-    } else {
-      addExtensionLink(m, item);
-    }
-  }
-
-  private static void addExtensionLink(LinkMenuBar m, TopMenuItem item) {
-    if (item.getUrl().startsWith("#") && (item.getTarget() == null || item.getTarget().isEmpty())) {
-      LinkMenuItem a = new LinkMenuItem(item.getName(), item.getUrl().substring(1));
-      if (item.getId() != null) {
-        a.getElement().setAttribute("id", item.getId());
-      }
-      m.addItem(a);
-    } else {
-      Anchor atag =
-          anchor(
-              item.getName(),
-              isAbsolute(item.getUrl()) ? item.getUrl() : selfRedirect(item.getUrl()));
-      if (item.getTarget() != null && !item.getTarget().isEmpty()) {
-        atag.setTarget(item.getTarget());
-      }
-      if (item.getId() != null) {
-        atag.getElement().setAttribute("id", item.getId());
-      }
-      m.add(atag);
-    }
-  }
-
-  private static boolean isAbsolute(String url) {
-    return url.matches("^https?://.*");
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
deleted file mode 100644
index eae3431..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.java
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gwt.i18n.client.Constants;
-
-public interface GerritConstants extends Constants {
-  String menuSignIn();
-
-  String menuRegister();
-
-  String reportBug();
-
-  String loadingPlugins();
-
-  String signInDialogTitle();
-
-  String signInDialogGoAnonymous();
-
-  String linkIdentityDialogTitle();
-
-  String registerDialogTitle();
-
-  String loginTypeUnsupported();
-
-  String errorTitle();
-
-  String errorDialogContinue();
-
-  String warnTitle();
-
-  String confirmationDialogOk();
-
-  String confirmationDialogCancel();
-
-  String branchCreationDialogTitle();
-
-  String branchCreationConfirmationMessage();
-
-  String tagCreationDialogTitle();
-
-  String tagCreationConfirmationMessage();
-
-  String branchDeletionDialogTitle();
-
-  String branchDeletionConfirmationMessage();
-
-  String tagDeletionDialogTitle();
-
-  String tagDeletionConfirmationMessage();
-
-  String newUi();
-
-  String notSignedInTitle();
-
-  String notSignedInBody();
-
-  String notFoundTitle();
-
-  String notFoundBody();
-
-  String noSuchAccountTitle();
-
-  String noSuchGroupTitle();
-
-  String inactiveAccountBody();
-
-  String labelNotApplicable();
-
-  String menuAll();
-
-  String menuAllOpen();
-
-  String menuAllMerged();
-
-  String menuAllAbandoned();
-
-  String menuMine();
-
-  String menuMyChanges();
-
-  String menuMyWatchedChanges();
-
-  String menuMyStarredChanges();
-
-  String menuMyDraftComments();
-
-  String menuDiff();
-
-  String menuDiffCommit();
-
-  String menuDiffPreferences();
-
-  String menuDiffPatchSets();
-
-  String menuDiffFiles();
-
-  String menuProjects();
-
-  String menuProjectsList();
-
-  String menuProjectsInfo();
-
-  String menuProjectsBranches();
-
-  String menuProjectsTags();
-
-  String menuProjectsAccess();
-
-  String menuProjectsDashboards();
-
-  String menuProjectsCreate();
-
-  String menuPeople();
-
-  String menuPeopleGroupsList();
-
-  String menuPeopleGroupsCreate();
-
-  String menuPlugins();
-
-  String menuPluginsInstalled();
-
-  String menuDocumentation();
-
-  String menuDocumentationTOC();
-
-  String menuDocumentationSearch();
-
-  String menuDocumentationUpload();
-
-  String menuDocumentationAccess();
-
-  String menuDocumentationAPI();
-
-  String menuDocumentationProjectOwnerGuide();
-
-  String searchHint();
-
-  String searchButton();
-
-  String rpcStatusWorking();
-
-  String sectionNavigation();
-
-  String sectionActions();
-
-  String keySearch();
-
-  String keyEditor();
-
-  String keyHelp();
-
-  String sectionJumping();
-
-  String jumpAllOpen();
-
-  String jumpAllMerged();
-
-  String jumpAllAbandoned();
-
-  String jumpMine();
-
-  String jumpMineWatched();
-
-  String jumpMineStarred();
-
-  String jumpMineDraftComments();
-
-  String projectAccessError();
-
-  String projectAccessProposeForReviewHint();
-
-  String userCannotVoteToolTip();
-
-  String stringListPanelAdd();
-
-  String stringListPanelDelete();
-
-  String stringListPanelUp();
-
-  String stringListPanelDown();
-
-  String searchDropdownChanges();
-
-  String searchDropdownDoc();
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
deleted file mode 100644
index 2819d22..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritConstants.properties
+++ /dev/null
@@ -1,121 +0,0 @@
-menuSignIn = Sign In
-menuRegister = Register
-reportBug = Report Bug
-loadingPlugins = Loading plugins ...
-
-signInDialogTitle = Code Review - Sign In
-signInDialogGoAnonymous = Go Anonymous
-
-linkIdentityDialogTitle = Code Review - Link Identity
-registerDialogTitle = Code Review - Register New Account
-loginTypeUnsupported = Sign in is not available.
-
-errorTitle = Code Review - Error
-errorDialogContinue = Continue
-warnTitle = Code Review - Warning
-
-confirmationDialogOk = OK
-confirmationDialogCancel = Cancel
-
-branchCreationDialogTitle = Branch Creation
-branchCreationConfirmationMessage = The following branch was successfully created:
-
-tagCreationDialogTitle = Tag Creation
-tagCreationConfirmationMessage = The following tag was successfully created:
-
-branchDeletionDialogTitle = Branch Deletion
-branchDeletionConfirmationMessage = Do you really want to delete the following branches?
-
-tagDeletionDialogTitle = Tag Deletion
-tagDeletionConfirmationMessage = Do you really want to delete the following tags?
-
-newUi = Switch to New UI
-
-notSignedInTitle = Code Review - Session Expired
-notSignedInBody = <b>Session Expired</b>\
-<p>You are no longer signed in to Gerrit Code Review.</p>\
-<p>To continue, please sign-in again.</p>
-
-notFoundTitle = Not Found
-notFoundBody = The page you requested was not found, or you do not have permission to view this page.
-noSuchAccountTitle = Code Review - Unknown User
-
-noSuchGroupTitle = Code Review - Unknown Group
-
-inactiveAccountBody = This user is currently inactive.
-
-labelNotApplicable = Label not applicable
-
-menuAll = All
-menuAllOpen = Open
-menuAllMerged = Merged
-menuAllAbandoned = Abandoned
-
-menuMine = My
-menuMyChanges = Changes
-menuMyStarredChanges = Starred Changes
-menuMyWatchedChanges = Watched Changes
-menuMyDraftComments = Draft Comments
-
-menuDiff = Differences
-menuDiffCommit = Commit Message
-menuDiffPreferences = Preferences
-menuDiffPatchSets = Patch Sets
-menuDiffFiles = Files
-
-menuProjects = Projects
-menuProjectsList = List
-menuProjectsInfo = General
-menuProjectsBranches = Branches
-menuProjectsTags = Tags
-menuProjectsAccess = Access
-menuProjectsDashboards = Dashboards
-menuProjectsCreate = Create New Project
-
-menuPeople = People
-menuPeopleGroupsList = List Groups
-menuPeopleGroupsCreate = Create New Group
-
-menuPlugins = Plugins
-menuPluginsInstalled = Installed
-
-menuDocumentation = Documentation
-menuDocumentationTOC = Table of Contents
-menuDocumentationSearch = Searching
-menuDocumentationUpload = Uploading
-menuDocumentationAccess = Access Controls
-menuDocumentationAPI = REST API
-menuDocumentationProjectOwnerGuide = Project Owner Guide
-
-searchHint = Search term
-searchButton = Search
-
-rpcStatusWorking = Working ...
-
-sectionNavigation = Navigation
-sectionActions = Actions
-keySearch = Search
-keyEditor = Open Inline Editor
-keyHelp = Press '?' to view keyboard shortcuts
-
-sectionJumping = Jumping
-jumpAllOpen = Go to all open changes
-jumpAllMerged = Go to all merged changes
-jumpAllAbandoned = Go to all abandoned changes
-jumpMine = Go to my dashboard
-jumpMineWatched = Go to watched changes
-jumpMineStarred = Go to starred changes
-jumpMineDraftComments = Go to draft comments
-
-projectAccessError = You don't have permissions to modify the access rights for the following refs:
-projectAccessProposeForReviewHint = You may propose these modifications to the project owners by clicking on 'Save for Review'.
-
-userCannotVoteToolTip = User cannot vote in this category
-
-stringListPanelAdd = Add
-stringListPanelDelete = Delete
-stringListPanelUp = Up
-stringListPanelDown = Down
-
-searchDropdownChanges = Changes
-searchDropdownDoc = Docs
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
deleted file mode 100644
index 968104c..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritCss.java
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gwt.resources.client.CssResource;
-
-public interface GerritCss extends CssResource {
-  String accountDashboard();
-
-  String accountInfoBlock();
-
-  String accountLinkPanel();
-
-  String accountPassword();
-
-  String accountUsername();
-
-  String activeRow();
-
-  String addBranch();
-
-  String addMemberTextBox();
-
-  String addSshKeyPanel();
-
-  String addWatchPanel();
-
-  String avatarInfoPanel();
-
-  String bottomheader();
-
-  String branchTableDeleteButton();
-
-  String branchTablePrevNextLinks();
-
-  String cAPPROVAL();
-
-  String cASSIGNEE();
-
-  String cASSIGNEDTOME();
-
-  String cLastUpdate();
-
-  String cOWNER();
-
-  String cSIZE();
-
-  String cSUBJECT();
-
-  String cSTATUS();
-
-  String changeSize();
-
-  String changeTable();
-
-  String changeTablePrevNextLinks();
-
-  String commentedActionDialog();
-
-  String commentedActionMessage();
-
-  String contributorAgreementAlreadySubmitted();
-
-  String contributorAgreementButton();
-
-  String contributorAgreementLegal();
-
-  String contributorAgreementShortDescription();
-
-  String createProjectPanel();
-
-  String dataCell();
-
-  String dataCellHidden();
-
-  String dataHeader();
-
-  String dataHeaderHidden();
-
-  String downloadBox();
-
-  String downloadBoxTable();
-
-  String downloadBoxTableCommandColumn();
-
-  String downloadBoxSpacer();
-
-  String downloadBoxScheme();
-
-  String downloadBoxCopyLabel();
-
-  String downloadLink();
-
-  String downloadLinkCopyLabel();
-
-  String downloadLinkHeader();
-
-  String downloadLinkHeaderGap();
-
-  String downloadLinkList();
-
-  String downloadLink_Active();
-
-  String editHeadButton();
-
-  String emptySection();
-
-  String errorDialog();
-
-  String errorDialogButtons();
-
-  String errorDialogErrorType();
-
-  String errorDialogGlass();
-
-  String errorDialogTitle();
-
-  String extensionPanel();
-
-  String loadingPluginsDialog();
-
-  String gerritBody();
-
-  String gerritTopMenu();
-
-  String greenCheckClass();
-
-  String groupDescriptionPanel();
-
-  String groupIncludesTable();
-
-  String groupMembersTable();
-
-  String groupName();
-
-  String groupNamePanel();
-
-  String groupNameTextBox();
-
-  String groupOptionsPanel();
-
-  String groupOwnerPanel();
-
-  String groupOwnerTextBox();
-
-  String groupUUIDPanel();
-
-  String header();
-
-  String iconCell();
-
-  String iconHeader();
-
-  String identityUntrustedExternalId();
-
-  String infoBlock();
-
-  String inputFieldTypeHint();
-
-  String labelNotApplicable();
-
-  String leftMostCell();
-
-  String link();
-
-  String linkMenuBar();
-
-  String linkMenuItemNotLast();
-
-  String maxObjectSizeLimitEffectiveLabel();
-
-  String menuBarUserName();
-
-  String menuBarUserNameAvatar();
-
-  String menuBarUserNameFocusPanel();
-
-  String menuBarUserNamePanel();
-
-  String menuItem();
-
-  String menuScreenMenuBar();
-
-  String needsReview();
-
-  String negscore();
-
-  String oauthExpires();
-
-  String oauthInfoBlock();
-
-  String oauthPanel();
-
-  String oauthPanelCookieEntry();
-
-  String oauthPanelCookieHeading();
-
-  String oauthPanelNetRCEntry();
-
-  String oauthPanelNetRCHeading();
-
-  String oauthToken();
-
-  String pagingLink();
-
-  String patchSetActions();
-
-  String pluginProjectConfigInheritedValue();
-
-  String pluginsTable();
-
-  String posscore();
-
-  String projectActions();
-
-  String projectFilterLabel();
-
-  String projectFilterPanel();
-
-  String projectNameColumn();
-
-  String queryIcon();
-
-  String rebaseContentPanel();
-
-  String rebaseSuggestBox();
-
-  String registerScreenExplain();
-
-  String registerScreenNextLinks();
-
-  String registerScreenSection();
-
-  String rpcStatus();
-
-  String screen();
-
-  String screenHeader();
-
-  String searchPanel();
-
-  String suggestBoxPopup();
-
-  String sectionHeader();
-
-  String singleLine();
-
-  String smallHeading();
-
-  String specialBranchDataCell();
-
-  String specialBranchIconCell();
-
-  String sshHostKeyPanel();
-
-  String sshHostKeyPanelFingerprintData();
-
-  String sshHostKeyPanelHeading();
-
-  String sshHostKeyPanelKnownHostEntry();
-
-  String sshKeyPanelEncodedKey();
-
-  String sshKeyPanelInvalid();
-
-  String sshKeyTable();
-
-  String stringListPanelButtons();
-
-  String topmenu();
-
-  String topmenuMenuLeft();
-
-  String topmenuMenuRight();
-
-  String topmenuTDglue();
-
-  String topmenuTDmenu();
-
-  String topmost();
-
-  String userInfoPopup();
-
-  String usernameField();
-
-  String watchedProjectFilter();
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.java
deleted file mode 100644
index 980529a..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gwt.i18n.client.Messages;
-
-public interface GerritMessages extends Messages {
-  String windowTitle1(String hostname);
-
-  String windowTitle2(String section, String hostname);
-
-  String poweredBy(String version);
-
-  String noSuchAccountMessage(String who);
-
-  String noSuchGroupMessage(String who);
-
-  String nameAlreadyUsedBody(String alreadyUsedName);
-
-  String branchCreationFailed(String branchName, String error);
-
-  String invalidBranchName(String branchName);
-
-  String invalidRevision(String revision);
-
-  String branchCreationNotAllowedUnderRefnamePrefix(String refnamePrefix);
-
-  String branchAlreadyExists(String branchName);
-
-  String branchCreationConflict(String branchName, String existingBranchName);
-
-  String pluginFailed(String scriptPath);
-
-  String cannotDownloadPlugin(String scriptPath);
-
-  String parentUpdateFailed(String message);
-
-  String fileCount(int fileNumber, int fileCount);
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties
deleted file mode 100644
index b2d67b8..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritMessages.properties
+++ /dev/null
@@ -1,21 +0,0 @@
-windowTitle1 = {0} Code Review
-windowTitle2 = {0} | {1} Code Review
-poweredBy = Powered by <a href="https://www.gerritcodereview.com/" target="_blank">Gerrit Code Review</a> ({0})
-
-noSuchAccountMessage = {0} is not a registered user.
-noSuchGroupMessage = Group {0} does not exist or is not visible to you.
-nameAlreadyUsedBody = The name {0} is already in use.
-
-branchCreationFailed = Creating branch {0} failed. Error: {1}
-invalidBranchName = The branch name {0} is not valid.
-invalidRevision = The revision {0} is not valid.
-branchCreationNotAllowedUnderRefnamePrefix = Branch creation is not allowed under {0}.
-branchAlreadyExists = A branch with the name {0} already exists.
-branchCreationConflict = Cannot create branch {0} since it conflicts with branch {1}.
-
-pluginFailed = Plugin "{0}" failed to load
-cannotDownloadPlugin = Cannot load plugin from {0}
-
-parentUpdateFailed = Setting parent project failed: {0}
-
-fileCount = File {0} of {1}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
deleted file mode 100644
index 01be2f2..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/GerritResources.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gwt.resources.client.CssResource;
-
-public interface GerritResources extends Resources {
-  @Source("gerrit.css")
-  GerritCss css();
-
-  @Source("gwt_override.css")
-  CssResource gwt_override();
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/HostPageDataService.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/HostPageDataService.java
deleted file mode 100644
index bd3d483..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/HostPageDataService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gerrit.common.data.HostPageData;
-import com.google.gwtjsonrpc.common.AsyncCallback;
-import com.google.gwtjsonrpc.common.HostPageCache;
-import com.google.gwtjsonrpc.common.RemoteJsonService;
-import com.google.gwtjsonrpc.common.RpcImpl;
-import com.google.gwtjsonrpc.common.RpcImpl.Version;
-
-@RpcImpl(version = Version.V2_0)
-interface HostPageDataService extends RemoteJsonService {
-  @HostPageCache(name = "gerrit_hostpagedata", once = true)
-  void load(AsyncCallback<HostPageData> callback);
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/JumpKeys.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/JumpKeys.java
deleted file mode 100644
index a4879ca..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/JumpKeys.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gerrit.common.PageLinks;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.ui.Widget;
-import com.google.gwtexpui.globalkey.client.CompoundKeyCommand;
-import com.google.gwtexpui.globalkey.client.GlobalKey;
-import com.google.gwtexpui.globalkey.client.KeyCommand;
-import com.google.gwtexpui.globalkey.client.KeyCommandSet;
-
-public class JumpKeys {
-  private static HandlerRegistration activeHandler;
-  private static KeyCommandSet keys;
-  private static Widget bodyWidget;
-
-  public static void enable(boolean enable) {
-    if (enable && activeHandler == null) {
-      activeHandler = GlobalKey.add(bodyWidget, keys);
-    } else if (!enable && activeHandler != null) {
-      activeHandler.removeHandler();
-      activeHandler = null;
-    }
-  }
-
-  static void register(Widget body) {
-    final KeyCommandSet jumps = new KeyCommandSet();
-
-    jumps.add(
-        new KeyCommand(0, 'o', Gerrit.C.jumpAllOpen()) {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            Gerrit.display(PageLinks.toChangeQuery("status:open"));
-          }
-        });
-    jumps.add(
-        new KeyCommand(0, 'm', Gerrit.C.jumpAllMerged()) {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            Gerrit.display(PageLinks.toChangeQuery("status:merged"));
-          }
-        });
-    jumps.add(
-        new KeyCommand(0, 'a', Gerrit.C.jumpAllAbandoned()) {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            Gerrit.display(PageLinks.toChangeQuery("status:abandoned"));
-          }
-        });
-
-    if (Gerrit.isSignedIn()) {
-      jumps.add(
-          new KeyCommand(0, 'i', Gerrit.C.jumpMine()) {
-            @Override
-            public void onKeyPress(KeyPressEvent event) {
-              Gerrit.display(PageLinks.MINE);
-            }
-          });
-      jumps.add(
-          new KeyCommand(0, 'c', Gerrit.C.jumpMineDraftComments()) {
-            @Override
-            public void onKeyPress(KeyPressEvent event) {
-              Gerrit.display(PageLinks.toChangeQuery("has:draft"));
-            }
-          });
-      jumps.add(
-          new KeyCommand(0, 'w', Gerrit.C.jumpMineWatched()) {
-            @Override
-            public void onKeyPress(KeyPressEvent event) {
-              Gerrit.display(PageLinks.toChangeQuery("is:watched status:open"));
-            }
-          });
-      jumps.add(
-          new KeyCommand(0, 's', Gerrit.C.jumpMineStarred()) {
-            @Override
-            public void onKeyPress(KeyPressEvent event) {
-              Gerrit.display(PageLinks.toChangeQuery("is:starred"));
-            }
-          });
-    }
-
-    keys = new KeyCommandSet(Gerrit.C.sectionJumping());
-    keys.add(new CompoundKeyCommand(0, 'g', "", jumps));
-    bodyWidget = body;
-    activeHandler = GlobalKey.add(body, keys);
-  }
-
-  private JumpKeys() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.java
deleted file mode 100644
index 36fa6e8..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.java
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (C) 2014 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.client;
-
-import com.google.gerrit.common.data.HostPageData;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.uibinder.client.UiBinder;
-import com.google.gwt.uibinder.client.UiField;
-import com.google.gwt.uibinder.client.UiHandler;
-import com.google.gwt.user.client.Cookies;
-import com.google.gwt.user.client.ui.Anchor;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.HTMLPanel;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwtexpui.safehtml.client.SafeHtml;
-import com.google.gwtexpui.safehtml.client.SafeHtmlBuilder;
-import java.util.ArrayList;
-import java.util.List;
-
-/** Displays pending messages from the server. */
-class MessageOfTheDayBar extends Composite {
-  interface Binder extends UiBinder<HTMLPanel, MessageOfTheDayBar> {}
-
-  private static final Binder uiBinder = GWT.create(Binder.class);
-
-  private final List<HostPageData.Message> motd;
-  @UiField HTML message;
-  @UiField Anchor dismiss;
-
-  MessageOfTheDayBar(List<HostPageData.Message> motd) {
-    this.motd = filter(motd);
-    initWidget(uiBinder.createAndBindUi(this));
-
-    SafeHtmlBuilder b = new SafeHtmlBuilder();
-    if (this.motd.size() == 1) {
-      b.append(SafeHtml.asis(this.motd.get(0).html));
-    } else {
-      for (HostPageData.Message m : this.motd) {
-        b.openDiv();
-        b.append(SafeHtml.asis(m.html));
-        b.openElement("hr");
-        b.closeSelf();
-        b.closeDiv();
-      }
-    }
-    message.setHTML(b);
-  }
-
-  void show() {
-    if (!motd.isEmpty()) {
-      RootPanel.get().add(this);
-    }
-  }
-
-  @UiHandler("dismiss")
-  void onDismiss(@SuppressWarnings("unused") ClickEvent e) {
-    removeFromParent();
-
-    for (HostPageData.Message m : motd) {
-      Cookies.setCookie(cookieName(m), "1", m.redisplay);
-    }
-  }
-
-  private static List<HostPageData.Message> filter(List<HostPageData.Message> in) {
-    List<HostPageData.Message> show = new ArrayList<>();
-    for (HostPageData.Message m : in) {
-      if (Cookies.getCookie(cookieName(m)) == null) {
-        show.add(m);
-      }
-    }
-    return show;
-  }
-
-  private static String cookieName(HostPageData.Message m) {
-    return "msg-" + m.id;
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.ui.xml
deleted file mode 100644
index 36d08b1..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/MessageOfTheDayBar.ui.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2014 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.
--->
-<ui:UiBinder
-    xmlns:ui='urn:ui:com.google.gwt.uibinder'
-    xmlns:c='urn:import:com.google.gwtexpui.globalkey.client'
-    xmlns:g='urn:import:com.google.gwt.user.client.ui'>
-  <ui:style gss='false'>
-    .popup {
-      position: fixed;
-      top: 5px;
-      left: 50%;
-      margin-left: -200px;
-      z-index: 201;
-      padding-top: 5px;
-      padding-bottom: 5px;
-      padding-left: 12px;
-      padding-right: 12px;
-      background: #FFF1A8;
-      border-radius: 10px;
-    }
-
-    @if user.agent safari {
-      .popup {
-        \-webkit-border-radius: 10px;
-      }
-    }
-    @if user.agent gecko1_8 {
-      .popup {
-        \-moz-border-radius: 10px;
-      }
-    }
-
-    .message {
-      display: inline;
-    }
-    .message a {
-      color: #222;
-      text-decoration: underline;
-    }
-    a.action {
-      color: #222;
-      text-decoration: underline;
-      display: inline-block;
-      margin-left: 0.5em;
-    }
-  </ui:style>
-  <g:HTMLPanel styleName='{style.popup}'>
-    <g:HTML ui:field='message' styleName='{style.message}'/>
-    <g:Anchor ui:field='dismiss'
-        styleName='{style.action}'
-        href='javascript:;'
-        title='Hide this message'>
-      <ui:attribute name='title'/>
-      Dismiss
-    </g:Anchor>
-  </g:HTMLPanel>
-</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotFoundScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotFoundScreen.java
deleted file mode 100644
index 29bbf85..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotFoundScreen.java
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gerrit.client.ui.Screen;
-import com.google.gwt.user.client.ui.Label;
-
-/** Displays an error message letting the user know the page doesn't exist. */
-public class NotFoundScreen extends Screen {
-  @Override
-  protected void onInitUI() {
-    super.onInitUI();
-    setPageTitle(Gerrit.C.notFoundTitle());
-    add(new Label(Gerrit.C.notFoundBody()));
-  }
-
-  @Override
-  protected void onLoad() {
-    super.onLoad();
-    display();
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotSignedInDialog.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotSignedInDialog.java
deleted file mode 100644
index cd5197a..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/NotSignedInDialog.java
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.logical.shared.CloseEvent;
-import com.google.gwt.event.logical.shared.CloseHandler;
-import com.google.gwt.user.client.History;
-import com.google.gwt.user.client.Window;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HTML;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwtexpui.globalkey.client.GlobalKey;
-
-/** A dialog box telling the user they are not signed in. */
-public class NotSignedInDialog extends PopupPanel implements CloseHandler<PopupPanel> {
-  private Button signin;
-  private boolean buttonClicked;
-
-  public NotSignedInDialog() {
-    super(/* auto hide */ false, /* modal */ true);
-    setGlassEnabled(true);
-    getGlassElement().addClassName(Gerrit.RESOURCES.css().errorDialogGlass());
-    addStyleName(Gerrit.RESOURCES.css().errorDialog());
-
-    final FlowPanel buttons = new FlowPanel();
-    signin = new Button();
-    signin.setText(Gerrit.C.menuSignIn());
-    signin.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            buttonClicked = true;
-            hide();
-            Gerrit.doSignIn(History.getToken());
-          }
-        });
-    buttons.add(signin);
-
-    final Button close = new Button();
-    close.getElement().getStyle().setProperty("marginLeft", "200px");
-    close.setText(Gerrit.C.signInDialogGoAnonymous());
-    close.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            buttonClicked = true;
-            Gerrit.deleteSessionCookie();
-            hide();
-          }
-        });
-    buttons.add(close);
-
-    Label title = new Label(Gerrit.C.notSignedInTitle());
-    title.setStyleName(Gerrit.RESOURCES.css().errorDialogTitle());
-
-    FlowPanel center = new FlowPanel();
-    center.add(title);
-    center.add(new HTML(Gerrit.C.notSignedInBody()));
-    center.add(buttons);
-    add(center);
-
-    int l = Window.getScrollLeft() + 20;
-    int t = Window.getScrollTop() + 20;
-    setPopupPosition(l, t);
-    addCloseHandler(this);
-  }
-
-  @Override
-  public void onClose(CloseEvent<PopupPanel> event) {
-    if (!buttonClicked) {
-      // the dialog was closed without one of the buttons being pressed
-      // e.g. the user pressed ESC to close the dialog
-      Gerrit.deleteSessionCookie();
-    }
-  }
-
-  @Override
-  public void center() {
-    show();
-    GlobalKey.dialog(this);
-    signin.setFocus(true);
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/RangeInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/RangeInfo.java
deleted file mode 100644
index 42454a3..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/RangeInfo.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2016 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.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class RangeInfo extends JavaScriptObject {
-  public final native int start() /*-{ return this.start; }-*/;
-
-  public final native int end() /*-{ return this.end; }-*/;
-
-  protected RangeInfo() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/RpcStatus.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/RpcStatus.java
deleted file mode 100644
index 4153439..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/RpcStatus.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (C) 2008 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.client;
-
-import com.google.gwt.user.client.ui.InlineLabel;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.RootPanel;
-import com.google.gwtjsonrpc.client.event.RpcCompleteEvent;
-import com.google.gwtjsonrpc.client.event.RpcCompleteHandler;
-import com.google.gwtjsonrpc.client.event.RpcStartEvent;
-import com.google.gwtjsonrpc.client.event.RpcStartHandler;
-
-public class RpcStatus implements RpcStartHandler, RpcCompleteHandler {
-  public static RpcStatus INSTANCE;
-
-  private static int hideDepth;
-
-  /** Execute code, hiding the RPCs they execute from being shown visually. */
-  public static void hide(Runnable run) {
-    try {
-      hideDepth++;
-      run.run();
-    } finally {
-      hideDepth--;
-    }
-  }
-
-  private final Label loading;
-  private int activeCalls;
-
-  RpcStatus() {
-    loading = new InlineLabel();
-    loading.setText(Gerrit.C.rpcStatusWorking());
-    loading.setStyleName(Gerrit.RESOURCES.css().rpcStatus());
-    loading.setVisible(false);
-    RootPanel.get().add(loading);
-  }
-
-  @Override
-  public void onRpcStart(RpcStartEvent event) {
-    onRpcStart();
-  }
-
-  public void onRpcStart() {
-    if (++activeCalls == 1) {
-      if (hideDepth == 0) {
-        loading.setVisible(true);
-      }
-    }
-  }
-
-  @Override
-  public void onRpcComplete(RpcCompleteEvent event) {
-    onRpcComplete();
-  }
-
-  public void onRpcComplete() {
-    if (--activeCalls == 0) {
-      loading.setVisible(false);
-    }
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchPanel.java
deleted file mode 100644
index 406ab4e..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchPanel.java
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (C) 2009 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.client;
-
-import com.google.gerrit.client.changes.QueryScreen;
-import com.google.gerrit.client.ui.HintTextBox;
-import com.google.gerrit.common.PageLinks;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.shared.HandlerRegistration;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.Composite;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.ListBox;
-import com.google.gwt.user.client.ui.SuggestBox;
-import com.google.gwt.user.client.ui.SuggestOracle.Suggestion;
-import com.google.gwtexpui.globalkey.client.GlobalKey;
-import com.google.gwtexpui.globalkey.client.KeyCommand;
-
-class SearchPanel extends Composite {
-  private final HintTextBox searchBox;
-  private final ListBox dropdown;
-  private HandlerRegistration regFocus;
-
-  SearchPanel() {
-    final FlowPanel body = new FlowPanel();
-    initWidget(body);
-    setStyleName(Gerrit.RESOURCES.css().searchPanel());
-
-    searchBox = new HintTextBox();
-    final MySuggestionDisplay suggestionDisplay = new MySuggestionDisplay();
-    searchBox.addKeyPressHandler(
-        new KeyPressHandler() {
-          @Override
-          public void onKeyPress(KeyPressEvent event) {
-            if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
-              if (!suggestionDisplay.isSuggestionSelected) {
-                doSearch();
-              }
-            }
-          }
-        });
-
-    if (Gerrit.hasDocSearch()) {
-      dropdown = new ListBox();
-      dropdown.setStyleName("searchDropdown");
-      dropdown.addItem(Gerrit.C.searchDropdownChanges());
-      dropdown.addItem(Gerrit.C.searchDropdownDoc());
-      dropdown.setVisibleItemCount(1);
-      dropdown.setSelectedIndex(0);
-    } else {
-      // Doc search is NOT available.
-      dropdown = null;
-    }
-
-    final SuggestBox suggestBox =
-        new SuggestBox(new SearchSuggestOracle(), searchBox, suggestionDisplay);
-    searchBox.setStyleName("searchTextBox");
-    searchBox.setVisibleLength(70);
-    searchBox.setHintText(Gerrit.C.searchHint());
-
-    final Button searchButton = new Button(Gerrit.C.searchButton());
-    searchButton.setStyleName("searchButton");
-    searchButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            doSearch();
-          }
-        });
-
-    body.add(suggestBox);
-    if (dropdown != null) {
-      body.add(dropdown);
-    }
-    body.add(searchButton);
-  }
-
-  void setText(String query) {
-    searchBox.setText(query);
-  }
-
-  @Override
-  protected void onLoad() {
-    super.onLoad();
-    if (regFocus == null) {
-      regFocus =
-          GlobalKey.addApplication(
-              this,
-              new KeyCommand(0, '/', Gerrit.C.keySearch()) {
-                @Override
-                public void onKeyPress(KeyPressEvent event) {
-                  event.preventDefault();
-                  searchBox.setFocus(true);
-                  searchBox.selectAll();
-                }
-              });
-    }
-  }
-
-  @Override
-  protected void onUnload() {
-    if (regFocus != null) {
-      regFocus.removeHandler();
-      regFocus = null;
-    }
-  }
-
-  private void doSearch() {
-    final String query = searchBox.getText().trim();
-    if ("".equals(query)) {
-      return;
-    }
-
-    searchBox.setFocus(false);
-
-    if (dropdown != null && dropdown.getSelectedValue().equals(Gerrit.C.searchDropdownDoc())) {
-      // doc
-      Gerrit.display(PageLinks.toDocumentationQuery(query));
-    } else {
-      // changes
-      if (query.matches("^[1-9][0-9]*$")) {
-        // Query is a change number. Project can't be supplied.
-        Gerrit.display(PageLinks.toChange(null, Change.Id.parse(query)));
-      } else {
-        Gerrit.display(PageLinks.toChangeQuery(query), QueryScreen.forQuery(query));
-      }
-    }
-  }
-
-  private static class MySuggestionDisplay extends SuggestBox.DefaultSuggestionDisplay {
-    private boolean isSuggestionSelected;
-
-    private MySuggestionDisplay() {
-      super();
-
-      getPopupPanel().addStyleName(Gerrit.RESOURCES.css().suggestBoxPopup());
-    }
-
-    @Override
-    protected Suggestion getCurrentSelection() {
-      Suggestion currentSelection = super.getCurrentSelection();
-      isSuggestionSelected = currentSelection != null;
-      return currentSelection;
-    }
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchSuggestOracle.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchSuggestOracle.java
deleted file mode 100644
index e74ed71..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/SearchSuggestOracle.java
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright (C) 2012 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.client;
-
-import com.google.gerrit.client.ui.AccountGroupSuggestOracle;
-import com.google.gerrit.client.ui.AccountSuggestOracle;
-import com.google.gerrit.client.ui.ProjectNameSuggestOracle;
-import com.google.gwt.user.client.ui.SuggestOracle;
-import com.google.gwtexpui.safehtml.client.HighlightSuggestOracle;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.TreeSet;
-
-public class SearchSuggestOracle extends HighlightSuggestOracle {
-  private static final List<ParamSuggester> paramSuggester =
-      Arrays.asList(
-          new ParamSuggester(
-              Arrays.asList("project:", "p:", "parentproject:"), new ProjectNameSuggestOracle()),
-          new ParamSuggester(
-              Arrays.asList(
-                  "owner:",
-                  "o:",
-                  "reviewer:",
-                  "r:",
-                  "commentby:",
-                  "reviewedby:",
-                  "author:",
-                  "committer:",
-                  "from:",
-                  "assignee:",
-                  "cc:"),
-              new AccountSuggestOracle() {
-                @Override
-                public void onRequestSuggestions(Request request, Callback done) {
-                  super.onRequestSuggestions(
-                      request,
-                      new Callback() {
-                        @Override
-                        public void onSuggestionsReady(final Request request, Response response) {
-                          if ("self".startsWith(request.getQuery())) {
-                            final ArrayList<SuggestOracle.Suggestion> r =
-                                new ArrayList<>(response.getSuggestions().size() + 1);
-                            r.add(
-                                new SuggestOracle.Suggestion() {
-                                  @Override
-                                  public String getDisplayString() {
-                                    return getReplacementString();
-                                  }
-
-                                  @Override
-                                  public String getReplacementString() {
-                                    return "self";
-                                  }
-                                });
-                            r.addAll(response.getSuggestions());
-                            response.setSuggestions(r);
-                          }
-                          done.onSuggestionsReady(request, response);
-                        }
-                      });
-                }
-              }),
-          new ParamSuggester(
-              Arrays.asList("ownerin:", "reviewerin:"), new AccountGroupSuggestOracle()));
-
-  private static final TreeSet<String> suggestions = new TreeSet<>();
-
-  static {
-    suggestions.add("age:");
-    suggestions.add("age:1week"); // Give an example age
-
-    suggestions.add("change:");
-
-    suggestions.add("owner:");
-    suggestions.add("owner:self");
-    suggestions.add("ownerin:");
-    suggestions.add("author:");
-    suggestions.add("committer:");
-    suggestions.add("assignee:");
-
-    suggestions.add("reviewer:");
-    suggestions.add("reviewer:self");
-    suggestions.add("reviewerin:");
-    suggestions.add("reviewedby:");
-
-    suggestions.add("commit:");
-    suggestions.add("comment:");
-    suggestions.add("message:");
-    suggestions.add("commentby:");
-    suggestions.add("from:");
-    suggestions.add("file:");
-    suggestions.add("conflicts:");
-    suggestions.add("project:");
-    suggestions.add("projects:");
-    suggestions.add("parentproject:");
-    suggestions.add("branch:");
-    suggestions.add("topic:");
-    suggestions.add("intopic:");
-    suggestions.add("ref:");
-    suggestions.add("tr:");
-    suggestions.add("bug:");
-    suggestions.add("label:");
-    suggestions.add("query:");
-    suggestions.add("has:");
-    suggestions.add("has:draft");
-    suggestions.add("has:edit");
-    suggestions.add("has:star");
-    suggestions.add("has:stars");
-    suggestions.add("has:unresolved");
-    suggestions.add("star:");
-
-    suggestions.add("is:");
-    suggestions.add("is:starred");
-    suggestions.add("is:watched");
-    suggestions.add("is:reviewed");
-    suggestions.add("is:owner");
-    suggestions.add("is:reviewer");
-    suggestions.add("is:open");
-    suggestions.add("is:pending");
-    suggestions.add("is:private");
-    suggestions.add("is:closed");
-    suggestions.add("is:merged");
-    suggestions.add("is:abandoned");
-    suggestions.add("is:mergeable");
-    suggestions.add("is:ignored");
-    suggestions.add("is:wip");
-    suggestions.add("is:assigned");
-    suggestions.add("is:submittable");
-
-    suggestions.add("status:");
-    suggestions.add("status:open");
-    suggestions.add("status:pending");
-    suggestions.add("status:reviewed");
-    suggestions.add("status:closed");
-    suggestions.add("status:merged");
-    suggestions.add("status:abandoned");
-
-    suggestions.add("added:");
-    suggestions.add("deleted:");
-    suggestions.add("delta:");
-    suggestions.add("size:");
-
-    suggestions.add("unresolved:");
-
-    suggestions.add("revertof:");
-
-    if (Gerrit.isNoteDbEnabled()) {
-      suggestions.add("cc:");
-      suggestions.add("hashtag:");
-    }
-
-    suggestions.add("is:assigned");
-    suggestions.add("is:unassigned");
-    suggestions.add("assignee:");
-
-    suggestions.add("AND");
-    suggestions.add("OR");
-    suggestions.add("NOT");
-  }
-
-  @Override
-  public void requestDefaultSuggestions(Request request, Callback done) {
-    final ArrayList<SearchSuggestion> r = new ArrayList<>();
-    // No text - show some default suggestions.
-    r.add(new SearchSuggestion("status:open", "status:open"));
-    r.add(new SearchSuggestion("age:1week", "age:1week"));
-    if (Gerrit.isSignedIn()) {
-      r.add(new SearchSuggestion("owner:self", "owner:self"));
-    }
-    done.onSuggestionsReady(request, new Response(r));
-  }
-
-  @Override
-  protected void onRequestSuggestions(Request request, Callback done) {
-    final String query = request.getQuery();
-
-    final String lastWord = getLastWord(query);
-    if (lastWord == null) {
-      // Starting a new word - don't show suggestions yet.
-      done.onSuggestionsReady(request, null);
-      return;
-    }
-
-    for (ParamSuggester ps : paramSuggester) {
-      if (ps.applicable(lastWord)) {
-        ps.suggest(lastWord, request, done);
-        return;
-      }
-    }
-
-    final ArrayList<SearchSuggestion> r = new ArrayList<>();
-    for (String suggestion : suggestions.tailSet(lastWord)) {
-      if ((lastWord.length() < suggestion.length()) && suggestion.startsWith(lastWord)) {
-        if (suggestion.contains("self") && !Gerrit.isSignedIn()) {
-          continue;
-        }
-        r.add(new SearchSuggestion(suggestion, query + suggestion.substring(lastWord.length())));
-      }
-    }
-    done.onSuggestionsReady(request, new Response(r));
-  }
-
-  private String getLastWord(String query) {
-    final int lastSpace = query.lastIndexOf(' ');
-    if (lastSpace == query.length() - 1) {
-      return null;
-    }
-    if (lastSpace == -1) {
-      return query;
-    }
-    return query.substring(lastSpace + 1);
-  }
-
-  @Override
-  protected String getQueryPattern(String query) {
-    return super.getQueryPattern(getLastWord(query));
-  }
-
-  @Override
-  protected boolean isHTML() {
-    return true;
-  }
-
-  private static class SearchSuggestion implements SuggestOracle.Suggestion {
-    private final String suggestion;
-    private final String fullQuery;
-
-    SearchSuggestion(String suggestion, String fullQuery) {
-      this.suggestion = suggestion;
-      // Add a space to the query if it is a complete operation (e.g.
-      // "status:open") so the user can keep on typing.
-      this.fullQuery = fullQuery.endsWith(":") ? fullQuery : fullQuery + " ";
-    }
-
-    @Override
-    public String getDisplayString() {
-      return suggestion;
-    }
-
-    @Override
-    public String getReplacementString() {
-      return fullQuery;
-    }
-  }
-
-  private static class ParamSuggester {
-    private final List<String> operators;
-    private final SuggestOracle parameterSuggestionOracle;
-
-    ParamSuggester(List<String> operators, SuggestOracle parameterSuggestionOracle) {
-      this.operators = operators;
-      this.parameterSuggestionOracle = parameterSuggestionOracle;
-    }
-
-    boolean applicable(String query) {
-      final String operator = getApplicableOperator(query, operators);
-      return operator != null && query.length() > operator.length();
-    }
-
-    private String getApplicableOperator(String lastWord, List<String> operators) {
-      for (String operator : operators) {
-        if (lastWord.startsWith(operator)) {
-          return operator;
-        }
-      }
-      return null;
-    }
-
-    void suggest(String lastWord, Request request, Callback done) {
-      final String operator = getApplicableOperator(lastWord, operators);
-      parameterSuggestionOracle.requestSuggestions(
-          new Request(lastWord.substring(operator.length()), request.getLimit()),
-          new Callback() {
-            @Override
-            public void onSuggestionsReady(Request req, Response response) {
-              final String query = request.getQuery();
-              final List<SearchSuggestOracle.Suggestion> r =
-                  new ArrayList<>(response.getSuggestions().size());
-              for (SearchSuggestOracle.Suggestion s : response.getSuggestions()) {
-                r.add(
-                    new SearchSuggestion(
-                        s.getDisplayString(),
-                        query.substring(0, query.length() - lastWord.length())
-                            + operator
-                            + quoteIfNeeded(s.getReplacementString())));
-              }
-              done.onSuggestionsReady(request, new Response(r));
-            }
-
-            private String quoteIfNeeded(String s) {
-              if (!s.matches("^\\S*$")) {
-                return "\"" + s + "\"";
-              }
-              return s;
-            }
-          });
-    }
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/StringListPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/StringListPanel.java
deleted file mode 100644
index f771fee..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/StringListPanel.java
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright (C) 2014 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.client;
-
-import com.google.gerrit.client.ui.NavigationTable;
-import com.google.gerrit.client.ui.OnEditEnabler;
-import com.google.gerrit.client.ui.SmallHeading;
-import com.google.gwt.event.dom.client.ClickEvent;
-import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.event.dom.client.KeyPressEvent;
-import com.google.gwt.event.dom.client.KeyPressHandler;
-import com.google.gwt.event.logical.shared.ValueChangeEvent;
-import com.google.gwt.event.logical.shared.ValueChangeHandler;
-import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.ui.Button;
-import com.google.gwt.user.client.ui.CheckBox;
-import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter;
-import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.FocusWidget;
-import com.google.gwt.user.client.ui.HasEnabled;
-import com.google.gwt.user.client.ui.HorizontalPanel;
-import com.google.gwt.user.client.ui.Image;
-import com.google.gwt.user.client.ui.ImageResourceRenderer;
-import com.google.gwtexpui.globalkey.client.NpTextBox;
-import java.util.ArrayList;
-import java.util.List;
-
-public class StringListPanel extends FlowPanel implements HasEnabled {
-  private final StringListTable t;
-  private HorizontalPanel titlePanel;
-  protected final HorizontalPanel buttonPanel;
-  private final Button deleteButton;
-  private Image info;
-  protected FocusWidget widget;
-
-  public StringListPanel(String title, List<String> fieldNames, FocusWidget w, boolean autoSort) {
-    widget = w;
-    if (title != null) {
-      titlePanel = new HorizontalPanel();
-      SmallHeading titleLabel = new SmallHeading(title);
-      titlePanel.add(titleLabel);
-      add(titlePanel);
-    }
-
-    t = new StringListTable(fieldNames, autoSort);
-    add(t);
-
-    buttonPanel = new HorizontalPanel();
-    buttonPanel.setStyleName(Gerrit.RESOURCES.css().stringListPanelButtons());
-    deleteButton = new Button(Gerrit.C.stringListPanelDelete());
-    deleteButton.setEnabled(false);
-    deleteButton.addClickHandler(
-        new ClickHandler() {
-          @Override
-          public void onClick(ClickEvent event) {
-            widget.setEnabled(true);
-            t.deleteChecked();
-          }
-        });
-    buttonPanel.add(deleteButton);
-    add(buttonPanel);
-  }
-
-  public void display(List<List<String>> values) {
-    t.display(values);
-  }
-
-  public void setInfo(String msg) {
-    if (info == null && titlePanel != null) {
-      info = new Image(Gerrit.RESOURCES.info());
-      titlePanel.add(info);
-    }
-    if (info != null) {
-      info.setTitle(msg);
-    }
-  }
-
-  public List<List<String>> getValues() {
-    return t.getValues();
-  }
-
-  public List<String> getValues(int i) {
-    List<List<String>> allValuesList = getValues();
-    List<String> singleValueList = new ArrayList<>(allValuesList.size());
-    for (List<String> values : allValuesList) {
-      singleValueList.add(values.get(i));
-    }
-    return singleValueList;
-  }
-
-  private class StringListTable extends NavigationTable<List<String>> {
-    private final Button addButton;
-    private final List<NpTextBox> inputs;
-    private final boolean autoSort;
-
-    StringListTable(List<String> names, boolean autoSort) {
-      this.autoSort = autoSort;
-
-      addButton = new Button(new ImageResourceRenderer().render(Gerrit.RESOURCES.listAdd()));
-      addButton.setTitle(Gerrit.C.stringListPanelAdd());
-      OnEditEnabler e = new OnEditEnabler(addButton);
-      inputs = new ArrayList<>();
-
-      FlexCellFormatter fmt = table.getFlexCellFormatter();
-      fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().iconHeader());
-      fmt.addStyleName(0, 0, Gerrit.RESOURCES.css().leftMostCell());
-      for (int i = 0; i < names.size(); i++) {
-        fmt.addStyleName(0, i + 1, Gerrit.RESOURCES.css().dataHeader());
-        table.setText(0, i + 1, names.get(i));
-
-        NpTextBox input = new NpTextBox();
-        input.setVisibleLength(35);
-        input.addKeyPressHandler(
-            new KeyPressHandler() {
-              @Override
-              public void onKeyPress(KeyPressEvent event) {
-                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
-                  widget.setEnabled(true);
-                  add();
-                }
-              }
-            });
-        inputs.add(input);
-        fmt.addStyleName(1, i + 1, Gerrit.RESOURCES.css().dataHeader());
-        table.setWidget(1, i + 1, input);
-        e.listenTo(input);
-      }
-      addButton.setEnabled(false);
-
-      addButton.addClickHandler(
-          new ClickHandler() {
-            @Override
-            public void onClick(ClickEvent event) {
-              widget.setEnabled(true);
-              add();
-            }
-          });
-      fmt.addStyleName(1, 0, Gerrit.RESOURCES.css().iconHeader());
-      fmt.addStyleName(1, 0, Gerrit.RESOURCES.css().leftMostCell());
-      table.setWidget(1, 0, addButton);
-
-      if (!autoSort) {
-        fmt.addStyleName(0, names.size() + 1, Gerrit.RESOURCES.css().iconHeader());
-        fmt.addStyleName(0, names.size() + 2, Gerrit.RESOURCES.css().iconHeader());
-        fmt.addStyleName(1, names.size() + 1, Gerrit.RESOURCES.css().iconHeader());
-        fmt.addStyleName(1, names.size() + 2, Gerrit.RESOURCES.css().iconHeader());
-      }
-    }
-
-    void display(List<List<String>> values) {
-      for (int row = 2; row < table.getRowCount(); row++) {
-        table.removeRow(row--);
-      }
-      int row = 2;
-      for (List<String> v : values) {
-        populate(row, v);
-        row++;
-      }
-      updateNavigationLinks();
-    }
-
-    List<List<String>> getValues() {
-      List<List<String>> values = new ArrayList<>();
-      for (int row = 2; row < table.getRowCount(); row++) {
-        values.add(getRowItem(row));
-      }
-      return values;
-    }
-
-    @Override
-    protected List<String> getRowItem(int row) {
-      List<String> v = new ArrayList<>();
-      for (int i = 0; i < inputs.size(); i++) {
-        v.add(table.getText(row, i + 1));
-      }
-      return v;
-    }
-
-    private void populate(int row, List<String> values) {
-      FlexCellFormatter fmt = table.getFlexCellFormatter();
-      fmt.addStyleName(row, 0, Gerrit.RESOURCES.css().iconCell());
-      fmt.addStyleName(row, 0, Gerrit.RESOURCES.css().leftMostCell());
-      CheckBox checkBox = new CheckBox();
-      checkBox.addValueChangeHandler(
-          new ValueChangeHandler<Boolean>() {
-            @Override
-            public void onValueChange(ValueChangeEvent<Boolean> event) {
-              enableDelete();
-            }
-          });
-      table.setWidget(row, 0, checkBox);
-      for (int i = 0; i < values.size(); i++) {
-        fmt.addStyleName(row, i + 1, Gerrit.RESOURCES.css().dataCell());
-        table.setText(row, i + 1, values.get(i));
-      }
-      if (!autoSort) {
-        fmt.addStyleName(row, values.size() + 1, Gerrit.RESOURCES.css().iconCell());
-        fmt.addStyleName(row, values.size() + 2, Gerrit.RESOURCES.css().dataCell());
-
-        Image down = new Image(Gerrit.RESOURCES.arrowDown());
-        down.setTitle(Gerrit.C.stringListPanelDown());
-        down.addClickHandler(
-            new ClickHandler() {
-              @Override
-              public void onClick(ClickEvent event) {
-                moveDown(row);
-              }
-            });
-        table.setWidget(row, values.size() + 1, down);
-
-        Image up = new Image(Gerrit.RESOURCES.arrowUp());
-        up.setTitle(Gerrit.C.stringListPanelUp());
-        up.addClickHandler(
-            new ClickHandler() {
-              @Override
-              public void onClick(ClickEvent event) {
-                moveUp(row);
-              }
-            });
-        table.setWidget(row, values.size() + 2, up);
-      }
-    }
-
-    @Override
-    protected void onCellSingleClick(Event event, int row, int column) {
-      if (column == inputs.size() + 1 && row >= 2 && row < table.getRowCount() - 2) {
-        moveDown(row);
-      } else if (column == inputs.size() + 2 && row > 2) {
-        moveUp(row);
-      }
-    }
-
-    void moveDown(int row) {
-      if (row < table.getRowCount() - 1) {
-        swap(row, row + 1);
-      }
-    }
-
-    void moveUp(int row) {
-      if (row > 2) {
-        swap(row - 1, row);
-      }
-    }
-
-    void swap(int row1, int row2) {
-      List<String> value = getRowItem(row1);
-      List<String> nextValue = getRowItem(row2);
-      populate(row1, nextValue);
-      populate(row2, value);
-      updateNavigationLinks();
-      widget.setEnabled(true);
-    }
-
-    private void updateNavigationLinks() {
-      if (!autoSort) {
-        for (int row = 2; row < table.getRowCount(); row++) {
-          table.getWidget(row, inputs.size() + 1).setVisible(row < table.getRowCount() - 1);
-          table.getWidget(row, inputs.size() + 2).setVisible(row > 2);
-        }
-      }
-    }
-
-    void add() {
-      List<String> values = new ArrayList<>();
-      for (NpTextBox input : inputs) {
-        values.add(input.getValue().trim());
-        input.setValue("");
-      }
-      insert(values);
-    }
-
-    void insert(List<String> v) {
-      int insertPos = table.getRowCount();
-      if (autoSort) {
-        for (int row = 1; row < table.getRowCount(); row++) {
-          int compareResult = v.get(0).compareTo(table.getText(row, 1));
-          if (compareResult < 0) {
-            insertPos = row;
-            break;
-          } else if (compareResult == 0) {
-            return;
-          }
-        }
-      }
-      table.insertRow(insertPos);
-      populate(insertPos, v);
-      updateNavigationLinks();
-    }
-
-    void enableDelete() {
-      for (int row = 2; row < table.getRowCount(); row++) {
-        if (((CheckBox) table.getWidget(row, 0)).getValue()) {
-          deleteButton.setEnabled(true);
-          return;
-        }
-      }
-      deleteButton.setEnabled(false);
-    }
-
-    void deleteChecked() {
-      deleteButton.setEnabled(false);
-      for (int row = 2; row < table.getRowCount(); row++) {
-        if (((CheckBox) table.getWidget(row, 0)).getValue()) {
-          table.removeRow(row--);
-        }
-      }
-      updateNavigationLinks();
-    }
-
-    @Override
-    protected void onOpenRow(int row) {}
-
-    @Override
-    protected Object getRowItemKey(List<String> item) {
-      return item.get(0);
-    }
-
-    void setEnabled(boolean enabled) {
-      addButton.setVisible(enabled);
-      for (NpTextBox input : inputs) {
-        input.setEnabled(enabled);
-      }
-      for (int row = 2; row < table.getRowCount(); row++) {
-        table.getWidget(row, 0).setVisible(enabled);
-        if (!autoSort) {
-          table.getWidget(row, inputs.size() + 1).setVisible(enabled);
-          table.getWidget(row, inputs.size() + 2).setVisible(enabled);
-        }
-      }
-      if (enabled) {
-        updateNavigationLinks();
-      }
-    }
-  }
-
-  @Override
-  public boolean isEnabled() {
-    return deleteButton.isVisible();
-  }
-
-  @Override
-  public void setEnabled(boolean enabled) {
-    t.setEnabled(enabled);
-    deleteButton.setVisible(enabled);
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Themer.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Themer.java
deleted file mode 100644
index d87c0b8..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Themer.java
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (C) 2013 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.client;
-
-import com.google.gerrit.client.projects.ThemeInfo;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.StyleElement;
-
-public class Themer {
-  public static class ThemerIE extends Themer {
-    protected ThemerIE() {}
-
-    @Override
-    protected String getCssText(StyleElement el) {
-      return el.getCssText();
-    }
-
-    @Override
-    protected void setCssText(StyleElement el, String css) {
-      el.setCssText(css);
-    }
-  }
-
-  protected StyleElement cssElement;
-  protected Element headerElement;
-  protected Element footerElement;
-  protected String cssText;
-  protected String headerHtml;
-  protected String footerHtml;
-
-  protected Themer() {}
-
-  public void set(ThemeInfo theme) {
-    if (theme != null) {
-      set(
-          theme.css() != null ? theme.css() : cssText,
-          theme.header() != null ? theme.header() : headerHtml,
-          theme.footer() != null ? theme.footer() : footerHtml);
-    } else {
-      set(cssText, headerHtml, footerHtml);
-    }
-  }
-
-  public void clear() {
-    set(null);
-  }
-
-  void init(Element css, Element header, Element footer) {
-    cssElement = StyleElement.as(css);
-    headerElement = header;
-    footerElement = footer;
-
-    cssText = getCssText(this.cssElement);
-    headerHtml = header.getInnerHTML();
-    footerHtml = footer.getInnerHTML();
-  }
-
-  protected String getCssText(StyleElement el) {
-    return el.getInnerHTML();
-  }
-
-  protected void setCssText(StyleElement el, String css) {
-    el.setInnerHTML(css);
-  }
-
-  private void set(String css, String header, String footer) {
-    setCssText(cssElement, css);
-    headerElement.setInnerHTML(header);
-    footerElement.setInnerHTML(footer);
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UrlAliasMatcher.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UrlAliasMatcher.java
deleted file mode 100644
index acaaf46..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UrlAliasMatcher.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2015 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.client;
-
-import com.google.gwt.regexp.shared.RegExp;
-import java.util.HashMap;
-import java.util.Map;
-
-public class UrlAliasMatcher {
-  private final Map<RegExp, String> userUrlAliases;
-  private final Map<RegExp, String> globalUrlAliases;
-
-  UrlAliasMatcher(Map<String, String> globalUrlAliases) {
-    this.globalUrlAliases = compile(globalUrlAliases);
-    this.userUrlAliases = new HashMap<>();
-  }
-
-  private static Map<RegExp, String> compile(Map<String, String> urlAliases) {
-    Map<RegExp, String> compiledUrlAliases = new HashMap<>();
-    if (urlAliases != null) {
-      for (Map.Entry<String, String> e : urlAliases.entrySet()) {
-        compiledUrlAliases.put(RegExp.compile(e.getKey()), e.getValue());
-      }
-    }
-    return compiledUrlAliases;
-  }
-
-  void clearUserAliases() {
-    this.userUrlAliases.clear();
-  }
-
-  void updateUserAliases(Map<String, String> userUrlAliases) {
-    clearUserAliases();
-    this.userUrlAliases.putAll(compile(userUrlAliases));
-  }
-
-  public String replace(String token) {
-    for (Map.Entry<RegExp, String> e : userUrlAliases.entrySet()) {
-      RegExp pat = e.getKey();
-      if (pat.exec(token) != null) {
-        return pat.replace(token, e.getValue());
-      }
-    }
-
-    for (Map.Entry<RegExp, String> e : globalUrlAliases.entrySet()) {
-      RegExp pat = e.getKey();
-      if (pat.exec(token) != null) {
-        return pat.replace(token, e.getValue());
-      }
-    }
-    return token;
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java
deleted file mode 100644
index cb529f4..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.java
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (C) 2012 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.client;
-
-import com.google.gerrit.client.info.AccountInfo;
-import com.google.gerrit.client.ui.InlineHyperlink;
-import com.google.gwt.core.client.GWT;
-import com.google.gwt.dom.client.AnchorElement;
-import com.google.gwt.dom.client.Element;
-import com.google.gwt.uibinder.client.UiBinder;
-import com.google.gwt.uibinder.client.UiField;
-import com.google.gwt.user.client.ui.Label;
-import com.google.gwt.user.client.ui.PopupPanel;
-import com.google.gwt.user.client.ui.Widget;
-
-public class UserPopupPanel extends PopupPanel {
-  interface Binder extends UiBinder<Widget, UserPopupPanel> {}
-
-  private static final Binder binder = GWT.create(Binder.class);
-
-  @UiField(provided = true)
-  AvatarImage avatar;
-
-  @UiField Label userName;
-  @UiField Label userEmail;
-  @UiField Element userLinks;
-  @UiField AnchorElement switchAccount;
-  @UiField AnchorElement logout;
-  @UiField InlineHyperlink settings;
-
-  public UserPopupPanel(AccountInfo account, boolean canLogOut, boolean showSettingsLink) {
-    super(/* auto hide */ true, /* modal */ false);
-    avatar = new AvatarImage(account, 100, false);
-    setWidget(binder.createAndBindUi(this));
-    setStyleName(Gerrit.RESOURCES.css().userInfoPopup());
-    if (account.name() != null) {
-      userName.setText(account.name());
-    }
-    if (account.email() != null) {
-      userEmail.setText(account.email());
-    }
-    if (showSettingsLink) {
-      String switchAccountUrl = Gerrit.info().auth().switchAccountUrl();
-      if (switchAccountUrl != null) {
-        switchAccount.setHref(switchAccountUrl.replace("${path}", "/"));
-      } else if (Gerrit.info().auth().isDev() || Gerrit.info().auth().isOpenId()) {
-        switchAccount.setHref(Gerrit.selfRedirect("/login"));
-      } else {
-        switchAccount.removeFromParent();
-        switchAccount = null;
-      }
-      if (canLogOut) {
-        logout.setHref(Gerrit.selfRedirect("/logout"));
-      } else {
-        logout.removeFromParent();
-        logout = null;
-      }
-
-    } else {
-      settings.removeFromParent();
-      settings = null;
-      userLinks.removeFromParent();
-      userLinks = null;
-      logout = null;
-    }
-
-    // We must show and then hide this popup so that it is part of the DOM.
-    // Otherwise the image does not get any events.  Calling hide() would
-    // remove it from the DOM so we use setVisible(false) instead.
-    show();
-    setVisible(false);
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.ui.xml
deleted file mode 100644
index 8f5073d..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/UserPopupPanel.ui.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-Copyright (C) 2012 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.
--->
-<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
-<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
-  xmlns:g='urn:import:com.google.gwt.user.client.ui'
-  xmlns:gerrit='urn:import:com.google.gerrit.client'
-  xmlns:u='urn:import:com.google.gerrit.client.ui'>
-  <ui:style gss='false'>
-    .panel {
-      padding: 8px;
-    }
-    .avatar {
-      padding-right: 4px;
-      width: 100px;
-      height: 100px;
-    }
-    .infoCell {
-      vertical-align: top;
-    }
-    .userName {
-      font-weight: bold;
-    }
-    .email {
-      padding-bottom: 6px;
-    }
-    .userLinks {
-      min-width: 250px;
-    }
-    .userLinksRight {
-      float: right;
-    }
-    .switchAccount {
-      border-right: 1px solid black;
-      padding-right: 0.5em;
-      margin-right: 0.5em;
-    }
-  </ui:style>
-
-  <g:HTMLPanel styleName='{style.panel}'>
-    <table><tr><td>
-      <gerrit:AvatarImage ui:field='avatar' styleName='{style.avatar}' />
-    </td><td class='{style.infoCell}'>
-      <g:Label ui:field='userName' styleName="{style.userName}" />
-      <g:Label ui:field='userEmail' styleName="{style.email}" />
-    </td></tr></table>
-    <div ui:field='userLinks' class='{style.userLinks}'>
-      <u:InlineHyperlink ui:field='settings' targetHistoryToken='/settings/'>
-        <ui:msg>Settings</ui:msg>
-      </u:InlineHyperlink>
-      <span class='{style.userLinksRight}'>
-        <a ui:field='switchAccount' class='{style.switchAccount}'><ui:msg>Switch Account</ui:msg></a
-        ><a ui:field='logout'><ui:msg>Sign Out</ui:msg></a>
-      </span>
-    </div>
-  </g:HTMLPanel>
-</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/VoidResult.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/VoidResult.java
deleted file mode 100644
index 810ebe7..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/VoidResult.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2013 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.client;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public final class VoidResult extends JavaScriptObject {
-  protected VoidResult() {}
-
-  public static VoidResult create() {
-    return createObject().cast();
-  }
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/AccessMap.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/AccessMap.java
deleted file mode 100644
index a0060d5..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/AccessMap.java
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2013 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.client.access;
-
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.RestApi;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import java.util.Collections;
-import java.util.Set;
-
-/** Access rights available from {@code /access/}. */
-public class AccessMap extends NativeMap<ProjectAccessInfo> {
-  public static void get(Set<Project.NameKey> projects, AsyncCallback<AccessMap> callback) {
-    RestApi api = new RestApi("/access/");
-    for (Project.NameKey p : projects) {
-      api.addParameter("project", p.get());
-    }
-    api.get(NativeMap.copyKeysIntoChildren(callback));
-  }
-
-  public static void get(Project.NameKey project, AsyncCallback<ProjectAccessInfo> cb) {
-    get(
-        Collections.singleton(project),
-        new AsyncCallback<AccessMap>() {
-          @Override
-          public void onSuccess(AccessMap result) {
-            cb.onSuccess(result.get(project.get()));
-          }
-
-          @Override
-          public void onFailure(Throwable caught) {
-            cb.onFailure(caught);
-          }
-        });
-  }
-
-  protected AccessMap() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/ProjectAccessInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/ProjectAccessInfo.java
deleted file mode 100644
index 88635df..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/access/ProjectAccessInfo.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2013 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.client.access;
-
-import com.google.gwt.core.client.JavaScriptObject;
-
-public class ProjectAccessInfo extends JavaScriptObject {
-  public final native boolean canAddRefs() /*-{ return this.can_add ? true : false; }-*/;
-
-  public final native boolean canAddTagRefs() /*-{ return this.can_add_tags ? true : false; }-*/;
-
-  public final native boolean isOwner() /*-{ return this.is_owner ? true : false; }-*/;
-
-  public final native boolean configVisible() /*-{ return this.config_visible ? true : false; }-*/;
-
-  protected ProjectAccessInfo() {}
-}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java
deleted file mode 100644
index 7f4522f..0000000
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountApi.java
+++ /dev/null
@@ -1,287 +0,0 @@
-// Copyright (C) 2013 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.client.account;
-
-import com.google.gerrit.client.VoidResult;
-import com.google.gerrit.client.info.AccountInfo;
-import com.google.gerrit.client.info.AgreementInfo;
-import com.google.gerrit.client.info.GpgKeyInfo;
-import com.google.gerrit.client.rpc.CallbackGroup;
-import com.google.gerrit.client.rpc.NativeMap;
-import com.google.gerrit.client.rpc.NativeString;
-import com.google.gerrit.client.rpc.Natives;
-import com.google.gerrit.client.rpc.RestApi;
-import com.google.gwt.core.client.JavaScriptObject;
-import com.google.gwt.core.client.JsArray;
-import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtorm.client.KeyUtil;
-import java.util.HashSet;
-import java.util.Set;
-
-/** A collection of static methods which work on the Gerrit REST API for specific accounts. */
-public class AccountApi {
-  public static RestApi self() {
-    return new RestApi("/accounts/").view("self");
-  }
-
-  /** Retrieve the account edit preferences */
-  public static void getEditPreferences(AsyncCallback<EditPreferences> cb) {
-    self().view("preferences.edit").get(cb);
-  }
-
-  /** Put the account edit preferences */
-  public static void putEditP