Merge "Wait for UI plugins to load"
diff --git a/.buckconfig b/.buckconfig
index 1bc29ac..9017c7e 100644
--- a/.buckconfig
+++ b/.buckconfig
@@ -5,6 +5,7 @@
   docs = //Documentation:html
   gerrit = //:gerrit
   release = //:release
+  withdocs = //:withdocs
 
 [buildfile]
   includes = //tools/default.defs
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 8428a74..6046ca7 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -21,8 +21,9 @@
   directory = /var/cache/gerrit2
 ----
 
-[[accounts]]Section accounts
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[accounts]]
+Section accounts
+~~~~~~~~~~~~~~~~
 
 [[accounts.visibility]]accounts.visibility::
 +
@@ -42,8 +43,9 @@
 +
 Default is `ALL`.
 
-[[addreviewer]]Section addreviewer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[addreviewer]]
+Section addreviewer
+~~~~~~~~~~~~~~~~~~~
 
 [[addreviewer.maxWithoutConfirmation]]addreviewer.maxWithoutConfirmation::
 +
@@ -69,8 +71,9 @@
 +
 Default is 20.
 
-[[auth]]Section auth
-~~~~~~~~~~~~~~~~~~~~
+[[auth]]
+Section auth
+~~~~~~~~~~~~
 
 See also link:config-sso.html[SSO configuration].
 
@@ -464,8 +467,9 @@
 +
 Default is true.
 
-[[cache]]Section cache
-~~~~~~~~~~~~~~~~~~~~~~
+[[cache]]
+Section cache
+~~~~~~~~~~~~~
 
 [[cache.directory]]cache.directory::
 +
@@ -767,8 +771,9 @@
 +
 Default is 5 minutes.
 
-[[change]]Section change
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[change]]
+Section change
+~~~~~~~~~~~~~~
 
 [[change.largeChange]]change.largeChange::
 +
@@ -800,8 +805,9 @@
 +
 Default is 30 seconds.
 
-[[changeMerge]]Section changeMerge
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[changeMerge]]
+Section changeMerge
+~~~~~~~~~~~~~~~~~~~
 
 [[changeMerge.checkFrequency]]changeMerge.checkFrequency::
 +
@@ -820,8 +826,10 @@
 +
 Default is 1.
 
-[[commentlink]]Section commentlink
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[commentlink]]
+Section commentlink
+~~~~~~~~~~~~~~~~~~~
+
 Comment links are find/replace strings applied to change descriptions,
 patch comments, in-line code comments and approval category value descriptions
 to turn set strings into hyperlinks.  One common use is for linking to
@@ -905,8 +913,9 @@
 link:rest-api-projects.html#get-config[REST API].
 
 
-[[contactstore]]Section contactstore
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[contactstore]]
+Section contactstore
+~~~~~~~~~~~~~~~~~~~~
 
 [[contactstore.url]]contactstore.url::
 +
@@ -921,8 +930,9 @@
 Shared secret of the web based contact store.
 
 
-[[container]]Section container
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[container]]
+Section container
+~~~~~~~~~~~~~~~~~
 
 These settings are applied only if Gerrit is started as the container
 process through Gerrit's 'gerrit.sh' rc.d compatible wrapper script.
@@ -977,8 +987,9 @@
 '$HOME/gerrit.war'.
 
 
-[[core]]Section core
-~~~~~~~~~~~~~~~~~~~~
+[[core]]
+Section core
+~~~~~~~~~~~~
 
 [[core.packedGitWindowSize]]core.packedGitWindowSize::
 +
@@ -1084,8 +1095,9 @@
 +
 Default is false, but in a future release may default to true.
 
-[[database]]Section database
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[database]]
+Section database
+~~~~~~~~~~~~~~~~
 
 The database section configures where Gerrit stores its metadata
 records about user accounts and change reviews.
@@ -1222,8 +1234,9 @@
 This setting only applies if
 <<database.connectionPool,database.connectionPool>> is true.
 
-[[download]]Section download
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[download]]
+Section download
+~~~~~~~~~~~~~~~~
 
 ----
 [download]
@@ -1303,8 +1316,9 @@
 If `download.scheme` is not specified, SSH, HTTP and Anonymous HTTP
 downloads are allowed.
 
-[[gerrit]]Section gerrit
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[gerrit]]
+Section gerrit
+~~~~~~~~~~~~~~
 
 [[gerrit.basePath]]gerrit.basePath::
 +
@@ -1378,13 +1392,20 @@
 Code Review's own bug tracker but could be directed to the system
 administrator's ticket queue.
 
+[[gerrit.reportBugText]]gerrit.reportBugText::
++
+Text to be displayed in the link to the bug report URL.
++
+Defaults to "Report Bug".
+
 [[gerrit.changeScreen]]gerrit.changeScreen::
 +
 Default change screen UI to direct users to. Valid values are
 `OLD_UI` and `CHANGE_SCREEN2`. Default is `CHANGE_SCREEN2`.
 
-[[gitweb]]Section gitweb
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[gitweb]]
+Section gitweb
+~~~~~~~~~~~~~~
 
 Gerrit can forward requests to either an internally managed gitweb
 (which allows Gerrit to enforce some access controls), or to an
@@ -1496,8 +1517,9 @@
 +
 Valid values are "true" and "false," default is "true".
 
-[[groups]]Section groups
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[groups]]
+Section groups
+~~~~~~~~~~~~~~
 
 [[groups.newGroupsVisibleToAll]]groups.newGroupsVisibleToAll::
 +
@@ -1506,8 +1528,9 @@
 +
 By default, false.
 
-[[hooks]]Section hooks
-~~~~~~~~~~~~~~~~~~~~~~
+[[hooks]]
+Section hooks
+~~~~~~~~~~~~~
 
 See also link:config-hooks.html[Hooks].
 
@@ -1580,8 +1603,9 @@
 Optional timeout value in seconds for synchronous hooks, if not specified
 then 30 seconds will be used.
 
-[[http]]Section http
-~~~~~~~~~~~~~~~~~~~~
+[[http]]
+Section http
+~~~~~~~~~~~~
 
 [[http.proxy]]http.proxy::
 +
@@ -1602,8 +1626,9 @@
 appear in the http.proxy property above.
 
 
-[[httpd]]Section httpd
-~~~~~~~~~~~~~~~~~~~~~~
+[[httpd]]
+Section httpd
+~~~~~~~~~~~~~
 
 The httpd section configures the embedded servlet container.
 
@@ -1835,8 +1860,9 @@
 If the file doesn't exist or can't be read the default robots.txt file
 bundled with the .war will be used instead.
 
-[[index]]Section index
-~~~~~~~~~~~~~~~~~~~~~~
+[[index]]
+Section index
+~~~~~~~~~~~~~
 
 The index section configures the secondary index.
 
@@ -1860,8 +1886,9 @@
 using the link:pgm-reindex.html[reindex program] before restarting the
 Gerrit server.
 
-[[ldap]]Section ldap
-~~~~~~~~~~~~~~~~~~~~
+[[ldap]]
+Section ldap
+~~~~~~~~~~~~
 
 LDAP integration is only enabled if `auth.type` is set to
 `HTTP_LDAP`, `LDAP` or `CLIENT_SSL_CERT_LDAP`.  See above for a
@@ -2147,8 +2174,9 @@
 must have the DWORD value `allowtgtsessionkey` set to 1 and the account must not
 have local administrator privileges.
 
-[[mimetype]]Section mimetype
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[mimetype]]
+Section mimetype
+~~~~~~~~~~~~~~~~
 
 [[mimetype.name.safe]]mimetype.<name>.safe::
 +
@@ -2176,8 +2204,10 @@
 ----
 
 
-[[pack]]Section pack
-~~~~~~~~~~~~~~~~~~~~
+[[pack]]
+Section pack
+~~~~~~~~~~~~
+
 Global settings controlling how Gerrit Code Review creates pack
 streams for Git clients running clone, fetch, or pull.  Most of these
 variables are per-client request, and thus should be carefully set
@@ -2201,8 +2231,9 @@
 By default, 1.
 
 
-[[plugins]]Section plugins
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[plugins]]
+Section plugins
+~~~~~~~~~~~~~~~
 
 [[plugins.checkFrequency]]plugins.checkFrequency::
 +
@@ -2217,8 +2248,10 @@
 Default is 1 minute.
 
 
-[[receive]]Section receive
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[receive]]
+Section receive
+~~~~~~~~~~~~~~~
+
 This section is used to set who can execute the 'receive-pack' and
 to limit the maximum Git object size that 'receive-pack' will accept.
 'receive-pack' is what runs on the server during a user's push or
@@ -2318,8 +2351,10 @@
 is assumed.
 
 
-[[repository]]Section repository
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[repository]]
+Section repository
+~~~~~~~~~~~~~~~~~~
+
 Repositories in this sense are the same as projects.
 
 In the following example configuration `Registered Users` is set
@@ -2348,8 +2383,9 @@
 groups are allowed.  Each on its own line.  Groups which don't exist
 in the database are ignored.
 
-[[rules]]Section rules
-~~~~~~~~~~~~~~~~~~~~~~
+[[rules]]
+Section rules
+~~~~~~~~~~~~~
 
 [[rules.enable]]rules.enable::
 +
@@ -2359,8 +2395,9 @@
 +
 Default is true, to execute project specific rules.
 
-[[sendemail]]Section sendemail
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[sendemail]]
+Section sendemail
+~~~~~~~~~~~~~~~~~
 
 [[sendemail.enable]]sendemail.enable::
 +
@@ -2488,8 +2525,9 @@
 By default, unset, so no Expiry-Date header is generated.
 
 
-[[site]]Section site
-~~~~~~~~~~~~~~~~~~~~
+[[site]]
+Section site
+~~~~~~~~~~~~
 
 [[site.checkUserAgent]]site.checkUserAgent::
 +
@@ -2511,8 +2549,9 @@
 and text results for changes. If false, the URL is disabled and
 returns 404 to clients. Default is true, enabling `/query`.
 
-[[ssh-alias]] Section ssh-alias
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[ssh-alias]]
+Section ssh-alias
+~~~~~~~~~~~~~~~~~
 
 Variables in section ssh-alias permit the site administrator to alias
 another command from Gerrit or a plugin into the `gerrit` command
@@ -2523,8 +2562,9 @@
   replicate = replication start
 ----
 
-[[sshd]] Section sshd
-~~~~~~~~~~~~~~~~~~~~~
+[[sshd]]
+Section sshd
+~~~~~~~~~~~~
 
 [[sshd.backend]]sshd.backend::
 +
@@ -2735,8 +2775,9 @@
 +
 By default, true.
 
-[[suggest]] Section suggest
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[suggest]]
+Section suggest
+~~~~~~~~~~~~~~~
 
 [[suggest.accounts]]suggest.accounts::
 +
@@ -2762,8 +2803,9 @@
 +
 By default 0.
 
-[[theme]] Section theme
-~~~~~~~~~~~~~~~~~~~~~~~
+[[theme]]
+Section theme
+~~~~~~~~~~~~~
 
 [[theme.backgroundColor]]theme.backgroundColor::
 +
@@ -2860,8 +2902,9 @@
   backgroundColor = FFFFFF
 ----
 
-[[trackingid]] Section trackingid
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[trackingid]]
+Section trackingid
+~~~~~~~~~~~~~~~~~~
 
 Tagged footer lines containing references to external
 tracking systems, parsed out of the commit message and
@@ -2913,8 +2956,9 @@
 It is possible to have several trackingid entries for the same
 tracking system.
 
-[[transfer]] Section transfer
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+[[transfer]]
+Section transfer
+~~~~~~~~~~~~~~~~
 
 [[transfer.timeout]]transfer.timeout::
 +
@@ -2931,8 +2975,10 @@
 Defaults to 0 seconds, wait indefinitely.
 
 
-[[upload]]Section upload
-~~~~~~~~~~~~~~~~~~~~~~~~
+[[upload]]
+Section upload
+~~~~~~~~~~~~~~
+
 Sets the group of users allowed to execute 'upload-pack' on the
 server, 'upload-pack' is what runs on the server during a user's
 fetch, clone or repo sync command.
@@ -2952,8 +2998,9 @@
 'upload-pack' on the server.
 
 
-[[user]] Section user
-~~~~~~~~~~~~~~~~~~~~~
+[[user]]
+Section user
+~~~~~~~~~~~~
 
 [[user.name]]user.name::
 +
diff --git a/Documentation/dev-buck.txt b/Documentation/dev-buck.txt
index 1acff3b..611d64d 100644
--- a/Documentation/dev-buck.txt
+++ b/Documentation/dev-buck.txt
@@ -211,7 +211,7 @@
 Documentation
 ~~~~~~~~~~~~~
 
