Merge branch 'stable-3.0' into stable-3.1

* stable-3.0:
  Add new documentation for the owners-autoassign plugin
  Allow async assignment of reviewers

Change-Id: Iecb2bb8431c5cc329258b0d6a50cf528b7d99447
diff --git a/BUILD b/BUILD
index b52c2c1..548e6a8 100644
--- a/BUILD
+++ b/BUILD
@@ -1,6 +1,6 @@
 load("//tools:genrule2.bzl", "genrule2")
 load("//tools/bzl:plugin.bzl", "PLUGIN_TEST_DEPS")
-load("//owners-common:common.bzl", "EXTERNAL_DEPS")
+load("//owners-common:common.bzl", "EXTERNAL_DEPS", "EXTERNAL_TEST_DEPS")
 
 genrule2(
     name = "all",
@@ -21,7 +21,7 @@
     name = "owners_classpath_deps",
     testonly = 1,
     visibility = ["//visibility:public"],
-    exports = EXTERNAL_DEPS + PLUGIN_TEST_DEPS + [
+    exports = EXTERNAL_DEPS + EXTERNAL_TEST_DEPS + PLUGIN_TEST_DEPS + [
         "//owners:owners__plugin",
         "//owners-autoassign:owners-autoassign__plugin",
         "//owners-common:owners-common__plugin",
diff --git a/README.md b/README.md
index aee2d8e..4c9519f 100644
--- a/README.md
+++ b/README.md
@@ -55,8 +55,8 @@
 The output is created in
 
 ```
-  bazel-genfiles/owners/owners.jar
-  bazel-genfiles/owners-autoassign/owners-autoassign.jar
+  bazel-bin/owners/owners.jar
+  bazel-bin/owners-autoassign/owners-autoassign.jar
 
 ```
 
@@ -104,8 +104,8 @@
 The output is created in
 
 ```
-  bazel-genfiles/plugins/owners/owners.jar
-  bazel-genfiles/plugins/owners-autoassign/owners-autoassign.jar
+  bazel-bin/plugins/owners/owners.jar
+  bazel-bin/plugins/owners-autoassign/owners-autoassign.jar
 ```
 
 To execute the tests run:
diff --git a/WORKSPACE b/WORKSPACE
index 5c0cb74..96a6228 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "7472a1104a37d514799100d6556445836e8efe4c",
+    commit = "56aafc4c0bb1b72fba34f5bdfb29ddb1e1a17801",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 7c6aa5c..bca48e4 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -33,3 +33,68 @@
         artifact = "org.yaml:snakeyaml:1.23",
         sha1 = "ec62d74fe50689c28c0ff5b35d3aebcaa8b5be68",
     )
+
+    maven_jar(
+        name = "easymock",
+        artifact = "org.easymock:easymock:3.1",
+        sha1 = "3e127311a86fc2e8f550ef8ee4abe094bbcf7e7e",
+        deps = [
+            "@cglib//jar",
+            "@objenesis//jar",
+        ],
+    )
+
+    maven_jar(
+        name = "cglib",
+        artifact = "cglib:cglib-nodep:3.2.6",
+        sha1 = "92bf48723d277d6efd1150b2f7e9e1e92cb56caf",
+    )
+
+    maven_jar(
+        name = "objenesis",
+        artifact = "org.objenesis:objenesis:2.6",
+        sha1 = "639033469776fd37c08358c6b92a4761feb2af4b",
+    )
+
+    POWERM_VERS = "1.6.1"
+    maven_jar(
+        name = "powermock-module-junit4",
+        artifact = "org.powermock:powermock-module-junit4:" + POWERM_VERS,
+        sha1 = "ea8530b2848542624f110a393513af397b37b9cf",
+    )
+
+    maven_jar(
+        name = "powermock-module-junit4-common",
+        artifact = "org.powermock:powermock-module-junit4-common:" + POWERM_VERS,
+        sha1 = "7222ced54dabc310895d02e45c5428ca05193cda",
+    )
+
+    maven_jar(
+        name = "powermock-reflect",
+        artifact = "org.powermock:powermock-reflect:" + POWERM_VERS,
+        sha1 = "97d25eda8275c11161bcddda6ef8beabd534c878",
+    )
+
+    maven_jar(
+        name = "powermock-api-easymock",
+        artifact = "org.powermock:powermock-api-easymock:" + POWERM_VERS,
+        sha1 = "aa740ecf89a2f64d410b3d93ef8cd6833009ef00",
+    )
+
+    maven_jar(
+        name = "powermock-api-support",
+        artifact = "org.powermock:powermock-api-support:" + POWERM_VERS,
+        sha1 = "592ee6d929c324109d3469501222e0c76ccf0869",
+    )
+
+    maven_jar(
+        name = "powermock-core",
+        artifact = "org.powermock:powermock-core:" + POWERM_VERS,
+        sha1 = "5afc1efce8d44ed76b30af939657bd598e45d962",
+    )
+
+    maven_jar(
+        name = "javassist",
+        artifact = "org.javassist:javassist:3.22.0-GA",
+        sha1 = "3e83394258ae2089be7219b971ec21a8288528ad",
+    )
diff --git a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/AsyncReviewerManager.java b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/AsyncReviewerManager.java
index 6f8f161..64607e6 100644
--- a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/AsyncReviewerManager.java
+++ b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/AsyncReviewerManager.java
@@ -15,10 +15,10 @@
 
 package com.googlesource.gerrit.owners.common;
 
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Account.Id;
 import com.google.gerrit.extensions.api.changes.ChangeApi;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
diff --git a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/GitRefListener.java b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/GitRefListener.java
index 48f55a5..81559f7 100644
--- a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/GitRefListener.java
+++ b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/GitRefListener.java
@@ -19,6 +19,10 @@
 import static com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace.IGNORE_NONE;
 
 import com.google.common.collect.Sets;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.Project;
+import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.exceptions.StorageException;
 import com.google.gerrit.extensions.annotations.Listen;
 import com.google.gerrit.extensions.api.GerritApi;
@@ -28,10 +32,6 @@
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.CurrentUser;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.patch.PatchList;
@@ -94,7 +94,7 @@
     if (currentUser.isIdentifiedUser()) {
       handleGitReferenceUpdated(event);
     } else if (updaterAccountInfo != null) {
-      handleGitReferenceUpdatedAsUser(event, new Account.Id(updaterAccountInfo._accountId));
+      handleGitReferenceUpdatedAsUser(event, Account.id(updaterAccountInfo._accountId));
     } else {
       handleGitReferenceUpdatedAsServer(event);
     }
@@ -140,7 +140,7 @@
     // The provider injected by Gerrit is shared with other workers on the
     // same local thread and thus cannot be closed in this event listener.
     try {
-      ChangeApi cApi = changes.id(cId.id);
+      ChangeApi cApi = changes.id(cId.get());
       ChangeInfo change = cApi.get();
       PatchList patchList = getPatchList(event, change);
       if (patchList != null) {
@@ -168,7 +168,7 @@
 
     PatchListKey plKey = PatchListKey.againstCommit(null, newId, IGNORE_NONE);
     try {
-      return patchListCache.get(plKey, new Project.NameKey(change.project));
+      return patchListCache.get(plKey, Project.nameKey(change.project));
     } catch (PatchListNotAvailableException e) {
       logger.warn("Could not load patch list: {}", plKey, e);
     }
diff --git a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/ReviewerManager.java b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/ReviewerManager.java
index 2ae2fcd..1347d33 100644
--- a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/ReviewerManager.java
+++ b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/ReviewerManager.java
@@ -15,8 +15,8 @@
 
 package com.googlesource.gerrit.owners.common;
 
+import com.google.gerrit.entities.Account;
 import com.google.gerrit.extensions.api.changes.ChangeApi;
-import com.google.gerrit.reviewdb.client.Account;
 import java.util.Collection;
 
 public interface ReviewerManager {
diff --git a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
index 61e51c4..71c1ac2 100644
--- a/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
+++ b/owners-autoassign/src/main/java/com/googlesource/gerrit/owners/common/SyncReviewerManager.java
@@ -16,16 +16,16 @@
 
 package com.googlesource.gerrit.owners.common;
 
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Account.Id;
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.GerritApi;
 import com.google.gerrit.extensions.api.changes.AddReviewerInput;
 import com.google.gerrit.extensions.api.changes.ChangeApi;
 import com.google.gerrit.extensions.api.changes.ReviewInput;
 import com.google.gerrit.extensions.common.ChangeInfo;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.client.Change;
-import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.permissions.ChangePermission;
 import com.google.gerrit.server.permissions.PermissionBackend;
@@ -69,7 +69,7 @@
     try {
       ChangeInfo changeInfo = cApi.get();
       try (ManualRequestContext ctx =
-          requestContext.openAs(new Account.Id(changeInfo.owner._accountId))) {
+          requestContext.openAs(Account.id(changeInfo.owner._accountId))) {
         // TODO(davido): Switch back to using changes API again,
         // when it supports batch mode for adding reviewers
         ReviewInput in = new ReviewInput();
@@ -97,7 +97,7 @@
   private boolean isVisibleTo(ChangeInfo changeInfo, Id account) {
     ChangeData changeData =
         changeDataFactory.create(
-            new Project.NameKey(changeInfo.project), new Change.Id(changeInfo._number));
+            Project.nameKey(changeInfo.project), Change.id(changeInfo._number));
     return permissionBackend
         .user(userFactory.create(account))
         .change(changeData)
diff --git a/owners-autoassign/src/main/resources/Documentation/config.md b/owners-autoassign/src/main/resources/Documentation/config.md
deleted file mode 120000
index beb6012..0000000
--- a/owners-autoassign/src/main/resources/Documentation/config.md
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../config.md
\ No newline at end of file
diff --git a/owners-autoassign/src/main/resources/Documentation/config.md b/owners-autoassign/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..b294ae8
--- /dev/null
+++ b/owners-autoassign/src/main/resources/Documentation/config.md
@@ -0,0 +1,270 @@
+## Configuration
+
+Owner approval is determined based on OWNERS files located in the same
+repository on the target branch of the changes uploaded for review.
+
+The `OWNERS` file has the following YAML structure:
+
+```yaml
+inherited: true
+owners:
+- some.email@example.com
+- User Name
+- group/Group of Users
+matchers:
+- suffix: .java
+  owners:
+      [...]
+- regex: .*/README.*
+  owners:
+      [...]
+- partial_regex: example
+  owners:
+      [...]
+- exact: path/to/file.txt
+      [...]
+```
+
+_NOTE: Be aware to double check that emails and full user names correspond to
+valid registered Gerrit users. When owner user full name or e-mail cannot be
+resolved, a corresponding WARN message is logged on Gerrit error_log and the
+user entry dropped._
+
+That translates to inheriting owner email address from any parent OWNER files
+and to define 'some.email@example.com' or 'User Name' users as the mandatory
+reviewers for all changes that include modification to those files.
+
+To specify a group of people instead of naming individual owners, prefix the
+group name or UUID with 'group/'.
+
+Additional owners can be specified for files selected by other matching
+conditions (matchers section). Matching can be done by file suffix, regex
+(partial or full) and exact string comparison. For exact match, path is
+relative to the root of the repo.
+
+The plugin analyzes the latest patch set by looking at each file directory and
+building an OWNERS hierarchy. It stops once it finds an OWNERS file that has
+“inherited” set to false (by default it’s true.)
+
+For example, imagine the following tree:
+
+```
+/OWNERS
+/example/src/main/OWNERS
+/example/src/main/java/com/example/foo/Foo.java
+/example/src/main/resources/config.properties
+/example/src/test/OWNERS
+/example/src/test/java/com/example/foo/FooTest.java
+```
+
+If you submit a patch set that changes /example/src/main/java/com/example/foo/Foo.java
+then the plugin will first open /example/src/main/OWNERS and if inherited is set
+to true combine it with the owners listed in /OWNERS.
+
+If for each patch there is a reviewer who gave a Code-Review +2 then the plugin
+will not add any labels, otherwise, it will add ```label('Code-Review from owners', need(_)).```
+
+## Global project OWNERS
+
+Set a OWNERS file into the project refs/meta/config to define a global set of
+rules applied to every change pushed, regardless of the folder or target branch.
+
+Example of assigning every configuration files to a specific owner group:
+
+```yaml
+matchers:
+- suffix: .config
+  owners:
+  - Configuration Managers
+```
+
+Global refs/meta/config OWNERS configuration is inherited only when the OWNERS file
+contain the 'inherited: true' condition at the top of the file or if they are absent.
+
+That means that in the absence of any OWNERS file in the target branch, the refs/meta/config
+OWNERS is used as global default.
+
+
+## Example 1 - OWNERS file without matchers and default Gerrit submit rules
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+And sample rules.pl that uses this predicate to enable the submit rule if
+one of the owners has given a Code Review +2
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(D),
+  D =.. [submit | Ds],
+  findall(U, gerrit:commit_label(label('Code-Review', 2), U), Approvers),
+  gerrit_owners:add_owner_approval(Approvers, Ds, A),
+  S =.. [submit | A].
+```
+
+Then Gerrit would evaluate the Prolog rule as follows:
+
+It first gets the current default on rule which gives ok() if no Code-Review -2
+and at least a Code-Review +2 is being provided.
+
+Then it accumulates in Approvers the list of users who had given Code-Review +2
+and then checks if this list contains either 'John Doe' or 'Doug Smith'.
+
+If Approvers list does not include one of the owners, then Owner-Approval need()
+is added thus making the change not submittable.
+
+## Example 2 - OWNERS file without matchers and no default Gerrit rules
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+And a rule which makes submittable a change if at least one of the owners has
+given a +1 without taking into consideration any other label:
+
+```prolog
+submit_rule(S) :-
+     Ds = [ label(‘owners_plugin_default’,ok(user(100000))) ],
+     findall(U, gerrit:commit_label(label('Code-Review', 1), U), Approvers),
+     gerrit_owners:add_owner_approval(Approvers, Ds, A),
+     S =.. [submit | A].
+```
+
+Then Gerrit would make the change Submittable only if 'John Doe' or 'Doug Smith'
+have provided at least a Code-Review +1.
+
+## Example 3 - OWNERS file without matchers and custom _Owner-Approves_ label
+
+Sometimes to differentiate the _owners approval_ on a change from the code
+review on the entire project. The scenario could be for instance the sign-off of
+the project's build dependencies based on the Company roles-and-responsibilities
+matrix and governance process.
+
+In this case, we need to grant specific people with the _Owner-Approved_ label
+without necessarily having to give Code-Review +2 rights on the entire project.
+
+Amend the project.config as shown in (1) and add a new label; then give
+permissions to any registered user. Finally, define a small variant of the
+Prolog rules as shown in (2).
+
+(1) Example fo the project config changes with the new label with values
+(label name and values are arbitrary)
+
+```
+[label "Owner-Approved"]
+     function = NoOp
+     defaultValue = 0
+     copyMinScore = true
+     copyAllScoresOnTrivialRebase = true
+     value = -1 I don't want this to be merged
+     value =  0 No score
+     value = +1 Approved
+[access "refs/heads/*"]
+     label-Owner-Approved = -1..+1 group Registered Users
+```
+
+(2) Define the project's rules.pl with an amended version of Example 1:
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(D),
+  D =.. [submit | Ds],
+  findall(U, gerrit:commit_label(label('Owner-Approved', 1), U), Approvers),
+  gerrit_owners:add_owner_approval(Approvers, Ds, A),
+  S =.. [submit | A].
+```
+
+Given now an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+A change cannot be submitted until John Doe or Doug Smith add a label
+"Owner-Approved", independently from being able to provide any Code-Review.
+
+## Example 4 - Owners based on matchers
+
+Often the ownership comes from the developer's skills and competencies and
+cannot be purely defined by the project's directory structure.
+For instance, all the files ending with .sql should be owned and signed-off by
+the DBA while all the ones ending with .css by approved by the UX Team.
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+matchers:
+- suffix: .sql
+  owners:
+  - Mister Dba
+- suffix: .css
+  owners:
+  - John Creative
+  - Matt Designer
+```
+
+And a rules.pl of:
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(L),
+  L =.. [submit | Sr ],
+  gerrit_owners:add_match_owner_approval(Sr,A),
+  S =.. [submit | A ].
+```
+
+Then for any change that contains files with .sql or .css extensions, besides
+to the default Gerrit submit rules, the extra constraints on the additional
+owners of the modified files will be added. The final submit is enabled if both
+Gerrit default rules are satisfied and all the owners of the .sql files
+(Mister Dba) and the .css files (either John Creative or Matt Designer) have
+provided their Code-Review +2 feedback.
+
+## Example 5 - Owners details on a per-file basis
+
+When using the owners with a series of matchers associated to different set of
+owners, it may not be trivial to understand exactly *why* change is not approved
+yet.
+
+We need to define one extra submit rule to scan the entire list of files in the
+change and their associated owners and cross-check with the existing Code-Review
+feedback received.
+
+Given the same OWNERS and rules.pl configuration of Example 4 with the following
+extra rule:
+
+```prolog
+submit_rule(submit(W)) :-
+  gerrit_owners:findall_match_file_user(W).
+```
+
+For every change that would include any .sql or .css file (e.g. my-update.sql
+and styles.css) Gerrit will display as additional description on the "need" code
+review labels section of the change screen:
+
+```
+Code-Review from owners
+Mister Dba owns my-update.sql
+John Creative, Matt Designer own styles.css
+```
+
+As soon as the owners reviews are provided, the corresponding entry will be
+removed from the "need" section of the change.
+
+In this way, it is always clear which owner needs to provide their feedback on
+which file of the change.
diff --git a/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/GitRefListenerIT.java b/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/GitRefListenerIT.java
index 2a9c406..58db2d8 100644
--- a/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/GitRefListenerIT.java
+++ b/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/GitRefListenerIT.java
@@ -19,8 +19,8 @@
 
 import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
 import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
-import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.server.AnonymousUser;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.ThreadLocalRequestContext;
diff --git a/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/ReferenceUpdatedEventTest.java b/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/ReferenceUpdatedEventTest.java
index 42ac39c..61a485f 100644
--- a/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/ReferenceUpdatedEventTest.java
+++ b/owners-autoassign/src/test/java/com/googlesource/gerrit/owners/common/ReferenceUpdatedEventTest.java
@@ -15,12 +15,11 @@
 
 package com.googlesource.gerrit.owners.common;
 
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Project;
 import com.google.gerrit.extensions.api.changes.NotifyHandling;
 import com.google.gerrit.extensions.common.AccountInfo;
 import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.client.Project;
 import org.eclipse.jgit.transport.ReceiveCommand;
 import org.junit.Ignore;
 
@@ -32,7 +31,7 @@
   private final String oldObjectId;
   private final String newObjectId;
   private final ReceiveCommand.Type type;
-  private final Id eventAccountId;
+  private final Account.Id eventAccountId;
 
   public ReferenceUpdatedEventTest(
       Project.NameKey project,
diff --git a/owners-common/BUILD b/owners-common/BUILD
index e2825d5..0f12783 100644
--- a/owners-common/BUILD
+++ b/owners-common/BUILD
@@ -1,6 +1,6 @@
 load("//tools/bzl:junit.bzl", "junit_tests")
 load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS", "PLUGIN_DEPS_NEVERLINK", "PLUGIN_TEST_DEPS", "gerrit_plugin")
-load("//owners-common:common.bzl", "EXTERNAL_DEPS")
+load("//owners-common:common.bzl", "EXTERNAL_DEPS", "EXTERNAL_TEST_DEPS")
 
 java_library(
     name = "owners-common",
@@ -21,7 +21,7 @@
     name = "test",
     testonly = 1,
     srcs = glob(["src/test/java/**/*.java"]),
-    deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+    deps = EXTERNAL_TEST_DEPS + PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
         ":owners-common",
     ],
 )
diff --git a/owners-common/common.bzl b/owners-common/common.bzl
index f766ff2..c571145 100644
--- a/owners-common/common.bzl
+++ b/owners-common/common.bzl
@@ -5,3 +5,14 @@
     "@jackson-dataformat-yaml//jar",
     "@snakeyaml//jar",
 ]
+
+EXTERNAL_TEST_DEPS = [
+    "@easymock//jar",
+    "@powermock-module-junit4//jar",
+    "@powermock-module-junit4-common//jar",
+    "@powermock-reflect//jar",
+    "@powermock-api-easymock//jar",
+    "@powermock-api-support//jar",
+    "@powermock-core//jar",
+    "@javassist//jar",
+]
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Accounts.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Accounts.java
index 0fdf717..9a27d36 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Accounts.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Accounts.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import com.google.inject.ImplementedBy;
 import java.util.Set;
 
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/AccountsImpl.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/AccountsImpl.java
index b5c1f90..52e2b58 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/AccountsImpl.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/AccountsImpl.java
@@ -18,9 +18,9 @@
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
 import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
 
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.client.AccountGroup;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Account.Id;
+import com.google.gerrit.entities.AccountGroup;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.account.AccountResolver;
@@ -64,7 +64,7 @@
     this.byId = byId;
     this.groupCache = groupCache;
     this.groupMembers = groupMembers;
-    this.adminUser = userFactory.create(new Account.Id(1000000));
+    this.adminUser = userFactory.create(Account.id(1000000));
     this.oneOffRequestContext = oneOffRequestContext;
   }
 
@@ -79,9 +79,9 @@
   private Set<Id> findAccountsInGroup(String groupNameOrUUID) {
     Optional<InternalGroup> group =
         groupCache
-            .get(new AccountGroup.NameKey(groupNameOrUUID))
+            .get(AccountGroup.nameKey(groupNameOrUUID))
             .map(Optional::of)
-            .orElse(groupCache.get(new AccountGroup.UUID(groupNameOrUUID)));
+            .orElse(groupCache.get(AccountGroup.uuid(groupNameOrUUID)));
 
     if (!group.isPresent()) {
       log.warn("Group {} was not found", groupNameOrUUID);
@@ -91,7 +91,7 @@
     try (ManualRequestContext ctx = oneOffRequestContext.openAs(adminUser.getAccountId())) {
 
       return groupMembers.listAccounts(group.get().getGroupUUID(), null).stream()
-          .map(Account::getId)
+          .map(Account::id)
           .collect(Collectors.toSet());
     } catch (NoSuchProjectException | IOException e) {
       log.error("Unable to list accounts in group " + group, e);
@@ -144,15 +144,15 @@
       return false;
     }
 
-    Account account = accountState.get().getAccount();
+    Account account = accountState.get().account();
     return isFullNameMatch(account, nameOrEmail)
-        || nameOrEmail.equalsIgnoreCase(account.getPreferredEmail())
-        || accountState.get().getExternalIds().stream()
+        || nameOrEmail.equalsIgnoreCase(account.preferredEmail())
+        || accountState.get().externalIds().stream()
             .anyMatch(eid -> isEMailMatch(eid, nameOrEmail) || isUsernameMatch(eid, nameOrEmail));
   }
 
   private boolean isFullNameMatch(Account account, String fullName) {
-    return Optional.ofNullable(account.getFullName())
+    return Optional.ofNullable(account.fullName())
         .filter(n -> n.trim().equalsIgnoreCase(fullName))
         .isPresent();
   }
@@ -174,7 +174,7 @@
   }
 
   private boolean isActive(Account.Id accountId) {
-    return byId.get(accountId).map(AccountState::getAccount).map(Account::isActive).orElse(false);
+    return byId.get(accountId).map(AccountState::account).map(Account::isActive).orElse(false);
   }
 
   private Optional<String> keySchemeRest(String scheme, ExternalId.Key key) {
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ConfigurationParser.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ConfigurationParser.java
index dcdd9f7..5b1049d 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ConfigurationParser.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ConfigurationParser.java
@@ -20,7 +20,7 @@
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import com.google.gerrit.reviewdb.client.Account.Id;
+import com.google.gerrit.entities.Account.Id;
 import java.io.IOException;
 import java.util.Optional;
 import java.util.Set;
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ExactMatcher.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ExactMatcher.java
index f638a32..07dadbe 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ExactMatcher.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/ExactMatcher.java
@@ -15,7 +15,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Set;
 
 public class ExactMatcher extends Matcher {
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Matcher.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Matcher.java
index d57116b..412fa79 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Matcher.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/Matcher.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Set;
 
 public abstract class Matcher {
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/OwnersMap.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/OwnersMap.java
index 8af46e3..06d9d12 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/OwnersMap.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/OwnersMap.java
@@ -18,8 +18,8 @@
 import com.google.common.collect.Maps;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Account.Id;
 import java.util.Map;
 import java.util.Set;
 
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PartialRegExMatcher.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PartialRegExMatcher.java
index 759170f..c046c13 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PartialRegExMatcher.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PartialRegExMatcher.java
@@ -15,7 +15,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Set;
 import java.util.regex.Pattern;
 
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwners.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwners.java
index bb53419..77289a3 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwners.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwners.java
@@ -16,18 +16,18 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG;
-import static com.google.gerrit.reviewdb.client.Patch.MERGE_LIST;
+import static com.google.gerrit.entities.Patch.COMMIT_MSG;
+import static com.google.gerrit.entities.Patch.MERGE_LIST;
 import static com.googlesource.gerrit.owners.common.JgitWrapper.getBlobAsBytes;
 
 import com.google.common.collect.Maps;
 import com.google.common.collect.Multimaps;
 import com.google.common.collect.SetMultimap;
 import com.google.common.collect.Sets;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.Account.Id;
-import com.google.gerrit.reviewdb.client.Patch;
-import com.google.gerrit.reviewdb.client.RefNames;
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.entities.Account.Id;
+import com.google.gerrit.entities.Patch;
+import com.google.gerrit.entities.RefNames;
 import com.google.gerrit.server.patch.PatchList;
 import com.google.gerrit.server.patch.PatchListEntry;
 import java.io.IOException;
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntry.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntry.java
index 3a7111d..d2c73ec 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntry.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/PathOwnersEntry.java
@@ -18,7 +18,7 @@
 
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/RegExMatcher.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/RegExMatcher.java
index 2f1c23d..45fd615 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/RegExMatcher.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/RegExMatcher.java
@@ -15,7 +15,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Set;
 import java.util.regex.Pattern;
 
diff --git a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/SuffixMatcher.java b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/SuffixMatcher.java
index 4c72b7a..39e8b32 100644
--- a/owners-common/src/main/java/com/googlesource/gerrit/owners/common/SuffixMatcher.java
+++ b/owners-common/src/main/java/com/googlesource/gerrit/owners/common/SuffixMatcher.java
@@ -15,7 +15,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Set;
 
 public class SuffixMatcher extends Matcher {
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/ClassicConfig.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/ClassicConfig.java
index e388125..a62ee5b 100644
--- a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/ClassicConfig.java
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/ClassicConfig.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import org.junit.Ignore;
 
 @Ignore
@@ -22,9 +22,9 @@
   public static final String USER_A_EMAIL_COM = "user-a@email.com";
   public static final String USER_B_EMAIL_COM = "user-b@email.com";
   public static final String USER_C_EMAIL_COM = "user-c@email.com";
-  public static final Account.Id USER_A_ID = new Account.Id(1);
-  public static final Account.Id USER_B_ID = new Account.Id(2);
-  public static final Account.Id USER_C_ID = new Account.Id(3);
+  public static final Account.Id USER_A_ID = Account.id(1);
+  public static final Account.Id USER_B_ID = Account.id(2);
+  public static final Account.Id USER_C_ID = Account.id(3);
 
   @Override
   public void setup() throws Exception {
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/Config.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/Config.java
index a5df462..ea00372 100644
--- a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/Config.java
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/Config.java
@@ -19,7 +19,7 @@
 import static org.easymock.EasyMock.expect;
 
 import com.google.common.base.Charsets;
-import com.google.gerrit.reviewdb.client.Patch;
+import com.google.gerrit.entities.Patch;
 import com.google.gerrit.server.patch.PatchList;
 import com.google.gerrit.server.patch.PatchListEntry;
 import java.io.IOException;
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/PathOwnersTest.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/PathOwnersTest.java
index 42a1796..df2b891 100644
--- a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/PathOwnersTest.java
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/PathOwnersTest.java
@@ -18,7 +18,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.powermock.api.easymock.PowerMock.replayAll;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Arrays;
 import java.util.Optional;
 import java.util.Set;
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/RegexTest.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/RegexTest.java
index 47f9381..b68ec99 100644
--- a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/RegexTest.java
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/RegexTest.java
@@ -15,6 +15,7 @@
 package com.googlesource.gerrit.owners.common;
 
 import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
 import static com.googlesource.gerrit.owners.common.MatcherConfig.exactMatcher;
 import static com.googlesource.gerrit.owners.common.MatcherConfig.partialRegexMatcher;
 import static com.googlesource.gerrit.owners.common.MatcherConfig.regexMatcher;
@@ -24,7 +25,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.powermock.api.easymock.PowerMock.replayAll;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
@@ -48,12 +49,12 @@
   private static final String ACCOUNT_D = "d";
   private static final String ACCOUNT_E = "e";
   private static final String ACCOUNT_F = "f";
-  private static final Account.Id ACCOUNT_A_ID = new Account.Id(1);
-  private static final Account.Id ACCOUNT_B_ID = new Account.Id(2);
-  private static final Account.Id ACCOUNT_C_ID = new Account.Id(3);
-  private static final Account.Id ACCOUNT_D_ID = new Account.Id(4);
-  private static final Account.Id ACCOUNT_E_ID = new Account.Id(5);
-  private static final Account.Id ACCOUNT_F_ID = new Account.Id(6);
+  private static final Account.Id ACCOUNT_A_ID = Account.id(1);
+  private static final Account.Id ACCOUNT_B_ID = Account.id(2);
+  private static final Account.Id ACCOUNT_C_ID = Account.id(3);
+  private static final Account.Id ACCOUNT_D_ID = Account.id(4);
+  private static final Account.Id ACCOUNT_E_ID = Account.id(5);
+  private static final Account.Id ACCOUNT_F_ID = Account.id(6);
 
   @Override
   @Before
@@ -82,7 +83,7 @@
     // the function to test
     Optional<OwnersConfig> configNullable = getOwnersConfig(fullConfig);
     // check classical configuration
-    assertTrue(configNullable.isPresent());
+    assertThat(configNullable).isPresent();
 
     OwnersConfig config = configNullable.get();
     assertTrue(config.isInherited());
@@ -227,7 +228,7 @@
     Optional<OwnersConfig> ownersConfigOpt =
         getOwnersConfig(createConfig(false, new String[0], suffixMatcher(".txt", ACCOUNT_B)));
 
-    assertThat(ownersConfigOpt.isPresent()).named("ownersConfig").isTrue();
+    assertThat(ownersConfigOpt).isPresent();
     OwnersConfig ownersConfig = ownersConfigOpt.get();
 
     assertThat(ownersConfig.getOwners()).isEmpty();
diff --git a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/TestAccounts.java b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/TestAccounts.java
index ba48011..c450f01 100644
--- a/owners-common/src/test/java/com/googlesource/gerrit/owners/common/TestAccounts.java
+++ b/owners-common/src/test/java/com/googlesource/gerrit/owners/common/TestAccounts.java
@@ -14,7 +14,7 @@
 
 package com.googlesource.gerrit.owners.common;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
diff --git a/owners/BUILD b/owners/BUILD
index 05c1fa7..3acc05b 100644
--- a/owners/BUILD
+++ b/owners/BUILD
@@ -1,5 +1,6 @@
-load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS_NEVERLINK", "gerrit_plugin")
+load("//tools/bzl:plugin.bzl", "PLUGIN_DEPS_NEVERLINK", "PLUGIN_TEST_DEPS", "gerrit_plugin")
 load("//lib/prolog:prolog.bzl", "prolog_cafe_library")
+load("//owners-common:common.bzl", "EXTERNAL_DEPS", "EXTERNAL_TEST_DEPS")
 
 PROLOG_PREDICATES = glob(["src/main/java/gerrit_owners/**/*.java"]) + [
     "src/main/java/com/googlesource/gerrit/owners/OwnersStoredValues.java",
@@ -44,3 +45,10 @@
         "//owners-common",
     ],
 )
+
+java_library(
+    name = "owners__plugin_test_deps",
+    testonly = 1,
+    visibility = ["//visibility:public"],
+    exports = EXTERNAL_DEPS + EXTERNAL_TEST_DEPS + PLUGIN_TEST_DEPS,
+)
diff --git a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersStoredValues.java b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersStoredValues.java
index 18abe29..f721539 100644
--- a/owners/src/main/java/com/googlesource/gerrit/owners/OwnersStoredValues.java
+++ b/owners/src/main/java/com/googlesource/gerrit/owners/OwnersStoredValues.java
@@ -43,7 +43,7 @@
           protected PathOwners createValue(Prolog engine) {
             PatchList patchList = StoredValues.PATCH_LIST.get(engine);
             Repository repository = StoredValues.REPOSITORY.get(engine);
-            String branch = StoredValues.getChange(engine).getDest().get();
+            String branch = StoredValues.getChange(engine).getDest().branch();
             return new PathOwners(accounts, repository, branch, patchList);
           }
         };
diff --git a/owners/src/main/java/gerrit_owners/PRED_file_owners_2.java b/owners/src/main/java/gerrit_owners/PRED_file_owners_2.java
index 4e7263a..fd87eb3 100644
--- a/owners/src/main/java/gerrit_owners/PRED_file_owners_2.java
+++ b/owners/src/main/java/gerrit_owners/PRED_file_owners_2.java
@@ -16,7 +16,7 @@
 
 import static com.googlesource.gerrit.owners.common.StreamUtils.iteratorStream;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import com.google.gerrit.server.IdentifiedUser;
 import com.google.gerrit.server.rules.PrologEnvironment;
 import com.google.gerrit.server.rules.StoredValues;
@@ -74,8 +74,8 @@
       cache.put(accountId, who);
       user = who;
     }
-    Account account = user.asIdentifiedUser().state().getAccount();
-    String userName = account.getFullName();
+    Account account = user.asIdentifiedUser().state().account();
+    String userName = account.fullName();
     return sanitizeAsSubmitLabel(userName);
   }
 
diff --git a/owners/src/main/java/gerrit_owners/PRED_matcher_owner_2.java b/owners/src/main/java/gerrit_owners/PRED_matcher_owner_2.java
index 5abf7ad..d056a9f 100644
--- a/owners/src/main/java/gerrit_owners/PRED_matcher_owner_2.java
+++ b/owners/src/main/java/gerrit_owners/PRED_matcher_owner_2.java
@@ -16,7 +16,7 @@
 
 package gerrit_owners;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import com.googlecode.prolog_cafe.exceptions.PrologException;
 import com.googlecode.prolog_cafe.lang.IntegerTerm;
 import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
diff --git a/owners/src/main/java/gerrit_owners/PRED_owner_2.java b/owners/src/main/java/gerrit_owners/PRED_owner_2.java
index 5697a32..9748934 100644
--- a/owners/src/main/java/gerrit_owners/PRED_owner_2.java
+++ b/owners/src/main/java/gerrit_owners/PRED_owner_2.java
@@ -16,7 +16,7 @@
 
 package gerrit_owners;
 
-import com.google.gerrit.reviewdb.client.Account;
+import com.google.gerrit.entities.Account;
 import com.googlecode.prolog_cafe.exceptions.PrologException;
 import com.googlecode.prolog_cafe.lang.IntegerTerm;
 import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
diff --git a/owners/src/main/resources/Documentation/config.md b/owners/src/main/resources/Documentation/config.md
deleted file mode 120000
index beb6012..0000000
--- a/owners/src/main/resources/Documentation/config.md
+++ /dev/null
@@ -1 +0,0 @@
-../../../../../config.md
\ No newline at end of file
diff --git a/owners/src/main/resources/Documentation/config.md b/owners/src/main/resources/Documentation/config.md
new file mode 100644
index 0000000..b294ae8
--- /dev/null
+++ b/owners/src/main/resources/Documentation/config.md
@@ -0,0 +1,270 @@
+## Configuration
+
+Owner approval is determined based on OWNERS files located in the same
+repository on the target branch of the changes uploaded for review.
+
+The `OWNERS` file has the following YAML structure:
+
+```yaml
+inherited: true
+owners:
+- some.email@example.com
+- User Name
+- group/Group of Users
+matchers:
+- suffix: .java
+  owners:
+      [...]
+- regex: .*/README.*
+  owners:
+      [...]
+- partial_regex: example
+  owners:
+      [...]
+- exact: path/to/file.txt
+      [...]
+```
+
+_NOTE: Be aware to double check that emails and full user names correspond to
+valid registered Gerrit users. When owner user full name or e-mail cannot be
+resolved, a corresponding WARN message is logged on Gerrit error_log and the
+user entry dropped._
+
+That translates to inheriting owner email address from any parent OWNER files
+and to define 'some.email@example.com' or 'User Name' users as the mandatory
+reviewers for all changes that include modification to those files.
+
+To specify a group of people instead of naming individual owners, prefix the
+group name or UUID with 'group/'.
+
+Additional owners can be specified for files selected by other matching
+conditions (matchers section). Matching can be done by file suffix, regex
+(partial or full) and exact string comparison. For exact match, path is
+relative to the root of the repo.
+
+The plugin analyzes the latest patch set by looking at each file directory and
+building an OWNERS hierarchy. It stops once it finds an OWNERS file that has
+“inherited” set to false (by default it’s true.)
+
+For example, imagine the following tree:
+
+```
+/OWNERS
+/example/src/main/OWNERS
+/example/src/main/java/com/example/foo/Foo.java
+/example/src/main/resources/config.properties
+/example/src/test/OWNERS
+/example/src/test/java/com/example/foo/FooTest.java
+```
+
+If you submit a patch set that changes /example/src/main/java/com/example/foo/Foo.java
+then the plugin will first open /example/src/main/OWNERS and if inherited is set
+to true combine it with the owners listed in /OWNERS.
+
+If for each patch there is a reviewer who gave a Code-Review +2 then the plugin
+will not add any labels, otherwise, it will add ```label('Code-Review from owners', need(_)).```
+
+## Global project OWNERS
+
+Set a OWNERS file into the project refs/meta/config to define a global set of
+rules applied to every change pushed, regardless of the folder or target branch.
+
+Example of assigning every configuration files to a specific owner group:
+
+```yaml
+matchers:
+- suffix: .config
+  owners:
+  - Configuration Managers
+```
+
+Global refs/meta/config OWNERS configuration is inherited only when the OWNERS file
+contain the 'inherited: true' condition at the top of the file or if they are absent.
+
+That means that in the absence of any OWNERS file in the target branch, the refs/meta/config
+OWNERS is used as global default.
+
+
+## Example 1 - OWNERS file without matchers and default Gerrit submit rules
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+And sample rules.pl that uses this predicate to enable the submit rule if
+one of the owners has given a Code Review +2
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(D),
+  D =.. [submit | Ds],
+  findall(U, gerrit:commit_label(label('Code-Review', 2), U), Approvers),
+  gerrit_owners:add_owner_approval(Approvers, Ds, A),
+  S =.. [submit | A].
+```
+
+Then Gerrit would evaluate the Prolog rule as follows:
+
+It first gets the current default on rule which gives ok() if no Code-Review -2
+and at least a Code-Review +2 is being provided.
+
+Then it accumulates in Approvers the list of users who had given Code-Review +2
+and then checks if this list contains either 'John Doe' or 'Doug Smith'.
+
+If Approvers list does not include one of the owners, then Owner-Approval need()
+is added thus making the change not submittable.
+
+## Example 2 - OWNERS file without matchers and no default Gerrit rules
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+And a rule which makes submittable a change if at least one of the owners has
+given a +1 without taking into consideration any other label:
+
+```prolog
+submit_rule(S) :-
+     Ds = [ label(‘owners_plugin_default’,ok(user(100000))) ],
+     findall(U, gerrit:commit_label(label('Code-Review', 1), U), Approvers),
+     gerrit_owners:add_owner_approval(Approvers, Ds, A),
+     S =.. [submit | A].
+```
+
+Then Gerrit would make the change Submittable only if 'John Doe' or 'Doug Smith'
+have provided at least a Code-Review +1.
+
+## Example 3 - OWNERS file without matchers and custom _Owner-Approves_ label
+
+Sometimes to differentiate the _owners approval_ on a change from the code
+review on the entire project. The scenario could be for instance the sign-off of
+the project's build dependencies based on the Company roles-and-responsibilities
+matrix and governance process.
+
+In this case, we need to grant specific people with the _Owner-Approved_ label
+without necessarily having to give Code-Review +2 rights on the entire project.
+
+Amend the project.config as shown in (1) and add a new label; then give
+permissions to any registered user. Finally, define a small variant of the
+Prolog rules as shown in (2).
+
+(1) Example fo the project config changes with the new label with values
+(label name and values are arbitrary)
+
+```
+[label "Owner-Approved"]
+     function = NoOp
+     defaultValue = 0
+     copyMinScore = true
+     copyAllScoresOnTrivialRebase = true
+     value = -1 I don't want this to be merged
+     value =  0 No score
+     value = +1 Approved
+[access "refs/heads/*"]
+     label-Owner-Approved = -1..+1 group Registered Users
+```
+
+(2) Define the project's rules.pl with an amended version of Example 1:
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(D),
+  D =.. [submit | Ds],
+  findall(U, gerrit:commit_label(label('Owner-Approved', 1), U), Approvers),
+  gerrit_owners:add_owner_approval(Approvers, Ds, A),
+  S =.. [submit | A].
+```
+
+Given now an OWNERS configuration of:
+
+```yaml
+inherited: true
+owners:
+- John Doe
+- Doug Smith
+```
+
+A change cannot be submitted until John Doe or Doug Smith add a label
+"Owner-Approved", independently from being able to provide any Code-Review.
+
+## Example 4 - Owners based on matchers
+
+Often the ownership comes from the developer's skills and competencies and
+cannot be purely defined by the project's directory structure.
+For instance, all the files ending with .sql should be owned and signed-off by
+the DBA while all the ones ending with .css by approved by the UX Team.
+
+Given an OWNERS configuration of:
+
+```yaml
+inherited: true
+matchers:
+- suffix: .sql
+  owners:
+  - Mister Dba
+- suffix: .css
+  owners:
+  - John Creative
+  - Matt Designer
+```
+
+And a rules.pl of:
+
+```prolog
+submit_rule(S) :-
+  gerrit:default_submit(L),
+  L =.. [submit | Sr ],
+  gerrit_owners:add_match_owner_approval(Sr,A),
+  S =.. [submit | A ].
+```
+
+Then for any change that contains files with .sql or .css extensions, besides
+to the default Gerrit submit rules, the extra constraints on the additional
+owners of the modified files will be added. The final submit is enabled if both
+Gerrit default rules are satisfied and all the owners of the .sql files
+(Mister Dba) and the .css files (either John Creative or Matt Designer) have
+provided their Code-Review +2 feedback.
+
+## Example 5 - Owners details on a per-file basis
+
+When using the owners with a series of matchers associated to different set of
+owners, it may not be trivial to understand exactly *why* change is not approved
+yet.
+
+We need to define one extra submit rule to scan the entire list of files in the
+change and their associated owners and cross-check with the existing Code-Review
+feedback received.
+
+Given the same OWNERS and rules.pl configuration of Example 4 with the following
+extra rule:
+
+```prolog
+submit_rule(submit(W)) :-
+  gerrit_owners:findall_match_file_user(W).
+```
+
+For every change that would include any .sql or .css file (e.g. my-update.sql
+and styles.css) Gerrit will display as additional description on the "need" code
+review labels section of the change screen:
+
+```
+Code-Review from owners
+Mister Dba owns my-update.sql
+John Creative, Matt Designer own styles.css
+```
+
+As soon as the owners reviews are provided, the corresponding entry will be
+removed from the "need" section of the change.
+
+In this way, it is always clear which owner needs to provide their feedback on
+which file of the change.
diff --git a/tools/bzl/maven_jar.bzl b/tools/bzl/maven_jar.bzl
index ce4730f..ed1504d 100644
--- a/tools/bzl/maven_jar.bzl
+++ b/tools/bzl/maven_jar.bzl
@@ -1,4 +1,4 @@
-load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", _GERRIT = "GERRIT", _maven_jar = "maven_jar")
+load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl", _gerrit = "GERRIT", _maven_jar = "maven_jar")
 
-GERRIT = _GERRIT
 maven_jar = _maven_jar
+GERRIT = _gerrit