Merge 'v2.1.9^0'

* commit 'v2.1.9':
  Update JGit to patch security hole during clone

Change-Id: I7ee366b2f7f930da5f63dd5f173e47a33f280436
diff --git a/.gitignore b/.gitignore
index 0476c1d..f318b65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 /.classpath
 /.project
+/.settings
 /.settings/org.eclipse.jdt.core.prefs
 /.settings/org.maven.ide.eclipse.prefs
 /test_site
diff --git a/Documentation/Makefile b/Documentation/Makefile
index f167cc5..5522239 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -15,7 +15,7 @@
 ASCIIDOC       ?= asciidoc
 ASCIIDOC_EXTRA ?=
 SVN            ?= svn
-PUB_ROOT       ?= https://gerrit.googlecode.com/svn/documentation
+PUB_ROOT       ?= https://gerrit-documentation.googlecode.com/svn/Documentation
 
 all: html
 
@@ -74,6 +74,7 @@
 	@echo "FORMAT $@"
 	@rm -f $@+ $@
 	@$(ASCIIDOC) -a toc \
+		-a data-uri \
 		-a 'revision=$(REVISION)' \
 		-b xhtml11 \
 		-f asciidoc.conf \
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 0984935..8d89fa2 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -33,6 +33,7 @@
 to permit administrative users to otherwise access Gerrit as any
 other normal user would, without needing two different accounts.
 
+[[anonymous_users]]
 Anonymous Users
 ~~~~~~~~~~~~~~~
 
@@ -44,14 +45,47 @@
 Administrators and project owners can grant access rights to this
 group in order to permit anonymous users to view project changes,
 without requiring sign in first.  Currently it is only worthwhile
-to grant `Read Access` to this group as Gerrit requires an account
+to grant `Read` access to this group as Gerrit requires an account
 identity for all other operations.
 
+[[non-interactive_users]]
+Non-Interactive Users
+~~~~~~~~~~~~~~~~~~~~~
+
+This is an internal user group, members of this group are not expected
+to perform interactive operations on the Gerrit web frontend.
+
+However, sometimes such a user may need a separate thread pool in
+order to prevent it from grabbing threads from the interactive users.
+
+These users live in a second thread pool, which separates operations
+made by the non-interactive users from the ones made by the interactive
+users. This ensures that the interactive users can keep working when
+resources are tight.
+
+[[project_owners]]
+Project Owners
+~~~~~~~~~~~~~~
+
+Access rights assigned to this group are always evaluated within the
+context of a project to which the access rights apply. These rights
+therefore apply to all the users who are owners of this project.
+
+By assigning access rights to this group on a parent project Gerrit
+administrators can define a set of default access rights for
+<<category_owner,project owners>>. Child projects inherit these
+access rights where they are resolved to the users that own the child
+project.  Having default access rights for
+<<category_owner,project owners>> assigned on a parent project may
+avoid the need to initially configure access rights for
+newly created child projects.
+
+[[registered_users]]
 Registered Users
 ~~~~~~~~~~~~~~~~
 
 All signed-in users are automatically a member of this group (and
-also 'Anonymous Users', see above).
+also <<anonymous_users,'Anonymous Users'>>, see above).
 
 Any access rights assigned to this group are inherited by all
 users as soon as they sign-in to Gerrit.  If OpenID authentication
@@ -64,22 +98,7 @@
 cause it to become approved or rejected.
 
 Registered users are always permitted to make and publish comments
-on any change in any project they have `Read Access` to.
-
-Project Owners
-~~~~~~~~~~~~~~
-
-Access rights assigned to this group are always evaluated within the
-context of a project and are resolved to access rights for all users
-which own the project.
-
-By assigning access rights to this group on a parent project Gerrit
-administrators can define a set of default access rights for project
-owners. Child projects inherit these access rights where they are
-resolved to the users that own the child project.
-Having default access rights for projects owners assigned on a parent
-project may avoid the need to initially configure access rights for
-newly created child projects.
+on any change in any project they have `Read` access to.
 
 
 Account Groups
@@ -92,8 +111,8 @@
 Every group has one other group designated as its owner.  Users who
 are members of the owner group can:
 
-* Add users to this group
-* Remove users from this group
+* Add users and other groups to this group
+* Remove users and other groups from this group
 * Change the name of this group
 * Change the description of this group
 * Change the owner of this group, to another group
@@ -120,7 +139,7 @@
 ----------------------------
 
 A system wide access control list affecting all projects is stored in
-project "`\-- All Projects \--`".  This inheritance can be configured
+project "`All-Projects`".  This inheritance can be configured
 through link:cmd-set-project-parent.html[gerrit set-project-parent].
 
 Per-project access control lists are also supported.
@@ -147,13 +166,13 @@
 
 Permissions can be set on a single reference name to match one
 branch (e.g. `refs/heads/master`), or on a reference namespace
-(e.g. `refs/heads/\*`) to match any branch starting with that
-prefix. So a permission with `refs/heads/\*` will match
+(e.g. `refs/heads/*`) to match any branch starting with that
+prefix. So a permission with `refs/heads/*` will match
 `refs/heads/master` and `refs/heads/experimental`, etc.
 
 Reference names can also be described with a regular expression
-by prefixing the reference name with `\^`.  For example
-`\^refs/heads/[a-z]\{1,8\}` matches all lower case branch names
+by prefixing the reference name with `^`.  For example
+`^refs/heads/[a-z]{1,8}` matches all lower case branch names
 between 1 and 8 characters long.  Within a regular expression `.`
 is a wildcard matching any character, but may be escaped as `\.`.
 The link:http://www.brics.dk/automaton/[dk.brics.automaton library]
@@ -164,7 +183,7 @@
 References can have the current user name automatically included,
 creating dynamic access controls that change to match the currently
 logged in user.  For example to provide a personal sandbox space
-to all developers, `refs/heads/sandbox/$\{username\}/*` allowing
+to all developers, `refs/heads/sandbox/${username}/*` allowing
 the user 'joe' to use 'refs/heads/sandbox/joe/foo'.
 
 When evaluating a reference-level access right, Gerrit will use
@@ -175,12 +194,12 @@
 on the project:
 
 [options="header"]
-|=====================================================
-|Group            |Reference Name|Category   |Range
-|Registered Users |refs/heads/*  |Code Review| -1..+1
-|Foo Leads        |refs/heads/*  |Code Review| -2..+2
-|QA Leads         |refs/heads/qa |Code Review| -2..+2
-|=====================================================
+|===============================================================
+|Group            |Reference Name|Category   |Range   |Exclusive
+|Registered Users |refs/heads/*  |Code Review| -1..+1 |
+|Foo Leads        |refs/heads/*  |Code Review| -2..+2 |
+|QA Leads         |refs/heads/qa |Code Review| -2..+2 |
+|===============================================================
 
 Then the effective range permitted to be used by the user is
 `-2..+2`, as the user's membership of `Foo Leads` effectively grant
@@ -190,20 +209,21 @@
 
 It is possible to configure Gerrit to grant an exclusive ref level
 access control so that only users of a specific group can perform
-an operation on a project/reference pair. This is done by prefixing
-the reference specified with a `'-'`.
+an operation on a project/reference pair. This is done by ticking
+the exclusive flag when setting the permission for the
+`refs/heads/qa` branch.
 
 For example, if a user who is a member of `Foo Leads` tries to
 review a change destined for branch `refs/heads/qa` in a project,
 and the following ACLs are granted:
 
 [options="header"]
-|=====================================================
-|Group           |Reference Name|Category   |Range
-|Registered Users|refs/heads/*  |Code Review| -1..+1
-|Foo Leads       |refs/heads/*  |Code Review| -2..+2
-|QA Leads        |-refs/heads/qa|Code Review| -2..+2
-|=====================================================
+|==============================================================
+|Group           |Reference Name|Category   |Range   |Exclusive
+|Registered Users|refs/heads/*  |Code Review| -1..+1 |
+|Foo Leads       |refs/heads/*  |Code Review| -2..+2 |
+|QA Leads        |refs/heads/qa |Code Review| -2..+2 |X
+|==============================================================
 
 Then this user will not have `Code Review` rights on that change,
 since there is an exclusive access right in place for the
@@ -216,14 +236,13 @@
 would be needed:
 
 [options="header"]
-|=====================================================
-|Group           |Reference Name|Category   |Range
-|Registered Users|refs/heads/*  |Code Review| -1..+1
-|Foo Leads       |refs/heads/*  |Code Review| -2..+2
-|QA Leads        |-refs/heads/qa|Code Review| -2..+2
-|Foo Leads       |refs/heads/qa |Code Review| -2..+2
-|=====================================================
-
+|==============================================================
+|Group           |Reference Name|Category   |Range   |Exclusive
+|Registered Users|refs/heads/*  |Code Review| -1..+1 |
+|Foo Leads       |refs/heads/*  |Code Review| -2..+2 |
+|QA Leads        |refs/heads/qa |Code Review| -2..+2 |X
+|Foo Leads       |refs/heads/qa |Code Review| -2..+2 |
+|==============================================================
 
 OpenID Authentication
 ~~~~~~~~~~~~~~~~~~~~~
@@ -237,249 +256,64 @@
 All Projects
 ~~~~~~~~~~~~
 
-Any access right granted to a group within `\-- All Projects \--`
+Any access right granted to a group within `All-Projects`
 is automatically inherited by every other project in the same
 Gerrit instance.  These rights can be seen, but not modified,
 in any other project's `Access` administration tab.
 
-Only members of the group `Administrators` may edit the access
-control list for `\-- All Projects \--`.
+Only members of the groups with the `Administrate Server` capability
+may edit the access control list for `All-Projects`. By default this
+capability is given to the group `Administrators`, but can be given
+to more groups.
 
 Ownership of this project cannot be delegated to another group.
 This restriction is by design.  Granting ownership to another
 group gives nearly the same level of access as membership in
 `Administrators` does, as group members would be able to alter
-permissions for every managed project.
+permissions for every managed project including global capabilities.
 
 Per-Project
 ~~~~~~~~~~~
 
-The per-project ACL is evaluated before the global
-`\-- All Projects \--` ACL, permitting some limited override
-capability to project owners.  This behavior is generally only
-useful on the `Read Access` category when granting `-1 No Access`
-within a specific project to deny access to a group.
+The per-project ACL is evaluated before the global `All-Projects` ACL,
+permitting some limited override capability to project owners. This
+behavior is generally only useful on the `Read` category when
+granting 'DENY' within a specific project to deny a group access.
 
 
-Categories
-----------
+[[access_category]]
+Access Categories
+-----------------
 
 Gerrit comes pre-configured with several default categories that
 can be granted to groups within projects, enabling functionality
 for that group's members.
 
-[[category_OWN]]
-Owner
-~~~~~
+With the release of the Gerrit 2.2.x series, the web GUI for ACL
+configuration was rewritten from scratch.  Use this
+<<conversion_table,table>> to better understand the access rights
+conversions from the Gerrit 2.1.x to the Gerrit 2.2.x series.
 
-The `Owner` category controls which groups can modify the project's
-configuration.  Users who are members of an owner group can:
 
-* Change the project description
-* Create/delete a branch through the web UI (not SSH)
-* Grant/revoke any access rights, including `Owner`
+[[category_label-Verified]]
+Label: Verified
+~~~~~~~~~~~~~~~
 
-Note that project owners implicitly have branch creation or deletion
-through the web UI, but not through SSH.  To get SSH branch access
-project owners must grant an access right to a group they are a
-member of, just like for any other user.
-
-Ownership over a particular branch subspace may be delegated by
-entering a branch pattern.  To delegate control over all branches
-that begin with `qa/` to the QA group, add `Owner` category
-for reference `refs/heads/qa/\*`.  Members of the QA group can
-further refine access, but only for references that begin with
-`refs/heads/qa/`.
-
-[[category_READ]]
-Read Access
-~~~~~~~~~~~
-
-The `Read Access` category controls visibility to the project's
-changes, comments, code diffs, and Git access over SSH or HTTP.
-A user must have `Read Access +1` in order to see a project, its
-changes, or any of its data.
-
-This category has a special behavior, where the per-project ACL is
-evaluated before the global all projects ACL.  If the per-project
-ACL has granted `Read Access -1`, and does not otherwise grant
-`Read Access \+1`, then a `Read Access +1` in the all projects ACL
-is ignored.  This behavior is useful to hide a handful of projects
-on an otherwise public server.
-
-For an open source, public Gerrit installation it is common to grant
-`Read Access +1` to `Anonymous Users` in the `\-- All Projects
-\--` ACL, enabling casual browsing of any project's changes,
-as well as fetching any project's repository over SSH or HTTP.
-New projects can be temporarily hidden from public view by granting
-`Read Access -1` to `Anonymous Users` and granting `Read Access +1`
-to the project owner's group within the per-project ACL.
-
-For a private Gerrit installation using a trusted HTTP authentication
-source, granting `Read Access +1` to `Registered Users` may be more
-typical, enabling read access only to those users who have been
-able to authenticate through the HTTP access controls.  This may
-be suitable in a corporate deployment if the HTTP access control
-is already restricted to the correct set of users.
-
-[[category_READ_2]]
-Upload Access
-~~~~~~~~~~~~~
-
-The `Read Access +2` permits the user to upload a non-merge commit
-to the project's `refs/for/BRANCH` namespace, creating a new change
-for code review.
-
-Rather than place this permission in its own category, its chained
-into the Read Access category as a higher level of access.  A user
-must be able to clone or fetch the project in order to create a new
-commit on their local system, so in practice they must also have
-Read Access +1 to even develop a change.  Therefore upload access
-implies read access by simply being a higher level of it.
-
-For an open source, public Gerrit installation, it is common to
-grant `Read Access +1..+2` to `Registered Users` in the `\-- All
-Projects \--` ACL.  For more private installations, its common to
-simply grant `Read Access +1..+2` to all users of a project.
-
-[[category_READ_3]]
-Upload Merge Access
-~~~~~~~~~~~~~~~~~~~
-The `Read Access +3` permits the user to upload merge commits, but is
-otherwise identical to `Read Access +2`. Some projects wish to
-restrict merges to being created by Gerrit. By granting,
-`Read Access +1..+2`, the only merges that enter the system will be
-those created by Gerrit, or those pushed directly.
-
-[[category_pTAG]]
-Push Tag
-~~~~~~~~
-
-This category permits users to push an annotated tag object over
-SSH into the project's repository.  Typically this would be done
-with a command line such as:
-
-====
-  git push ssh://USER@HOST:PORT/PROJECT tag v1.0
-====
-
-Tags must be annotated (created with `git tag -a` or `git tag -s`),
-should exist in the `refs/tags/` namespace, and should be new.
-
-This category is intended to be used to publish tags when a project
-reaches a stable release point worth remembering in history.
-
-The range of values is:
-
-* +1 Create Signed Tag
-+
-A new signed tag may be created.  The tagger email address must be
-verified for the current user.
-
-* +2 Create Annotated Tag
-+
-A new annotated (unsigned) tag may be created.  The tagger email
-address must be verified for the current user.
-
-To push tags created by users other than the current user (such
-as tags mirrored from an upstream project), `Forge Identity +2`
-must be also granted in addition to `Push Tag >= +1`.
-
-To push lightweight (non annotated) tags, grant `Push Branch +2
-Create Branch` for reference name `refs/tags/*`, as lightweight
-tags are implemented just like branches in Git.
-
-To delete or overwrite an existing tag, grant `Push Branch +3
-Force Push Branch; Delete Branch` for reference name `refs/tags/*`,
-as deleting a tag requires the same permission as deleting a branch.
-
-[[category_pHD]]
-Push Branch
-~~~~~~~~~~~
-
-This category permits users to push directly into a branch over SSH,
-bypassing any code review process that would otherwise be used.
-
-This category has several possible values:
-
-* +1 Update Branch
-+
-Any existing branch can be fast-forwarded to a new commit.
-Creation of new branches is rejected.  Deletion of existing branches
-is rejected.  This is the safest mode as commits cannot be discarded.
-
-* +2 Create Branch
-+
-Implies 'Update Branch', but also allows the creation of a new branch
-if the name does not not already designate an existing branch name.
-Like update branch, existing commits cannot be discarded.
-
-* +3 Force Push Branch; Delete Branch
-+
-Implies both 'Update Branch' and 'Create Branch', but also allows an
-existing branch to be deleted. Since a force push is effectively a
-delete immediately followed by a create, but performed atomically on
-the server and logged, this level also permits forced push updates
-to branches.  This level may allow existing commits to be discarded
-from a project history.
-
-This category is primarily useful for projects that only want to
-take advantage of Gerrit's access control features and do not need
-its code review functionality.  Projects that need to require code
-reviews should not grant this category.
-
-[[category_FORG]]
-Forge Identity
-~~~~~~~~~~~~~~
-
-Normally Gerrit requires the author and the committer identity
-lines in a Git commit object (or tagger line in an annotated tag) to
-match one of the registered email addresses of the uploading user.
-This permission allows users to bypass that validation, which may
-be necessary when mirroring changes from an upstream project.
-
-* +1 Forge Author Identity
-+
-Permits the use of an unverified author line in commit objects.
-This can be useful when applying patches received by email from
-3rd parties, when cherry-picking changes written by others across
-branches, or when amending someone else's commit to fix up a minor
-problem before submitting.
-+
-By default this is granted to `Registered Users` in all projects,
-but a site administrator may disable it if verified authorship
-is required.
-
-* +2 Forge Committer or Tagger Identity
-+
-Implies 'Forge Author Identity', but also allows the use of an
-unverified committer line in commit objects, or an unverified tagger
-line in annotated tag objects.  Typically this is only required
-when mirroring commits from an upstream project repository.
-
-* +3 Forge Gerrit Code Review Server Identity
-+
-Implies 'Forge Committer or Tagger Identity' as well as 'Forge
-Author Identity', but additionally allows the use of the server's
-own name and email on the committer line of a new commit object.
-This should only be necessary when force pushing a commit history
-which has been rewritten by 'git filter-branch' and that contains
-merge commits previously created by this Gerrit Code Review server.
-
-[[category_VRIF]]
-Verified
-~~~~~~~~
-
-The verified category can have any meaning the project desires.
-It was originally invented by the Android Open Source Project to
-mean 'compiles, passes basic unit tests'.
+The verified category is one of two default categories that is
+configured upon the creation of a Gerrit instance. It may have
+any meaning the project desires.  It was originally invented by
+the Android Open Source Project to mean
+'compiles, passes basic unit tests'.
 
 The range of values is:
 
 * -1 Fails
 +
 Tried to compile, but got a compile error, or tried to run tests,
-but one or more tests did not pass.
+but one or more tests did not pass.  This value is valid
+across all patch sets in the same change, i.e. the reviewer must
+actively change his/her review to something else before the change
+is submittable.
 +
 *Any -1 blocks submit.*
 
@@ -493,8 +327,8 @@
 +
 *Any +1 enables submit.*
 
-In order to submit a change, the change must have a `+1 Verified` in
-this category from at least one authorized user, and no `-1 Fails`
+For a change to be submittable, the change must have a `+1 Verified`
+in this category from at least one authorized user, and no `-1 Fails`
 from an authorized user.  Thus, `-1 Fails` can block a submit,
 while `+1 Verified` enables a submit.
 
@@ -508,7 +342,7 @@
 
 If a Gerrit installation wants to modify the description text
 associated with these category values, the text can be updated
-in the `name` column of the `category_id = \'VRIF'` rows in the
+in the `name` column of the `category_id = 'VRIF'` rows in the
 `approval_category_values` table.
 
 Additional values could also be added to this category, to allow it
@@ -520,20 +354,25 @@
 A restart is required after making database changes.
 See <<restart_changes,below>>.
 
-[[category_CVRW]]
-Code Review
-~~~~~~~~~~~
+[[category_label-Code-Review]]
+Label: Code Review
+~~~~~~~~~~~~~~~~~~
 
-The code review category can have any meaning the project desires.
-It was originally invented by the Android Open Source Project to
-mean 'I read the code and it seems reasonably correct'.
+The code review category is the second of two default categories that
+is configured upon the creation of a Gerrit instance. It may have
+any meaning the project desires.  It was originally invented by the
+Android Open Source Project to mean 'I read the code and it seems
+reasonably correct'.
 
 The range of values is:
 
 * -2 Do not submit
 +
 The code is so horribly incorrect/buggy/broken that it must not be
-submitted to this project, or to this branch.
+submitted to this project, or to this branch.  This value is valid
+across all patch sets in the same change, i.e. the reviewer must
+actively change his/her review to something else before the change
+is submittable.
 +
 *Any -2 blocks submit.*
 
@@ -568,10 +407,11 @@
 +
 *Any +2 enables submit.*
 
-In order to submit a change, the change must have a `+2 Looks good to
-me, approved` in this category from at least one authorized user,
-and no `-2 Do not submit` from an authorized user.  Thus `-2`
-can block a submit, while `+2` can enable it.
+For a change to be submittable, the latest patch set must have a
+`+2 Looks good to me, approved` in this category from at least one
+authorized user, and no `-2 Do not submit` from an authorized user.
+Thus `-2` on any patch set can block a submit, while `+2` on the
+latest patch set can enable it.
 
 If a Gerrit installation does not wish to use this category in any
 project, it can be deleted from the database:
@@ -583,7 +423,7 @@
 
 If a Gerrit installation wants to modify the description text
 associated with these category values, the text can be updated
-in the `name` column of the `category_id = \'CRVW'` rows in the
+in the `name` column of the `category_id = 'CRVW'` rows in the
 `approval_category_values` table.
 
 Additional values could be inserted into `approval_category_values`
@@ -604,7 +444,275 @@
 A restart is required after making database changes.
 See <<restart_changes,below>>.
 
-[[category_SUBM]]
+[[category_create]]
+Create reference
+~~~~~~~~~~~~~~~~
+
+The create reference category controls whether it is possible to
+create new references, branches or tags.  This implies that the
+reference must not already exist, it's not a destructive permission
+in that you can't overwrite or remove any previosuly existing
+references (and also discard any commits in the process).
+
+It's probably most common to either permit the creation of a single
+branch in many gits (by granting permission on a parent project), or
+to grant this permission to a name pattern of branches.
+
+This permission is often given in conjunction with regular push
+branch permissions, allowing the holder of both to create new branches
+as well as bypass review for new commits on that branch.
+
+To push lightweight (non annotated) tags, grant
+`Create Reference` for reference name `refs/tags/*`, as lightweight
+tags are implemented just like branches in Git.
+
+For example, to grant the possibility to create new branches under the
+namespace `foo`, you have to grant this permission on
+`refs/heads/foo/*` for the group that should have it.
+Finally, if you plan to grant each user a personal namespace in
+where they are free to create as many branches as they wish, you
+should grant the create reference permission so it's possible
+to create new branches. This is done by using the special
+`${username}` keyword in the reference pattern, e.g.
+`refs/heads/sandbox/${username}/*`. If you do, it's also recommended
+you grant the users the push force permission to be able to clean up
+stale branches.
+
+
+[[category_forge_author]]
+Forge Author
+~~~~~~~~~~~~
+
+Normally Gerrit requires the author and the committer identity
+lines in a Git commit object (or tagger line in an annotated tag) to
+match one of the registered email addresses of the uploading user.
+This permission allows users to bypass parts of that validation, which
+may be necessary when mirroring changes from an upstream project.
+
+Permits the use of an unverified author line in commit objects.
+This can be useful when applying patches received by email from
+3rd parties, when cherry-picking changes written by others across
+branches, or when amending someone else's commit to fix up a minor
+problem before submitting.
+
+By default this is granted to `Registered Users` in all projects,
+but a site administrator may disable it if verified authorship
+is required.
+
+
+[[category_forge_committer]]
+Forge Committer
+~~~~~~~~~~~~~~~
+
+Normally Gerrit requires the author and the committer identity
+lines in a Git commit object (or tagger line in an annotated tag) to
+match one of the registered email addresses of the uploading user.
+This permission allows users to bypass parts of that validation, which
+may be necessary when mirroring changes from an upstream project.
+
+Allows the use of an unverified committer line in commit objects, or an
+unverified tagger line in annotated tag objects.  Typically this is only
+required when mirroring commits from an upstream project repository.
+
+
+[[category_forge_server]]
+Forge Server
+~~~~~~~~~~~~
+
+Normally Gerrit requires the author and the committer identity
+lines in a Git commit object (or tagger line in an annotated tag) to
+match one of the registered email addresses of the uploading user.
+This permission allows users to bypass parts of that validation, which
+may be necessary when mirroring changes from an upstream project.
+
+Allows the use of the server's own name and email on the committer
+line of a new commit object.  This should only be necessary when force
+pushing a commit history which has been rewritten by 'git filter-branch'
+and that contains merge commits previously created by this Gerrit Code
+Review server.
+
+
+[[category_owner]]
+Owner
+~~~~~
+
+The `Owner` category controls which groups can modify the project's
+configuration.  Users who are members of an owner group can:
+
+* Change the project description
+* Create/delete a branch through the web UI (not SSH)
+* Grant/revoke any access rights, including `Owner`
+
+Note that project owners implicitly have branch creation or deletion
+through the web UI, but not through SSH.  To get SSH branch access
+project owners must grant an access right to a group they are a
+member of, just like for any other user.
+
+Ownership over a particular branch subspace may be delegated by
+entering a branch pattern.  To delegate control over all branches
+that begin with `qa/` to the QA group, add `Owner` category
+for reference `refs/heads/qa/\*`.  Members of the QA group can
+further refine access, but only for references that begin with
+`refs/heads/qa/`. See <<project_owners,project owners>> to find
+out more about this role.
+
+
+[[category_push]]
+Push
+~~~~
+
+This category controls how users are allowed to upload new commits
+to projects in Gerrit. It can either give permission to push
+directly into a branch, bypassing any code review process
+that would otherwise be used. Or it may give permission to upload
+new changes for code review, this depends on which namespace the
+permission is granted to.
+
+
+[[category_push_direct]]
+Direct Push
+^^^^^^^^^^^
+
+Any existing branch can be fast-forwarded to a new commit.
+Creation of new branches is controlled by the 
+link:access-control.html#category_create['Create Reference']
+category.  Deletion of existing branches is rejected.  This is the
+safest mode as commits cannot be discarded.
+
+* Force option
++
+Allows an existing branch to be deleted. Since a force push is
+effectively a delete immediately followed by a create, but performed
+atomically on the server and logged, this option also permits forced
+push updates to branches.  Enabling this option allows existing commits
+to be discarded from a project history.
+
+The push category is primarily useful for projects that only want to
+take advantage of Gerrit's access control features and do not need
+its code review functionality.  Projects that need to require code
+reviews should not grant this category.
+
+
+[[category_push_review]]
+Upload To Code Review
+^^^^^^^^^^^^^^^^^^^^^
+
+The `Push` access right granted on the namespace
+`refs/for/refs/heads/BRANCH` permits the user to upload a non-merge
+commit to the project's `refs/for/BRANCH` namespace, creating a new
+change for code review.
+
+A user must be able to clone or fetch the project in order to create
+a new commit on their local system, so in practice they must also
+have the `Read` access granted to upload a change.
+
+For an open source, public Gerrit installation, it is common to
+grant `Read` and `Push` for `refs/for/refs/heads/*`
+to `Registered Users` in the `All-Projects` ACL.  For more
+private installations, its common to simply grant `Read` and
+`Push` for `refs/for/refs/heads/*` to all users of a project.
+
+* Force option
++
+The force option has no function when granted to a branch in the
+`refs/for/refs/heads/*` namespace.
+
+
+[[category_push_merge]]
+Push Merge Commits
+~~~~~~~~~~~~~~~~~~~~
+
+The `Push Merge Commit` permits the user to upload merge commits.
+It's an addon to the <<category_push,Push>> access right, and so it
+won't be sufficient with only `Push Merge Commit` granted for a push
+to happen.  Some projects wish to restrict merges to being created by
+Gerrit. By granting `Push` without `Push Merge Commit`, the only
+merges that enter the system will be those created by Gerrit.
+
+
+[[category_push_annotated]]
+Push Annotated Tag
+~~~~~~~~~~~~~~~~~~
+
+This category permits users to push an annotated tag object over
+SSH into the project's repository.  Typically this would be done
+with a command line such as:
+
+====
+  git push ssh://USER@HOST:PORT/PROJECT tag v1.0
+====
+
+Tags must be annotated (created with `git tag -a` or `git tag -s`),
+should exist in the `refs/tags/` namespace, and should be new.
+
+This category is intended to be used to publish tags when a project
+reaches a stable release point worth remembering in history.
+
+It allows for a new annotated (unsigned) tag to be created.  The
+tagger email address must be verified for the current user.
+
+To push tags created by users other than the current user (such
+as tags mirrored from an upstream project), `Forge Committer Identity`
+must be also granted in addition to `Push Annotated Tag`.
+
+To push lightweight (non annotated) tags, grant
+<<category_create,`Create Reference`>> for reference name
+`refs/tags/*`, as lightweight tags are implemented just like
+branches in Git.
+
+To delete or overwrite an existing tag, grant `Push` with the force
+option enabled for reference name `refs/tags/*`, as deleting a tag
+requires the same permission as deleting a branch.
+
+
+[[category_read]]
+Read
+~~~~
+
+The `Read` category controls visibility to the project's
+changes, comments, code diffs, and Git access over SSH or HTTP.
+A user must have this access granted in order to see a project, its
+changes, or any of its data.
+
+This category has a special behavior, where the per-project ACL is
+evaluated before the global all projects ACL.  If the per-project
+ACL has granted `Read` with 'DENY', and does not otherwise grant
+`Read` with 'ALLOW', then a `Read` in the all projects ACL
+is ignored.  This behavior is useful to hide a handful of projects
+on an otherwise public server.
+
+For an open source, public Gerrit installation it is common to grant
+`Read` to `Anonymous Users` in the `All-Projects` ACL, enabling
+casual browsing of any project's changes, as well as fetching any
+project's repository over SSH or HTTP.  New projects can be
+temporarily hidden from public view by granting `Read` with 'DENY'
+to `Anonymous Users` and granting `Read` to the project owner's
+group within the per-project ACL.
+
+For a private Gerrit installation using a trusted HTTP authentication
+source, granting `Read` to `Registered Users` may be more
+typical, enabling read access only to those users who have been
+able to authenticate through the HTTP access controls.  This may
+be suitable in a corporate deployment if the HTTP access control
+is already restricted to the correct set of users.
+
+
+[[category_rebase]]
+Rebase
+~~~~~~
+
+This category permits users to rebase changes via the web UI by pushing
+the `Rebase Change` button.
+
+The change owner and submitters can always rebase changes in the web UI
+(even without having the `Rebase` access right assigned).
+
+Users without this access right who are able to upload new patch sets
+can still do the rebase locally and upload the rebased commit as a new
+patch set.
+
+
+[[category_submit]]
 Submit
 ~~~~~~
 
@@ -619,23 +727,22 @@
 `Code Review`, above) must enable submit, and also must not block it.
 See above for details on each category.
 
+
 [[category_makeoneup]]
 Your Category Here
 ~~~~~~~~~~~~~~~~~~
 
 Gerrit administrators can also make up their own categories.
 
-See above for descriptions of how `Verified` and `Code Review` work,
-and insert your own category with `function_name = \'MaxWithBlock'`
-to get the same behavior over your own range of values, in any
-category you desire.
+See above for descriptions of how <<category_verified,`Verified`>>
+and <<category_review,`Code Review`>> work, and insert your own
+category with `function_name = 'MaxWithBlock'` to get the same
+behavior over your own range of values, in any category you desire.
 
 Ensure `category_id` is unique within your `approval_categories`
 table.  The default values `VRIF` and `CVRF` used for the categories
 described above are simply that, defaults, and have no special
-meaning to Gerrit.  The other standard category_id values like
-`OWN`, `READ`, `SUBM`, `pTAG` and `pHD` have special meaning and
-should not be modified or reused.
+meaning to Gerrit.
 
 The `position` column of `approval_categories` controls which column
 of the 'Approvals' table the category appears in, providing some
@@ -665,7 +772,7 @@
   VALUES
     ('Copyright Check'
     ,3
-    'MaxWithBlock'
+    ,'MaxWithBlock'
     ,'copy');
 
   INSERT INTO approval_category_values
@@ -696,6 +803,369 @@
 and don't notice changes until the page is closed and opened again,
 or is reloaded.
 
+
+Examples of typical roles in a project
+--------------------------------------
+
+Below follows a set of typical roles on a server and which access
+rights these roles typically should be granted. You may see them as
+general guide lines for a typical way to set up your project on a
+brand new Gerrit instance.
+
+[[examples_contributor]]
+Contributor
+~~~~~~~~~~~
+
+This is the typical user on a public server. They are able to read
+your project and upload new changes to it. They are able to give
+feedback on other changes as well, but are unable to block or approve
+any changes.
+
+Suggested access rights to grant:
+
+* <<category_read,`Read`>> on 'refs/heads/\*' and 'refs/tags/*'
+* <<category_push,`Push`>> to 'refs/for/refs/heads/\*' and 'refs/changes/*'
+* <<category_label-Code-Review,`Code review`>> with range '-1' to '+1'
+
+
+[[examples_developer]]
+Developer
+~~~~~~~~~
+
+This is the typical core developer on a public server.  They are able
+to read the project, upload changes to a branch.  They are allowed to
+push merge commits to merge branches together.  Also, they are allowed
+to forge author identity, thus handling commits belonging to others
+than themselves, effectively allowing them to transfer commits
+between different branches.
+
+They are furthermore able to code review and verify commits, and
+eventually submit them.  If you have an automated CI system that
+builds all uploaded patch sets you might want to skip the
+verification rights for the developer and let the CI system do that
+exclusively.
+
+Suggested access rights to grant:
+
+* <<category_read,`Read`>> on 'refs/heads/\*' and 'refs/tags/*'
+* <<category_push,`Push`>> to 'refs/for/refs/heads/\*' and 'refs/changes/*'
+* <<category_push_merge,`Push merge commit`>> to 'refs/for/refs/heads/\*' and 'refs/changes/*'
+* <<category_forge_author,`Forge Author Identity`>>
+* <<category_label-Code-Review,`Label: Code review`>> with range '-2' to '+2'
+* <<category_label-Verified,`Label: Verify`>> with range '-1' to '+1'
+* <<category_submit,`Submit`>>
+
+If the project is small or the developers are seasoned it might make
+sense to give them the freedom to push commits directly to a branch.
+
+Optional access rights to grant:
+
+* <<category_push,`Push`>> to 'refs/heads/*'
+* <<category_push_merge,`Push merge commit`>> to 'refs/heads/*'
+
+
+[[examples_cisystem]]
+CI system
+~~~~~~~~~
+
+A typical Continous Integration system should be able to download new changes
+to build and then leave a verdict somehow.
+
+As an example, the popular
+link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[gerrit-trigger plugin]
+for Jenkins/Hudson can set labels at:
+
+* The start of a build
+* A successful build
+* An unstable build (tests fails)
+* A failed build
+
+Usually the range chosen for this verdict is the verify label.  Depending on
+the size of your project and discipline of involved developers you might want
+to limit access right to the +1 `Verify` label to the CI system only.  That
+way it's guaranteed that submitted commits always get built and pass tests
+successfully.
+
+If the build doesn't complete successfully the CI system can set the
+`Verify` label to -1.  However that means that a failed build will block
+submit of the change even if someone else sets `Verify` +1.  Depending on the
+project and how much the CI system can be trusted for accurate results, a
+blocking label might not be feasible.  A recommended alternative is to set the
+label `Code-review` to -1 instead, as it isn't a blocking label but still
+shows a red label in the Gerrit UI.  Optionally; to enable the possibility to
+deliver different results (build error vs unstable for instance) it's also
+possible to set `Code-review` +1 as well.
+
+If pushing new changes is granted, it's possible to automate cherry-pick of
+submitted changes for upload to other branches under certain conditions.  This
+is probably not the first step of what a project wants to automate however,
+and so the push right can be found under the optional section.
+
+Suggested access rights to grant, that won't block changes:
+
+* <<category_read,`Read`>> on 'refs/heads/\*' and 'refs/tags/*'
+* <<category_label-Code-Review,`Label: Code review`>> with range '-1' to '0'
+* <<category_label-Verified,`Label: Verify`>> with range '0' to '+1'
+
+Optional access rights to grant:
+
+* <<category_label-Code-Review,`Label: Code review`>> with range '-1' to '+1'
+* <<category_push,`Push`>> to 'refs/for/refs/heads/\*' and 'refs/changes/*'
+
+
+[[examples_integrator]]
+Integrator
+~~~~~~~~~~
+
+Integrators are like developers but with some additional rights granted due
+to their administrative role in a project.  They can upload or push any commit
+with any committer email (not just their own) and they can also create new
+tags and branches.
+
+Suggested access rights to grant:
+
+* <<examples_developer,Developer rights>>
+* <<category_push,`Push`>> to 'refs/heads/*'
+* <<category_push_merge,`Push merge commit`>> to 'refs/heads/*'
+* <<category_forge_committer,`Forge Committer Identity`>> to 'refs/for/refs/heads/\*' and 'refs/changes/*'
+* <<category_create,`Create Reference`>> to 'refs/heads/*'
+* <<category_push_annotated,`Push Annotated Tag`>> to 'refs/tags/*'
+
+
+[[examples_project-owner]]
+Project owner
+~~~~~~~~~~~~~
+
+The project owner is almost like an integrator but with additional destructive
+power in the form of being able to delete branches.  Optionally these users
+also have the power to configure access rights in gits assigned to them.
+
+[WARNING]
+These users should be really knowledgable about git, for instance knowing why
+tags never should be removed from a server.  This role is granted potentially
+destructive access rights and cleaning up after such a mishap could be time
+consuming!
+
+Suggested access rights to grant:
+
+* <<examples_integrator,Integrator rights>>
+* <<category_push,`Push`>> with the force option to 'refs/heads/\*' and 'refs/tags/*'
+
+Optional access right to grant:
+
+* <<category_owner,`Owner`>> in the gits they mostly work with.
+
+[[examples_administrator]]
+Administrator
+~~~~~~~~~~~~~
+
+The administrator role is the most powerful role known in the Gerrit universe.
+This role may grant itself (or others) any access right, and it already has
+all capabilities granted as well.  By default the
+<<administrators,`Administrators` group>> is the group that has this role.
+
+Mandatory access rights:
+
+* <<capability_administrateServer,The `Administrate Server` capability>>
+
+Suggested access rights to grant:
+
+* <<examples_project-owner,Project owner rights>>
+
+
+[[conversion_table]]
+Conversion table from 2.1.x series to 2.2.x series
+--------------------------------------------------
+
+[options="header"]
+|=================================================================================
+|Gerrit 2.1.x                 |Gerrit 2.2.x
+|Code review                  |<<category_label-Code-Review,Label: Code review>>
+|Verify                       |<<category_label-Verified,Label: Verify>>
+|Forge Identity +1            |Forge <<category_forge_author,author>> identity
+|Forge Identity +2            |Forge <<category_forge_committer,committer>> & <<category_forge_author,author>> identity
+|Forge Identity +3            |Forge <<category_forge_server,server>> & <<category_forge_committer,committer>> & <<category_forge_author,author>> identity
+|Owner                        |<<category_owner,Owner>>
+|Push branch +1               |<<category_push_direct,Push>>
+|Push branch +2               |<<category_create,Create reference>> & <<category_push_direct,Push>>
+|Push branch +3               |<<category_push_direct,Push>> (with force) & <<category_create,Create reference>>
+|Push tag +1 & Push Branch +2 |No support to limit to push signed tag
+|Push tag +2 & Push Branch +2 |<<category_push_annotated,Push annotated tag>>
+|Push Branch +2 (refs/tags/*) |<<category_create,Create reference>> (refs/tags/...)
+|Push Branch +3 (refs/tags/*) |<<category_push_direct,Push>> (with force on refs/tags/...)
+|Read +1                      |<<category_read,Read>>
+|Read +2                      |<<category_read,Read>> & <<category_push_review,Push>> (refs/for/refs/...)
+|Read +3                      |<<category_read,Read>> & <<category_push_review,Push>> (refs/for/refs/...) & <<category_push_merge,Push Merge Commit>>
+|Submit                       |<<category_submit,Submit>>
+|=================================================================================
+
+
+[NOTE]
+In Gerrit 2.2.x, the way to set permissions for upload has changed entirely.
+To upload a change for review is no longer a separate permission type,
+instead you grant ordinary push permissions to the actual
+recieving reference. In practice this means that you set push permissions
+on `refs/for/refs/heads/<branch>` rather than permissions to upload changes
+on `refs/heads/<branch>`.
+
+
+System capabilities
+-------------------
+
+The system capabilities control actions that the administrators of
+the server can perform which usually affect the entire
+server in some way.  The administrators may delegate these
+capabilities to trusted groups of users.
+
+Delegation of capabilities allows groups to be granted a subset of
+administrative capabilities without being given complete
+administrative control of the server.  This makes it possible to
+keep fewer users in the administrators group, even while spreading
+much of the server administration burden out to more users.
+
+Below you find a list of capabilities available:
+
+
+[[capability_administrateServer]]
+Administrate Server
+~~~~~~~~~~~~~~~~~~~
+
+This is in effect the owner and administrator role of the Gerrit
+instance.  Any members of a group granted this capability will be
+able to grant any access right to any group. They will also have all
+capabilities granted to them automatically.
+
+
+[[capability_createAccount]]
+Create Account
+~~~~~~~~~~~~~~
+
+Allow link:cmd-create-account.html[account creation over the ssh prompt].
+This capability allows the granted group members to create non-interactive
+service accounts.  These service accounts are generally used for automation
+and made to be members of the
+link:access-control.html#non-interactive_users['Non-Interactive users'] group.
+
+
+[[capability_createGroup]]
+Create Group
+~~~~~~~~~~~~
+
+Allow group creation.  Groups are used to grant users access to different
+actions in projects.  This capability allows the granted group members to
+either link:cmd-create-group.html[create new groups via ssh] or via the web UI.
+
+
+[[capability_createProject]]
+Create Project
+~~~~~~~~~~~~~~
+
+Allow project creation.  This capability allows the granted group to
+either link:cmd-create-project.html[create new git projects via ssh]
+or via the web UI.
+
+
+[[capability_flushCaches]]
+Flush Caches
+~~~~~~~~~~~~
+
+Allow the flushing of Gerrit's caches.  This capability allows the granted
+group to link:cmd-flush-caches.html[flush some or all Gerrit caches via ssh].
+
+[NOTE]
+This capability doesn't imply permissions to the show-caches command.  For that
+you need the <<capability_viewCaches,view caches capability>>.
+
+
+[[capability_kill]]
+Kill Task
+~~~~~~~~~
+
+Allow the operation of the link:cmd-kill.html[kill command over ssh].  The
+kill command ends tasks that currently occupy the Gerrit server, usually
+a replication task or a user initiated task such as an upload-pack or
+recieve-pack.
+
+
+[[capability_priority]]
+Priority
+~~~~~~~~
+
+This capability allows users to use
+link:config-gerrit.html#sshd.batchThreads[the thread pool reserved] for
+link:access-control.html#non-interactive_users['Non-Interactive Users'].
+It's a binary value in that granted users either have access to the thread
+pool, or they don't.
+
+There are three modes for this capability and they're listed by rising
+priority:
+
+No capability configured.::
+The user isn't a member of a group with any priority capability granted. By
+default the user is then in the 'INTERACTIVE' thread pool.
+
+'BATCH'::
+If there's a thread pool configured for 'Non-Interactive Users' and a user is
+granted the priority capability with the 'BATCH' mode selected, the user ends
+up in the separate batch user thread pool. This is true unless the user is
+also granted the below 'INTERACTIVE' option.
+
+'INTERACTIVE'::
+If a user is granted the priority capability with the 'INTERACTIVE' option,
+regardless if they also have the 'BATCH' option or not, they are in the
+'INTERACTIVE' thread pool.
+
+
+[[capability_queryLimit]]
+Query Limit
+~~~~~~~~~~~
+
+Allow site administrators to configure the query limit for users to
+be above the default hard-coded value of 500.  Administrators can add
+a global block to `All-Projects` with group(s) that
+should have different limits:
+
+When applying a query limit to a user the largest value granted by
+any of their groups is used.
+
+This limit applies not only to the link:cmd-query.html[`gerrit query`]
+command, but also to the web UI results pagination size.
+
+
+[[capability_startReplication]]
+Start Replication
+~~~~~~~~~~~~~~~~~
+
+Allow access to execute link:cmd-replicate.html[the `gerrit replicate` command].
+
+
+[[capability_viewCaches]]
+View Caches
+~~~~~~~~~~~
+
+Allow querying for status of Gerrit's internal caches.  This capability allows
+the granted group to
+link:cmd-show-caches.html[look at some or all Gerrit caches via ssh].
+
+
+[[capability_viewConnections]]
+View Connections
+~~~~~~~~~~~~~~~~
+
+Allow querying for status of Gerrit's current client connections.  This
+capability allows the granted group to
+link:cmd-show-connections.html[look at Gerrit's current connections via ssh].
+
+
+[[capability_viewQueue]]
+View Queue
+~~~~~~~~~~
+
+Allow querying for status of Gerrit's internal task queue.  This capability
+allows the granted group to
+link:cmd-show-queue.html[look at the Gerrit task queue via ssh].
+
+
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-cherry-pick.txt b/Documentation/cmd-cherry-pick.txt
index 0831d9d..568c872 100644
--- a/Documentation/cmd-cherry-pick.txt
+++ b/Documentation/cmd-cherry-pick.txt
@@ -9,10 +9,8 @@
 --------
 [verse]
 'gerrit-cherry-pick' <remote> <changeid>...
-
-'gerrit-cherry-pick' \--continue | \--skip | \--abort
-
-'gerrit-cherry-pick' \--close <remote>
+'gerrit-cherry-pick' --continue | --skip | --abort
+'gerrit-cherry-pick' --close <remote>
 
 DESCRIPTION
 -----------
@@ -22,13 +20,13 @@
 
 If a merge failure prevents this from being completely automatic,
 you will be asked to resolve the conflict and restart the command
-with the `\--continue` option.
+with the `--continue` option.
 
 Change ids may be specified as either the change id (e.g. 1234)
 or as change id slash patch set number (e.g. 1234/8).  If the patch
 set number is not supplied, `/1` is assumed.
 
-The `\--close` command line option is now deprecated, as closing
+The `--close` command line option is now deprecated, as closing
 existing changes post cherry-pick is better handled simply by
 ensuring link:user-changeid.html[Change-Id lines] are present in
 each commit message.
@@ -38,9 +36,11 @@
 To obtain the 'gerrit-cherry-pick' script use scp, curl or wget to
 copy it to your local system:
 
+====
   $ scp -p -P 29418 john.doe@review.example.com:bin/gerrit-cherry-pick ~/bin/
 
   $ curl http://review.example.com/tools/bin/gerrit-cherry-pick
+====
 
 GERRIT
 ------
diff --git a/Documentation/cmd-create-account.txt b/Documentation/cmd-create-account.txt
index ab5663c..98f950f 100644
--- a/Documentation/cmd-create-account.txt
+++ b/Documentation/cmd-create-account.txt
@@ -8,12 +8,12 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit create-account' \
-[\--group <GROUP>] \
-[\--full-name <FULLNAME>] \
-[\--email <EMAIL>] \
-[\--ssh-key -|<KEY>] \
-<USERNAME>
+'ssh' -p <port> <host> 'gerrit create-account'
+  [--group <GROUP>]
+  [--full-name <FULLNAME>]
+  [--email <EMAIL>]
+  [--ssh-key - | <KEY>]
+  <USERNAME>
 
 DESCRIPTION
 -----------
@@ -27,7 +27,9 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_createAccount[the 'Create Account' global capability].
 
 SCRIPTING
 ---------
@@ -38,23 +40,23 @@
 <USERNAME>::
 	Required; SSH username of the user account.
 
-\--ssh-key::
+--ssh-key::
 	Content of the public SSH key to load into the account's
 	keyring.  If `-` the key is read from stdin, rather than
 	from the command line.
 
-\--group::
-	Name of the group to put the user into.  Multiple \--group
+--group::
+	Name of the group to put the user into.  Multiple --group
 	options may be specified to add the user to multiple groups.
 
-\--full-name::
+--full-name::
 	Display name of the user account.
 +
-Names containing spaces should be quoted in single quotes (\').
+Names containing spaces should be quoted in single quotes (').
 This most likely requires double quoting the value, for example
-`\--full-name "\'A description string\'"`.
+`--full-name "'A description string'"`.
 
-\--email::
+--email::
 	Preferred email address for the user account.
 
 EXAMPLES
diff --git a/Documentation/cmd-create-group.txt b/Documentation/cmd-create-group.txt
index 1e46e14..475d2c5 100644
--- a/Documentation/cmd-create-group.txt
+++ b/Documentation/cmd-create-group.txt
@@ -8,12 +8,13 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit create-group' \
-[\--owner <GROUP>] \
-[\--description <DESC>] \
-[\--member <USERNAME>] \
-[\--group <GROUP>] \
-<GROUP>
+'ssh' -p <port> <host> 'gerrit create-group'
+  [--owner <GROUP>]
+  [--description <DESC>]
+  [--member <USERNAME>]
+  [--group <GROUP>]
+  [--visible-to-all]
+  <GROUP>
 
 DESCRIPTION
 -----------
@@ -26,7 +27,9 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_createGroup[the 'Create Group' global capability].
 
 SCRIPTING
 ---------
@@ -37,24 +40,27 @@
 <GROUP>::
 	Required; name of the new group.
 
-\--owner, -o::
+--owner, -o::
 	Name of the owning group. If not specified the group will be self-owning.
 
-\--description, -d::
+--description, -d::
 	Description of group.
 +
 Description values containing spaces should be quoted in single quotes
-(\').  This most likely requires double quoting the value, for example
-`\--description "\'A description string\'"`.
+(').  This most likely requires double quoting the value, for example
+`--description "'A description string'"`.
 
-\--member::
-	User name to become initial member of the group.  Multiple \--member
+--member::
+	User name to become initial member of the group.  Multiple --member
 	options may be specified to add more initial members.
 
-\--group::
-	Group name to include in the group.  Multiple \--group options may
+--group::
+	Group name to include in the group.  Multiple --group options may
 	be specified to include more initial groups.
 
+--visible-to-all::
+	If specified, the group members will be visible to all users.
+
 EXAMPLES
 --------
 Create a new account group called `gerritdev` with two initial members
diff --git a/Documentation/cmd-create-project.txt b/Documentation/cmd-create-project.txt
index 71c0d1f..f22141c 100644
--- a/Documentation/cmd-create-project.txt
+++ b/Documentation/cmd-create-project.txt
@@ -8,18 +8,20 @@
 SYNOPSIS
 --------
 [verse]
- 'ssh' -p <port> <host> 'gerrit create-project' \
- --name <NAME> \
- [--branch <REF>] \
- [\--owner <GROUP> ...] \
- [\--parent <NAME>] \
- [\--permissions-only] \
- [\--description <DESC>] \
- [\--submit-type <TYPE>] \
- [\--use-content-merge] \
- [\--use-contributor-agreements] \
- [\--use-signed-off-by] \
- [\--empty-commit]
+'ssh' -p <port> <host> 'gerrit create-project'
+  [--owner <GROUP> ... | -o <GROUP> ...]
+  [--parent <NAME> | -p <NAME> ]
+  [--suggest-parents | -S ]
+  [--permissions-only]
+  [--description <DESC> | -d <DESC>]
+  [--submit-type <TYPE> |  -t <TYPE>]
+  [--use-contributor-agreements | --ca]
+  [--use-signed-off-by | --so]
+  [--use-content-merge]
+  [--require-change-id | --id]
+  [--branch <REF> | -b <REF>]
+  [--empty-commit]
+  { <NAME> | --name <NAME> }
 
 DESCRIPTION
 -----------
@@ -36,11 +38,9 @@
 
 ACCESS
 ------
-Caller must be a member of any of the groups defined by
-repository.*.createGroup in gerrit.config.
-
-If there is no such declaration, caller is required to be a member
-of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_createProject[the 'Create Project' global capability].
 
 SCRIPTING
 ---------
@@ -48,43 +48,58 @@
 
 OPTIONS
 -------
-\--name::
-	Required; name of the project to create.  If name ends with
-	`.git` the suffix will be automatically removed.
+<NAME>::
+	Required; name of the new project to create.  If name ends
+	with `.git` the suffix will be automatically removed.
 
-\--branch::
+--name::
+-n::
+	Deprecated alias for the <NAME> argument. This option may
+	be removed in a future release.
+
+--branch::
+-b::
 	Name of the initial branch in the newly created project.
 	Defaults to 'master'.
 
-\--owner::
+--owner::
+-o::
 	Name of the group(s) which will initially own this repository.
 	The specified group(s) must already be defined within Gerrit.
 	Several groups can be specified on the command line.
 +
-Defaults to what is specified by repository.*.ownerGroup
-in gerrit.config. If no such declaration(s) exist,
-repository.*.createGroup will be used. If they don't exist,
-`Administrators` will be used.
+Defaults to what is specified by `repository.*.ownerGroup`
+in gerrit.config.
 
-\--parent::
+--parent::
+-p::
 	Name of the parent project to inherit access rights
 	through. If not specified, the parent is set to the default
-	project `\-- All Projects \--`.
+	project `All-Projects`.
 
-\--permissions-only::
+--suggest-parents::
+-S::
+	Suggest parent candidates. This option cannot be used with
+	other arguments. Print out a list of projects that are
+	already parents to other projects, thus it can help the user
+	find a suitable parent for the new project.
+
+--permissions-only::
 	Create the project only to serve as a parent for other
-	projects.  The new project's Git repository will not be
-	initialized, and cannot be cloned.
+	projects.  The new project's Git repository will be
+	initialized to have 'HEAD' point to 'refs/meta/config'.
 
-\--description::
+--description::
+-d::
 	Initial description of the project.  If not specified,
 	no description is stored.
 +
 Description values containing spaces should be quoted in single quotes
-(\').  This most likely requires double quoting the value, for example
-`\--description "\'A description string\'"`.
+(').  This most likely requires double quoting the value, for example
+`--description "'A description string'"`.
 
-\--submit-type::
+--submit-type::
+-t::
 	Action used by Gerrit to submit an approved change to its
 	destination branch.  Supported options are:
 +
@@ -97,24 +112,32 @@
 Defaults to MERGE_IF_NECESSARY.  For more details see
 link:project-setup.html#submit_type[Change Submit Actions].
 
-\--use-content-merge::
+--use-content-merge::
 	If enabled, Gerrit will try to perform a 3-way merge of text
 	file content when a file has been modified by both the
 	destination branch and the change being submitted.  This
 	option only takes effect if submit type is not
 	FAST_FORWARD_ONLY.  Disabled by default.
 
-\--use-contributor-agreements::
+--use-contributor-agreements::
+--ca::
 	If enabled, authors must complete a contributor agreement
 	on the site before pushing any commits or changes to this
 	project.  Disabled by default.
 
-\--use-signed-off-by::
+--use-signed-off-by::
+--so:
 	If enabled, each change must contain a Signed-off-by line
 	from either the author or the uploader in the commit message.
 	Disabled by default.
 
-\--empty-commit:
+--require-change-id::
+--id::
+	Require a valid link:user-changeid.html[Change-Id] footer
+	in any commit uploaded for review. This does not apply to
+	commits pushed directly to a branch or tag.
+
+--empty-commit::
 	Creates an initial empty commit for the Git repository of the
 	project that is newly created.
 
@@ -124,13 +147,13 @@
 Create a new project called `tools/gerrit`:
 
 ====
-	$ ssh -p 29418 review.example.com gerrit create-project --name tools/gerrit.git
+	$ ssh -p 29418 review.example.com gerrit create-project tools/gerrit.git
 ====
 
 Create a new project with a description:
 
 ====
-	$ ssh -p 29418 review.example.com gerrit create-project --name tool.git --description "'Tools used by build system'"
+	$ ssh -p 29418 review.example.com gerrit create-project tool.git --description "'Tools used by build system'"
 ====
 
 Note that it is necessary to quote the description twice.  The local
diff --git a/Documentation/cmd-flush-caches.txt b/Documentation/cmd-flush-caches.txt
index 573cd78..bc6fac5 100644
--- a/Documentation/cmd-flush-caches.txt
+++ b/Documentation/cmd-flush-caches.txt
@@ -8,8 +8,9 @@
 SYNOPSIS
 --------
 [verse]
- 'ssh' -p <port> <host> 'gerrit flush-caches' \
- [\--all | \--list | \--cache <NAME> ...]
+'ssh' -p <port> <host> 'gerrit flush-caches' --all
+'ssh' -p <port> <host> 'gerrit flush-caches' --list
+'ssh' -p <port> <host> 'gerrit flush-caches' --cache <NAME> ...
 
 DESCRIPTION
 -----------
@@ -24,7 +25,9 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or in a group that have been granted
+link:access-control.html#capability_flushCaches[the 'Flush Caches' global capability].
 
 SCRIPTING
 ---------
@@ -32,19 +35,19 @@
 
 OPTIONS
 -------
-\--all::
+--all::
 	Flush all known caches.  This is like applying a big hammer,
 	it will force everything out, potentially more than was
-	necessary for the change made.	This option automatically
+	necessary for the change made. This option automatically
 	skips flushing potentially dangerous caches such as
 	"web_sessions".  To flush one of these caches, the caller
 	must specifically name them on the command line, e.g. pass
-	`\--cache=web_sessions`.
+	`--cache web_sessions`.
 
-\--list::
+--list::
 	Show a list of the caches.
 
-\--cache=<NAME>::
+--cache <NAME>::
 	Flush only the cache called <NAME>.  May be supplied more
 	than once to flush multiple caches in a single command
 	execution.
diff --git a/Documentation/cmd-gsql.txt b/Documentation/cmd-gsql.txt
index 7fc8a9b..3c4f1b5 100644
--- a/Documentation/cmd-gsql.txt
+++ b/Documentation/cmd-gsql.txt
@@ -8,9 +8,9 @@
 SYNOPSIS
 --------
 [verse]
- 'ssh' -p <port> <host> 'gerrit gsql' \
- [\--format \{PRETTY | JSON\}] \
- [\-c QUERY]
+'ssh' -p <port> <host> 'gerrit gsql'
+  [--format {PRETTY | JSON}]
+  [-c QUERY]
 
 DESCRIPTION
 -----------
@@ -20,7 +20,7 @@
 
 OPTIONS
 -------
-\--format::
+--format::
 	Set the format records are output in.  In PRETTY (the
 	default) records are displayed in a tabular output suitable
 	for reading by a human on a sufficiently wide terminal.
diff --git a/Documentation/cmd-hook-commit-msg.txt b/Documentation/cmd-hook-commit-msg.txt
index b21f5c0..6318bba 100644
--- a/Documentation/cmd-hook-commit-msg.txt
+++ b/Documentation/cmd-hook-commit-msg.txt
@@ -53,12 +53,25 @@
 
 OBTAINING
 ---------
-To obtain the 'commit-msg' script use scp, wget or curl to copy it
-to your local system:
+To obtain the 'commit-msg' script use scp, wget or curl to download it
+to your local system from your gerrit server.
 
-  $ scp -p -P 29418 john.doe@review.example.com:hooks/commit-msg .git/hooks/
+You can use either of the below commands:
 
-  $ curl http://review.example.com/tools/hooks/commit-msg
+====
+  $ scp -p -P 29418 <your username>@<your Gerrit review server>:hooks/commit-msg <local path to your git>/.git/hooks/
+
+  $ curl -o <local path to your git>/.git/hooks/commit-msg <your Gerrit http URL>/tools/hooks/commit-msg
+====
+
+A specific example of this might look something like this:
+
+.Example
+====
+  $ scp -p -P 29418 john.doe@review.example.com:hooks/commit-msg ~/duhproject/.git/hooks/
+
+  $ curl -o ~/duhproject/.git/hooks/commit-msg http://review.example.com/tools/hooks/commit-msg
+====
 
 SEE ALSO
 --------
diff --git a/Documentation/cmd-index.txt b/Documentation/cmd-index.txt
index 8a6cb6d..b09c3b3 100644
--- a/Documentation/cmd-index.txt
+++ b/Documentation/cmd-index.txt
@@ -51,6 +51,33 @@
 [[user_commands]]User Commands
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+'gerrit approve'::
+	'Deprecated alias for `gerrit review`.'
+
+link:cmd-ls-groups.html[gerrit ls-groups]::
+	List groups visible to the caller.
+
+link:cmd-ls-projects.html[gerrit ls-projects]::
+	List projects visible to the caller.
+
+link:cmd-rename-group.html[gerrit rename-group]::
+	Rename an account group.
+
+link:cmd-set-reviewers.html[gerrit set-reviewers]::
+        Add or remove reviewers on a change.
+
+link:cmd-query.html[gerrit query]::
+	Query the change database.
+
+'gerrit receive-pack'::
+	'Deprecated alias for `git receive-pack`.'
+
+link:cmd-review.html[gerrit review]::
+	Verify, approve and/or submit a patch set from the command line.
+
+link:cmd-stream-events.html[gerrit stream-events]::
+	Monitor events occurring in real time.
+
 git upload-pack::
 	Standard Git server side command for client side `git fetch`.
 
@@ -60,25 +87,7 @@
 Also implements the magic associated with uploading commits for
 review.  See link:user-upload.html#push_create[Creating Changes].
 
-link:cmd-review.html[gerrit approve]::
-	Alias for 'gerrit review'.
-
-link:cmd-ls-projects.html[gerrit ls-projects]::
-	List projects visible to the caller.
-
-link:cmd-query.html[gerrit query]::
-	Query the change database.
-
-link:cmd-review.html[gerrit review]::
-	Verify, approve and/or submit a patch set from the command line.
-
-link:cmd-stream-events.html[gerrit stream-events]::
-	Monitor events occuring in real time.
-
-gerrit receive-pack::
-	Legacy alias for `git receive-pack`.
-
-[[admin_commands]]Adminstrator Commands
+[[admin_commands]]Administrator Commands
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 link:cmd-create-account.html[gerrit create-account]::
@@ -96,6 +105,9 @@
 link:cmd-gsql.html[gerrit gsql]::
 	Administrative interface to active database.
 
+link:cmd-replicate.html[gerrit replicate]::
+	Manually trigger replication, to recover a node.
+
 link:cmd-set-project-parent.html[gerrit set-project-parent]::
 	Change the project permissions are inherited from.
 
@@ -108,9 +120,6 @@
 link:cmd-show-queue.html[gerrit show-queue]::
 	Display the background work queues, including replication.
 
-link:cmd-replicate.html[gerrit replicate]::
-	Manually trigger replication, to recover a node.
-
 link:cmd-kill.html[kill]::
 	Kills a scheduled or running task.
 
diff --git a/Documentation/cmd-kill.txt b/Documentation/cmd-kill.txt
index a76be84..f09053e 100644
--- a/Documentation/cmd-kill.txt
+++ b/Documentation/cmd-kill.txt
@@ -18,7 +18,8 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted link:access-control.html#capability_kill[the 'Kill Task' global capability].
 
 SCRIPTING
 ---------
diff --git a/Documentation/cmd-ls-groups.txt b/Documentation/cmd-ls-groups.txt
new file mode 100644
index 0000000..8564db2
--- /dev/null
+++ b/Documentation/cmd-ls-groups.txt
@@ -0,0 +1,96 @@
+gerrit ls-groups
+================
+
+NAME
+----
+gerrit ls-groups - List groups visible to caller
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit ls-groups'
+  [--project <NAME>]
+  [--user <NAME>]
+  [--visible-to-all]
+  [--type {internal | ldap | system}]
+
+DESCRIPTION
+-----------
+Displays the list of group names, one per line, that are visible to
+the account of the calling user.
+
+If the caller is a member of the privileged 'Administrators' group,
+all groups are listed.
+
+ACCESS
+------
+Any user who has configured an SSH key.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+--project::
+-p::
+	Name of the project for which the groups should be listed. Only
+	groups are listed for which any permission is set on this project
+	(or for which a permission is inherited from a parent project).
+	Multiple --project options may be specified to specify additional
+	projects. In this case all groups are listed that have a
+	permission for any of the specified projects.
++
+This option can't be used together with the '--user' option.
+
+--user::
+-u::
+	User for which the groups should be listed. Only groups are
+	listed that contain this user as a member.
++
+The calling user can list the groups for the own user or must be a
+member of the privileged 'Administrators' group to list the groups
+for other users.
++
+This option can't be used together with the '--project' option.
+
+--visible-to-all::
+	Displays only groups that are visible to all registered users
+	(groups that are explicitly marked as visible to all registered
+	users).
+
+--type::
+	Display only groups of the specified type. If not specified,
+	groups of all types are displayed. Supported types:
++
+--
+`internal`:: Any group defined within Gerrit.
+`ldap`:: Any group defined by an external LDAP database.
+`system`:: Any system defined and managed group.
+--
+
+EXAMPLES
+--------
+
+List visible groups:
+=====
+	$ ssh -p 29418 review.example.com gerrit ls-groups
+	Administrators
+	Anonymous Users
+	MyProject_Committers
+	Project Owners
+	Registered Users
+=====
+
+List all groups for which any permission is set for the project
+"MyProject":
+=====
+	$ ssh -p 29418 review.example.com gerrit ls-groups --project MyProject
+	MyProject_Committers
+	Project Owners
+	Registered Users
+=====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-ls-projects.txt b/Documentation/cmd-ls-projects.txt
index 1e7b4cc..7782aa8 100644
--- a/Documentation/cmd-ls-projects.txt
+++ b/Documentation/cmd-ls-projects.txt
@@ -8,7 +8,10 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit ls-projects' [\--show-branch <BRANCH>]
+'ssh' -p <port> <host> 'gerrit ls-projects'
+  [--show-branch <BRANCH> ...]
+  [--tree]
+  [--type {code | permissions | all}]
 
 DESCRIPTION
 -----------
@@ -28,15 +31,47 @@
 
 OPTIONS
 -------
-\--show-branch::
-\-b::
-	Name of the branch for which the command will display the sha of each project.
+--show-branch::
+-b::
+	Branch for which the command will display the sha of each project.
+	The command may have multiple --show-branch parameters, in this case
+	sha will be shown for each of the branches.
+	If the user does not have READ access to some branch or the branch does not
+	exist then stub (40 `-` symbols) is shown.
+	If the user does not have access to any branch in the project then the
+	whole project is not shown.
 
-\--tree::
-\-t::
+--description::
+--d::
+	Allows listing of projects together with their respective
+	description.
++
+Line-feeds are escaped to allow ls-project to keep the
+"one project per line"-style.
+
+--tree::
+-t::
 	Displays project inheritance in a tree-like format.
 	This option does not work together with the show-branch option.
 
+--type::
+	Display only projects of the specified type.  If not
+	specified, defaults to `code`. Supported types:
++
+--
+`code`:: Any project likely to contain user files.
+`permissions`:: Projects created with the `--permissions-only` flag.
+`all`:: Any type of project.
+--
+
+--all::
+	Display all projects that are accessible by the calling user
+	account. Besides the projects that the calling user account has
+	been granted 'READ' access to, this includes all projects that
+	are owned by the calling user account (even if for these projects
+	the 'READ' access right is not assigned to the calling user
+	account).
+
 EXAMPLES
 --------
 
diff --git a/Documentation/cmd-query.txt b/Documentation/cmd-query.txt
index c8996eb..253bed1 100644
--- a/Documentation/cmd-query.txt
+++ b/Documentation/cmd-query.txt
@@ -8,14 +8,18 @@
 SYNOPSIS
 --------
 [verse]
- 'ssh' -p <port> <host> 'gerrit query' \
- [\--format {TEXT | JSON}] \
- [\--current-patch-set] \
- [\--patch-sets|--all-approvals] \
- [\--] \
- <query> \
- [limit:<n>] \
- [resume\_sortkey:<sortKey>]
+'ssh' -p <port> <host> 'gerrit query'
+  [--format {TEXT | JSON}]
+  [--current-patch-set]
+  [--patch-sets | --all-approvals]
+  [--files]
+  [--comments]
+  [--commit-message]
+  [--dependencies]
+  [--]
+  <query>
+  [limit:<n>]
+  [resume_sortkey:<sortKey>]
 
 DESCRIPTION
 -----------
@@ -39,27 +43,50 @@
 
 OPTIONS
 -------
-\--current-patch-set::
+--format::
+	Formatting method for the results. TEXT is the default,
+	presenting a human readable display. JSON creates one line
+	per matching record, with embedded LFs escaped.
+
+--current-patch-set::
 	Include information about the current patch set in the results.
 
-\--patch-sets::
+--patch-sets::
 	Include information about all patch sets.  If combined with
-	the \--current-patch-set flag then the current patch set
+	the --current-patch-set flag then the current patch set
 	information will be output twice, once in each field.
 
-\--all-approvals::
+--all-approvals::
 	Include information about all patch sets along with the
 	approval information for each patch set.  If combined with
-	the \--current-patch-set flag then the current patch set
+	the --current-patch-set flag then the current patch set
 	information will be output twice, once in each field.
 
+--files::
+	Support for listing files with patch sets and their
+	attributes (ADDED, MODIFIED, DELETED, RENAMED, COPIED).
+	Note that this option requires either the --current-patch-set
+	or the --patch-sets option in order to give any file information.
+
+--comments::
+	Include comments for all changes. If combined with the
+	--patch-sets flag then all in-line comments are included for
+	each patch set.
+
+--commit-message::
+	Include the full commit message in the change description.
+
+--dependencies::
+	Show information about patch sets which depend on, or are needed by,
+	each patch set.
+
 limit:<n>::
 	Maximum number of results to return.  This is actually a
 	query operator, and not a command line option.	If more
 	than one limit: operator is provided, the smallest limit
 	will be used to cut the result set.
 
-resume\_sortkey:<sortKey>::
+resume_sortkey:<sortKey>::
 	Resume results from this sort key.  Callers should pass
 	the sortKey of the last change of the prior result set to
 	resume a prior query.  This is actually a query operator,
@@ -77,20 +104,20 @@
 --------
 
 Find the 2 most recent open changes in the tools/gerrit project:
------
+====
   $ ssh -p 29418 review.example.com gerrit query --format=JSON status:open project:tools/gerrit limit:2
   {"project":"tools/gerrit", ...}
   {"project":"tools/gerrit", ..., sortKey:"000e6aee00003e26", ...}
   {"type":"stats","rowCount":2,"runningTimeMilliseconds:15}
------
+====
 
 Resume the same query and obtain the final results:
------
+====
   $ ssh -p 29418 review.example.com gerrit query --format=JSON status:open project:tools/gerrit limit:2 resume_sortkey:000e6aee00003e26
   {"project":"tools/gerrit", ...}
   {"project":"tools/gerrit", ...}
   {"type":"stats","rowCount":1,"runningTimeMilliseconds:15}
------
+====
 
 
 SCHEMA
diff --git a/Documentation/cmd-receive-pack.txt b/Documentation/cmd-receive-pack.txt
index ca96550..7e5ca09 100644
--- a/Documentation/cmd-receive-pack.txt
+++ b/Documentation/cmd-receive-pack.txt
@@ -8,7 +8,7 @@
 SYNOPSIS
 --------
 [verse]
-git receive-pack [\--reviewer <address>] [\--cc <address>] <project>
+'git receive-pack' [--reviewer <address>] [--cc <address>] <project>
 
 DESCRIPTION
 -----------
@@ -24,11 +24,11 @@
 <project>::
 	The remote repository that will receive the pushed objects,
 	and create (or update) changes.  Within Gerrit Code Review
-	this is the name of a project.	The optional leading `/`
+	this is the name of a project.  The optional leading `/`
 	and or trailing `.git` suffix will be removed, if supplied.
 
-\--re <address>::
-\--reviewer <address>::
+--reviewer <address>::
+--re <address>::
 	Automatically add <address> as a reviewer to any change
 	created or updated by the pushed commit objects.  These
 	changes will appear in the reviewer's dashboard, and will
@@ -38,10 +38,10 @@
 +
 This is a Gerrit Code Review specific extension.
 
-\--cc <address>::
+--cc <address>::
 	Carbon-copy <address> on the created or updated changes,
 	but don't request them to perform a review.  Like with
-	\--reviewer the changes will appear in the CC'd user's
+	--reviewer the changes will appear in the CC'd user's
 	dashboard, and will be emailed to them.
 +
 May be specified more than once to specify multiple CCs.
@@ -82,12 +82,12 @@
 ====
 
 afterwards `.git/config` contains the following:
-====
-	[remote "charlie"]
-		url = ssh://review.example.com:29418/project
-		push = HEAD:refs/for/master
-		receivepack = git receive-pack --reviewer charlie@example.com --cc alice@example.com --cc bob@example.com
-====
+----
+[remote "charlie"]
+  url = ssh://review.example.com:29418/project
+  push = HEAD:refs/for/master
+  receivepack = git receive-pack --reviewer charlie@example.com --cc alice@example.com --cc bob@example.com
+----
 
 and now sending a new change for review to charlie, CC'ing both
 alice and bob is much easier:
diff --git a/Documentation/cmd-rename-group.txt b/Documentation/cmd-rename-group.txt
new file mode 100644
index 0000000..e810727
--- /dev/null
+++ b/Documentation/cmd-rename-group.txt
@@ -0,0 +1,46 @@
+gerrit rename-group
+===================
+
+NAME
+----
+gerrit rename-group - Rename an account group.
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit rename-group'
+  <GROUP>
+  <NEWNAME>
+
+DESCRIPTION
+-----------
+Renames an account group.
+
+ACCESS
+------
+Caller must be a member of the group owning the group to be renamed
+or be a member of the privileged 'Administrators' group.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+OPTIONS
+-------
+<GROUP>::
+	Required; name of the group to be renamed.
+
+<NEWNAME>::
+	Required; new name of the group.
+
+EXAMPLES
+--------
+Rename the group "MyGroup" to "MyCommitters".
+
+====
+	$ ssh -p 29418 user@review.example.com gerrit rename-group MyGroup MyCommitters
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-replicate.txt b/Documentation/cmd-replicate.txt
index 7f88b47..7722027 100644
--- a/Documentation/cmd-replicate.txt
+++ b/Documentation/cmd-replicate.txt
@@ -8,9 +8,9 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit replicate' \
-[\--url <PATTERN>] \
-\{\--all | <PROJECT> ...}
+'ssh' -p <port> <host> 'gerrit replicate'
+  [--url <PATTERN>]
+  {--all | <PROJECT> ...}
 
 DESCRIPTION
 -----------
@@ -32,13 +32,13 @@
   pack files to the destinations.
 +
 If the local server is repacked, and then the resulting pack files
-are sent to remote peers using `rsync -a \--delete-after`, there
+are sent to remote peers using `rsync -a --delete-after`, there
 is a chance that the rsync missed a change that was added during
 the rsync data transfer, and the rsync will remove that changes's
 data from the remote, even though the automatic replication pushed
 it there in parallel to the rsync.
 +
-Its a good idea to run replicate with `\--all` to ensure all
+Its a good idea to run replicate with `--all` to ensure all
 projects are consistent after the rsync is complete.
 
 * After deleting a ref by hand.
@@ -52,7 +52,9 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_startReplication[the 'Start Replication' global capability].
 
 SCRIPTING
 ---------
@@ -60,10 +62,10 @@
 
 OPTIONS
 -------
-\--all::
+--all::
 	Schedule replicating for all projects.
 
-\--url=<PATTERN>::
+--url <PATTERN>::
 	Replicate only to replication destinations whose URL
 	contains the substring <PATTERN>.  This can be useful to
 	replicate only to a previously down node, which has been
@@ -74,21 +76,21 @@
 Replicate every project, to every configured remote:
 
 ====
-	$ ssh -p 29418 review.example.com gerrit replicate --all
+  $ ssh -p 29418 review.example.com gerrit replicate --all
 ====
 
 Replicate only to `srv2` now that it is back online:
 
 ====
-	$ ssh -p 29418 review.example.com gerrit replicate --url=srv2 --all
+  $ ssh -p 29418 review.example.com gerrit replicate --url srv2 --all
 ====
 
 Replicate only the `tools/gerrit` project, after deleting a ref
 locally by hand:
 
 ====
-	$ git --git-dir=/home/git/tools/gerrit.git update-ref -d refs/changes/00/100/1
-	$ ssh -p 29418 review.example.com gerrit replicate tools/gerrit
+  $ git --git-dir=/home/git/tools/gerrit.git update-ref -d refs/changes/00/100/1
+  $ ssh -p 29418 review.example.com gerrit replicate tools/gerrit
 ====
 
 SEE ALSO
diff --git a/Documentation/cmd-review.txt b/Documentation/cmd-review.txt
index 5645f51..ac613e5 100644
--- a/Documentation/cmd-review.txt
+++ b/Documentation/cmd-review.txt
@@ -8,8 +8,16 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit approve' [\--project <PROJECT>] [\--message <MESSAGE>] [\--verified <N>] [\--code-review <N>] [\--abandon] [\--restore] [\--submit]  {COMMIT | CHANGEID,PATCHSET}...
-'ssh' -p <port> <host> 'gerrit review' [\--project <PROJECT>] [\--message <MESSAGE>] [\--verified <N>] [\--code-review <N>] [\--abandon] [\--restore] [\--submit]  {COMMIT | CHANGEID,PATCHSET}...
+'ssh' -p <port> <host> 'gerrit review'
+  [--project <PROJECT>]
+  [--message <MESSAGE>]
+  [--force-message]
+  [--submit]
+  [--abandon | --restore]
+  [--publish]
+  [--delete]
+  [--verified <N>] [--code-review <N>]
+  {COMMIT | CHANGEID,PATCHSET}...
 
 DESCRIPTION
 -----------
@@ -19,7 +27,7 @@
 
 Patch sets should be specified as complete or abbreviated commit
 SHA-1s.  If the same commit is available in multiple projects the
-\--project option may be used to limit where Gerrit searches for
+--project option may be used to limit where Gerrit searches for
 the change to only the contents of the specified project.
 
 For current backward compatibility with user tools patch sets may
@@ -31,42 +39,63 @@
 OPTIONS
 -------
 
-\--project::
+--project::
 -p::
 	Name of the project the intended changes are contained
 	within.  This option must be supplied before the commit
 	SHA-1 in order to take effect.
 
-\--message::
+--message::
 -m::
 	Optional cover letter to include as part of the message
 	sent to reviewers when the approval states are updated.
 
-\--help::
+--force-message::
+	Option which allows Gerrit to publish the --message, even
+	when the labels could not be applied due to change being
+	closed).
++
+Used by some scripts/CI-systems, where the results (or links
+to the result) are posted as a message after completion of a
+build (often together with a label-change, indicating the success
+of the build).
++
+If the message is posted successfully, the cmd will return
+successfully, even if the label could not be changed.
+
+--help::
 -h::
 	Display site-specific usage information, including the
 	complete listing of supported approval categories and values.
 
-\--code-review::
-\--verified::
-	Set the approval category to the value 'N'.  The exact
-	option names supported and the range of values permitted
-	differs per site, check the output of \--help, or contact
-	your site administrator for further details.
-
-\--abandon::
+--abandon::
 	Abandon the specified patch set(s).
 	(option is mutually exclusive with --submit and --restore)
 
-\--restore::
-	Restore the specified abandonned patch set(s).
+--restore::
+	Restore the specified abandoned patch set(s).
 	(option is mutually exclusive with --abandon)
 
-\--submit::
+--submit::
 -s::
 	Submit the specified patch set(s) for merging.
 	(option is mutually exclusive with --abandon)
 
+--publish::
+	Publish the specified draft patch set(s).
+	(option is mutually exclusive with --submit, --restore, --abandon, and --delete)
+
+--delete::
+	Delete the specified draft patch set(s).
+	(option is mutually exclusive with --submit, --restore, --abandon, and --publish)
+
+--code-review::
+--verified::
+	Set the approval category to the value 'N'.  The exact
+	option names supported and the range of values permitted
+	differs per site, check the output of --help, or contact
+	your site administrator for further details.
+
 ACCESS
 ------
 Any user who has configured an SSH key.
@@ -80,25 +109,30 @@
 
 Approve the change with commit c0ff33 as "Verified +1"
 =====
-	$ ssh -p 29418 review.example.com gerrit review --verified=+1 c0ff33
+	$ ssh -p 29418 review.example.com gerrit review --verified +1 c0ff33
 =====
 
 Append the message "Build Successful". Notice two levels of quoting is
 required, one for the local shell, and another for the argument parser
 inside the Gerrit server:
 =====
-	$ ssh -p 29418 review.example.com gerrit review -m '"Build Successful"'
+	$ ssh -p 29418 review.example.com gerrit review -m '"Build Successful"' c0ff33
 =====
 
 Mark the unmerged commits both "Verified +1" and "Code Review +2" and
 submit them for merging:
 ====
-	$ ssh -p 29418 review.example.com gerrit review \
-	--verified=+1 \
-	--code-review=+2 \
-	--submit \
-	--project=this/project \
-	$(git rev-list origin/master..HEAD)
+  $ ssh -p 29418 review.example.com gerrit review \
+    --verified +1 \
+    --code-review +2 \
+    --submit \
+    --project this/project \
+    $(git rev-list origin/master..HEAD)
+====
+
+Abandon an active change:
+====
+  $ ssh -p 29418 review.example.com gerrit review --abandon c0ff33
 ====
 
 SEE ALSO
diff --git a/Documentation/cmd-set-project-parent.txt b/Documentation/cmd-set-project-parent.txt
index 699d76f..1e7e6c5 100644
--- a/Documentation/cmd-set-project-parent.txt
+++ b/Documentation/cmd-set-project-parent.txt
@@ -8,15 +8,17 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit set-project-parent' \
-[\--parent <NAME>] \
-<NAME> ...
+'ssh' -p <port> <host> 'gerrit set-project-parent'
+  [--parent <NAME>]
+  [--children-of <NAME>]
+  [--exclude <NAME>]
+  <NAME> ...
 
 DESCRIPTION
 -----------
 Changes the project that permissions are inherited through.
 Every project inherits permissions from another project, by
-default this is `\-- All Projects \--`.  This command sets
+default this is `All-Projects`.  This command sets
 the project to inherit through another one.
 
 ACCESS
@@ -29,9 +31,22 @@
 
 OPTIONS
 -------
-\--parent::
-	Name of the parent to inherit through.	If not specified,
-	the parent is set back to the default `\-- All Projects \--`.
+--parent::
+	Name of the parent to inherit through. If not specified,
+	the parent is set back to the default `All-Projects`.
+
+--children-of::
+	Name of the parent project for which all child projects should be
+	reparented. If the new parent project or any project in its
+	parent line is a child of this parent project it is automatically
+	excluded from reparenting.
+
+--exclude::
+	Name of a child project that should not be reparented. This
+	option can only be used if the option --children-of is set.
+	Multiple child projects can be excluded from reparenting by
+	specifying the --exclude option multiple times. Excluding a
+	project that is not a child project has no effect.
 
 EXAMPLES
 --------
@@ -41,6 +56,13 @@
 	$ ssh -p 29418 review.example.com gerrit set-project-parent --parent kernel/common kernel/omap
 ====
 
+Reparent all children of `myParent` to `myOtherParent`:
+
+====
+	$ ssh -p 29418 review.example.com gerrit set-project-parent \
+	  --children-of myParent --parent myOtherParent
+====
+
 SEE ALSO
 --------
 
diff --git a/Documentation/cmd-set-reviewers.txt b/Documentation/cmd-set-reviewers.txt
new file mode 100644
index 0000000..9e08e39
--- /dev/null
+++ b/Documentation/cmd-set-reviewers.txt
@@ -0,0 +1,89 @@
+gerrit set-reviewers
+====================
+
+NAME
+----
+gerrit set-reviewers - Add or remove reviewers to a change
+
+SYNOPSIS
+--------
+[verse]
+'ssh' -p <port> <host> 'gerrit set-reviewers'
+  [--project <PROJECT>]
+  [--add REVIEWER ...]
+  [--remove REVIEWER ...]
+  [--]
+  {COMMIT | CHANGE-ID}...
+
+DESCRIPTION
+-----------
+Adds or removes reviewers to the specified change, sending email
+notifications when changes are made.
+
+Changes should be specified as complete or abbreviated Change-Ids
+such as 'Iac6b2ac2'.  They may also be specified by numeric change
+identifiers, such as '8242' or by complete or abbreviated commit
+SHA-1s.
+
+OPTIONS
+-------
+
+--project::
+-p::
+	Name of the project the intended change is contained within.  This
+	option must be supplied before Change-ID in order to take effect.
+
+--add::
+-a::
+	A user that should be added as reviewer to the change or a group
+	for which all members should be added as reviewers to the change.
+	Multiple users and groups can be added at once as reviewers by
+	using this option multiple times.
+
+--remove::
+-r::
+	Remove this user from the reviewer list of the change. Multiple
+	users can be removed at once from the reviewer list by using this
+	option multiple times.
+
+--help::
+-h::
+	Display site-specific usage information
+
+ACCESS
+------
+Any user who has configured an SSH key.
+
+SCRIPTING
+---------
+This command is intended to be used in scripts.
+
+EXAMPLES
+--------
+
+Add reviewers alice and bob, but remove eve from change Iac6b2ac2.
+=====
+	$ ssh -p 29418 review.example.com gerrit set-reviewers \
+	  -a alice@example.com -a bob@example.com \
+	  -r eve@example.com \
+	  Iac6b2ac2
+=====
+
+Add reviewer elvis to old-style change id 1935 specifying that the change is in project "graceland"
+=====
+	$ ssh -p 29418 review.example.com gerrit set-reviewers \
+	  --project graceland \
+	  -a elvis@example.com \
+	  1935
+=====
+
+Add all project owners as reviewers to change Iac6b2ac2.
+=====
+	$ ssh -p 29418 review.example.com gerrit set-reviewers \
+	  -a "'Project Owners'" \
+	  Iac6b2ac2
+=====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/cmd-show-caches.txt b/Documentation/cmd-show-caches.txt
index 5998859..126b2a0 100644
--- a/Documentation/cmd-show-caches.txt
+++ b/Documentation/cmd-show-caches.txt
@@ -8,15 +8,28 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'gerrit show-caches'
+'ssh' -p <port> <host> 'gerrit show-caches' [--gc] [--show-jvm]
 
 DESCRIPTION
 -----------
 Display statistics about the size and hit ratio of in-memory caches.
 
+OPTIONS
+-------
+--gc::
+	Request Java garbage collection before displaying information
+	about the Java memory heap.
+
+--show-jvm::
+	List the name and version of the Java virtual machine, host
+	operating system, and other details about the environment
+	that Gerrit Code Review is running in.
+
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_viewCaches[the 'View Caches' global capability].
 
 SCRIPTING
 ---------
@@ -27,27 +40,33 @@
 
 ====
 	$ ssh -p 29418 review.example.com gerrit show-caches
+	Gerrit Code Review        2.2.2                     now    10:03:34   PDT
+	                                                 uptime     1 min 39 sec
+	
 	  Name               Max |Object Count        |  AvgGet  |Hit Ratio     |
 	                     Age |  Disk    Mem    Cnt|          |Disk Mem  Agg |
 	-------------------------+--------------------+----------+--------------+
-	  accounts           90d |                 295|          |           99%|
-	  accounts_byemail   90d |                 109|          |           97%|
-	D diff               90d |  2695    128   2707|   0.4ms  | 11%  86%  98%|
-	  groups             90d |                  94|          |           80%|
-	  openid             5m  |                  30|   0.4ms  |            9%|
-	  projects           90d |                 188|          |           99%|
-	  sshkeys            90d |                   9|          |           94%|
-	D web_sessions       12h |           30     30|          |  0%  99%  99%|
-
-	JGit Buffer Cache:
-	  open files  :              23
-	  loaded      :   6.82 mb
-	  mem%        :   2%
-
-	JVM Heap:
-	  max         : 880.00 mb
-	  inuse       : 136.57 mb
-	  mem%        :  44%
+	  accounts           90d |                   1|          |           95%|
+	  accounts_byemail   90d |                    |          |              |
+	  accounts_byname    90d |                   1|          |              |
+	  adv_bases          10m |                    |          |              |
+	D diff               90d |     8             8|          |              |
+	D diff_intraline     90d |     1             1|          |              |
+	  groups             90d |                  19|          |            0%|
+	  groups_byext       90d |                    |          |              |
+	  groups_byinclude   90d |                  21|          |           80%|
+	  groups_byname      90d |                    |          |              |
+	  groups_byuuid      90d |                    |          |              |
+	  project_list       90d |                    |          |              |
+	  projects           90d |                   1|          |           80%|
+	  sshkeys            90d |                   1|          |           90%|
+	D web_sessions       12h |                    |          |              |
+	
+	SSH:      1  users, oldest session started 782 ms ago
+	Tasks:    2  total =    1 running +      0 ready +    1 sleeping
+	Mem:  46.13m total =  16.17m used +  29.96m free +   0.00k buffers
+	     246.56m max
+	           0 open files,        6 cpus available,       23 threads
 ====
 
 SEE ALSO
diff --git a/Documentation/cmd-show-connections.txt b/Documentation/cmd-show-connections.txt
index 177a915..b5d41bd 100644
--- a/Documentation/cmd-show-connections.txt
+++ b/Documentation/cmd-show-connections.txt
@@ -18,7 +18,9 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+Caller must be a member of the privileged 'Administrators' group,
+or have been granted
+link:access-control.html#capability_viewConnections[the 'View Connections' global capability].
 
 SCRIPTING
 ---------
@@ -26,8 +28,8 @@
 
 OPTIONS
 -------
+--numeric::
 -n::
-\--numeric::
 	Show client hostnames as IP addresses instead of DNS hostname.
 
 DISPLAY
@@ -35,7 +37,7 @@
 
 Session::
 	Unique session identifier on this server.  Session
-	identifiers have a period of 2\^32-1 and start from a
+	identifiers have a period of 2^32-1 and start from a
 	random value.
 
 Start::
diff --git a/Documentation/cmd-show-queue.txt b/Documentation/cmd-show-queue.txt
index 3e3638e..f99e342 100644
--- a/Documentation/cmd-show-queue.txt
+++ b/Documentation/cmd-show-queue.txt
@@ -8,8 +8,8 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> <host> 'ps'
 'ssh' -p <port> <host> 'gerrit show-queue'
+'ssh' -p <port> <host> 'ps'
 
 DESCRIPTION
 -----------
@@ -24,7 +24,14 @@
 
 ACCESS
 ------
-Caller must be a member of the privileged 'Administrators' group.
+End-users may see a task in the queue only if they can also see
+the project the task is associated with. Tasks operating on other
+projects, or that do not have a specific project are hidden.
+
+Members of the group 'Administrators', or any group that has been
+granted
+link:access-control.html#capability_viewQueue[the 'View Queue' capability]
+can see all queue entries.
 
 SCRIPTING
 ---------
@@ -36,7 +43,7 @@
 Task::
 	Unique task identifier on this server.	May be passed into
 	link:cmd-kill.html[kill] to cancel or terminate the task.
-	Task identifiers have a period of 2\^32-1, and start from
+	Task identifiers have a period of 2^32-1, and start from
 	a random value.
 
 State::
diff --git a/Documentation/cmd-stream-events.txt b/Documentation/cmd-stream-events.txt
index fb54f67..bf78051 100644
--- a/Documentation/cmd-stream-events.txt
+++ b/Documentation/cmd-stream-events.txt
@@ -3,7 +3,7 @@
 
 NAME
 ----
-gerrit stream-events - Monitor events occuring in real time
+gerrit stream-events - Monitor events occurring in real time
 
 SYNOPSIS
 --------
@@ -13,7 +13,7 @@
 DESCRIPTION
 -----------
 
-Provides a portal into the major events occuring on the server,
+Provides a portal into the major events occurring on the server,
 outputing activity data in real-time to the client.  Events are
 filtered by the caller's access permissions, ensuring the caller
 only receives events for changes they can view on the web, or in
@@ -32,11 +32,11 @@
 EXAMPLES
 --------
 
------
+====
   $ ssh -p 29418 review.example.com gerrit stream-events
   {"type":"comment-added",change:{"project":"tools/gerrit", ...}, ...}
   {"type":"comment-added",change:{"project":"tools/gerrit", ...}, ...}
------
+====
 
 SCHEMA
 ------
diff --git a/Documentation/cmd-suexec.txt b/Documentation/cmd-suexec.txt
index 98a66ad..baffd53 100644
--- a/Documentation/cmd-suexec.txt
+++ b/Documentation/cmd-suexec.txt
@@ -8,28 +8,38 @@
 SYNOPSIS
 --------
 [verse]
-'ssh' -p <port> 'Gerrit Code Review'@localhost -i <private host key> 'suexec' \--as <EMAIL> [\--from HOST:PORT] [\--] [COMMAND]
+'ssh' -p <port>
+  -i SITE_PATH/etc/ssh_host_rsa_key
+  '"Gerrit Code Review@localhost"'
+  'suexec'
+  --as <EMAIL>
+  [--from HOST:PORT]
+  [--]
+  [COMMAND]
 
 DESCRIPTION
 -----------
-The suexec command can only be invoked by the magic user Gerrit Code Review
-and permits executing any other command as any other registered user account.
+The suexec command can only be invoked by the magic user `Gerrit
+Code Review` and permits executing any other command as any other
+registered user account.
 
 OPTIONS
 -------
 
-\--as::
+--as::
 	Email address of the user you want to impersonate.
-\--from::
-	Hostname and port of the machine you want to impersonate the command
-	coming from.
+
+--from::
+	Hostname and port of the machine you want to impersonate
+	the command coming from.
+
 COMMAND::
 	Gerrit command you want to run.
 
 ACCESS
 ------
-Caller must be the magic user Gerrit Code Review using the SSH daemon's host key
-or a key on this daemon's peer host key ring.
+Caller must be the magic user Gerrit Code Review using the SSH
+daemon's host key or a key on this daemon's peer host key ring.
 
 SCRIPTING
 ---------
@@ -40,9 +50,13 @@
 
 Approve the change with commit c0ff33 as "Verified +1" as user bob@example.com
 =====
-	$ sudo -u gerrit ssh -p 29418 -i site_path/etc/ssh_host_rsa_key \
-	'Gerrit Code Review'@localhost suexec --as bob@example.com -- \
-	gerrit approve --verified=+1 c0ff33
+  $ sudo -u gerrit ssh -p 29418 \
+    -i site_path/etc/ssh_host_rsa_key \
+    "Gerrit Code Review@localhost" \
+    suexec \
+    --as bob@example.com \
+    -- \
+    gerrit approve --verified +1 c0ff33
 =====
 
 GERRIT
diff --git a/Documentation/config-contact.txt b/Documentation/config-contact.txt
index 845a1ba..5c633cf 100644
--- a/Documentation/config-contact.txt
+++ b/Documentation/config-contact.txt
@@ -69,11 +69,11 @@
 
 Install a contact store implementation somewhere to receive
 the contact records.  To be really paranoid, Gerrit always
-ships the data to another HTTP server, preferrably over HTTPS.
+ships the data to another HTTP server, preferably over HTTPS.
 Existing open-source server implementations can be found in the
 gerrit-contactstore project.
 
-* link:http://android.git.kernel.org/?p=tools/gerrit-contactstore.git[gerrit-contactstore]
+* link:https://code.google.com/p/gerrit/source/checkout?repo=contactstore[gerrit-contactstore]
 
 Configure `'$site_path'/etc/gerrit.config` with the contact store's
 URL (in `contactstore.url`), and if needed, APPSEC value (in
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 8f751b4..535aaa8 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -9,7 +9,7 @@
 
 [NOTE]
 The contents of the `etc/gerrit.config` file are cached at startup
-by Gerrit.  If you modify any propeties in this file, Gerrit needs
+by Gerrit.  If you modify any properties in this file, Gerrit needs
 to be restarted before it will use the new values.
 
 Sample `etc/gerrit.config`:
@@ -24,6 +24,54 @@
   diskbuffer = 10 m
 ----
 
+[[accounts]]Section accounts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[accounts.visibility]]accounts.visibility::
++
+Controls visibility of other users' dashboard pages and
+completion suggestions to web users.
++
+If `ALL`, all users are visible to all other users, even
+anonymous users.
++
+If `SAME_GROUP`, only users who are also members of a group the
+current user is a member of are visible.
++
+If `VISIBLE_GROUP`, only users who are members of at least one group
+that is visible to the current user are visible.
++
+If `NONE`, no users other than the current user are visible.
++
+Default is `ALL`.
+
+[[addreviewer]]Section addreviewer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[[addreviewer.maxWithoutConfirmation]]addreviewer.maxWithoutConfirmation::
++
+The maximum number of reviewers a user can add at once by adding a
+group as reviewer without being asked to confirm the operation.
++
+If set to 0, the user will never be asked to confirm adding a group
+as reviewer.
++
+Default is 10.
++
+This setting only applies for adding reviewers in the Gerrit WebUI,
+but is ignored when adding reviewers with the
+link:cmd-set-reviewers.html[set-reviewers] command.
+
+[[addreviewer.maxAllowed]]addreviewer.maxAllowed::
++
+The maximum number of reviewers a user can add at once by adding a
+group as reviewer.
++
+If set to 0, there is no limit for the number of reviewers that can
+be added at once by adding a group as reviewer.
++
+Default is 20.
+
 [[auth]]Section auth
 ~~~~~~~~~~~~~~~~~~~~
 
@@ -43,7 +91,7 @@
 * `HTTP`
 +
 Gerrit relies upon data presented in the HTTP request.  This includes
-HTTP basic authentication, or some types of commerical single-sign-on
+HTTP basic authentication, or some types of commercial single-sign-on
 solutions.  With this setting enabled the authentication must
 take place in the web server or servlet container, and not from
 within Gerrit.
@@ -165,6 +213,22 @@
 +
 Default is -1, permitting infinite time between authentications.
 
+[[auth.maxRegisterEmailTokenAge]]auth.maxRegisterEmailTokenAge::
++
+Time in seconds before an email verification token sent to a user in
+order to validate their email address expires.
++
+* s, sec, second, seconds
+* m, min, minute, minutes
+* h, hr, hour, hours
+* d, day, days
+* w, week, weeks (`1 week` is treated as `7 days`)
+* mon, month, months (`1 month` is treated as `30 days`)
+* y, year, years (`1 year` is treated as `365 days`)
+
++
+Default is 12 hours.
+
 [[auth.httpHeader]]auth.httpHeader::
 +
 HTTP header to trust the username from, or unset to select HTTP basic
@@ -205,7 +269,7 @@
 user login names.  Only used if auth.type is `HTTP`, `HTTP_LDAP`
 or `LDAP`.
 +
-This value can be set to a format string, where `\{0\}` is replaced
+This value can be set to a format string, where `{0}` is replaced
 with the login name.  E.g. "\{0\}+gerrit@example.com" with a user
 login name of "foo" will produce "foo+gerrit@example.com" during
 the first time user "foo" registers.
@@ -244,6 +308,36 @@
 +
 By default, unset/false.
 
+[[auth.trustContainerAuth]]auth.trustContainerAuth::
++
+If true then it is the responsibility of the container hosting
+Gerrit to authenticate users. In this case Gerrit will blindly trust
+the container.
++
+This parameter only affects git over http traffic. If set to false
+then Gerrit will do the authentication (using DIGEST authentication).
++
+By default this is set to false.
+
+[[auth.userNameToLowerCase]]auth.userNameToLowerCase::
++
+If set the username that is received to authenticate a git operation
+is converted to lower case for looking up the user account in Gerrit.
++
+By setting this parameter a case insensitive authentication for the
+git operations can be achieved, if it is ensured that the usernames in
+Gerrit (scheme `username`) are stored in lower case (e.g. if the
+parameter link:#ldap.accountSshUserName[ldap.accountSshUserName] is
+set to `${sAMAccountName.toLowerCase}`). It is important that for all
+existing accounts this username is already in lower case. It is not
+possible to convert the usernames of the existing accounts to lower
+case because this would break the access to existing per-user
+branches.
++
+This parameter only affects git over http and git over SSH traffic.
++
+By default this is set to false.
+
 [[cache]]Section cache
 ~~~~~~~~~~~~~~~~~~~~~~
 
@@ -416,6 +510,13 @@
 cache automatically updates when a user first creates their account
 within Gerrit, so the cache expire time is largely irrelevant.
 
+cache `"permission_sort"`::
++
+Caches the order access control sections must be applied to a
+reference.  Sorting the sections can be expensive when regular
+expressions are used, so this cache remembers the ordering for
+each branch.
+
 cache `"projects"`::
 +
 Caches the project description records, from the `projects` table
@@ -497,9 +598,38 @@
 +
 Default is true, enabled.
 
+cache.projects.checkFrequency::
++
+How often project configuration should be checked for update from Git.
+Gerrit Code Review caches project access rules and configuration in
+memory, checking the refs/meta/config branch every checkFrequency
+minutes to see if a new revision should be loaded and used for future
+access. Values can be specified using standard time unit abbreviations
+('ms', 'sec', 'min', etc.).
++
+If set to 0, checks occur every time, which may slow down operations.
+Administrators may force the cache to flush with
+link:cmd-flush-caches.html[gerrit flush-caches].
++
+Default is 5 minutes.
+
+[[changeMerge]]Section changeMerge
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Controls whether or not the mergeability test of changes is
+enabled.  If enabled, when the change page is loaded, the test is
+triggered. The submit button will be enabled or disabled according to
+the result.
+
+----
+[changeMerge]
+  test = true
+----
+
+By default this is false (test is not enabled).
 
 [[commentlink]]Section commentlink
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Comment links are find/replace strings applied to change descriptions,
 patch comments, and in-line code comments to turn set strings into
 hyperlinks.  One common use is for linking to bug-tracking systems.
@@ -717,6 +847,15 @@
 Default on JGit is false. Although potentially slower, it yields
 much more predictable behavior.
 
+[[core.asyncLoggingBufferSize]]core.asyncLoggingBufferSize::
++
+Size of the buffer to store logging events for asynchronous logging.
+Putting a larger value can protect threads from stalling when the
+AsyncAppender threads are not fast enough to consume the logging events
+from the buffer. It also protects from loosing log entries in this case.
++
+Default is 64 entries.
+
 [[database]]Section database
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -893,10 +1032,19 @@
 Local filesystem directory holding all Git repositories that
 Gerrit knows about and can process changes for.  A project
 entity in Gerrit maps to a local Git repository by creating
-the path string `"$\{basePath}/$\{project_name}.git"`.
+the path string `"${basePath}/${project_name}.git"`.
 +
 If relative, the path is resolved relative to `'$site_path'`.
 
+[[gerrit.allProjects]]gerrit.allProjects::
++
+Name of the permissions-only project defining global server
+access controls and settings. These are inherited into every
+other project managed by the running server. The name is
+relative to `gerrit.basePath`.
++
+Defaults to `All-Projects` if not set.
+
 [[gerrit.canonicalWebUrl]]gerrit.canonicalWebUrl::
 +
 The default URL for Gerrit to be accessed through.
@@ -920,6 +1068,16 @@
 by the system administrator, and might not even be running on the
 same host as Gerrit.
 
+[[gerrit.gitHttpUrl]]gerrit.gitHttpUrl::
++
+Optional base URL for repositories available over the HTTP
+protocol.  For example, set this to `http://mirror.example.com/base/`
+to have Gerrit display URLs from this server, rather than itself.
++
+By default unset, as the HTTP daemon must be configured externally
+by the system administrator, and might not even be running on the
+same host as Gerrit.
+
 [[gerrit.replicateOnStartup]]gerrit.replicateOnStartup::
 +
 If true, replicates to all remotes on startup to ensure they are
@@ -953,36 +1111,70 @@
 [[gitweb.type]]gitweb.type::
 +
 Optional type of affiliated gitweb service. This allows using
-alternatives to gitweb, such as cgit.
+alternatives to gitweb, such as cgit. If set to disabled there
+is no gitweb hyperlinking support.
 +
-Valid values are `gitweb`, `cgit` or `custom`.
+Valid values are `gitweb`, `cgit`, `disabled` or `custom`.
 
-[[gitweb.type]]gitweb.revision::
+[[gitweb.revision]]gitweb.revision::
 +
 Optional pattern to use for constructing the gitweb URL when pointing
 at a specific commit when `custom` is used above.
 +
-Valid replacements are `$\{project\}` for the project name in Gerrit
-and `$\{commit\}` for the SHA1 hash for the commit.
+Valid replacements are `${project}` for the project name in Gerrit
+and `${commit}` for the SHA1 hash for the commit.
 
-[[gitweb.type]]gitweb.project::
+[[gitweb.project]]gitweb.project::
 +
 Optional pattern to use for constructing the gitweb URL when pointing
 at a specific project when `custom` is used above.
 +
-Valid replacements are `$\{project\}` for the project name in Gerrit.
+Valid replacements are `${project}` for the project name in Gerrit.
 
-[[gitweb.type]]gitweb.branch::
+[[gitweb.branch]]gitweb.branch::
 +
 Optional pattern to use for constructing the gitweb URL when pointing
 at a specific branch when `custom` is used above.
 +
-Valid replacements are `$\{project\}` for the project name in Gerrit
-and `$\{branch\}` for the name of the branch.
+Valid replacements are `${project}` for the project name in Gerrit
+and `${branch}` for the name of the branch.
 
+[[gitweb.filehistory]]gitweb.filehistory::
++
+Optional pattern to use for constructing the gitweb URL when pointing
+at the history of a file in a specific branch when `custom` is used
+above.
++
+Valid replacements are `${project}` for the project name in Gerrit,
+`${file}` for the file name and `${branch}` for the name of the
+branch.
+
+[[gitweb.linkname]]gitweb.linkname::
++
+Optional setting for modifying the link name presented to the user
+in the Gerrit web-UI.
++
+Default linkname for custom type is "gitweb".
+
+[[gitweb.pathSeparator]]gitweb.pathSeparator::
++
+Optional character to substitute the standard path separator (slash) in
+project names and branch names.
++
+By default, Gerrit will use hexadecimal encoding for slashes in project and
+branch names. Some web servers, such as Tomcat, reject this hexadecimal
+encoding in the URL.
++
+Some alternative gitweb services, such as link:http://gitblit.com[Gitblit],
+allow using an alternative path separator character. In Gitblit, this can be
+configured through the property link:http://gitblit.com/properties.html[web.forwardSlashCharacter].
+In Gerrit, the alternative path separator can be configured correspondingly
+using the property 'gitweb.pathSeparator'.
++
+Valid values are the characters '*', '(' and ')'.
 
 [[hooks]]Section hooks
-~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~
 
 See also link:config-hooks.html[Hooks].
 
@@ -1040,7 +1232,7 @@
 [[httpd.listenUrl]]httpd.listenUrl::
 +
 Specifies the URLs the internal HTTP daemon should listen for
-connections on.  The special hostname '\*' may be used to listen
+connections on.  The special hostname '*' may be used to listen
 on all local addresses.  A context path may optionally be included,
 placing Gerrit Code Review's web address within a subdirectory of
 the server.
@@ -1269,6 +1461,16 @@
 +
 By default, `ignore`.
 
+[[ldap.readTimeout]]ldap.readTimeout::
++
+_(Optional)_ The read timeout for an LDAP operation. The value is
+in the usual time-unit format like "1 s", "100 ms", etc...
+A timeout can be used to avoid blocking all of the SSH command start
+threads in case when the LDAP server becomes slow.
++
+By default there is no timeout and Gerrit will wait for the LDAP
+server to respond until the TCP connection times out.
+
 [[ldap.accountBase]]ldap.accountBase::
 +
 Root of the tree containing all user accounts.  This is typically
@@ -1290,17 +1492,17 @@
 Query pattern to use when searching for a user account.  This may be
 any valid LDAP query expression, including the standard `(&...)` and
 `(|...)` operators.  If auth.type is `HTTP_LDAP` then the variable
-`$\{username\}` is replaced with a parameter set to the username
+`${username}` is replaced with a parameter set to the username
 that was supplied by the HTTP server.  If auth.type is `LDAP` then
-the variable `$\{username\}` is replaced by the string entered by
+the variable `${username}` is replaced by the string entered by
 the end user.
 +
 This pattern is used to search the objects contained directly under
 the `ldap.accountBase` tree.  A typical setting for this parameter
-is `(uid=$\{username\})` or `(cn=$\{username\})`, but the proper
+is `(uid=${username})` or `(cn=${username})`, but the proper
 setting depends on the LDAP schema used by the directory server.
 +
-Default is `(uid=$\{username\})` for RFC 2307 servers,
+Default is `(uid=${username})` for RFC 2307 servers,
 and `(&(objectClass=user)(sAMAccountName=${username}))`
 for Active Directory.
 
@@ -1313,7 +1515,7 @@
 +
 Attribute values may be concatenated with literal strings, for
 example to join given name and surname together use the pattern
-`$\{givenName\} $\{SN\}`.
+`${givenName} ${SN}`.
 +
 If set, users will be unable to modify their full name field, as
 Gerrit will populate it only from the LDAP data.
@@ -1330,7 +1532,7 @@
 Attribute values may be concatenated with literal strings,
 for example to set the email address to the lowercase form
 of sAMAccountName followed by a constant domain name, use
-`$\{sAMAccountName.toLowerCase\}@example.com`.
+`${sAMAccountName.toLowerCase}@example.com`.
 +
 If set, the preferred email address will be prefilled from LDAP,
 but users may still be able to register additional email address,
@@ -1348,12 +1550,12 @@
 SSH clients will default to.
 +
 Attribute values may also be forced to lowercase, or to uppercase in
-an expression.  For example, `$\{sAMAccountName.toLowerCase\}` will
+an expression.  For example, `${sAMAccountName.toLowerCase}` will
 force the value of sAMAccountName, if defined, to be all lowercase.
 The suffix `.toUpperCase` can be used for the other direction.
 The suffix `.localPart` can be used to split attribute values of
 the form 'user@example.com' and return only the left hand side, for
-example `$\{userPrincipalName.localPart\}` would provide only 'user'.
+example `${userPrincipalName.localPart}` would provide only 'user'.
 +
 If set, users will be unable to modify their SSH username field, as
 Gerrit will populate it only from the LDAP data.
@@ -1391,11 +1593,11 @@
 Query pattern used when searching for an LDAP group to connect
 to a Gerrit group.  This may be any valid LDAP query expression,
 including the standard `(&...)` and `(|...)` operators.  The variable
-`$\{groupname\}` is replaced with the search term supplied by the
+`${groupname}` is replaced with the search term supplied by the
 group owner.
 +
-Default is `(cn=$\{groupname\})` for RFC 2307,
-and `(&(objectClass=group)(cn=$\{groupname\}))` for Active Directory.
+Default is `(cn=${groupname})` for RFC 2307,
+and `(&(objectClass=group)(cn=${groupname}))` for Active Directory.
 
 [[ldap.groupMemberPattern]]ldap.groupMemberPattern::
 +
@@ -1403,17 +1605,35 @@
 account is currently a member of.  This may be any valid LDAP query
 expression, including the standard `(&...)` and `(|...)` operators.
 +
-If auth.type is `HTTP_LDAP` then the variable `$\{username\}` is
+If auth.type is `HTTP_LDAP` then the variable `${username}` is
 replaced with a parameter set to the username that was supplied
 by the HTTP server.  Other variables appearing in the pattern,
-such as `$\{fooBarAttribute\}`, are replaced with the value of the
+such as `${fooBarAttribute}`, are replaced with the value of the
 corresponding attribute (in this case, `fooBarAttribute`) as read
 from the user's account object matched under `ldap.accountBase`.
-Attributes such as `$\{dn\}` or `$\{uidNumber\}` may be useful.
+Attributes such as `${dn}` or `${uidNumber}` may be useful.
 +
-Default is `(memberUid=$\{username\})` for RFC 2307,
+Default is `(memberUid=${username})` for RFC 2307,
 and unset (disabled) for Active Directory.
 
+[[ldap.localUsernameToLowerCase]]ldap.localUsernameToLowerCase::
++
+Converts the local username, that is used to login into the Gerrit
+WebUI, to lower case before doing the LDAP authentication. By setting
+this parameter to true, a case insensitive login to the Gerrit WebUI
+can be achieved.
++
+If set, it must be ensured that the local usernames for all existing
+accounts are converted to lower case, otherwise a user that has a
+local username that contains upper case characters cannot login
+anymore. The local usernames for the existing accounts can be
+converted to lower case by running the server program
+link:pgm-LocalUsernamesToLowerCase.html[LocalUsernamesToLowerCase].
+Please be aware that the conversion of the local usernames to lower
+case can't be undone. For newly created accounts the local username
+will be directly stored in lower case.
++
+By default, unset/false.
 
 [[mimetype]]Section mimetype
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1423,8 +1643,8 @@
 If set to true, files with the MIME type `<name>` will be sent as
 direct downloads to the user's browser, rather than being wrapped up
 inside of zipped archives.  The type name may be a complete type
-name, e.g. `image/gif`, a generic media type, e.g. `image/\*`,
-or the wildcard `\*/*` to match all types.
+name, e.g. `image/gif`, a generic media type, e.g. `image/*`,
+or the wildcard `*/*` to match all types.
 +
 By default, false for all MIME types.
 
@@ -1471,14 +1691,17 @@
 
 [[receive]]Section receive
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
-Sets the group of users allowed to execute 'receive-pack' on the
-server, 'receive-pack' is what runs on the server during a user's
-push or repo upload command.
+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
+repo upload command. It also contains some advanced options for tuning the
+behavior of Gerrit's 'receive-pack' mechanism.
 
 ----
 [receive]
   allowGroup = GROUP_ALLOWED_TO_EXECUTE
   allowGroup = YET_ANOTHER_GROUP_ALLOWED_TO_EXECUTE
+  maxObjectSizeLimit = 40 m
 ----
 
 [[receive.allowGroup]]receive.allowGroup::
@@ -1489,20 +1712,48 @@
 If no groups are added, any user will be allowed to execute
 'receive-pack' on the server.
 
+[[receive.maxObjectSizeLimit]]receive.maxObjectSizeLimit::
++
+Maximum allowed Git object size that 'receive-pack' will accept.
+If an object is larger than the given size the pack-parsing will abort
+and the push operation will fail. If set to zero then there is no
+limit.
++
+Gerrit administrator can use this setting to prevent developers
+from pushing objects which are too large to Gerrit.
++
+Default is zero.
++
+Common unit suffixes of 'k', 'm', or 'g' are supported.
+
+[[receive.threadPoolSize]]receive.threadPoolSize::
++
+Maximum size of the thread pool in which the change data in received packs is
+processed.
++
+Defaults to the number of available CPUs according to the Java runtime.
+
+[[receive.timeout]]receive.timeout::
++
+Overall timeout on the time taken to process the change data in
+received packs. Only includes the time processing Gerrit changes
+and updating references, not the time to index the pack. Values can
+be specified using standard time unit abbreviations ('ms', 'sec',
+'min', etc.).
++
+Default is 2 minutes. If no unit is specified, millisconds
+is assumed.
+
 
 [[repository]]Section repository
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Repositories in this sense are the same as projects.
 
-In the following example configuration the `Administrators` and the
-`Registered Users` groups are set to be the ones to be allowed to
-create projects matching `*` (any project).  `Registered Users` is
-set to be the default owner of new projects.
+In the following example configuration `Registered Users` is set
+to be the default owner of new projects.
 
 ----
 [repository "*"]
-  createGroup = Administrators
-  createGroup = Registered Users
   ownerGroup = Registered Users
 ----
 
@@ -1510,24 +1761,22 @@
 Currently only the repository name `*` is supported.
 This is a wildcard designating all repositories.
 
-[[repository.name.createGroup]]repository.<name>.createGroup::
-+
-A name of a group which exists in the database. Zero, one or many
-groups are allowed.  Each on its own line.  Groups which don't exist
-in the database are ignored.
-+
-If no groups are declared (or only non-existing ones), the default
-value `Administrators` is used.
-
 [[repository.name.ownerGroup]]repository.<name>.ownerGroup::
 +
 A name of a group which exists in the database. Zero, one or many
 groups are allowed.  Each on its own line.  Groups which don't exist
 in the database are ignored.
+
+[[rules]]Section rules
+~~~~~~~~~~~~~~~~~~~~~~
+
+[[rules.enable]]rules.enable::
 +
-If no groups are declared (or only non-existing ones), it defaults
-to whatever is declared by `repository.<name>.createGroup` (including
-any fallback to `Administrators`.)
+If true, Gerrit will load and excute 'rules.pl' files in each
+project's refs/meta/config branch, if present. When set to false,
+only the default internal rules will be used.
++
+Default is true, to execute project specific rules.
 
 [[sendemail]]Section sendemail
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1554,7 +1803,7 @@
 +
 * `MIXED`
 +
-Shorthand for `$\{user\} (Code Review) <review@example.com>` where
+Shorthand for `${user} (Code Review) <review@example.com>` where
 `review@example.com` is the same as <<user.email,user.email>>.
 See below for a description of how the replacement is handled.
 +
@@ -1570,7 +1819,7 @@
 If set to a name and email address in brackets, Gerrit will use
 this name and email address for any messages, overriding the name
 that may have been selected for commits by user.name and user.email.
-Optionally, the name portion may contain the placeholder `$\{user\}`,
+Optionally, the name portion may contain the placeholder `${user}`,
 which is replaced by the Full Name of the current user.
 
 +
@@ -1640,6 +1889,25 @@
 +
 By default, unset, so no Expiry-Date header is generated.
 
+
+[[site]]Section site
+~~~~~~~~~~~~~~~~~~~~
+
+[[site.checkUserAgent]]site.checkUserAgent::
++
+If true the server checks the User-Agent HTTP header and sends the
+correct JavaScript to the client as part of the initial page load.
+This usually reduces a round-trip for the client, allowing the UI to
+start more quickly. If false, a tiny JavaScript loader is sent to the
+client instead to determine the correct code to use. Default is true.
+
+[[site.refreshHeaderFooter]]site.refreshHeaderFooter::
++
+If true the server checks the site header, footer and CSS files for
+updated versions. If false, a server restart is required to change
+any of these resources. Default is true, allowing automatic reloads.
+
+
 [[sshd]] Section sshd
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -1653,14 +1921,34 @@
 * 'hostname':'port' (for example `review.example.com:29418`)
 * 'IPv4':'port' (for example `10.0.0.1:29418`)
 * ['IPv6']:'port' (for example `[ff02::1]:29418`)
-* \*:'port' (for example `*:29418`)
+* *:'port' (for example `*:29418`)
 
 +
 If multiple values are supplied, the daemon will listen on all
 of them.
 +
+To disable the internal SSHD, set listenAddress to `off`.
++
 By default, *:29418.
 
+[[sshd.advertisedAddress]]sshd.advertisedAddress::
++
+Specifies the addresses clients should be told to connect to.
+This may differ from sshd.listenAddress if a firewall based port
+redirector is being used, making Gerrit appear to answer on port
+22. The following forms may be used to specify an address.  In any
+form, `:'port'` may be omitted to use the default SSH port of 22.
++
+* 'hostname':'port' (for example `review.example.com:22`)
+* 'IPv4':'port' (for example `10.0.0.1:29418`)
+* ['IPv6']:'port' (for example `[ff02::1]:29418`)
+
++
+If multiple values are supplied, the daemon will advertise all
+of them.
++
+By default, sshd.listenAddress.
+
 [[sshd.reuseAddress]]sshd.reuseAddress::
 +
 If true, permits the daemon to bind to the port even if the port
@@ -1688,8 +1976,9 @@
 [[sshd.batchThreads]]sshd.batchThreads::
 +
 Number of threads to allocate for SSH command requests from
-non-interactive users. If equals to 0, then all non-interactive
-requests are executed in the same queue as interactive requests.
+link:access-control.html#non-interactive_users[non-interactive users].
+If equals to 0, then all non-interactive requests are executed in the same
+queue as interactive requests.
 +
 Any other value will remove the number of threads from the queue
 allocated to interactive users, and create a separate thread pool
@@ -1710,7 +1999,7 @@
 +
 By default, 1 plus the number of CPUs available to the JVM.
 
-[sshd.commandStartThreads]]sshd.commandStartThreads::
+[[sshd.commandStartThreads]]sshd.commandStartThreads::
 +
 Number of threads used to parse a command line submitted by a client
 over SSH for execution, create the internal data structures used by
@@ -1781,21 +2070,22 @@
 [[suggest]] Section suggest
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-[[suggest.accounts]]::
+[[suggest.accounts]]suggest.accounts::
 +
-If `ALL`, all matching user accounts will be offered as
-completion suggestions when adding a reviewer to a change,
-or a user to a group.
+If `true`, visible user accounts (according to the value of
+`accounts.visibility`) will be offered as completion suggestions
+when adding a reviewer to a change, or a user to a group.
 +
-If `SAME_GROUP`, only users who are also members of a group the
-current user is a member of will be offered.
+If `false`, account suggestion is disabled.
 +
-If `VISIBLE_GROUP`, only users who are members of at least one group
-that is visible to the current user will be offered.
+Older configurations may also have one of the `accounts.visibility`
+values for this field, including `OFF` as a synonym for `NONE`. If
+`accounts.visibility` is also set, that value overrides this one;
+otherwise, this value applies to both `suggest.accounts` and
+`accounts.visibility`.
 +
-If `OFF`, no account suggestions are given.
-+
-Default is `ALL`.
+New configurations should prefer the boolean value for this field
+and an enum value for `accounts.visibility`.
 
 [[theme]] Section theme
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -1864,7 +2154,7 @@
 this section, existing changes must be reindexed with the
 link:pgm-ScanTrackingIds.html[ScanTrackingIds] program.
 
-The tracking ids are serachable using tr:<tracking id> or
+The tracking ids are searchable using tr:<tracking id> or
 bug:<tracking id>.
 
 ----
@@ -1882,7 +2172,9 @@
 [[trackingid.name.footer]]trackingid.<name>.footer::
 +
 A prefix tag that identify the footer line to parse for tracking ids.
-Several trakingid entries can have the same footer tag.
+Several trackingid entries can have the same footer tag. A single
+trackingid entry can have multiple footer tags. If multiple footer
+tags are specified, each tag will be parsed separately.
 (the trailing ":" is optional)
 
 [[trackingid.name.match]]trackingid.<name>.match::
@@ -1924,7 +2216,7 @@
 
 
 [[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.
@@ -1964,9 +2256,16 @@
 +
 By default, not set, generating the value at startup.
 
+[[user.anonymousCoward]]user.anonymousCoward::
++
+Username that this displayed in the Gerrit WebUI and in e-mail
+notifications if the full name of the user is not set.
++
+By default "Anonymous Coward" is used.
+
 
 File `etc/secure.config`
--------------------------
+------------------------
 The optional file `'$site_path'/etc/secure.config` overrides (or
 supplements) the settings supplied by `'$site_path'/etc/gerrit.config`.
 The file should be readable only by the daemon process and can be
@@ -1975,6 +2274,9 @@
 
 Sample `etc/secure.config`:
 ----
+[auth]
+  registerEmailPrivateKey = 2zHNrXE2bsoylzUqDxZp0H1cqUmjgWb6
+
 [database]
   username = webuser
   password = s3kr3t
@@ -2001,6 +2303,16 @@
 
 * link:config-replication.html[Git Replication/Mirroring]
 
+File `etc/peer_keys`
+--------------------
+
+The optional file `'$site_path'/etc/peer_keys` controls who can
+login as the 'Gerrit Code Review' user, required for the link:cmd-suexec.html[suexec]
+command.
+
+The format is one Base-64 encoded public key per line.
+
+
 Database system_config
 ----------------------
 
@@ -2028,64 +2340,6 @@
 * link:config-headerfooter.html[Site Header/Footer]
 * link:config-replication.html[Git Replication/Mirroring]
 
-Not User Serviceable
-~~~~~~~~~~~~~~~~~~~~
-
-These fields generally shouldn't be modified.
-
-register_email_private_key::
-+
-Private key used to sign the links emailed to users when they
-request to register a new email address on their user account.
-When the link is activated, the private key authenticates the link
-was created and sent by this Gerrit server, proving that the user
-can receive email at the address they are registering.
-+
-This column is automatically generated when the database is
-initialized.  Changing it to a new value would cause all current
-links to be invalidated.
-+
-Changing it is not recommended.
-
-admin_group_id::
-+
-Unique identity of the group with full privileges.  Any user who
-is a member of this group may manage any other group, any project,
-and other system settings over the web.
-+
-This is initialized by Gerrit to be the "Administrators" group.
-+
-Changing it is not recommended.
-
-anonymous_group_id::
-+
-Unique identity of the group for anonymous (not authenticated) users.
-+
-All users are a member of this group, whether or not they are
-actually signed in to Gerrit.  Any access rights assigned to
-this group are inherited by all users.
-+
-This is initialized by Gerrit to be the "Anonymous Users" group.
-+
-Changing it is not recommended.
-
-registered_group_id::
-+
-Unique identity of the group for all authenticated users.
-+
-All signed-in users are a member of this group.  Any access rights
-assigned to this group are inherited by all users once they have
-authenticated to Gerrit.
-+
-Since account registration is open and fairly easy to obtain,
-moving from the "Anonymous Users" group to this group is not
-very difficult.  Caution should be taken when assigning any
-permissions to this group.
-+
-This is initialized by Gerrit to be the "Registered Users" group.
-+
-Changing it is not recommended.
-
 GERRIT
 ------
 Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-hooks.txt b/Documentation/config-hooks.txt
index fd2ae82..ceb7c78 100644
--- a/Documentation/config-hooks.txt
+++ b/Documentation/config-hooks.txt
@@ -11,7 +11,7 @@
 
 Make sure your hook scripts are executable if running on *nix.
 
-Hooks are run in the background after the relevent change has
+Hooks are run in the background after the relevant change has
 taken place so are unable to affect the outcome of any given
 change. Because of the fact the hooks are run in the background
 after the activity, a hook might not be notified about an event if
@@ -75,6 +75,15 @@
   ref-updated --oldrev <old rev> --newrev <new rev> --refname <ref name> --project <project name> --submitter <submitter>
 ====
 
+cla-signed
+~~~~~~~~~~~
+
+Called whenever a user signs a contributor license agreement
+
+====
+  cla-signed --submitter <submitter> --user-id <user_id> --cla-id <cla_id>
+====
+
 
 Configuration Settings
 ----------------------
@@ -91,7 +100,7 @@
 -------------------
 
 If link:config-gerrit.html#gerrit.canonicalWebUrl[gerrit.canonicalWebUrl]
-is not set in `gerrit.config` the `\--change-url` flag may not be
+is not set in `gerrit.config` the `--change-url` flag may not be
 passed to all hooks.  Hooks started out of an SSH context (for example
 the patchset-created hook) don't know the server's web URL, unless
 this variable is configured.
diff --git a/Documentation/config-mail.txt b/Documentation/config-mail.txt
index 168bbfe..8aa7d08 100644
--- a/Documentation/config-mail.txt
+++ b/Documentation/config-mail.txt
@@ -83,6 +83,14 @@
 related to a user submitting a new patchset for a change.  It is a
 `ChangeEmail`: see `ChangeSubject.vm` and `ChangeFooter.vm`.
 
+Restored.vm
+~~~~~~~~~~~
+
+The `Restored.vm` template will determine the contents of the email related
+to a change being restored.  It is a `ChangeEmail`: see `ChangeSubject.vm` and
+`ChangeFooter.vm`.
+
+
 
 Mail Variables and Methods
 --------------------------
diff --git a/Documentation/config-replication.txt b/Documentation/config-replication.txt
index 53c69a5..772282e 100644
--- a/Documentation/config-replication.txt
+++ b/Documentation/config-replication.txt
@@ -14,7 +14,10 @@
 public/private key pair.  On a trusted network it is also possible to
 use replication over the insecure (but much faster) git:// protocol,
 by enabling the `receive-pack` service on the receiving system, but
-this configuration is not recommended.
+this configuration is not recommended.  It is also possible to
+specify a local path as replication target. This makes e.g. sense if
+a network share is mounted to which the repositories should be
+replicated.
 
 Enabling Replication
 --------------------
@@ -28,8 +31,8 @@
   sudo su -c 'ssh mirror1.us.some.org echo' gerrit2
 ====
 
-Next, create `'$site_path'/replication.config` as a Git-style config
-file, and restart Gerrit.
+Next, create `'$site_path'/etc/replication.config` as a Git-style
+config file, and restart Gerrit.
 
 Example `replication.config` to replicate in parallel to four
 different hosts:
@@ -55,8 +58,9 @@
 [[replication_config]]File `replication.config`
 -----------------------------------------------
 
-The optional file `'$site_path'/replication.config` is a Git-style
-config file that controls the replication settings for Gerrit.
+The optional file `'$site_path'/etc/replication.config` is a
+Git-style config file that controls the replication settings for
+Gerrit.
 
 The file is composed of one or more `remote` sections, each remote
 section provides common configuration settings for one or more
@@ -84,7 +88,7 @@
 threads in the thread pool, Gerrit pushes to all URLs in parallel,
 using one thread per URL.
 +
-Within each URL value the magic placeholder `$\{name}` is replaced
+Within each URL value the magic placeholder `${name}` is replaced
 with the Gerrit project name.  This is a Gerrit specific extension
 to the otherwise standard Git URL syntax and it must be included
 in each URL so that Gerrit can figure out where each project needs
@@ -123,16 +127,16 @@
 [[remote.name.push]]remote.<name>.push::
 +
 Standard Git refspec denoting what should be replicated.  Setting this
-to `+refs/heads/\*:refs/heads/\*` would mirror only the active
+to `+refs/heads/*:refs/heads/*` would mirror only the active
 branches, but not the change refs under `refs/changes/`, or the tags
 under `refs/tags/`.
 +
 Multiple push keys can be supplied, to specify multiple patterns
 to match against.  In the example file above, remote "pubmirror"
-uses two push keys to match both `refs/heads/\*` and `refs/tags/*`,
+uses two push keys to match both `refs/heads/*` and `refs/tags/*`,
 but excludes all others, including `refs/changes/*`.
 +
-Defaults to `+refs/\*:refs/*` (all refs) if not specified.
+Defaults to `+refs/*:refs/*` (all refs) if not specified.
 
 [[remote.name.timeout]]remote.<name>.timeout::
 +
@@ -193,6 +197,22 @@
 By default, replicates without group control, i.e replicates
 everything to all remotes.
 
+[[remote.name.replicatePermissions]]remote.<name>.replicatePermissions::
++
+If true, permissions-only projects and the refs/meta/config branch
+will also be replicated to the remote site.  These projects and
+branches may be needed to keep a backup or slave server current.
++
+By default, true, replicating everything.
+
+[[remote.name.mirror]]remote.<name>.mirror::
++
+If true, replication will remove remote branches that absent locally
+or invisible to the replication (i.e. read access denied via 'authGroup'
+option).
++
+By default, false, do not remove remote branches.
+
 
 [[secure_config]]File `secure.config`
 -----------------------------------------------
diff --git a/Documentation/config-sso.txt b/Documentation/config-sso.txt
index 37f5b05..9aa06be 100644
--- a/Documentation/config-sso.txt
+++ b/Documentation/config-sso.txt
@@ -88,7 +88,7 @@
 standard `Authorization` HTTP header.
 
 The auth.emailFormat field ('optional') sets the preferred email
-address during first login.  Gerrit will replace `\{0\}` with the
+address during first login.  Gerrit will replace `{0}` with the
 username, as obtained from the Authorization header.  A format such
 as shown in the example would be typical, to add the domain name
 of the organization.
@@ -152,7 +152,7 @@
 single sign-on or security group to ensure the setting is correct.
 
 The auth.emailFormat field ('optional') sets the user's preferred
-email address when they first login.  Gerrit will replace `\{0\}`
+email address when they first login.  Gerrit will replace `{0}`
 with the username, as supplied by Siteminder.  A format such as
 shown in the example would be typical, to add the domain name of
 the organization.
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt
new file mode 100644
index 0000000..2609b05
--- /dev/null
+++ b/Documentation/dev-contributing.txt
@@ -0,0 +1,243 @@
+Gerrit Code Review - Contributing
+=================================
+
+Gerrit is developed as a self-hosting open source project and
+very much welcomes contributions from anyone with a contributor's
+agreement on file with the project.
+
+* https://gerrit-review.googlesource.com/
+
+The Contributor License Agreements:
+
+* https://gerrit-review.googlesource.com/static/cla_individual.html
+* https://gerrit-review.googlesource.com/static/cla_corporate.html
+
+As Gerrit is a code review tool, naturally contributions will
+be reviewed before they will get submitted to the code base.  To
+start your contribution, please make a git commit and upload it
+for review to the main Gerrit review server.  To help speed up the
+review of your change, review these guidelines before submitting
+your change.  You can view the pending Gerrit contributions and
+their statuses here:
+
+* https://gerrit-review.googlesource.com/#/q/status:open+project:gerrit,n,z
+
+Depending on the size of that list it might take a while for
+your change to get reviewed.  Naturally there are fewer
+approvers than contributors; so anything that you can do to
+ensure that your contribution will undergo fewer revisions
+will speed up the contribution process.  This includes helping
+out reviewing other people's changes to relieve the load from
+the approvers.  Even if you are not familiar with Gerrit's
+internals, it would be of great help if you can download, try
+out, and comment on new features.  If it works as advertised,
+say so, and if you have the priviliges to do so, go ahead
+and give it a +1 Verified.  If you would find the feature
+useful, say so and give it a +1 code review.
+
+And finally, the quicker you respond to the comments of your
+reviewers, the quicker your change might get merged!  Try to
+reply to every comment after submitting your new patch,
+particularly if you decided against making the suggested change.
+Reviewers don't want to seem like nags and pester you if you
+haven't replied or made a fix, so it helps them know if you
+missed it or decided against it.
+
+
+Review Criteria
+---------------
+
+Here are some hints as to what approvers may be looking for
+before approving or submitting changes to the Gerrit project.
+Let's start with the simple nit picky stuff.  You are likely
+excited that your code works; help us share your excitement
+by not distracting us with the simple stuff.  Thanks to Gerrit,
+problems are often highlighted and we find it hard to look
+beyond simple spacing issues.  Blame it on our short attention
+spans, we really do want your code.
+
+
+Commit Message
+--------------
+
+It is essential to have a good commit message if you want your
+change to be reviewed.
+
+  * Keep lines no longer than 72 chars
+  * Start with a short one line summary
+  * Followed by a blank line
+  * Followed by one or more explanatory paragraphs
+  * Use the present tense (fix instead of fixed)
+  * Include a Bug: Issue <#> line if fixing a Gerrit issue
+  * Include a Change-Id line
+
+
+A sample good Gerrit commit message:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+====
+  Add sample commit message to guidelines doc
+
+  The original patch set for the contributing guidelines doc did not
+  include a sample commit message, this new patchset does.  Hopefully this
+  makes things a bit clearer since examples can sometimes help when
+  explanations don't.
+
+  Note that the body of this commit message can be several paragraphs, and
+  that I word wrap it at 72 characters.  Also note that I keep the summary
+  line under 50 characters since it is often truncated by tools which
+  display just the git summary.
+
+  Bug: Issue 98765605
+  Change-Id: Ic4a7c07eeb98cdeaf44e9d231a65a51f3fceae52
+====
+
+
+Style
+-----
+
+The basic coding style is covered by the tools/GoogleFormat.xml
+doc, see the link:dev-eclipse.html#Formatting[Eclipse Setup]
+for that.
+
+Highlighted/additional styling notes:
+
+  * It is generally more important to match the style of the nearby
+    code which you are modifying than it is to match the style
+    in the formatting guidelines.  This is especially true within the
+    same file.
+  * Review your change in Gerrit to see if it highlights
+    mistakingly deleted/added spaces on lines, trailing spaces.
+  * Line length should be 80 or less, unless the code reads
+    better with something slightly longer.  Shorter lines not only
+    help reviewers who may use a tablet to review the code, but future
+    contributors may also like to open several editors side by
+    side while editing new changes.
+  * Use 2 spaces for indent (no tabs)
+  * Use brackets in all ifs, spaces before/after if parens.
+  * Use /** */ style Javadocs for variables.
+
+Additionally, you will notice that most of the newline spacing
+is fairly consistent throughout the code in Gerrit, it helps to
+stick to the blank line conventions.  Here are some specific
+examples:
+
+  * Keep a blank line between all class and method declarations.
+  * Do not add blank lines at the beginning or end of class/methods.
+  * Put a blank line between external import sources, but not
+    between internal ones.
+
+
+Code Organization
+-----------------
+
+Do your best to organize classes and methods in a logical way.
+Here are some guidelines that Gerrit uses:
+
+  * Ensure a standard copyright header is included at the top
+    of any new files (copy it from another file, update the year).
+  * Always place loggers first in your class!
+  * Define any static interfaces next in your class.
+  * Define non static interfaces after static interfaces in your
+    class.
+  * Next you should define static types and members.
+  * Finally instance members, then constuctors, and then instance
+    methods.
+  * Some common exceptions are private helper static methods which
+    might appear near the instance methods which they help.
+  * Getters and setters for the same instance field should usually
+    be near each other baring a good reason not to.
+  * If you are using assisted injection, the factory for your class
+    should be before the instance members.
+  * Annotations should go before language keywords (final, private...) +
+    Example: @Assisted @Nullable final type varName
+  * Imports should be mostly aphabetical (uppercase sorts before
+    all lowercase, which means classes come before packages at the
+    same level).
+
+Wow that's a lot!  But don't worry, you'll get the habit and most
+of the code is organized this way already; so if you pay attention
+to the class you are editing you will likely pick up on it.
+Naturally new classes are a little harder; you may want to come
+back and consult this section when creating them.
+
+
+Design
+------
+
+Here are some design level ojectives that you should keep in mind
+when coding:
+
+  * ORM entity objects should match exactly one row in the database.
+  * Most client pages should perform only one RPC to load so as to
+    keep latencies down.  Exceptions would apply to RPCs which need
+    to load large data sets if splitting them out will help the
+    page load faster.  Generally page loads are expected to complete
+    in under 100ms.  This will be the case for most operations,
+    unless the data being fetched is not using Gerrit's caching
+    infrastructure.  In these slower cases, it is worth considering
+    mitigating this longer load by using a second RPC to fill in
+    this data after the page is displayed (or alternatively it might
+    be worth proposing caching this data).
+  * @Inject should be used on constructors, not on fields.  The
+    current exceptions are the ssh commands, these were implemented
+    earlier in Gerrit's development.  To stay consistent, new ssh
+    commands should follow this older pattern; but eventually these
+    should get converted to eliminate this exception.
+  * Don't leave repository objects (git or schema) open.  A .close()
+    after every open should be placed in a finally{} block.
+  * Don't leave UI components, which can cause new actions to occur,
+    enabled during RPCs which update the DB.  This is to prevent
+    people from submitting actions more than once when operating
+    on slow links.  If the action buttons are disabled, they cannot
+    be resubmitted and the user can see that Gerrit is still busy.
+  * GWT EventBus is the new way forward.
+
+
+Tests
+-----
+
+  * Tests for new code will greatly help your change get approved.
+
+
+Change Size/Number of Files Touched
+-----------------------------------
+
+And finally, I probably cannot say enough about change sizes.
+Generally, smaller is better, hopefully within reason.  Do try to
+keep things which will be confusing on their own together,
+especially if changing one without the other will break something!
+
+  * If a new feature is implemented and it is a larger one, try to
+    identify if it can be split into smaller logical features; when
+    in doubt, err on the smaller side.
+  * Separate bug fixes from feature improvements.  The bug fix may
+    be an easy candidate for approval and should not need to wait
+    for new features to be approved.  Also, combining the two makes
+    reviewing harder since then there is no clear line between the
+    fix and the feature.
+  * Separate supporting refactoring from feature changes.  If your
+    new feature requires some refactoring, it helps to make the
+    refactoring a separate change which your feature change
+    depends on.  This way, reviewers can easily review the refactor
+    change as a something that should not alter the current
+    functionality, and feel more confident they can more easily
+    spot errors this way.  Of course, it also makes it easier to
+    test and locate later on if an unfortunate error does slip in.
+    Lastly, by not having to see refactoring changes at the same
+    time, it helps reviewers understand how your feature changes
+    the current functionality.
+  * Separate logical features into separate changes.  This
+    is often the hardest part.  Here is an example:  when adding a
+    new ability, make separate changes for the UI and the ssh
+    commands if possible.
+  * Do only what the commit message describes.  In other words, things which
+    are not strictly related to the commit message shouldn't be part of
+    a change, even trivial things like externalizing a string somewhere
+    or fixing a typo.  This help keep "git blame" more useful in the future
+    and it also makes "git revert" more useful.
+  * Use topic branches to link your separate changes together.
+
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/dev-design.txt b/Documentation/dev-design.txt
index 571ec6c..bf5ba73 100644
--- a/Documentation/dev-design.txt
+++ b/Documentation/dev-design.txt
@@ -87,8 +87,9 @@
 
 Each Git commit created on the client desktop system is converted
 into a unique change record which can be reviewed independently.
-Change records are stored in PostgreSQL, where they can be queried to
-present customized user dashboards, enumerating any pending changes.
+Change records are stored in a database: PostgreSQL, MySql, or the
+built-in H2, where they can be queried to present customized user
+dashboards, enumerating any pending changes.
 
 A summary of each newly uploaded change is automatically emailed
 to reviewers, so they receive a direct hyperlink to review the
@@ -113,7 +114,7 @@
 After a change has been scored positively by reviewers, Gerrit
 enables a submit button on the web interface.  Authorized users
 can push the submit button to have the change enter the project
-repository.  The equivilant in Subversion or Perforce would be
+repository.  The equivalent in Subversion or Perforce would be
 that Gerrit is invoking `svn commit` or `p4 submit` on behalf of
 the web user pressing the button.  Due to the way Git audit trails
 are maintained, the user pressing the submit button does not need
@@ -160,11 +161,11 @@
 
 The Gerrit metadata contains a summary of the available changes,
 all comments (published and drafts), and individual user account
-information.  The metadata is housed in a PostgreSQL database,
+information.  The metadata is mostly housed in the database (*1),
 which can be located either on the same server as Gerrit, or on
 a different (but nearby) server.  Most installations would opt to
-install both Gerrit and PostgreSQL on the same server, to reduce
-administration overheads.
+install both Gerrit and the metadata database on the same server,
+to reduce administration overheads.
 
 User authentication is handled by OpenID, and therefore Gerrit
 requires that the OpenID provider selected by a user must be
@@ -175,6 +176,13 @@
 * link:http://www.postgresql.org/about/[About PostgreSQL]
 * link:http://openid.net/developers/specs/[OpenID Specifications]
 
+*1  Although an effort is underway to eliminate the use of the
+database altogether, and to store all the metadata directly in
+the git repositories themselves.  So far, as of Gerrit 2.2.1, of
+all Gerrit's metadata, only the project configuration metadata
+has been migrated out of the database and into the git
+repositories for each project.
+
 
 Project Information
 -------------------
@@ -345,7 +353,7 @@
 to be used with the JSON-RPC interface.
 
 * link:http://json-rpc.org/wd/JSON-RPC-1-1-WD-20060807.html[JSON-RPC 1.1]
-* link:http://android.git.kernel.org/?p=tools/gwtjsonrpc.git;a=blob;f=README;hb=HEAD[XSRF JSON-RPC]
+* link:http://code.google.com/p/gerrit/source/browse/README?repo=gwtjsonrpc&name=master[XSRF JSON-RPC]
 
 
 Privacy Considerations
@@ -426,7 +434,7 @@
 
 Both of these assumptions are also based upon the idea that Gerrit
 will be a lot less popular than blog software, and thus will be
-running on a lot less websites.  Spammers therefore have very little
+running on a lot fewer websites.  Spammers therefore have very little
 returned benefit for getting over the protocol hurdles.
 
 These assumptions may need to be revisited in the future if any
@@ -438,7 +446,7 @@
 
 Gerrit targets for sub-250 ms per page request, mostly by using
 very compact JSON payloads bewteen client and server.  However, as
-most of the serving stack (network, hardware, PostgreSQL metadata
+most of the serving stack (network, hardware, metadata
 database) is out of control of the Gerrit developers, no real
 guarantees can be made about latency.
 
@@ -632,19 +640,18 @@
 or becomes corrupt, Gerrit has no provisions to fallback or retry
 and errors will be returned to clients.
 
-Gerrit largely assumes that the metadata PostgreSQL database is
-online and answering both read and write queries.  Query failures
-immediately result in the operation aborting and errors being
-returned to the client, with no retry or fallback provisions.
+Gerrit largely assumes that the metadata database is online and
+answering both read and write queries.  Query failures immediately
+result in the operation aborting and errors being returned to the
+client, with no retry or fallback provisions.
 
 Due to the relatively small scale described above, it is very likely
-that the Git filesystem and PostgreSQL based metadata database
-are all housed on the same server that is running Gerrit.  If any
-failure arises in one of these components, it is likely to manifest
-in the others too.  It is also likely that the administrator cannot
-be bothered to deploy a cluster of load-balanced server hardware,
-as the scale and expected load does not justify the hardware or
-management costs.
+that the Git filesystem and metadata database are all housed on the
+same server that is running Gerrit.  If any failure arises in one of
+these components, it is likely to manifest in the others too.  It is
+also likely that the administrator cannot be bothered to deploy a
+cluster of load-balanced server hardware, as the scale and expected
+load does not justify the hardware or management costs.
 
 Most deployments caring about reliability will setup a warm-spare
 standby system and use a manual fail-over process to switch from the
diff --git a/Documentation/dev-eclipse.txt b/Documentation/dev-eclipse.txt
index 82d0a67..e239a63 100644
--- a/Documentation/dev-eclipse.txt
+++ b/Documentation/dev-eclipse.txt
@@ -13,9 +13,10 @@
 
 Install the Maven Integration plugins:
 
-http://m2eclipse.codehaus.org/[m2eclipse]
+http://www.eclipse.org/m2e/download/[m2eclipse]
 
 
+[[Formatting]]
 Code Formatter Settings
 -----------------------
 
diff --git a/Documentation/dev-readme.txt b/Documentation/dev-readme.txt
index 2ae9fac..552b5a8 100644
--- a/Documentation/dev-readme.txt
+++ b/Documentation/dev-readme.txt
@@ -11,7 +11,7 @@
 Create a new client workspace:
 
 ----
-  git clone git://android.git.kernel.org/tools/gerrit.git
+  git clone https://gerrit.googlesource.com/gerrit
   cd gerrit
 ----
 
diff --git a/Documentation/error-branch-not-found.txt b/Documentation/error-branch-not-found.txt
index 43d3546..e2dcff1 100644
--- a/Documentation/error-branch-not-found.txt
+++ b/Documentation/error-branch-not-found.txt
@@ -25,8 +25,8 @@
   'Admin' -> 'Projects' and browse your project, in the 'Branches'
   tab you can then create a new branch).
 
-Please note that you need the access right '+2 Create Branch' in the
-link:access-control.html#category_pHD['Push Branch'] category to create new branches.
+Please note that you need to be granted the
+link:access-control.html#category_create['Create reference'] access to create new branches.
 
 
 GERRIT
diff --git a/Documentation/error-not-a-gerrit-project.txt b/Documentation/error-not-a-gerrit-project.txt
index f6e90fa..368a102 100644
--- a/Documentation/error-not-a-gerrit-project.txt
+++ b/Documentation/error-not-a-gerrit-project.txt
@@ -16,10 +16,11 @@
 . Verify that you are pushing to the correct Gerrit server.
 . Go in the Gerrit WebUI to 'Admin' -> 'Projects' and check that the
   project is listed. If the project is not listed the project either
-  does not exist or you don't have read access ('+1 Read Access' in
-  the link:access-control.html#category_READ['Read Access'] category) for it. This means if you certain that
-  the project name is right you should contact the Gerrit
-  Administrator or project owner to request access to the project.
+  does not exist or you don't have
+  link:access-control.html#category_read['Read'] access for it. This
+  means if you certain that the project name is right you should
+  contact the Gerrit Administrator or project owner to request access
+  to the project.
 
 This error message might be misleading if the project actually exists
 but the push is failing because the pushing user has no read access
diff --git a/Documentation/error-not-allowed-to-upload-merges.txt b/Documentation/error-not-allowed-to-upload-merges.txt
index 3b52bc2..981ba91 100644
--- a/Documentation/error-not-allowed-to-upload-merges.txt
+++ b/Documentation/error-not-allowed-to-upload-merges.txt
@@ -6,13 +6,14 @@
 project to which the push is done.
 
 If you need to upload merge commits, you can contact one of the
-project owners and request for this project permissions to upload
-merge commits (access right '+3 Upload merges permission' in the
-link:access-control.html#category_READ['Read Access'] category).
+project owners and request permissions to upload merge commits
+(access right link:access-control.html#category_push_merge['Push Merge Commit'])
+for this project.
 
 If one of your changes could not be merged in Gerrit due to conflicts
 and you created the merge commit to resolve the conflicts, you might
-want to revert the merge and instead of this do a link:http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html[rebase].
+want to revert the merge and instead of this do a
+link:http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html[rebase].
 
 
 GERRIT
diff --git a/Documentation/error-not-signed-off-by.txt b/Documentation/error-not-signed-off-by.txt
index 4f88774..00f179b 100644
--- a/Documentation/error-not-signed-off-by.txt
+++ b/Documentation/error-not-signed-off-by.txt
@@ -7,8 +7,8 @@
 required and the commit message does not contain it, Gerrit rejects
 to push the commit with this error message.
 
-This policy can be bypassed by having the access right '+2 Forge
-Committer or Tagger Identity' in the link:access-control.html#category_FORG['Forge Identity'] category.
+This policy can be bypassed by having the access right
+link:access-control.html#category_forge_committer['Forge Committer'].
 
 This error may happen for different reasons if you do not have the
 access right to forge the committer identity:
diff --git a/Documentation/error-prohibited-by-gerrit.txt b/Documentation/error-prohibited-by-gerrit.txt
index 90c937e..69f80c1 100644
--- a/Documentation/error-prohibited-by-gerrit.txt
+++ b/Documentation/error-prohibited-by-gerrit.txt
@@ -8,15 +8,17 @@
 In particular this error occurs:
 
 1. if you push a commit for code review to a branch for which you
-   don't have upload permissions (access right '+2 Upload permission'
-   in the link:access-control.html#category_READ['Read Access'] category)
-2. if you bypass code review without sufficient privileges in the
-   link:access-control.html#category_pHD['Push Branch'] category
-3. if you push a signed or annotated tag without sufficient
-   privileges in the link:access-control.html#category_pTAG['Push Tag'] category
-4. if you push a lightweight tag without the access right '+2 Create
-   Branch' for the reference name 'refs/tags/*' in the link:access-control.html#category_pHD['Push Branch']
-   category
+   don't have upload permissions (access right
+   link:access-control.html#category_push_review['Push'] on
+   `refs/for/refs/heads/*`)
+2. if you bypass code review without
+   link:access-control.html#category_push_direct['Push'] access right
+   on `refs/heads/*`
+3. if you push an annotated tag without
+   link:access-control.html#category_push_annotated['Push Annotated Tag']
+   access right on 'refs/tags/*'
+4. if you push a lightweight tag without the access right link:access-control.html#category_create['Create
+   Reference'] for the reference name 'refs/tags/*'
 
 For new users it happens often that they accidentally try to bypass
 code review. The push then fails with the error message 'prohibited
diff --git a/Documentation/error-upload-denied.txt b/Documentation/error-upload-denied.txt
index 947280f..5dec8ab 100644
--- a/Documentation/error-upload-denied.txt
+++ b/Documentation/error-upload-denied.txt
@@ -8,8 +8,8 @@
 There are two possibilities how to continue in this situation:
 
 . contact one of the project owners and request upload permissions
-  for the project (access right '+2 Upload permission' in the
-  link:access-control.html#category_READ['Read Access'] category)
+  for the project (access right
+  link:access-control.html#category_push['Push'])
 . export your commit as a patch using the link:http://www.kernel.org/pub/software/scm/git/docs/git-format-patch.html[git format-patch] command
   and provide the patch file to one of the project owners
 
diff --git a/Documentation/error-you-are-not-author.txt b/Documentation/error-you-are-not-author.txt
index 47a7652..a245252 100644
--- a/Documentation/error-you-are-not-author.txt
+++ b/Documentation/error-you-are-not-author.txt
@@ -5,8 +5,8 @@
 the author matches one of the registered e-mail addresses of the
 pushing user. If this is not the case pushing the commit fails with
 the error message "you are not author ...". This policy can be
-bypassed by having the access right '+1 Forge Author Identity' in the
-link:access-control.html#category_FORG['Forge Identity'] category.
+bypassed by having the access right
+link:access-control.html#category_forge_author['Forge Author'].
 
 This error may happen for two reasons:
 
@@ -95,7 +95,7 @@
 you have to amend the commit with explicitly setting the author
 before continuing the rebase.
 
-Here is an exmaple that shows how the interactive rebase is used to
+Here is an example that shows how the interactive rebase is used to
 update the author for the last 3 commits:
 
 ----
diff --git a/Documentation/error-you-are-not-committer.txt b/Documentation/error-you-are-not-committer.txt
index 26e0cae..b5b8c44 100644
--- a/Documentation/error-you-are-not-committer.txt
+++ b/Documentation/error-you-are-not-committer.txt
@@ -5,8 +5,8 @@
 the committer matches one of the registered e-mail addresses of the
 pushing user. If this is not the case pushing the commit fails with
 the error message "you are not committer ...". This policy can be
-bypassed by having the access right '+2 Forge Committer or Tagger
-Identity' in the link:access-control.html#category_FORG['Forge Identity'] category.
+bypassed by having the access right
+link:access-control.html#category_forge_committer['Forge Committer'].
 
 This error may happen for two reasons:
 
diff --git a/Documentation/i18n-readme.txt b/Documentation/i18n-readme.txt
index 74a8e49..080ecb6 100644
--- a/Documentation/i18n-readme.txt
+++ b/Documentation/i18n-readme.txt
@@ -12,7 +12,7 @@
 The getName() function produces only a single translation of the
 description string.  This name is set by the Gerrit administrator,
 which may cause problems if the site is translated into multiple
-langauges and different users want different translations.
+languages and different users want different translations.
 
 ApprovalCategoryValue
 ---------------------
@@ -20,7 +20,7 @@
 The getName() function produces only a single translation of the
 description string.  This name is set by the Gerrit administrator,
 which may cause problems if the site is translated into multiple
-langauges and different users want different translations.
+languages and different users want different translations.
 
 /Gerrit Gerrit.html
 -------------------
diff --git a/Documentation/images/intro-quick-central-gerrit.dia b/Documentation/images/intro-quick-central-gerrit.dia
new file mode 100644
index 0000000..8192ba9
--- /dev/null
+++ b/Documentation/images/intro-quick-central-gerrit.dia
Binary files differ
diff --git a/Documentation/images/intro-quick-central-gerrit.png b/Documentation/images/intro-quick-central-gerrit.png
new file mode 100644
index 0000000..61b9638
--- /dev/null
+++ b/Documentation/images/intro-quick-central-gerrit.png
Binary files differ
diff --git a/Documentation/images/intro-quick-central-repo.dia b/Documentation/images/intro-quick-central-repo.dia
new file mode 100644
index 0000000..9916dbb
--- /dev/null
+++ b/Documentation/images/intro-quick-central-repo.dia
Binary files differ
diff --git a/Documentation/images/intro-quick-central-repo.png b/Documentation/images/intro-quick-central-repo.png
new file mode 100644
index 0000000..84ffeb0
--- /dev/null
+++ b/Documentation/images/intro-quick-central-repo.png
Binary files differ
diff --git a/Documentation/images/intro-quick-hot-key-help.jpg b/Documentation/images/intro-quick-hot-key-help.jpg
new file mode 100644
index 0000000..41bcbe4
--- /dev/null
+++ b/Documentation/images/intro-quick-hot-key-help.jpg
Binary files differ
diff --git a/Documentation/images/intro-quick-new-review.jpg b/Documentation/images/intro-quick-new-review.jpg
new file mode 100644
index 0000000..99e6c55
--- /dev/null
+++ b/Documentation/images/intro-quick-new-review.jpg
Binary files differ
diff --git a/Documentation/images/intro-quick-review-2-patches.jpg b/Documentation/images/intro-quick-review-2-patches.jpg
new file mode 100644
index 0000000..29c99cc
--- /dev/null
+++ b/Documentation/images/intro-quick-review-2-patches.jpg
Binary files differ
diff --git a/Documentation/images/intro-quick-review-line-comment.jpg b/Documentation/images/intro-quick-review-line-comment.jpg
new file mode 100644
index 0000000..eeb144a
--- /dev/null
+++ b/Documentation/images/intro-quick-review-line-comment.jpg
Binary files differ
diff --git a/Documentation/images/intro-quick-reviewing-the-change.jpg b/Documentation/images/intro-quick-reviewing-the-change.jpg
new file mode 100644
index 0000000..bfded9e
--- /dev/null
+++ b/Documentation/images/intro-quick-reviewing-the-change.jpg
Binary files differ
diff --git a/Documentation/images/intro-quick-verifying.jpg b/Documentation/images/intro-quick-verifying.jpg
new file mode 100644
index 0000000..7679c0a
--- /dev/null
+++ b/Documentation/images/intro-quick-verifying.jpg
Binary files differ
diff --git a/Documentation/index.txt b/Documentation/index.txt
index 1ad51a3..5143bf7 100644
--- a/Documentation/index.txt
+++ b/Documentation/index.txt
@@ -1,6 +1,11 @@
 Gerrit Code Review for Git
 ==========================
 
+Getting Started
+---------------
+
+* link:intro-quick.html[A Quick Introduction To Gerrit]
+
 User Guide
 ----------
 
@@ -13,12 +18,14 @@
 * link:user-signedoffby.html[Signed-off-by Lines]
 * link:access-control.html[Access Controls]
 * link:error-messages.html[Error Messages]
+* link:user-submodules.html[Subscribing to Git Submodules]
 
 Installation
 ------------
 
 * link:licenses.html[Licenses and Notices]
 * link:install.html[Installation Guide]
+* link:install-quick.html[Quick Installation in 10 Minutes]
 * link:project-setup.html[Project Setup]
 
 Configuration
@@ -39,6 +46,7 @@
 
 * link:dev-readme.html[Developer Setup]
 * link:dev-eclipse.html[Eclipse Setup]
+* link:dev-contributing.html[Contributing to Gerrit]
 * link:dev-design.html[System Design]
 * link:i18n-readme.html[i18n Support]
 
diff --git a/Documentation/install-j2ee.txt b/Documentation/install-j2ee.txt
index d51ba68..507d6c5 100644
--- a/Documentation/install-j2ee.txt
+++ b/Documentation/install-j2ee.txt
@@ -11,7 +11,7 @@
 
 Gerrit Code Review can be installed into any J2EE servlet container,
 including popular open source containers such as Jetty or Tomcat, or
-any commerical server which supports the J2EE servlet specification.
+any commercial server which supports the J2EE servlet specification.
 
 
 Installation
diff --git a/Documentation/install-quick.txt b/Documentation/install-quick.txt
new file mode 100644
index 0000000..6bea7f8
--- /dev/null
+++ b/Documentation/install-quick.txt
@@ -0,0 +1,333 @@
+Gerrit Code Review - Quick get started guide
+============================================
+
+****
+This guide was made with the impatient in mind, ready to try out Gerrit on their
+own server but not prepared to make the full installation procedure yet.
+
+Explanation is sparse and you should not use a server installed this way in a
+live setup, this is made with proof of concept activities in mind.
+
+It is presumed you install it on a Unix based server such as any of the Linux
+flavors or BSD.
+
+It's also presumed that you have access to an OpenID enabled email address.
+Examples of OpenID enable email providers are gmail, yahoo and hotmail.
+It's also possible to register a custom email address with OpenID, but that is
+outside the scope of this quick installation guide. For testing purposes one of
+the above providers should be fine. Please note that network access to the
+OpenID provider you choose is necessary for both you and your Gerrit instance.
+****
+
+
+[[requirements]]
+Requirements
+------------
+
+Most distributions come with Java today. Do you already have Java installed?
+
+----
+  $ 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)
+----
+
+If Java isn't installed, get it:
+
+* JDK, minimum version 1.6 http://www.oracle.com/technetwork/java/javase/downloads/index.html[Download]
+
+
+[[user]]
+Create a user to host the Gerrit service
+----------------------------------------
+
+We will run the service as a non privileged user on your system.
+First create the user and then become the user:
+
+----
+  $ sudo adduser gerrit2
+  $ sudo su gerrit2
+----
+
+If you don't have root privileges you could skip this step and run gerrit
+as your own user as well.
+
+
+[[download]]
+Download Gerrit
+---------------
+
+It's time to download the archive that contains the gerrit web and ssh service.
+
+You can choose from different versions to download from here:
+
+* http://code.google.com/p/gerrit/downloads/list[A list of releases available]
+
+This tutorial is based on version 2.2.2, and you can download that from this link
+
+* http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.war[Link to the 2.2.2 war archive]
+
+
+[[initialization]]
+Initialize the Site
+-------------------
+
+It's time to run the initialization, and with the batch switch enabled, we don't have to answer any questions at all:
+
+----
+  gerrit2@host:~$ java -jar gerrit.war init --batch -d ~/gerrit_testsite
+  Generating SSH host key ... rsa(simple)... done
+  Initialized /home/gerrit2/gerrit_testsite
+  Executing /home/gerrit2/gerrit_testsite/bin/gerrit.sh start
+  Starting Gerrit Code Review: OK
+  gerrit2@host:~$
+----
+
+When the init is complete, you can review your settings in the
+file `'$site_path/etc/gerrit.config'`.
+
+An important setting will be the canonicalWebUrl which will
+be needed later to access gerrit's web interface.
+
+----
+  gerrit2@host:~$ cat ~/gerrit_testsite/etc/gerrit.config | grep canonical
+  canonicalWebUrl = http://localhost:8080/
+  gerrit2@host:~$
+----
+[[usersetup]]
+The first user
+--------------
+
+It's time to exit the gerrit2 account as you now have Gerrit running on your
+host and setup your first workspace.
+
+Start a shell with the credentials of the account you will perform
+development under.
+
+Check whether there are any ssh keys already. You're looking for two files,
+id_rsa and id_rsa.pub.
+
+----
+  user@host:~$ ls .ssh
+  authorized_keys  config  id_rsa  id_rsa.pub  known_hosts
+  user@host:~$
+----
+
+If you have the files, you may skip the key generating step.
+
+If you don't see the files in your listing, your will have to generate rsa
+keys for your ssh sessions:
+
+SSH key generation
+~~~~~~~~~~~~~~~~~~
+
+*Please don't generate new keys if you already have a valid keypair!*
+*They will be overwritten!*
+
+----
+  user@host:~$ ssh-keygen -t rsa
+  Generating public/private rsa key pair.
+  Enter file in which to save the key (/home/user/.ssh/id_rsa):
+  Created directory '/home/user/.ssh'.
+  Enter passphrase (empty for no passphrase):
+  Enter same passphrase again:
+  Your identification has been saved in /home/user/.ssh/id_rsa.
+  Your public key has been saved in /home/user/.ssh/id_rsa.pub.
+  The key fingerprint is:
+  00:11:22:00:11:22:00:11:44:00:11:22:00:11:22:99 user@host
+  The key's randomart image is:
+  +--[ RSA 2048]----+
+  |     ..+.*=+oo.*E|
+  |      u.OoB.. . +|
+  |       ..*.      |
+  |       o         |
+  |      . S ..     |
+  |                 |
+  |                 |
+  |          ..     |
+  |                 |
+  +-----------------+
+  user@host:~$
+----
+
+Registering your key in Gerrit
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Open a browser and enter the canonical url you got before when
+initializing Gerrit.
+
+----
+  Canonical URL                [http://localhost:8080/]:
+----
+
+Register a new account in Gerrit through the web interface with the
+email address of your choice.
+The first user to sign-in and register an account will be
+automatically placed into the fully privileged Administrators group,
+permitting server management over the web and over SSH.  Subsequent
+users will be automatically registered as unprivileged users.
+
+Once signed in as your user, you find a little wizard to get you started.
+The wizard helps you fill out:
+
+* Real name (visible name in Gerrit)
+* Register your email (it must be confirmed later)
+* Select a username with which to communicate with Gerrit over ssh+git
+
+* The server will ask you for an RSA public key.
+That's the key we generated above, and it's time to make sure that Gerrit knows
+about our new key and can identify us by it.
+
+----
+  user@host:~$ cat .ssh/id_rsa.pub
+  ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5E785mWtMckorP5v40PyFeui9T50dKpaGYw67Mlv2J3aGBG3tS0qBQxKEpiV0J4+W0RgQHbWfNqdUYen9bC5VVH/GatYWkpL9TjjUcHzF1rX3Eyv7PHuHLAyd/8Zdv6R3saF+hNpp1JW0BSa7HXzK7iNCVA3kBuBthxeGh3OoFbaXHn1zwwVQw8I5+Lp9OOIY7sJEsM/kW699XDV6z2zlkByNVEp45j+g26x5rCnGS8GJM7A0uHsaWJddO6TiyR6/2SOBF1VtKw49XLTQcmDInFAZzUsAZSDKlfYloPkpA6YdqeG0eJqau+jtzuigydoVj4j9xidcJ9HtxZcJNuraw== user@host
+  user@host:~$
+----
+
+Copy the string starting with ssh-rsa to your clipboard and then paste it
+into the box for RSA keys. Make *absolutely sure* no extra spaces or line feeds
+are entered in the middle of the RSA string.
+
+Verify that the ssh connection works for you.
+
+----
+  user@host:~$ ssh user@localhost -p 29418
+  The authenticity of host '[localhost]:29418 ([127.0.0.1]:29418)' can't be established.
+  RSA key fingerprint is db:07:3d:c2:94:25:b5:8d:ac:bc:b5:9e:2f:95:5f:4a.
+  Are you sure you want to continue connecting (yes/no)? yes
+  Warning: Permanently added '[localhost]:29418' (RSA) to the list of known hosts.
+
+  ****    Welcome to Gerrit Code Review    ****
+
+  Hi user, you have successfully connected over SSH.
+
+  Unfortunately, interactive shells are disabled.
+  To clone a hosted Git repository, use:
+
+  git clone ssh://user@localhost:29418/REPOSITORY_NAME.git
+
+  user@host:~$
+----
+
+Project creation
+----------------
+
+Your base Gerrit server is now running and you have a user that's ready
+to interact with it.  You now have two options, either you create a new
+test project to work with or you already have a git with history that
+you would like to import into gerrit and try out code review on.
+
+New project from scratch
+~~~~~~~~~~~~~~~~~~~~~~~~
+If you choose to create a new repository from scratch, it's easier for
+you to create a project with an initial commit in it. That way first
+time setup between client and server is easier.
+
+This is done via the SSH port:
+
+----
+  user@host:~$ ssh -p 29418 user@localhost gerrit create-project --empty-commit --name demo-project
+  user@host:~$
+----
+
+This will create a repository that you could clone to work with.
+
+Already existing project
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The other alternative is if you already have a git project that you
+want to try out Gerrit on.
+First you have to create the project, this is done via the SSH port:
+
+----
+  user@host:~$ ssh -p 29418 user@localhost gerrit create-project --name demo-project
+  user@host:~$
+----
+
+You need to make sure that at least initially your account is granted
+"Create Reference" privileges for the refs/heads/* reference.
+This is done via the web interface in the Admin/Projects/Access page
+that correspond to your project.
+
+After that it's time to upload the previous history to the server:
+
+----
+  user@host:~/my-project$ git push ssh://user@localhost:29418/demo-project *:*
+  Counting objects: 2011, done.
+  Writing objects: 100% (2011/2011), 456293 bytes, done.
+  Total 2011 (delta 0), reused 0 (delta 0)
+  To ssh://user@localhost:29418/demo-project
+   * [new branch]      master -> master
+  user@host:~/my-project$
+----
+
+This will create a repository that you could clone to work with.
+
+
+My first change
+---------------
+
+Download a local clone of the repository and move into it
+
+----
+  user@host:~$ git clone ssh://user@host:29418/demo-project
+  Cloning into demo-project...
+  remote: Counting objects: 2, done
+  remote: Finding sources: 100% (2/2)
+  remote: Total 2 (delta 0), reused 0 (delta 0)
+  user@host:~$ cd demo-project
+  user@host:~/demo-project$
+----
+
+Then make a change to it and upload it as a reviewable change in Gerrit.
+
+----
+  user@host:~/demo-project$ date > testfile.txt
+  user@host:~/demo-project$ git add testfile.txt
+  user@host:~/demo-project$ git commit -m "My pretty test commit"
+  [master ff643a5] My pretty test commit
+   1 files changed, 1 insertions(+), 0 deletions(-)
+   create mode 100644 testfile.txt
+  user@host:~/demo-project$
+----
+
+Usually when you push to a remote git, you push to the reference
+`'/refs/heads/branch'`, but when working with Gerrit you have to push to a
+virtual branch representing "code review before submittal to branch".
+This virtual name space is known as /refs/for/<branch>
+
+----
+  user@host:~/demo-project$ git push origin HEAD:refs/for/master
+  Counting objects: 4, done.
+  Writing objects: 100% (3/3), 293 bytes, done.
+  Total 3 (delta 0), reused 0 (delta 0)
+  remote:
+  remote: New Changes:
+  remote:   http://localhost:8080/1
+  remote:
+  To ssh://user@localhost:29418/demo-project
+   * [new branch]      HEAD -> refs/for/master
+  user@host:~/demo-project$
+----
+
+You should now be able to access your change by browsing to the http URL
+suggested above, http://localhost:8080/1
+
+
+Quick Installation Complete
+---------------------------
+
+This covers the scope of getting Gerrit started and your first change uploaded.
+It doesn't give any clue as to how the review workflow works, please find
+link:http://source.android.com/submit-patches/workflow[Default Workflow] to
+learn more about the workflow of Gerrit.
+
+To read more on the installation of Gerrit please read link:install.html[the detailed
+installation page].
+
+
+GERRIT
+------
+
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/install.txt b/Documentation/install.txt
index 6d477bb..b90bbce 100644
--- a/Documentation/install.txt
+++ b/Documentation/install.txt
@@ -1,8 +1,17 @@
 Gerrit Code Review - Installation Guide
 =======================================
 
-You need a SQL database to house the review metadata.  Currently H2,
-MySQL and PostgreSQL are the only supported databases.
+[[requirements]]
+Requirements
+-----------
+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]
+
+You'll also need a 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.
+
 
 [[download]]
 Download Gerrit
@@ -20,6 +29,7 @@
 If you would prefer to build Gerrit directly from source, review
 the notes under link:dev-readme.html[developer setup].
 
+
 [[createdb]]
 Database Setup
 --------------
@@ -28,15 +38,27 @@
 H2
 ~~
 
-During init Gerrit will automatically configure the embedded H2
-database.  No additional configuration is necessary.  Using the
-embedded H2 database is the easiest way to get a Gerrit site up
-and running.
+During the init phase of Gerrit you will need to specify which database to use.
+If you choose H2, Gerrit will automatically set up the embedded H2 database as
+backend so no set up in advance is necessary.  Also, no additional configuration is
+necessary.  Using the embedded H2 database is the easiest way to get a Gerrit
+site up and running, making it ideal for proof of concepts or small team
+servers.  On the flip side, H2 is not the recommended option for large
+corporate installations. This is because there is no easy way to interact
+with the database while Gerrit is offline, it's not easy to backup the data,
+and it's not possible to set up H2 in a load balanced/hotswap configuration.
+
+
+If this option interests you, you might want to consider link:install-quick.html[the quick guide].
 
 [[createdb_postgres]]
 PostgreSQL
 ~~~~~~~~~~
 
+This option is more complicated than the H2 option but is recommended
+for larger installations. It's the database backend with the largest userbase
+in the Gerrit community.
+
 Create a user for the web application within Postgres, assign it a
 password, create a database to store the metadata, and grant the user
 full rights on the newly created database:
@@ -46,10 +68,14 @@
   createdb -E UTF-8 -O gerrit2 reviewdb
 ----
 
+
 [[createdb_mysql]]
 MySQL
 ~~~~~
 
+This option is also more complicated than the H2 option. Just as with
+PostgreSQL it's also recommended for larger installations.
+
 Create a user for the web application within the database, assign it a
 password, create a database, and give the newly created user full
 rights on it:
@@ -74,6 +100,11 @@
 to as `'$site_path'`.  If the embedded H2 database is being used,
 its data files will also be stored under this directory.
 
+You also have to decide where to store your server side git repositories. This
+can either be a relative path under `'$site_path'` or an absolute path
+anywhere on your server system. You have to choose a place before commencing
+your init phase.
+
 Initialize a new site directory by running the init command, passing
 the path of the site directory to be created as an argument to the
 '-d' option.  Its recommended that Gerrit Code Review be given its
@@ -82,23 +113,27 @@
 ----
   sudo adduser gerrit2
   sudo su gerrit2
-  cd ~gerrit2
 
-  java -jar gerrit.war init -d review_site
+  java -jar gerrit.war init -d /path/to/your/gerrit_application_directory
 ----
 
-If run from an interactive terminal, 'init' will prompt through a
+'Please note:' If you choose a location where your new user doesn't
+have any privileges, you may have to manually create the directory first and
+then give ownership of that location to the `'gerrit2'` user.
+
+If run from an interactive terminal, the init command will prompt through a
 series of configuration questions, including gathering information
-about the database created above.  If the terminal is not interactive
-init will make some reasonable default selections, and will use the
-embedded H2 database.
+about the database created above.  If the terminal is not interactive,
+running the init command will choose some reasonable default selections,
+and will use the embedded H2 database. Once the init phase is complete,
+you can review your settings in the file `'$site_path/etc/gerrit.config'`.
 
-Init may need to download additional JARs to support optional selected
-functionality.  If a download fails a URL will be displayed and init
-will wait for the user to manually download the JAR and store it in
-the target location.
+When running the init command, additional JARs might be downloaded to
+support optional selected functionality.  If a download fails a URL will
+be displayed and init will wait for the user to manually download the JAR
+and store it in the target location.
 
-When 'init' is complete, the daemon will be automatically started
+When the init phase is complete, the daemon will be automatically started
 in the background and your web browser will open to the site:
 
 ----
@@ -116,6 +151,14 @@
 users will be automatically registered as unprivileged users.
 
 
+Installation Complete
+---------------------
+
+Your base Gerrit server is now installed and running.  You're now ready to
+either set up more projects or start working with the projects you've already
+imported.
+
+
 [[project_setup]]
 Project Setup
 -------------
diff --git a/Documentation/intro-quick.txt b/Documentation/intro-quick.txt
new file mode 100644
index 0000000..3d5cbcb
--- /dev/null
+++ b/Documentation/intro-quick.txt
@@ -0,0 +1,390 @@
+Gerrit Code Review - A Quick Introduction
+=========================================
+
+Gerrit is a web-based code review tool built on top of the git version
+control system, but if you've got as far as reading this guide then
+you probably already know that. The purpose of this introduction is to
+allow you to answer the question, is Gerrit the right tool for me?
+Will it fit in my work flow and in my organization?
+
+What is Gerrit?
+---------------
+
+I assume that if you're reading this then you're already convinced of
+the benefits of code review in general but want some technical support
+to make it easy. Code reviews mean different things to different people.
+To some it's a formal meeting with a projector and an entire team
+going through the code line by line. To others it's getting someone to
+glance over the code before it is committed.
+
+Gerrit is intended to provide a light weight framework for reviewing
+every commit before it is accepted into the code base. Changes are
+uploaded to Gerrit but don't actually become a part of the project
+until they've been reviewed and accepted. In many ways this is simply
+tooling to support the standard open source process of submitting
+patches which are then reviewed by the project members before being
+applied to the code base. However Gerrit goes a step further making it
+simple for all committers on a project to ensure that changes are
+checked over before they're actually applied. Because of this Gerrit
+is equally useful where all users are trusted committers such as may
+the case with closed-source commercial development. Either way it's
+still desirable to have code reviewed to improve the quality and
+maintainability of the code. After all, if only one person has seen
+the code it may be a little difficult to maintain when that person
+leaves.
+
+Gerrit is firstly a staging area where changes can be checked over
+before becoming a part of the code base. It is also an enabler for
+this review process, capturing notes and comments about the changes to
+enable discussion of the change. This is particularly useful with
+distributed teams where this conversation can't happen face to face.
+Even with a co-located team having a review tool as an option is
+beneficial because reviews can be done at a time that is convenient
+for the reviewer. This allows the developer to create the review and
+explain the change while it is fresh in their mind. Without such a
+tool they either need to interrupt someone to review the code or
+switch context to explain the change when they've already moved on to
+the next task.
+
+This also creates a lasting record of the conversation which can be
+useful for answering the inevitable "I know we changed this for a
+reason" questions.
+
+Where does Gerrit fit in?
+-------------------------
+
+Any team with more than one member has a central source repository of
+some kind (or they should). Git can theoretically work without such a
+central location but in practice there is usually a central
+repository. This serves as the authoritative copy of what is actually in
+the project. This is what everyone fetches from and pushes to and is
+generally where build servers and other such tools get the source
+from.
+
+.Central Source Repository
+image::images/intro-quick-central-repo.png[Authoritative Source Repository]
+
+Gerrit is deployed in place of this central repository and adds an
+additional concept, a store of pending changes. Everyone still fetches
+from the authoritative repository but instead of pushing back to it,
+they push to this pending changes location. A change can only be submitted
+into the authoritative repository and become an accepted part of the project
+once the change has been reviewed and approved.
+
+.Gerrit in place of Central Repository
+image::images/intro-quick-central-gerrit.png[Gerrit in place of Central Repository]
+
+Like any repository hosting solution, Gerrit has a powerful
+link:access-control.html[access control model.]
+Users can even be granted access to push directly into the central
+repository, bypassing code review entirely. Gerrit can even be used
+without code review, used simply to host the repositories and
+controlling access. But generally it's just simpler and safer to go
+through the review process even for users who are allowed to directly
+push.
+
+The Life and Times of a Change
+------------------------------
+
+The easiest way to get a feel for how Gerrit works is to follow a
+change through its entire life cycle. For the purpose of this example
+we'll assume that the Gerrit Server is running on a server called
++gerrithost+ with the HTTP interface on port +8080+ and the SSH
+interface on port +29418+. The project we'll be working on is called
++RecipeBook+ and we'll be developing a change for the +master+ branch.
+
+Cloning the Repository
+~~~~~~~~~~~~~~~~~~~~~~
+
+Obviously the first thing we need to do is get the source that we're
+going to be modifying. As with any git project you do this by cloning
+the central repository that Gerrit is hosting. e.g.
+
+----
+$ git clone ssh://gerrithost:29418/RecipeBook.git RecipeBook
+Cloning into RecipeBook...
+----
+
+Then we need to make our actual change and commit it locally. Gerrit
+doesn't really change anything here, this is just the standard editing
+and git. While not strictly required, it's best to include a Change-Id
+in your commit message so that Gerrit can link together different
+versions of the same change being reviewed. Gerrit contains a standard
+link:user-changeid.html[Change-Id commit-msg hook]
+that will generate a unique Change-Id when you commit. If you don't do
+this then Gerrit will generate a Change-Id when you push your change
+for review. But because you don't have the Change-Id in your commit
+message you'll need to manually copy it in if you need to upload
+another version of your change. Because of this it's best to just
+install the hook and forget about it.
+
+Creating the Review
+~~~~~~~~~~~~~~~~~~~
+
+Once you've made your change and committed it locally it's time to
+push it to Gerrit so that it can be reviewed. This is done with a git
+push to the Gerrit server. Since we cloned our local repository
+directly from Gerrit it is the origin so we don't have to redefine the
+remote.
+
+----
+$ <work>
+$ git commit
+[master 9651f22] Change to a proper, yeast based pizza dough.
+ 1 files changed, 3 insertions(+), 2 deletions(-)
+$ git push origin HEAD:refs/for/master
+Counting objects: 5, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (3/3), 542 bytes, done.
+Total 3 (delta 0), reused 0 (delta 0)
+remote: 
+remote: New Changes:
+remote:   http://gerrithost:8080/68
+remote: 
+To ssh://gerrithost:29418/RecipeBook.git
+ * [new branch]      HEAD -> refs/for/master
+----
+
+The only different thing about this is the +refs/for/master+ branch.
+This is a magic branch that creates reviews that target the master
+branch. For every branch Gerrit tracks there is a magic
++refs/for/<branch_name>+ that you push to to create reviews.
+
+In the output of this command you'll notice that there is a link to
+the HTTP interface of the Gerrit server we just pushed to. This is the
+web interface where we will review this commit. Let's follow that link
+and see what we get.
+
+.Gerrit Code Review Screen
+image::images/intro-quick-new-review.jpg[Gerrit Review Screen]
+
+This is the Gerrit code review screen where someone will come to
+review the change. There isn't too much to see here yet, you can look
+at the diff of your change, add some comments explaining what you did
+and why, you may even add a list of people that should review the change.
+
+Reviewers can find changes that they want to review in any number of
+ways. Gerrit has a capable
+link:user-search.html[search]
+that allows project leaders (or anyone else) to find changes that need
+to be reviewed. Users can also setup watches on Gerrit projects with a
+search expression, this causes Gerrit to notify them of matching
+changes. So adding a reviewer when creating a review is just a
+recommendation.
+
+At this point the change is available for review and we need to switch
+roles to continue following the change. Now let's pretend we're the
+reviewer.
+
+Reviewing the Change
+~~~~~~~~~~~~~~~~~~~~
+
+The reviewer's life starts at the code review screen shown above. He
+can get here in a number of ways, but for some reason they've decided
+to review this change. Of particular note on this screen are the two
+"Need" lines:
+
+----
+* Need Verified
+* Need Code-Review
+----
+
+Gerrit's default work-flow requires two checks before a change is
+accepted. Code-Review is someone looking at the code, ensuring it
+meets the project guidelines, intent etc. Verifying is checking that
+the code actually compiles, unit tests pass etc. Verification is
+usually done by an automated build server rather than a person. There
+is even a
+link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[Gerrit Trigger Jenkins Plugin]
+that will automatically build each uploaded change and update the
+verified score accordingly.
+
+It is important to note that Code-Review and Verification are
+different permissions in Gerrit, allowing these tasks to be separated.
+For example, an automated process would have rights to verify but not
+to code-review.
+
+Since we are the code reviewer, we're going to review the code. To do
+this we can view it within the Gerrit web interface as either a
+unified or side-by-side diff by selecting the appropriate option. In
+the example below we've selected the side-by-side view. In either of
+these views you can add comments by double clicking on the line (or
+single click the line number) that you want to comment on. Once
+published these comments are viewable to all, allowing discussion
+of the change to take place.
+
+.Side By Side Patch View
+image::images/intro-quick-review-line-comment.jpg[Adding a Comment]
+
+Code reviewers end up spending a lot of time navigating these screens,
+looking at and commenting on these changes. To make this as efficient
+as possible Gerrit has keyboard shortcuts for most operations (and
+even some operations that are only accessible via the hot-keys). At
+any time you can hit the +?+ key to see the keyboard shortcuts.
+
+.Gerrit Hot Key Help
+image::images/intro-quick-hot-key-help.jpg[Hot Key Help]
+
+Once we've looked over the changes we need to complete reviewing the
+submission. To do this we click the _Review_ button on the change
+screen where we started. This allows us to enter a Code Review label
+and message.
+
+.Reviewing the Change
+image::images/intro-quick-reviewing-the-change.jpg[Reviewing the Change]
+
+The label that the reviewer selects determines what can happen next.
+The +1 and -1 level are just an opinion where as the +2 and -2 levels
+are allowing or blocking the change. In order for a change to be
+accepted it must have at least one +2 and no -2 votes.
+Although these are numeric values, they in no way accumulate;
+two +1s do not equate to a +2.
+
+Regardless of what label is selected, once the _Publish Comments_
+button has been clicked, the cover message and any comments on the
+files become visible to all users.
+
+In this case the change was not accepted so the creator needs to
+rework it. So let's switch roles back to the creator where we
+started.
+
+Reworking the Change
+~~~~~~~~~~~~~~~~~~~~
+
+As long as we set up the
+link:user-changeid.html[Change-Id commit-msg hook]
+before we uploaded the change, re-working it is easy. All we need
+to do to upload a re-worked change is to push another commit that has
+the same Change-Id in the message. Since the hook added a Change-ID in
+our initial commit we can simply checkout and then amend that commit.
+Then push it to Gerrit in the same way as we did to create the review. E.g.
+
+----
+$ <checkout first commit>
+$ <rework>
+$ git commit --amend
+$ git push origin HEAD:refs/for/master
+Counting objects: 5, done.
+Delta compression using up to 8 threads.
+Compressing objects: 100% (2/2), done.
+Writing objects: 100% (3/3), 546 bytes, done.
+Total 3 (delta 0), reused 0 (delta 0)
+To ssh://gerrithost:29418/RecipeBook.git
+ * [new branch]      HEAD -> refs/for/master
+----
+
+Note that the output is slightly different this time around. We don't
+get told about a new review because we're adding to an existing
+review. Having uploaded the reworked commit we can go back into the
+Gerrit web interface and look at our change.
+
+.Reviewing the Rework
+image::images/intro-quick-review-2-patches.jpg[Reviewing the Rework]
+
+If you look closely you'll notice that there are now two patch sets
+associated with this change, the initial submission and the rework.
+Rather than repeating ourselves lets assume that this time around the
+patch is given a +2 score by the code reviewer.
+
+Trying out the Change
+~~~~~~~~~~~~~~~~~~~~~
+
+With Gerrit's default work-flow there are two sign-offs, code review
+and verify. Verifying means checking that the change actually works.
+This would typically be checking that the code compiles, unit tests
+pass and similar checks. Really a project can decide how much or
+little they want to do here. It's also worth noting that this is only
+Gerrit's default work-flow, the verify check can actually be removed
+or others added.
+
+As mentioned in the code review section, verification is typically an
+automated process using the
+link:https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger[Gerrit Trigger Jenkins Plugin]
+or similar. But there are times when the code needs to be manually
+verified, or the reviewer needs to check that something actually works
+or how it works. Sometimes it's just nice to work through the code in a
+development environment rather than the web interface. All of these
+involve someone needing to get the change into their development
+environment. Gerrit makes this process easy by exposing each change as
+a git branch. So all the reviewers need to do is fetch and checkout that
+branch from Gerrit and they will have the change.
+
+We don't even need to think about it that hard, if you look at the
+earlier screen shots of the Gerrit Code Review Screen you'll notice a
+_download_ command. All we need to do to get the change is copy
+paste this command and run it in our Gerrit checkout.
+
+----
+$ git fetch http://gerrithost:8080/p/RecipeBook refs/changes/68/68/2
+From http://gerrithost:8080/p/RecipeBook
+ * branch            refs/changes/68/68/2 -> FETCH_HEAD
+$ git checkout FETCH_HEAD
+Note: checking out 'FETCH_HEAD'.
+
+You are in 'detached HEAD' state. You can look around, make experimental
+changes and commit them, and you can discard any commits you make in this
+state without impacting any branches by performing another checkout.
+
+If you want to create a new branch to retain commits you create, you may
+do so (now or later) by using -b with the checkout command again. Example:
+
+  git checkout -b new_branch_name
+
+HEAD is now at d5dacdb... Change to a proper, yeast based pizza dough.
+----
+
+Easy as that, we now have the change in our working copy to play with.
+You might be interested in what the numbers of the refspec mean.
+
+* The first *68* is the id if the change +mod 100+.  The only reason
+for this initial number is to reduce the number of files in any given
+directory within the git repository.
+* The second *68* is the full id of the change. You'll notice this in
+the URL of the Gerrit review screen.
+* The *2* is the patch-set within the change. In this example we
+uploaded some fixes so we want the second patch set rather than the
+initial one which the reviewer rejected.
+
+Manually Verifying the Change
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For simplicity we're just going to manually verify the change.
+The Verifier may be the same person as the code reviewer or a
+different person entirely. It really depends on the size of the
+project and what works. If you have Verify permission then when you
+click the _Review_ button in the Gerrit web interface you'll be
+presented with a verify score.
+
+.Verifying the Change
+image::images/intro-quick-verifying.jpg[Verifying the Change]
+
+Unlike the code review the verify check doesn't have a +2 or -2 level,
+it's either a pass or fail so all we need for the change to be
+submitted is a +1 score (and no -1's).
+
+Submitting the Change
+~~~~~~~~~~~~~~~~~~~~~
+
+You might have noticed that in the verify screen shot there are two
+buttons for submitting the score _Publish Comments_ and _Publish
+and Submit_. The publish and submit button is always visible, but will
+only work if the change meets the criteria for being submitted (I.e.
+has been both verified and code reviewed). So it's a convenience to be
+able to post review scores as well as submitting the change by clicking
+a single button. If you choose just to publish comments at this point then
+the score will be stored but the change won't yet be accepted into the code
+base. In this case there will be a _Submit Patch Set X_ button on the
+main screen. Just as Code Review and Verify are different operations
+that can be done by different users, Submission is a third operation
+that can be limited down to another group of users.
+
+Activating the _Publish and Submit_ or _Submit Patch Set X_ button
+will merge the change into the main part of the repository so that it
+becomes an accepted part of the project. After this anyone fetching
+the git repository will receive this change as a part of the master
+branch.
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/json.txt b/Documentation/json.txt
index 99b158d..b1dbc32 100644
--- a/Documentation/json.txt
+++ b/Documentation/json.txt
@@ -28,6 +28,8 @@
 
 url:: Canonical URL to reach this change
 
+commitMessage:: The full commit message for the change.
+
 lastUpdated:: Time in seconds since the UNIX epoch when this change
 was last updated.
 
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index 6442e9c..69018d8 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -36,6 +36,7 @@
 |Ehcache                    | <<apache2,Apache License 2.0>>
 |mime-util                  | <<apache2,Apache License 2.0>>
 |Jetty                      | <<apache2,Apache License 2.0>>, or link:http://www.eclipse.org/legal/epl-v10.html[EPL]
+|Prolog Cafe                | <<prolog_cafe,EPL or GPL>>
 |Google Code Prettify       | <<apache2,Apache License 2.0>>
 |JGit                       | <<jgit,New-Style BSD>>
 |JSch                       | <<sshd,New-Style BSD>>
@@ -399,6 +400,23 @@
 POSSIBILITY OF SUCH DAMAGE.
 ----
 
+[[prolog_cafe]]
+Prolog Cafe - EPL or GPL
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Originally developed by Mutsunori BANBARA and Naoyuki TAMURA at the
+Kobe University, JAPAN. Gerrit Code Review uses a fork derived from
+the 1.2.5 release.
+
+Prolog Cafe is dual licensed and available under either the
+link:http://opensource.org/licenses/eclipse-1.0.php[Eclipse Public License],
+or the
+link:http://www.gnu.org/licenses/gpl-2.0.html[GPL version 2.0 (or later)].
+
+In the context of Gerrit Code Review, Prolog Cafe is consumed
+under either the EPL or GPL version 3.0 as GPL version 2.0 is
+not compatible with Apache License 2.0.
+
 [[h2]]
 H2 Database - EPL or modified MPL
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/Documentation/pgm-ExportReviewNotes.txt b/Documentation/pgm-ExportReviewNotes.txt
index 602c245..17cc862 100644
--- a/Documentation/pgm-ExportReviewNotes.txt
+++ b/Documentation/pgm-ExportReviewNotes.txt
@@ -26,7 +26,7 @@
 -d::
 \--site-path::
 	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libaries and log files.
+	configuration data, supporting libraries and log files.
 
 \--threads::
 	Number of threads to perform the scan work with.  Default: 2.
diff --git a/Documentation/pgm-LocalUsernamesToLowerCase.txt b/Documentation/pgm-LocalUsernamesToLowerCase.txt
new file mode 100644
index 0000000..9189fee
--- /dev/null
+++ b/Documentation/pgm-LocalUsernamesToLowerCase.txt
@@ -0,0 +1,68 @@
+LocalUsernamesToLowerCase
+=========================
+
+NAME
+----
+LocalUsernamesToLowerCase - Convert the local username of every
+account to lower case
+
+SYNOPSIS
+--------
+[verse]
+'java' -jar gerrit.war 'LocalUsernamesToLowerCase' -d <SITE_PATH>
+
+DESCRIPTION
+-----------
+Converts the local username for every account to lower case. The
+local username is the username that is used to login into the Gerrit
+WebUI.
+
+This task is only intended to be run if the configuration parameter
+link:config-gerrit.html#ldap.localUsernameToLowerCase[ldap.localUsernameToLowerCase]
+was set to true to achieve case insensitive LDAP login to the Gerrit
+WebUI.
+
+Please be aware that the conversion of the local usernames to lower
+case can't be undone.
+
+The program will produce errors if there are accounts that have the
+same local username, but with different case. In this case the local
+username for these accounts is not converted to lower case.
+
+This task can run in the background concurrently to the server if the
+database is MySQL or PostgreSQL. If the database is H2, this task
+must be run by itself.
+
+OPTIONS
+-------
+
+-d::
+\--site-path::
+	Location of the gerrit.config file, and all other per-site
+	configuration data, supporting libraries and log files.
+
+\--threads::
+	Number of threads to perform the scan work with.  Defaults to
+	twice the number of CPUs available.
+
+CONTEXT
+-------
+This command can only be run on a server which has direct
+connectivity to the metadata database.
+
+EXAMPLES
+--------
+To convert the local username of every account to lower case:
+
+====
+	$ java -jar gerrit.war LocalUsernamesToLowerCase -d site_path
+====
+
+See Also
+--------
+
+* Configuration parameter link:config-gerrit.html#ldap.localUsernameToLowerCase[ldap.localUsernameToLowerCase]
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/pgm-ScanTrackingIds.txt b/Documentation/pgm-ScanTrackingIds.txt
index 4ab4a02..ea5d72e 100644
--- a/Documentation/pgm-ScanTrackingIds.txt
+++ b/Documentation/pgm-ScanTrackingIds.txt
@@ -26,7 +26,7 @@
 -d::
 \--site-path::
 	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libaries and log files.
+	configuration data, supporting libraries and log files.
 
 \--threads::
 	Number of threads to perform the scan work with.  Defaults to
diff --git a/Documentation/pgm-daemon.txt b/Documentation/pgm-daemon.txt
index 0b2e72f..1c1d343 100644
--- a/Documentation/pgm-daemon.txt
+++ b/Documentation/pgm-daemon.txt
@@ -33,7 +33,7 @@
 -d::
 \--site-path::
 	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libaries and log files.
+	configuration data, supporting libraries and log files.
 
 \--enable-httpd::
 \--disable-httpd::
@@ -48,7 +48,7 @@
 \--slave::
 	Run in slave mode, permitting only read operations
     by clients.  Commands which modify state such as
-    link:cmd-receive-pack.html[recieve-pack] (creates new changes
+    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.
 +
diff --git a/Documentation/pgm-gsql.txt b/Documentation/pgm-gsql.txt
index 938aafd..c3a492a 100644
--- a/Documentation/pgm-gsql.txt
+++ b/Documentation/pgm-gsql.txt
@@ -26,7 +26,7 @@
 -d::
 \--site-path::
 	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libaries and log files.
+	configuration data, supporting libraries and log files.
 
 CONTEXT
 -------
diff --git a/Documentation/pgm-index.txt b/Documentation/pgm-index.txt
index ce9de71..5cbe6ba0 100644
--- a/Documentation/pgm-index.txt
+++ b/Documentation/pgm-index.txt
@@ -10,22 +10,34 @@
 --------------------
 
 link:pgm-init.html[init]::
-  Initialize a new Gerrit server installation
+	Initialize a new Gerrit server installation.
 
 link:pgm-daemon.html[daemon]::
-  Gerrit HTTP, SSH network server.
+	Gerrit HTTP, SSH network server.
 
 link:pgm-gsql.html[gsql]::
 	Administrative interface to idle database.
 
+link:pgm-prolog-shell.html[prolog-shell]::
+	Simple interactive Prolog interpreter.
+
+link:pgm-rulec.html[rulec]::
+	Compile project-specific Prolog rules to JARs.
+
+version::
+	Display the release version of Gerrit Code Review.
+
+Transition Utilities
+--------------------
+
 link:pgm-ExportReviewNotes.html[ExportReviewNotes]::
 	Export submitted review information to refs/notes/review.
 
 link:pgm-ScanTrackingIds.html[ScanTrackingIds]::
 	Rescan all changes after configuring trackingids.
 
-version::
-  Display the release version of Gerrit Code Review.
+link:pgm-LocalUsernamesToLowerCase.html[LocalUsernamesToLowerCase]::
+	Convert the local username of every account to lower case.
 
 GERRIT
 ------
diff --git a/Documentation/pgm-init.txt b/Documentation/pgm-init.txt
index 9644e92..c53c57d 100644
--- a/Documentation/pgm-init.txt
+++ b/Documentation/pgm-init.txt
@@ -11,7 +11,6 @@
 'java' -jar gerrit.war 'init'
 	-d <SITE_PATH>
 	[\--batch]
-	[\--import-projects]
 	[\--no-auto-start]
 
 DESCRIPTION
@@ -21,7 +20,7 @@
 into a newly created `$site_path`.
 
 If run an an existing `$site_path`, init will upgrade some resources
-as necessary.  This can be useful to import newly created projects.
+as necessary.
 
 OPTIONS
 -------
@@ -30,22 +29,16 @@
 	configuration defaults are chosen based on the whims of
 	the Gerrit developers.
 
-\--import-projects::
-	Recursively search
-	link:config-gerrit.html#gerrit.basePath[gerrit.basePath]
-	for any Git repositories not yet registered as a project,
-	and initializes a new project for them.
-
 \--no-auto-start::
 	Don't automatically start the daemon after initializing a
-	newly created site path.  This permits the administartor
+	newly created site path.  This permits the administrator
 	to inspect and modify the configuration before the daemon
 	is started.
 
 -d::
 \--site-path::
 	Location of the gerrit.config file, and all other per-site
-	configuration data, supporting libaries and log files.
+	configuration data, supporting libraries and log files.
 
 CONTEXT
 -------
diff --git a/Documentation/pgm-prolog-shell.txt b/Documentation/pgm-prolog-shell.txt
new file mode 100644
index 0000000..f3fa2d8
--- /dev/null
+++ b/Documentation/pgm-prolog-shell.txt
@@ -0,0 +1,57 @@
+prolog-shell
+============
+
+NAME
+----
+prolog-shell - Simple interactive Prolog interpreter
+
+SYNOPSIS
+--------
+[verse]
+'java' -jar gerrit.war 'prolog-shell' [-s FILE.pl ...]
+
+DESCRIPTION
+-----------
+Provides a simple interactive Prolog interpreter for development
+and testing.
+
+OPTIONS
+-------
+-s::
+	Dynamically load the Prolog source code at startup,
+	as though the user had entered `['FILE.pl'].` into
+	the interepter once it was running. This option may
+	be supplied more than once to load multiple files.
+
+EXAMPLES
+--------
+Define a simple predicate and test it:
+
+====
+	$ cat >simple.pl
+	food(apple).
+	food(orange).
+	^D
+
+	$ java -jar gerrit.war prolog-shell -s simple.pl
+	Gerrit Code Review 2.2.1-84-ge9c3992 - Interactive Prolog Shell
+	based on Prolog Cafe 1.2.5 (mantis)
+	         Copyright(C) 1997-2009 M.Banbara and N.Tamura
+	(type Ctrl-D or "halt." to exit, "['path/to/file.pl']." to load a file)
+
+	{consulting /usr/local/google/users/sop/gerrit2/gerrit/simple.pl ...}
+	{/usr/local/google/users/sop/gerrit2/gerrit/simple.pl consulted 99 msec}
+
+	| ?- food(Type).
+
+	Type = apple ? ;
+
+	Type = orange ? ;
+
+	no
+	| ?-
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/pgm-rulec.txt b/Documentation/pgm-rulec.txt
new file mode 100644
index 0000000..6d0a632
--- /dev/null
+++ b/Documentation/pgm-rulec.txt
@@ -0,0 +1,54 @@
+rulec
+=====
+
+NAME
+----
+rulec - Compile project-specific Prolog rules to JARs
+
+SYNOPSIS
+--------
+[verse]
+'java' -jar gerrit.war 'rulec' -d <SITE_PATH> [--all | <PROJECT>...]
+
+DESCRIPTION
+-----------
+Looks for a Prolog rule file named `rules.pl` on the repository's
+`refs/meta/config` branch. If rules.pl exists, creates a JAR file
+named `rules-'SHA1'.jar` in `'$site_path'/cache/rules`.
+
+OPTIONS
+-------
+-d::
+--site-path::
+	Location of the gerrit.config file, and all other per-site
+	configuration data, supporting libraries and log files.
+
+--all::
+	Compile rules for all projects.
+
+--quiet::
+	Suppress non-error output messages.
+
+<PROJECT>:
+	Compile rules for the specified project.
+
+CONTEXT
+-------
+This command can only be run on a server which has direct
+connectivity to the metadata database, and local access to the
+managed Git repositories.
+
+Caching needs to be enabled. See
+link:config-gerrit.html#cache.directory[cache.directory].
+
+EXAMPLES
+--------
+To compile a rule JAR file for test/project:
+
+====
+	$ java -jar gerrit.war rulec -d site_path test/project
+====
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/project-setup.txt b/Documentation/project-setup.txt
index e775e9a..3d979d3 100644
--- a/Documentation/project-setup.txt
+++ b/Documentation/project-setup.txt
@@ -1,10 +1,6 @@
 Gerrit Code Review - Project Configuration
 ==========================================
 
-All Git repositories under gerrit.basePath must be registered in
-the Gerrit database in order to be accessed through SSH, or through
-the web interface.
-
 Create Through SSH
 ------------------
 
@@ -22,7 +18,7 @@
 Manual Creation
 ---------------
 
-Projects may also be manually registered with the database.
+Projects may also be manually created.
 
 Create Git Repository
 ~~~~~~~~~~~~~~~~~~~~~
@@ -47,23 +43,10 @@
 Register Project
 ~~~~~~~~~~~~~~~~
 
-One insert is needed to register a project with Gerrit.
-
-[NOTE]
-Note that the `.git` suffix is not typically included in the
-project name, as it looks cleaner in the web when not shown.
-Gerrit automatically assumes that `project.git` is the Git repository
-for a project named `project`.
+Either restart the server, or flush the `project_list` cache:
 
 ====
-  INSERT INTO projects
-  (use_contributor_agreements
-   ,submit_type
-   ,name)
-  VALUES
-  ('N'
-  ,'M'
-  ,'new/project');
+  ssh -p 29418 localhost gerrit flush-caches --cache project_list
 ====
 
 [[submit_type]]
@@ -85,20 +68,19 @@
 
 * Merge If Necessary
 +
-This is the default for a new project (and why `\'M'` is suggested
-above in the insert statement).
+This is the default for a new project.
 +
 If the change being submitted is a strict superset of the destination
 branch, then the branch is fast-forwarded to the change.  If not,
 then a merge commit is automatically created.  This is identical
-to the classical `git merge` behavior, or `git merge \--ff`.
+to the classical `git merge` behavior, or `git merge --ff`.
 
 * Always Merge
 +
 Always produce a merge commit, even if the change is a strict
 superset of the destination branch.  This is identical to the
-behavior of `git merge \--no-ff`, and may be useful if the
-project needs to follow submits with `git log \--first-parent`.
+behavior of `git merge --no-ff`, and may be useful if the
+project needs to follow submits with `git log --first-parent`.
 
 * Cherry Pick
 +
@@ -117,13 +99,17 @@
 the right order since inter-change dependencies will not be
 enforced for them.
 
+When Gerrit tries to do a merge, by default the merge will only
+succeed if there is no path conflict. By selecting the checkbox
+`Automatically resolve conflicts` Gerrit will try do a content merge
+if a path conflict occurs.
+
 
 Registering Additional Branches
 -------------------------------
 
 Branches can be created over the SSH port by any `git push` client,
-if the user has been granted the `Push Branch` > `Create Branch`
-(or higher) access right.
+if the user has been granted the `Create Reference` access right.
 
 Additional branches can also be created through the web UI, assuming
 at least one commit already exists in the project repository.
diff --git a/Documentation/user-changeid.txt b/Documentation/user-changeid.txt
index 1fa627c..124ec31 100644
--- a/Documentation/user-changeid.txt
+++ b/Documentation/user-changeid.txt
@@ -57,7 +57,7 @@
 Change Upload
 --------------
 
-During upload by pushing to a `refs/for/\*` or `refs/heads/\*`
+During upload by pushing to a `refs/for/*` or `refs/heads/*`
 branch, Gerrit will use the Change-Id line to:
 
 * Create a new change
@@ -103,7 +103,7 @@
 Amending a commit
 ~~~~~~~~~~~~~~~~~
 
-When amending a commit with `git commit \--amend`, leave the
+When amending a commit with `git commit --amend`, leave the
 Change-Id line unmodified in the commit message.  This will allow
 Gerrit to automatically update the change with the amended commit.
 
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index ba031db..3aafe8c 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -100,7 +100,7 @@
 [[project]]
 project:'PROJECT'::
 +
-Changes occuring in 'PROJECT'. If 'PROJECT' starts with `^` it
+Changes occurring in 'PROJECT'. If 'PROJECT' starts with `^` it
 matches project names by regular expression.  The
 link:http://www.brics.dk/automaton/[dk.brics.automaton
 library] is used for evaluation of such patterns.
@@ -109,12 +109,9 @@
 [[branch]]
 branch:'BRANCH'::
 +
-Changes for 'BRANCH'.  The branch name is the short name shown
-in the web interface, without the traditional 'refs/heads/'
-prefix.  This operator is a shorthand for 'refs:'.  Searching for
-'branch:master' really means 'ref:refs/heads/master', and searching
-for 'branch:refs/heads/master' is the same as searching for
-'ref:refs/heads/refs/heads/master'.
+Changes for 'BRANCH'.  The branch name is either the short name shown
+in the web interface or the full name of the destination branch with
+the traditional 'refs/heads/' prefix.
 +
 If 'BRANCH' starts with `^` it matches branch names by regular
 expression patterns.  The
@@ -181,11 +178,11 @@
 anchoring the match to the start of the string.  To match all Java
 files, use `file:^.*\.java`.
 +
-The entire regular expression pattern, including the `\^` character,
+The entire regular expression pattern, including the `^` character,
 should be double quoted when using more complex construction (like
 ones using a bracket expression). For example, to match all XML
 files named like 'name1.xml', 'name2.xml', and 'name3.xml' use
-`\file:"\^name[1-3].xml"`.
+`file:"^name[1-3].xml"`.
 +
 Currently this operator is only available on a watched project
 and may not be used in the search bar.
@@ -314,8 +311,8 @@
 `label:CodeReview=+2`::
 `label:CodeReview+2`::
 +
-Matches changes where there is at least one \+2 score for Code Review.
-The \+ prefix is optional for positive score values.  If the + is used,
+Matches changes where there is at least one +2 score for Code Review.
+The + prefix is optional for positive score values.  If the + is used,
 the = operator is optional.
 
 `label:CodeReview=-2`::
diff --git a/Documentation/user-submodules.txt b/Documentation/user-submodules.txt
new file mode 100644
index 0000000..3d14437
--- /dev/null
+++ b/Documentation/user-submodules.txt
@@ -0,0 +1,143 @@
+Gerrit Code Review - Superprojects subscribed to submodules updates
+===================================================================
+
+Description
+-----------
+
+Gerrit supports a custom git superproject feature for tracking submodules.
+This feature is useful for automatic updates on superprojects whenever
+a change is merged on tracked submodules. To take advantage of this
+feature, one should add submodule(s) to a local working copy of a
+superproject, edit the created .gitmodules configuration file to
+have a branch field on each submodule section with the value of the
+submodule branch it is subscribing to, commit the changes, push and
+merge the commit.
+
+When a commit is merged to a project, the commit content is scanned
+to identify if it registers git submodules (if the commit registers
+any gitlinks and .gitmodules file with required info) and if so,
+a new submodule subscription is registered.
+
+When a new commit of a registered submodule is merged, gerrit
+automatically updates the subscribers to the submodule with a new
+commit having the updated gitlinks.
+
+Git Submodules Overview
+-----------------------
+
+It is a git feature that allows an external repository to be
+attached inside a repository at a specific path. The objective here
+is to provide a brief overview, further details can be found
+in the official git submodule command documentation.
+
+Imagine a repository called 'super' and another one called 'a'.
+Also consider 'a' available in a running gerrit instance on "server".
+With this feature, one could attach 'a' inside of 'super' repository
+at path 'a' by executing the following command when being inside
+'super':
+=====
+git submodule add ssh://server/a a
+====
+
+Still considering the above example, after its execution notice that
+inside the local repository 'super' the 'a' folder is considered a
+gitlink to the external repository 'a'. Also notice a file called
+.gitmodules is created (it is a config file containing the
+subscription of 'a'). To provide the sha-1 each gitlink points to in
+the external repository, one should use the command:
+====
+git submodule status
+====
+
+In the example provided, if 'a' is updated and 'super' is supposed
+to see the latest sha-1 (considering here 'a' has only the master
+branch), one should then commit the modified gitlink for 'a' in
+the 'super' project. Actually it would not even need to be an
+external update, one could move to 'a' folder (insider 'super'),
+modify its content, commit, then move back to 'super' and
+commit the modified gitlink for 'a'.
+
+Creating a New Subscription
+---------------------------
+
+Defining the Submodule Branch
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This is required because Submodule subscription is actually the
+subscription of a submodule project and one of its branches for
+a branch of a super project.
+
+Since it manages subscriptions in the branch scope, we could have
+a scenario having a project called 'super' having a branch 'integration'
+subscribed to a project called 'a' in branch 'integration', and also
+having the same 'super' project but in branch 'dev' subscribed to the 'a'
+project in a branch called 'local-dev'.
+
+After adding the git submodule to a super project, one should edit
+the .gitmodules file to add a branch field to each submodule
+section which is supposed to be subscribed.
+
+The branch field is not filled by the git submodule command. Its value
+should indicate the branch of a submodule project that when updated
+will trigger automatic update of its registered gitlink.
+
+The branch value could be '.' if the submodule project branch
+has the same name as the destination branch of the commit having
+gitlinks/.gitmodules file.
+
+The branch field of a submodule section is a custom git submodule
+feature for gerrit use. One should always be sure to fill it in
+editing .gitmodules file after adding submodules to a super project,
+if it is the intention to make use of the gerrit feature introduced here.
+
+Any git submodules which are added and not have the branch field
+available in the .gitmodules file will not be subscribed by gerrit
+to automatically update the superproject.
+
+Detecting and Subscribing Submodules
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Whenever a commit is merged to a project, its content is scanned
+to identify if it registers any submodules (if the commit contains new
+gitlinks and a .gitmodules file with all required info) and if so,
+a new submodule subscription is registered.
+
+Automatic Update of Superprojects
+---------------------------------
+
+After a superproject is subscribed to a submodule, it is not
+required to push/merge commits to this superproject to update the
+gitlink to the submodule.
+
+Whenever a commit is merged in a submodule, its subscribed superproject
+is updated.
+
+Imagine a superproject called 'super' having a branch called 'dev'
+having subscribed to a submodule 'a' on a branch 'dev-of-a'. When a commit
+is merged in branch 'dev-of-a' of 'a' project, gerrit automatically
+creates a new commit on branch 'dev' of 'super' updating the gitlink
+to point to the just merged commit.
+
+Canonical Web Url
+~~~~~~~~~~~~~~~~~
+
+Gerrit will automatically update only the superprojects that added
+the submodules of urls of the running server (the one described in
+the canonical web url value in gerrit configuration file).
+
+The Gerrit instance administrator group should always certify to
+provide the canonical web url value in its configuration file. Users
+should certify to use the url value of the running gerrit instance to
+add/subscribe submodules.
+
+Removing Subscriptions
+----------------------
+
+If one has added a submodule subscription and drops it, it is
+required to merge a commit updating the subscribed super
+project/branch to remove the gitlink and the submodule section
+of the .gitmodules file.
+
+GERRIT
+------
+Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/user-upload.txt b/Documentation/user-upload.txt
index 8a08317..8e05e72 100644
--- a/Documentation/user-upload.txt
+++ b/Documentation/user-upload.txt
@@ -15,7 +15,8 @@
 
 Each user uploading changes to Gerrit must configure one or more SSH
 public keys.  The per-user SSH key list can be accessed over the web
-within Gerrit by `Settings`, and then accessing the `SSH Keys` tab.
+within Gerrit by `Settings`, and then accessing the `SSH Public Keys`
+tab.
 
 [[configure_ssh]]
 Configuration
@@ -60,14 +61,25 @@
 port 29418, using the same hostname as the web server:
 
 ====
+..................................................................
   $ ssh -p 29418 sshusername@hostname
-  gerrit: no shell available
+
+    ****    Welcome to Gerrit Code Review    ****
+
+    Hi John Doe, you have successfully connected over SSH.
+
+    Unfortunately, interactive shells are disabled.
+    To clone a hosted Git repository, use:
+
+    git clone ssh://sshusername@hostname:29418/REPOSITORY_NAME.git
+
   Connection to hostname closed.
+..................................................................
 ====
 
-In the command above, `sshusername` was configured on the `SSH Keys`
-tab of the `Settings` screen.  If it is not set, propose a name
-and use `Change Username` to select the name.
+In the command above, `sshusername` was configured as `Username` on
+the `Profile` tab of the `Settings` screen.  If it is not set,
+propose a name and use `Select Username` to select the name.
 
 To determine the port number Gerrit is running on, visit the special
 information URL `http://'hostname'/ssh_info`, and copy the port
@@ -142,15 +154,15 @@
   $ git push tr:kernel/common HEAD:refs/for/experimental
 ====
 
-Specific reviewers can be requested and/or additional ``carbon
-copies'' of the notification message may be sent by including these
+Specific reviewers can be requested and/or additional 'carbon
+copies' of the notification message may be sent by including these
 as arguments to `git receive-pack`:
 
 ====
   git push --receive-pack='git receive-pack --reviewer=a@a.com --cc=b@o.com' tr:kernel/common HEAD:refs/for/experimental
 ====
 
-The `\--reviewer='email'` and `\--cc='email'` options may be
+The `--reviewer='email'` and `--cc='email'` options may be
 specified as many times as necessary to cover all interested
 parties.  Gerrit will automatically avoid sending duplicate email
 notifications, such as if one of the specified reviewers or CC
@@ -268,19 +280,26 @@
 * `refs/tags/*`: annotated tag objects pointing to any other type
 of Git object can be created.
 
-To push branches, the `Push Branch` project right must be granted
-to one (or more) of the user's groups.  The allowed levels within
-this category are:
+To push branches, the proper access rights must be configured first.
+Here follows a few examples of how to configure this in Gerrit:
 
 * Update: Any existing branch can be fast-forwarded to a new commit.
 This is the safest mode as commits cannot be discarded.  Creation
-of new branches is rejected.
-* Create: Implies Update, but also allows creation of a new branch
-if the name does not not already designate an existing branch name.
-* Delete: Implies Create and Update, but also allows an existing
+of new branches is rejected. Can be configured with
+link:access-control.html#category_push_direct['Push'] access.
+* Create: Allows creation of a new branch if the name does not
+already designate an existing branch name.  Needs
+link:access-control.html#category_create['Create Reference']
+configured. Please note that once created, this permission doesn't
+grant the right to update the branch with further commits (see above
+for update details).
+* Delete: Implies Update, but also allows an existing
 branch to be deleted.  Since a force push is effectively a delete
 followed by a create, but performed atomically on the server and
 logged, this also permits forced push updates to branches.
+To grant this access, configure
+link:access-control.html#category_push_direct['Push'] with the
+'Force' option ticked.
 
 To push annotated tags, the `Push Annotated Tag` project right must
 be granted to one (or more) of the user's groups.  There is only
@@ -323,17 +342,17 @@
 ~~~~~~~~~~~~~~~
 
 To replace changes, ensure Change-Id lines were created in the
-commit messages, and just use `repo upload` without the `\--replace`
-command line flag.  Gerrit Code Review will automatically match
-the commits back to their original changes by taking advantage of
-their Change-Id lines.
+commit messages, and just use `repo upload`.
+Gerrit Code Review will automatically match the commits back to
+their original changes by taking advantage of their Change-Id lines.
 
 If Change-Id lines are not present in the commit messages, consider
 amending the message and copying the line from the change's page
 on the web.
 
 If Change-Id lines are not available, then the user must use the much
-more manual mapping technique offered by `repo upload \--replace`.
+more <<manual_replacement_mapping,manual mapping technique>> offered
+by using `git push` to a specific `refs/changes/change#` reference.
 
 For more about Change-Ids, see link:user-changeid.html[Change-Id Lines].
 
@@ -345,8 +364,8 @@
 own process space, Gerrit maintains complete control over how the
 repository is updated, and what responses are sent to the `git push`
 client invoked by the end-user, or by `repo upload`.  This allows
-Gerrit to provide magical refs, such as `refs/for/\*` for new
-change submission and `refs/changes/\*` for change replacement.
+Gerrit to provide magical refs, such as `refs/for/*` for new
+change submission and `refs/changes/*` for change replacement.
 When a push request is received to create a ref in one of these
 namespaces Gerrit performs its own logic to update the database,
 and then lies to the client about the result of the operation.
diff --git a/ReleaseNotes/Makefile b/ReleaseNotes/Makefile
index 219498b..5137b59 100644
--- a/ReleaseNotes/Makefile
+++ b/ReleaseNotes/Makefile
@@ -15,7 +15,7 @@
 ASCIIDOC       ?= asciidoc
 ASCIIDOC_EXTRA ?=
 SVN            ?= svn
-PUB_ROOT       ?= https://gerrit.googlecode.com/svn/ReleaseNotes
+PUB_ROOT       ?= https://gerrit-documentation.googlecode.com/svn/ReleaseNotes
 
 DOC_HTML      := $(patsubst %.txt,%.html,$(wildcard ReleaseNotes*.txt))
 COMMIT        := $(shell git describe HEAD | sed s/^v//)
diff --git a/ReleaseNotes/ReleaseNotes-2.1.7.2.txt b/ReleaseNotes/ReleaseNotes-2.1.7.2.txt
index 2d7622e..9172b4a 100644
--- a/ReleaseNotes/ReleaseNotes-2.1.7.2.txt
+++ b/ReleaseNotes/ReleaseNotes-2.1.7.2.txt
@@ -1,9 +1,9 @@
-Release notes for Gerrit 2.1.7.1
+Release notes for Gerrit 2.1.7.2
 ================================
 
-Gerrit 2.1.7.1 is now available:
+Gerrit 2.1.7.2 is now available:
 
-link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.1.7.1.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.1.7.1.war]
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.1.7.2.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.1.7.2.war]
 
 Bug Fixes
 ---------
diff --git a/ReleaseNotes/ReleaseNotes-2.2.0.txt b/ReleaseNotes/ReleaseNotes-2.2.0.txt
new file mode 100644
index 0000000..58605fe
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.2.0.txt
@@ -0,0 +1,65 @@
+Release notes for Gerrit 2.2.0
+==============================
+
+Gerrit 2.2.0 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.0.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.0.war]
+
+Schema Change
+-------------
+*WARNING:* Upgrading to 2.2.0 requires the server be first upgraded
+to 2.1.7, and then to 2.2.0.
+
+*WARNING:* This release contains schema changes.  To upgrade:
+----
+  java -jar gerrit.war init -d site_path
+----
+
+*WARNING:* The "projects" and "ref_rights" tables are no longer
+stored in the SQL database. The tables have been moved to Git
+storage, inside of the `refs/meta/config` branch of each managed
+Git repository. The init based upgrade tool will automatically
+export the current table contents and create the Git data.
+
+New Features
+------------
+
+Project Administration
+~~~~~~~~~~~~~~~~~~~~~~
+* issue 436 List projects by scanning the managed Git directory
++
+Instead of generating the list of projects from SQL database, the
+project list is obtained by recursively scanning the Git directory.
+Adding new projects is now simply a matter of creating the Git
+repository under the directory and flushing the "projects" cache
+to force the server to rescan the directory. Administrators may
+also continue to use `gerrit create-project`.
+
+* Move "projects" table into Git
++
+The projects table columns are now stored in the `project.config`
+file of the `refs/meta/config` branch of each managed Git repository.
+
+* Move "ref_rights" table into Git
++
+The "ref_rights" table is now stored in the "access" sections of
+the `project.config` file on the `refs/meta/config` branch of each
+managed Git repository. This brings version control auditing to the
+access data of each project.
+
+* New project Access screen to edit access controls
++
+The Access panel of the project administration has been rewritten
+with a new UI that reflects the new Git based storage format.
+
+Bug Fixes
+---------
+
+Project Administration
+~~~~~~~~~~~~~~~~~~~~~~
+* Avoid unnecessary updates to $GIT_DIR/description
++
+Gerrit always tried to rewrite the gitweb "description" file when the
+project was modified. This lead to unnecessary changes in the local
+filesystem, leading to more data to rsync to backups than necessary.
+Fixed to only update the file if the content changes.
diff --git a/ReleaseNotes/ReleaseNotes-2.2.1.txt b/ReleaseNotes/ReleaseNotes-2.2.1.txt
new file mode 100644
index 0000000..19af06d
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.2.1.txt
@@ -0,0 +1,79 @@
+Release notes for Gerrit 2.2.1
+==============================
+
+Gerrit 2.2.1 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.1.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.1.war]
+
+Schema Change
+-------------
+*WARNING:* This release contains schema changes.  To upgrade:
+----
+  java -jar gerrit.war init -d site_path
+----
+
+*WARNING:* Upgrading to 2.2.x requires the server be first upgraded
+to 2.1.7, and then to 2.2.x.
+
+New Features
+------------
+* Add 'Expand All Comments' checkbox in PatchScreen
++
+Allows users to save a user preference that automatically expands
+any inline comment boxes when a page displays.
+
+* Multiple branches in ls-project
++
+The -b option may be supplied multiple times to ls-project, each
+usage adds a new column of output per project line listing the
+current value of that branch.
+
+Bug Fixes
+---------
+* issue 994 Rename "-- All Projects --" to "All-Projects"
++
+The name "-- All Projects --.git" is difficult to work with on
+the UNIX command line, due to tools assuming the name is actually
+part of a long option. The project has been renamed to remove these
+leading hypens, and remove spaces, making it more friendly to work
+with on the command line.
+
+* issue 997 Resolve Project Owners when checking access rights
++
+Members of the 'Project Owners' magical group did not always have
+their project owner privileges when Gerrit Code Review was looking
+for "access to any ref" at the project level. This was caused by
+not expanding the 'Project Owner's group to the actual ownership
+list. Fixed.
+
+* issue 999 Do not reset Patch History selection on navigation
++
+Navigating to the next/previous file lost the setting of the
+"Old Version" made under the "Patch History" expandable control
+on a specific file view. This was accidentally broken when the
+"Old Version History" control was added to the change page. Fixed.
+
+* issue 1001 Fix search by codereview status
++
+Searching for labels (or any approval scores) was broken due to an
+incorrect usage of the Java "equals()" method. Fixed.
+
+* issue 1000 Fix administration of projects with no access controls
++
+Projects that had no access sections could not have additional
+sections added to them, due to a bug in the web UI. Fixed.
+
+* Fix API breakage on ChangeDetailService
++
+Version 2.1.7 broke the Gerrit Code Review plugin for Mylyn Reviews
+due to an accidential signature change of one of the remote JSON
+APIs. The ChangeDetailService.patchSetDetail() method is back to the
+old signature and a new patchSetDetail2() method has been added to
+handle the newer calling convention used in some contexts of the
+web UI.
+
+* Add error messages for abandon and restore when in bad state
++
+Instead of crashing with internal NullPointerExceptions, report
+a better error message to clients when a change is being moved
+between states.
diff --git a/ReleaseNotes/ReleaseNotes-2.2.2.1.txt b/ReleaseNotes/ReleaseNotes-2.2.2.1.txt
new file mode 100644
index 0000000..4613787
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.2.2.1.txt
@@ -0,0 +1,53 @@
+Release notes for Gerrit 2.2.2.1
+================================
+
+Gerrit 2.2.2.1 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.1.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.1.war]
+
+
+There are no schema changes from 2.2.2.  However, if upgrading from
+anything but 2.2.2, follow the upgrade procedure in the 2.2.2
+link:ReleaseNotes-2.2.2.html[ReleaseNotes].
+
+
+Bug Fixes
+---------
+* issue 1139 Fix change state in patch set approval if reviewer is added to
+closed change
++
+For the dummy patch set approval that is created when a reviewer is
+added the cached change state is always open, which is incorrect if a
+reviewer is added to a closed change. As a result the closed change will
+appear in the reviewers dashboard in the 'Review Requests' section and will
+stay there forever.  Ensure the correct change state is cached in the dummy
+patch set approval when it is created.
+
+* issue 1171 Fix ownerin and reviewerin searches
++
+Update the ownerin and reviewerin searches to use AccountGroup.UUID as
+required by commit e662fb3d4d7d0ad05791b8d2143ac5ce58117335.
+
+* issue 871 Display hash of the cherry-pick merge in comment
++
+After merging a change via cherry-pick, we add the commit's
+hash to the comment. This was accidentally removed in
+commit 14246de3c0f81c06bba8d4530e6bf00e918c11b0
+
+
+Documentation
+-------------
+* Update top level SUBMITTING_PATCHES
++
+This document is out of date, the URLs are from last August.
+Direct readers to the new server.
+
+* Add contributing guideline document
+
+* Documentation: update version references for 2.2.2
++
+Correct wording and instructions to be sure they match what would
+be observed with the indicated version of gerrit.
+Expand instructions when needed to ensure all commands could be
+executed and were successful.
+Indent commands and output based on a run of the instructions
diff --git a/ReleaseNotes/ReleaseNotes-2.2.2.2.txt b/ReleaseNotes/ReleaseNotes-2.2.2.2.txt
new file mode 100644
index 0000000..db5d750
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.2.2.2.txt
@@ -0,0 +1,24 @@
+Release notes for Gerrit 2.2.2.2
+================================
+
+Gerrit 2.2.2.2 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.2.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.2.war]
+
+There are no schema changes from 2.2.2, or 2.2.2.1.
+
+However, if upgrading from anything earlier, follow the upgrade
+procedure in the 2.2.2 link:ReleaseNotes-2.2.2.html[ReleaseNotes].
+
+Security Fixes
+--------------
+* Some access control sections may be ignored
++
+Gerrit sometimes ignored an access control section in a project
+if the exact same section name appeared in All-Projects. The bug
+required an unrelated project to have access.inheritFrom set to
+All-Projects and be accessed before the project that has the same
+section name as All-Projects. This is an unlikely scenario for
+most servers, as Gerrit does not normally set inheritFrom equal to
+All-Projects. The usual behavior is to not supply this property in
+project.config, and permit the implicit inheritence to take place.
diff --git a/ReleaseNotes/ReleaseNotes-2.2.2.txt b/ReleaseNotes/ReleaseNotes-2.2.2.txt
new file mode 100644
index 0000000..3f1f76f
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.2.2.txt
@@ -0,0 +1,669 @@
+Release notes for Gerrit 2.2.2
+==============================
+
+Gerrit 2.2.2 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.2.2.war]
+
+Schema Change
+-------------
+*WARNING:* This release contains schema changes.  To upgrade:
+----
+  java -jar gerrit.war init -d site_path
+----
+
+*WARNING:* Upgrading to 2.2.x requires the server be first upgraded
+to 2.1.7 (or a later 2.1.x version), and then to 2.2.x.
+
+New Features
+------------
+
+Prolog
+~~~~~~
+* issue 971 Use Prolog Cafe for ChangeControl.canSubmit()
+
+*  Add per-project prolog submit rule files
++
+When loading the prolog environment, now checks refs/meta/config
+branch for a file called rules.pl. If it exists, consult the
+file. Expects a predicate called submit_rule. If no file is found,
+uses the default_submit predicate in common_rules.pl.
+
+*  Add inheritance of prolog rules
++
+Projects now inherit the prolog rules defined in their parent
+project. Submit results from the child project are filtered by the
+parent project using the filter predicate defined the parent's
+rules.pl. The results of the filtering are then passed up to the
+parent's parent and filtered, repeating this process up to the top
+level All-Projects.
+
+* Load precompiled prolog rules from jar file
++
+Looks in (site)/cache/rules for a jar file called:
+  rules-(sha1 of rules.pl).jar
+Loads the precompiled prolog rules and uses them instead of
+consulting rules.pl. If the jar does not exist, consults rules.pl.
+If rules.pl does not exist, uses the default submit rules.
+
+* Cmd line tool rulec to compile jar from prolog
++
+Rulec takes rules.pl from the refs/meta/config branch and creates a
+jar file named rules-(sha1 of rules.pl).jar in (sitepath)/cache/rules.
+Generates temporary prolog, java src, and class files which are
+deleted afterwards.
+
+* prolog-shell: Simple command line Prolog interpreter
++
+Define a small interactive interpreter that users or site
+administartors can play around with by downloading the Gerrit WAR
+file and executing: java -jar gerrit.war prolog-shell
+
+Prolog Predicates
+^^^^^^^^^^^^^^^^^
+*  Add Prolog Predicates to check commit messages and edits
++
+commit_message returns the commit message as a symbol.
++
+commit_message_matches takes in a regex pattern and checks it against
+the commit message.
++
+commit_edits takes in a regex pattern for filenames and a regex
+pattern for edits. For all files in a commit that match the filename
+regex.  Returns true if the edits in any of those files match the
+edit regex.
+
+* Add Prolog  Predicates to expose commit filelist
++
+commit_delta/1,3,4 each takes a regular expression and matches it to
+the path of all the files in the latest patchset of a commit.
+If applicable (changes where the file is renamed or copied), the
+regex is also checked against the old path.
++
+commit_delta/1 returns true if any files match the regex
++
+commit_delta/3 returns the changetype and path, if the changetype is
+renamed, it also returns the old path. If the changetype is rename,
+it returns a delete for oldpath and an add for newpath. If the
+changetype is copy, an add is returned along with newpath.
++
+commit_delta/4 returns the changetype, new path, and old path
+ (if applicable).
+
+* Add Prolog predicates that expose the branch, owner,
+project, and  topic of a change, the author and committer of the most
+recent patchset in the change, and who is the current user.
+
+* For user-related predicates, if the user is not a gerrit user, will
+return user(anonymous) or similar. Author and committer predicates
+for commits return user(id), name, and email.
+
+* Make max_with_block/4 public
++
+This is the current rule generally applied to a label function. Make
+it exportable for now until we can come back and clean up the legacy
+approval data code.
+
+Web
+~~~
+
+* Support in Firefox delete key in NpIntTextBox
++
+Pressing the delete key while being in a NpIntTextBox (e.g. in the
+text box for the Tab Width or Columns preference when comparing a
+file) now works in Firefox.
+
+* Make sure special keys work in text fields
++
+There is a bug in gwt 2.1.0 that prevents pressing special keys like
+Enter, Backspace etc. from being properly recognized and so they have no effect.
+
+ChangeScreen
+^^^^^^^^^^^^
+* issue 855 Indicate outdated dependencies on the ChangeScreen
++
+If a change dependency is no longer the latest patchSet for that
+change, mark it OUTDATED in the dependencies table and make
+its row red, and add a warning message to the dependencies
+header, also keep the dependencies disclosure panel open
+even when an outdated dependent change is merged.
+Additionally make the link for dependencies link to the
+exact patchSet of the dependent change.
+
+* issue 881 Allow adding groups as reviewer
++
+On the ChangeScreen it is now possible to add a group as reviewer for
+a change. When a group is added as reviewer the group is resolved and
+all its members are added as reviewers to the change.
+
+* Update approvals in web UI to adapt to rules.pl submit_rule
++
+The UI now shows whatever the results of the submit_rule are, which
+permits the submit_rule to make an ApprovalCategory optional, or to
+make a new label required.
+
+Diff Screen
+^^^^^^^^^^^
+* Add top level menus for a new PatchScreen header
++
+Modify the PatchScreen so that the header contents is selectable
+using top level menus. Allow the header to display the commit
+message, the preferences, the Patch Sets, or the File List.
+
+* Add SideBySide and Unified links to Differences top level menus
++
+These new menu entries allow a user to switch view types easily
+without returning to the ChangeScreen.  Also, they double as a
+way to hide the header on the PatchScreen (when clicking on the
+currently displayed type).
+
+* Add user pref to retain PatchScreen Header when changing files
+
+* Flip the orientation of PatchHistory Table
+
+* Remove the 'Change SHA1:' from the PatchScreen title
+
+* Remove scrollbar from Commit Message
+
+* Allow comment editing with single click on line numbers
++
+Make it easier to comment (and now possible on android devices which
+zoom on double click) on a patch by simply clicking on the line number.
+
+* Add a "Save" button to the PatchScriptSettingsPanel
++
+The "Update" button now only updates the display.  Addittionally,
+for logged in users, a "Save" button now behaves the way that
+"Update" used to behave for logged in users.
+
+* issue 665 Display merge changes as differences from automatic result
++
+Instead of displaying nothing for a two-parent merge commit, compute
+the automatic merge result and display the difference between the
+automatic result that Git would create, and the actual result that
+was uploaded by the author/committer of the merge.
+
+Groups
+^^^^^^
+* Add menu to AccountGroupScreen
++
+This change introduces a menu in the AccountGroupScreen and
+different screens for subsets of the functionality (similar as it's
+done for the ProjectScreen).  Links from other screens to the
+AccountGroupScreen are resolved depending on the group type.
+
+* Display groupUUID on AccountGroupInfoScreen
++
+To assign a privilege to a new group by editing the
+'project.config' file, the new group needs to be added to the
+'groups' file in the 'refs/meta/config' branch which requires
+the UUID of the group to be known.
+
+Project Access
+^^^^^^^^^^^^^^
+* Automatically add new rule when adding new permission
++
+If a new permission was added to a block, immediately create the new
+group entry box and focus it, so the user can assign the permission.
+
+* Only show Exclusive checkbox on reference sections
++
+In the access editor, hide the Exclusive checkbox on the
+Global Capabilities section since it has no inheritance and
+the exclusive bit isn't supported.
+
+* Disable editing after successful save of Access screen
++
+When the access has been successfully modified for a project,
+switch back to the "read-only" view where the widgets are all
+disabled and the Edit button is enabled.
+
+Project Branches
+^^^^^^^^^^^^^^^^
+* Display refs/meta/config branch on ProjectBranchesScreen
++
+The new refs/meta/config branch was not shown in the ProjectBranchesScreen.
+Since refs/meta/config is not just any branch, but has a special
+meaning to Gerrit it is now displayed at the top below HEAD.
+
+* Highlight HEAD and refs/meta/config
++
+Since HEAD and refs/meta/config do not represent ordinary branches,
+highlight their rows with a special style in the ProjectBranchesScreen.
+
+URLs
+^^^^
+* Modernize URLs to be shorter and consistent
++
+Instead of http://site/#change,1234 we now use a slightly more
+common looking   http://site/#/c/1234  URL to link to a change.
++
+Files within a patch set are now denoted below the change, as in
+http://site/#/c/1234/1/src/module/foo.c
++
+Also fix the dynamic redirects of http://site/1234
+and http://site/r/deadbeef to jump directly to the corresponding
+change if there is exactly one possible URL.
++
+Entities that have multiple views suffix the URL with ",view-name"
+to indicate which view the user wants to see.
+
+* issue 1018 Accept ~ in linkify() URLs
+
+SSH
+~~~
+* Added a set-reviewers ssh command
+
+* Support removing more than one reviewer at once
++
+This way we can batch delete reviewers from a change.
+
+* issue 881 Support adding groups as reviewer by SSH command
++
+With the set-reviewers SSH command it is now possible to also add
+groups as reviewer for a change.
+
+* Fail review command for changing labels when change is closed
++
+If a reviewer attempts to change a review label (approval) after a
+change is closed using the ssh review command, cause it to fail the
+command and output a message.
+
+* ls-projects: Fix display of All-Projects under --tree
++
+Everything should be nested below All-Projects, since that is actually
+the root level.
+
+* ls-projects: Add --type to filter by project type
++
+ls-projects now supports --type code|permissions|all.  The default is
+code which now skips permissions only projects, restoring the output
+to what appears from Gerrit 2.1.7 and earlier.
+
+* show-caches: Improve memory reporting
++
+Change the way memory is reported to show the actual values,
+and the equation that determines how these are put together
+to form the current usage.  Include some additional data including
+server version, current time, process uptime, active SSH
+connections, and tasks in the task queue. The --show-jvm option
+will report additional data about the JVM, and tell the caller
+where it is running.
+
+Queries
+^^^^^^^
+* Output patchset creation date for 'query' command.
+
+* issue 1053 Support comments option in query command
++
+Query SSH command will show all comments if option --comments is
+used. If --comments is used together with --patch-sets all inline
+comments are included in the output.
+
+Config
+~~~~~~
+* Move batch user priority to a capability
++
+Instead of using a magical group, use a special capability to
+denote users that should get the batch priority behavior.
+
+* issue 742 Make administrator, create-project a global capability
++
+This gets rid of the special entries in system_config and
+gerrit.config related to who the Administrators group is,
+or which groups are permitted to create new projects on
+this server.
+
+* issue 48 & 742  Add fine-grained capabilities for administrative actions
++
+The Global Capabilities section in All-Projects can now be used to
+grant subcommands that are available over SSH and were previously
+restricted to only Administrators.
+
+* Disallow project names ending in "/"
+
+* issue 934 query: Enable configurable result limit
++
+Allow site administrators to configure the query limit for user to be
+above the default hard-coded value of 500 by adding a global
+[capability] block to All-Projects project.config file with group(s)
+that should have different limits.
+
+* Introduced a new PermissionRule.Action: BLOCK.
++
+Besides already existing ALLOW and DENY actions this change
+introduces the BLOCK action in order to enable blocking some
+permission rules globally.
+
+* issue 813 Use remote.name.replicatePermissions to hide permissions
++
+Administrators can now disable replication of permissions-only
+projects and the per-project refs/meta/config in replication.config
+by setting the replicatePermissions field to false.
+
+* Add a Restored.vm template and use it.
++
+The restore action has been erroneously using the Abandoned.vm
+template.  Create a template and sender for the restorecommand.
+
+* sshd.advertisedAddress: specify the displayed SSH host/port
++
+This allows aliases which redirect to gerrit's ssh port (say
+from port 22) to be setup and advertised to users.
+
+Dev
+~~~
+* Updated eclipse settings for 3.7 and m2e 1.0
+
+* Fix build in m2eclipse 1.0
++
+Ignore the antrun and the build-helper-maven-plugin tasks in m2eclipse.
+
+* Make Gerrit with gwt 2.3.0 run in gwtdebug mode
+
+* Fix a number of build warnings that have crept in
+
+* Accept email address automatically
++
+Enable Gerrit to accept email address automatically in
+"DEVELOPMENT_BECOME_ANY_ACCOUNT" mode without a confirmation email.
+
+* Added clickable user names at the BecomeAnyAccountLoginServlet.
++
+The first 5 (by accountId) user names are displayed as clickable
+links. Clicking a user name logs in as this user, speeding up
+switching between different users when using the
+DEVELOPMENT_BECOME_ANY_ACCOUNT authentication type.
+
+Miscellaneous
+~~~~~~~~~~~~~
+* Permit adding reviewers to closed changes
++
+Permit adding a reviewer to closed changes to support post-submit
+discussion threads.
+
+* issue 805 Don't check for multiple change-ids when pushing directly
+to refs/heads.
+
+* Avoid costly findMergedInto during push to refs/for/*
++
+No longer close a change when a commit is pushed to res/for/* and the
+Change-Id in the commit message footer matches another commit on an
+existing branch or tag.
+
+* Allow serving static files in subdirectories
+
+* issue 1019 Normalize OpenID URLs with http:// prefix
++
+No longer violate OpenID 1.1 and 2.0, both of which require
+OpenIDs to be normalized (http:// added).
+
+* Allow container-based authentication for git over http
++
+Gerrit was insisting on DIGEST authentication when doing git over
+http. A new boolean configuration parameter auth.trustContainerAuth
+allows gerrit to be configured to trust the container to do the
+authentication.
+
+* issue 848 Add rpc method for GerritConfig
++
+Exposes what types of reviews are possible via json rpc, so that the
+Eclipse Reviews plugin currently can parse the javascript from a
+gerrit page load.
+
+
+Performance
+-----------
+* Bumped Brics version to 1.11.8
++
+This Brics version fixes a performance issue in some larger Gerrit systems.
+
+* Add permission_sort cache to remember sort orderings
++
+Cache the order AccessSections should be sorted in, making any future
+sorting for the same reference name and same set of section patterns
+cheaper.
+
+* Refactor how permissions are matched by ProjectControl, RefControl
++
+More aggressively cache many of the auth objects at a cost of memory,
+but this should be an improvement in response timse.
+
+* Substantialy speed up pushing changes for review
++
+Pushing a new change for review checks if the change is related to
+the branch it's destined for. It used to do this in a way that
+required a topo-sort of the rev history, and now uses JGit's
+merge-base functionality.
+
+* Add cache for tag advertisements
++
+To make the general case more efficient, introduce a cache called "git_tags".
++
+On a trivial usage of the Linux kernel repository, the average
+running time of the VisibleRefFilter when caches were hot was
+7195.68 ms.  With this commit, it is a mere 5.07 milliseconds
+on a hot cache.  A reduction of 99% of the running time.
+
+* Don't set lastCheckTime in ProjectState
++
+The lastCheckTime/generation fields are actually a counter that
+is incremented using a background thread. The values don't match
+the system clock, and thus reading System.currentTimeMillis()
+during the construction of ProjectState is a waste of resources.
+
+
+Upgrades
+--------
+* Upgrade to GWT 2.3.0
+* Upgrade to Gson to 1.7.1
+* Upgrade to gwtjsonrpc 1.2.4
+* Upgrade to gwtexpui 1.2.5
+* Upgrade to Jsch 0.1.44-1
+* Upgrade to Brics 1.11.8
+
+
+Bug Fixes
+---------
+* Fix: Issue where Gerrit could not linkify certain URLs
+
+* issue 1015 Fix handling of regex ref patterns in Access panel
++
+regex patterns such as "\^refs/heads/[A-Z]{2,}\-[0-9]\+.\*" were being
+prefixed with "refs/heads/", resulting in invalid reference patterns
+like "refs/heads/^refs/heads/[A-Z]{2,}-[0-9]+.*".
+
+* issue 1002 Check for and disallow pushing of invalid refs/meta/config
++
+If the project.config or groups files are somehow invalid on
+the refs/meta/config branch, or would be made invalid due to
+a bad code review being submitted to this branch, reject the
+user's attempt to push.
+
+* issue 1002 Fix NPE in PermissionRuleEditor when group lacks UUID
++
+If a group does not have an entry in the "groups" table within
+the refs/meta/config branch render the group name as a span,
+without the link instead of crashing the UI.
+
+* issue 972 Filter access section rules to only visible groups
++
+Users who are not the owner of an access section can now only
+see group names and rules for groups which they are a member of,
+are visible to all users, or that they own.
+
+* Correctly handle missing refs/meta/config branch
++
+If the refs/meta/config branch did not exist, getRevision() no longer
+throws an NPE when trying to access the ProjectDetail.
+
+* Allow loading Project Access when there is no refs/meta/config
++
+Enable loading the access screen with a null revision field,
+and on save of any edits require the branch to be new.
+
+* create-project: Fix creation vs. replication order
++
+Create the project on remote mirrors before creating either the
+refs/meta/config or the initial empty branch. This way those can be
+replicated to the remote mirrors once they have been created locally.
+
+* create-project: Bring back --permissions-only flag
++
+If a project is permissions only, assign HEAD to point to
+refs/meta/config. This way the gitweb view of the project
+shows the permissions history by default, and clients that
+clone the project are able to get a detached HEAD pointing
+to the current permission state, rather than an empty
+repository.
+
+* create-project: Fix error reporting when repository exists
++
+If a repository already exists, tell the user it already is
+available, without disclosing the server side path from gerrit.basePath.
+
+* Do not log timeout errors on upload and receive connections
+
+* Only automatically create accounts for LDAP systems
++
+If the account management is LDAP, try to automatically create
+accounts by looking up the data in LDAP. Otherwise fail and reject an
+invalid account reference that was supplied on the command line via
+SSH.
+
+* Add missing RevWalk.reset() after checking merge base
++
+This fixes an exception from RevWalk when trying to push a new
+commit for review.
+
+* issue 1069 Do not send an email on reviews when there is no message.
++
+No longer send an email when reviewing a change via ssh, and
+the change message is blank (when no change message is actually
+added to the review).
+
+* Ignore PartialResultException from LDAP.
++
+This exception occurs when the server isn't following referrals for
+you, and thus the result contains a referral. That happens when
+you're using Active Directory. You almost certainly don't really want
+to follow referrals in AD *anyways*, so just ignore these exceptions,
+so we can still use the actual data.
+
+* issue 518 Fix MySQL counter resets
++
+gwtorm 1.1.5 was patched to leave in the dummy row that incremented
+the counter, ensuring the server will use MAX() + 1 instead of 1 on
+the next increment after restart.
+
+* Don't delete account_id row on MySQL
++
+If the table is an InnoDB table deleting the row after allocation may
+cause the sequence to reset when the server restarts, giving out
+duplicate account_ids later.
+
+
+Documentation
+-------------
+
+New Documents
+~~~~~~~~~~~~~
+* First Cut of Gerrit Walkthrough Introduction documentation.
++
+Add a new document intended to be a complement for the existing
+reference documentation to allow potential users to easily get a
+feel for how Gerrit is used, where it fits and whether it will
+work for them.
+
+* Introducing a quick and dirty setup tutorial
++
+The new document covers quick installation, new project and first
+upload.  It contains lots of quoted output, with a demo style to it.
+
+Access Control
+~~~~~~~~~~~~~~
+* Code review
+
+* Conversion table between 2.1 and 2.2
++
+Add a table to ease conversion from 2.1.x. The table tries to address
+the old permissions one by one except for the push tag permission which
+in effect needed two permissions to work properly. This should
+be familiar to the administrator used to the 2.1.x permission model
+however.
+
+* Reformatted text
+
+* Verify
++
+Updated some text in the Per project-section and edited the verified
+section to reflect the current label.
+
+* Capabilities
++
+Adds general information about global capabilities, how the server
+ownership is administered.
+
+* Added non-interactive users
++
+This change adds the non-interactive user group.
+It also adds that groups can be members of other groups.
+The groups are now sorted in alphabetical order.
+
+* Reordering categories
++
+Access categories are now sorted to match drop down box in UI
+
+Other Documentation
+~~~~~~~~~~~~~~~~~~~
+* Added additional information on the install instructions.
++
+The installation instructions presumes much prior knowledge,
+make some of that knowledge less implicit.
+
+* Provides a template to the download example.
++
+Clarifies that the example host must be replaced with proper
+hostname.
+
+* Provided an example on how to abandon a change from
+the command line
+
+* update links from kernel.org to code.google.com
+
+
+* Rename '-- All Projects --' in documentation to 'All-Projects'
+
+* Explain 'Automatically resolve conflicts'
+
+* Update documentation for testing SSH connection
++
+The command output that is shown in the example and the description
+how to set the ssh username were outdated.
+
+* Remove unneeded escape characters from the documentation
++
+The old version of asciidoc required certain characters to be escaped
+with a backslash and when the upgrade to the new version was done all
+those backslashes that were used for escaping became visible.
+
+* Clean up pgm-index
++
+Break out the utilities into their own section, and correct
+some of the item descriptions.
+
+* Update manual project creation instructions
+
+* Update project configuration documentation
++
+Remove the textual reference to obsolete SQL insert statement to
+create new projects.
+
+* Clean up command line documentation, examples
++
+The formatting was pretty wrong after upgrading to a newer version
+of AsciiDoc, so fix up most of the formatting, correct some order
+of commands in the index, and make create-project conform to the
+same format used by create-account and create-group.
+
+* Correct syntax of SQL statement for inserting approval category
diff --git a/ReleaseNotes/ReleaseNotes-2.3.1.txt b/ReleaseNotes/ReleaseNotes-2.3.1.txt
new file mode 100644
index 0000000..324a3c1
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.3.1.txt
@@ -0,0 +1,24 @@
+Release notes for Gerrit 2.3.1
+==============================
+
+Gerrit 2.3.1 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.3.1.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.3.1.war]
+
+There are no schema changes from 2.3.
+
+However, if upgrading from anything earlier, follow the upgrade
+procedure in the 2.3 link:ReleaseNotes-2.3.html[ReleaseNotes].
+
+Security Fixes
+--------------
+* Some access control sections may be ignored
++
+Gerrit sometimes ignored an access control section in a project
+if the exact same section name appeared in All-Projects. The bug
+required an unrelated project to have access.inheritFrom set to
+All-Projects and be accessed before the project that has the same
+section name as All-Projects. This is an unlikely scenario for
+most servers, as Gerrit does not normally set inheritFrom equal to
+All-Projects. The usual behavior is to not supply this property in
+project.config, and permit the implicit inheritence to take place.
diff --git a/ReleaseNotes/ReleaseNotes-2.3.txt b/ReleaseNotes/ReleaseNotes-2.3.txt
new file mode 100644
index 0000000..965c8e3
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.3.txt
@@ -0,0 +1,474 @@
+Release notes for Gerrit 2.3
+============================
+
+Gerrit 2.3 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.3.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.3.war]
+
+Schema Change
+-------------
+*WARNING:* This release contains schema changes.  To upgrade:
+----
+  java -jar gerrit.war init -d site_path
+----
+
+*WARNING:* Upgrading to 2.3.x requires the server be first upgraded
+to 2.1.7 (or a later 2.1.x version), and then to 2.3.x.
+
+If you are upgrading from 2.2.x.x, you may ignore this warning and
+upgrade directly to 2.3.x.
+
+
+New Features
+------------
+Drafts
+~~~~~~
+* New draft statuses and magic branches
++
+Adds draft status to Change. DRAFT status in change occurs before NEW
+and will be for a change that is not meant for review (yet).
+Also adds magic branches refs/drafts/ and refs/publish/ that
+will handle whether or not a patchset is a draft or goes straight to
+review. refs/for/ should be deprecated in favor of explicitly marking
+a patchset as a draft or directly to review.
+
+* Draft patchset and change visibility in UI
++
+If a patchset is a draft, adds a (DRAFT) label next to the revision
+(or gitweb link if it exists). If a change is a draft, adds a (DRAFT)
+next to the subject and changes the status appropriately.
+
+* Publish draft patchsets in UI and SSH
++
+Adds Publish button to draft patchsets in UI and an option to
+publish draft patchsets in the review ssh command. Publishing a draft
+patchset makes it visible. Publishing a draft patchset in a draft
+change irreversibly upgrades the change status to NEW.
+
+* Delete draft changes and patchsets
++
+Adds ability to delete draft changes and patchsets that are not meant
+or fit for code review. Deleting a draft patchset also deletes the
+corresponding ref from the repository and decrements the next patch
+set number for the change if necessary. Deleting a draft change
+deletes all of its (draft) patchsets.
+
+* Add pushing drafts to refs/drafts/
++
+Pushing to refs/drafts/ will now push a draft patchset. If this is the
+first patch set, change created will be in draft status. Pushing a
+draft patchset to a draft change keeps it in draft status. Pushing
+a non-draft patchset (with refs/publish/ or refs/for/, they do the
+same thing) to a draft change turns it into a non-draft change.
+Draft patchsets cannot be submitted.
+
+* When pushing changes as drafts, output [DRAFT] next to the change link
+
+
+Web
+~~~
+* issue 203 Create project through web interface
++
+Add a new panel in the Admin->Projects Screen.  It
+enables the users that are allowed to create projects
+via command-line to create them also via web interface.
+
+* Suggest parent for 'create-project' in the UI.
++
+Add a list of parent suggestions for 'create project'
+in the UI, so the user can select a parent for the new
+project from a list of projects that are already parents to
+other projects.
+
+* issue 981 Fix diffs skipping one line
++
+Don't show '... skipping 1 common line ...'.  The text to show this
+takes up just as much space as showing the line which was skipped.
+
+* issue 18 Support expanding lines of context in diff
++
+Allow lines of context which were skipped in the side-by-side diff
+view to be expanded.  This makes it easier to get more code context
+when needed but not show huge amounts of unneeded data.
+
+* Move checkbox to mark file as reviewed into title bar
+
+* Redirect the user to the reverted change (when reverting).
+
+* On group rename update the group name in the page title
+
+* In ProjectAccessScreen add link to history of project.config in gitweb
+
+* Removed superfluous 'comment' for patch history table.
+
+* Make OpenID login images transparent
+
+* Disable SSH Keys in the web UI if SSHD is disabled
+
+
+SSH
+~~~
+* Adds --description (-d) option to ls-projects
++
+Allows listing of projects together with their respective
+description.
+
+* ls-projects: new option to list all accessible projects
++
+Add a new option '--all' to the 'ls-projects' SSH command to display
+all projects that are accessible by the calling user account. Besides
+the projects that the calling user account has been granted 'READ'
+access to, this includes all projects that are owned by the calling
+user account (even if for these projects the 'READ' access right is
+not assigned to the calling user account).
+
+* Suggest parent for 'create-project' in the SSH command
++
+Add an option '--suggest-parents' which will print out
+a list of projects that are already parents to another
+projects, thus it can help user to find a suitable
+parent for the new project.
+
+* Support reparenting all children of a parent project
++
+This change adds a new option to the 'set-project-parent' command that
+allows reparenting all child projects of one parent project to another
+parent project.
+
+* set-parent-project: evict child projects from project cache
+
+* Add ssh command to list groups.
+
+* ls-groups: add option to list groups for a project
++
+Add an option to the ls-groups SSH command that allows to list only
+those groups for which any permission is assigned to a project.
+
+* ls-groups: Add option to only list groups that are visible to all
+
+* ls-groups: Support listing groups by group type
+
+* ls-groups: Support listing of groups for a user
+
+* Add new SSH command to rename groups
+
+* Support for --file option for ssh queries.
++
+Allows user to list files and attributes (ADDED,
+MODIFIED, DELETED, RENAMED, COPIED) when querying for
+patch sets.
+
+* Output full commit message in query results
+
+* Option for SSHD review-cmd to always publish the message.
++
+"--force-message" option for the SSHD review command,
+which allows Gerrit to publish the "--message", even if the
+labels could not be applied due to change being closed.
+
+
+Config
+~~~~~~
+* issue 349 Apply states for projects (active, readonly and hidden)
++
+Active state indicates the project is regular and is the default value.
++
+Read Only means that users can see the project if read permission is
+granted, but all modification operations are disabled.
++
+Hidden means the project is not visible for those who are not owners
+
+* Enable case insensitive login to Gerrit WebUI for LDAP authentication
++
+Gerrit treats user names as case sensitive, while some LDAP servers
+don't. On first login to Gerrit the user enters his user name and
+Gerrit queries LDAP for it. Since LDAP is case-insensitive with regards
+to  the username, the LDAP authentication succeeds regardless in
+which case the user typed in his user name. The username is stored in
+Gerrit exactly as entered by the user. For further logins the user
+always has to use the same case. If the user specifies his user name in
+a different case Gerrit tries to create a new account which fails with
+"Cannot assign user name ... to account ...; name already in use.".
+This error occurs because the LDAP query resolves to the same LDAP
+user and storing the username for SSH (which is by default always
+lower case) fails because such an entry exists already for the first
+account that the user created.
++
+This change introduces a new configuration parameter that converts the
+user name always to lower case before doing the LDAP authentication.
+By this the login to the Gerrit WebUI gets case insensitive. If this
+configuration parameter is set, the user names for all existing
+accounts have to be converted to lower case. This change includes a
+server program to do this conversion.
+
+* Enable case insensitive authentication for git operations
++
+A new configuration parameter is introduced that converts the username
+that is received to authenticate a git operation to lower case for
+looking up the user account in Gerrit.
++
+By setting this parameter a case insensitive authentication for the
+git operations can be achieved, if it is ensured that the usernames in
+Gerrit (scheme 'username') are stored in lower case (e.g. if the
+parameter 'ldap.accountSshUserName' is set to
+'${sAMAccountName.toLowerCase}').
+
+* Support replication to local folder
+
+* Read timeout parameter for LDAP connections: ldap.readTimeout
++
+This helps prevent a very slow LDAP server from blocking
+all SSH command creation threads.
+
+* Introduce a git maxObjectSizeLimit in the [recieve] config
++
+This limits the size of uploaded files
+
+* Make 'Anonymous Coward' configurable
+
+* Add property to configure path separator in URLs for a gitweb service
+
+* Customize link-name pointing to gitweb-service.
++
+Previously the link to the external gitweb-type
+pages said "(gitweb)" regardless if using cgit
+or a custom service.
+
+* Support gitweb.type=disabled
+
+* rules.enable: Support disabling per project prolog rules in gerrit.config
+
+* Allow site administrators to define Git-over-HTTP mirror URL
+
+* Allow sshd.listenAddress = off to disable the daemon
+
+* daemon: Allow httpd without sshd
+
+* Allow disabling certain features of HostPageServlet
++
+These features are: user agent detection and automatic refresh
+logic associated with the site header, footer and CSS.
+
+
+Dev
+~~~
+* Fix 'No source code is available for type org.eclipse.jgit.lib.Constants'
+
+* Fix miscellaneous compiler warnings
+
+* Add entries to .gitignore for m2e settings/preference files
+
+* Package source JARs for antlr, httpd, server
+
+* pom.xml: change gerrit-war's dependency on gerrit-main to runtime
++
+This only seems to matter to IntelliJ, since the Main class is
+provided to the war via an overlay in gerrit-war/pom.xml
+
+* Fixed the full name of the MAVEN2_CLASSPATH_CONTAINER
++
+Fixes java.lang.NoClassDefFoundError: com/google/gwt/dev/DevMode
+
+
+Miscellaneous
+~~~~~~~~~~~~~
+* Allow superprojects to subscribe to submodules updates
++
+The feature introduced in this release allows superprojects to
+subscribe to submodules updates.
++
+When a commit is merged to a project, the commit content is scanned
+to identify if it registers submodules (if the commit contains new
+gitlinks and .gitmodules file with required info) and if so, a new
+submodule subscription is registered.
++
+When a new commit of a registered submodule is merged, gerrit
+automatically updates the subscribers to the submodule with new
+commit having the updated gitlinks.
++
+The most notable benefit of the feature is to not require
+to push/merge commits of super projects (subscribers) with gitlinks
+whenever a project being a submodule is updated. It is only
+required to push commits with gitlinks when they are created
+(and in this case it is also required to push .gitmodules file).
+
+* Allow Realm to participate when linking an account identity
++
+When linking a new user identity to an exisiting account, permit the
+Realm to observe the new incoming identity and the current account,
+and to alter the request. This enables a Realm to observe when a
+user verifies a new email address link.
+
+* issue 871 Show latest patchset with cherry-picked merge
++
+When a change is published via the cherry-pick merge strategy,
+show the final commit as a patchset in the change history.
+This now makes it possible to search for the cherry-picked SHA1.
+
+* issue 871 Display hash of the cherry-pick merge in comment
+
+* Added more verbose messages when changes are being rejected
+
+* Display proper error message when LDAP is unavailable
+
+* Clarify error msg when user's not allowed to '--force push'.
+
+* ContainerAuthFilter: fail with FORBIDDEN if username not set
+
+* Resolve 'Project Owners' group if it is included into another group
+
+* Hide SSH URL in email footers if SSH is disabled
+
+* Sort the jar files from the war before adding to classpath.
+
+* Apply user preferences when loading site
+
+* Ensure HttpLog can always get the user identity
+
+* Prevent comments spam for abandoned commit
++
+If some change was abandoned but later submitted (e.g. by
+cherry-picking it to a another branch) then pushing a new branch
+that contains this change no longer adds a new comment.
+
+* Make Address, EmailHeader visible to other EmailSenders
+
+* Use transactions to handle comments when possible
+
+* Try to use transactions when creating changes
+
+* gerrit.sh: disown doesn't accept pid as a argument, fix script
+
+* gerrit.sh: detach gerrit properly so it won't keep bad ssh sessions open.
+
+* Cache list of all groups in the group cache
+
+* issue 1161 Evict project in user cache on save of project meta data
+
+* Ensure that the site paths are resolved to their canonical form (for Windows)
+
+* Connect Velocity to slf4j
+
+* Expose project permissionOnly status via JSON-RPC
+
+* Make HEAD of All-Projects point to refs/meta/config
+
+* issue 1158 Added support for European style dates
+
+* Make macros in email templates local to the template
+
+* Support http://server/project for Git access
+
+* Use _ instead of $ for implementation-detail Prolog predicates
+
+* Update the Sign In anchor with current URL
++
+Always update the href of the Sign In anchor in the menu bar with
+the current page URL after /login/, making the redirect process
+bring users back to the current view after sign in.
+
+* Improve validation of email registration tokens
+
+
+Upgrades
+--------
+* Upgrade to gwtorm 1.2
+
+* Upgrade to JGit 1.1.0.201109151100-r.119-gb4495d1
++
+This is needed because of this change:
+https://gerrit-review.googlesource.com/#/c/30450/
+
+* Support Velocity 1.5 (as well as previous 1.6.4)
+
+
+Bug Fixes
+---------
+* Avoid NPE when group is missing
+
+* Do not fail with NPE if context path of request is null
+
+* Fix NPE in set-project-parent command if parent is not specified
+
+* Only send mail to author and committer if they are registered to prevent an NPE
+
+* Avoid potential NPE when querying the queue.
+
+* Allow loading Project Access when there is no refs/meta/config
+
+* Fix calculation of project name if repo is not existing
++
+If a project inherits from a non existing parent, prevent a
+StringIndexOutOfBoundsException.
+
+* Fix: Supress "Error on refs/cache-automerge" warnings.
+
+* Don't allow registering for cleanup after cleanup runs
++
+This prevents leaking a database connection.
+
+* issue 807 Fix: Tags are not replicated properly
+
+* Prevent smtp rejected users from rejecting emails for all users
+
+* Fix token saving redirect in container auth
++
+Update the jump page that redirects users from /#TOKEN to
+/login/TOKEN.  This forces using the container based
+authentication.  Also correct "/login//" to be just "/login/".
+
+* Use custom error messages for Git-over-HTTP
++
+Ensure clients see messages related to contributor agreement not
+being activated even if they push over HTTP.
+
+* Avoid double key event for GroupReferenceBox
+
+* Fix git push authentication over HTTP
+
+* Fix http://login/ redirect bug
+
+* Fix missing targets in /login/ URLs
+
+* set-project-parent: if update of 1 project fails continue with others
+
+* Verify the case of the project name before opening git repository
+
+* Update top level SUBMITTING_PATCHES URLs
+
+
+Documentation
+-------------
+* Some updates to the design docs
+
+* cmd-index: Fix link to documentation of rename-group command
+
+* Update documentation for testing SSH connection
+
+* Bypass review updated with 2.2.x permissions
+
+* Add documentation for 'peer_keys'
+
+* Improve 'Push Merge Commit' access right documentation
+
+* Access control: Capabilities documented
+** Administrate Server
+** Create Account
+** Create Group
+** Create Project
+** Flush Caches
+** Kill Task
+** Priority
+** Query Limit
+** Start Replication
+** View caches
+** View connections
+** View queue
+
+* Access control: Example roles documented
+** Contributor
+** Developer
+** CI System
+** Integrator
+** Project owner
+** Administrator
diff --git a/ReleaseNotes/ReleaseNotes-2.4.1.txt b/ReleaseNotes/ReleaseNotes-2.4.1.txt
new file mode 100644
index 0000000..15dc1d3
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.4.1.txt
@@ -0,0 +1,55 @@
+Release notes for Gerrit 2.4.1
+==============================
+
+Gerrit 2.4.1 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.1.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.1.war]
+
+
+There are no schema changes from 2.4.  However, if upgrading from
+anything but 2.4, follow the upgrade procedure in the 2.4
+link:ReleaseNotes-2.4.html[ReleaseNotes].
+
+
+Bug Fixes
+---------
+* Catch all exceptions when async emailing
++
+This fixes email notification issues reported
+link:https://groups.google.com/group/repo-discuss/browse_thread/thread/dd157ebc55b962ef/652822d6fbe61e71[here].
+
+* Fixed cleanup of propagated SshScopes
++
+This improves error reporting in case of email notification errors.
+
+* issue 1394 Fix lookup of the 'Commit Message' file in patch set
++
+There is an assumption that the commit message is always first in the list of
+files of a patch set. However, there was another place in Gerrit code, which
+did binary search through the list of the files, without taking this assumption
+into account. In case when a patch set contained a file which lexicographically
+sorted before '/COMMIT_MSG' (like '.gitignore' for example) it could have
+happened that the commit message was not found and, as a side effect, it wasn't
+possible to review it.
+
+* issue 1162 Fix deadlock on destroy of CommandFactoryProvider
+
+* Honor the sendmail.smtpUser from gerrit.config on upgrade
++
+If sendmail.smtpUser was not present in the gerrit.config then don't set it in
+site upgrade.
+
+* issue 1420 Forge committer bypassed
++
+It was possible to forge committer even without having permission for that.
+This was a regression from 2.3.
+
+* Make sure the "Object too large..." error message is printed when an object
+larger than receive.maxObjectSizeLimit is rejected by Gerrit
+
+* Display proper error if file diff fails because content is too large
+
+* Get around a log4j bug that causes AsyncAppender-Dispatcher thread to die and
+block other threads
+** Make async logging buffer size configurable
+** Make logging events discardable, prevent NPE in AsyncAppender-Dispatcher thread
diff --git a/ReleaseNotes/ReleaseNotes-2.4.2.txt b/ReleaseNotes/ReleaseNotes-2.4.2.txt
new file mode 100644
index 0000000..afa1d96
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.4.2.txt
@@ -0,0 +1,24 @@
+Release notes for Gerrit 2.4.2
+==============================
+
+Gerrit 2.4.2 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.2.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.2.war]
+
+There are no schema changes from 2.4, or 2.4.1.
+
+However, if upgrading from anything earlier, follow the upgrade
+procedure in the 2.4 link:ReleaseNotes-2.4.html[ReleaseNotes].
+
+Security Fixes
+--------------
+* Some access control sections may be ignored
++
+Gerrit sometimes ignored an access control section in a project
+if the exact same section name appeared in All-Projects. The bug
+required an unrelated project to have access.inheritFrom set to
+All-Projects and be accessed before the project that has the same
+section name as All-Projects. This is an unlikely scenario for
+most servers, as Gerrit does not normally set inheritFrom equal to
+All-Projects. The usual behavior is to not supply this property in
+project.config, and permit the implicit inheritence to take place.
diff --git a/ReleaseNotes/ReleaseNotes-2.4.txt b/ReleaseNotes/ReleaseNotes-2.4.txt
new file mode 100644
index 0000000..82f3ed4
--- /dev/null
+++ b/ReleaseNotes/ReleaseNotes-2.4.txt
@@ -0,0 +1,257 @@
+Release notes for Gerrit 2.4
+============================
+
+Gerrit 2.4 is now available:
+
+link:http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.war[http://code.google.com/p/gerrit/downloads/detail?name=gerrit-2.4.war]
+
+Schema Change
+-------------
+*WARNING:* This release contains schema changes.  To upgrade:
+----
+  java -jar gerrit.war init -d site_path
+----
+
+*WARNING:* Upgrading to 2.4.x requires the server be first upgraded to 2.1.7 (or
+a later 2.1.x version), and then to 2.4.x.  If you are upgrading from 2.2.x.x or
+newer, you may ignore this warning and upgrade directly to 2.4.x.
+
+New Features
+------------
+
+Security
+~~~~~~~~
+
+* Restrict visibility to arbitrary user dashboards
++
+Administrators have some expectation when using the 'suggest.accounts'
+visibility restriction feature that users cannot get the names or
+email addresses for arbitrary accounts. In fact, because account IDs
+are sequential, it would be easy for an adversary to get personal
+information of all users on the server by requesting every user's
+dashboard.
++
+This includes changing the meaning of the 'suggest.accounts' config
+option to be a boolean indicating whether account suggestion should
+happen at all, which is now orthogonal to the account visibility
+restriction policy. We still recognize the old values for
+'suggest.accounts', with the slight behavior change that
+'suggest.accounts=OFF' now means that users cannot access the dashboards
+of any other users. Administrators who do not want this behavior can
+update their configuration.
+
+* Indicate that 'not found' may actually be a permission issue
+
+Web
+~~~
+
+* Add user preference to mark files reviewed automatically or manually
++
+Add a checkbox to the preferences header on the diff
+screen which allows a user to specify whether they
+want manual-reviewing enabled or disabled.  Previously,
+every file was auto marked reviewed when a user first
+displayed it.  The new manual mode prevents this auto
+marking and only marks a file reviewed when the user
+explicitly clicks on the reviewed checkbox.
+
+* Use 'Auto Merge' for merge commit's base comparison
++
+When reviewing a merge commit, the old wording in the version history dropdown
+of 'Base' doesn't really match Gerrit's behavior.  Updating this to use
+'Auto Merge' as suggested by Shawn Pearce on IRC.
+
+* issue 1035 Add rebase button to the change screen
++
+This change adds a rebase button along with the rest of
+the action buttons in the change page. When pressing the
+button, the most recent patch set will be rebased onto
+the tip of the destination branch or the latest patchset
+of the change we depend upon. A new patch set containing
+the rebased commit will be produced and added to the
+change.
++
+Rebasing of a change in web UI is restricted to change owner, submitter or
+those with the (new) 'rebase' permission.
+
+* Add a new permission 'rebase' to permit rebasing changes in the web UI
+
+* Make a user's dashboard visible if any of the changes are visible to the
+current user.
+
+* Change 'Loading ...' to say 'Working ...' as, often, there is more going on
+than just loading a response.
+
+Performance
+~~~~~~~~~~~
+
+* Asynchronously send email so it does not block the UI
+* Optimize queries for open/merged changes by project + branch
+
+Git
+~~~
+
+* Implement a multi-sub-task progress monitor for ReceiveCommits
+
+* Close corresponding change when pushing to 'refs/heads/*'
++
+Gerrit would not close the open changes with matching change-ids,
+when the user pushes commits directly to 'refs/heads/*'.
++
+This issue could be triggered for two reasons:
+
+. It is triggered when Gerrit detects no changes between the
+pushed commits and the current patchset on the open changes. This
+patch make sure that the matching open change is always closed when
+pushing to 'refs/heads/*', even if no visible changes is detected.
+
+. The same commit exists on another branch than the destination
+branch. This could trick gerrit into just "re-closing" the wrong
+change.
+
+* Run ReceiveCommits in a shared thread pool
++
+Since the work to ReceiveCommits may take a long, potentially unbounded
+amount of time, we would like to have it run in the background so it
+can be monitored for timeouts and cancelled, and have stalls reported
+to the user from the main thread.
+
+Search
+~~~~~~
+
+* Add the '--dependencies' option to the 'query' command.
++
+This option includes information about patch sets which depend on, or are
+needed by, each patch set.
+
+* Branch Operator: Support full branch names
++
+The search operator for branches required the provided value to be the
+short branch name that is shown in the web interface (without the
+'refs/heads/' prefix). Change the branch operator so that it also
+supports full branch names as value.
++
+It is intuive that searching with 'branch:master' and searching with
+'branch:refs/for/master' deliver the same result. So far
+'branch:refs/for/master' was the same as searching with
+'refs:refs/heads/refs/heads/master' which is unexpected for most users.
+
+* Add comment inclusion via '&comments=true' over HTTP
++
+With this change, we can fetch the comments on a patchset by sending a
+request to 'https://site/query?comments=true'
+
+Access Rights
+~~~~~~~~~~~~~
+
+* Added the 'emailReviewers' as a global capability.
++
+This replaces the 'emailOnlyAuthors' flag of account groups.
+
+Dev
+~~~
+
+* issue 1272 Add scripts to create release notes from git log
++
+These script generates a list of commits from git log between two given commits
+and outputs the asciidoc format containting list of commits subject and body.
+
+* Update URL for m2eclipse
++
+The project is now under the Eclipse Foundation umbrella.
+
+* Add missing ignore for m2e prefs in gerrit-ehcache
+
+* Add '--issues' and '--issue_numbers' options to the 'gitlog2asciidoc.py'
+
+Miscellaneous
+~~~~~~~~~~~~~
+
+* Remove perl from 'commit-msg' hook
++
+Removing perl from the commit-msg hook reduces the dependencies
+gerrit imposes on its users.
+
+* updating contrib 'trivial_rebase.py' for 2.2.2.1
+
+Upgrades
+--------
+
+* Updated to Guice 3.0.
+* Updated to gwtorm 1.4.
+* Update JGit to 1.3.0.201202151440-r.75-gff13648
+* Update to gwtjsonrpc 1.3
++
+The change also shrinks the built WAR from 38M to 23M
+by excluding the now unnecessary GWT server code.
+
+Bug Fixes
+---------
+
+* issue 904 Users who starred a change should receive all the emails about a change.
+
+* Fix: 'Diff All Side-by-Side' and 'Diff All Unified' buttons
++
+When pressing the 'Diff All Side-by-Side' or
+'Diff All Unified' button on the change screen, the
+opened browser windows/tabs shows diffs using "Base"
+as old version and the latest one as active patch set,
+regardless what has been set using the
+"Old Version History:" drop down menu and what is
+currently active patch set.
++
+Gerrit doesn't remember the base patch set in the URL,
+making it impossible to copy-and-paste the URL to
+co-workers to show them the same diff a user is
+looking at.
++
+This change fixes this behavior to make sure that
+the opened new browser windows shows diffs using the
+correct old patch set and active patch set.
+
+* Fix NPEs looking up groups by UUID in GroupCache
+
+* Fix default 'receive.timeout'
++
+This should be in milliseconds, not seconds. Set the default to be
+2 minutes in milliseconds and update the documentation to reflect
+that milliseconds are the default unit of time used here.
+
+* Fix 'development_become_any_account' redirects
+* issue 1299 Allow configuration of optional pattern for gitweb file history link
+* Use servlet context path during logout
+
+* issue 1353 Fix case check for project name so that symlinks work again
+* Fix merging of access sections
+* Fix inconsistent behaviour when replicating refs/meta/config
+* Fix duplicated results on status:open project:P branch:B
+
+Documentation
+-------------
+
+Access Rights
+~~~~~~~~~~~~~
+* Capabilities introduced
+* Kill and priority capabilities
+* Administrate server capability
+* Create account capability
+* Create group and project capability
+* Flush caches capability
+* Capability replication and view caches
+* Capability view conn. & queue
+* Example roles introduced
+* Developer example role
+* CI system example role
+* Integrator example role
+* Project owner example role
+* Administrator example role
+
+Miscellaneous
+~~~~~~~~~~~~~
+* User upload documentation: Replace changes
+* Add visible-to-all flag in the documentation for cmd-create-group
+* Add a contributing guideline for annotations
+* Add missing header for suggest.accounts documentation
+* Fix anchors for description of gitweb config parameters
+* Add missing section name to config-gerrit documentation
+* Fix documentation of ls-projects
diff --git a/ReleaseNotes/index.txt b/ReleaseNotes/index.txt
index 48bf6ef..5f8de28 100644
--- a/ReleaseNotes/index.txt
+++ b/ReleaseNotes/index.txt
@@ -1,6 +1,28 @@
 Gerrit Code Review - Release Notes
 ==================================
 
+[[2_4]]
+Version 2.4.x
+-------------
+* link:ReleaseNotes-2.4.2.html[2.4.2]
+* link:ReleaseNotes-2.4.1.html[2.4.1]
+* link:ReleaseNotes-2.4.html[2.4]
+
+[[2_3]]
+Version 2.3.x
+-------------
+* link:ReleaseNotes-2.3.html[2.3]
+* link:ReleaseNotes-2.3.1.html[2.3.1]
+
+[[2_2]]
+Version 2.2.x
+-------------
+* link:ReleaseNotes-2.2.2.html[2.2.2],
+* link:ReleaseNotes-2.2.2.2.html[2.2.2.2],
+* link:ReleaseNotes-2.2.2.1.html[2.2.2.1],
+* link:ReleaseNotes-2.2.1.html[2.2.1],
+* link:ReleaseNotes-2.2.0.html[2.2.0]
+
 [[2_1]]
 Version 2.1.x
 -------------
diff --git a/SUBMITTING_PATCHES b/SUBMITTING_PATCHES
index b444862..e766ef1 100644
--- a/SUBMITTING_PATCHES
+++ b/SUBMITTING_PATCHES
@@ -5,7 +5,7 @@
  - Make sure all code is under the Apache License, 2.0.
  - Publish your changes for review:
 
-   git push ssh://review.source.android.com:29418/tools/gerrit.git HEAD:refs/for/master
+   git push https://gerrit-review.googlesource.com/gerrit HEAD:refs/for/master
 
 
 Long Version:
@@ -55,23 +55,22 @@
 
 Instead, login to the Gerrit Code Review tool at:
 
-  https://review.source.android.com/
+  https://gerrit-review.googlesource.com/
 
 Ensure you have completed one of the necessary contributor
 agreements, providing documentation to the project maintainers that
 they have right to redistribute your work under the Apache License:
 
-  https://review.source.android.com/#settings,agreements
+  https://gerrit-review.googlesource.com/#/settings/agreements
 
-Ensure you have registered one or more SSH public keys, so you can
-push your commits directly over SSH:
+Ensure you have obtained a unique HTTP password to identify yourself:
 
-  https://review.source.android.com/#settings,ssh-keys
+  https://gerrit-review.googlesource.com/#/settings/http-password
 
-Push your patches over SSH to the review server, possibly through
+Push your patches over HTTPS to the review server, possibly through
 a remembered remote to make this easier in the future:
 
-   git config remote.review.url ssh://review.source.android.com:29418/tools/gerrit.git
+   git config remote.review.url https://google-review.googlesource.com/gerrit
    git config remote.review.push HEAD:refs/for/master
 
    git push review
diff --git a/contrib/trivial_rebase.py b/contrib/trivial_rebase.py
index a5123a3..a514b4c 100755
--- a/contrib/trivial_rebase.py
+++ b/contrib/trivial_rebase.py
@@ -93,8 +93,8 @@
 
   Returns a list of approval dicts"""
   sql_query = ("\"SELECT value,account_id,category_id FROM patch_set_approvals "
-               "WHERE change_id = (SELECT change_id FROM changes WHERE "
-               "patch_set_id = %s AND change_key = \'%s\') AND value <> 0\""
+               "WHERE patch_set_id = %s AND change_id = (SELECT change_id FROM "
+               "changes WHERE change_key = \'%s\') AND value <> 0\""
                % ((patchset - 1), changeId))
   gsql_out = GsqlQuery(sql_query, server, port)
   approvals = []
diff --git a/gerrit-antlr/.gitignore b/gerrit-antlr/.gitignore
index 903c6c8..194bedc 100644
--- a/gerrit-antlr/.gitignore
+++ b/gerrit-antlr/.gitignore
@@ -2,3 +2,4 @@
 /.classpath
 /.project
 /.settings/org.maven.ide.eclipse.prefs
+/.settings/org.eclipse.m2e.core.prefs
\ No newline at end of file
diff --git a/gerrit-antlr/.settings/org.eclipse.core.resources.prefs b/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
index 82eb859..589908f 100644
--- a/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-antlr/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,4 @@
-#Tue Sep 02 16:59:24 PDT 2008
+#Thu Jul 28 11:02:35 PDT 2011
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
 encoding/<project>=UTF-8
diff --git a/gerrit-antlr/pom.xml b/gerrit-antlr/pom.xml
index 139cb30..aa0d7fd 100644
--- a/gerrit-antlr/pom.xml
+++ b/gerrit-antlr/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>com.google.gerrit</groupId>
     <artifactId>gerrit-parent</artifactId>
-    <version>2.1-SNAPSHOT</version>
+    <version>2.4-SNAPSHOT</version>
   </parent>
 
   <artifactId>gerrit-antlr</artifactId>
@@ -52,6 +52,18 @@
           </execution>
         </executions>
       </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/gerrit-common/.gitignore b/gerrit-common/.gitignore
index 903c6c8..194bedc 100644
--- a/gerrit-common/.gitignore
+++ b/gerrit-common/.gitignore
@@ -2,3 +2,4 @@
 /.classpath
 /.project
 /.settings/org.maven.ide.eclipse.prefs
+/.settings/org.eclipse.m2e.core.prefs
\ No newline at end of file
diff --git a/gerrit-common/.settings/org.eclipse.core.resources.prefs b/gerrit-common/.settings/org.eclipse.core.resources.prefs
index 82eb859..fc11c3f 100644
--- a/gerrit-common/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-common/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,5 @@
-#Tue Sep 02 16:59:24 PDT 2008
+#Thu Jul 28 11:02:36 PDT 2011
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
+encoding//src/test/java=UTF-8
 encoding/<project>=UTF-8
diff --git a/gerrit-common/.settings/org.eclipse.jdt.core.prefs b/gerrit-common/.settings/org.eclipse.jdt.core.prefs
index 04afc7f..470942d 100644
--- a/gerrit-common/.settings/org.eclipse.jdt.core.prefs
+++ b/gerrit-common/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Tue May 12 17:44:13 PDT 2009
+#Thu Jul 28 11:02:36 PDT 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
@@ -9,6 +9,7 @@
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 org.eclipse.jdt.core.compiler.source=1.6
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
diff --git a/gerrit-common/pom.xml b/gerrit-common/pom.xml
index e878b80..e7933ea 100644
--- a/gerrit-common/pom.xml
+++ b/gerrit-common/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>com.google.gerrit</groupId>
     <artifactId>gerrit-parent</artifactId>
-    <version>2.1-SNAPSHOT</version>
+    <version>2.4-SNAPSHOT</version>
   </parent>
 
   <artifactId>gerrit-common</artifactId>
@@ -90,6 +90,17 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
   </build>
 </project>
diff --git a/gerrit-common/src/main/java/com/google/gerrit/Common.gwt.xml b/gerrit-common/src/main/java/com/google/gerrit/Common.gwt.xml
index 171ae8a..468b477 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/Common.gwt.xml
+++ b/gerrit-common/src/main/java/com/google/gerrit/Common.gwt.xml
@@ -14,7 +14,7 @@
  limitations under the License.
 -->
 <module>
-  <inherits name='com.google.gerrit.ReviewDB' />
+  <inherits name='com.google.gerrit.reviewdb.ReviewDB' />
   <inherits name='com.google.gwtjsonrpc.GWTJSONRPC'/>
   <source path='common' />
 </module>
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
index efe311f..71df400 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/PageLinks.java
@@ -16,42 +16,47 @@
 
 import com.google.gerrit.common.data.AccountInfo;
 import com.google.gerrit.common.data.ChangeInfo;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gerrit.reviewdb.Project;
-import com.google.gerrit.reviewdb.Change.Status;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.Change.Status;
 import com.google.gwtorm.client.KeyUtil;
 
 public class PageLinks {
-  public static final String SETTINGS = "settings";
-  public static final String SETTINGS_PREFERENCES = "settings,preferences";
-  public static final String SETTINGS_SSHKEYS = "settings,ssh-keys";
-  public static final String SETTINGS_HTTP_PASSWORD = "settings,http-password";
-  public static final String SETTINGS_WEBIDENT = "settings,web-identities";
-  public static final String SETTINGS_MYGROUPS = "settings,group-memberships";
-  public static final String SETTINGS_AGREEMENTS = "settings,agreements";
-  public static final String SETTINGS_CONTACT = "settings,contact";
-  public static final String SETTINGS_PROJECTS = "settings,projects";
-  public static final String SETTINGS_NEW_AGREEMENT = "settings,new-agreement";
-  public static final String REGISTER = "register";
+  public static final String SETTINGS = "/settings/";
+  public static final String SETTINGS_PREFERENCES = "/settings/preferences";
+  public static final String SETTINGS_SSHKEYS = "/settings/ssh-keys";
+  public static final String SETTINGS_HTTP_PASSWORD = "/settings/http-password";
+  public static final String SETTINGS_WEBIDENT = "/settings/web-identities";
+  public static final String SETTINGS_MYGROUPS = "/settings/group-memberships";
+  public static final String SETTINGS_AGREEMENTS = "/settings/agreements";
+  public static final String SETTINGS_CONTACT = "/settings/contact";
+  public static final String SETTINGS_PROJECTS = "/settings/projects";
+  public static final String SETTINGS_NEW_AGREEMENT = "/settings/new-agreement";
+  public static final String REGISTER = "/register";
 
   public static final String TOP = "n,z";
 
-  public static final String MINE = "mine";
-  public static final String ADMIN_GROUPS = "admin,groups";
-  public static final String ADMIN_PROJECTS = "admin,projects";
+  public static final String MINE = "/";
+  public static final String ADMIN_GROUPS = "/admin/groups/";
+  public static final String ADMIN_PROJECTS = "/admin/projects/";
+  public static final String ADMIN_CREATE_PROJECT = "/admin/create-project/";
 
   public static String toChange(final ChangeInfo c) {
     return toChange(c.getId());
   }
 
   public static String toChange(final Change.Id c) {
-    return "change," + c.toString();
+    return "/c/" + c + "/";
   }
 
   public static String toChange(final PatchSet.Id ps) {
-    return "change," + ps.getParentKey().toString() + ",patchset=" + ps.get();
+    return "/c/" + ps.getParentKey() + "/" + ps.get();
+  }
+
+  public static String toProjectAcceess(final Project.NameKey p) {
+    return "/admin/projects/" + p.get() + ",access";
   }
 
   public static String toAccountDashboard(final AccountInfo acct) {
@@ -59,11 +64,16 @@
   }
 
   public static String toAccountDashboard(final Account.Id acct) {
-    return "dashboard," + acct.toString();
+    return "/dashboard/" + acct.toString();
   }
 
   public static String toChangeQuery(final String query) {
-    return "q," + KeyUtil.encode(query) + "," + TOP;
+    return toChangeQuery(query, TOP);
+  }
+
+  public static String toChangeQuery(String query, String page) {
+    query = KeyUtil.encode(query).replaceAll("%3[Aa]", ":");
+    return "/q/" + query + "," + page;
   }
 
   public static String projectQuery(Project.NameKey proj, Status status) {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdProviderPattern.java b/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdProviderPattern.java
index 731d765..c80d3eb 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdProviderPattern.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdProviderPattern.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.auth.openid;
 
-import com.google.gerrit.reviewdb.AccountExternalId;
+import com.google.gerrit.reviewdb.client.AccountExternalId;
 
 public class OpenIdProviderPattern {
   public static OpenIdProviderPattern create(String pattern) {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdService.java b/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdService.java
index 0a24cd5..0deba34 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/auth/openid/OpenIdService.java
@@ -15,11 +15,11 @@
 package com.google.gerrit.common.auth.openid;
 
 import com.google.gerrit.common.auth.SignInMode;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.AllowCrossSiteRequest;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.AllowCrossSiteRequest;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 @RpcImpl(version = Version.V2_0)
 public interface OpenIdService extends RemoteJsonService {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/LoginResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/LoginResult.java
index dcabf81..e89cdd2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/LoginResult.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/LoginResult.java
@@ -14,7 +14,40 @@
 
 package com.google.gerrit.common.auth.userpass;
 
+import com.google.gerrit.reviewdb.client.AuthType;
+
 public class LoginResult {
   public boolean success;
   public boolean isNew;
+
+  protected AuthType authType;
+  protected Error error;
+
+  protected LoginResult() {
+  }
+
+  public LoginResult(final AuthType authType) {
+    this.authType = authType;
+  }
+
+  public AuthType getAuthType() {
+    return authType;
+  }
+
+  public void setError(final Error error) {
+    this.error = error;
+    success = error == null;
+  }
+
+  public Error getError() {
+    return error;
+  }
+
+  public static enum Error {
+    /** Username or password are invalid */
+    INVALID_LOGIN,
+
+    /** The authentication server is unavailable or the query to it timed out */
+    AUTHENTICATION_UNAVAILABLE
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/UserPassAuthService.java b/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/UserPassAuthService.java
index 5f39bc3..1d25a3d 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/UserPassAuthService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/auth/userpass/UserPassAuthService.java
@@ -14,11 +14,11 @@
 
 package com.google.gerrit.common.auth.userpass;
 
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.AllowCrossSiteRequest;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.AllowCrossSiteRequest;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 @RpcImpl(version = Version.V2_0)
 public interface UserPassAuthService extends RemoteJsonService {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccessSection.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccessSection.java
new file mode 100644
index 0000000..cd64b0a
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccessSection.java
@@ -0,0 +1,121 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+import com.google.gerrit.reviewdb.client.Project;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/** Portion of a {@link Project} describing access rules. */
+public class AccessSection extends RefConfigSection implements
+    Comparable<AccessSection> {
+  /** Special name given to the global capabilities; not a valid reference. */
+  public static final String GLOBAL_CAPABILITIES = "GLOBAL_CAPABILITIES";
+
+  protected List<Permission> permissions;
+
+  protected AccessSection() {
+  }
+
+  public AccessSection(String refPattern) {
+    super(refPattern);
+  }
+
+  public List<Permission> getPermissions() {
+    if (permissions == null) {
+      permissions = new ArrayList<Permission>();
+    }
+    return permissions;
+  }
+
+  public void setPermissions(List<Permission> list) {
+    Set<String> names = new HashSet<String>();
+    for (Permission p : list) {
+      if (!names.add(p.getName().toLowerCase())) {
+        throw new IllegalArgumentException();
+      }
+    }
+
+    permissions = list;
+  }
+
+  public Permission getPermission(String name) {
+    return getPermission(name, false);
+  }
+
+  public Permission getPermission(String name, boolean create) {
+    for (Permission p : getPermissions()) {
+      if (p.getName().equalsIgnoreCase(name)) {
+        return p;
+      }
+    }
+
+    if (create) {
+      Permission p = new Permission(name);
+      permissions.add(p);
+      return p;
+    } else {
+      return null;
+    }
+  }
+
+  public void remove(Permission permission) {
+    if (permission != null) {
+      removePermission(permission.getName());
+    }
+  }
+
+  public void removePermission(String name) {
+    if (permissions != null) {
+      for (Iterator<Permission> itr = permissions.iterator(); itr.hasNext();) {
+        if (name.equalsIgnoreCase(itr.next().getName())) {
+          itr.remove();
+        }
+      }
+    }
+  }
+
+  public void mergeFrom(AccessSection section) {
+    for (Permission src : section.getPermissions()) {
+      Permission dst = getPermission(src.getName());
+      if (dst != null) {
+        dst.mergeFrom(src);
+      } else {
+        permissions.add(src);
+      }
+    }
+  }
+
+  @Override
+  public int compareTo(AccessSection o) {
+    return comparePattern().compareTo(o.comparePattern());
+  }
+
+  private String comparePattern() {
+    if (getName().startsWith(REGEX_PREFIX)) {
+      return getName().substring(REGEX_PREFIX.length());
+    }
+    return getName();
+  }
+
+  @Override
+  public String toString() {
+    return "AccessSection[" + getName() + "]";
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountDashboardInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountDashboardInfo.java
index abcfe28..e24900b 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountDashboardInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountDashboardInfo.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
+import com.google.gerrit.reviewdb.client.Account;
 
 import java.util.List;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfo.java
index 39c5d9c..9a4d9fb 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountInfo.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
+import com.google.gerrit.reviewdb.client.Account;
 
 /** Summary information about an {@link Account}, for simple tabular displays. */
 public class AccountInfo {
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 cf5f20b..bc028e8 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
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
+import com.google.gerrit.reviewdb.client.Account;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountProjectWatchInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountProjectWatchInfo.java
index 89a50f1..581a09b 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountProjectWatchInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountProjectWatchInfo.java
@@ -14,8 +14,8 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountProjectWatch;
-import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.reviewdb.client.AccountProjectWatch;
+import com.google.gerrit.reviewdb.client.Project;
 
 public final class AccountProjectWatchInfo {
   protected AccountProjectWatch watch;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
index 1117455..21aca69 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountSecurity.java
@@ -15,17 +15,16 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AccountExternalId;
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.AccountSshKey;
-import com.google.gerrit.reviewdb.ContactInformation;
-import com.google.gerrit.reviewdb.ContributorAgreement;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountExternalId;
+import com.google.gerrit.reviewdb.client.AccountSshKey;
+import com.google.gerrit.reviewdb.client.ContactInformation;
+import com.google.gerrit.reviewdb.client.ContributorAgreement;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 import java.util.Set;
@@ -57,7 +56,7 @@
   void myExternalIds(AsyncCallback<List<AccountExternalId>> callback);
 
   @SignInRequired
-  void myGroups(AsyncCallback<List<AccountGroup>> callback);
+  void myGroups(AsyncCallback<List<GroupDetail>> callback);
 
   @SignInRequired
   void deleteExternalIds(Set<AccountExternalId.Key> keys,
@@ -72,7 +71,7 @@
       AsyncCallback<VoidResult> callback);
 
   @SignInRequired
-  void registerEmail(String address, AsyncCallback<VoidResult> callback);
+  void registerEmail(String address, AsyncCallback<Account> callback);
 
   @SignInRequired
   void validateEmail(String token, AsyncCallback<VoidResult> callback);
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountService.java
index e219074..7377d7e 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AccountService.java
@@ -15,15 +15,15 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AccountDiffPreference;
-import com.google.gerrit.reviewdb.AccountGeneralPreferences;
-import com.google.gerrit.reviewdb.AccountProjectWatch;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences;
+import com.google.gerrit.reviewdb.client.AccountProjectWatch;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 import java.util.Set;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/AgreementInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/AgreementInfo.java
index 7ae651e..0c6f6b7 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/AgreementInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/AgreementInfo.java
@@ -14,9 +14,9 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountAgreement;
-import com.google.gerrit.reviewdb.AccountGroupAgreement;
-import com.google.gerrit.reviewdb.ContributorAgreement;
+import com.google.gerrit.reviewdb.client.AccountAgreement;
+import com.google.gerrit.reviewdb.client.AccountGroupAgreement;
+import com.google.gerrit.reviewdb.client.ContributorAgreement;
 
 import java.util.List;
 import java.util.Map;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalDetail.java
index 9834693..3d438f2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalDetail.java
@@ -14,16 +14,16 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.PatchSetApproval;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.ApprovalCategory;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
 
 import java.sql.Timestamp;
 import java.util.ArrayList;
 import java.util.Comparator;
-import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
+import java.util.Set;
 
 public class ApprovalDetail {
   public static final Comparator<ApprovalDetail> SORT =
@@ -43,6 +43,8 @@
   protected List<PatchSetApproval> approvals;
   protected boolean canRemove;
 
+  private transient Set<String> approved;
+  private transient Set<String> rejected;
   private transient int hasNonZero;
   private transient Timestamp sortOrder = EG_D;
 
@@ -66,13 +68,17 @@
     canRemove = removeable;
   }
 
-  public Map<ApprovalCategory.Id, PatchSetApproval> getApprovalMap() {
-    final HashMap<ApprovalCategory.Id, PatchSetApproval> r;
-    r = new HashMap<ApprovalCategory.Id, PatchSetApproval>();
-    for (final PatchSetApproval ca : approvals) {
-      r.put(ca.getCategoryId(), ca);
+  public List<PatchSetApproval> getPatchSetApprovals() {
+    return approvals;
+  }
+
+  public PatchSetApproval getPatchSetApproval(ApprovalCategory.Id category) {
+    for (PatchSetApproval psa : approvals) {
+      if (psa.getCategoryId().equals(category)) {
+        return psa;
+      }
     }
-    return r;
+    return null;
   }
 
   public void sortFirst() {
@@ -91,4 +97,26 @@
       hasNonZero = 1;
     }
   }
+
+  public void approved(String label) {
+    if (approved == null) {
+      approved = new HashSet<String>();
+    }
+    approved.add(label);
+  }
+
+  public void rejected(String label) {
+    if (rejected == null) {
+      rejected = new HashSet<String>();
+    }
+    rejected.add(label);
+  }
+
+  public boolean isApproved(String label) {
+    return approved != null && approved.contains(label);
+  }
+
+  public boolean isRejected(String label) {
+    return rejected != null && rejected.contains(label);
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummary.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummary.java
index 57e8b71..19c9d67 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummary.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummary.java
@@ -14,8 +14,8 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.PatchSetApproval;
+import com.google.gerrit.reviewdb.client.ApprovalCategory;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummarySet.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummarySet.java
index 57ee928..2b11085 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummarySet.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalSummarySet.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Change;
+import com.google.gerrit.reviewdb.client.Change;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalType.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalType.java
index ea9aedb..333b91c 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalType.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalType.java
@@ -14,9 +14,9 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.ApprovalCategoryValue;
-import com.google.gerrit.reviewdb.PatchSetApproval;
+import com.google.gerrit.reviewdb.client.ApprovalCategory;
+import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -31,6 +31,7 @@
   protected short maxNegative;
   protected short maxPositive;
 
+  private transient List<Integer> intList;
   private transient Map<Short, ApprovalCategoryValue> byValue;
 
   protected ApprovalType() {
@@ -56,6 +57,9 @@
         maxPositive = values.get(values.size() - 1).getValue();
       }
     }
+
+    // Force the label name to pre-compute so we don't have data race conditions.
+    getCategory().getLabelName();
   }
 
   public ApprovalCategory getCategory() {
@@ -107,4 +111,16 @@
       }
     }
   }
+
+  public List<Integer> getValuesAsList() {
+    if (intList == null) {
+      intList = new ArrayList<Integer>(values.size());
+      for (ApprovalCategoryValue acv : values) {
+        intList.add(Integer.valueOf(acv.getValue()));
+      }
+      Collections.sort(intList);
+      Collections.reverse(intList);
+    }
+    return intList;
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalTypes.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalTypes.java
index 1b6d4a3..b1e32d1 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalTypes.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ApprovalTypes.java
@@ -14,25 +14,22 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.ApprovalCategory;
+import com.google.gerrit.reviewdb.client.ApprovalCategory;
 
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 public class ApprovalTypes {
   protected List<ApprovalType> approvalTypes;
-  protected List<ApprovalType> actionTypes;
-  private transient Map<ApprovalCategory.Id, ApprovalType> byCategoryId;
+  private transient Map<ApprovalCategory.Id, ApprovalType> byId;
+  private transient Map<String, ApprovalType> byLabel;
 
   protected ApprovalTypes() {
   }
 
-  public ApprovalTypes(final List<ApprovalType> approvals,
-      final List<ApprovalType> actions) {
+  public ApprovalTypes(final List<ApprovalType> approvals) {
     approvalTypes = approvals;
-    actionTypes = actions;
     byCategory();
   }
 
@@ -40,33 +37,35 @@
     return approvalTypes;
   }
 
-  public List<ApprovalType> getActionTypes() {
-    return actionTypes;
-  }
-
-  public ApprovalType getApprovalType(final ApprovalCategory.Id id) {
+  public ApprovalType byId(final ApprovalCategory.Id id) {
     return byCategory().get(id);
   }
 
-  public Set<ApprovalCategory.Id> getApprovalCategories() {
-    return byCategory().keySet();
-  }
-
   private Map<ApprovalCategory.Id, ApprovalType> byCategory() {
-    if (byCategoryId == null) {
-      byCategoryId = new HashMap<ApprovalCategory.Id, ApprovalType>();
-      if (actionTypes != null) {
-        for (final ApprovalType t : actionTypes) {
-          byCategoryId.put(t.getCategory().getId(), t);
-        }
-      }
-
+    if (byId == null) {
+      byId = new HashMap<ApprovalCategory.Id, ApprovalType>();
       if (approvalTypes != null) {
         for (final ApprovalType t : approvalTypes) {
-          byCategoryId.put(t.getCategory().getId(), t);
+          byId.put(t.getCategory().getId(), t);
         }
       }
     }
-    return byCategoryId;
+    return byId;
+  }
+
+  public ApprovalType byLabel(String labelName) {
+    return byLabel().get(labelName.toLowerCase());
+  }
+
+  private Map<String, ApprovalType> byLabel() {
+    if (byLabel == null) {
+      byLabel = new HashMap<String, ApprovalType>();
+      if (approvalTypes != null) {
+        for (ApprovalType t : approvalTypes) {
+          byLabel.put(t.getCategory().getLabelName().toLowerCase(), t);
+        }
+      }
+    }
+    return byLabel;
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/Capable.java
similarity index 64%
copy from gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java
copy to gerrit-common/src/main/java/com/google/gerrit/common/data/Capable.java
index 83bca7b..0be4b76 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/Capable.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 The Android Open Source Project
+// Copyright (C) 2008 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,14 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.schema;
+package com.google.gerrit.common.data;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
+public class Capable {
+  public static final Capable OK = new Capable("OK");
 
-public class Schema_42 extends SchemaVersion {
-  @Inject
-  Schema_42(Provider<Schema_41> prior) {
-    super(prior);
+  private final String message;
+
+  public Capable(String msg) {
+    message = msg;
+  }
+
+  public String getMessage() {
+    return message;
   }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
index 572fd7a..74d1962 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetail.java
@@ -14,35 +14,37 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.ChangeMessage;
-import com.google.gerrit.reviewdb.PatchSet;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.ChangeMessage;
+import com.google.gerrit.reviewdb.client.PatchSet;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
 
 /** Detail necessary to display a change. */
 public class ChangeDetail {
   protected AccountInfoCache accounts;
   protected boolean allowsAnonymous;
   protected boolean canAbandon;
+  protected boolean canPublish;
+  protected boolean canRebase;
   protected boolean canRestore;
   protected boolean canRevert;
+  protected boolean canDeleteDraft;
   protected Change change;
   protected boolean starred;
   protected List<ChangeInfo> dependsOn;
   protected List<ChangeInfo> neededBy;
   protected List<PatchSet> patchSets;
   protected List<ApprovalDetail> approvals;
-  protected Set<ApprovalCategory.Id> missingApprovals;
+  protected List<SubmitRecord> submitRecords;
+  protected boolean canSubmit;
   protected List<ChangeMessage> messages;
   protected PatchSet.Id currentPatchSetId;
   protected PatchSetDetail currentDetail;
-  protected Set<ApprovalCategory.Id> currentActions;
+  protected boolean canEdit;
 
   public ChangeDetail() {
   }
@@ -71,6 +73,22 @@
     canAbandon = a;
   }
 
+  public boolean canPublish() {
+    return canPublish;
+  }
+
+  public void setCanPublish(final boolean a) {
+    canPublish = a;
+  }
+
+  public boolean canRebase() {
+    return canRebase;
+  }
+
+  public void setCanRebase(final boolean a) {
+    canRebase = a;
+  }
+
   public boolean canRestore() {
     return canRestore;
   }
@@ -87,6 +105,22 @@
       canRevert = a;
   }
 
+  public boolean canSubmit() {
+    return canSubmit;
+  }
+
+  public void setCanSubmit(boolean a) {
+    canSubmit = a;
+  }
+
+  public boolean canDeleteDraft() {
+    return canDeleteDraft;
+  }
+
+  public void setCanDeleteDraft(boolean a) {
+    canDeleteDraft = a;
+  }
+
   public Change getChange() {
     return change;
   }
@@ -145,20 +179,12 @@
     Collections.sort(approvals, ApprovalDetail.SORT);
   }
 
-  public Set<ApprovalCategory.Id> getMissingApprovals() {
-    return missingApprovals;
+  public void setSubmitRecords(List<SubmitRecord> all) {
+    submitRecords = all;
   }
 
-  public void setMissingApprovals(Set<ApprovalCategory.Id> a) {
-    missingApprovals = a;
-  }
-
-  public Set<ApprovalCategory.Id> getCurrentActions() {
-    return currentActions;
-  }
-
-  public void setCurrentActions(Set<ApprovalCategory.Id> a) {
-    currentActions = a;
+  public List<SubmitRecord> getSubmitRecords() {
+    return submitRecords;
   }
 
   public boolean isCurrentPatchSet(final PatchSetDetail detail) {
@@ -189,7 +215,19 @@
     currentDetail = d;
   }
 
+  public void setCurrentPatchSetId(final PatchSet.Id id) {
+    currentPatchSetId = id;
+  }
+
   public String getDescription() {
     return currentDetail != null ? currentDetail.getInfo().getMessage() : "";
   }
+
+  public void setCanEdit(boolean a) {
+    canEdit = a;
+  }
+
+  public boolean canEdit() {
+    return canEdit;
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetailService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetailService.java
index 2fbda21..8b43624 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetailService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeDetailService.java
@@ -15,13 +15,13 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.AccountDiffPreference;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 @RpcImpl(version = Version.V2_0)
 public interface ChangeDetailService extends RemoteJsonService {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeInfo.java
index b5271ec..391d615 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeInfo.java
@@ -14,8 +14,9 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.Change;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchSet;
 
 import java.sql.Timestamp;
 
@@ -31,11 +32,13 @@
   protected boolean starred;
   protected Timestamp lastUpdatedOn;
   protected String sortKey;
+  protected PatchSet.Id patchSetId;
+  protected boolean latest;
 
   protected ChangeInfo() {
   }
 
-  public ChangeInfo(final Change c) {
+  public ChangeInfo(final Change c, final PatchSet.Id patchId) {
     id = c.getId();
     key = c.getKey();
     owner = c.getOwner();
@@ -46,6 +49,12 @@
     topic = c.getTopic();
     lastUpdatedOn = c.getLastUpdatedOn();
     sortKey = c.getSortKey();
+    patchSetId = patchId;
+    latest = patchSetId == null || c.currPatchSetId().equals(patchSetId);
+  }
+
+  public ChangeInfo(final Change c) {
+    this(c, null);
   }
 
   public Change.Id getId() {
@@ -88,6 +97,14 @@
     starred = s;
   }
 
+  public PatchSet.Id getPatchSetId() {
+    return patchSetId;
+  }
+
+  public boolean isLatest() {
+    return latest;
+  }
+
   public java.sql.Timestamp getLastUpdatedOn() {
     return lastUpdatedOn;
   }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeListService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeListService.java
index 5ff85e3..f646bc6 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeListService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeListService.java
@@ -15,13 +15,13 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.Set;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeManageService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeManageService.java
index cb38c3b..872bddc 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeManageService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ChangeManageService.java
@@ -15,11 +15,12 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 @RpcImpl(version = Version.V2_0)
 public interface ChangeManageService extends RemoteJsonService {
@@ -37,4 +38,13 @@
   @SignInRequired
   void restoreChange(PatchSet.Id patchSetId, String message,
       AsyncCallback<ChangeDetail> callback);
+
+  @SignInRequired
+  void publish(PatchSet.Id patchSetId, AsyncCallback<ChangeDetail> callback);
+
+  @SignInRequired
+  void deleteDraftChange(PatchSet.Id patchSetId, AsyncCallback<VoidResult> callback);
+
+  @SignInRequired
+  void rebaseChange(PatchSet.Id patchSetId, AsyncCallback<ChangeDetail> callback);
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java
index 576e077..0e079b3 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/CommentDetail.java
@@ -14,8 +14,8 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.PatchLineComment;
-import com.google.gerrit.reviewdb.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchLineComment;
+import com.google.gerrit.reviewdb.client.PatchSet;
 
 import java.util.ArrayList;
 import java.util.Collections;
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 9bb87ab..456ffb4 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
@@ -15,10 +15,10 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.openid.OpenIdProviderPattern;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AuthType;
-import com.google.gerrit.reviewdb.Project;
-import com.google.gerrit.reviewdb.AccountGeneralPreferences.DownloadScheme;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AuthType;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.AccountGeneralPreferences.DownloadScheme;
 import com.google.gwtexpui.safehtml.client.RegexFindReplace;
 
 import java.util.List;
@@ -26,21 +26,25 @@
 
 public class GerritConfig implements Cloneable {
   protected String registerUrl;
+  protected String httpPasswordUrl;
   protected List<OpenIdProviderPattern> allowedOpenIDs;
 
-  protected GitwebLink gitweb;
+  protected GitwebConfig gitweb;
   protected boolean useContributorAgreements;
   protected boolean useContactInfo;
   protected boolean allowRegisterNewEmail;
   protected AuthType authType;
   protected Set<DownloadScheme> downloadSchemes;
   protected String gitDaemonUrl;
+  protected String gitHttpUrl;
   protected String sshdAddress;
   protected Project.NameKey wildProject;
   protected ApprovalTypes approvalTypes;
   protected Set<Account.FieldName> editableAccountFields;
   protected List<RegexFindReplace> commentLinks;
   protected boolean documentationAvailable;
+  protected boolean testChangeMerge;
+  protected String anonymousCowardName;
 
   public String getRegisterUrl() {
     return registerUrl;
@@ -50,6 +54,14 @@
     registerUrl = u;
   }
 
+  public String getHttpPasswordUrl() {
+    return httpPasswordUrl;
+  }
+
+  public void setHttpPasswordUrl(String url) {
+    httpPasswordUrl = url;
+  }
+
   public List<OpenIdProviderPattern> getAllowedOpenIDs() {
     return allowedOpenIDs;
   }
@@ -74,11 +86,11 @@
     downloadSchemes = s;
   }
 
-  public GitwebLink getGitwebLink() {
+  public GitwebConfig getGitwebLink() {
     return gitweb;
   }
 
-  public void setGitwebLink(final GitwebLink w) {
+  public void setGitwebLink(final GitwebConfig w) {
     gitweb = w;
   }
 
@@ -109,6 +121,17 @@
     gitDaemonUrl = url;
   }
 
+  public String getGitHttpUrl() {
+    return gitHttpUrl;
+  }
+
+  public void setGitHttpUrl(String url) {
+    if (url != null && !url.endsWith("/")) {
+      url += "/";
+    }
+    gitHttpUrl = url;
+  }
+
   public String getSshdAddress() {
     return sshdAddress;
   }
@@ -160,4 +183,20 @@
   public void setDocumentationAvailable(final boolean available) {
     documentationAvailable = available;
   }
+
+  public boolean testChangeMerge() {
+    return testChangeMerge;
+  }
+
+  public void setTestChangeMerge(final boolean test) {
+    testChangeMerge = test;
+  }
+
+  public String getAnonymousCowardName() {
+    return anonymousCowardName;
+  }
+
+  public void setAnonymousCowardName(final String anonymousCowardName) {
+    this.anonymousCowardName = anonymousCowardName;
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GitWebType.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GitWebType.java
index 7eb6955..0e2e50d 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GitWebType.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GitWebType.java
@@ -27,18 +27,27 @@
 
     if (name == null || name.isEmpty() || name.equalsIgnoreCase("gitweb")) {
       type = new GitWebType();
+      type.setLinkName("gitweb");
       type.setProject("?p=${project}.git;a=summary");
       type.setRevision("?p=${project}.git;a=commit;h=${commit}");
       type.setBranch("?p=${project}.git;a=shortlog;h=${branch}");
+      type.setFileHistory("?p=${project}.git;a=history;hb=${branch};f=${file}");
 
     } else if (name.equalsIgnoreCase("cgit")) {
       type = new GitWebType();
+      type.setLinkName("cgit");
       type.setProject("${project}/summary");
       type.setRevision("${project}/commit/?id=${commit}");
       type.setBranch("${project}/log/?h=${branch}");
+      type.setFileHistory("${project}/log/${file}?h=${branch}");
 
     } else if (name.equalsIgnoreCase("custom")) {
       type = new GitWebType();
+      // The custom name is not defined, let's keep the old style of using GitWeb
+      type.setLinkName("gitweb");
+
+    } else if (name.equalsIgnoreCase("disabled")) {
+      type = null;
 
     } else {
       type = null;
@@ -47,6 +56,9 @@
     return type;
   }
 
+  /** name of the type. */
+  private String name;
+
   /** String for revision view url. */
   private String revision;
 
@@ -56,6 +68,13 @@
   /** ParamertizedString for branch view url. */
   private String branch;
 
+  /** ParamertizedString for file history view url. */
+  private String fileHistory;
+
+  /** Character to substitute the standard path separator '/' in branch and
+    * project names */
+  private char pathSeparator = '/';
+
   /** Private default constructor for gson. */
   protected GitWebType() {
   }
@@ -70,6 +89,15 @@
   }
 
   /**
+   * Get the String for link-name of the type.
+   *
+   * @return The String for link-name of the type
+   */
+  public String getLinkName() {
+    return name;
+  }
+
+  /**
    * Get the String for project view.
    *
    * @return The String for project view
@@ -88,6 +116,15 @@
   }
 
   /**
+   * Get the String for file history view.
+   *
+   * @return The String for file history view
+   */
+  public String getFileHistory() {
+    return fileHistory;
+  }
+
+  /**
    * Set the pattern for branch view.
    *
    * @param pattern The pattern for branch view
@@ -99,6 +136,17 @@
   }
 
   /**
+   * Set the pattern for link-name type.
+   *
+   * @param pattern The pattern for link-name type
+   */
+  public void setLinkName(final String name) {
+    if (name != null && !name.isEmpty()) {
+      this.name = name;
+    }
+  }
+
+  /**
    * Set the pattern for project view.
    *
    * @param pattern The pattern for project view
@@ -119,4 +167,38 @@
       revision = pattern;
     }
   }
+
+  /**
+   * Set the pattern for file history view.
+   *
+   * @param pattern The pattern for file history view
+   */
+  public void setFileHistory(final String pattern) {
+    if (pattern != null && !pattern.isEmpty()) {
+      fileHistory = pattern;
+    }
+  }
+
+  /**
+   * Replace the standard path separator ('/') in a branch name or project
+   * name with a custom path separator configured by the property
+   * gitweb.pathSeparator.
+   * @param urlSegment The branch or project to replace the path separator in
+   * @return the urlSegment with the standard path separator replaced by the
+   * custom path separator
+   */
+  public String replacePathSeparator(String urlSegment) {
+    if ('/' != pathSeparator) {
+      return urlSegment.replace('/', pathSeparator);
+    }
+    return urlSegment;
+  }
+
+  /**
+   * Set the custom path separator
+   * @param separator The custom path separator
+   */
+  public void setPathSeparator(char separator) {
+    this.pathSeparator = separator;
+  }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebConfig.java
similarity index 60%
copy from gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java
copy to gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebConfig.java
index 83bca7b..0503c60 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_42.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebConfig.java
@@ -1,4 +1,4 @@
-// Copyright (C) 2010 The Android Open Source Project
+// Copyright (C) 2008 The Android Open Source Project
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -12,14 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.schema;
+package com.google.gerrit.common.data;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
+/** Link to an external gitweb server. */
+public class GitwebConfig {
+  public String baseUrl;
+  public GitWebType type;
 
-public class Schema_42 extends SchemaVersion {
-  @Inject
-  Schema_42(Provider<Schema_41> prior) {
-    super(prior);
+  protected GitwebConfig() {
+  }
+
+  public GitwebConfig(final String base, final GitWebType gitWebType) {
+    baseUrl = base;
+    type = gitWebType;
   }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebLink.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebLink.java
deleted file mode 100644
index 937bbd4..0000000
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GitwebLink.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2008 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.common.data;
-
-import com.google.gerrit.reviewdb.Branch;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gerrit.reviewdb.Project;
-import com.google.gwt.http.client.URL;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/** Link to an external gitweb server. */
-public class GitwebLink {
-  protected String baseUrl;
-
-  protected GitWebType type;
-
-  protected GitwebLink() {
-  }
-
-  public GitwebLink(final String base, final GitWebType gitWebType) {
-    baseUrl = base;
-    type = gitWebType;
-  }
-
-  public String toRevision(final Project.NameKey project, final PatchSet ps) {
-    ParamertizedString pattern = new ParamertizedString(type.getRevision());
-
-    final Map<String, String> p = new HashMap<String, String>();
-    p.put("project", URL.encodeQueryString(project.get()));
-    p.put("commit", URL.encodeQueryString(ps.getRevision().get()));
-    return baseUrl + pattern.replace(p);
-  }
-
-  public String toProject(final Project.NameKey project) {
-    ParamertizedString pattern = new ParamertizedString(type.getProject());
-
-    final Map<String, String> p = new HashMap<String, String>();
-    p.put("project", URL.encodeQueryString(project.get()));
-    return baseUrl + pattern.replace(p);
-  }
-
-  public String toBranch(final Branch.NameKey branch) {
-    ParamertizedString pattern = new ParamertizedString(type.getBranch());
-
-    final Map<String, String> p = new HashMap<String, String>();
-    p.put("project", URL.encodeQueryString(branch.getParentKey().get()));
-    p.put("branch", URL.encodeQueryString(branch.get()));
-    return baseUrl + pattern.replace(p);
-  }
-}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
new file mode 100644
index 0000000..d3d2a4d
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GlobalCapability.java
@@ -0,0 +1,119 @@
+// Copyright (C) 2011 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.common.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Server wide capabilities. Represented as {@link Permission} objects. */
+public class GlobalCapability {
+  /**
+   * Denotes the server's administrators.
+   * <p>
+   * This is similar to UNIX root, or Windows SYSTEM account. Any user that
+   * has this capability can perform almost any other action, or can grant
+   * themselves the power to perform any other action on the site. Most of
+   * the other capabilities and permissions fall-back to the predicate
+   * "OR user has capablity ADMINISTRATE_SERVER".
+   */
+  public static final String ADMINISTRATE_SERVER = "administrateServer";
+
+  /** Can create any account on the server. */
+  public static final String CREATE_ACCOUNT = "createAccount";
+
+  /** Can create any group on the server. */
+  public static final String CREATE_GROUP = "createGroup";
+
+  /** Can create any project on the server. */
+  public static final String CREATE_PROJECT = "createProject";
+
+  /**
+   * Denotes who may email change reviewers.
+   * <p>
+   * This can be used to deny build bots from emailing reviewers and people who
+   * have starred the changed. Instead, only the authors of the change will be
+   * emailed. The allow rules are evaluated before deny rules, however the
+   * default is to allow emailing, if no explicit rule is matched.
+   */
+  public static final String EMAIL_REVIEWERS = "emailReviewers";
+
+  /** Can flush any cache except the active web_sessions cache. */
+  public static final String FLUSH_CACHES = "flushCaches";
+
+  /** Can terminate any task using the kill command. */
+  public static final String KILL_TASK = "killTask";
+
+  /** Queue a user can access to submit their tasks to. */
+  public static final String PRIORITY = "priority";
+
+  /** Maximum result limit per executed query. */
+  public static final String QUERY_LIMIT = "queryLimit";
+
+  /** Forcefully restart replication to any configured destination. */
+  public static final String START_REPLICATION = "startReplication";
+
+  /** Can view the server's current cache states. */
+  public static final String VIEW_CACHES = "viewCaches";
+
+  /** Can view open connections to the server's SSH port. */
+  public static final String VIEW_CONNECTIONS = "viewConnections";
+
+  /** Can view all pending tasks in the queue (not just the filtered set). */
+  public static final String VIEW_QUEUE = "viewQueue";
+
+  private static final List<String> NAMES_LC;
+
+  static {
+    NAMES_LC = new ArrayList<String>();
+    NAMES_LC.add(ADMINISTRATE_SERVER.toLowerCase());
+    NAMES_LC.add(CREATE_ACCOUNT.toLowerCase());
+    NAMES_LC.add(CREATE_GROUP.toLowerCase());
+    NAMES_LC.add(CREATE_PROJECT.toLowerCase());
+    NAMES_LC.add(EMAIL_REVIEWERS.toLowerCase());
+    NAMES_LC.add(FLUSH_CACHES.toLowerCase());
+    NAMES_LC.add(KILL_TASK.toLowerCase());
+    NAMES_LC.add(PRIORITY.toLowerCase());
+    NAMES_LC.add(QUERY_LIMIT.toLowerCase());
+    NAMES_LC.add(START_REPLICATION.toLowerCase());
+    NAMES_LC.add(VIEW_CACHES.toLowerCase());
+    NAMES_LC.add(VIEW_CONNECTIONS.toLowerCase());
+    NAMES_LC.add(VIEW_QUEUE.toLowerCase());
+  }
+
+  /** @return true if the name is recognized as a capability name. */
+  public static boolean isCapability(String varName) {
+    return NAMES_LC.contains(varName.toLowerCase());
+  }
+
+  /** @return true if the capability should have a range attached. */
+  public static boolean hasRange(String varName) {
+    return QUERY_LIMIT.equalsIgnoreCase(varName);
+  }
+
+  /** @return the valid range for the capability if it has one, otherwise null. */
+  public static PermissionRange.WithDefaults getRange(String varName) {
+    if (QUERY_LIMIT.equalsIgnoreCase(varName)) {
+      return new PermissionRange.WithDefaults(
+          varName,
+          0, Integer.MAX_VALUE,
+          0, 500);
+    }
+    return null;
+  }
+
+  private GlobalCapability() {
+    // Utility class, do not create instances.
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupAdminService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupAdminService.java
index ce508cc..f385e27 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupAdminService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupAdminService.java
@@ -15,14 +15,14 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.AccountGroupInclude;
-import com.google.gerrit.reviewdb.AccountGroupMember;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupInclude;
+import com.google.gerrit.reviewdb.client.AccountGroupMember;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 import java.util.Set;
@@ -30,13 +30,14 @@
 @RpcImpl(version = Version.V2_0)
 public interface GroupAdminService extends RemoteJsonService {
   @SignInRequired
-  void visibleGroups(AsyncCallback<List<AccountGroup>> callback);
+  void visibleGroups(AsyncCallback<GroupList> callback);
 
   @SignInRequired
   void createGroup(String newName, AsyncCallback<AccountGroup.Id> callback);
 
   @SignInRequired
-  void groupDetail(AccountGroup.Id groupId, AsyncCallback<GroupDetail> callback);
+  void groupDetail(AccountGroup.Id groupId, AccountGroup.UUID uuid,
+      AsyncCallback<GroupDetail> callback);
 
   @SignInRequired
   void changeGroupDescription(AccountGroup.Id groupId, String description,
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupDetail.java
index 69e535c..65723f7 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupDetail.java
@@ -14,9 +14,9 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.AccountGroupInclude;
-import com.google.gerrit.reviewdb.AccountGroupMember;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroupInclude;
+import com.google.gerrit.reviewdb.client.AccountGroupMember;
 
 import java.util.List;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfo.java
index 55577f2..547a5f4 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupInfo.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 
 /** Summary information about an {@link AccountGroup}, for simple tabular displays. */
 public class GroupInfo {
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 80d8756..6a5dd5c 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
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 
 import java.util.Collections;
 import java.util.HashMap;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupList.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupList.java
new file mode 100644
index 0000000..6352461
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupList.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2011 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.common.data;
+
+import java.util.List;
+
+public class GroupList {
+  protected List<GroupDetail> groups;
+  protected boolean canCreateGroup;
+
+  protected GroupList() {
+  }
+
+  public GroupList(final List<GroupDetail> groups, final boolean canCreateGroup) {
+    this.groups = groups;
+    this.canCreateGroup = canCreateGroup;
+  }
+
+  public List<GroupDetail> getGroups() {
+    return groups;
+  }
+
+  public void setGroups(List<GroupDetail> groups) {
+    this.groups = groups;
+  }
+
+  public boolean isCanCreateGroup() {
+    return canCreateGroup;
+  }
+
+  public void setCanCreateGroup(boolean set) {
+    canCreateGroup = set;
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupOptions.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupOptions.java
index 82e0618..c6ed781 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupOptions.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupOptions.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 
 /**
  * Options for an {@link AccountGroup}.
@@ -22,22 +22,15 @@
 public class GroupOptions {
 
   private boolean visibleToAll;
-  private boolean emailOnlyAuthors;
 
   protected GroupOptions() {
   }
 
-  public GroupOptions(final boolean visibleToAll,
-       final boolean emailOnlyAuthors) {
+  public GroupOptions(final boolean visibleToAll) {
     this.visibleToAll = visibleToAll;
-    this.emailOnlyAuthors = emailOnlyAuthors;
   }
 
   public boolean isVisibleToAll() {
     return visibleToAll;
   }
-
-  public boolean isEmailOnlyAuthors() {
-    return emailOnlyAuthors;
-  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java
new file mode 100644
index 0000000..f05d1b9
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/GroupReference.java
@@ -0,0 +1,76 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+import com.google.gerrit.reviewdb.client.AccountGroup;
+
+/** Describes a group within a projects {@link AccessSection}s. */
+public class GroupReference implements Comparable<GroupReference> {
+  /** @return a new reference to the given group description. */
+  public static GroupReference forGroup(AccountGroup group) {
+    return new GroupReference(group.getGroupUUID(), group.getName());
+  }
+
+  protected String uuid;
+  protected String name;
+
+  protected GroupReference() {
+  }
+
+  public GroupReference(AccountGroup.UUID uuid, String name) {
+    setUUID(uuid);
+    setName(name);
+  }
+
+  public AccountGroup.UUID getUUID() {
+    return uuid != null ? new AccountGroup.UUID(uuid) : null;
+  }
+
+  public void setUUID(AccountGroup.UUID newUUID) {
+    uuid = newUUID != null ? newUUID.get() : null;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String newName) {
+    this.name = newName;
+  }
+
+  @Override
+  public int compareTo(GroupReference o) {
+    return uuid(this).compareTo(uuid(o));
+  }
+
+  private static String uuid(GroupReference a) {
+    return a.getUUID() != null ? a.getUUID().get() : "?";
+  }
+
+  @Override
+  public int hashCode() {
+    return uuid(this).hashCode();
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    return o instanceof GroupReference && compareTo((GroupReference) o) == 0;
+  }
+
+  @Override
+  public String toString() {
+    return "Group[" + getName() + " / " + getUUID() + "]";
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
index 66b0c3b..c3d3f1e 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/HostPageData.java
@@ -14,13 +14,14 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AccountDiffPreference;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference;
 
 /** Data sent as part of the host page, to bootstrap the UI. */
 public class HostPageData {
   public Account account;
   public AccountDiffPreference accountDiffPref;
+  public String xsrfToken;
   public GerritConfig config;
   public Theme theme;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java
deleted file mode 100644
index 4dc998b..0000000
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/InheritedRefRight.java
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (C) 2010 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.common.data;
-
-import com.google.gerrit.reviewdb.RefRight;
-
-/**
- * Additional data about a {@link RefRight} not normally loaded: defines if a
- * right is inherited from a parent structure (e.g. a parent project).
- */
-public class InheritedRefRight {
-  private RefRight right;
-  private boolean inherited;
-  private boolean owner;
-
-  /**
-   * Creates a instance of a {@link RefRight} with data about inheritance
-   */
-  protected InheritedRefRight() {
-  }
-
-  /**
-   * Creates a instance of a {@link RefRight} with data about inheritance
-   *
-   * @param right the right
-   * @param inherited true if the right is inherited, false otherwise
-   * @param owner true if right is owned by current user, false otherwise
-   */
-  public InheritedRefRight(RefRight right, boolean inherited, boolean owner) {
-    this.right = right;
-    this.inherited = inherited;
-    this.owner = owner;
-  }
-
-  public RefRight getRight() {
-    return right;
-  }
-
-  public boolean isInherited() {
-    return inherited;
-  }
-
-  public boolean isOwner() {
-    return owner;
-  }
-
-  @Override
-  public boolean equals(Object o) {
-    if (o instanceof InheritedRefRight) {
-      InheritedRefRight a = this;
-      InheritedRefRight b = (InheritedRefRight) o;
-      return a.getRight().equals(b.getRight())
-          && a.isInherited() == b.isInherited();
-    }
-    return false;
-  }
-
-  @Override
-  public int hashCode() {
-    return getRight().hashCode();
-  }
-}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java
index 7341c47..1c830e9 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ListBranchesResult.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Branch;
+import com.google.gerrit.reviewdb.client.Branch;
 
 import java.util.List;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ParamertizedString.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
similarity index 81%
rename from gerrit-common/src/main/java/com/google/gerrit/common/data/ParamertizedString.java
rename to gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
index ae696b5..68676cf 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ParamertizedString.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ParameterizedString.java
@@ -21,10 +21,10 @@
 import java.util.Map;
 
 /** Performs replacements on strings such as <code>Hello ${user}</code>. */
-public class ParamertizedString {
+public class ParameterizedString {
   /** Obtain a string which has no parameters and always produces the value. */
-  public static ParamertizedString asis(final String constant) {
-    return new ParamertizedString(new Constant(constant));
+  public static ParameterizedString asis(final String constant) {
+    return new ParameterizedString(new Constant(constant));
   }
 
   private final String pattern;
@@ -32,18 +32,18 @@
   private final List<Format> patternOps;
   private final List<Parameter> parameters;
 
-  protected ParamertizedString() {
+  protected ParameterizedString() {
     this(new Constant(""));
   }
 
-  private ParamertizedString(final Constant c) {
+  private ParameterizedString(final Constant c) {
     pattern = c.text;
     rawPattern = c.text;
     patternOps = Collections.<Format> singletonList(c);
     parameters = Collections.emptyList();
   }
 
-  public ParamertizedString(final String pattern) {
+  public ParameterizedString(final String pattern) {
     final StringBuilder raw = new StringBuilder();
     final List<Parameter> prs = new ArrayList<Parameter>(4);
     final List<Format> ops = new ArrayList<Format>(4);
@@ -63,20 +63,27 @@
       ops.add(new Constant(pattern.substring(i, b)));
 
       String expr = pattern.substring(b + 2, e);
-      Function function;
-      int lastDot = expr.lastIndexOf('.');
-      if (lastDot < 0) {
-        function = NOOP;
+      String parameterName = "";
+      List<Function> functions = new ArrayList<Function>();
+      if (!expr.contains(".")) {
+        parameterName = expr;
       } else {
-        function = FUNCTIONS.get(expr.substring(lastDot + 1));
-        if (function == null) {
-          function = NOOP;
-        } else {
-          expr = expr.substring(0, lastDot);
+        int firstDot = expr.indexOf('.');
+        parameterName = expr.substring(0, firstDot);
+        String actionsStr = expr.substring(firstDot + 1);
+        String[] actions = actionsStr.split("\\.");
+
+        for (String action : actions) {
+          Function function = FUNCTIONS.get(action);
+          if (function == null) {
+            function = NOOP;
+          }
+          functions.add(function);
         }
       }
 
-      final Parameter p = new Parameter(expr, function);
+      final Parameter p =
+          new Parameter(parameterName, Collections.unmodifiableList(functions));
       raw.append("{" + prs.size() + "}");
       prs.add(p);
       ops.add(p);
@@ -152,7 +159,7 @@
 
     @Override
     public String toString() {
-      return ParamertizedString.this.replace(params);
+      return ParameterizedString.this.replace(params);
     }
   }
 
@@ -175,11 +182,11 @@
 
   private static class Parameter extends Format {
     private final String name;
-    private final Function function;
+    private final List<Function> functions;
 
-    Parameter(final String name, final Function function) {
+    Parameter(final String name, final List<Function> functions) {
       this.name = name;
-      this.function = function;
+      this.functions = functions;
     }
 
     @Override
@@ -188,7 +195,10 @@
       if (v == null) {
         v = "";
       }
-      b.append(function.apply(v));
+      for (Function function : functions) {
+        v = function.apply(v);
+      }
+      b.append(v);
     }
   }
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
index 5aec0c7..0191544 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchDetailService.java
@@ -15,19 +15,19 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AccountDiffPreference;
-import com.google.gerrit.reviewdb.ApprovalCategoryValue;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.Patch;
-import com.google.gerrit.reviewdb.PatchLineComment;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gerrit.reviewdb.Patch.Key;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference;
+import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchLineComment;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.Patch.Key;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 import java.util.Set;
@@ -44,13 +44,29 @@
   @SignInRequired
   void deleteDraft(PatchLineComment.Key key, AsyncCallback<VoidResult> callback);
 
+  /**
+   * Deletes the specified draft patch set. If the draft patch set is the only
+   * patch set of the change, then also the change gets deleted.
+   *
+   * @param psid ID of the draft patch set that should be deleted
+   * @param callback callback to report the result of the draft patch set
+   *        deletion operation; if the draft patch set was successfully deleted
+   *        {@link AsyncCallback#onSuccess(Object)} is invoked and the change
+   *        details are passed as parameter; if the change gets deleted because
+   *        the draft patch set that was deleted was the only patch set in the
+   *        change, then <code>null</code> is passed as result to
+   *        {@link AsyncCallback#onSuccess(Object)}
+   */
+  @SignInRequired
+  void deleteDraftPatchSet(PatchSet.Id psid, AsyncCallback<ChangeDetail> callback);
+
   @SignInRequired
   void publishComments(PatchSet.Id psid, String message,
       Set<ApprovalCategoryValue.Id> approvals,
       AsyncCallback<VoidResult> callback);
 
   @SignInRequired
-  void addReviewers(Change.Id id, List<String> reviewers,
+  void addReviewers(Change.Id id, List<String> reviewers, boolean confirmed,
       AsyncCallback<ReviewerResult> callback);
 
   @SignInRequired
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchScript.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchScript.java
index 24cdee4..2308b77 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchScript.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchScript.java
@@ -14,16 +14,13 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.prettify.client.ClientSideFormatter;
 import com.google.gerrit.prettify.common.EditList;
-import com.google.gerrit.prettify.common.PrettyFormatter;
 import com.google.gerrit.prettify.common.SparseFileContent;
-import com.google.gerrit.prettify.common.SparseHtmlFile;
-import com.google.gerrit.reviewdb.AccountDiffPreference;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.Patch;
-import com.google.gerrit.reviewdb.AccountDiffPreference.Whitespace;
-import com.google.gerrit.reviewdb.Patch.ChangeType;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference;
+import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.Patch.ChangeType;
 
 import org.eclipse.jgit.diff.Edit;
 
@@ -155,6 +152,10 @@
     return intralineFailure;
   }
 
+  public boolean isExpandAllComments() {
+    return diffPrefs.isExpandAllComments();
+  }
+
   public SparseFileContent getA() {
     return a;
   }
@@ -163,36 +164,6 @@
     return b;
   }
 
-  public SparseHtmlFile getSparseHtmlFileA() {
-    AccountDiffPreference dp = new AccountDiffPreference(diffPrefs);
-    dp.setShowWhitespaceErrors(false);
-
-    PrettyFormatter f = ClientSideFormatter.FACTORY.get();
-    f.setDiffPrefs(dp);
-    f.setFileName(a.getPath());
-    f.setEditFilter(PrettyFormatter.A);
-    f.setEditList(edits);
-    f.format(a);
-    return f;
-  }
-
-  public SparseHtmlFile getSparseHtmlFileB() {
-    AccountDiffPreference dp = new AccountDiffPreference(diffPrefs);
-
-    PrettyFormatter f = ClientSideFormatter.FACTORY.get();
-    f.setDiffPrefs(dp);
-    f.setFileName(b.getPath());
-    f.setEditFilter(PrettyFormatter.B);
-    f.setEditList(edits);
-
-    if (dp.isSyntaxHighlighting() && a.isWholeFile() && !b.isWholeFile()) {
-      f.format(b.apply(a, edits));
-    } else {
-      f.format(b);
-    }
-    return f;
-  }
-
   public List<Edit> getEdits() {
     return edits;
   }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetDetail.java
index 64e666e..a2debf2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetDetail.java
@@ -14,9 +14,9 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Patch;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gerrit.reviewdb.PatchSetInfo;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.PatchSetInfo;
 
 import java.util.List;
 
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetPublishDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetPublishDetail.java
index 7a0ada3..075d558 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetPublishDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PatchSetPublishDetail.java
@@ -14,40 +14,36 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.ApprovalCategoryValue;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.PatchLineComment;
-import com.google.gerrit.reviewdb.PatchSetApproval;
-import com.google.gerrit.reviewdb.PatchSetInfo;
+import com.google.gerrit.reviewdb.client.ApprovalCategory;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.PatchLineComment;
+import com.google.gerrit.reviewdb.client.PatchSetApproval;
+import com.google.gerrit.reviewdb.client.PatchSetInfo;
 
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 public class PatchSetPublishDetail {
   protected AccountInfoCache accounts;
   protected PatchSetInfo patchSetInfo;
   protected Change change;
   protected List<PatchLineComment> drafts;
-  protected Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> allowed;
-  protected Map<ApprovalCategory.Id, PatchSetApproval> given;
-  protected boolean isSubmitAllowed;
+  protected List<PermissionRange> labels;
+  protected List<PatchSetApproval> given;
+  protected boolean canSubmit;
 
-  public Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> getAllowed() {
-    return allowed;
+  public List<PermissionRange> getLabels() {
+    return labels;
   }
 
-  public void setAllowed(
-      Map<ApprovalCategory.Id, Set<ApprovalCategoryValue.Id>> allowed) {
-    this.allowed = allowed;
+  public void setLabels(List<PermissionRange> labels) {
+    this.labels = labels;
   }
 
-  public Map<ApprovalCategory.Id, PatchSetApproval> getGiven() {
+  public List<PatchSetApproval> getGiven() {
     return given;
   }
 
-  public void setGiven(Map<ApprovalCategory.Id, PatchSetApproval> given) {
+  public void setGiven(List<PatchSetApproval> given) {
     this.given = given;
   }
 
@@ -67,8 +63,8 @@
     this.drafts = drafts;
   }
 
-  public void setSubmitAllowed(boolean allowed) {
-    isSubmitAllowed = allowed;
+  public void setCanSubmit(boolean allowed) {
+    canSubmit = allowed;
   }
 
   public AccountInfoCache getAccounts() {
@@ -87,20 +83,25 @@
     return drafts;
   }
 
-  public boolean isAllowed(final ApprovalCategory.Id id) {
-    final Set<ApprovalCategoryValue.Id> s = getAllowed(id);
-    return s != null && !s.isEmpty();
+  public PermissionRange getRange(final String permissionName) {
+    for (PermissionRange s : labels) {
+      if (s.getName().equals(permissionName)) {
+        return s;
+      }
+    }
+    return null;
   }
 
-  public Set<ApprovalCategoryValue.Id> getAllowed(final ApprovalCategory.Id id) {
-    return allowed.get(id);
+  public PatchSetApproval getChangeApproval(ApprovalCategory.Id id) {
+    for (PatchSetApproval a : given) {
+      if (a.getCategoryId().equals(id)) {
+        return a;
+      }
+    }
+    return null;
   }
 
-  public PatchSetApproval getChangeApproval(final ApprovalCategory.Id id) {
-    return given.get(id);
-  }
-
-  public boolean isSubmitAllowed() {
-    return isSubmitAllowed;
+  public boolean canSubmit() {
+    return canSubmit;
   }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java
new file mode 100644
index 0000000..20261de
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/Permission.java
@@ -0,0 +1,211 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/** A single permission within an {@link AccessSection} of a project. */
+public class Permission implements Comparable<Permission> {
+  public static final String CREATE = "create";
+  public static final String FORGE_AUTHOR = "forgeAuthor";
+  public static final String FORGE_COMMITTER = "forgeCommitter";
+  public static final String FORGE_SERVER = "forgeServerAsCommitter";
+  public static final String LABEL = "label-";
+  public static final String OWNER = "owner";
+  public static final String PUSH = "push";
+  public static final String PUSH_MERGE = "pushMerge";
+  public static final String PUSH_TAG = "pushTag";
+  public static final String READ = "read";
+  public static final String REBASE = "rebase";
+  public static final String SUBMIT = "submit";
+
+  private static final List<String> NAMES_LC;
+  private static final int labelIndex;
+
+  static {
+    NAMES_LC = new ArrayList<String>();
+    NAMES_LC.add(OWNER.toLowerCase());
+    NAMES_LC.add(READ.toLowerCase());
+    NAMES_LC.add(CREATE.toLowerCase());
+    NAMES_LC.add(FORGE_AUTHOR.toLowerCase());
+    NAMES_LC.add(FORGE_COMMITTER.toLowerCase());
+    NAMES_LC.add(FORGE_SERVER.toLowerCase());
+    NAMES_LC.add(PUSH.toLowerCase());
+    NAMES_LC.add(PUSH_MERGE.toLowerCase());
+    NAMES_LC.add(PUSH_TAG.toLowerCase());
+    NAMES_LC.add(LABEL.toLowerCase());
+    NAMES_LC.add(REBASE.toLowerCase());
+    NAMES_LC.add(SUBMIT.toLowerCase());
+
+    labelIndex = NAMES_LC.indexOf(Permission.LABEL);
+  }
+
+  /** @return true if the name is recognized as a permission name. */
+  public static boolean isPermission(String varName) {
+    String lc = varName.toLowerCase();
+    if (lc.startsWith(LABEL)) {
+      return LABEL.length() < lc.length();
+    }
+    return NAMES_LC.contains(lc);
+  }
+
+  /** @return true if the permission name is actually for a review label. */
+  public static boolean isLabel(String varName) {
+    return varName.startsWith(LABEL) && LABEL.length() < varName.length();
+  }
+
+  /** @return permission name for the given review label. */
+  public static String forLabel(String labelName) {
+    return LABEL + labelName;
+  }
+
+  protected String name;
+  protected boolean exclusiveGroup;
+  protected List<PermissionRule> rules;
+
+  protected Permission() {
+  }
+
+  public Permission(String name) {
+    this.name = name;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public boolean isLabel() {
+    return isLabel(getName());
+  }
+
+  public String getLabel() {
+    if (isLabel()) {
+      return getName().substring(LABEL.length());
+    }
+    return null;
+  }
+
+  public Boolean getExclusiveGroup() {
+    // Only permit exclusive group behavior on non OWNER permissions,
+    // otherwise an owner might lose access to a delegated subspace.
+    //
+    return exclusiveGroup && !OWNER.equals(getName());
+  }
+
+  public void setExclusiveGroup(Boolean newExclusiveGroup) {
+    exclusiveGroup = newExclusiveGroup;
+  }
+
+  public List<PermissionRule> getRules() {
+    initRules();
+    return rules;
+  }
+
+  public void setRules(List<PermissionRule> list) {
+    rules = list;
+  }
+
+  public void add(PermissionRule rule) {
+    initRules();
+    rules.add(rule);
+  }
+
+  public void remove(PermissionRule rule) {
+    if (rule != null) {
+      removeRule(rule.getGroup());
+    }
+  }
+
+  public void removeRule(GroupReference group) {
+    if (rules != null) {
+      for (Iterator<PermissionRule> itr = rules.iterator(); itr.hasNext();) {
+        if (sameGroup(itr.next(), group)) {
+          itr.remove();
+        }
+      }
+    }
+  }
+
+  public PermissionRule getRule(GroupReference group) {
+    return getRule(group, false);
+  }
+
+  public PermissionRule getRule(GroupReference group, boolean create) {
+    initRules();
+
+    for (PermissionRule r : rules) {
+      if (sameGroup(r, group)) {
+        return r;
+      }
+    }
+
+    if (create) {
+      PermissionRule r = new PermissionRule(group);
+      rules.add(r);
+      return r;
+    } else {
+      return null;
+    }
+  }
+
+  void mergeFrom(Permission src) {
+    for (PermissionRule srcRule : src.getRules()) {
+      PermissionRule dstRule = getRule(srcRule.getGroup());
+      if (dstRule != null) {
+        dstRule.mergeFrom(srcRule);
+      } else {
+        add(srcRule);
+      }
+    }
+  }
+
+  private static boolean sameGroup(PermissionRule rule, GroupReference group) {
+    if (group.getUUID() != null) {
+      return group.getUUID().equals(rule.getGroup().getUUID());
+
+    } else if (group.getName() != null) {
+      return group.getName().equals(rule.getGroup().getName());
+
+    } else {
+      return false;
+    }
+  }
+
+  private void initRules() {
+    if (rules == null) {
+      rules = new ArrayList<PermissionRule>(4);
+    }
+  }
+
+  @Override
+  public int compareTo(Permission b) {
+    int cmp = index(this) - index(b);
+    if (cmp == 0) {
+      cmp = getName().compareTo(b.getName());
+    }
+    return cmp;
+  }
+
+  private static int index(Permission a) {
+    if (a.isLabel()) {
+      return labelIndex;
+    }
+
+    int index = NAMES_LC.indexOf(a.getName().toLowerCase());
+    return 0 <= index ? index : NAMES_LC.size();
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRange.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRange.java
new file mode 100644
index 0000000..3490dd7
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRange.java
@@ -0,0 +1,138 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PermissionRange implements Comparable<PermissionRange> {
+  public static class WithDefaults extends PermissionRange {
+    protected int defaultMin;
+    protected int defaultMax;
+
+    protected WithDefaults() {
+    }
+
+    public WithDefaults(String name, int min, int max, int defMin, int defMax) {
+      super(name, min, max);
+      setDefaultRange(defMin, defMax);
+    }
+
+    public int getDefaultMin() {
+      return defaultMin;
+    }
+
+    public int getDefaultMax() {
+      return defaultMax;
+    }
+
+    public void setDefaultRange(int min, int max) {
+      defaultMin = min;
+      defaultMax = max;
+    }
+
+    /** @return all values between {@link #getMin()} and {@link #getMax()} */
+    public List<Integer> getValuesAsList() {
+      ArrayList<Integer> r = new ArrayList<Integer>(getRangeSize());
+      for (int i = min; i <= max; i++) {
+        r.add(i);
+      }
+      return r;
+    }
+
+    /** @return number of values between {@link #getMin()} and {@link #getMax()} */
+    public int getRangeSize() {
+      return max - min;
+    }
+  }
+
+  protected String name;
+  protected int min;
+  protected int max;
+
+  protected PermissionRange() {
+  }
+
+  public PermissionRange(String name, int min, int max) {
+    this.name = name;
+
+    if (min <= max) {
+      this.min = min;
+      this.max = max;
+    } else {
+      this.min = max;
+      this.max = min;
+    }
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public boolean isLabel() {
+    return Permission.isLabel(getName());
+  }
+
+  public String getLabel() {
+    return isLabel() ? getName().substring(Permission.LABEL.length()) : null;
+  }
+
+  public int getMin() {
+    return min;
+  }
+
+  public int getMax() {
+    return max;
+  }
+
+  /** True if the value is within the range. */
+  public boolean contains(int value) {
+    return getMin() <= value && value <= getMax();
+  }
+
+  /** Normalize the value to fit within the bounds of the range. */
+  public int squash(int value) {
+    return Math.min(Math.max(getMin(), value), getMax());
+  }
+
+  /** True both {@link #getMin()} and {@link #getMax()} are 0. */
+  public boolean isEmpty() {
+    return getMin() == 0 && getMax() == 0;
+  }
+
+  @Override
+  public int compareTo(PermissionRange o) {
+    return getName().compareTo(o.getName());
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder r = new StringBuilder();
+    if (getMin() < 0 && getMax() == 0) {
+      r.append(getMin());
+      r.append(' ');
+    } else {
+      if (getMin() != getMax()) {
+        if (0 <= getMin()) r.append('+');
+        r.append(getMin());
+        r.append("..");
+      }
+      if (0 <= getMax()) r.append('+');
+      r.append(getMax());
+      r.append(' ');
+    }
+    return r.toString();
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRule.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRule.java
new file mode 100644
index 0000000..9b6695e
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/PermissionRule.java
@@ -0,0 +1,260 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+public class PermissionRule implements Comparable<PermissionRule> {
+  public static final String FORCE_PUSH = "Force Push";
+  public static enum Action {
+    ALLOW, DENY, BLOCK,
+
+    INTERACTIVE, BATCH;
+  }
+
+  protected Action action = Action.ALLOW;
+  protected boolean force;
+  protected int min;
+  protected int max;
+  protected GroupReference group;
+
+  public PermissionRule() {
+  }
+
+  public PermissionRule(GroupReference group) {
+    this.group = group;
+  }
+
+  public Action getAction() {
+    return action;
+  }
+
+  public void setAction(Action action) {
+    if (action == null) {
+      throw new NullPointerException("action");
+    }
+    this.action = action;
+  }
+
+  public boolean isDeny() {
+    return action == Action.DENY;
+  }
+
+  public void setDeny() {
+    action = Action.DENY;
+  }
+
+  public boolean isBlock() {
+    return action == Action.BLOCK;
+  }
+
+  public void setBlock() {
+    action = Action.BLOCK;
+  }
+
+  public Boolean getForce() {
+    return force;
+  }
+
+  public void setForce(Boolean newForce) {
+    force = newForce;
+  }
+
+  public Integer getMin() {
+    return min;
+  }
+
+  public void setMin(Integer min) {
+    this.min = min;
+  }
+
+  public void setMax(Integer max) {
+    this.max = max;
+  }
+
+  public Integer getMax() {
+    return max;
+  }
+
+  public void setRange(int newMin, int newMax) {
+    if (newMax < newMin) {
+      min = newMax;
+      max = newMin;
+    } else {
+      min = newMin;
+      max = newMax;
+    }
+  }
+
+  public GroupReference getGroup() {
+    return group;
+  }
+
+  public void setGroup(GroupReference newGroup) {
+    group = newGroup;
+  }
+
+  void mergeFrom(PermissionRule src) {
+    if (getAction() != src.getAction()) {
+      if (getAction() == Action.BLOCK || src.getAction() == Action.BLOCK) {
+        setAction(Action.BLOCK);
+
+      } else if (getAction() == Action.DENY || src.getAction() == Action.DENY) {
+        setAction(Action.DENY);
+
+      } else if (getAction() == Action.BATCH || src.getAction() == Action.BATCH) {
+        setAction(Action.BATCH);
+
+      }
+    }
+
+    setForce(getForce() || src.getForce());
+    setRange(Math.min(getMin(), src.getMin()), Math.max(getMax(), src.getMax()));
+  }
+
+  @Override
+  public int compareTo(PermissionRule o) {
+    int cmp = action(this) - action(o);
+    if (cmp == 0) cmp = range(o) - range(this);
+    if (cmp == 0) cmp = group(this).compareTo(group(o));
+    return cmp;
+  }
+
+  private static int action(PermissionRule a) {
+    switch (a.getAction()) {
+      case DENY:
+        return 0;
+      default:
+        return 1 + a.getAction().ordinal();
+    }
+  }
+
+  private static int range(PermissionRule a) {
+    return Math.abs(a.getMin()) + Math.abs(a.getMax());
+  }
+
+  private static String group(PermissionRule a) {
+    return a.getGroup().getName() != null ? a.getGroup().getName() : "";
+  }
+
+  @Override
+  public String toString() {
+    return asString(true);
+  }
+
+  public String asString(boolean canUseRange) {
+    StringBuilder r = new StringBuilder();
+
+    switch (getAction()) {
+      case ALLOW:
+        break;
+
+      case DENY:
+        r.append("deny ");
+        break;
+
+      case BLOCK:
+        r.append("block ");
+        break;
+
+      case INTERACTIVE:
+        r.append("interactive ");
+        break;
+
+      case BATCH:
+        r.append("batch ");
+        break;
+    }
+
+    if (getForce()) {
+      r.append("+force ");
+    }
+
+    if (canUseRange && (getMin() != 0 || getMax() != 0)) {
+      if (0 <= getMin()) r.append('+');
+      r.append(getMin());
+      r.append("..");
+      if (0 <= getMax()) r.append('+');
+      r.append(getMax());
+      r.append(' ');
+    }
+
+    r.append("group ");
+    r.append(getGroup().getName());
+
+    return r.toString();
+  }
+
+  public static PermissionRule fromString(String src, boolean mightUseRange) {
+    final String orig = src;
+    final PermissionRule rule = new PermissionRule();
+
+    src = src.trim();
+
+    if (src.startsWith("deny ")) {
+      rule.setAction(Action.DENY);
+      src = src.substring("deny ".length()).trim();
+
+    } else if (src.startsWith("block ")) {
+      rule.setAction(Action.BLOCK);
+      src = src.substring("block ".length()).trim();
+
+    } else if (src.startsWith("interactive ")) {
+      rule.setAction(Action.INTERACTIVE);
+      src = src.substring("interactive ".length()).trim();
+
+    } else if (src.startsWith("batch ")) {
+      rule.setAction(Action.BATCH);
+      src = src.substring("batch ".length()).trim();
+    }
+
+    if (src.startsWith("+force ")) {
+      rule.setForce(true);
+      src = src.substring("+force ".length()).trim();
+    }
+
+    if (mightUseRange && !src.startsWith("group ")) {
+      int sp = src.indexOf(' ');
+      String range = src.substring(0, sp);
+
+      if (range.matches("^([+-]?\\d+)\\.\\.([+-]?\\d+)$")) {
+        int dotdot = range.indexOf("..");
+        int min = parseInt(range.substring(0, dotdot));
+        int max = parseInt(range.substring(dotdot + 2));
+        rule.setRange(min, max);
+      } else {
+        throw new IllegalArgumentException("Invalid range in rule: " + orig);
+      }
+
+      src = src.substring(sp + 1).trim();
+    }
+
+    if (src.startsWith("group ")) {
+      src = src.substring(6).trim();
+      GroupReference group = new GroupReference();
+      group.setName(src);
+      rule.setGroup(group);
+    } else {
+      throw new IllegalArgumentException("Rule must include group: " + orig);
+    }
+
+    return rule;
+  }
+
+  private static int parseInt(String value) {
+    if (value.startsWith("+")) {
+      value = value.substring(1);
+    }
+    return Integer.parseInt(value);
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAccess.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAccess.java
new file mode 100644
index 0000000..f935c03
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAccess.java
@@ -0,0 +1,97 @@
+// Copyright (C) 2011 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.common.data;
+
+import com.google.gerrit.reviewdb.client.Project;
+
+import java.util.List;
+import java.util.Set;
+
+public class ProjectAccess {
+  protected Project.NameKey projectName;
+  protected String revision;
+  protected Project.NameKey inheritsFrom;
+  protected List<AccessSection> local;
+  protected Set<String> ownerOf;
+  protected boolean isConfigVisible;
+
+  public ProjectAccess() {
+  }
+
+  public Project.NameKey getProjectName() {
+    return projectName;
+  }
+
+  public void setProjectName(Project.NameKey projectName) {
+    this.projectName = projectName;
+  }
+
+  public String getRevision() {
+    return revision;
+  }
+
+  public void setRevision(String name) {
+    revision = name;
+  }
+
+  public Project.NameKey getInheritsFrom() {
+    return inheritsFrom;
+  }
+
+  public void setInheritsFrom(Project.NameKey name) {
+    inheritsFrom = name;
+  }
+
+  public List<AccessSection> getLocal() {
+    return local;
+  }
+
+  public void setLocal(List<AccessSection> as) {
+    local = as;
+  }
+
+  public AccessSection getLocal(String name) {
+    for (AccessSection s : local) {
+      if (s.getName().equals(name)) {
+        return s;
+      }
+    }
+    return null;
+  }
+
+  public boolean isOwnerOf(AccessSection section) {
+    return isOwnerOf(section.getName());
+  }
+
+  public boolean isOwnerOf(String name) {
+    return ownerOf.contains(name);
+  }
+
+  public Set<String> getOwnerOf() {
+    return ownerOf;
+  }
+
+  public void setOwnerOf(Set<String> refs) {
+    ownerOf = refs;
+  }
+
+  public boolean isConfigVisible() {
+    return isConfigVisible;
+  }
+
+  public void setConfigVisible(boolean isConfigVisible) {
+    this.isConfigVisible = isConfigVisible;
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
index b5a986f..1b504b0 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectAdminService.java
@@ -15,37 +15,43 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.ApprovalCategory;
-import com.google.gerrit.reviewdb.Branch;
-import com.google.gerrit.reviewdb.Project;
-import com.google.gerrit.reviewdb.RefRight;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.Branch;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 import java.util.Set;
 
 @RpcImpl(version = Version.V2_0)
 public interface ProjectAdminService extends RemoteJsonService {
-  void visibleProjects(AsyncCallback<List<Project>> callback);
+  void visibleProjects(AsyncCallback<ProjectList> callback);
+
+  void visibleProjectDetails(AsyncCallback<List<ProjectDetail>> callback);
+  void suggestParentCandidates(AsyncCallback<List<Project>> callback);
 
   void projectDetail(Project.NameKey projectName,
       AsyncCallback<ProjectDetail> callback);
 
   @SignInRequired
+  void createNewProject(String projectName, String parentName,
+      boolean emptyCommit, boolean permissionsOnly,
+      AsyncCallback<VoidResult> callback);
+
+  void projectAccess(Project.NameKey projectName,
+      AsyncCallback<ProjectAccess> callback);
+
+  @SignInRequired
   void changeProjectSettings(Project update,
       AsyncCallback<ProjectDetail> callback);
 
   @SignInRequired
-  void deleteRight(Project.NameKey projectName, Set<RefRight.Key> ids,
-      AsyncCallback<ProjectDetail> callback);
-
-  @SignInRequired
-  void addRight(Project.NameKey projectName, ApprovalCategory.Id categoryId,
-      String groupName, String refName, short min, short max,
-      AsyncCallback<ProjectDetail> callback);
+  void changeProjectAccess(Project.NameKey projectName, String baseRevision,
+      String message, List<AccessSection> sections,
+      AsyncCallback<ProjectAccess> callback);
 
   void listBranches(Project.NameKey projectName,
       AsyncCallback<ListBranchesResult> callback);
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
index 2aa8c62..1d88cf8 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectDetail.java
@@ -14,20 +14,16 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.Project;
-
-import java.util.List;
-import java.util.Map;
+import com.google.gerrit.reviewdb.client.Project;
 
 public class ProjectDetail {
   public Project project;
-  public Map<AccountGroup.Id, AccountGroup> groups;
-  public List<InheritedRefRight> rights;
   public boolean canModifyDescription;
   public boolean canModifyMergeType;
   public boolean canModifyAgreements;
   public boolean canModifyAccess;
+  public boolean canModifyState;
+  public boolean isPermissionOnly;
 
   public ProjectDetail() {
   }
@@ -36,14 +32,6 @@
     project = p;
   }
 
-  public void setGroups(final Map<AccountGroup.Id, AccountGroup> g) {
-    groups = g;
-  }
-
-  public void setRights(final List<InheritedRefRight> r) {
-    rights = r;
-  }
-
   public void setCanModifyDescription(final boolean cmd) {
     canModifyDescription = cmd;
   }
@@ -52,6 +40,10 @@
     canModifyMergeType = cmmt;
   }
 
+  public void setCanModifyState(final boolean cms) {
+    canModifyState = cms;
+  }
+
   public void setCanModifyAgreements(final boolean cma) {
     canModifyAgreements = cma;
   }
@@ -59,4 +51,8 @@
   public void setCanModifyAccess(final boolean cma) {
     canModifyAccess = cma;
   }
+
+  public void setPermissionOnly(final boolean ipo) {
+    isPermissionOnly = ipo;
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectInfo.java
index 8f22936..dfef806 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectInfo.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectInfo.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.reviewdb.client.Project;
 
 public class ProjectInfo {
   protected Project.NameKey key;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectList.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectList.java
new file mode 100644
index 0000000..8511460
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ProjectList.java
@@ -0,0 +1,43 @@
+// Copyright (C) 2011 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.common.data;
+
+import com.google.gerrit.reviewdb.client.Project;
+
+import java.util.List;
+
+public class ProjectList {
+  protected List<Project> projects;
+  protected boolean canCreateProject;
+
+  public ProjectList() {
+  }
+
+  public List<Project> getProjects() {
+    return projects;
+  }
+
+  public void setProjects(List<Project> projects) {
+    this.projects = projects;
+  }
+
+  public boolean canCreateProject() {
+    return canCreateProject;
+  }
+
+  public void setCanCreateProject(boolean canCreateProject) {
+    this.canCreateProject = canCreateProject;
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/RefConfigSection.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/RefConfigSection.java
new file mode 100644
index 0000000..490378e
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/RefConfigSection.java
@@ -0,0 +1,48 @@
+// Copyright (C) 2011 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.common.data;
+
+public abstract class RefConfigSection {
+  /** Pattern that matches all references in a project. */
+  public static final String ALL = "refs/*";
+
+  /** Pattern that matches all branches in a project. */
+  public static final String HEADS = "refs/heads/*";
+
+  /** Prefix that triggers a regular expression pattern. */
+  public static final String REGEX_PREFIX = "^";
+
+  /** @return true if the name is likely to be a valid reference section name. */
+  public static boolean isValid(String name) {
+    return name.startsWith("refs/") || name.startsWith("^refs/");
+  }
+
+  protected String name;
+
+  public RefConfigSection() {
+  }
+
+  public RefConfigSection(String name) {
+    setName(name);
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewResult.java
new file mode 100644
index 0000000..001f9b4
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewResult.java
@@ -0,0 +1,122 @@
+// Copyright (C) 2011 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.common.data;
+
+import com.google.gerrit.reviewdb.client.Change;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Result from performing a review (comment, abandon, etc.)
+ */
+public class ReviewResult {
+  protected List<Error> errors;
+  protected Change.Id changeId;
+
+  public ReviewResult() {
+    errors = new ArrayList<Error>();
+  }
+
+  public void addError(final Error e) {
+    errors.add(e);
+  }
+
+  public List<Error> getErrors() {
+    return errors;
+  }
+
+  public Change.Id getChangeId() {
+    return changeId;
+  }
+
+  public void setChangeId(Change.Id changeId) {
+    this.changeId = changeId;
+  }
+
+  public static class Error {
+    public static enum Type {
+      /** Not permitted to abandon this change. */
+      ABANDON_NOT_PERMITTED,
+
+      /** Not permitted to restore this change. */
+      RESTORE_NOT_PERMITTED,
+
+      /** Not permitted to submit this change. */
+      SUBMIT_NOT_PERMITTED,
+
+      /** Approvals or dependencies are lacking for submission. */
+      SUBMIT_NOT_READY,
+
+      /** Review operation invalid because change is closed. */
+      CHANGE_IS_CLOSED,
+
+      /** Not permitted to publish this draft patch set */
+      PUBLISH_NOT_PERMITTED,
+
+      /** Not permitted to delete this draft patch set */
+      DELETE_NOT_PERMITTED,
+
+      /** Review operation not permitted by rule. */
+      RULE_ERROR,
+
+      /** Review operation invalid because patch set is not a draft. */
+      NOT_A_DRAFT,
+
+      /** Error writing change to git repository */
+      GIT_ERROR
+    }
+
+    protected Type type;
+    protected String message;
+
+    protected Error() {
+    }
+
+    public Error(final Type type) {
+      this.type = type;
+      this.message = null;
+    }
+
+    public Error(final Type type, final String message) {
+      this.type = type;
+      this.message = message;
+    }
+
+    public Type getType() {
+      return type;
+    }
+
+    public String getMessage() {
+      return message;
+    }
+
+    public String getMessageOrType() {
+      if (message != null) {
+        return message;
+      }
+      return "" + type;
+    }
+
+    @Override
+    public String toString() {
+      String ret = type + "";
+      if (message != null) {
+        ret += " " + message;
+      }
+      return ret;
+    }
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerInfo.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerInfo.java
new file mode 100644
index 0000000..063f13b
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerInfo.java
@@ -0,0 +1,58 @@
+// Copyright (C) 2011 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.common.data;
+
+/**
+ * Suggested reviewer for a change. Can be a user ({@link AccountInfo}) or a
+ * group ({@link GroupReference}).
+ */
+public class ReviewerInfo implements Comparable<ReviewerInfo> {
+  private AccountInfo accountInfo;
+  private GroupReference groupReference;
+
+  protected ReviewerInfo() {
+  }
+
+  public ReviewerInfo(final AccountInfo accountInfo) {
+    this.accountInfo = accountInfo;
+  }
+
+  public ReviewerInfo(final GroupReference groupReference) {
+    this.groupReference = groupReference;
+  }
+
+  public AccountInfo getAccountInfo() {
+    return accountInfo;
+  }
+
+  public GroupReference getGroup() {
+    return groupReference;
+  }
+
+  @Override
+  public int compareTo(final ReviewerInfo o) {
+    return getSortValue().compareTo(o.getSortValue());
+  }
+
+  private String getSortValue() {
+    if (accountInfo != null) {
+      if (accountInfo.getPreferredEmail() != null) {
+        return accountInfo.getPreferredEmail();
+      }
+      return accountInfo.getFullName().toString();
+    }
+    return groupReference.getName();
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
index 678ec79..d85095a 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ReviewerResult.java
@@ -24,6 +24,8 @@
 public class ReviewerResult {
   protected List<Error> errors;
   protected ChangeDetail change;
+  protected int memberCount;
+  protected boolean askForConfirmation;
 
   public ReviewerResult() {
     errors = new ArrayList<Error>();
@@ -45,10 +47,26 @@
     change = d;
   }
 
+  public int getMemberCount() {
+    return memberCount;
+  }
+
+  public void setMemberCount(final int memberCount) {
+    this.memberCount = memberCount;
+  }
+
+  public boolean askForConfirmation() {
+    return askForConfirmation;
+  }
+
+  public void setAskForConfirmation(final boolean askForConfirmation) {
+    this.askForConfirmation = askForConfirmation;
+  }
+
   public static class Error {
     public static enum Type {
-      /** Name supplied does not match to a registered account. */
-      ACCOUNT_NOT_FOUND,
+      /** Name supplied does not match to a registered account or account group. */
+      REVIEWER_NOT_FOUND,
 
       /** The account is inactive. */
       ACCOUNT_INACTIVE,
@@ -56,8 +74,20 @@
       /** The account is not permitted to see the change. */
       CHANGE_NOT_VISIBLE,
 
-      /** Could not remove this reviewer from the change. */
-      COULD_NOT_REMOVE
+      /** The groups has no members. */
+      GROUP_EMPTY,
+
+      /** The groups has too many members. */
+      GROUP_HAS_TOO_MANY_MEMBERS,
+
+      /** The group is not allowed to be added as reviewer. */
+      GROUP_NOT_ALLOWED,
+
+      /** Could not remove this reviewer from the change due to ORMException. */
+      COULD_NOT_REMOVE,
+
+      /** Not permitted to remove this reviewer from the change. */
+      REMOVE_NOT_PERMITTED
     }
 
     protected Type type;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/SubmitRecord.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/SubmitRecord.java
new file mode 100644
index 0000000..5049ba4
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/SubmitRecord.java
@@ -0,0 +1,82 @@
+// Copyright (C) 2011 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.common.data;
+
+import com.google.gerrit.reviewdb.client.Account;
+
+import java.util.List;
+
+/**
+ * Describes the state required to submit a change.
+ */
+public class SubmitRecord {
+  public static enum Status {
+    /** The change is ready for submission. */
+    OK,
+
+    /** The change is missing a required label. */
+    NOT_READY,
+
+    /** The change has been closed. */
+    CLOSED,
+
+    /**
+     * An internal server error occurred preventing computation.
+     * <p>
+     * Additional detail may be available in {@link SubmitRecord#errorMessage}.
+     */
+    RULE_ERROR;
+  }
+
+  public Status status;
+  public List<Label> labels;
+  public String errorMessage;
+
+  public static class Label {
+    public static enum Status {
+      /**
+       * This label provides what is necessary for submission.
+       * <p>
+       * If provided, {@link Label#appliedBy} describes the user account
+       * that applied this label to the change.
+       */
+      OK,
+
+      /**
+       * This label prevents the change from being submitted.
+       * <p>
+       * If provided, {@link Label#appliedBy} describes the user account
+       * that applied this label to the change.
+       */
+      REJECT,
+
+      /**
+       * The label is required for submission, but has not been satisfied.
+       */
+      NEED,
+
+      /**
+       * The label is required for submission, but is impossible to complete.
+       * The likely cause is access has not been granted correctly by the
+       * project owner or site administrator.
+       */
+      IMPOSSIBLE;
+    }
+
+    public String label;
+    public Status status;
+    public Account.Id appliedBy;
+  }
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
index 9dae169..85518b2 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/SuggestService.java
@@ -14,12 +14,13 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.AccountGroupName;
-import com.google.gerrit.reviewdb.Project;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 
@@ -32,5 +33,23 @@
       AsyncCallback<List<AccountInfo>> callback);
 
   void suggestAccountGroup(String query, int limit,
-      AsyncCallback<List<AccountGroupName>> callback);
+      AsyncCallback<List<GroupReference>> callback);
+
+  /**
+   * @see #suggestChangeReviewer(com.google.gerrit.reviewdb.client.Change.Id, String, int, AsyncCallback)
+   */
+  @Deprecated
+  void suggestReviewer(Project.NameKey project, String query, int limit,
+      AsyncCallback<List<ReviewerInfo>> callback);
+
+  /**
+   * Suggests reviewers. A reviewer can be a user or a group. Inactive users,
+   * the system groups {@link AccountGroup#ANONYMOUS_USERS} and
+   * {@link AccountGroup#REGISTERED_USERS} and groups that have more than the
+   * configured <code>addReviewer.maxAllowed</code> members are not suggested as
+   * reviewers.
+   * @param changeId the change for which reviewers should be suggested
+   */
+  void suggestChangeReviewer(Change.Id changeId, String query, int limit,
+      AsyncCallback<List<ReviewerInfo>> callback);
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/SystemInfoService.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/SystemInfoService.java
index 3c16018..78ccca1 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/SystemInfoService.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/SystemInfoService.java
@@ -15,13 +15,13 @@
 package com.google.gerrit.common.data;
 
 import com.google.gerrit.common.auth.SignInRequired;
-import com.google.gerrit.reviewdb.ContributorAgreement;
-import com.google.gwt.user.client.rpc.AsyncCallback;
-import com.google.gwtjsonrpc.client.AllowCrossSiteRequest;
-import com.google.gwtjsonrpc.client.RemoteJsonService;
-import com.google.gwtjsonrpc.client.RpcImpl;
-import com.google.gwtjsonrpc.client.VoidResult;
-import com.google.gwtjsonrpc.client.RpcImpl.Version;
+import com.google.gerrit.reviewdb.client.ContributorAgreement;
+import com.google.gwtjsonrpc.common.AsyncCallback;
+import com.google.gwtjsonrpc.common.AllowCrossSiteRequest;
+import com.google.gwtjsonrpc.common.RemoteJsonService;
+import com.google.gwtjsonrpc.common.RpcImpl;
+import com.google.gwtjsonrpc.common.VoidResult;
+import com.google.gwtjsonrpc.common.RpcImpl.Version;
 
 import java.util.List;
 
@@ -34,4 +34,6 @@
   void contributorAgreements(AsyncCallback<List<ContributorAgreement>> callback);
 
   void clientError(String message, AsyncCallback<VoidResult> callback);
+
+  public void gerritConfig(final AsyncCallback<GerritConfig> callback);
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/ToggleStarRequest.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/ToggleStarRequest.java
index 32178fb..c9ba72f 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/ToggleStarRequest.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/ToggleStarRequest.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.data;
 
-import com.google.gerrit.reviewdb.Change;
+import com.google.gerrit.reviewdb.client.Change;
 
 import java.util.HashSet;
 import java.util.Set;
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidNameException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidNameException.java
index 5eb6e3f..d975aef 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidNameException.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidNameException.java
@@ -23,4 +23,8 @@
   public InvalidNameException() {
     super(MESSAGE);
   }
+
+  public InvalidNameException(String invalidName) {
+    super(MESSAGE + ": " + invalidName);
+  }
 }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidQueryException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidQueryException.java
index 4a66a416a..53792e4 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidQueryException.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidQueryException.java
@@ -18,6 +18,10 @@
 public class InvalidQueryException extends Exception {
   private static final long serialVersionUID = 1L;
 
+  public InvalidQueryException(String message) {
+    super(message);
+  }
+
   public InvalidQueryException(String message, String query) {
     super("Invalid query: " + query + "\n\n" + message);
   }
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidUserNameException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidUserNameException.java
index 55d490c..f1c35a8 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidUserNameException.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/InvalidUserNameException.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.errors;
 
-import com.google.gerrit.reviewdb.Account;
+import com.google.gerrit.reviewdb.client.Account;
 
 /** Error indicating the SSH user name does not match {@link Account#USER_NAME_PATTERN} pattern. */
 public class InvalidUserNameException extends Exception {
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/NoSuchGroupException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/NoSuchGroupException.java
index 4e117b1..ade0d98 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/errors/NoSuchGroupException.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/NoSuchGroupException.java
@@ -14,7 +14,7 @@
 
 package com.google.gerrit.common.errors;
 
-import com.google.gerrit.reviewdb.AccountGroup;
+import com.google.gerrit.reviewdb.client.AccountGroup;
 
 /** Indicates the account group does not exist. */
 public class NoSuchGroupException extends Exception {
@@ -26,10 +26,18 @@
     this(key, null);
   }
 
+  public NoSuchGroupException(final AccountGroup.UUID key) {
+    this(key, null);
+  }
+
   public NoSuchGroupException(final AccountGroup.Id key, final Throwable why) {
     super(MESSAGE + key.toString(), why);
   }
 
+  public NoSuchGroupException(final AccountGroup.UUID key, final Throwable why) {
+    super(MESSAGE + key.toString(), why);
+  }
+
   public NoSuchGroupException(final AccountGroup.NameKey k) {
     this(k, null);
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_50.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/PermissionDeniedException.java
similarity index 69%
copy from gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_50.java
copy to gerrit-common/src/main/java/com/google/gerrit/common/errors/PermissionDeniedException.java
index 4a90c1f..76520aa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_50.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/PermissionDeniedException.java
@@ -12,14 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.schema;
+package com.google.gerrit.common.errors;
 
-import com.google.inject.Inject;
-import com.google.inject.Provider;
+/** Indicats the user cannot perform this task. */
+public class PermissionDeniedException extends Exception {
+  private static final long serialVersionUID = 1L;
 
-public class Schema_50 extends SchemaVersion {
-  @Inject
-  Schema_50(Provider<Schema_49> prior) {
-    super(prior);
+  public PermissionDeniedException(String msg) {
+    super(msg);
   }
-}
\ No newline at end of file
+}
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/errors/ProjectCreationFailedException.java b/gerrit-common/src/main/java/com/google/gerrit/common/errors/ProjectCreationFailedException.java
new file mode 100644
index 0000000..0437d77
--- /dev/null
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/errors/ProjectCreationFailedException.java
@@ -0,0 +1,29 @@
+// Copyright (C) 2011 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.common.errors;
+
+/** Error indicating failed to create new project. */
+public class ProjectCreationFailedException extends Exception {
+  private static final long serialVersionUID = 1L;
+
+  public ProjectCreationFailedException(final String message) {
+    this(message, null);
+  }
+
+  public ProjectCreationFailedException(final String message,
+      final Throwable why) {
+    super(message, why);
+  }
+}
diff --git a/gerrit-common/src/test/java/com/google/gerrit/common/data/EncodePathSeparatorTest.java b/gerrit-common/src/test/java/com/google/gerrit/common/data/EncodePathSeparatorTest.java
new file mode 100644
index 0000000..e00fa48
--- /dev/null
+++ b/gerrit-common/src/test/java/com/google/gerrit/common/data/EncodePathSeparatorTest.java
@@ -0,0 +1,36 @@
+// Copyright (C) 2011 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.common.data;
+
+import junit.framework.TestCase;
+
+public class EncodePathSeparatorTest extends TestCase {
+
+  public void testDefaultBehaviour() {
+
+    GitWebType gitWebType = GitWebType.fromName(null);
+
+    assertEquals("a/b", gitWebType.replacePathSeparator("a/b"));
+  }
+
+  public void testExclamationMark() {
+
+    GitWebType gitWebType = GitWebType.fromName(null);
+    gitWebType.setPathSeparator('!');
+
+    assertEquals("a!b", gitWebType.replacePathSeparator("a/b"));
+  }
+
+}
diff --git a/gerrit-common/src/test/java/com/google/gerrit/common/data/ParamertizedStringTest.java b/gerrit-common/src/test/java/com/google/gerrit/common/data/ParamertizedStringTest.java
deleted file mode 100644
index af8301f..0000000
--- a/gerrit-common/src/test/java/com/google/gerrit/common/data/ParamertizedStringTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (C) 2009 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.common.data;
-
-import junit.framework.TestCase;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class ParamertizedStringTest extends TestCase {
-  public void testEmptyString() {
-    final ParamertizedString p = new ParamertizedString("");
-    assertEquals("", p.getPattern());
-    assertEquals("", p.getRawPattern());
-    assertTrue(p.getParameterNames().isEmpty());
-
-    final Map<String, String> a = new HashMap<String, String>();
-    assertNotNull(p.bind(a));
-    assertEquals(0, p.bind(a).length);
-    assertEquals("", p.replace(a));
-  }
-
-  public void testAsis1() {
-    final ParamertizedString p = ParamertizedString.asis("${bar}c");
-    assertEquals("${bar}c", p.getPattern());
-    assertEquals("${bar}c", p.getRawPattern());
-    assertTrue(p.getParameterNames().isEmpty());
-
-    final Map<String, String> a = new HashMap<String, String>();
-    a.put("bar", "frobinator");
-    assertNotNull(p.bind(a));
-    assertEquals(0, p.bind(a).length);
-    assertEquals("${bar}c", p.replace(a));
-  }
-
-  public void testReplace1() {
-    final ParamertizedString p = new ParamertizedString("${bar}c");
-    assertEquals("${bar}c", p.getPattern());
-    assertEquals("{0}c", p.getRawPattern());
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("bar"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-    a.put("bar", "frobinator");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("frobinator", p.bind(a)[0]);
-    assertEquals("frobinatorc", p.replace(a));
-  }
-
-  public void testReplace2() {
-    final ParamertizedString p = new ParamertizedString("a${bar}c");
-    assertEquals("a${bar}c", p.getPattern());
-    assertEquals("a{0}c", p.getRawPattern());
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("bar"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-    a.put("bar", "frobinator");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("frobinator", p.bind(a)[0]);
-    assertEquals("afrobinatorc", p.replace(a));
-  }
-
-  public void testReplace3() {
-    final ParamertizedString p = new ParamertizedString("a${bar}");
-    assertEquals("a${bar}", p.getPattern());
-    assertEquals("a{0}", p.getRawPattern());
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("bar"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-    a.put("bar", "frobinator");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("frobinator", p.bind(a)[0]);
-    assertEquals("afrobinator", p.replace(a));
-  }
-
-  public void testReplace4() {
-    final ParamertizedString p = new ParamertizedString("a${bar}c");
-    assertEquals("a${bar}c", p.getPattern());
-    assertEquals("a{0}c", p.getRawPattern());
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("bar"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("", p.bind(a)[0]);
-    assertEquals("ac", p.replace(a));
-  }
-
-  public void testReplaceToLowerCase() {
-    final ParamertizedString p = new ParamertizedString("${a.toLowerCase}");
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("a"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-
-    a.put("a", "foo");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("foo", p.bind(a)[0]);
-    assertEquals("foo", p.replace(a));
-
-    a.put("a", "FOO");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("foo", p.bind(a)[0]);
-    assertEquals("foo", p.replace(a));
-  }
-
-  public void testReplaceToUpperCase() {
-    final ParamertizedString p = new ParamertizedString("${a.toUpperCase}");
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("a"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-
-    a.put("a", "foo");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("FOO", p.bind(a)[0]);
-    assertEquals("FOO", p.replace(a));
-
-    a.put("a", "FOO");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("FOO", p.bind(a)[0]);
-    assertEquals("FOO", p.replace(a));
-  }
-
-  public void testReplaceLocalName() {
-    final ParamertizedString p = new ParamertizedString("${a.localPart}");
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("a"));
-
-    final Map<String, String> a = new HashMap<String, String>();
-
-    a.put("a", "foo@example.com");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("foo", p.bind(a)[0]);
-    assertEquals("foo", p.replace(a));
-
-    a.put("a", "foo");
-    assertNotNull(p.bind(a));
-    assertEquals(1, p.bind(a).length);
-    assertEquals("foo", p.bind(a)[0]);
-    assertEquals("foo", p.replace(a));
-  }
-
-  public void testUndefinedFunctionName() {
-    ParamertizedString p = new ParamertizedString("${a.anUndefinedMethod}");
-    assertEquals(1, p.getParameterNames().size());
-    assertTrue(p.getParameterNames().contains("a.anUndefinedMethod"));
-  }
-}
diff --git a/gerrit-common/src/test/java/com/google/gerrit/common/data/ParameterizedStringTest.java b/gerrit-common/src/test/java/com/google/gerrit/common/data/ParameterizedStringTest.java
new file mode 100644
index 0000000..a2d1279
--- /dev/null
+++ b/gerrit-common/src/test/java/com/google/gerrit/common/data/ParameterizedStringTest.java
@@ -0,0 +1,374 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.common.data;
+
+import junit.framework.TestCase;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ParameterizedStringTest extends TestCase {
+  public void testEmptyString() {
+    final ParameterizedString p = new ParameterizedString("");
+    assertEquals("", p.getPattern());
+    assertEquals("", p.getRawPattern());
+    assertTrue(p.getParameterNames().isEmpty());
+
+    final Map<String, String> a = new HashMap<String, String>();
+    assertNotNull(p.bind(a));
+    assertEquals(0, p.bind(a).length);
+    assertEquals("", p.replace(a));
+  }
+
+  public void testAsis1() {
+    final ParameterizedString p = ParameterizedString.asis("${bar}c");
+    assertEquals("${bar}c", p.getPattern());
+    assertEquals("${bar}c", p.getRawPattern());
+    assertTrue(p.getParameterNames().isEmpty());
+
+    final Map<String, String> a = new HashMap<String, String>();
+    a.put("bar", "frobinator");
+    assertNotNull(p.bind(a));
+    assertEquals(0, p.bind(a).length);
+    assertEquals("${bar}c", p.replace(a));
+  }
+
+  public void testReplace1() {
+    final ParameterizedString p = new ParameterizedString("${bar}c");
+    assertEquals("${bar}c", p.getPattern());
+    assertEquals("{0}c", p.getRawPattern());
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("bar"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+    a.put("bar", "frobinator");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("frobinator", p.bind(a)[0]);
+    assertEquals("frobinatorc", p.replace(a));
+  }
+
+  public void testReplace2() {
+    final ParameterizedString p = new ParameterizedString("a${bar}c");
+    assertEquals("a${bar}c", p.getPattern());
+    assertEquals("a{0}c", p.getRawPattern());
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("bar"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+    a.put("bar", "frobinator");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("frobinator", p.bind(a)[0]);
+    assertEquals("afrobinatorc", p.replace(a));
+  }
+
+  public void testReplace3() {
+    final ParameterizedString p = new ParameterizedString("a${bar}");
+    assertEquals("a${bar}", p.getPattern());
+    assertEquals("a{0}", p.getRawPattern());
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("bar"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+    a.put("bar", "frobinator");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("frobinator", p.bind(a)[0]);
+    assertEquals("afrobinator", p.replace(a));
+  }
+
+  public void testReplace4() {
+    final ParameterizedString p = new ParameterizedString("a${bar}c");
+    assertEquals("a${bar}c", p.getPattern());
+    assertEquals("a{0}c", p.getRawPattern());
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("bar"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("", p.bind(a)[0]);
+    assertEquals("ac", p.replace(a));
+  }
+
+  public void testReplaceToLowerCase() {
+    final ParameterizedString p = new ParameterizedString("${a.toLowerCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+
+    a.put("a", "FOO");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+  }
+
+  public void testReplaceToUpperCase() {
+    final ParameterizedString p = new ParameterizedString("${a.toUpperCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+
+    a.put("a", "FOO");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+  }
+
+  public void testReplaceLocalName() {
+    final ParameterizedString p = new ParameterizedString("${a.localPart}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+
+    a.put("a", "foo");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+  }
+
+  public void testUndefinedFunctionName() {
+    ParameterizedString p =
+        new ParameterizedString(
+            "hi, ${userName.toUpperCase},your eamil address is '${email.toLowerCase.localPart}'.right?");
+    assertEquals(2, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("userName"));
+    assertTrue(p.getParameterNames().contains("email"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+    a.put("userName", "firstName lastName");
+    a.put("email", "FIRSTNAME.LASTNAME@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(2, p.bind(a).length);
+
+    assertEquals("FIRSTNAME LASTNAME", p.bind(a)[0]);
+    assertEquals("firstname.lastname", p.bind(a)[1]);
+    assertEquals("hi, FIRSTNAME LASTNAME,your eamil address is 'firstname.lastname'.right?", p.replace(a));
+  }
+
+  public void testReplaceToUpperCaseToLowerCase() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toUpperCase.toLowerCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo@example.com", p.bind(a)[0]);
+    assertEquals("foo@example.com", p.replace(a));
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo@example.com", p.bind(a)[0]);
+    assertEquals("foo@example.com", p.replace(a));
+  }
+
+  public void testReplaceToUpperCaseLocalName() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toUpperCase.localPart}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+  }
+
+  public void testReplaceToUpperCaseAnUndefinedMethod() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toUpperCase.anUndefinedMethod}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO@EXAMPLE.COM", p.bind(a)[0]);
+    assertEquals("FOO@EXAMPLE.COM", p.replace(a));
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO@EXAMPLE.COM", p.bind(a)[0]);
+    assertEquals("FOO@EXAMPLE.COM", p.replace(a));
+  }
+
+  public void testReplaceLocalNameToUpperCase() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.localPart.toUpperCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+  }
+
+  public void testReplaceLocalNameToLowerCase() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.localPart.toLowerCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+  }
+
+  public void testReplaceLocalNameAnUndefinedMethod() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.localPart.anUndefinedMethod}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO", p.bind(a)[0]);
+    assertEquals("FOO", p.replace(a));
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+  }
+
+  public void testReplaceToLowerCaseToUpperCase() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toLowerCase.toUpperCase}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO@EXAMPLE.COM", p.bind(a)[0]);
+    assertEquals("FOO@EXAMPLE.COM", p.replace(a));
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("FOO@EXAMPLE.COM", p.bind(a)[0]);
+    assertEquals("FOO@EXAMPLE.COM", p.replace(a));
+  }
+
+  public void testReplaceToLowerCaseLocalName() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toLowerCase.localPart}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo", p.bind(a)[0]);
+    assertEquals("foo", p.replace(a));
+  }
+
+  public void testReplaceToLowerCaseAnUndefinedMethod() {
+    final ParameterizedString p =
+        new ParameterizedString("${a.toLowerCase.anUndefinedMethod}");
+    assertEquals(1, p.getParameterNames().size());
+    assertTrue(p.getParameterNames().contains("a"));
+
+    final Map<String, String> a = new HashMap<String, String>();
+
+    a.put("a", "foo@example.com");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo@example.com", p.bind(a)[0]);
+    assertEquals("foo@example.com", p.replace(a));
+
+    a.put("a", "FOO@EXAMPLE.COM");
+    assertNotNull(p.bind(a));
+    assertEquals(1, p.bind(a).length);
+    assertEquals("foo@example.com", p.bind(a)[0]);
+    assertEquals("foo@example.com", p.replace(a));
+  }
+}
diff --git a/gerrit-ehcache/.gitignore b/gerrit-ehcache/.gitignore
new file mode 100644
index 0000000..20251d4
--- /dev/null
+++ b/gerrit-ehcache/.gitignore
@@ -0,0 +1,5 @@
+/target
+/.classpath
+/.project
+/.settings/org.eclipse.m2e.core.prefs
+/.settings/org.maven.ide.eclipse.prefs
diff --git a/gerrit-ehcache/.settings/org.eclipse.core.resources.prefs b/gerrit-ehcache/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..82eb859
--- /dev/null
+++ b/gerrit-ehcache/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,3 @@
+#Tue Sep 02 16:59:24 PDT 2008
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/gerrit-ehcache/.settings/org.eclipse.core.runtime.prefs b/gerrit-ehcache/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..8667cfd
--- /dev/null
+++ b/gerrit-ehcache/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,3 @@
+#Tue Sep 02 16:59:24 PDT 2008
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/gerrit-ehcache/.settings/org.eclipse.jdt.core.prefs b/gerrit-ehcache/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..e89c048
--- /dev/null
+++ b/gerrit-ehcache/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,269 @@
+#Thu Jan 19 12:55:44 PST 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_assignment=16
+org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_enum_constants=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_field=0
+org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
+org.eclipse.jdt.core.formatter.blank_lines_before_imports=0
+org.eclipse.jdt.core.formatter.blank_lines_before_member_type=0
+org.eclipse.jdt.core.formatter.blank_lines_before_method=1
+org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
+org.eclipse.jdt.core.formatter.blank_lines_before_package=0
+org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=2
+org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
+org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.format_block_comments=true
+org.eclipse.jdt.core.formatter.comment.format_header=true
+org.eclipse.jdt.core.formatter.comment.format_html=true
+org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
+org.eclipse.jdt.core.formatter.comment.format_line_comments=true
+org.eclipse.jdt.core.formatter.comment.format_source_code=true
+org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
+org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
+org.eclipse.jdt.core.formatter.comment.line_length=80
+org.eclipse.jdt.core.formatter.compact_else_if=true
+org.eclipse.jdt.core.formatter.continuation_indentation=2
+org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
+org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
+org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_empty_lines=false
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
+org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
+org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
+org.eclipse.jdt.core.formatter.indentation.size=4
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
+org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
+org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
+org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
+org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
+org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
+org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
+org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
+org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.lineSplit=80
+org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=3
+org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=false
+org.eclipse.jdt.core.formatter.tabulation.char=space
+org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
diff --git a/gerrit-ehcache/.settings/org.eclipse.jdt.ui.prefs b/gerrit-ehcache/.settings/org.eclipse.jdt.ui.prefs
new file mode 100644
index 0000000..d4218a5
--- /dev/null
+++ b/gerrit-ehcache/.settings/org.eclipse.jdt.ui.prefs
@@ -0,0 +1,61 @@
+#Wed Jul 29 11:31:38 PDT 2009
+eclipse.preferences.version=1
+editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
+formatter_profile=_Google Format
+formatter_settings_version=11
+org.eclipse.jdt.ui.ignorelowercasenames=true
+org.eclipse.jdt.ui.importorder=com.google;com;junit;net;org;java;javax;
+org.eclipse.jdt.ui.ondemandthreshold=99
+org.eclipse.jdt.ui.staticondemandthreshold=99
+org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates/>
+sp_cleanup.add_default_serial_version_id=true
+sp_cleanup.add_generated_serial_version_id=false
+sp_cleanup.add_missing_annotations=false
+sp_cleanup.add_missing_deprecated_annotations=true
+sp_cleanup.add_missing_methods=false
+sp_cleanup.add_missing_nls_tags=false
+sp_cleanup.add_missing_override_annotations=true
+sp_cleanup.add_serial_version_id=false
+sp_cleanup.always_use_blocks=true
+sp_cleanup.always_use_parentheses_in_expressions=false
+sp_cleanup.always_use_this_for_non_static_field_access=false
+sp_cleanup.always_use_this_for_non_static_method_access=false
+sp_cleanup.convert_to_enhanced_for_loop=false
+sp_cleanup.correct_indentation=false
+sp_cleanup.format_source_code=false
+sp_cleanup.format_source_code_changes_only=false
+sp_cleanup.make_local_variable_final=true
+sp_cleanup.make_parameters_final=true
+sp_cleanup.make_private_fields_final=true
+sp_cleanup.make_type_abstract_if_missing_method=false
+sp_cleanup.make_variable_declarations_final=false
+sp_cleanup.never_use_blocks=false
+sp_cleanup.never_use_parentheses_in_expressions=true
+sp_cleanup.on_save_use_additional_actions=true
+sp_cleanup.organize_imports=false
+sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+sp_cleanup.remove_private_constructors=true
+sp_cleanup.remove_trailing_whitespaces=true
+sp_cleanup.remove_trailing_whitespaces_all=true
+sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+sp_cleanup.remove_unnecessary_casts=false
+sp_cleanup.remove_unnecessary_nls_tags=false
+sp_cleanup.remove_unused_imports=false
+sp_cleanup.remove_unused_local_variables=false
+sp_cleanup.remove_unused_private_fields=true
+sp_cleanup.remove_unused_private_members=false
+sp_cleanup.remove_unused_private_methods=true
+sp_cleanup.remove_unused_private_types=true
+sp_cleanup.sort_members=false
+sp_cleanup.sort_members_all=false
+sp_cleanup.use_blocks=false
+sp_cleanup.use_blocks_only_for_return_and_throw=false
+sp_cleanup.use_parentheses_in_expressions=false
+sp_cleanup.use_this_for_non_static_field_access=false
+sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+sp_cleanup.use_this_for_non_static_method_access=false
+sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
diff --git a/gerrit-ehcache/pom.xml b/gerrit-ehcache/pom.xml
new file mode 100644
index 0000000..839c52b
--- /dev/null
+++ b/gerrit-ehcache/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Copyright (C) 2010 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.gerrit</groupId>
+    <artifactId>gerrit-parent</artifactId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>gerrit-ehcache</artifactId>
+  <name>Gerrit Code Review - Ehcache Bindings</name>
+
+  <description>
+    Bindings to Ehcache
+  </description>
+
+  <dependencies>
+    <dependency>
+      <groupId>net.sf.ehcache</groupId>
+      <artifactId>ehcache-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.gerrit</groupId>
+      <artifactId>gerrit-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/EhcachePoolImpl.java b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/EhcachePoolImpl.java
new file mode 100644
index 0000000..c25c381
--- /dev/null
+++ b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/EhcachePoolImpl.java
@@ -0,0 +1,271 @@
+// Copyright (C) 2009 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.ehcache;
+
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import com.google.gerrit.lifecycle.LifecycleListener;
+import com.google.gerrit.lifecycle.LifecycleModule;
+import com.google.gerrit.server.cache.CacheModule;
+import com.google.gerrit.server.cache.CachePool;
+import com.google.gerrit.server.cache.CacheProvider;
+import com.google.gerrit.server.cache.EntryCreator;
+import com.google.gerrit.server.cache.EvictionPolicy;
+import com.google.gerrit.server.cache.ProxyCache;
+import com.google.gerrit.server.config.ConfigUtil;
+import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.Configuration;
+import net.sf.ehcache.config.DiskStoreConfiguration;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+
+import org.eclipse.jgit.lib.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Pool of all declared caches created by {@link CacheModule}s. */
+@Singleton
+public class EhcachePoolImpl implements CachePool {
+  private static final Logger log =
+      LoggerFactory.getLogger(EhcachePoolImpl.class);
+
+  public static class Module extends LifecycleModule {
+    @Override
+    protected void configure() {
+      bind(CachePool.class).to(EhcachePoolImpl.class);
+      bind(EhcachePoolImpl.class);
+      listener().to(EhcachePoolImpl.Lifecycle.class);
+    }
+  }
+
+  public static class Lifecycle implements LifecycleListener {
+    private final EhcachePoolImpl cachePool;
+
+    @Inject
+    Lifecycle(final EhcachePoolImpl cachePool) {
+      this.cachePool = cachePool;
+    }
+
+    @Override
+    public void start() {
+      cachePool.start();
+    }
+
+    @Override
+    public void stop() {
+      cachePool.stop();
+    }
+  }
+
+  private final Config config;
+  private final SitePaths site;
+
+  private final Object lock = new Object();
+  private final Map<String, CacheProvider<?, ?>> caches;
+  private CacheManager manager;
+
+  @Inject
+  EhcachePoolImpl(@GerritServerConfig final Config cfg, final SitePaths site) {
+    this.config = cfg;
+    this.site = site;
+    this.caches = new HashMap<String, CacheProvider<?, ?>>();
+  }
+
+  private void start() {
+    synchronized (lock) {
+      if (manager != null) {
+        throw new IllegalStateException("Cache pool has already been started");
+      }
+
+      try {
+        System.setProperty("net.sf.ehcache.skipUpdateCheck", "" + true);
+      } catch (SecurityException e) {
+        // Ignore it, the system is just going to ping some external page
+        // using a background thread and there's not much we can do about
+        // it now.
+      }
+
+      manager = new CacheManager(new Factory().toConfiguration());
+      for (CacheProvider<?, ?> p : caches.values()) {
+        Ehcache eh = manager.getEhcache(p.getName());
+        EntryCreator<?, ?> c = p.getEntryCreator();
+        if (c != null) {
+          p.bind(new PopulatingCache(eh, c));
+        } else {
+          p.bind(new SimpleCache(eh));
+        }
+      }
+    }
+  }
+
+  private void stop() {
+    synchronized (lock) {
+      if (manager != null) {
+        manager.shutdown();
+      }
+    }
+  }
+
+  /** <i>Discouraged</i> Get the underlying cache descriptions, for statistics. */
+  public CacheManager getCacheManager() {
+    synchronized (lock) {
+      return manager;
+    }
+  }
+
+  public <K, V> ProxyCache<K, V> register(final CacheProvider<K, V> provider) {
+    synchronized (lock) {
+      if (manager != null) {
+        throw new IllegalStateException("Cache pool has already been started");
+      }
+
+      final String n = provider.getName();
+      if (caches.containsKey(n) && caches.get(n) != provider) {
+        throw new IllegalStateException("Cache \"" + n + "\" already defined");
+      }
+      caches.put(n, provider);
+      return new ProxyCache<K, V>();
+    }
+  }
+
+  private class Factory {
+    private static final int MB = 1024 * 1024;
+    private final Configuration mgr = new Configuration();
+
+    Configuration toConfiguration() {
+      configureDiskStore();
+      configureDefaultCache();
+
+      for (CacheProvider<?, ?> p : caches.values()) {
+        final String name = p.getName();
+        final CacheConfiguration c = newCache(name);
+        c.setMemoryStoreEvictionPolicyFromObject(toPolicy(p.evictionPolicy()));
+
+        c.setMaxElementsInMemory(getInt(name, "memorylimit", p.memoryLimit()));
+
+        c.setTimeToIdleSeconds(0);
+        c.setTimeToLiveSeconds(getSeconds(name, "maxage", p.maxAge()));
+        c.setEternal(c.getTimeToLiveSeconds() == 0);
+
+        if (p.disk() && mgr.getDiskStoreConfiguration() != null) {
+          c.setMaxElementsOnDisk(getInt(name, "disklimit", p.diskLimit()));
+
+          int v = c.getDiskSpoolBufferSizeMB() * MB;
+          v = getInt(name, "diskbuffer", v) / MB;
+          c.setDiskSpoolBufferSizeMB(Math.max(1, v));
+          c.setOverflowToDisk(c.getMaxElementsOnDisk() > 0);
+          c.setDiskPersistent(c.getMaxElementsOnDisk() > 0);
+        }
+
+        mgr.addCache(c);
+      }
+
+      return mgr;
+    }
+
+    private MemoryStoreEvictionPolicy toPolicy(final EvictionPolicy policy) {
+      switch (policy) {
+        case LFU:
+          return MemoryStoreEvictionPolicy.LFU;
+
+        case LRU:
+          return MemoryStoreEvictionPolicy.LRU;
+
+        default:
+          throw new IllegalArgumentException("Unsupported " + policy);
+      }
+    }
+
+    private int getInt(String n, String s, int d) {
+      return config.getInt("cache", n, s, d);
+    }
+
+    private long getSeconds(String n, String s, long d) {
+      d = MINUTES.convert(d, SECONDS);
+      long m = ConfigUtil.getTimeUnit(config, "cache", n, s, d, MINUTES);
+      return SECONDS.convert(m, MINUTES);
+    }
+
+    private void configureDiskStore() {
+      boolean needDisk = false;
+      for (CacheProvider<?, ?> p : caches.values()) {
+        if (p.disk()) {
+          needDisk = true;
+          break;
+        }
+      }
+      if (!needDisk) {
+        return;
+      }
+
+      File loc = site.resolve(config.getString("cache", null, "directory"));
+      if (loc == null) {
+      } else if (loc.exists() || loc.mkdirs()) {
+        if (loc.canWrite()) {
+          final DiskStoreConfiguration c = new DiskStoreConfiguration();
+          c.setPath(loc.getAbsolutePath());
+          mgr.addDiskStore(c);
+          log.info("Enabling disk cache " + loc.getAbsolutePath());
+        } else {
+          log.warn("Can't write to disk cache: " + loc.getAbsolutePath());
+        }
+      } else {
+        log.warn("Can't create disk cache: " + loc.getAbsolutePath());
+      }
+    }
+
+    private CacheConfiguration newConfiguration() {
+      CacheConfiguration c = new CacheConfiguration();
+
+      c.setMaxElementsInMemory(1024);
+      c.setMemoryStoreEvictionPolicyFromObject(MemoryStoreEvictionPolicy.LFU);
+
+      c.setTimeToIdleSeconds(0);
+      c.setTimeToLiveSeconds(0 /* infinite */);
+      c.setEternal(true);
+
+      if (mgr.getDiskStoreConfiguration() != null) {
+        c.setMaxElementsOnDisk(16384);
+        c.setOverflowToDisk(false);
+        c.setDiskPersistent(false);
+
+        c.setDiskSpoolBufferSizeMB(5);
+        c.setDiskExpiryThreadIntervalSeconds(60 * 60);
+      }
+      return c;
+    }
+
+    private void configureDefaultCache() {
+      mgr.setDefaultCacheConfiguration(newConfiguration());
+    }
+
+    private CacheConfiguration newCache(final String name) {
+      CacheConfiguration c = newConfiguration();
+      c.setName(name);
+      return c;
+    }
+  }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/cache/PopulatingCache.java b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/PopulatingCache.java
similarity index 92%
rename from gerrit-server/src/main/java/com/google/gerrit/server/cache/PopulatingCache.java
rename to gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/PopulatingCache.java
index 0822cc0..f5c6c45 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/cache/PopulatingCache.java
+++ b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/PopulatingCache.java
@@ -12,9 +12,10 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.cache;
+package com.google.gerrit.ehcache;
 
-import static java.util.concurrent.TimeUnit.SECONDS;
+import com.google.gerrit.server.cache.Cache;
+import com.google.gerrit.server.cache.EntryCreator;
 
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.Ehcache;
@@ -24,8 +25,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.concurrent.TimeUnit;
-
 /**
  * A decorator for {@link Cache} which automatically constructs missing entries.
  * <p>
@@ -109,12 +108,6 @@
   }
 
   @Override
-  public long getTimeToLive(final TimeUnit unit) {
-    final long maxAge = self.getCacheConfiguration().getTimeToLiveSeconds();
-    return unit.convert(maxAge, SECONDS);
-  }
-
-  @Override
   public String toString() {
     return "Cache[" + self.getName() + "]";
   }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/cache/SimpleCache.java b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/SimpleCache.java
similarity index 86%
rename from gerrit-server/src/main/java/com/google/gerrit/server/cache/SimpleCache.java
rename to gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/SimpleCache.java
index 2283f96..e4428e3 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/cache/SimpleCache.java
+++ b/gerrit-ehcache/src/main/java/com/google/gerrit/ehcache/SimpleCache.java
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package com.google.gerrit.server.cache;
+package com.google.gerrit.ehcache;
 
-import static java.util.concurrent.TimeUnit.SECONDS;
+import com.google.gerrit.server.cache.Cache;
 
 import net.sf.ehcache.CacheException;
 import net.sf.ehcache.Ehcache;
@@ -23,8 +23,6 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.concurrent.TimeUnit;
-
 /**
  * A fast in-memory and/or on-disk based cache.
  *
@@ -77,12 +75,6 @@
   }
 
   @Override
-  public long getTimeToLive(final TimeUnit unit) {
-    final long maxAge = self.getCacheConfiguration().getTimeToLiveSeconds();
-    return unit.convert(maxAge, SECONDS);
-  }
-
-  @Override
   public String toString() {
     return "Cache[" + self.getName() + "]";
   }
diff --git a/gerrit-gwtdebug/.gitignore b/gerrit-gwtdebug/.gitignore
index 903c6c8..194bedc 100644
--- a/gerrit-gwtdebug/.gitignore
+++ b/gerrit-gwtdebug/.gitignore
@@ -2,3 +2,4 @@
 /.classpath
 /.project
 /.settings/org.maven.ide.eclipse.prefs
+/.settings/org.eclipse.m2e.core.prefs
\ No newline at end of file
diff --git a/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs b/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
index 82eb859..36e1448 100644
--- a/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-gwtdebug/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,4 @@
-#Tue Sep 02 16:59:24 PDT 2008
+#Thu Jul 28 11:02:38 PDT 2011
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
 encoding/<project>=UTF-8
diff --git a/gerrit-gwtdebug/.settings/org.eclipse.jdt.core.prefs b/gerrit-gwtdebug/.settings/org.eclipse.jdt.core.prefs
index 04afc7f..d2b5901 100644
--- a/gerrit-gwtdebug/.settings/org.eclipse.jdt.core.prefs
+++ b/gerrit-gwtdebug/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Tue May 12 17:44:13 PDT 2009
+#Thu Jul 28 11:02:38 PDT 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
@@ -9,6 +9,7 @@
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 org.eclipse.jdt.core.compiler.source=1.6
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
diff --git a/gerrit-gwtdebug/pom.xml b/gerrit-gwtdebug/pom.xml
index 88246ac..734f645 100644
--- a/gerrit-gwtdebug/pom.xml
+++ b/gerrit-gwtdebug/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>com.google.gerrit</groupId>
     <artifactId>gerrit-parent</artifactId>
-    <version>2.1-SNAPSHOT</version>
+    <version>2.4-SNAPSHOT</version>
   </parent>
 
   <artifactId>gerrit-gwtdebug</artifactId>
@@ -83,5 +83,18 @@
       <version>140</version>
       <scope>provided</scope>
     </dependency>
+
+    <!-- GWT should require these itself, but doesn't. -->
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <classifier>sources</classifier>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java b/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
index 1834cdf..d23aa35 100644
--- a/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
+++ b/gerrit-gwtdebug/src/main/java/com/google/gerrit/gwtdebug/GerritDebugLauncher.java
@@ -23,11 +23,11 @@
 
 import org.mortbay.component.AbstractLifeCycle;
 import org.mortbay.jetty.AbstractConnector;
+import org.mortbay.jetty.HttpFields.Field;
 import org.mortbay.jetty.Request;
 import org.mortbay.jetty.RequestLog;
 import org.mortbay.jetty.Response;
 import org.mortbay.jetty.Server;
-import org.mortbay.jetty.HttpFields.Field;
 import org.mortbay.jetty.handler.RequestLogHandler;
 import org.mortbay.jetty.nio.SelectChannelConnector;
 import org.mortbay.jetty.webapp.WebAppClassLoader;
diff --git a/gerrit-gwtui/.gitignore b/gerrit-gwtui/.gitignore
index 903c6c8..194bedc 100644
--- a/gerrit-gwtui/.gitignore
+++ b/gerrit-gwtui/.gitignore
@@ -2,3 +2,4 @@
 /.classpath
 /.project
 /.settings/org.maven.ide.eclipse.prefs
+/.settings/org.eclipse.m2e.core.prefs
\ No newline at end of file
diff --git a/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs b/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
index 82eb859..c780f44 100644
--- a/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
+++ b/gerrit-gwtui/.settings/org.eclipse.core.resources.prefs
@@ -1,3 +1,4 @@
-#Tue Sep 02 16:59:24 PDT 2008
+#Thu Jul 28 11:02:36 PDT 2011
 eclipse.preferences.version=1
+encoding//src/main/java=UTF-8
 encoding/<project>=UTF-8
diff --git a/gerrit-gwtui/.settings/org.eclipse.jdt.core.prefs b/gerrit-gwtui/.settings/org.eclipse.jdt.core.prefs
index 04afc7f..470942d 100644
--- a/gerrit-gwtui/.settings/org.eclipse.jdt.core.prefs
+++ b/gerrit-gwtui/.settings/org.eclipse.jdt.core.prefs
@@ -1,4 +1,4 @@
-#Tue May 12 17:44:13 PDT 2009
+#Thu Jul 28 11:02:36 PDT 2011
 eclipse.preferences.version=1
 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
@@ -9,6 +9,7 @@
 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
 org.eclipse.jdt.core.compiler.source=1.6
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
diff --git a/gerrit-gwtui/pom.xml b/gerrit-gwtui/pom.xml
index f1e7438..f14daf6 100644
--- a/gerrit-gwtui/pom.xml
+++ b/gerrit-gwtui/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>com.google.gerrit</groupId>
     <artifactId>gerrit-parent</artifactId>
-    <version>2.1-SNAPSHOT</version>
+    <version>2.4-SNAPSHOT</version>
   </parent>
 
   <artifactId>gerrit-gwtui</artifactId>
@@ -37,7 +37,6 @@
     <dependency>
       <groupId>com.google.gwt</groupId>
       <artifactId>gwt-user</artifactId>
-      <version>${gwtVersion}</version>
     </dependency>
 
     <dependency>
@@ -135,6 +134,19 @@
       <classifier>sources</classifier>
       <type>jar</type>
     </dependency>
+
+    <!-- GWT should require these itself, but doesn't. -->
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.validation</groupId>
+      <artifactId>validation-api</artifactId>
+      <classifier>sources</classifier>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 
   <profiles>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml
index ec0f74f..8555c75 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/GerritGwtUI.gwt.xml
@@ -14,6 +14,7 @@
  limitations under the License.
 -->
 <module rename-to="gerrit">
+  <inherits name='com.google.gwt.editor.Editor'/>
   <inherits name='com.google.gwt.user.User'/>
   <inherits name='com.google.gwt.resources.Resources'/>
   <inherits name='com.google.gwt.user.theme.chrome.Chrome'/>
@@ -31,6 +32,7 @@
   <extend-property name='locale' values='en'/>
   <set-property-fallback name='locale' value='en'/>
   <set-property name='locale' value='en'/>
+  <set-configuration-property name='UiBinder.useSafeHtmlTemplates' value='true'/>
 
   <entry-point class='com.google.gerrit.client.Gerrit'/>
 </module>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java
index c4cb770..36169db 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/ConfirmationDialog.java
@@ -19,8 +19,9 @@
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.ui.Button;
 import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.Widget;
 import com.google.gwtexpui.globalkey.client.GlobalKey;
+import com.google.gwtexpui.safehtml.client.SafeHtml;
 import com.google.gwtexpui.user.client.AutoCenterDialogBox;
 
 public class ConfirmationDialog extends AutoCenterDialogBox {
@@ -28,7 +29,7 @@
 
   private Button cancelButton;
 
-  public ConfirmationDialog(final String dialogTitle, final HTML message,
+  public ConfirmationDialog(final String dialogTitle, final SafeHtml message,
       final ConfirmationCallback callback) {
     super(/* auto hide */false, /* modal */true);
     setGlassEnabled(true);
@@ -59,11 +60,12 @@
     buttons.add(cancelButton);
 
     final FlowPanel center = new FlowPanel();
-    center.add(message);
+    final Widget msgWidget = message.toBlockWidget();
+    center.add(msgWidget);
     center.add(buttons);
     add(center);
 
-    message.setWidth("400px");
+    msgWidget.setWidth("400px");
 
     setWidget(center);
   }
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 2b3ace4..3aee0e2 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
@@ -14,6 +14,7 @@
 
 package com.google.gerrit.client;
 
+import static com.google.gerrit.common.PageLinks.ADMIN_CREATE_PROJECT;
 import static com.google.gerrit.common.PageLinks.ADMIN_GROUPS;
 import static com.google.gerrit.common.PageLinks.ADMIN_PROJECTS;
 import static com.google.gerrit.common.PageLinks.MINE;
@@ -42,13 +43,17 @@
 import com.google.gerrit.client.account.NewAgreementScreen;
 import com.google.gerrit.client.account.RegisterScreen;
 import com.google.gerrit.client.account.ValidateEmailScreen;
+import com.google.gerrit.client.admin.AccountGroupInfoScreen;
+import com.google.gerrit.client.admin.AccountGroupMembersScreen;
 import com.google.gerrit.client.admin.AccountGroupScreen;
+import com.google.gerrit.client.admin.CreateProjectScreen;
 import com.google.gerrit.client.admin.GroupListScreen;
 import com.google.gerrit.client.admin.ProjectAccessScreen;
 import com.google.gerrit.client.admin.ProjectBranchesScreen;
 import com.google.gerrit.client.admin.ProjectInfoScreen;
 import com.google.gerrit.client.admin.ProjectListScreen;
 import com.google.gerrit.client.admin.ProjectScreen;
+import com.google.gerrit.client.admin.Util;
 import com.google.gerrit.client.auth.openid.OpenIdSignInDialog;
 import com.google.gerrit.client.auth.userpass.UserPassSignInDialog;
 import com.google.gerrit.client.changes.AccountDashboardScreen;
@@ -57,50 +62,101 @@
 import com.google.gerrit.client.changes.PublishCommentScreen;
 import com.google.gerrit.client.changes.QueryScreen;
 import com.google.gerrit.client.patches.PatchScreen;
+import com.google.gerrit.client.rpc.GerritCallback;
 import com.google.gerrit.client.ui.Screen;
+import com.google.gerrit.common.PageLinks;
 import com.google.gerrit.common.auth.SignInMode;
+import com.google.gerrit.common.data.GroupDetail;
 import com.google.gerrit.common.data.PatchSetDetail;
-import com.google.gerrit.reviewdb.Account;
-import com.google.gerrit.reviewdb.AccountGroup;
-import com.google.gerrit.reviewdb.Change;
-import com.google.gerrit.reviewdb.Patch;
-import com.google.gerrit.reviewdb.PatchSet;
-import com.google.gerrit.reviewdb.Project;
+import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.reviewdb.client.Change;
+import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.reviewdb.client.Project;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.core.client.RunAsyncCallback;
+import com.google.gwt.user.client.Window;
 import com.google.gwtorm.client.KeyUtil;
 
 public class Dispatcher {
   public static String toPatchSideBySide(final Patch.Key id) {
-    return toPatch("sidebyside", id);
+    return toPatch("", null, id);
+  }
+
+  public static String toPatchSideBySide(PatchSet.Id diffBase, Patch.Key id) {
+    return toPatch("", diffBase, id);
   }
 
   public static String toPatchUnified(final Patch.Key id) {
-    return toPatch("unified", id);
+    return toPatch("unified", null, id);
   }
 
-  public static String toPatch(final String type, final Patch.Key id) {
-    return "patch," + type + "," + id.toString();
+  public static String toPatchUnified(PatchSet.Id diffBase, Patch.Key id) {
+    return toPatch("unified", diffBase, id);
   }
 
-  public static String toAccountGroup(final AccountGroup.Id id) {
-    return "admin,group," + id.toString();
+  private static String toPatch(String type, PatchSet.Id diffBase, Patch.Key id) {
+    PatchSet.Id ps = id.getParentKey();
+    Change.Id c = ps.getParentKey();
+    StringBuilder p = new StringBuilder();
+    p.append("/c/").append(c).append("/");
+    if (diffBase != null) {
+      p.append(diffBase.get()).append("..");
+    }
+    p.append(ps.get()).append("/").append(KeyUtil.encode(id.get()));
+    if (type != null && !type.isEmpty()) {
+      p.append(",").append(type);
+    }
+    return p.toString();
   }
 
-  public static String toProjectAdmin(final Project.NameKey n, final String tab) {
-    return "admin,project," + n.toString() + "," + tab;
+  public static String toPatch(final PatchScreen.Type type, final Patch.Key id) {
+    if (type == PatchScreen.Type.SIDE_BY_SIDE) {
+      return toPatchSideBySide(id);
+    } else {
+      return toPatchUnified(id);
+    }
   }
 
-  static final String RELOAD_UI = "reload-ui,";
+  public static String toPublish(PatchSet.Id ps) {
+    Change.Id c = ps.getParentKey();
+    return "/c/" + c + "/" + ps.get() + ",publish";
+  }
+
+  public static String toGroup(final AccountGroup.Id id) {
+    return "/admin/groups/" + id.toString();
+  }
+
+  public static String toGroup(AccountGroup.Id id, String panel) {
+    return "/admin/groups/" + id.toString() + "," + panel;
+  }
+
+  public static String toGroup(final AccountGroup.UUID uuid) {
+    return "/admin/groups/uuid-" + uuid.toString();
+  }
+
+  public static String toGroup(AccountGroup.UUID uuid, String panel) {
+    return "/admin/groups/uuid-" + uuid.toString() + "," + panel;
+  }
+
+  public static String toProjectAdmin(Project.NameKey n, String panel) {
+    if (ProjectScreen.INFO.equals(panel)) {
+      return "/admin/projects/" + n.toString();
+    }
+    return "/admin/projects/" + n.toString() + "," + panel;
+  }
+
+  static final String RELOAD_UI = "/reload-ui/";
   private static boolean wasStartedByReloadUI;
 
   void display(String token) {
     assert token != null;
     try {
       try {
-        if (token.startsWith(RELOAD_UI)) {
+        if (matchPrefix(RELOAD_UI, token)) {
           wasStartedByReloadUI = true;
-          token = skip(RELOAD_UI, token);
+          token = skip(token);
         }
         select(token);
       } finally {
@@ -113,193 +169,328 @@
   }
 
   private static void select(final String token) {
-    if (token.startsWith("patch,")) {
-      patch(token, null, 0, null, null);
+    if (matchPrefix("/q/", token)) {
+      query(token);
 
-    } else if (token.startsWith("change,publish,")) {
-      publish(token);
+    } else if (matchPrefix("/c/", token)) {
+      change(token);
 
-    } else if (MINE.equals(token) || token.startsWith("mine,")) {
+    } else if (matchExact(MINE, token)) {
       Gerrit.display(token, mine(token));
 
-    } else if (token.startsWith("all,")) {
-      Gerrit.display(token, all(token));
+    } else if (matchPrefix("/dashboard/", token)) {
+      dashboard(token);
 
-    } else if (token.startsWith("project,")) {
-      Gerrit.display(token, project(token));
-
-    } else if (SETTINGS.equals(token) //
-        || REGISTER.equals(token) //
-        || token.startsWith("settings,") //
-        || token.startsWith("register,") //
-        || token.startsWith("VE,") //
-        || token.startsWith("SignInFailure,")) {
+    } else if (matchExact(SETTINGS, token) //
+        || matchPrefix("/settings/", token) //
+        || matchExact("register", token) //
+        || matchExact(REGISTER, token) //
+        || matchPrefix("/register/", token) //
+        || matchPrefix("/VE/", token) || matchPrefix("VE,", token) //
+        || matchPrefix("/SignInFailure,", token)) {
       settings(token);
 
-    } else if (token.startsWith("admin,")) {
+    } else if (matchPrefix("/admin/", token)) {
       admin(token);
 
-    } else {
-      Gerrit.display(token, core(token));
-    }
-  }
-
-  private static Screen mine(final String token) {
-    if (MINE.equals(token)) {
-      if (Gerrit.isSignedIn()) {
-        return new AccountDashboardScreen(Gerrit.getUserAccount().getId());
-
-      } else {
-        final Screen r = new AccountDashboardScreen(null);
-        r.setRequiresSignIn(true);
-        return r;
-      }
-
-    } else if ("mine,starred".equals(token)) {
-      return QueryScreen.forQuery("is:starred");
-
-    } else if ("mine,drafts".equals(token)) {
-      return QueryScreen.forQuery("has:draft");
+    } else if (/* LEGACY URL */matchPrefix("all,", token)) {
+      redirectFromLegacyToken(token, legacyAll(token));
+    } else if (/* LEGACY URL */matchPrefix("mine,", token)
+        || matchExact("mine", token)) {
+      redirectFromLegacyToken(token, legacyMine(token));
+    } else if (/* LEGACY URL */matchPrefix("project,", token)) {
+      redirectFromLegacyToken(token, legacyProject(token));
+    } else if (/* LEGACY URL */matchPrefix("change,", token)) {
+      redirectFromLegacyToken(token, legacyChange(token));
+    } else if (/* LEGACY URL */matchPrefix("patch,", token)) {
+      redirectFromLegacyToken(token, legacyPatch(token));
+    } else if (/* LEGACY URL */matchPrefix("admin,", token)) {
+      redirectFromLegacyToken(token, legacyAdmin(token));
+    } else if (/* LEGACY URL */matchPrefix("settings,", token)
+        || matchPrefix("register,", token)
+        || matchPrefix("q,", token)) {
+      redirectFromLegacyToken(token, legacySettings(token));
 
     } else {
-      String p = "mine,watched,";
-      if (token.startsWith(p)) {
-        return QueryScreen.forQuery("is:watched status:open", skip(p, token));
-      }
-
-      return new NotFoundScreen();
+      Gerrit.display(token, new NotFoundScreen());
     }
   }
 
-  private static Screen all(final String token) {
-    String p;
-
-    p = "all,abandoned,";
-    if (token.startsWith(p)) {
-      return QueryScreen.forQuery("status:abandoned", skip(p, token));
+  private static void redirectFromLegacyToken(String oldToken, String newToken) {
+    if (newToken != null) {
+      Window.Location.replace(Window.Location.getPath() + "#" + newToken);
+    } else {
+      Gerrit.display(oldToken, new NotFoundScreen());
     }
-
-    p = "all,merged,";
-    if (token.startsWith(p)) {
-      return QueryScreen.forQuery("status:merged", skip(p, token));
-    }
-
-    p = "all,open,";
-    if (token.startsWith(p)) {
-      return QueryScreen.forQuery("status:open", skip(p, token));
-    }
-
-    return new NotFoundScreen();
   }
 
-  private static Screen project(final String token) {
-    String p;
+  private static String legacyMine(final String token) {
+    if (matchExact("mine", token)) {
+      return MINE;
+    }
 
-    p = "project,open,";
-    if (token.startsWith(p)) {
-      final String s = skip(p, token);
+    if (matchExact("mine,starred", token)) {
+      return PageLinks.toChangeQuery("is:starred");
+    }
+
+    if (matchExact("mine,drafts", token)) {
+      return PageLinks.toChangeQuery("has:draft");
+    }
+
+    if (matchPrefix("mine,watched,", token)) {
+      return PageLinks.toChangeQuery("is:watched status:open", skip(token));
+    }
+
+    return null;
+  }
+
+  private static String legacyAll(final String token) {
+    if (matchPrefix("all,abandoned,", token)) {
+      return PageLinks.toChangeQuery("status:abandoned", skip(token));
+    }
+
+    if (matchPrefix("all,merged,", token)) {
+      return PageLinks.toChangeQuery("status:merged", skip(token));
+    }
+
+    if (matchPrefix("all,open,", token)) {
+      return PageLinks.toChangeQuery("status:open", skip(token));
+    }
+
+    return null;
+  }
+
+  private static String legacyProject(final String token) {
+    if (matchPrefix("project,open,", token)) {
+      final String s = skip(token);
       final int c = s.indexOf(',');
       Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
-      return QueryScreen.forQuery( //
+      return PageLinks.toChangeQuery( //
           "status:open " + op("project", proj.get()), //
           s.substring(c + 1));
     }
 
-    p = "project,merged,";
-    if (token.startsWith(p)) {
-      final String s = skip(p, token);
+    if (matchPrefix("project,merged,", token)) {
+      final String s = skip(token);
       final int c = s.indexOf(',');
       Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
-      return QueryScreen.forQuery( //
+      return PageLinks.toChangeQuery( //
           "status:merged " + op("project", proj.get()), //
           s.substring(c + 1));
     }
 
-    p = "project,abandoned,";
-    if (token.startsWith(p)) {
-      final String s = skip(p, token);
+    if (matchPrefix("project,abandoned,", token)) {
+      final String s = skip(token);
       final int c = s.indexOf(',');
       Project.NameKey proj = Project.NameKey.parse(s.substring(0, c));
-      return QueryScreen.forQuery( //
+      return PageLinks.toChangeQuery( //
           "status:abandoned " + op("project", proj.get()), //
           s.substring(c + 1));
     }
 
-    return new NotFoundScreen();
+    return null;
   }
 
-  private static Screen core(final String token) {
-    String p;
+  private static String legacyChange(final String token) {
+    final String s = skip(token);
+    final String t[] = s.split(",", 2);
+    if (t.length > 1 && matchPrefix("patchset=", t[1])) {
+      return PageLinks.toChange(PatchSet.Id.parse(t[0] + "," + skip(t[1])));
+    }
+    return PageLinks.toChange(Change.Id.parse(t[0]));
+  }
 
-    p = "change,";
-    if (token.startsWith(p)) {
-      final String s = skip(p, token);
-      final String q = "patchset=";
-      final String t[] = s.split(",", 2);
-      if (t.length > 1 && t[1].startsWith(q)) {
-        return new ChangeScreen(PatchSet.Id.parse(t[0] + "," + skip(q, t[1])));
+  private static String legacyPatch(String token) {
+    if (/* LEGACY URL */matchPrefix("patch,sidebyside,", token)) {
+      return toPatchSideBySide(Patch.Key.parse(skip(token)));
+    }
+
+    if (/* LEGACY URL */matchPrefix("patch,unified,", token)) {
+      return toPatchUnified(Patch.Key.parse(skip(token)));
+    }
+
+    return null;
+  }
+
+  private static String legacyAdmin(String token) {
+    if (matchPrefix("admin,group,", token)) {
+      return "/admin/groups/" + skip(token);
+    }
+
+    if (matchPrefix("admin,project,", token)) {
+      String rest = skip(token);
+      int c = rest.indexOf(',');
+      String panel;
+      Project.NameKey k;
+      if (0 < c) {
+        panel = rest.substring(c + 1);
+        k = Project.NameKey.parse(rest.substring(0, c));
+      } else {
+        panel = ProjectScreen.INFO;
+        k = Project.NameKey.parse(rest);
       }
-      return new ChangeScreen(Change.Id.parse(t[0]));
+      return toProjectAdmin(k, panel);
     }
 
-    p = "dashboard,";
-    if (token.startsWith(p))
-      return new AccountDashboardScreen(Account.Id.parse(skip(p, token)));
-
-    p = "q,";
-    if (token.startsWith(p)) {
-      final String s = skip(p, token);
-      final int c = s.indexOf(',');
-      return new QueryScreen(s.substring(0, c), s.substring(c + 1));
-    }
-
-    return new NotFoundScreen();
+    return null;
   }
 
-  private static void publish(String token) {
+  private static String legacySettings(String token) {
+    int c = token.indexOf(',');
+    if (0 < c) {
+      return "/" + token.substring(0, c) + "/" + token.substring(c + 1);
+    }
+    return null;
+  }
+
+  private static void query(final String token) {
+    final String s = skip(token);
+    final int c = s.indexOf(',');
+    Gerrit.display(token, new QueryScreen(s.substring(0, c), s.substring(c + 1)));
+  }
+
+  private static Screen mine(final String token) {
+    if (Gerrit.isSignedIn()) {
+      return new AccountDashboardScreen(Gerrit.getUserAccount().getId());
+
+    } else {
+      Screen r = new AccountDashboardScreen(null);
+      r.setRequiresSignIn(true);
+      return r;
+    }
+  }
+
+  private static void dashboard(final String token) {
+    Gerrit.display(token, //
+        new AccountDashboardScreen(Account.Id.parse(skip(token))));
+  }
+
+  private static void change(final String token) {
+    String rest = skip(token);
+    int c = rest.lastIndexOf(',');
+    String panel = null;
+    if (0 <= c) {
+      panel = rest.substring(c + 1);
+      rest = rest.substring(0, c);
+    }
+
+    Change.Id id;
+    int s = rest.indexOf('/');
+    if (0 <= s) {