-To build the documentation:
+To build only the documentation:
 
 ----
   buck build docs
@@ -229,6 +229,18 @@
   buck-out/gen/Documentation/html.zip
 ----
 
+To build the executable WAR with the documentation included:
+
+----
+  buck build withdocs
+----
+
+The WAR file will be placed in:
+
+----
+  buck-out/gen/withdocs.war
+----
+
 [[release]]
 Gerrit Release WAR File
 ~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index d961f70..e73e039 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -61,7 +61,7 @@
 ----
 
 Accept defaults by pressing Enter until 'init' completes, or add
-the '\--batch' command line option to avoid them entirely.  It is
+the '--batch' command line option to avoid them entirely.  It is
 recommended to change the listen addresses from '*' to 'localhost' to
 prevent outside connections from contacting the development instance.
 
diff --git a/Documentation/install-quick.txt b/Documentation/install-quick.txt
index 741de35..de17abd 100644
--- a/Documentation/install-quick.txt
+++ b/Documentation/install-quick.txt
@@ -28,14 +28,14 @@
 
 ----
   $ java -version
-  java version "1.6.0_26"
-  Java(TM) SE Runtime Environment (build 1.6.0_26-b03-384-10M3425)
-  Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-384, mixed mode)
+  java version "1.7.0_21"
+  Java(TM) SE Runtime Environment (build 1.7.0_21-b11)
+  Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
 ----
 
 If Java isn't installed, get it:
 
-* JDK, minimum version 1.6 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
+* JDK, minimum version 1.7 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
 
 
 [[user]]
diff --git a/Documentation/install.txt b/Documentation/install.txt
index 8e836f8..cbd9965 100644
--- a/Documentation/install.txt
+++ b/Documentation/install.txt
@@ -7,7 +7,7 @@
 To run the Gerrit service, the following requirements must be met on
 the host:
 
-* JDK, minimum version 1.6 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
+* JDK, minimum version 1.7 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
 
 You'll also need an SQL database to house the review metadata. You have the
 choice of either using the embedded H2 or to host your own MySQL or PostgreSQL.
diff --git a/Documentation/intro-change-screen.txt b/Documentation/intro-change-screen.txt
index a9b747e..8b381d2 100644
--- a/Documentation/intro-change-screen.txt
+++ b/Documentation/intro-change-screen.txt
@@ -104,9 +104,13 @@
 ------------
 
 This button corresponds to the 'Review' button the on patch set panel on the old
-change screen.  The only new feature: the user can optionally send an email
-during the vote. Inline comments are displayed inside of the ReplyBox. Editing
-them inline in the ReplyBox is currently not possible.
+change screen. The user can optionally send an email during the vote. Inline
+comments are displayed inside of the ReplyBox. Editing them inline in the
+ReplyBox is currently not possible.
+
+Hint: if "LGTM" (acronym for 'Looks Good To Me') is typed in the ReplyBox,
+then the highest possible score for 'Code-Review' category for logged in user
+is selected.
 
 Key bindings: "a" to open the drop down. "ESC" to close it.
 
diff --git a/Documentation/pgm-LocalUsernamesToLowerCase.txt b/Documentation/pgm-LocalUsernamesToLowerCase.txt
index bac3dc0..cd16617 100644
--- a/Documentation/pgm-LocalUsernamesToLowerCase.txt
+++ b/Documentation/pgm-LocalUsernamesToLowerCase.txt
@@ -38,11 +38,11 @@
 -------
 
 -d::
-\--site-path::
+--site-path::
 	Location of the gerrit.config file, and all other per-site
 	configuration data, supporting libraries and log files.
 
-\--threads::
+--threads::
 	Number of threads to perform the scan work with.  Defaults to
 	twice the number of CPUs available.
 
diff --git a/Documentation/pgm-daemon.txt b/Documentation/pgm-daemon.txt
index 19743a5..5a43bbc 100644
--- a/Documentation/pgm-daemon.txt
+++ b/Documentation/pgm-daemon.txt
@@ -10,12 +10,12 @@
 --
 'java' -jar gerrit.war 'daemon'
 	-d <SITE_PATH>
-	[\--enable-httpd | \--disable-httpd]
-	[\--enable-sshd | \--disable-sshd]
-	[\--console-log]
-	[\--slave]
-	[\--headless]
-	[\--init]
+	[--enable-httpd | --disable-httpd]
+	[--enable-sshd | --disable-sshd]
+	[--console-log]
+	[--slave]
+	[--headless]
+	[--init]
 	[-s]
 --
 
@@ -35,42 +35,42 @@
 -------
 
 -d::
-\--site-path::
+--site-path::
 	Location of the gerrit.config file, and all other per-site
 	configuration data, supporting libraries and log files.
 
-\--enable-httpd::
-\--disable-httpd::
+--enable-httpd::
+--disable-httpd::
 	Enable (or disable) the internal HTTP daemon, answering
 	web requests.  Enabled by default.
 
-\--enable-sshd::
-\--disable-sshd::
+--enable-sshd::
+--disable-sshd::
 	Enable (or disable) the internal SSH daemon, answering SSH
 	clients and remotely executed commands.  Enabled by default.
 
-\--slave::
+--slave::
 	Run in slave mode, permitting only read operations
     by clients.  Commands which modify state such as
     link:cmd-receive-pack.html[receive-pack] (creates new changes
     or updates existing ones) or link:cmd-review.html[review]
     (sets approve marks) are disabled.
 +
-This option automatically implies '\--disable-httpd \--enable-sshd'.
+This option automatically implies '--disable-httpd --enable-sshd'.
 
-\--console-log::
+--console-log::
 	Send log messages to the console, instead of to the standard
 	log file '$site_path/logs/error_log'.
 
-\--headless::
+--headless::
 	Don't start the default Gerrit UI. May be useful when Gerrit is
 	run with an alternative UI.
 
-\--init::
+--init::
 	Run init before starting the daemon. This will create a new site or
 	upgrade an existing site.
 
-\--s::
+--s::
 	Start link:dev-inspector.html[Gerrit Inspector] on the console, a
 	built-in interactive inspection environment to assist debugging and
 	troubleshooting of Gerrit code.
diff --git a/Documentation/pgm-gsql.txt b/Documentation/pgm-gsql.txt
index 0f9e5e4..a22880d 100644
--- a/Documentation/pgm-gsql.txt
+++ b/Documentation/pgm-gsql.txt
@@ -25,7 +25,7 @@
 -------
 
 -d::
-\--site-path::
+--site-path::
 	Location of the gerrit.config file, and all other per-site
 	configuration data, supporting libraries and log files.
 
diff --git a/Documentation/pgm-init.txt b/Documentation/pgm-init.txt
index 78e2e33..07ca154 100644
--- a/Documentation/pgm-init.txt
+++ b/Documentation/pgm-init.txt
@@ -10,10 +10,10 @@
 --
 'java' -jar gerrit.war 'init'
 	-d <SITE_PATH>
-	[\--batch]
-	[\--no-auto-start]
-	[\--list-plugins]
-	[\--install-plugin=<PLUGIN_NAME>]
+	[--batch]
+	[--no-auto-start]
+	[--list-plugins]
+	[--install-plugin=<PLUGIN_NAME>]
 --
 
 DESCRIPTION
@@ -27,7 +27,7 @@
 
 OPTIONS
 -------
-\--batch::
+--batch::
 	Run in batch mode, skipping interactive prompts.  Reasonable
 	configuration defaults are chosen based on the whims of
 	the Gerrit developers.
@@ -37,22 +37,24 @@
 SQL statements to drop these objects is provided. To drop the unused
 objects these SQL statements have to be executed manually.
 
-\--no-auto-start::
+--no-auto-start::
 	Don't automatically start the daemon after initializing a
 	newly created site path.  This permits the administrator
 	to inspect and modify the configuration before the daemon
 	is started.
 
 -d::
-\--site-path::
+--site-path::
 	Location of the gerrit.config file, and all other per-site
 	configuration data, supporting libraries and log files.
 
-\--list-plugins::
+--list-plugins::
 	Print names of plugins that can be installed during init process.
 
-\--install-plugin:
+--install-plugin:
 	Automatically install plugin with given name without asking.
+	This option may be supplied more than once to install multiple
+	plugins.
 
 CONTEXT
 -------
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index d9ceed7..7a7a173 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -2311,11 +2311,13 @@
   {
     "meta_a": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 372
     },
     "meta_b": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 578
     },
     "change_type": "MODIFIED",
     "diff_header": [
@@ -2379,11 +2381,13 @@
   {
     "meta_a": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 372
     },
     "meta_b": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 578
     },
     "change_type": "MODIFIED",
     "diff_header": [
@@ -2431,11 +2435,13 @@
   {
     "meta_a": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 578
     },
     "meta_b": {
       "name": "gerrit-server/src/main/java/com/google/gerrit/server/project/RefControl.java",
-      "content_type": "text/x-java-source"
+      "content_type": "text/x-java-source",
+      "lines": 578
     },
     "change_type": "MODIFIED",
     "content": [
@@ -3008,6 +3014,7 @@
 |Field Name    |Description
 |`name`        |The name of the file.
 |`content_type`|The content type of the file.
+|`lines`       |The total number of lines in the file.
 |==========================
 
 [[diff-info]]
diff --git a/Documentation/rest-api-documentation.txt b/Documentation/rest-api-documentation.txt
index 0defe6d..56e6c92 100644
--- a/Documentation/rest-api-documentation.txt
+++ b/Documentation/rest-api-documentation.txt
@@ -7,9 +7,9 @@
 
 Please note that this feature is only usable with documentation built-in.
 You'll need to
-`buck build :withdocs`
+`buck build withdocs`
 or
-`buck build :release`
+`buck build release`
 to test this feature.
 
 [[documentation-endpoints]]
diff --git a/Documentation/rest-api-plugins.txt b/Documentation/rest-api-plugins.txt
index e9e0a1c..c51a551 100644
--- a/Documentation/rest-api-plugins.txt
+++ b/Documentation/rest-api-plugins.txt
@@ -47,7 +47,7 @@
       "kind": "gerritcodereview#plugin",
       "id": "delete-project",
       "index_url": "plugins/delete-project/",
-      "version": "2.9-SNAPSHOT",
+      "version": "2.9-SNAPSHOT"
     },
     "reviewers-by-blame": {
       "kind": "gerritcodereview#plugin",
@@ -55,7 +55,7 @@
       "index_url": "plugins/reviewers-by-blame/",
       "version": "2.9-SNAPSHOT",
       "disabled": true
-    },
+    }
   }
 ----
 
diff --git a/ReleaseNotes/ReleaseNotes-2.7.txt b/ReleaseNotes/ReleaseNotes-2.7.txt
index 3a2ebf9..5133c04 100644
--- a/ReleaseNotes/ReleaseNotes-2.7.txt
+++ b/ReleaseNotes/ReleaseNotes-2.7.txt
@@ -73,7 +73,7 @@
 
 * New 'Stream Events' global capability.
 +
-The link:http://gerrit-documentation.googlecode.com/svn/Documentation/2.7/access-control.txt#capability_streamEvents[
+The link:http://gerrit-documentation.googlecode.com/svn/Documentation/2.7/access-control.html#capability_streamEvents[
 Stream Events capability] controls access to the `stream-events` ssh command.
 +
 Only administrators and users having this capability are allowed to use `stream-events`.
diff --git a/ReleaseNotes/ReleaseNotes-2.8.1.txt b/ReleaseNotes/ReleaseNotes-2.8.1.txt
new file mode 100644
index 0000000..13762e31
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.8.1.txt
@@ -0,0 +1,31 @@
+Release notes for Gerrit 2.8.1
+==============================
+
+There are no schema changes from link:ReleaseNotes-2.8.html[2.8].
+
+link:https://gerrit-releases.storage.googleapis.com/gerrit-2.8.1.war[https://gerrit-releases.storage.googleapis.com/gerrit-2.8.1.war]
+
+Bug Fixes
+---------
+* link:https://code.google.com/p/gerrit/issues/detail?id=2073[Issue 2073]:
+Changes that depend on outdated patch sets were missing in the related changes list.
++
+After rebasing the first change the other changes disappeared from the related changes list.
+
+* Fix plugin API packaging. Parts from JGit signed library were included in the
+plugin API. As a consequence unit tests were failing to execute against it.
+
+* Fix IllegalArgumentException in task queue comparator.
++
+This could happen if you have a long queue and the state of a task (DONE, CANCELLED,
+RUNNING, READY, SLEEPING, OTHER) changes while the sorting is ongoing.
+
+* Delegate to the filters for init and destroy phases in AllRequestFilter.
++
+This fixes a bug that prevented javamelody from working properly.
+
+* Fix ArrayOutOfBoundsException on initial commits.
++
+This happened if a new patch set was given for an initial commit in a repository.
+
+* Enable syntax highlighting for CXX, HXX, Python, Go, BUCK and .gitmodules.
diff --git a/ReleaseNotes/ReleaseNotes-2.8.txt b/ReleaseNotes/ReleaseNotes-2.8.txt
index b7b868b..418edf2 100644
--- a/ReleaseNotes/ReleaseNotes-2.8.txt
+++ b/ReleaseNotes/ReleaseNotes-2.8.txt
@@ -27,6 +27,24 @@
 back to the old behavior, set the parameter `remote.NAME.createMissingRepositories`
 in the `replication.config` file to `false`.
 
+*WARNING:* The deprecated `approve` alias for the
+link:https://gerrit-documentation.storage.googleapis.com/Documentation/2.8/cmd-review.html[
+review] SSH command has been removed. This is important for all users
+of the Jenkins link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[
+Gerrit Trigger Plugin] since this plugin by default uses the `approve`
+command to vote and comment on changes in Gerrit. If you use the Gerrit
+Trigger Plugin, go to its global configuration in Jenkins and adapt the
+Gerrit commands to use the `review` command instead of the `approve`
+command.
+
+*WARNING:* The new change screen only displays download commands if the
+`download-commands` core plugin or any other plugin providing download
+commands is installed. The `download-commands` plugin provides the
+standard download schemes and commands. It is packaged together with
+Gerrit and can be installed during the
+link:https://gerrit-review.googlesource.com/Documentation/pgm-init.html[
+site initialization].
+
 
 Release Highlights
 ------------------
@@ -571,6 +589,32 @@
 
 * Allow usernames to begin with digit.
 
+* Verify access to source ref during add branch operation.
++
+Previously Gerrit didn't check access to source ref during add branch
+operation. Because of that users could create a branch from any known
+commit SHA1, even when they didn't have access to that commit.
+
+* Fix Gerrit API sources JAR contents.
++
+The gerrit-extension-api-X.Y-all-sources.jar did not actually contain any
+sources.
+
+* Generate javadoc for Gerrit Extension and Plugin APIs.
+
+* link:https://code.google.com/p/gerrit/issues/detail?id=2244[Issue 2244]:
+Update patch status before skipping duplicate emails.
+
+* link:https://code.google.com/p/gerrit/issues/detail?id=1640[Issue 1640]:
+Catch missing LDAP accounts in group membership.
+
+* Use `rev-parse` to find gitdir when generating commit-msg hook hint.
+
+* Performance Fix: Minimize number of advertisedHaves.
++
+By filtering the refs before the objectIds are added to advertisedHaves,
+lots of time can be saved when pushing to complex Gits.
+
 
 Configuration
 ~~~~~~~~~~~~~
@@ -595,6 +639,8 @@
 * Do not override error and gc logging configuration provided by the
 `-Dlog4j.configuration` parameter.
 
+* Fix JdbcSQLException when numbers are read from cache.
+
 Web UI
 ~~~~~~
 
@@ -614,6 +660,12 @@
 
 * Display "Working..." when header is hidden.
 
+* link:https://code.google.com/p/gerrit/issues/detail?id=2125[Issue 2125]:
+Correctly shows '-1' instead of '1' for label score.
++
+If a user voted '-1', and then another user voted '+1' for a label, the
+label was shown as a red '1' in the change list instead of red '-1'.
+
 Change Screens
 ^^^^^^^^^^^^^^
 
@@ -635,6 +687,24 @@
 In this case, it makes more sense for the message to say "Uploaded
 patch set N" instead.
 
+* Make links appear with consistent colors.
+
+* Prevent duplicate permitted_labels from being shown in labels list.
+
+Diff Screens
+^^^^^^^^^^^^
+
+
+* link:https://code.google.com/p/gerrit/issues/detail?id=1233[Issue 1233]:
+Prevent expansion when whole file isn't loaded.
+
+* link:https://code.google.com/p/gerrit/issues/detail?id=2122[Issue 2122]:
+Show review comments for unchanged files.
++
+When comparing patch sets and some comment was put in one side,
+that comment was not shown if there was no code changed between
+the two patch sets
+
 Project Screens
 ^^^^^^^^^^^^^^^
 
@@ -708,6 +778,8 @@
 The API is simplified in the sense that one Event now corresponds to
 one ref update only.
 
+* Make plugin servlet's context path authorization aware.
+
 
 Review Notes
 ^^^^^^^^^^^^
@@ -723,6 +795,8 @@
 
 * Create review note also when newObjectId already present in another branch.
 
+* Correct documentation of the export command.
+
 Emails
 ~~~~~~
 
@@ -751,6 +825,9 @@
 * Various spelling mistakes are corrected in the documentation and previous
 release notes.
 
+* link:https://code.google.com/p/gerrit/issues/detail?id=2144[Issue 2144]:
+Documentation of the query operator is fixed.
+
 
 Upgrades
 --------
@@ -762,6 +839,9 @@
 * Update H2 to 1.3.173
 * Update bouncycastle to 1.44
 * Update Apache Mina to 2.0.7
-* Update Apache SSHD to 0.9.0.201311081
+* link:https://code.google.com/p/gerrit/issues/detail?id=2232[Issue 2232]:
+Update Apache SSHD to 0.9.0.201311081
 * asciidoctor 0.1.4 is now required to build the documentation
 * jsr305 library was removed
+* link:https://code.google.com/p/gerrit/issues/detail?id=2232[Issue 2232]:
+Update Jsch to 1.5.0
diff --git a/ReleaseNotes/index.txt b/ReleaseNotes/index.txt
index effb0d4..b37f63b 100644
--- a/ReleaseNotes/index.txt
+++ b/ReleaseNotes/index.txt
@@ -9,6 +9,7 @@
 [[2_8]]
 Version 2.8.x
 -------------
+* link:ReleaseNotes-2.8.1.html[2.8.1]
 * link:ReleaseNotes-2.8.html[2.8]
 
 [[2_7]]
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfoCache.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfoCache.java
index 95e7587..042d08d 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfoCache.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfoCache.java
@@ -20,7 +20,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/** In-memory table of {@link AccountInfo}, indexed by {@link Account.Id}. */
+/** In-memory table of {@link AccountInfo}, indexed by {@code Account.Id}. */
 public class AccountInfoCache {
   private static final AccountInfoCache EMPTY;
   static {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
index df4e861..38afaab 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GerritConfig.java
@@ -32,6 +32,7 @@
   protected String switchAccountUrl;
   protected String httpPasswordUrl;
   protected String reportBugUrl;
+  protected String reportBugText;
   protected boolean gitBasicAuth;
 
   protected GitwebConfig gitweb;
@@ -103,6 +104,14 @@
     reportBugUrl = u;
   }
 
+  public String getReportBugText() {
+    return reportBugText;
+  }
+
+  public void setReportBugText(String t) {
+    reportBugText = t;
+  }
+
   public boolean isGitBasicAuth() {
     return gitBasicAuth;
   }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfoCache.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfoCache.java
index 999428a..e177708 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfoCache.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfoCache.java
@@ -20,7 +20,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/** In-memory table of {@link GroupInfo}, indexed by {@link AccountGroup.Id}. */
+/** In-memory table of {@link GroupInfo}, indexed by {@code AccountGroup.Id}. */
 public class GroupInfoCache {
   private static final GroupInfoCache EMPTY;
   static {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
index 81ba1bd..5a4bc85 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
@@ -66,7 +66,7 @@
       // "${parameter[.functions...]}" -> "parameter[.functions...]"
       final Parameter p = new Parameter(pattern.substring(b + 2, e));
 
-      raw.append("{" + prs.size() + "}");
+      raw.append("{").append(prs.size()).append("}");
       prs.add(p);
       ops.add(p);
 
diff --git a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/rebind/ServerPlannedIFrameLinker.java b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/rebind/ServerPlannedIFrameLinker.java
index 3e2361c..371b644 100644
--- a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/rebind/ServerPlannedIFrameLinker.java
+++ b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/rebind/ServerPlannedIFrameLinker.java
@@ -48,7 +48,8 @@
     }
 
     for (CompilationResult r : artifacts.find(CompilationResult.class)) {
-      table.append(r.getStrongName() + "\n");
+      table.append(r.getStrongName());
+      table.append("\n");
       for (SortedMap<SelectionProperty, String> p : r.getPropertyMap()) {
         for (Map.Entry<SelectionProperty, String> e : p.entrySet()) {
           table.append("  ");
diff --git a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/server/Permutation.java b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/server/Permutation.java
index 87979cc..5b0ef49 100644
--- a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/server/Permutation.java
+++ b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/linker/server/Permutation.java
@@ -100,8 +100,8 @@
     // Prevents mixed mode security in IE6/7.
     s.append("f.src=\"javascript:''\";");
     s.append("f.id=n;");
-    s.append("f.style.cssText"
-        + "='position:absolute;width:0;height:0;border:none';");
+    s.append("f.style.cssText");
+    s.append("='position:absolute;width:0;height:0;border:none';");
     s.append("f.tabIndex=-1;");
     s.append("d.body.appendChild(f);");
 
diff --git a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
index b8fbb8c..ed4e6cb 100644
--- a/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
+++ b/gerrit-gwtexpui/src/main/java/com/google/gwtexpui/safehtml/client/HighlightSuggestOracle.java
@@ -23,8 +23,10 @@
  * <p>
  * Suggestions supplied by the implementation of
  * {@link #onRequestSuggestions(Request, Callback)} are modified to wrap all
- * occurrences of the {@link SuggestOracle.Request#getQuery()} substring in HTML
- * {@code &lt;strong&gt;} tags, so they can be emphasized to the user.
+ * occurrences of the
+ * {@link com.google.gwt.user.client.ui.SuggestOracle.Request#getQuery()}
+ * substring in HTML {@code &lt;strong&gt;} tags, so they can be emphasized to
+ * the user.
  */
 public abstract class HighlightSuggestOracle extends SuggestOracle {
   private static String escape(String ds) {
@@ -57,9 +59,10 @@
   }
 
   /**
-   * @return true if {@link SuggestOracle.Suggestion#getDisplayString()} returns
-   *         HTML; false if the text must be escaped before evaluating in an
-   *         HTML like context.
+   * @return true if
+   *         {@link com.google.gwt.user.client.ui.SuggestOracle.Suggestion#getDisplayString()}
+   *         returns HTML; false if the text must be escaped before evaluating
+   *         in an HTML like context.
    */
   protected boolean isHTML() {
     return false;
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
index b44bd3d..fa4ff06 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Dispatcher.java
@@ -91,10 +91,12 @@
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.RunAsyncCallback;
 import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.Cookies;
 import com.google.gwt.user.client.Window;
 import com.google.gwtorm.client.KeyUtil;
 
 public class Dispatcher {
+  public static final String COOKIE_CS2 = "gerrit_cs2";
   public static boolean changeScreen2;
 
   public static String toPatchSideBySide(final Patch.Key id) {
@@ -491,7 +493,7 @@
     if (rest.isEmpty()) {
       Gerrit.display(token, panel== null
           ? (isChangeScreen2()
-              ? new ChangeScreen2(id, null, null, false)
+              ? new ChangeScreen2(id, null, null, false, false)
               : new ChangeScreen(id))
           : new NotFoundScreen());
       return;
@@ -528,7 +530,7 @@
                 base != null
                     ? String.valueOf(base.get())
                     : null,
-                String.valueOf(ps.get()), false)
+                String.valueOf(ps.get()), false, false)
             : new ChangeScreen(id));
       } else if ("publish".equals(panel)) {
         publish(ps);
@@ -551,6 +553,11 @@
           .getGeneralPreferences()
           .getChangeScreen();
     }
+    String v = Cookies.getCookie(Dispatcher.COOKIE_CS2);
+    if (v != null) {
+      changeScreen2 = "1".equals(v);
+      return changeScreen2;
+    }
     if (ui == null) {
       ui = Gerrit.getConfig().getChangeScreen();
     }
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
index b00808f..7972e52 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/Gerrit.java
@@ -457,15 +457,15 @@
     btmmenu.add(new InlineLabel(C.keyHelp()));
     btmmenu.add(new InlineLabel(" | "));
     btmmenu.add(new InlineHTML(M.poweredBy(vs)));
-    if (getConfig().getReportBugUrl() != null) {
-      Anchor a = new Anchor(
-          C.reportBug(),
-          getConfig().getReportBugUrl());
-      a.setTarget("_blank");
-      a.setStyleName("");
-      btmmenu.add(new InlineLabel(" | "));
-      btmmenu.add(a);
-    }
+
+    final String reportBugText = getConfig().getReportBugText();
+    Anchor a = new Anchor(
+        reportBugText == null ? C.reportBug() : reportBugText,
+        getConfig().getReportBugUrl());
+    a.setTarget("_blank");
+    a.setStyleName("");
+    btmmenu.add(new InlineLabel(" | "));
+    btmmenu.add(a);
   }
 
   private void onModuleLoad2(HostPageData hpd) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountMessages.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountMessages.properties
index 313893e..994c236 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountMessages.properties
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountMessages.properties
@@ -1,7 +1,7 @@
 lines = {0} lines
 rowsPerPage = {0} rows per page
 
-changeScreenServerDefault = Server Default ({0}) 
+changeScreenServerDefault = Server Default ({0})
 
 enterIAGREE = (enter {0} in the box to the left)
 contactOnFile = Contact information last updated on {0,date,medium} at {0,time,short}.
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
index a12e6fe..dc32f22 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
@@ -129,6 +129,7 @@
   private Timestamp lastDisplayedUpdate;
   private UpdateAvailableBar updateAvailable;
   private boolean openReplyBox;
+  private boolean focusSubmit;
   private boolean loaded;
 
   @UiField HTMLPanel headerLine;
@@ -175,11 +176,14 @@
   private PatchSetsAction patchSetsAction;
   private DownloadAction downloadAction;
 
-  public ChangeScreen2(Change.Id changeId, String base, String revision, boolean openReplyBox) {
+  public ChangeScreen2(Change.Id changeId,
+      String base, String revision,
+      boolean openReplyBox, boolean focusSubmit) {
     this.changeId = changeId;
     this.base = normalize(base);
     this.revision = normalize(revision);
     this.openReplyBox = openReplyBox;
+    this.focusSubmit = focusSubmit;
     add(uiBinder.createAndBindUi(this));
   }
 
@@ -418,6 +422,8 @@
 
     if (openReplyBox) {
       onReply();
+    } else if (focusSubmit && actions.isSubmitEnabled()) {
+      actions.submit.setFocus(true);
     } else {
       String prior = Gerrit.getPriorView();
       if (prior != null && prior.startsWith("/c/")) {
@@ -427,6 +433,9 @@
 
     ChangeGlue.fireShowChange(changeInfo, changeInfo.revision(revision));
     startPoller();
+    if (NewChangeScreenBar.show()) {
+      add(new NewChangeScreenBar(changeId));
+    }
   }
 
   private void scrollToPath(String token) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
index 7a611ff..c974180 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/FileTable.java
@@ -63,16 +63,18 @@
   }
 
   interface FileTableCss extends CssResource {
+    String table();
     String pointer();
     String reviewed();
     String status();
     String pathColumn();
+    String commonPrefix();
+    String renameCopySource();
     String draftColumn();
     String newColumn();
     String commentColumn();
     String deltaColumn1();
     String deltaColumn2();
-    String commonPrefix();
     String inserted();
     String deleted();
   }
@@ -335,6 +337,7 @@
       this.comments = comments;
       this.drafts = drafts;
       this.hasUser = Gerrit.isSignedIn();
+      table.addStyleName(R.css().table());
     }
 
     public boolean execute() {
@@ -474,8 +477,14 @@
         lastPath = path;
       }
 
-      sb.closeAnchor()
-        .closeTd();
+      sb.closeAnchor();
+      if (info.old_path() != null) {
+        sb.br();
+        sb.openSpan().setStyleName(R.css().renameCopySource())
+          .append(info.old_path())
+          .closeSpan();
+      }
+      sb.closeTd();
     }
 
     private int commonPrefix(String path) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java
new file mode 100644
index 0000000..fa65514
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.java
@@ -0,0 +1,105 @@
+// 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.change;
+
+import com.google.gerrit.client.Dispatcher;
+import com.google.gerrit.client.Gerrit;
+import com.google.gerrit.client.account.AccountApi;
+import com.google.gerrit.common.PageLinks;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ChangeScreen;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.dom.client.Element;
+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.rpc.AsyncCallback;
+import com.google.gwt.user.client.ui.Anchor;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTMLPanel;
+import com.google.gwt.user.client.ui.UIObject;
+
+import java.util.Date;
+
+/** Displays a welcome to the new change screen bar. */
+class NewChangeScreenBar extends Composite {
+  interface Binder extends UiBinder<HTMLPanel, NewChangeScreenBar> {}
+  private static final Binder uiBinder = GWT.create(Binder.class);
+
+  static boolean show() {
+    if (Gerrit.isSignedIn()) {
+      return Gerrit.getUserAccount()
+          .getGeneralPreferences()
+          .getChangeScreen() == null;
+    }
+    return Cookies.getCookie(Dispatcher.COOKIE_CS2) == null;
+  }
+
+  private final Change.Id id;
+
+  @UiField Element docs;
+  @UiField Element settings;
+  @UiField Anchor keepNew;
+  @UiField Anchor keepOld;
+
+  NewChangeScreenBar(Change.Id id) {
+    this.id = id;
+    initWidget(uiBinder.createAndBindUi(this));
+    UIObject.setVisible(docs, Gerrit.getConfig().isDocumentationAvailable());
+    UIObject.setVisible(settings, Gerrit.isSignedIn());
+  }
+
+  @UiHandler("keepOld")
+  void onKeepOld(ClickEvent e) {
+    save(ChangeScreen.OLD_UI);
+    Gerrit.display(PageLinks.toChange(id));
+  }
+
+  @UiHandler("keepNew")
+  void onKeepNew(ClickEvent e) {
+    save(ChangeScreen.CHANGE_SCREEN2);
+  }
+
+  private void save(ChangeScreen sel) {
+    removeFromParent();
+    Dispatcher.changeScreen2 = sel == ChangeScreen.CHANGE_SCREEN2;
+
+    if (Gerrit.isSignedIn()) {
+      Gerrit.getUserAccount().getGeneralPreferences().setChangeScreen(sel);
+
+      Prefs in = Prefs.createObject().cast();
+      in.change_screen(sel.name());
+      AccountApi.self().view("preferences").background().post(in,
+        new AsyncCallback<JavaScriptObject>() {
+          @Override public void onFailure(Throwable caught) {}
+          @Override public void onSuccess(JavaScriptObject result) {}
+        });
+    } else {
+      Cookies.setCookie(
+        Dispatcher.COOKIE_CS2,
+        Dispatcher.changeScreen2 ? "1" : "0",
+        new Date(System.currentTimeMillis() + 7 * 24 * 3600 * 1000));
+    }
+  }
+
+  private static class Prefs extends JavaScriptObject {
+    final native void change_screen(String n) /*-{ this.change_screen=n }-*/;
+    protected Prefs() {
+    }
+  }
+}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml
new file mode 100644
index 0000000..5df52cb
--- /dev/null
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/NewChangeScreenBar.ui.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<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>
+    .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;
+      text-align: center;
+      background: #FFF1A8;
+      -webkit-border-radius: 10px;
+      -moz-border-radius: 10px;
+    }
+    a.action {
+      color: #222;
+      text-decoration: underline;
+      display: inline-block;
+      margin-left: 0.5em;
+    }
+    .welcome { font-weight: bold; }
+  </ui:style>
+  <g:HTMLPanel styleName='{style.popup}'>
+    <div><ui:msg><span class='{style.welcome}'>Welcome to the new change screen!</span>
+      <a ui:field='docs'
+         class='{style.action}'
+         href='Documentation/intro-change-screen.html'
+         target='_blank'>Learn more</a></ui:msg>
+    </div>
+    <div>
+      <ui:msg>You can<g:Anchor ui:field='keepOld'
+          styleName='{style.action}'
+          href='javascript:;'
+          title='Switch back to the old screen'><ui:attribute name='title'/>revert to the old screen</g:Anchor>
+      <span ui:field='settings'>in Settings &gt; Preferences</span>.
+      <g:Anchor ui:field='keepNew'
+          styleName='{style.action}'
+          href='javascript:;'
+          title='Keep the new change screen'>
+        <ui:attribute name='title'/>
+        Got it!
+      </g:Anchor></ui:msg>
+    </div>
+  </g:HTMLPanel>
+</ui:UiBinder>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/QuickApprove.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/QuickApprove.java
index ddb7d56..395d9c5 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/QuickApprove.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/QuickApprove.java
@@ -112,7 +112,9 @@
       .post(input, new GerritCallback<ReviewInput>() {
         @Override
         public void onSuccess(ReviewInput result) {
-          Gerrit.display(PageLinks.toChange(changeId));
+          Gerrit.display(
+            PageLinks.toChange(changeId),
+            new ChangeScreen2(changeId, null, null, false, true));
         }
       });
   }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
index 665c711..08c7d5d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/RelatedChanges.java
@@ -106,8 +106,9 @@
   }
 
   private final List<RelatedChangesTab> tabs;
-  private int maxHeight;
+  private int maxHeightWithHeader;
   private int selectedTab;
+  private int outstandingCallbacks;
 
   RelatedChanges() {
     tabs = new ArrayList<RelatedChangesTab>(Tab.values().length);
@@ -133,7 +134,6 @@
 
     for (Tab tabInfo : Tab.values()) {
       RelatedChangesTab panel = new RelatedChangesTab();
-      panel.setMaxHeight(maxHeight);
       add(panel, tabInfo.defaultTitle);
       tabs.add(panel);
 
@@ -205,13 +205,18 @@
   }
 
   void setMaxHeight(int height) {
-    maxHeight = height - (getTabBar().getOffsetHeight() + 2 /* padding */);
-    for (int i = 0; i < getTabBar().getTabCount(); i++) {
-      tabs.get(i).setMaxHeight(maxHeight);
+    maxHeightWithHeader = height;
+    if (isVisible()) {
+      applyMaxHeight();
     }
   }
 
-  private int outstandingCallbacks;
+  private void applyMaxHeight() {
+    int header = getTabBar().getOffsetHeight() + 2 /* padding */;
+    for (int i = 0; i < getTabBar().getTabCount(); i++) {
+      tabs.get(i).setMaxHeight(maxHeightWithHeader - header);
+    }
+  }
 
   private abstract class TabCallback<T> implements AsyncCallback<T> {
     private final Tab tabInfo;
@@ -253,6 +258,7 @@
           if (getTabBar().isTabEnabled(i)) {
             selectTab(i);
             setVisible(true);
+            applyMaxHeight();
             break;
           }
         }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyAction.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyAction.java
index 26e3b74..be1e217 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyAction.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyAction.java
@@ -23,6 +23,7 @@
 import com.google.gwt.core.client.JsArrayString;
 import com.google.gwt.event.logical.shared.CloseEvent;
 import com.google.gwt.event.logical.shared.CloseHandler;
+import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.PopupPanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.google.gwtexpui.globalkey.client.GlobalKey;
@@ -101,6 +102,7 @@
       }
     });
     p.add(replyBox);
+    Window.scrollTo(0, 0);
     p.showRelativeTo(replyButton);
     GlobalKey.dialog(p);
     popup = p;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
index 36a831e..3693ced 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
@@ -31,6 +31,7 @@
 import com.google.gerrit.client.ui.CommentLinkProcessor;
 import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.common.data.LabelValue;
+import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Patch;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gwt.core.client.GWT;
@@ -49,7 +50,6 @@
 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.Window;
 import com.google.gwt.user.client.rpc.AsyncCallback;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.CheckBox;
@@ -84,6 +84,7 @@
   private final CommentLinkProcessor clp;
   private final PatchSet.Id psId;
   private final String revision;
+  private final NativeMap<LabelInfo> labels;
   private ReviewInput in = ReviewInput.create();
   private Runnable lgtm;
 
@@ -106,6 +107,7 @@
     this.clp = clp;
     this.psId = psId;
     this.revision = revision;
+    this.labels = all;
     initWidget(uiBinder.createAndBindUi(this));
 
     List<String> names = new ArrayList<String>(permitted.keySet());
@@ -124,7 +126,9 @@
           if ((e.getCharCode() == '\n' || e.getCharCode() == KEY_ENTER)
               && e.isControlKeyDown()) {
             e.preventDefault();
-            onPost(null);
+            if (post.isEnabled()) {
+              onPost(null);
+            }
           }
         }
       },
@@ -152,7 +156,6 @@
     Scheduler.get().scheduleDeferred(new ScheduledCommand() {
       @Override
       public void execute() {
-        Window.scrollTo(0, 0);
         message.setFocus(true);
       }});
     Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
@@ -193,14 +196,28 @@
   void onPost(ClickEvent e) {
     in.message(message.getText().trim());
     in.prePost();
+
+    boolean s = false;
+    for (String name : labels.keySet()) {
+      if (in.label(name) != 0) {
+        if (in.label(name) == labels.get(name).value_set().last()) {
+          s = true;
+          break;
+        }
+      }
+    }
+    final boolean submit = s;
+
     ChangeApi.revision(psId.getParentKey().get(), revision)
       .view("review")
       .post(in, new GerritCallback<ReviewInput>() {
         @Override
         public void onSuccess(ReviewInput result) {
-          Gerrit.display(PageLinks.toChange(
-              psId.getParentKey(),
-              String.valueOf(psId.get())));
+          Change.Id changeId = psId.getParentKey();
+          String rev = String.valueOf(psId.get());
+          Gerrit.display(
+            PageLinks.toChange(changeId, rev),
+            new ChangeScreen2(changeId, null, rev, false, submit));
         }
       });
     hide();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
index a9d5a38..c2947cf 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/file_table.css
@@ -19,6 +19,10 @@
   vertical-align: top;
 }
 
+.table tr {
+  vertical-align: top;
+}
+
 .status {
   padding-right: 4px;
   color: #888;
@@ -34,6 +38,10 @@
 .commonPrefix {
   color: #888;
 }
+.renameCopySource {
+  color: #888;
+  font-size: smaller;
+}
 
 .draftColumn,
 .newColumn,
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ReviewInput.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ReviewInput.java
index 0599a8b..03c115a 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ReviewInput.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ReviewInput.java
@@ -36,6 +36,7 @@
 
   public final native void message(String m) /*-{ if(m)this.message=m; }-*/;
   public final native void label(String n, short v) /*-{ this.labels[n]=v; }-*/;
+  public final native short label(String n) /*-{ return this.labels[n]||0 }-*/;
   public final native void comments(NativeMap<JsArray<CommentInfo>> m)
   /*-{ this.comments=m }-*/;
 
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java
index d5f7819..be222ef 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/DiffInfo.java
@@ -99,6 +99,7 @@
   public static class FileMeta extends JavaScriptObject {
     public final native String name() /*-{ return this.name; }-*/;
     public final native String content_type() /*-{ return this.content_type; }-*/;
+    public final native int lines() /*-{ return this.lines || 0 }-*/;
 
     protected FileMeta() {
     }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
index c87bb28..4f2fa10 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
@@ -49,6 +49,7 @@
 import com.google.gwt.core.client.JsArray;
 import com.google.gwt.core.client.JsArrayString;
 import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.RepeatingCommand;
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.NativeEvent;
@@ -122,6 +123,7 @@
   private JsArray<CommentInfo> draftsBase;
   private JsArray<CommentInfo> draftsRevision;
   private DiffInfo diff;
+  private boolean largeFile;
   private LineMapper mapper;
   private List<TextMarker> markers;
   private List<Runnable> undoLineClass;
@@ -188,10 +190,16 @@
         @Override
         public void onSuccess(DiffInfo diffInfo) {
           diff = diffInfo;
-          new ModeInjector()
-            .add(getContentType(diff.meta_a()))
-            .add(getContentType(diff.meta_b()))
-            .inject(modeInjectorCb);
+          if (prefs.syntaxHighlighting()) {
+            largeFile = isLargeFile(diffInfo);
+            if (largeFile) {
+              modeInjectorCb.onSuccess(null);
+            } else {
+              injectMode(diffInfo, modeInjectorCb);
+            }
+          } else {
+            modeInjectorCb.onSuccess(null);
+          }
         }
       }));
 
@@ -524,6 +532,18 @@
         resizeCodeMirror();
       }
     });
+
+    if (largeFile && prefs.syntaxHighlighting()) {
+      Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
+        @Override
+        public boolean execute() {
+          if (prefs.syntaxHighlighting() && isAttached()) {
+            setSyntaxHighlighting(prefs.syntaxHighlighting());
+          }
+          return false;
+        }
+      }, 250);
+    }
   }
 
   private CodeMirror createCodeMirror(
@@ -536,7 +556,7 @@
       .set("cursorHeight", 0.85)
       .set("lineNumbers", true)
       .set("tabSize", prefs.tabSize())
-      .set("mode", getContentType(meta))
+      .set("mode", largeFile ? null : getContentType(meta))
       .set("lineWrapping", false)
       .set("styleSelectedText", true)
       .set("showTrailingSpace", prefs.showWhitespaceErrors())
@@ -573,14 +593,26 @@
     prefsAction.update();
   }
 
-  void setSyntaxHighlighting(final boolean b) {
-    operation(new Runnable() {
-      @Override
-      public void run() {
-        cmA.setOption("mode", b ? getContentType(diff.meta_a()) : null);
-        cmB.setOption("mode", b ? getContentType(diff.meta_b()) : null);
-      }
-    });
+  void setSyntaxHighlighting(boolean b) {
+    if (b) {
+      injectMode(diff, new AsyncCallback<Void>() {
+        @Override
+        public void onSuccess(Void result) {
+          if (prefs.syntaxHighlighting()) {
+            cmA.setOption("mode", getContentType(diff.meta_a()));
+            cmB.setOption("mode", getContentType(diff.meta_b()));
+          }
+        }
+
+        @Override
+        public void onFailure(Throwable caught) {
+          prefs.syntaxHighlighting(false);
+        }
+      });
+    } else {
+      cmA.setOption("mode", (String) null);
+      cmB.setOption("mode", (String) null);
+    }
   }
 
   void setContext(final int context) {
@@ -1291,7 +1323,7 @@
     String rev = String.valueOf(revision.get());
     Gerrit.display(
       PageLinks.toChange(changeId, rev),
-      new ChangeScreen2(changeId, b, rev, openReplyBox));
+      new ChangeScreen2(changeId, b, rev, openReplyBox, false));
   }
 
   private Runnable openClosePublished(final CodeMirror cm) {
@@ -1547,6 +1579,13 @@
         : null;
   }
 
+  private void injectMode(DiffInfo diffInfo, AsyncCallback<Void> cb) {
+    new ModeInjector()
+      .add(getContentType(diffInfo.meta_a()))
+      .add(getContentType(diffInfo.meta_b()))
+      .inject(cb);
+  }
+
   DiffPreferences getPrefs() {
     return prefs;
   }
@@ -1624,4 +1663,9 @@
         }
       });
   }
+
+  private static boolean isLargeFile(DiffInfo diffInfo) {
+    return (diffInfo.meta_a() != null && diffInfo.meta_a().lines() > 500)
+        || (diffInfo.meta_b() != null && diffInfo.meta_b().lines() > 500);
+  }
 }
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
index c39070f..9c8ec57 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/gerrit.css
@@ -371,7 +371,7 @@
   text-align: center;
   font-weight: bold;
   background: #FFF1A8;
-  z-index: 10;
+  z-index: 200;
 }
 
 
@@ -539,7 +539,8 @@
   height: 20px;
 }
 
-.changeTable a.gwt-InlineHyperlink {
+.changeTable a.gwt-InlineHyperlink,
+.changeTable a.gwt-Anchor {
   color: #222 !important;
 }
 
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
index edf1664..e4ac7b1 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/Loader.java
@@ -95,6 +95,10 @@
       km.remove(s);
     }
     CodeMirror.addKeyMap("vim_ro", km);
+    CodeMirror.mapVimKey("j", "gj");
+    CodeMirror.mapVimKey("k", "gk");
+    CodeMirror.mapVimKey("Down", "gj");
+    CodeMirror.mapVimKey("Up", "gk");
   }
 
   private static void error(Exception e) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/AllRequestFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/AllRequestFilter.java
index c8d237c..3b48b65 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/AllRequestFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/AllRequestFilter.java
@@ -69,10 +69,16 @@
 
     @Override
     public void init(FilterConfig config) throws ServletException {
+      for (AllRequestFilter f: filters) {
+        f.init(config);
+      }
     }
 
     @Override
     public void destroy() {
+      for (AllRequestFilter f: filters) {
+        f.destroy();
+      }
     }
   }
 
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
index 0cfdf0e..7f6a2df 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/GerritConfigProvider.java
@@ -129,12 +129,10 @@
     config.setLargeChangeSize(cfg.getInt("change", "largeChange", 500));
     config.setNewFeatures(cfg.getBoolean("gerrit", "enableNewFeatures", true));
 
-    config.setReportBugUrl(cfg.getString("gerrit", null, "reportBugUrl"));
-    if (config.getReportBugUrl() == null) {
-      config.setReportBugUrl("http://code.google.com/p/gerrit/issues/list");
-    } else if (config.getReportBugUrl().isEmpty()) {
-      config.setReportBugUrl(null);
-    }
+    final String reportBugUrl = cfg.getString("gerrit", null, "reportBugUrl");
+    config.setReportBugUrl(reportBugUrl != null ?
+        reportBugUrl : "http://code.google.com/p/gerrit/issues/list");
+    config.setReportBugText(cfg.getString("gerrit", null, "reportBugText"));
 
     config.setGitBasicAuth(authConfig.isGitBasicAuth());
 
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
index c55f9d3..763075e 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectBasicAuthFilter.java
@@ -169,7 +169,7 @@
       if (sc == SC_UNAUTHORIZED) {
         StringBuilder v = new StringBuilder();
         v.append(LIT_BASIC);
-        v.append("realm=\"" + REALM_NAME + "\"");
+        v.append("realm=\"").append(REALM_NAME).append("\"");
         setHeader(WWW_AUTHENTICATE, v.toString());
       } else if (containsHeader(WWW_AUTHENTICATE)) {
         setHeader(WWW_AUTHENTICATE, null);
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
index bbbe9f8..45e4504 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/ProjectDigestFilter.java
@@ -293,7 +293,7 @@
       if (sc == SC_UNAUTHORIZED) {
         StringBuilder v = new StringBuilder();
         v.append("Digest");
-        v.append(" realm=\"" + REALM_NAME + "\"");
+        v.append(" realm=\"").append(REALM_NAME).append("\"");
 
         String url = urlProvider.get();
         if (url == null) {
@@ -303,14 +303,14 @@
           }
         }
         if (url != null && !url.isEmpty()) {
-          v.append(", domain=\"" + url + "\"");
+          v.append(", domain=\"").append(url).append("\"");
         }
 
         v.append(", qop=\"auth\"");
         if (stale != null) {
-          v.append(", stale=" + stale);
+          v.append(", stale=").append(stale);
         }
-        v.append(", nonce=\"" + newNonce() + "\"");
+        v.append(", nonce=\"").append(newNonce()).append("\"");
         setHeader(WWW_AUTHENTICATE, v.toString());
 
       } else if (containsHeader(WWW_AUTHENTICATE)) {
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
index 644e30e..8f66b05 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/plugins/HttpPluginServlet.java
@@ -323,7 +323,7 @@
       String sectionTitle, StringBuilder md, String prefix,
       int nameOffset) throws IOException {
     if (!entries.isEmpty()) {
-      md.append("## " + sectionTitle +  " ##\n");
+      md.append("## ").append(sectionTitle).append(" ##\n");
       for(JarEntry entry : entries) {
         String rsrc = entry.getName().substring(prefix.length());
         String entryTitle;
diff --git a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/XrdsServlet.java b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/XrdsServlet.java
index 98ad11d..4719a84 100644
--- a/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/XrdsServlet.java
+++ b/gerrit-openid/src/main/java/com/google/gerrit/httpd/auth/openid/XrdsServlet.java
@@ -43,7 +43,7 @@
   protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
       throws IOException {
     final StringBuilder r = new StringBuilder();
-    r.append("<?xml version=\"1.0\" encoding=\"" + ENC + "\"?>");
+    r.append("<?xml version=\"1.0\" encoding=\"").append(ENC).append("\"?>");
     r.append("<xrds:XRDS");
     r.append(" xmlns:xrds=\"xri://$xrds\"");
     r.append(" xmlns:openid=\"http://openid.net/xmlns/1.0\"");
@@ -51,7 +51,8 @@
     r.append("<XRD>");
     r.append("<Service priority=\"1\">");
     r.append("<Type>http://specs.openid.net/auth/2.0/return_to</Type>");
-    r.append("<URI>" + url.get() + OpenIdServiceImpl.RETURN_URL + "</URI>");
+    r.append("<URI>").append(url.get()).append(OpenIdServiceImpl.RETURN_URL)
+     .append("</URI>");
     r.append("</Service>");
     r.append("</XRD>");
     r.append("</xrds:XRDS>");
diff --git a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
index 31c303d..2257ea2 100644
--- a/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
+++ b/gerrit-reviewdb/src/main/java/com/google/gerrit/reviewdb/client/AccountGeneralPreferences.java
@@ -46,7 +46,10 @@
     ISO("MM-dd", "yyyy-MM-dd"),
 
     /** European style dates: 27. Apr, 27.04.2010 */
-    EURO("d. MMM", "dd.MM.yyyy");
+    EURO("d. MMM", "dd.MM.yyyy"),
+
+    /** UK style dates: 27/04, 27/04/2010 */
+    UK("dd/MM", "dd/MM/yyyy");
 
     private final String shortFormat;
     private final String longFormat;
diff --git a/gerrit-server/BUCK b/gerrit-server/BUCK
index 58ea18e..5e992cd9 100644
--- a/gerrit-server/BUCK
+++ b/gerrit-server/BUCK
@@ -2,10 +2,8 @@
   'src/main/java/com/google/gerrit/server/documentation/Constants.java',
 ]
 
-SRCS = glob([
-    'src/main/java/**/*.java',
-    'src/test/java/com/google/gerrit/server/project/Util.java',
-  ],
+SRCS = glob(
+  ['src/main/java/**/*.java'],
   excludes = CONSTANTS_SRC,
 )
 RESOURCES =  glob(['src/main/resources/**/*'])
@@ -80,7 +78,10 @@
   visibility = ['PUBLIC'],
 )
 
-TESTUTIL = glob(['src/test/java/com/google/gerrit/testutil/**/*.java'])
+TESTUTIL = glob([
+  'src/test/java/com/google/gerrit/testutil/**/*.java',
+  'src/test/java/com/google/gerrit/server/project/Util.java',
+  ])
 java_library(
   name = 'testutil',
   srcs = TESTUTIL,
@@ -129,11 +130,13 @@
   deps = [
     ':prolog_test_case',
     ':server',
+    ':testutil',
     '//gerrit-common:server',
     '//gerrit-reviewdb:server',
     '//gerrit-server/src/main/prolog:common',
     '//lib:gwtorm',
     '//lib:junit',
+    '//lib/jgit:jgit',
     '//lib/guice:guice',
     '//lib/prolog:prolog-cafe',
   ],
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
index afba67f..dc876b1 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ChangeUtil.java
@@ -323,10 +323,11 @@
         ChangeMessage cmsg = new ChangeMessage(
             new ChangeMessage.Key(changeId, messageUUID(db.get())),
             user().getAccountId(), TimeUtil.nowTs(), patchSetId);
-        StringBuilder msgBuf =
-            new StringBuilder("Patch Set " + patchSetId.get() + ": Reverted");
+        StringBuilder msgBuf = new StringBuilder();
+        msgBuf.append("Patch Set ").append(patchSetId.get()).append(": Reverted");
         msgBuf.append("\n\n");
-        msgBuf.append("This patchset was reverted in change: " + change.getKey().get());
+        msgBuf.append("This patchset was reverted in change: ")
+              .append(change.getKey().get());
         cmsg.setMessage(msgBuf.toString());
 
         ins.setMessage(cmsg).insert();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/DefaultFileExtensionRegistry.java b/gerrit-server/src/main/java/com/google/gerrit/server/DefaultFileExtensionRegistry.java
index 15062ac..bc41fea 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/DefaultFileExtensionRegistry.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/DefaultFileExtensionRegistry.java
@@ -30,12 +30,17 @@
   private static final MimeType INI = newMimeType("text/x-ini", 2);
   private static final MimeType PYTHON = newMimeType("text/x-python", 2);
 
-  private static final ImmutableMap<String, MimeType> TYPES = ImmutableMap.of(
-      ".gitmodules", INI,
-      "project.config", INI,
-      "BUCK", PYTHON,
-      "defs", newMimeType(PYTHON.toString(), 1),
-      "go", newMimeType("text/x-go", 1));
+  private static final ImmutableMap<String, MimeType> TYPES =
+    ImmutableMap.<String,MimeType>builder()
+      .put(".gitmodules", INI)
+      .put("project.config", INI)
+      .put("BUCK", PYTHON)
+      .put("defs", newMimeType(PYTHON.toString(), 1))
+      .put("py", newMimeType(PYTHON.toString(), 1))
+      .put("go", newMimeType("text/x-go", 1))
+      .put("cxx", newMimeType("text/x-c++src", 1))
+      .put("hxx", newMimeType("text/x-c++hdr", 1))
+      .build();
 
   private static MimeType newMimeType(String type, final int specificity) {
     return new MimeType(type) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
index 33d2116..d0418eb 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/SetPreferences.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.CommentVisibilityStrategy;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DateFormat;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DiffView;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.ChangeScreen;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadCommand;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
 import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.TimeFormat;
@@ -50,6 +51,7 @@
     Boolean sizeBarInChangeTable;
     CommentVisibilityStrategy commentVisibilityStrategy;
     DiffView diffView;
+    ChangeScreen changeScreen;
   }
 
   private final Provider<CurrentUser> self;
@@ -131,6 +133,9 @@
       if (i.diffView != null) {
         p.setDiffView(i.diffView);
       }
+      if (i.changeScreen != null) {
+        p.setChangeScreen(i.changeScreen);
+      }
 
       db.accounts().update(Collections.singleton(a));
       db.commit();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
index f206a3d..4beb70d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/CherryPickChange.java
@@ -252,12 +252,12 @@
         new ChangeMessage.Key(
             patchSetId.getParentKey(), ChangeUtil.messageUUID(db)),
         currentUser.getAccountId(), TimeUtil.nowTs(), patchSetId);
-    StringBuilder msgBuf =
-        new StringBuilder("Patch Set " + patchSetId.get()
-            + ": Cherry Picked");
+    StringBuilder msgBuf = new StringBuilder();
+    msgBuf.append("Patch Set ").append(patchSetId.get())
+          .append(": Cherry Picked");
     msgBuf.append("\n\n");
-    msgBuf.append("This patchset was cherry picked to change: "
-        + dest.getKey().get());
+    msgBuf.append("This patchset was cherry picked to change: ")
+          .append(dest.getKey().get());
     cmsg.setMessage(msgBuf.toString());
     return cmsg;
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
index 04136bd..f0365b7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
@@ -132,12 +132,14 @@
         result.metaA = new FileMeta();
         result.metaA.name = Objects.firstNonNull(ps.getOldName(), ps.getNewName());
         result.metaA.setContentType(ps.getFileModeA(), ps.getMimeTypeA());
+        result.metaA.lines = ps.getA().size();
       }
 
       if (ps.getDisplayMethodB() != DisplayMethod.NONE) {
         result.metaB = new FileMeta();
         result.metaB.name = ps.getNewName();
         result.metaB.setContentType(ps.getFileModeB(), ps.getMimeTypeB());
+        result.metaB.lines = ps.getB().size();
       }
 
       if (intraline) {
@@ -179,7 +181,7 @@
   static class FileMeta {
     String name;
     String contentType;
-    String url;
+    Integer lines;
 
     void setContentType(FileMode fileMode, String mimeType) {
       switch (fileMode) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
index eae7494..53c6e79 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/MergeabilityChecker.java
@@ -47,6 +47,7 @@
 import com.google.inject.ProvisionException;
 
 import org.eclipse.jgit.errors.ConfigInvalidException;
+import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.ObjectId;
 import org.slf4j.Logger;
@@ -116,16 +117,9 @@
     if (ref.equals(GitRepositoryManager.REF_CONFIG)) {
       Project.NameKey p = new Project.NameKey(event.getProjectName());
       try {
-        ProjectConfig oldCfg =
-            ProjectConfig.read(metaDataUpdateFactory.create(p),
-                ObjectId.fromString(event.getOldObjectId()));
-        ProjectConfig newCfg =
-            ProjectConfig.read(metaDataUpdateFactory.create(p),
-                ObjectId.fromString(event.getNewObjectId()));
-        if (!oldCfg.getProject().getSubmitType().equals(newCfg.getProject().getSubmitType())
-            || oldCfg.getProject().getUseContentMerge() != newCfg.getProject().getUseContentMerge()
-            || (oldCfg.getRulesId() == null ? newCfg.getRulesId() != null
-                : !oldCfg.getRulesId().equals(newCfg.getRulesId()))) {
+        ProjectConfig oldCfg = parseConfig(p, event.getOldObjectId());
+        ProjectConfig newCfg = parseConfig(p, event.getNewObjectId());
+        if (recheckMerges(oldCfg, newCfg)) {
           try {
             new ProjectUpdateTask(schemaFactory, p).call();
           } catch (Exception e) {
@@ -145,6 +139,26 @@
     }
   }
 
+  private boolean recheckMerges(ProjectConfig oldCfg, ProjectConfig newCfg) {
+    if (oldCfg == null || newCfg == null) {
+      return true;
+    }
+    return !oldCfg.getProject().getSubmitType().equals(newCfg.getProject().getSubmitType())
+        || oldCfg.getProject().getUseContentMerge() != newCfg.getProject().getUseContentMerge()
+        || (oldCfg.getRulesId() == null
+            ? newCfg.getRulesId() != null
+            : !oldCfg.getRulesId().equals(newCfg.getRulesId()));
+  }
+
+  private ProjectConfig parseConfig(Project.NameKey p, String idStr)
+      throws IOException, ConfigInvalidException, RepositoryNotFoundException {
+    ObjectId id = ObjectId.fromString(idStr);
+    if (ObjectId.zeroId().equals(id)) {
+      return null;
+    }
+    return ProjectConfig.read(metaDataUpdateFactory.create(p), id);
+  }
+
   /**
    * Updates the mergeability flag of the change asynchronously. If the
    * mergeability flag is updated the change is reindexed.
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
index 5302b65..b74c56c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PatchSetInserter.java
@@ -365,8 +365,7 @@
   public static ChangeKind getChangeKind(MergeUtil.Factory mergeUtilFactory, ProjectState project,
       Repository git, RevCommit prior, RevCommit next) {
     if (!next.getFullMessage().equals(prior.getFullMessage())) {
-      if (next.getTree() == prior.getTree()
-          && prior.getParent(0).equals(next.getParent(0))) {
+      if (next.getTree() == prior.getTree() && isSameParents(prior, next)) {
         return ChangeKind.NO_CODE_CHANGE;
       } else {
         return ChangeKind.REWORK;
@@ -379,7 +378,7 @@
     }
 
     if (next.getTree() == prior.getTree() &&
-       prior.getParent(0).equals(next.getParent(0))) {
+       isSameParents(prior, next)) {
       return ChangeKind.TRIVIAL_REBASE;
     }
 
@@ -404,6 +403,15 @@
     }
   }
 
+  private static boolean isSameParents(RevCommit prior, RevCommit next) {
+    if (prior.getParentCount() != next.getParentCount()) {
+      return false;
+    } else if (prior.getParentCount() == 0) {
+      return true;
+    }
+    return prior.getParent(0).equals(next.getParent(0));
+  }
+
   public class ChangeModifiedException extends InvalidChangeOperationException {
     private static final long serialVersionUID = 1L;
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
index 89e2f1a..0e8ba05 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Submit.java
@@ -268,17 +268,18 @@
 
               case REJECT:
                 if (msg.length() > 0) msg.append("; ");
-                msg.append("blocked by " + lbl.label);
+                msg.append("blocked by ").append(lbl.label);
                 continue;
 
               case NEED:
                 if (msg.length() > 0) msg.append("; ");
-                msg.append("needs " + lbl.label);
+                msg.append("needs ").append(lbl.label);
                 continue;
 
               case IMPOSSIBLE:
                 if (msg.length() > 0) msg.append("; ");
-                msg.append("needs " + lbl.label + " (check project access)");
+                msg.append("needs ").append(lbl.label)
+                   .append(" (check project access)");
                 continue;
 
               default:
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/contact/EncryptedContactStore.java b/gerrit-server/src/main/java/com/google/gerrit/server/contact/EncryptedContactStore.java
index 17c9060..40699c8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/contact/EncryptedContactStore.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/contact/EncryptedContactStore.java
@@ -173,17 +173,23 @@
     }
   }
 
+  @SuppressWarnings("deprecation")
+  private final PGPEncryptedDataGenerator cpk()
+      throws NoSuchProviderException, PGPException {
+    PGPEncryptedDataGenerator cpk =
+        new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, prng, "BC");
+    cpk.addMethod(dest);
+    return cpk;
+  }
+
   private byte[] encrypt(final String name, final Date date,
       final byte[] rawText) throws NoSuchProviderException, PGPException,
       IOException {
     final byte[] zText = compress(name, date, rawText);
-    final PGPEncryptedDataGenerator cpk =
-        new PGPEncryptedDataGenerator(PGPEncryptedData.CAST5, true, prng, "BC");
-    cpk.addMethod(dest);
 
     final ByteArrayOutputStream buf = new ByteArrayOutputStream();
     final ArmoredOutputStream aout = new ArmoredOutputStream(buf);
-    final OutputStream cout = cpk.open(aout, zText.length);
+    final OutputStream cout = cpk().open(aout, zText.length);
     cout.write(zText);
     cout.close();
     aout.close();
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
index 09355b4..ee610fc 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/MergeOp.java
@@ -750,8 +750,7 @@
       // dependencies.
       //
       StringBuilder m = new StringBuilder();
-      m.append("Change cannot be merged due"
-          + " to unsatisfiable dependencies.\n");
+      m.append("Change cannot be merged due to unsatisfiable dependencies.\n");
       m.append("\n");
       m.append("The following dependency errors were found:\n");
       m.append("\n");
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
index 2025225..14a8fe7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/SubmoduleOp.java
@@ -271,7 +271,7 @@
 
         msgbuf.append("\nProject: ");
         msgbuf.append(me.getKey().getParentKey().get());
-        msgbuf.append("  " + me.getValue().getName());
+        msgbuf.append("  ").append(me.getValue().getName());
         msgbuf.append("\n");
         if (modules.size() == 1 && msg != null) {
           msgbuf.append(msg);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
index 79ffb1f..0719c7d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java
@@ -71,18 +71,6 @@
     return revision != null ? revision.copy() : null;
   }
 
-  /** Initialize in-memory as though the repository branch doesn't exist. */
-  public void createInMemory() {
-    try {
-      revision = null;
-      onLoad();
-    } catch (IOException err) {
-      throw new RuntimeException("Unexpected IOException", err);
-    } catch (ConfigInvalidException err) {
-      throw new RuntimeException("Unexpected ConfigInvalidException", err);
-    }
-  }
-
   /**
    * Load the current version from the branch.
    * <p>
@@ -116,19 +104,13 @@
    */
   public void load(Repository db, ObjectId id) throws IOException,
       ConfigInvalidException {
-    if (id != null) {
-      reader = db.newObjectReader();
-      try {
-        revision = new RevWalk(reader).parseCommit(id);
-        onLoad();
-      } finally {
-        reader.release();
-        reader = null;
-      }
-    } else {
-      // The branch does not yet exist.
-      revision = null;
+    reader = db.newObjectReader();
+    try {
+      revision = id != null ? new RevWalk(reader).parseCommit(id) : null;
       onLoad();
+    } finally {
+      reader.release();
+      reader = null;
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
index 7357279..05dbf0e 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/validators/CommitValidators.java
@@ -519,9 +519,9 @@
       PersonIdent who, IdentifiedUser currentUser, String canonicalWebUrl) {
     StringBuilder sb = new StringBuilder();
     sb.append("\n");
-    sb.append("ERROR:  In commit " + c.name() + "\n");
-    sb.append("ERROR:  " + type + " email address " + who.getEmailAddress()
-        + "\n");
+    sb.append("ERROR:  In commit ").append(c.name()).append("\n");
+    sb.append("ERROR:  ").append(type).append(" email address ")
+      .append(who.getEmailAddress()).append("\n");
     sb.append("ERROR:  does not match your user account.\n");
     sb.append("ERROR:\n");
     if (currentUser.getEmailAddresses().isEmpty()) {
@@ -529,14 +529,14 @@
     } else {
       sb.append("ERROR:  The following addresses are currently registered:\n");
       for (String address : currentUser.getEmailAddresses()) {
-        sb.append("ERROR:    " + address + "\n");
+        sb.append("ERROR:    ").append(address).append("\n");
       }
     }
     sb.append("ERROR:\n");
     if (canonicalWebUrl != null) {
       sb.append("ERROR:  To register an email address, please visit:\n");
-      sb.append("ERROR:  " + canonicalWebUrl + "#" + PageLinks.SETTINGS_CONTACT
-          + "\n");
+      sb.append("ERROR:  ").append(canonicalWebUrl).append("#")
+        .append(PageLinks.SETTINGS_CONTACT).append("\n");
     }
     sb.append("\n");
     return new CommitValidationMessage(sb.toString(), false);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
index 39d0ff8..8498b86 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/ChangeEmail.java
@@ -226,9 +226,9 @@
       StringBuilder detail = new StringBuilder();
 
       if (patchSetInfo != null) {
-        detail.append(patchSetInfo.getMessage().trim() + "\n");
+        detail.append(patchSetInfo.getMessage().trim()).append("\n");
       } else {
-        detail.append(change.getSubject().trim() + "\n");
+        detail.append(change.getSubject().trim()).append("\n");
       }
 
       if (patchSet != null) {
@@ -238,7 +238,8 @@
           if (Patch.COMMIT_MSG.equals(p.getNewName())) {
             continue;
           }
-          detail.append(p.getChangeType().getCode() + " " + p.getNewName() + "\n");
+          detail.append(p.getChangeType().getCode())
+                .append(" ").append(p.getNewName()).append("\n");
         }
         detail.append(MessageFormat.format("" //
             + "{0,choice,0#0 files|1#1 file|1<{0} files} changed, " //
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/mail/SmtpEmailSender.java b/gerrit-server/src/main/java/com/google/gerrit/server/mail/SmtpEmailSender.java
index b32e7f4..3f97cf7 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/mail/SmtpEmailSender.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/mail/SmtpEmailSender.java
@@ -177,8 +177,9 @@
         for (Address addr : rcpt) {
           if (!client.addRecipient(addr.email)) {
             String error = client.getReplyString();
-            rejected.append("Server " + smtpHost + " rejected recipient "
-                + addr + ": " + error);
+            rejected.append("Server ").append(smtpHost)
+                    .append(" rejected recipient ").append(addr)
+                    .append(": ").append(error);
           }
         }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
index 29f0138..7d521f2 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/PatchListLoader.java
@@ -170,19 +170,19 @@
 
     hdr.append("diff --git");
     if (aCommit != null) {
-      hdr.append(" a/" + Patch.COMMIT_MSG);
+      hdr.append(" a/").append(Patch.COMMIT_MSG);
     } else {
-      hdr.append(" " + FileHeader.DEV_NULL);
+      hdr.append(" ").append(FileHeader.DEV_NULL);
     }
-    hdr.append(" b/" + Patch.COMMIT_MSG);
+    hdr.append(" b/").append(Patch.COMMIT_MSG);
     hdr.append("\n");
 
     if (aCommit != null) {
-      hdr.append("--- a/" + Patch.COMMIT_MSG + "\n");
+      hdr.append("--- a/").append(Patch.COMMIT_MSG).append("\n");
     } else {
-      hdr.append("--- " + FileHeader.DEV_NULL + "\n");
+      hdr.append("--- ").append(FileHeader.DEV_NULL).append("\n");
     }
-    hdr.append("+++ b/" + Patch.COMMIT_MSG + "\n");
+    hdr.append("+++ b/").append(Patch.COMMIT_MSG).append("\n");
 
     Text aText =
         aCommit != null ? Text.forCommit(db, reader, aCommit) : Text.EMPTY;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java b/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java
index 97f53fc..f12b02b 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/patch/Text.java
@@ -89,7 +89,7 @@
   private static void appendPersonIdent(StringBuilder b, String field,
       PersonIdent person) {
     if (person != null) {
-      b.append(field + ":    ");
+      b.append(field).append(":    ");
       if (person.getName() != null) {
         b.append(" ");
         b.append(person.getName());
@@ -103,7 +103,7 @@
 
       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ZZZ");
       sdf.setTimeZone(person.getTimeZone());
-      b.append(field + "Date: ");
+      b.append(field).append("Date: ");
       b.append(sdf.format(person.getWhen()));
       b.append("\n");
     }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
index 08dba3a..ee27de3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/plugins/PluginLoader.java
@@ -508,7 +508,7 @@
       return loadJsPlugin(name, srcPlugin, snapshot);
     } else {
       throw new InvalidPluginException(String.format(
-          "Unsupported plugin type: ", srcPlugin.getName()));
+          "Unsupported plugin type: %s", srcPlugin.getName()));
     }
   }
 
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
index cbb56b3..3b6ce91 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/PermissionCollection.java
@@ -27,6 +27,7 @@
 import com.google.inject.Singleton;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -59,22 +60,23 @@
      *        priority order (project specific definitions must appear before
      *        inherited ones).
      * @param ref reference being accessed.
-     * @param username if the reference is a per-user reference, access sections
-     *        using the parameter variable "${username}" will first have {@code
-     *        username} inserted into them before seeing if they apply to the
-     *        reference named by {@code ref}. If null, per-user references are
-     *        ignored.
+     * @param usernames if the reference is a per-user reference, access sections
+     *        using the parameter variable "${username}" will first have each of
+     *        {@code usernames} inserted into them before seeing if they apply to
+     *        the reference named by {@code ref}. If null or empty, per-user
+     *        references are ignored.
      * @return map of permissions that apply to this reference, keyed by
      *         permission name.
      */
     PermissionCollection filter(Iterable<SectionMatcher> matcherList,
-        String ref, String username) {
+        String ref, Collection<String> usernames) {
       if (isRE(ref)) {
         ref = RefControl.shortestExample(ref);
       } else if (ref.endsWith("/*")) {
         ref = ref.substring(0, ref.length() - 1);
       }
 
+      boolean hasUsernames = usernames != null && !usernames.isEmpty();
       boolean perUser = false;
       Map<AccessSection, Project.NameKey> sectionToProject = Maps.newLinkedHashMap();
       for (SectionMatcher sm : matcherList) {
@@ -90,12 +92,17 @@
         // that will never be shared with non-user references, and the per-user
         // references are usually less frequent than the non-user references.
         //
-        if (username != null && !perUser
-            && sm.matcher instanceof RefPatternMatcher.ExpandParameters) {
-          perUser = ((RefPatternMatcher.ExpandParameters) sm.matcher).matchPrefix(ref);
-        }
-
-        if (sm.match(ref, username)) {
+        if (hasUsernames) {
+          if (!perUser && sm.matcher instanceof RefPatternMatcher.ExpandParameters) {
+            perUser = ((RefPatternMatcher.ExpandParameters) sm.matcher).matchPrefix(ref);
+          }
+          for (String username : usernames) {
+            if (sm.match(ref, username)) {
+              sectionToProject.put(sm.section, sm.project);
+              break;
+            }
+          }
+        } else if (sm.match(ref, null)) {
           sectionToProject.put(sm.section, sm.project);
         }
       }
@@ -140,21 +147,20 @@
         }
       }
 
-      return new PermissionCollection(permissions, ruleProps,
-          perUser ? username : null);
+      return new PermissionCollection(permissions, ruleProps, perUser);
     }
   }
 
   private final Map<String, List<PermissionRule>> rules;
   private final Map<PermissionRule, ProjectRef> ruleProps;
-  private final String username;
+  private final boolean perUser;
 
   private PermissionCollection(Map<String, List<PermissionRule>> rules,
       Map<PermissionRule, ProjectRef> ruleProps,
-      String username) {
+      boolean perUser) {
     this.rules = rules;
     this.ruleProps = ruleProps;
-    this.username = username;
+    this.perUser = perUser;
   }
 
   /**
@@ -162,7 +168,7 @@
    *         this collection, making the results user specific.
    */
   public boolean isUserSpecific() {
-    return username != null;
+    return perUser;
   }
 
   /**
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
index 30cfc2b..1156677 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ProjectControl.java
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.server.project;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 import com.google.gerrit.common.Nullable;
 import com.google.gerrit.common.PageLinks;
@@ -191,8 +192,15 @@
     }
     RefControl ctl = refControls.get(refName);
     if (ctl == null) {
+      ImmutableList.Builder<String> usernames = ImmutableList.<String> builder();
+      if (user.getUserName() != null) {
+        usernames.add(user.getUserName());
+      }
+      if (user instanceof IdentifiedUser) {
+        usernames.addAll(((IdentifiedUser) user).getEmailAddresses());
+      }
       PermissionCollection relevant =
-          permissionFilter.filter(access(), refName, user.getUserName());
+          permissionFilter.filter(access(), refName, usernames.build());
       ctl = new RefControl(this, refName, relevant);
       refControls.put(refName, ctl);
     }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
index 0c8ecb8..dcf6841 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/RefPatternMatcher.java
@@ -105,7 +105,7 @@
 
       String u;
       if (isRE(template.getPattern())) {
-        u = username.replace(".", "\\.");
+        u = Pattern.quote(username);
       } else {
         u = username;
       }
diff --git a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
index 03a82d4..cf7ace2 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/rules/GerritCommonTest.java
@@ -15,19 +15,20 @@
 package com.google.gerrit.rules;
 
 import static com.google.gerrit.common.data.Permission.LABEL;
-import static com.google.gerrit.server.project.Util.value;
 import static com.google.gerrit.server.project.Util.category;
 import static com.google.gerrit.server.project.Util.grant;
+import static com.google.gerrit.server.project.Util.value;
 
-import com.google.gerrit.server.git.ProjectConfig;
-import com.google.gerrit.server.group.SystemGroupBackend;
-import com.google.gerrit.server.project.Util;
-import com.google.gerrit.server.util.TimeUtil;
 import com.google.gerrit.common.data.LabelType;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.Branch;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.server.group.SystemGroupBackend;
+import com.google.gerrit.server.project.Util;
+import com.google.gerrit.server.util.TimeUtil;
+import com.google.gerrit.testutil.InMemoryRepositoryManager;
 import com.google.inject.AbstractModule;
 
 import org.junit.Before;
@@ -67,7 +68,7 @@
     });
 
     local = new ProjectConfig(localKey);
-    local.createInMemory();
+    local.load(InMemoryRepositoryManager.newRepository(localKey));
     Q.setRefPatterns(Arrays.asList("refs/heads/develop"));
 
     local.getLabelSections().put(V.getName(), V);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
index b9e9a4c..dea4af8 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/SubmoduleOpTest.java
@@ -828,7 +828,7 @@
    * </p>
    *
    * @param gitModulesFileContent The .gitmodules file content.
-   * @param mergedBranch The {@link Branch.NameKey} instance representing the
+   * @param mergedBranch The {@code Branch.NameKey} instance representing the
    *        project/branch the commit was merged.
    * @param extractedSubscriptions The subscription rows extracted from
    *        gitmodules file.
@@ -854,7 +854,7 @@
    * </p>
    *
    * @param gitModulesFileContent The .gitmodules file content.
-   * @param mergedBranch The {@link Branch.NameKey} instance representing the
+   * @param mergedBranch The {@code Branch.NameKey} instance representing the
    *        project/branch the commit was merged.
    * @param extractedSubscriptions The subscription rows extracted from
    *        gitmodules file.
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
index 94b0632..594580f 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/RefControlTest.java
@@ -27,6 +27,7 @@
 import static com.google.gerrit.server.project.Util.DEVS;
 import static com.google.gerrit.server.project.Util.doNotInherit;
 import static com.google.gerrit.server.project.Util.grant;
+import static com.google.gerrit.testutil.InMemoryRepositoryManager.newRepository;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
@@ -61,7 +62,7 @@
   @Before
   public void setUp() throws Exception {
     local = new ProjectConfig(localKey);
-    local.createInMemory();
+    local.load(newRepository(localKey));
     util.add(local);
   }
 
@@ -157,14 +158,14 @@
   }
 
   @Test
-  public void testInheritDuplicateSections() {
+  public void testInheritDuplicateSections() throws Exception {
     grant(util.getParentConfig(), READ, ADMIN, "refs/*");
     grant(local, READ, DEVS, "refs/heads/*");
     local.getProject().setParentName(util.getParentConfig().getProject().getName());
     assertTrue("a can read", util.user(local, "a", ADMIN).isVisible());
 
     local = new ProjectConfig(new Project.NameKey("local"));
-    local.createInMemory();
+    local.load(newRepository(localKey));
     grant(local, READ, DEVS, "refs/*");
     assertTrue("d can read", util.user(local, "d", DEVS).isVisible());
   }
@@ -246,6 +247,18 @@
   }
 
   @Test
+  public void testUsernameEmailPatternWithRegex() {
+    grant(local, READ, DEVS, "^refs/sb/${username}/heads/.*");
+
+    ProjectControl u = util.user(local, "d.v@ger-rit.org", DEVS);
+    ProjectControl d = util.user(local, "dev@ger-rit.org", DEVS);
+    assertFalse("u can't read",
+        u.controlForRef("refs/sb/dev@ger-rit.org/heads/foobar").isVisible());
+    assertTrue("d can read",
+        d.controlForRef("refs/sb/dev@ger-rit.org/heads/foobar").isVisible());
+  }
+
+  @Test
   public void testSortWithRegex() {
     grant(local, READ, DEVS, "^refs/heads/.*");
     grant(util.getParentConfig(), READ, ANONYMOUS_USERS, "^refs/heads/.*-QA-.*");
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
index 3d1df7a..ec83824 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/project/Util.java
@@ -41,10 +41,13 @@
 import com.google.gerrit.server.config.SitePaths;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.ProjectConfig;
+import com.google.gerrit.testutil.InMemoryRepositoryManager;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Repository;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -116,16 +119,22 @@
   private final ProjectCache projectCache;
   private final CapabilityControl.Factory capabilityControlFactory;
   private final PermissionCollection.Factory sectionSorter;
+  private final GitRepositoryManager repoManager;
 
   private final AllProjectsName allProjectsName = new AllProjectsName("parent");
   private final ProjectConfig parent = new ProjectConfig(allProjectsName);
 
   public Util() {
     all = new HashMap<Project.NameKey, ProjectState>();
-    parent.createInMemory();
-    parent.getLabelSections().put(CR.getName(), CR);
-
-    add(parent);
+    repoManager = new InMemoryRepositoryManager();
+    try {
+      Repository repo = repoManager.createRepository(allProjectsName);
+      parent.load(repo);
+      parent.getLabelSections().put(CR.getName(), CR);
+      add(parent);
+    } catch (IOException | ConfigInvalidException e) {
+      throw new RuntimeException(e);
+    }
 
     projectCache = new ProjectCache() {
       @Override
@@ -199,15 +208,19 @@
 
   public void add(ProjectConfig pc) {
     PrologEnvironment.Factory envFactory = null;
-    GitRepositoryManager mgr = null;
     ProjectControl.AssistedFactory projectControlFactory = null;
     RulesCache rulesCache = null;
     SitePaths sitePaths = null;
     List<CommentLinkInfo> commentLinks = null;
 
+    try {
+      repoManager.createRepository(pc.getProject().getNameKey());
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
     all.put(pc.getProject().getNameKey(), new ProjectState(sitePaths,
-        projectCache, allProjectsName, projectControlFactory, envFactory, mgr,
-        rulesCache, commentLinks, pc));
+        projectCache, allProjectsName, projectControlFactory, envFactory,
+        repoManager, rulesCache, commentLinks, pc));
   }
 
   public ProjectControl user(ProjectConfig local, AccountGroup.UUID... memberOf) {
diff --git a/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryRepositoryManager.java b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryRepositoryManager.java
index c6626f0..328df75 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryRepositoryManager.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/testutil/InMemoryRepositoryManager.java
@@ -31,6 +31,10 @@
 
 /** Repository manager that uses in-memory repositories. */
 public class InMemoryRepositoryManager implements GitRepositoryManager {
+  public static InMemoryRepository newRepository(Project.NameKey name) {
+    return new Repo(name);
+  }
+
   private static class Description extends DfsRepositoryDescription {
     private String desc;
 
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
index 4ac8f64..40f7c7d 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/BaseCommand.java
@@ -405,7 +405,7 @@
       m.append(context.getCommandLine());
       if (userProvider.get().isIdentifiedUser()) {
         IdentifiedUser u = (IdentifiedUser) userProvider.get();
-        m.append(" (" + u.getAccount().getUserName() + ")");
+        m.append(" (").append(u.getAccount().getUserName()).append(")");
       }
       this.taskName = m.toString();
     }
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java
index e08d411..67144cd 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/SshDaemon.java
@@ -436,7 +436,8 @@
       final NamedFactory<T> n = find(name, avail);
       if (n == null) {
         final StringBuilder msg = new StringBuilder();
-        msg.append("sshd." + key + " = " + name + " unsupported; only ");
+        msg.append("sshd.").append(key).append(" = ").append(name)
+           .append(" unsupported; only ");
         for (int i = 0; i < avail.length; i++) {
           if (avail[i] == null) {
             continue;
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java
index c68dc26..fa48084 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/AdminSetParent.java
@@ -130,16 +130,18 @@
       if (allProjectsName.equals(nameKey)) {
         // Don't allow the wild card project to have a parent.
         //
-        err.append("error: Cannot set parent of '" + name + "'\n");
+        err.append("error: Cannot set parent of '").append(name).append("'\n");
         continue;
       }
 
       if (grandParents.contains(nameKey) || nameKey.equals(newParentKey)) {
         // Try to avoid creating a cycle in the parent pointers.
         //
-        err.append("error: Cycle exists between '" + name + "' and '"
-            + (newParentKey != null ? newParentKey.get() : allProjectsName.get())
-            + "'\n");
+        err.append("error: Cycle exists between '")
+           .append(name)
+           .append("' and '")
+           .append(newParentKey != null ? newParentKey.get() : allProjectsName.get())
+           .append("'\n");
         continue;
       }
 
@@ -155,15 +157,15 @@
           md.close();
         }
       } catch (RepositoryNotFoundException notFound) {
-        err.append("error: Project " + name + " not found\n");
+        err.append("error: Project ").append(name).append(" not found\n");
       } catch (IOException e) {
         final String msg = "Cannot update project " + name;
         log.error(msg, e);
-        err.append("error: " + msg + "\n");
+        err.append("error: ").append(msg).append("\n");
       } catch (ConfigInvalidException e) {
         final String msg = "Cannot update project " + name;
         log.error(msg, e);
-        err.append("error: " + msg + "\n");
+        err.append("error: ").append(msg).append("\n");
       }
 
       projectCache.evict(nameKey);
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
index 2a8650a..92444f4 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/Receive.java
@@ -105,8 +105,8 @@
       // we want to present this error to the user
       if (badStream.getCause() instanceof TooLargeObjectInPackException) {
         StringBuilder msg = new StringBuilder();
-        msg.append("Receive error on project \""
-            + projectControl.getProject().getName() + "\"");
+        msg.append("Receive error on project \"")
+           .append(projectControl.getProject().getName()).append("\"");
         msg.append(" (user ");
         msg.append(currentUser.getAccount().getUserName());
         msg.append(" account ");
@@ -121,10 +121,10 @@
       // Log what the heck is going on, as detailed as we can.
       //
       StringBuilder msg = new StringBuilder();
-      msg.append("Unpack error on project \""
-          + projectControl.getProject().getName() + "\":\n");
+      msg.append("Unpack error on project \"")
+         .append(projectControl.getProject().getName()).append("\":\n");
 
-      msg.append("  AdvertiseRefsHook: " + rp.getAdvertiseRefsHook());
+      msg.append("  AdvertiseRefsHook: ").append(rp.getAdvertiseRefsHook());
       if (rp.getAdvertiseRefsHook() == AdvertiseRefsHook.DEFAULT) {
         msg.append("DEFAULT");
       } else if (rp.getAdvertiseRefsHook() instanceof VisibleRefFilter) {
@@ -136,10 +136,10 @@
 
       if (rp.getAdvertiseRefsHook() instanceof VisibleRefFilter) {
         Map<String, Ref> adv = rp.getAdvertisedRefs();
-        msg.append("  Visible references (" + adv.size() + "):\n");
+        msg.append("  Visible references (").append(adv.size()).append("):\n");
         for (Ref ref : adv.values()) {
-          msg.append("  - " + ref.getObjectId().abbreviate(8).name() + " "
-              + ref.getName() + "\n");
+          msg.append("  - ").append(ref.getObjectId().abbreviate(8).name())
+             .append(" ").append(ref.getName()).append("\n");
         }
 
         Map<String, Ref> allRefs =
@@ -151,10 +151,10 @@
           }
         }
 
-        msg.append("  Hidden references (" + hidden.size() + "):\n");
+        msg.append("  Hidden references (").append(hidden.size()).append("):\n");
         for (Ref ref : hidden) {
-          msg.append("  - " + ref.getObjectId().abbreviate(8).name() + " "
-              + ref.getName() + "\n");
+          msg.append("  - ").append(ref.getObjectId().abbreviate(8).name())
+              .append(" ").append(ref.getName()).append("\n");
         }
       }
 
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ScpCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ScpCommand.java
index 987380f..65f876f 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ScpCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/ScpCommand.java
@@ -203,7 +203,7 @@
         buf.append(TYPE_FILE);
         break;
     }
-    buf.append("0" + Integer.toOctalString(dir.getMode())); // perms
+    buf.append("0").append(Integer.toOctalString(dir.getMode())); // perms
     buf.append(" ");
     buf.append(len); // length
     buf.append(" ");
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
index b45fb3a..e0c2a97 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/SetProjectCommand.java
@@ -160,15 +160,15 @@
         md.close();
       }
     } catch (RepositoryNotFoundException notFound) {
-      err.append("error: Project " + name + " not found\n");
+      err.append("error: Project ").append(name).append(" not found\n");
     } catch (IOException e) {
       final String msg = "Cannot update project " + name;
       log.error(msg, e);
-      err.append("error: " + msg + "\n");
+      err.append("error: ").append(msg).append("\n");
     } catch (ConfigInvalidException e) {
       final String msg = "Cannot update project " + name;
       log.error(msg, e);
-      err.append("error: " + msg + "\n");
+      err.append("error: ").append(msg).append("\n");
     }
     projectCache.evict(ctlProject);