Merge "Fix duplicate revert messages in `RevertSubmission`."
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index 3107e7c..951cc9c 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -492,7 +492,7 @@
 Maven dependencies are maintained in two separate files: `tools/deps.toml` and
 `tools/nongoogle.toml`. Depending on whether Google will use the dependency
 or not, dependencies should be added to one or the other file. If unsure, the
-dependency should be added to `tools/deps.bzl`. A Googler will check the dependency
+dependency should be added to `tools/deps.toml`. A Googler will check the dependency
 during review and provide feedback.
 
 When adding a new maven dependency add a line like this:
@@ -510,7 +510,7 @@
 
 [source,bash]
 ----
-REPIN=1 bazel run @gerrit_deps//:pin
+REPIN=1 bazel run @external_deps//:pin
 ----
 
 == Building against unpublished Maven JARs
diff --git a/MODULE.bazel b/MODULE.bazel
index df46187..0f438c7 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -33,11 +33,55 @@
 
 maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
 
+# Root-level dependency versions declared by Gerrit must take precedence over
+# versions contributed by layered modules (e.g. JGit) when resolving the shared
+# maven.install("external_deps") repository.
+#
+# rules_jvm_external currently lacks a mechanism for the root module to globally
+# enforce its declared versions across the layered Maven graph when using
+# bzlmod. In particular, version_conflict_policy = "pinned" still fails early
+# with duplicate artifacts when multiple modules contribute different versions.
+#
+# As a workaround, we explicitly force the root-selected versions here via
+# maven.amend_artifact(force_version = "true") for GA coordinates that may also
+# be introduced transitively by JGit.
+#
+# Versions themselves are sourced from deps.toml and the pinned lockfile.
+#
+# TODO(davido): Remove this workaround once global root version enforcement is
+# supported in rules_jvm_external:
+# https://github.com/bazel-contrib/rules_jvm_external/issues/1549
+_GERRIT_FORCED_ARTIFACTS = [
+    "args4j:args4j",
+    "com.googlecode.javaewah:JavaEWAH",
+    "commons-codec:commons-codec",
+    "org.apache.commons:commons-lang3",
+    "org.eclipse.jetty:jetty-http",
+    "org.eclipse.jetty:jetty-io",
+    "org.eclipse.jetty:jetty-security",
+    "org.eclipse.jetty:jetty-server",
+    "org.eclipse.jetty:jetty-util",
+    "org.eclipse.jetty:jetty-util-ajax",
+]
+
+[
+    maven.amend_artifact(
+        name = "external_deps",
+        coordinates = coord,
+        force_version = "true",
+    )
+    for coord in _GERRIT_FORCED_ARTIFACTS
+]
+
 # Empty maven.install call to apply the configuration to the installation from
 # toml files.
 maven.install(
-    name = "gerrit_deps",
+    name = "external_deps",
     artifacts = [],
+    # CRITICAL: Must remain "error".
+    # This guarantees fail-fast behavior if multiple versions of the same
+    # artifact are introduced by contributing modules. Downgrading this to
+    # "warn" would allow version skew to silently leak into release.war.
     duplicate_version_warning = "error",
     excluded_artifacts = [
         # Although flexmark is published as many small modules, the `flexmark-all`
@@ -136,20 +180,23 @@
     fail_if_repin_required = True,
     fail_on_missing_checksum = True,
     fetch_sources = True,
-    lock_file = "//:gerrit_deps.lock.json",
+    known_contributing_modules = [
+        "jgit",
+        "gerrit",
+    ],
+    lock_file = "//:external_deps.lock.json",
     repositories = [
         "https://repo1.maven.org/maven2",
         "https://gerrit-maven.storage.googleapis.com",
     ],
-    strict_visibility = True,
     version_conflict_policy = "pinned",
 )
 maven.from_toml(
-    name = "gerrit_deps",
+    name = "external_deps",
     libs_versions_toml = "//tools:deps.toml",
 )
 maven.from_toml(
-    name = "gerrit_deps",
+    name = "external_deps",
     libs_versions_toml = "//tools:nongoogle.toml",
 )
-use_repo(maven, "gerrit_deps")
+use_repo(maven, "external_deps")
diff --git a/gerrit_deps.lock.json b/external_deps.lock.json
similarity index 91%
rename from gerrit_deps.lock.json
rename to external_deps.lock.json
index 4399e21..88c09e0 100644
--- a/gerrit_deps.lock.json
+++ b/external_deps.lock.json
@@ -3,7 +3,7 @@
   "__INPUT_ARTIFACTS_HASH": {
     "antlr:antlr": 1249073166,
     "aopalliance:aopalliance": -1416324331,
-    "args4j:args4j": 1223353088,
+    "args4j:args4j": 484840357,
     "ch.qos.reload4j:reload4j": -1216325797,
     "com.github.ben-manes.caffeine:caffeine": 1735183231,
     "com.github.ben-manes.caffeine:guava": -2131703186,
@@ -17,6 +17,7 @@
     "com.google.code.gson:gson": 245099245,
     "com.google.common.html.types:types": 1474029483,
     "com.google.errorprone:error_prone_annotations": -1409032738,
+    "com.google.errorprone:error_prone_type_annotations": -1223112919,
     "com.google.escapevelocity:escapevelocity": -17168624,
     "com.google.flogger:flogger": -825712792,
     "com.google.flogger:flogger-log4j-backend": 1730247028,
@@ -38,7 +39,7 @@
     "com.google.truth.extensions:truth-liteproto-extension": 1463279446,
     "com.google.truth.extensions:truth-proto-extension": 1270333764,
     "com.google.truth:truth": -790731381,
-    "com.googlecode.javaewah:JavaEWAH": 1888112392,
+    "com.googlecode.javaewah:JavaEWAH": 1414179411,
     "com.googlecode.prolog-cafe:prolog-cafeteria": 1472963375,
     "com.googlecode.prolog-cafe:prolog-compiler": -348984778,
     "com.googlecode.prolog-cafe:prolog-io": -1081577073,
@@ -46,6 +47,8 @@
     "com.h2database:h2": 867138720,
     "com.ibm.icu:icu4j": -802150924,
     "com.icegreen:greenmail": -1151466560,
+    "com.jcraft:jsch": 1133842314,
+    "com.jcraft:jzlib": 864660349,
     "com.ryanharter.auto.value:auto-value-gson-extension": 520453879,
     "com.ryanharter.auto.value:auto-value-gson-factory": 1068512450,
     "com.ryanharter.auto.value:auto-value-gson-runtime": 187755792,
@@ -101,12 +104,12 @@
     "com.vladsch.flexmark:flexmark-util-visitor": -1002447604,
     "com.vladsch.flexmark:flexmark-youtrack-converter": -1024344568,
     "commons-beanutils:commons-beanutils": -399736270,
-    "commons-codec:commons-codec": 828154456,
+    "commons-codec:commons-codec": -1724312797,
     "commons-collections:commons-collections": -1308259318,
     "commons-dbcp:commons-dbcp": -873877417,
     "commons-digester:commons-digester": 1688456634,
     "commons-io:commons-io": -1192334111,
-    "commons-logging:commons-logging": 2056692342,
+    "commons-logging:commons-logging": 416626737,
     "commons-net:commons-net": 1227155931,
     "commons-pool:commons-pool": -2015226625,
     "commons-validator:commons-validator": -89255997,
@@ -124,13 +127,17 @@
     "log4j:log4j": 182326902,
     "net.bytebuddy:byte-buddy": -628486182,
     "net.bytebuddy:byte-buddy-agent": -1065427230,
+    "net.java.dev.jna:jna": 929040997,
+    "net.java.dev.jna:jna-platform": 1235639073,
     "net.minidev:json-smart": -1043043954,
+    "net.sf.jopt-simple:jopt-simple": 906822697,
     "net.sourceforge.nekohtml:nekohtml": 1723624706,
     "org.antlr:antlr": -2055062274,
     "org.antlr:antlr-runtime": -2145792567,
     "org.antlr:stringtemplate": -752719922,
     "org.apache.commons:commons-compress": -1289113474,
-    "org.apache.commons:commons-lang3": -1897960160,
+    "org.apache.commons:commons-lang3": 109544183,
+    "org.apache.commons:commons-math3": -1738699872,
     "org.apache.commons:commons-text": -1886494041,
     "org.apache.httpcomponents:fluent-hc": 58615850,
     "org.apache.httpcomponents:httpclient": 1643860045,
@@ -152,6 +159,7 @@
     "org.apache.sshd:sshd-osgi": 1671034928,
     "org.apache.sshd:sshd-sftp": 2079258759,
     "org.asciidoctor:asciidoctorj": -457860213,
+    "org.assertj:assertj-core": -1145412507,
     "org.bouncycastle:bcpg-jdk18on": 235240928,
     "org.bouncycastle:bcpkix-jdk18on": 1954093523,
     "org.bouncycastle:bcprov-jdk18on": 402064210,
@@ -160,14 +168,18 @@
     "org.commonmark:commonmark-ext-autolink": -1853742120,
     "org.commonmark:commonmark-ext-gfm-strikethrough": 350394231,
     "org.commonmark:commonmark-ext-gfm-tables": 1881582931,
-    "org.eclipse.jetty:jetty-http": -1084689220,
-    "org.eclipse.jetty:jetty-io": 1206202206,
+    "org.eclipse.jetty.ee8:jetty-ee8-nested": -685134473,
+    "org.eclipse.jetty.ee8:jetty-ee8-security": 2052418638,
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet": -1368555033,
+    "org.eclipse.jetty:jetty-http": 1984891007,
+    "org.eclipse.jetty:jetty-io": 1765684893,
     "org.eclipse.jetty:jetty-jmx": -1704061949,
-    "org.eclipse.jetty:jetty-security": 879497732,
-    "org.eclipse.jetty:jetty-server": 1530157281,
+    "org.eclipse.jetty:jetty-security": 1160320567,
+    "org.eclipse.jetty:jetty-server": 280305722,
     "org.eclipse.jetty:jetty-servlet": 697742931,
-    "org.eclipse.jetty:jetty-util": 1271788162,
-    "org.eclipse.jetty:jetty-util-ajax": -1924489267,
+    "org.eclipse.jetty:jetty-session": 292732683,
+    "org.eclipse.jetty:jetty-util": -1520256775,
+    "org.eclipse.jetty:jetty-util-ajax": -726746674,
     "org.hamcrest:hamcrest": 1547523135,
     "org.jruby:jruby-complete": -2103568068,
     "org.json:json": -811907600,
@@ -176,6 +188,8 @@
     "org.nibor.autolink:autolink": -342487050,
     "org.objenesis:objenesis": 748376655,
     "org.openid4java:openid4java": -842286787,
+    "org.openjdk.jmh:jmh-core": 983716932,
+    "org.openjdk.jmh:jmh-generator-annprocess": -1162360421,
     "org.ow2.asm:asm": 1206815935,
     "org.ow2.asm:asm-analysis": 53497832,
     "org.ow2.asm:asm-commons": 1607605466,
@@ -188,6 +202,7 @@
     "org.slf4j:slf4j-ext": 890682116,
     "org.slf4j:slf4j-log4j12": -630224096,
     "org.slf4j:slf4j-reload4j": -1466046388,
+    "org.slf4j:slf4j-simple": -487947767,
     "org.tukaani:xz": 64286142,
     "repositories": 2019057769,
     "xerces:xercesImpl": -1165914651,
@@ -286,6 +301,10 @@
     "com.ibm.icu:icu4j:jar:sources": 864352766,
     "com.icegreen:greenmail": 798674118,
     "com.icegreen:greenmail:jar:sources": -1978817971,
+    "com.jcraft:jsch": 1986987929,
+    "com.jcraft:jsch:jar:sources": 707308247,
+    "com.jcraft:jzlib": 1581025040,
+    "com.jcraft:jzlib:jar:sources": 807243431,
     "com.ryanharter.auto.value:auto-value-gson-extension": -887048407,
     "com.ryanharter.auto.value:auto-value-gson-extension:jar:sources": 1925708692,
     "com.ryanharter.auto.value:auto-value-gson-factory": -1576123811,
@@ -332,8 +351,14 @@
     "net.bytebuddy:byte-buddy-agent": -36999869,
     "net.bytebuddy:byte-buddy-agent:jar:sources": -1736884395,
     "net.bytebuddy:byte-buddy:jar:sources": -102524345,
+    "net.java.dev.jna:jna": -1916526385,
+    "net.java.dev.jna:jna-platform": 459618853,
+    "net.java.dev.jna:jna-platform:jar:sources": -2077304647,
+    "net.java.dev.jna:jna:jar:sources": 1518406952,
     "net.minidev:json-smart": -1913865264,
     "net.minidev:json-smart:jar:sources": 475976688,
+    "net.sf.jopt-simple:jopt-simple": 1531230776,
+    "net.sf.jopt-simple:jopt-simple:jar:sources": -1087190884,
     "net.sourceforge.nekohtml:nekohtml": 589300296,
     "net.sourceforge.nekohtml:nekohtml:jar:sources": 1455941061,
     "org.antlr:ST4": 943007212,
@@ -348,6 +373,8 @@
     "org.apache.commons:commons-compress:jar:sources": 128824058,
     "org.apache.commons:commons-lang3": 1593572986,
     "org.apache.commons:commons-lang3:jar:sources": 1589181154,
+    "org.apache.commons:commons-math3": 1532637713,
+    "org.apache.commons:commons-math3:jar:sources": 1655744467,
     "org.apache.commons:commons-text": -1205775100,
     "org.apache.commons:commons-text:jar:sources": 1247506591,
     "org.apache.httpcomponents:fluent-hc": 1857459163,
@@ -380,6 +407,8 @@
     "org.apache.sshd:sshd-sftp:jar:sources": 1450030982,
     "org.asciidoctor:asciidoctorj": -943976727,
     "org.asciidoctor:asciidoctorj:jar:sources": -1022891917,
+    "org.assertj:assertj-core": -1968284012,
+    "org.assertj:assertj-core:jar:sources": 1906472612,
     "org.bouncycastle:bcpg-jdk18on": -733747199,
     "org.bouncycastle:bcpg-jdk18on:jar:sources": -1694649401,
     "org.bouncycastle:bcpkix-jdk18on": -1768219399,
@@ -400,6 +429,14 @@
     "org.commonmark:commonmark-ext-gfm-tables": -435057552,
     "org.commonmark:commonmark-ext-gfm-tables:jar:sources": -1247551792,
     "org.commonmark:commonmark:jar:sources": -1275158082,
+    "org.eclipse.jetty.ee8:jetty-ee8-nested": 1225428153,
+    "org.eclipse.jetty.ee8:jetty-ee8-nested:jar:sources": 1999421701,
+    "org.eclipse.jetty.ee8:jetty-ee8-security": 667551496,
+    "org.eclipse.jetty.ee8:jetty-ee8-security:jar:sources": 447244400,
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet": 368157283,
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet:jar:sources": -2138255372,
+    "org.eclipse.jetty.toolchain:jetty-servlet-api": 626738376,
+    "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:sources": -717561233,
     "org.eclipse.jetty:jetty-http": -2051325092,
     "org.eclipse.jetty:jetty-http:jar:sources": -882391521,
     "org.eclipse.jetty:jetty-io": 1774579468,
@@ -412,6 +449,8 @@
     "org.eclipse.jetty:jetty-server:jar:sources": -710016839,
     "org.eclipse.jetty:jetty-servlet": -974397932,
     "org.eclipse.jetty:jetty-servlet:jar:sources": 1281350506,
+    "org.eclipse.jetty:jetty-session": 1978843064,
+    "org.eclipse.jetty:jetty-session:jar:sources": 244883860,
     "org.eclipse.jetty:jetty-util": 2086696316,
     "org.eclipse.jetty:jetty-util-ajax": -451213174,
     "org.eclipse.jetty:jetty-util-ajax:jar:sources": 1686109257,
@@ -434,6 +473,10 @@
     "org.objenesis:objenesis:jar:sources": 707329220,
     "org.openid4java:openid4java": 1656473252,
     "org.openid4java:openid4java:jar:sources": 789962531,
+    "org.openjdk.jmh:jmh-core": -381500549,
+    "org.openjdk.jmh:jmh-core:jar:sources": -1014071512,
+    "org.openjdk.jmh:jmh-generator-annprocess": -1315975534,
+    "org.openjdk.jmh:jmh-generator-annprocess:jar:sources": 81479330,
     "org.ow2.asm:asm": 1540593910,
     "org.ow2.asm:asm-analysis": 1735619699,
     "org.ow2.asm:asm-analysis:jar:sources": 609078251,
@@ -456,6 +499,8 @@
     "org.slf4j:slf4j-ext:jar:sources": 1756640360,
     "org.slf4j:slf4j-reload4j": 874028571,
     "org.slf4j:slf4j-reload4j:jar:sources": 1517828526,
+    "org.slf4j:slf4j-simple": 2142683014,
+    "org.slf4j:slf4j-simple:jar:sources": 334190933,
     "org.tukaani:xz": 1462559085,
     "org.tukaani:xz:jar:sources": 1791731254,
     "xerces:xercesImpl": -723395208,
@@ -789,6 +834,20 @@
       },
       "version": "1.5.5"
     },
+    "com.jcraft:jsch": {
+      "shasums": {
+        "jar": "d492b15a6d2ea3f1cc39c422c953c40c12289073dbe8360d98c0f6f9ec74fc44",
+        "sources": "e01ff2d282aa1b492bbb6187b3e363cd20a6ef51a6f23ae0ec4be179570a8480"
+      },
+      "version": "0.1.55"
+    },
+    "com.jcraft:jzlib": {
+      "shasums": {
+        "jar": "89b1360f407381bf61fde411019d8cbd009ebb10cff715f3669017a031027560",
+        "sources": "35ebd67941ce7024e6e7d80b60a4252a9687fa0f909a7079ac904bef6c1658cf"
+      },
+      "version": "1.1.3"
+    },
     "com.ryanharter.auto.value:auto-value-gson-extension": {
       "shasums": {
         "jar": "261be84be30a56994e132d718a85efcd579197a2edb9426b84c5722c56955eca",
@@ -955,6 +1014,20 @@
       },
       "version": "1.18.4"
     },
+    "net.java.dev.jna:jna": {
+      "shasums": {
+        "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557",
+        "sources": "0b9224e215b3c6a464959e3f994ddd64c14d46fb4014facd6afa1cc18e469466"
+      },
+      "version": "5.18.1"
+    },
+    "net.java.dev.jna:jna-platform": {
+      "shasums": {
+        "jar": "ad14c1b1ec4f43d396231219dfa635ebf828f738eac9f890ea1bc07795892d9a",
+        "sources": "5ffcac4b35114c6539ab9485592a90153ddeefb60e675dd9e8a2ee24e54ec1bc"
+      },
+      "version": "5.18.1"
+    },
     "net.minidev:json-smart": {
       "shasums": {
         "jar": "cebda25c3191aa441673c43d7a5a9567aa5d86a10101ae915a885c90bcee8771",
@@ -962,6 +1035,13 @@
       },
       "version": "1.1.1"
     },
+    "net.sf.jopt-simple:jopt-simple": {
+      "shasums": {
+        "jar": "df26cc58f235f477db07f753ba5a3ab243ebe5789d9f89ecf68dd62ea9a66c28",
+        "sources": "06b283801a5a94ef697b7f2c79a048c4e2f848b3daddda61cab74d882bdd97a5"
+      },
+      "version": "5.0.4"
+    },
     "net.sourceforge.nekohtml:nekohtml": {
       "shasums": {
         "jar": "f44f6f6b355dfb083cdbd5b33c9d7920fef0c77281095df30a2b18ba5eb60d69",
@@ -1011,6 +1091,13 @@
       },
       "version": "3.18.0"
     },
+    "org.apache.commons:commons-math3": {
+      "shasums": {
+        "jar": "1e56d7b058d28b65abd256b8458e3885b674c1d588fa43cd7d1cbb9c7ef2b308",
+        "sources": "e2ff85a3c360d56c51a7021614a194f3fbaf224054642ac535016f118322934d"
+      },
+      "version": "3.6.1"
+    },
     "org.apache.commons:commons-text": {
       "shasums": {
         "jar": "58d2da30f058512a1e7f914e39241deca4dff5c27a085b4ed2faa9e7208067f6",
@@ -1123,6 +1210,13 @@
       },
       "version": "1.5.8.1"
     },
+    "org.assertj:assertj-core": {
+      "shasums": {
+        "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f",
+        "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee"
+      },
+      "version": "3.27.7"
+    },
     "org.bouncycastle:bcpg-jdk18on": {
       "shasums": {
         "jar": "4077fd4517761c98a81944c70a376ce73f4eb3e44c03db1eb5d699fc28ab48aa",
@@ -1193,6 +1287,34 @@
       },
       "version": "0.24.0"
     },
+    "org.eclipse.jetty.ee8:jetty-ee8-nested": {
+      "shasums": {
+        "jar": "0bcc1d92d6dc482bac55979b6c9d7756f8b061295fc41cf2713354f9bd464c38",
+        "sources": "82f199d42bbfaecdf1574347191f9177af11d4ea692760cd0a84d0b8c89b4a53"
+      },
+      "version": "12.1.5"
+    },
+    "org.eclipse.jetty.ee8:jetty-ee8-security": {
+      "shasums": {
+        "jar": "789ba4518cd2848563473d636270b42c541d34cf79bed36c84e3ce811f76c2cd",
+        "sources": "f232e995398de354b6d4c8fe67b60a708bae0b0cccfe933787ed8966886e3139"
+      },
+      "version": "12.1.5"
+    },
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet": {
+      "shasums": {
+        "jar": "3c27e08483b1f2860e727c7577e094e63af595159dabe28022dd4e10e37f12b0",
+        "sources": "4a2e1e23c428c562bc456cc62e8bb0848f571c7505460b56927d51240e899474"
+      },
+      "version": "12.1.5"
+    },
+    "org.eclipse.jetty.toolchain:jetty-servlet-api": {
+      "shasums": {
+        "jar": "d90bf1f8a9d2ba89f4510bb51e1516dcf94ef6dc034e00f233654abdd78f2210",
+        "sources": "4184a1bf70ea545bceb0a5aef1061e1f9986d9fe8f22a1cc77cf22931fcb9029"
+      },
+      "version": "4.0.6"
+    },
     "org.eclipse.jetty:jetty-http": {
       "shasums": {
         "jar": "02c6514977f0051dfdecf8d0799acf7a88fd8008a5fd9320a92f2e5db45d297b",
@@ -1235,6 +1357,13 @@
       },
       "version": "9.4.57.v20241219"
     },
+    "org.eclipse.jetty:jetty-session": {
+      "shasums": {
+        "jar": "ebe4f30c6fe7656294d884e1dc8eea4c77b6c861e3c010847a76fd78164ae166",
+        "sources": "629906b99619eee119e44ff3c786c89ef20350958e16546fd62fb4ec7f08c6d9"
+      },
+      "version": "12.1.5"
+    },
     "org.eclipse.jetty:jetty-util": {
       "shasums": {
         "jar": "6ccbf678716778e316cc097d8aada4fe2a2e16c0bbfd8a1763204d6724b423f4",
@@ -1312,6 +1441,20 @@
       },
       "version": "1.0.0"
     },
+    "org.openjdk.jmh:jmh-core": {
+      "shasums": {
+        "jar": "dc0eaf2bbf0036a70b60798c785d6e03a9daf06b68b8edb0f1ba9eb3421baeb3",
+        "sources": "fd4beda07b3b94cd0e32199401bbb2d9ed3371a770c8c320761b9442ff3e8e05"
+      },
+      "version": "1.37"
+    },
+    "org.openjdk.jmh:jmh-generator-annprocess": {
+      "shasums": {
+        "jar": "6a5604b5b804e0daca1145df1077609321687734a8b49387e49f10557c186c77",
+        "sources": "cc1b661fb209ae1a433e331e8e78bab680674153b0a6ac69d47d11c60fb5e47e"
+      },
+      "version": "1.37"
+    },
     "org.ow2.asm:asm": {
       "shasums": {
         "jar": "6f3828a215c920059a5efa2fb55c233d6c54ec5cadca99ce1b1bdd10077c7ddd",
@@ -1389,6 +1532,13 @@
       },
       "version": "2.0.17"
     },
+    "org.slf4j:slf4j-simple": {
+      "shasums": {
+        "jar": "ddfea59ac074c6d3e24ac2c38622d2d963895e17f70b38ed4bdae4d780be6964",
+        "sources": "30b660e79419bfcebd678e75bdfe3644eaf325f50253a68395d93634da5953df"
+      },
+      "version": "2.0.17"
+    },
     "org.tukaani:xz": {
       "shasums": {
         "jar": "0a4077f6aeae2865532a564807af8d30c26acc6f63b7928d93bd7ab1f2190449",
@@ -1566,6 +1716,9 @@
     "junit:junit": [
       "org.hamcrest:hamcrest-core"
     ],
+    "net.java.dev.jna:jna-platform": [
+      "net.java.dev.jna:jna"
+    ],
     "net.sourceforge.nekohtml:nekohtml": [
       "xerces:xercesImpl"
     ],
@@ -1629,6 +1782,9 @@
       "com.beust:jcommander",
       "org.jruby:jruby-complete"
     ],
+    "org.assertj:assertj-core": [
+      "net.bytebuddy:byte-buddy"
+    ],
     "org.bouncycastle:bcpg-jdk18on": [
       "org.bouncycastle:bcprov-jdk18on",
       "org.bouncycastle:bcutil-jdk18on"
@@ -1649,6 +1805,23 @@
     "org.commonmark:commonmark-ext-gfm-tables": [
       "org.commonmark:commonmark"
     ],
+    "org.eclipse.jetty.ee8:jetty-ee8-nested": [
+      "org.eclipse.jetty.toolchain:jetty-servlet-api",
+      "org.eclipse.jetty:jetty-http",
+      "org.eclipse.jetty:jetty-security",
+      "org.eclipse.jetty:jetty-server",
+      "org.eclipse.jetty:jetty-session",
+      "org.slf4j:slf4j-api"
+    ],
+    "org.eclipse.jetty.ee8:jetty-ee8-security": [
+      "org.eclipse.jetty.ee8:jetty-ee8-nested",
+      "org.slf4j:slf4j-api"
+    ],
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet": [
+      "org.eclipse.jetty.ee8:jetty-ee8-nested",
+      "org.eclipse.jetty.ee8:jetty-ee8-security",
+      "org.slf4j:slf4j-api"
+    ],
     "org.eclipse.jetty:jetty-http": [
       "org.eclipse.jetty:jetty-io",
       "org.eclipse.jetty:jetty-util"
@@ -1671,6 +1844,10 @@
       "org.eclipse.jetty:jetty-security",
       "org.eclipse.jetty:jetty-util-ajax"
     ],
+    "org.eclipse.jetty:jetty-session": [
+      "org.eclipse.jetty:jetty-server",
+      "org.slf4j:slf4j-api"
+    ],
     "org.eclipse.jetty:jetty-util-ajax": [
       "org.eclipse.jetty:jetty-util"
     ],
@@ -1685,6 +1862,13 @@
       "org.apache.httpcomponents:httpclient",
       "xerces:xercesImpl"
     ],
+    "org.openjdk.jmh:jmh-core": [
+      "net.sf.jopt-simple:jopt-simple",
+      "org.apache.commons:commons-math3"
+    ],
+    "org.openjdk.jmh:jmh-generator-annprocess": [
+      "org.openjdk.jmh:jmh-core"
+    ],
     "org.ow2.asm:asm-analysis": [
       "org.ow2.asm:asm-tree"
     ],
@@ -1712,6 +1896,9 @@
     "org.slf4j:slf4j-reload4j": [
       "ch.qos.reload4j:reload4j",
       "org.slf4j:slf4j-api"
+    ],
+    "org.slf4j:slf4j-simple": [
+      "org.slf4j:slf4j-api"
     ]
   },
   "packages": {
@@ -2151,6 +2338,15 @@
       "com.icegreen.greenmail.user",
       "com.icegreen.greenmail.util"
     ],
+    "com.jcraft:jsch": [
+      "com.jcraft.jsch",
+      "com.jcraft.jsch.jce",
+      "com.jcraft.jsch.jcraft",
+      "com.jcraft.jsch.jgss"
+    ],
+    "com.jcraft:jzlib": [
+      "com.jcraft.jzlib"
+    ],
     "com.ryanharter.auto.value:auto-value-gson-extension": [
       "autovaluegson.shaded.com.google.auto.common",
       "autovaluegson.shaded.com.google.common.annotations",
@@ -2497,10 +2693,38 @@
       "net.bytebuddy.agent",
       "net.bytebuddy.agent.utility.nullability"
     ],
+    "net.java.dev.jna:jna": [
+      "com.sun.jna",
+      "com.sun.jna.internal",
+      "com.sun.jna.ptr",
+      "com.sun.jna.win32"
+    ],
+    "net.java.dev.jna:jna-platform": [
+      "com.sun.jna.platform",
+      "com.sun.jna.platform.bsd",
+      "com.sun.jna.platform.dnd",
+      "com.sun.jna.platform.linux",
+      "com.sun.jna.platform.mac",
+      "com.sun.jna.platform.unix",
+      "com.sun.jna.platform.unix.aix",
+      "com.sun.jna.platform.unix.solaris",
+      "com.sun.jna.platform.win32",
+      "com.sun.jna.platform.win32.COM",
+      "com.sun.jna.platform.win32.COM.tlb",
+      "com.sun.jna.platform.win32.COM.tlb.imp",
+      "com.sun.jna.platform.win32.COM.util",
+      "com.sun.jna.platform.win32.COM.util.annotation",
+      "com.sun.jna.platform.wince"
+    ],
     "net.minidev:json-smart": [
       "net.minidev.json",
       "net.minidev.json.parser"
     ],
+    "net.sf.jopt-simple:jopt-simple": [
+      "joptsimple",
+      "joptsimple.internal",
+      "joptsimple.util"
+    ],
     "net.sourceforge.nekohtml:nekohtml": [
       "org.cyberneko.html",
       "org.cyberneko.html.filters",
@@ -2593,6 +2817,83 @@
       "org.apache.commons.lang3.tuple",
       "org.apache.commons.lang3.util"
     ],
+    "org.apache.commons:commons-math3": [
+      "org.apache.commons.math3",
+      "org.apache.commons.math3.analysis",
+      "org.apache.commons.math3.analysis.differentiation",
+      "org.apache.commons.math3.analysis.function",
+      "org.apache.commons.math3.analysis.integration",
+      "org.apache.commons.math3.analysis.integration.gauss",
+      "org.apache.commons.math3.analysis.interpolation",
+      "org.apache.commons.math3.analysis.polynomials",
+      "org.apache.commons.math3.analysis.solvers",
+      "org.apache.commons.math3.complex",
+      "org.apache.commons.math3.dfp",
+      "org.apache.commons.math3.distribution",
+      "org.apache.commons.math3.distribution.fitting",
+      "org.apache.commons.math3.exception",
+      "org.apache.commons.math3.exception.util",
+      "org.apache.commons.math3.filter",
+      "org.apache.commons.math3.fitting",
+      "org.apache.commons.math3.fitting.leastsquares",
+      "org.apache.commons.math3.fraction",
+      "org.apache.commons.math3.genetics",
+      "org.apache.commons.math3.geometry",
+      "org.apache.commons.math3.geometry.enclosing",
+      "org.apache.commons.math3.geometry.euclidean.oned",
+      "org.apache.commons.math3.geometry.euclidean.threed",
+      "org.apache.commons.math3.geometry.euclidean.twod",
+      "org.apache.commons.math3.geometry.euclidean.twod.hull",
+      "org.apache.commons.math3.geometry.hull",
+      "org.apache.commons.math3.geometry.partitioning",
+      "org.apache.commons.math3.geometry.partitioning.utilities",
+      "org.apache.commons.math3.geometry.spherical.oned",
+      "org.apache.commons.math3.geometry.spherical.twod",
+      "org.apache.commons.math3.linear",
+      "org.apache.commons.math3.ml.clustering",
+      "org.apache.commons.math3.ml.clustering.evaluation",
+      "org.apache.commons.math3.ml.distance",
+      "org.apache.commons.math3.ml.neuralnet",
+      "org.apache.commons.math3.ml.neuralnet.oned",
+      "org.apache.commons.math3.ml.neuralnet.sofm",
+      "org.apache.commons.math3.ml.neuralnet.sofm.util",
+      "org.apache.commons.math3.ml.neuralnet.twod",
+      "org.apache.commons.math3.ml.neuralnet.twod.util",
+      "org.apache.commons.math3.ode",
+      "org.apache.commons.math3.ode.events",
+      "org.apache.commons.math3.ode.nonstiff",
+      "org.apache.commons.math3.ode.sampling",
+      "org.apache.commons.math3.optim",
+      "org.apache.commons.math3.optim.linear",
+      "org.apache.commons.math3.optim.nonlinear.scalar",
+      "org.apache.commons.math3.optim.nonlinear.scalar.gradient",
+      "org.apache.commons.math3.optim.nonlinear.scalar.noderiv",
+      "org.apache.commons.math3.optim.nonlinear.vector",
+      "org.apache.commons.math3.optim.nonlinear.vector.jacobian",
+      "org.apache.commons.math3.optim.univariate",
+      "org.apache.commons.math3.optimization",
+      "org.apache.commons.math3.optimization.direct",
+      "org.apache.commons.math3.optimization.fitting",
+      "org.apache.commons.math3.optimization.general",
+      "org.apache.commons.math3.optimization.linear",
+      "org.apache.commons.math3.optimization.univariate",
+      "org.apache.commons.math3.primes",
+      "org.apache.commons.math3.random",
+      "org.apache.commons.math3.special",
+      "org.apache.commons.math3.stat",
+      "org.apache.commons.math3.stat.clustering",
+      "org.apache.commons.math3.stat.correlation",
+      "org.apache.commons.math3.stat.descriptive",
+      "org.apache.commons.math3.stat.descriptive.moment",
+      "org.apache.commons.math3.stat.descriptive.rank",
+      "org.apache.commons.math3.stat.descriptive.summary",
+      "org.apache.commons.math3.stat.inference",
+      "org.apache.commons.math3.stat.interval",
+      "org.apache.commons.math3.stat.ranking",
+      "org.apache.commons.math3.stat.regression",
+      "org.apache.commons.math3.transform",
+      "org.apache.commons.math3.util"
+    ],
     "org.apache.commons:commons-text": [
       "org.apache.commons.text",
       "org.apache.commons.text.diff",
@@ -3038,6 +3339,37 @@
       "org.asciidoctor.log",
       "org.asciidoctor.log.internal"
     ],
+    "org.assertj:assertj-core": [
+      "org.assertj.core.annotation",
+      "org.assertj.core.annotations",
+      "org.assertj.core.api",
+      "org.assertj.core.api.exception",
+      "org.assertj.core.api.filter",
+      "org.assertj.core.api.iterable",
+      "org.assertj.core.api.junit.jupiter",
+      "org.assertj.core.api.recursive",
+      "org.assertj.core.api.recursive.assertion",
+      "org.assertj.core.api.recursive.comparison",
+      "org.assertj.core.condition",
+      "org.assertj.core.configuration",
+      "org.assertj.core.data",
+      "org.assertj.core.description",
+      "org.assertj.core.error",
+      "org.assertj.core.error.array2d",
+      "org.assertj.core.error.future",
+      "org.assertj.core.error.uri",
+      "org.assertj.core.extractor",
+      "org.assertj.core.groups",
+      "org.assertj.core.internal",
+      "org.assertj.core.internal.annotation",
+      "org.assertj.core.matcher",
+      "org.assertj.core.presentation",
+      "org.assertj.core.util",
+      "org.assertj.core.util.diff",
+      "org.assertj.core.util.diff.myers",
+      "org.assertj.core.util.introspection",
+      "org.assertj.core.util.xml"
+    ],
     "org.bouncycastle:bcpg-jdk18on": [
       "org.bouncycastle.apache.bzip2",
       "org.bouncycastle.bcpg",
@@ -3412,6 +3744,25 @@
       "org.commonmark.ext.gfm.tables",
       "org.commonmark.ext.gfm.tables.internal"
     ],
+    "org.eclipse.jetty.ee8:jetty-ee8-nested": [
+      "org.eclipse.jetty.ee8.nested",
+      "org.eclipse.jetty.ee8.nested.jmx"
+    ],
+    "org.eclipse.jetty.ee8:jetty-ee8-security": [
+      "org.eclipse.jetty.ee8.security",
+      "org.eclipse.jetty.ee8.security.authentication"
+    ],
+    "org.eclipse.jetty.ee8:jetty-ee8-servlet": [
+      "org.eclipse.jetty.ee8.servlet",
+      "org.eclipse.jetty.ee8.servlet.jmx",
+      "org.eclipse.jetty.ee8.servlet.listener"
+    ],
+    "org.eclipse.jetty.toolchain:jetty-servlet-api": [
+      "javax.servlet",
+      "javax.servlet.annotation",
+      "javax.servlet.descriptor",
+      "javax.servlet.http"
+    ],
     "org.eclipse.jetty:jetty-http": [
       "org.eclipse.jetty.http",
       "org.eclipse.jetty.http.compression",
@@ -3445,6 +3796,9 @@
       "org.eclipse.jetty.servlet.jmx",
       "org.eclipse.jetty.servlet.listener"
     ],
+    "org.eclipse.jetty:jetty-session": [
+      "org.eclipse.jetty.session"
+    ],
     "org.eclipse.jetty:jetty-util": [
       "org.eclipse.jetty.util",
       "org.eclipse.jetty.util.annotation",
@@ -3808,6 +4162,25 @@
       "org.openid4java.server",
       "org.openid4java.util"
     ],
+    "org.openjdk.jmh:jmh-core": [
+      "org.openjdk.jmh",
+      "org.openjdk.jmh.annotations",
+      "org.openjdk.jmh.generators.core",
+      "org.openjdk.jmh.infra",
+      "org.openjdk.jmh.profile",
+      "org.openjdk.jmh.results",
+      "org.openjdk.jmh.results.format",
+      "org.openjdk.jmh.runner",
+      "org.openjdk.jmh.runner.format",
+      "org.openjdk.jmh.runner.link",
+      "org.openjdk.jmh.runner.options",
+      "org.openjdk.jmh.util",
+      "org.openjdk.jmh.util.lines"
+    ],
+    "org.openjdk.jmh:jmh-generator-annprocess": [
+      "org.openjdk.jmh.generators",
+      "org.openjdk.jmh.generators.annotations"
+    ],
     "org.ow2.asm:asm": [
       "org.objectweb.asm",
       "org.objectweb.asm.signature"
@@ -3855,6 +4228,9 @@
     "org.slf4j:slf4j-reload4j": [
       "org.slf4j.reload4j"
     ],
+    "org.slf4j:slf4j-simple": [
+      "org.slf4j.simple"
+    ],
     "org.tukaani:xz": [
       "org.tukaani.xz",
       "org.tukaani.xz.check",
@@ -4003,6 +4379,10 @@
       "com.ibm.icu:icu4j:jar:sources",
       "com.icegreen:greenmail",
       "com.icegreen:greenmail:jar:sources",
+      "com.jcraft:jsch",
+      "com.jcraft:jsch:jar:sources",
+      "com.jcraft:jzlib",
+      "com.jcraft:jzlib:jar:sources",
       "com.ryanharter.auto.value:auto-value-gson-extension",
       "com.ryanharter.auto.value:auto-value-gson-extension:jar:sources",
       "com.ryanharter.auto.value:auto-value-gson-factory",
@@ -4049,8 +4429,14 @@
       "net.bytebuddy:byte-buddy-agent",
       "net.bytebuddy:byte-buddy-agent:jar:sources",
       "net.bytebuddy:byte-buddy:jar:sources",
+      "net.java.dev.jna:jna",
+      "net.java.dev.jna:jna-platform",
+      "net.java.dev.jna:jna-platform:jar:sources",
+      "net.java.dev.jna:jna:jar:sources",
       "net.minidev:json-smart",
       "net.minidev:json-smart:jar:sources",
+      "net.sf.jopt-simple:jopt-simple",
+      "net.sf.jopt-simple:jopt-simple:jar:sources",
       "net.sourceforge.nekohtml:nekohtml",
       "net.sourceforge.nekohtml:nekohtml:jar:sources",
       "org.antlr:ST4",
@@ -4065,6 +4451,8 @@
       "org.apache.commons:commons-compress:jar:sources",
       "org.apache.commons:commons-lang3",
       "org.apache.commons:commons-lang3:jar:sources",
+      "org.apache.commons:commons-math3",
+      "org.apache.commons:commons-math3:jar:sources",
       "org.apache.commons:commons-text",
       "org.apache.commons:commons-text:jar:sources",
       "org.apache.httpcomponents:fluent-hc",
@@ -4097,6 +4485,8 @@
       "org.apache.sshd:sshd-sftp:jar:sources",
       "org.asciidoctor:asciidoctorj",
       "org.asciidoctor:asciidoctorj:jar:sources",
+      "org.assertj:assertj-core",
+      "org.assertj:assertj-core:jar:sources",
       "org.bouncycastle:bcpg-jdk18on",
       "org.bouncycastle:bcpg-jdk18on:jar:sources",
       "org.bouncycastle:bcpkix-jdk18on",
@@ -4117,6 +4507,14 @@
       "org.commonmark:commonmark-ext-gfm-tables",
       "org.commonmark:commonmark-ext-gfm-tables:jar:sources",
       "org.commonmark:commonmark:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-nested",
+      "org.eclipse.jetty.ee8:jetty-ee8-nested:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-security",
+      "org.eclipse.jetty.ee8:jetty-ee8-security:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-servlet",
+      "org.eclipse.jetty.ee8:jetty-ee8-servlet:jar:sources",
+      "org.eclipse.jetty.toolchain:jetty-servlet-api",
+      "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:sources",
       "org.eclipse.jetty:jetty-http",
       "org.eclipse.jetty:jetty-http:jar:sources",
       "org.eclipse.jetty:jetty-io",
@@ -4129,6 +4527,8 @@
       "org.eclipse.jetty:jetty-server:jar:sources",
       "org.eclipse.jetty:jetty-servlet",
       "org.eclipse.jetty:jetty-servlet:jar:sources",
+      "org.eclipse.jetty:jetty-session",
+      "org.eclipse.jetty:jetty-session:jar:sources",
       "org.eclipse.jetty:jetty-util",
       "org.eclipse.jetty:jetty-util-ajax",
       "org.eclipse.jetty:jetty-util-ajax:jar:sources",
@@ -4151,6 +4551,10 @@
       "org.objenesis:objenesis:jar:sources",
       "org.openid4java:openid4java",
       "org.openid4java:openid4java:jar:sources",
+      "org.openjdk.jmh:jmh-core",
+      "org.openjdk.jmh:jmh-core:jar:sources",
+      "org.openjdk.jmh:jmh-generator-annprocess",
+      "org.openjdk.jmh:jmh-generator-annprocess:jar:sources",
       "org.ow2.asm:asm",
       "org.ow2.asm:asm-analysis",
       "org.ow2.asm:asm-analysis:jar:sources",
@@ -4173,6 +4577,8 @@
       "org.slf4j:slf4j-ext:jar:sources",
       "org.slf4j:slf4j-reload4j",
       "org.slf4j:slf4j-reload4j:jar:sources",
+      "org.slf4j:slf4j-simple",
+      "org.slf4j:slf4j-simple:jar:sources",
       "org.tukaani:xz",
       "org.tukaani:xz:jar:sources",
       "xerces:xercesImpl",
@@ -4271,6 +4677,10 @@
       "com.ibm.icu:icu4j:jar:sources",
       "com.icegreen:greenmail",
       "com.icegreen:greenmail:jar:sources",
+      "com.jcraft:jsch",
+      "com.jcraft:jsch:jar:sources",
+      "com.jcraft:jzlib",
+      "com.jcraft:jzlib:jar:sources",
       "com.ryanharter.auto.value:auto-value-gson-extension",
       "com.ryanharter.auto.value:auto-value-gson-extension:jar:sources",
       "com.ryanharter.auto.value:auto-value-gson-factory",
@@ -4317,8 +4727,14 @@
       "net.bytebuddy:byte-buddy-agent",
       "net.bytebuddy:byte-buddy-agent:jar:sources",
       "net.bytebuddy:byte-buddy:jar:sources",
+      "net.java.dev.jna:jna",
+      "net.java.dev.jna:jna-platform",
+      "net.java.dev.jna:jna-platform:jar:sources",
+      "net.java.dev.jna:jna:jar:sources",
       "net.minidev:json-smart",
       "net.minidev:json-smart:jar:sources",
+      "net.sf.jopt-simple:jopt-simple",
+      "net.sf.jopt-simple:jopt-simple:jar:sources",
       "net.sourceforge.nekohtml:nekohtml",
       "net.sourceforge.nekohtml:nekohtml:jar:sources",
       "org.antlr:ST4",
@@ -4333,6 +4749,8 @@
       "org.apache.commons:commons-compress:jar:sources",
       "org.apache.commons:commons-lang3",
       "org.apache.commons:commons-lang3:jar:sources",
+      "org.apache.commons:commons-math3",
+      "org.apache.commons:commons-math3:jar:sources",
       "org.apache.commons:commons-text",
       "org.apache.commons:commons-text:jar:sources",
       "org.apache.httpcomponents:fluent-hc",
@@ -4365,6 +4783,8 @@
       "org.apache.sshd:sshd-sftp:jar:sources",
       "org.asciidoctor:asciidoctorj",
       "org.asciidoctor:asciidoctorj:jar:sources",
+      "org.assertj:assertj-core",
+      "org.assertj:assertj-core:jar:sources",
       "org.bouncycastle:bcpg-jdk18on",
       "org.bouncycastle:bcpg-jdk18on:jar:sources",
       "org.bouncycastle:bcpkix-jdk18on",
@@ -4385,6 +4805,14 @@
       "org.commonmark:commonmark-ext-gfm-tables",
       "org.commonmark:commonmark-ext-gfm-tables:jar:sources",
       "org.commonmark:commonmark:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-nested",
+      "org.eclipse.jetty.ee8:jetty-ee8-nested:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-security",
+      "org.eclipse.jetty.ee8:jetty-ee8-security:jar:sources",
+      "org.eclipse.jetty.ee8:jetty-ee8-servlet",
+      "org.eclipse.jetty.ee8:jetty-ee8-servlet:jar:sources",
+      "org.eclipse.jetty.toolchain:jetty-servlet-api",
+      "org.eclipse.jetty.toolchain:jetty-servlet-api:jar:sources",
       "org.eclipse.jetty:jetty-http",
       "org.eclipse.jetty:jetty-http:jar:sources",
       "org.eclipse.jetty:jetty-io",
@@ -4397,6 +4825,8 @@
       "org.eclipse.jetty:jetty-server:jar:sources",
       "org.eclipse.jetty:jetty-servlet",
       "org.eclipse.jetty:jetty-servlet:jar:sources",
+      "org.eclipse.jetty:jetty-session",
+      "org.eclipse.jetty:jetty-session:jar:sources",
       "org.eclipse.jetty:jetty-util",
       "org.eclipse.jetty:jetty-util-ajax",
       "org.eclipse.jetty:jetty-util-ajax:jar:sources",
@@ -4419,6 +4849,10 @@
       "org.objenesis:objenesis:jar:sources",
       "org.openid4java:openid4java",
       "org.openid4java:openid4java:jar:sources",
+      "org.openjdk.jmh:jmh-core",
+      "org.openjdk.jmh:jmh-core:jar:sources",
+      "org.openjdk.jmh:jmh-generator-annprocess",
+      "org.openjdk.jmh:jmh-generator-annprocess:jar:sources",
       "org.ow2.asm:asm",
       "org.ow2.asm:asm-analysis",
       "org.ow2.asm:asm-analysis:jar:sources",
@@ -4441,6 +4875,8 @@
       "org.slf4j:slf4j-ext:jar:sources",
       "org.slf4j:slf4j-reload4j",
       "org.slf4j:slf4j-reload4j:jar:sources",
+      "org.slf4j:slf4j-simple",
+      "org.slf4j:slf4j-simple:jar:sources",
       "org.tukaani:xz",
       "org.tukaani:xz:jar:sources",
       "xerces:xercesImpl",
@@ -4788,6 +5224,16 @@
         "org.jruby.embed.jsr223.JRubyEngineFactory"
       ]
     },
+    "org.openjdk.jmh:jmh-generator-annprocess": {
+      "javax.annotation.processing.Processor": [
+        "org.openjdk.jmh.generators.BenchmarkProcessor"
+      ]
+    },
+    "org.openjdk.jmh:jmh-generator-annprocess:jar:sources": {
+      "javax.annotation.processing.Processor": [
+        "org.openjdk.jmh.generators.BenchmarkProcessor"
+      ]
+    },
     "org.slf4j:jcl-over-slf4j": {
       "org.apache.commons.logging.LogFactory": [
         "org.apache.commons.logging.impl.SLF4JLogFactory"
@@ -4808,6 +5254,16 @@
         "org.slf4j.reload4j.Reload4jServiceProvider"
       ]
     },
+    "org.slf4j:slf4j-simple": {
+      "org.slf4j.spi.SLF4JServiceProvider": [
+        "org.slf4j.simple.SimpleServiceProvider"
+      ]
+    },
+    "org.slf4j:slf4j-simple:jar:sources": {
+      "org.slf4j.spi.SLF4JServiceProvider": [
+        "org.slf4j.simple.SimpleServiceProvider"
+      ]
+    },
     "xerces:xercesImpl": {
       "javax.xml.datatype.DatatypeFactory": [
         "org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl"
diff --git a/lib/BUILD b/lib/BUILD
index 1f26176..7255a4d 100644
--- a/lib/BUILD
+++ b/lib/BUILD
@@ -18,21 +18,21 @@
     data = ["//lib:LICENSE-Apache2.0"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:javax_servlet_javax_servlet_api"],
+    exports = ["@external_deps//:javax_servlet_javax_servlet_api"],
 )
 
 java_library(
     name = "servlet-api-without-neverlink",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:javax_servlet_javax_servlet_api"],
+    exports = ["@external_deps//:javax_servlet_javax_servlet_api"],
 )
 
 java_library(
     name = "gson",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_code_gson_gson"],
+    exports = ["@external_deps//:com_google_code_gson_gson"],
 )
 
 java_library(
@@ -88,28 +88,28 @@
     name = "javaewah",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_googlecode_javaewah_JavaEWAH"],
+    exports = ["@external_deps//:com_googlecode_javaewah_JavaEWAH"],
 )
 
 java_library(
     name = "protobuf",
     data = ["//lib:LICENSE-protobuf"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_protobuf_protobuf_java"],
+    exports = ["@external_deps//:com_google_protobuf_protobuf_java"],
 )
 
 java_library(
     name = "guava-failureaccess",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_guava_failureaccess"],
+    exports = ["@external_deps//:com_google_guava_failureaccess"],
 )
 
 java_library(
     name = "j2objc",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_j2objc_j2objc_annotations"],
+    exports = ["@external_deps//:com_google_j2objc_j2objc_annotations"],
 )
 
 java_library(
@@ -119,7 +119,7 @@
     exports = [
         ":guava-failureaccess",
         ":j2objc",
-        "@gerrit_deps//:com_google_guava_guava",
+        "@external_deps//:com_google_guava_guava",
     ],
 )
 
@@ -128,7 +128,7 @@
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
     exports = [
-        "@gerrit_deps//:com_google_guava_guava_testlib",
+        "@external_deps//:com_google_guava_guava_testlib",
     ],
 )
 
@@ -139,7 +139,7 @@
         "//java/com/google/gerrit/acceptance:__pkg__",
         "//java/com/google/gerrit/server/cache/mem:__pkg__",
     ],
-    exports = ["@gerrit_deps//:com_github_ben_manes_caffeine_caffeine"],
+    exports = ["@external_deps//:com_github_ben_manes_caffeine_caffeine"],
 )
 
 java_library(
@@ -149,56 +149,56 @@
         "//java/com/google/gerrit/acceptance:__pkg__",
         "//java/com/google/gerrit/server/cache/mem:__pkg__",
     ],
-    exports = ["@gerrit_deps//:com_github_ben_manes_caffeine_guava"],
+    exports = ["@external_deps//:com_github_ben_manes_caffeine_guava"],
 )
 
 java_library(
     name = "args4j",
     data = ["//lib:LICENSE-args4j"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:args4j_args4j"],
+    exports = ["@external_deps//:args4j_args4j"],
 )
 
 java_library(
     name = "automaton",
     data = ["//lib:LICENSE-automaton"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:dk_brics_automaton"],
+    exports = ["@external_deps//:dk_brics_automaton"],
 )
 
 java_library(
     name = "flexmark-all-lib",
     data = ["//lib:LICENSE-flexmark"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_vladsch_flexmark_flexmark_all_lib"],
+    exports = ["@external_deps//:com_vladsch_flexmark_flexmark_all_lib"],
 )
 
 java_library(
     name = "autolink",
     data = ["//lib:LICENSE-autolink"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_nibor_autolink_autolink"],
+    exports = ["@external_deps//:org_nibor_autolink_autolink"],
 )
 
 java_library(
     name = "tukaani-xz",
     data = ["//lib:LICENSE-xz"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_tukaani_xz"],
+    exports = ["@external_deps//:org_tukaani_xz"],
 )
 
 java_library(
     name = "mime-util",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:eu_medsea_mimeutil_mime_util"],
+    exports = ["@external_deps//:eu_medsea_mimeutil_mime_util"],
 )
 
 java_library(
     name = "guava-retrying",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_github_rholder_guava_retrying"],
+    exports = ["@external_deps//:com_github_rholder_guava_retrying"],
     runtime_deps = [":jsr305"],
 )
 
@@ -206,28 +206,28 @@
     name = "jsr305",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_code_findbugs_jsr305"],
+    exports = ["@external_deps//:com_google_code_findbugs_jsr305"],
 )
 
 java_library(
     name = "blame-cache",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_gitiles_blame_cache"],
+    exports = ["@external_deps//:com_google_gitiles_blame_cache"],
 )
 
 java_library(
     name = "h2",
     data = ["//lib:LICENSE-h2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_h2database_h2"],
+    exports = ["@external_deps//:com_h2database_h2"],
 )
 
 java_library(
     name = "jimfs",
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_jimfs_jimfs"],
+    exports = ["@external_deps//:com_google_jimfs_jimfs"],
     runtime_deps = [":guava"],
 )
 
@@ -237,7 +237,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":hamcrest",
-        "@gerrit_deps//:junit_junit",
+        "@external_deps//:junit_junit",
     ],
     runtime_deps = [":hamcrest"],
 )
@@ -246,14 +246,14 @@
     name = "hamcrest",
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_hamcrest_hamcrest"],
+    exports = ["@external_deps//:org_hamcrest_hamcrest"],
 )
 
 java_library(
     name = "soy",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_template_soy"],
+    exports = ["@external_deps//:com_google_template_soy"],
     runtime_deps = [
         ":args4j",
         ":gson",
@@ -277,14 +277,14 @@
     name = "html-types",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_common_html_types_types"],
+    exports = ["@external_deps//:com_google_common_html_types_types"],
 )
 
 java_library(
     name = "icu4j",
     data = ["//lib:LICENSE-icu4j"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_ibm_icu_icu4j"],
+    exports = ["@external_deps//:com_ibm_icu_icu4j"],
 )
 
 java_library(
@@ -292,8 +292,8 @@
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
     exports = [
-        "@gerrit_deps//:org_roaringbitmap_RoaringBitmap",
-        "@gerrit_deps//:org_roaringbitmap_shims",
+        "@external_deps//:org_roaringbitmap_RoaringBitmap",
+        "@external_deps//:org_roaringbitmap_shims",
     ],
 )
 
diff --git a/lib/antlr/BUILD b/lib/antlr/BUILD
index efbf30c..f9b19c7 100644
--- a/lib/antlr/BUILD
+++ b/lib/antlr/BUILD
@@ -5,20 +5,20 @@
 java_library(
     name = "antlr27",
     data = ["//lib:LICENSE-antlr"],
-    exports = ["@gerrit_deps//:antlr_antlr_2_7_7"],
+    exports = ["@external_deps//:antlr_antlr_2_7_7"],
 )
 
 java_library(
     name = "stringtemplate",
     data = ["//lib:LICENSE-antlr"],
-    exports = ["@gerrit_deps//:org_antlr_stringtemplate"],
+    exports = ["@external_deps//:org_antlr_stringtemplate"],
 )
 
 java_library(
     name = "java-runtime",
     data = ["//lib:LICENSE-antlr"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_antlr_antlr_runtime"],
+    exports = ["@external_deps//:org_antlr_antlr_runtime"],
 )
 
 # See https://github.com/bazelbuild/bazel/issues/3542
@@ -34,7 +34,7 @@
 java_library(
     name = "tool",
     data = ["//lib:LICENSE-antlr"],
-    exports = ["@gerrit_deps//:org_antlr_antlr"],
+    exports = ["@external_deps//:org_antlr_antlr"],
     runtime_deps = [
         ":antlr27",
         ":java-runtime",
diff --git a/lib/asciidoctor/BUILD b/lib/asciidoctor/BUILD
index cde87bf..c4ca4da 100644
--- a/lib/asciidoctor/BUILD
+++ b/lib/asciidoctor/BUILD
@@ -4,12 +4,12 @@
     name = "asciidoctor",
     data = ["//lib:LICENSE-asciidoctor"],
     visibility = ["//java/com/google/gerrit/asciidoctor:__pkg__"],
-    exports = ["@gerrit_deps//:org_asciidoctor_asciidoctorj"],
+    exports = ["@external_deps//:org_asciidoctor_asciidoctorj"],
     runtime_deps = [":jruby"],
 )
 
 java_library(
     name = "jruby",
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
-    exports = ["@gerrit_deps//:org_jruby_jruby_complete"],
+    exports = ["@external_deps//:org_jruby_jruby_complete"],
 )
diff --git a/lib/auto/BUILD b/lib/auto/BUILD
index 6831996..31044b6 100644
--- a/lib/auto/BUILD
+++ b/lib/auto/BUILD
@@ -4,8 +4,8 @@
     name = "auto-annotation-plugin",
     processor_class = "com.google.auto.value.processor.AutoAnnotationProcessor",
     deps = [
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
     ],
 )
 
@@ -15,14 +15,14 @@
     processor_class = "com.google.auto.factory.processor.AutoFactoryProcessor",
     visibility = ["//visibility:private"],
     deps = [
-        "@gerrit_deps//:com_google_auto_auto_common",
-        "@gerrit_deps//:com_google_auto_factory_auto_factory",
-        "@gerrit_deps//:com_google_auto_service_auto_service_annotations",
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
-        "@gerrit_deps//:com_google_guava_guava",
-        "@gerrit_deps//:com_squareup_javapoet",
-        "@gerrit_deps//:javax_inject_javax_inject",
+        "@external_deps//:com_google_auto_auto_common",
+        "@external_deps//:com_google_auto_factory_auto_factory",
+        "@external_deps//:com_google_auto_service_auto_service_annotations",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_guava_guava",
+        "@external_deps//:com_squareup_javapoet",
+        "@external_deps//:javax_inject_javax_inject",
     ],
 )
 
@@ -30,14 +30,14 @@
     name = "auto-builder-plugin",
     processor_class = "com.google.auto.value.processor.AutoBuilderProcessor",
     deps = [
-        "@gerrit_deps//:com_google_auto_auto_common",
-        "@gerrit_deps//:com_google_auto_factory_auto_factory",
-        "@gerrit_deps//:com_google_auto_service_auto_service_annotations",
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
-        "@gerrit_deps//:com_google_guava_guava",
-        "@gerrit_deps//:com_squareup_javapoet",
-        "@gerrit_deps//:javax_inject_javax_inject",
+        "@external_deps//:com_google_auto_auto_common",
+        "@external_deps//:com_google_auto_factory_auto_factory",
+        "@external_deps//:com_google_auto_service_auto_service_annotations",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_guava_guava",
+        "@external_deps//:com_squareup_javapoet",
+        "@external_deps//:javax_inject_javax_inject",
     ],
 )
 
@@ -45,8 +45,8 @@
     name = "auto-value-plugin",
     processor_class = "com.google.auto.value.processor.AutoValueProcessor",
     deps = [
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
     ],
 )
 
@@ -54,8 +54,8 @@
     name = "auto-oneof-plugin",
     processor_class = "com.google.auto.value.processor.AutoOneOfProcessor",
     deps = [
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
     ],
 )
 
@@ -63,14 +63,14 @@
     name = "auto-value-gson-plugin",
     processor_class = "com.ryanharter.auto.value.gson.factory.AutoValueGsonAdapterFactoryProcessor",
     deps = [
-        "@gerrit_deps//:com_google_auto_value_auto_value",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
-        "@gerrit_deps//:com_google_code_gson_gson",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_extension",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_factory",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
-        "@gerrit_deps//:com_squareup_javapoet",
-        "@gerrit_deps//:io_sweers_autotransient_autotransient",
+        "@external_deps//:com_google_auto_value_auto_value",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_code_gson_gson",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_extension",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_factory",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
+        "@external_deps//:com_squareup_javapoet",
+        "@external_deps//:io_sweers_autotransient_autotransient",
     ],
 )
 
@@ -81,7 +81,7 @@
         ":auto-factory-plugin",
     ],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_auto_factory_auto_factory"],
+    exports = ["@external_deps//:com_google_auto_factory_auto_factory"],
 )
 
 java_library(
@@ -94,7 +94,7 @@
         ":auto-oneof-plugin",
     ],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_auto_value_auto_value"],
+    exports = ["@external_deps//:com_google_auto_value_auto_value"],
 )
 
 java_library(
@@ -107,7 +107,7 @@
         ":auto-oneof-plugin",
     ],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_auto_value_auto_value_annotations"],
+    exports = ["@external_deps//:com_google_auto_value_auto_value_annotations"],
 )
 
 java_library(
@@ -118,6 +118,6 @@
     ],
     visibility = ["//visibility:public"],
     exports = [
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
     ],
 )
diff --git a/lib/bouncycastle/BUILD b/lib/bouncycastle/BUILD
index b7ff237..fbfc223 100644
--- a/lib/bouncycastle/BUILD
+++ b/lib/bouncycastle/BUILD
@@ -4,28 +4,28 @@
     name = "bcprov",
     data = ["//lib:LICENSE-bouncycastle"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcprov_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcprov_jdk18on"],
 )
 
 java_library(
     name = "bcpg",
     data = ["//lib:LICENSE-bouncycastle"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcpg_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcpg_jdk18on"],
 )
 
 java_library(
     name = "bcpkix",
     data = ["//lib:LICENSE-bouncycastle"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcpkix_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcpkix_jdk18on"],
 )
 
 java_library(
     name = "bcutil",
     data = ["//lib:LICENSE-bouncycastle"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcutil_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcutil_jdk18on"],
 )
 
 java_library(
@@ -33,7 +33,7 @@
     data = ["//lib:LICENSE-bouncycastle"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcprov_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcprov_jdk18on"],
 )
 
 java_library(
@@ -41,7 +41,7 @@
     data = ["//lib:LICENSE-bouncycastle"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcpg_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcpg_jdk18on"],
 )
 
 java_library(
@@ -49,7 +49,7 @@
     data = ["//lib:LICENSE-bouncycastle"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcpkix_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcpkix_jdk18on"],
 )
 
 java_library(
@@ -57,5 +57,5 @@
     data = ["//lib:LICENSE-bouncycastle"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_bouncycastle_bcutil_jdk18on"],
+    exports = ["@external_deps//:org_bouncycastle_bcutil_jdk18on"],
 )
diff --git a/lib/commons/BUILD b/lib/commons/BUILD
index 58e0be1..3e8cf74 100644
--- a/lib/commons/BUILD
+++ b/lib/commons/BUILD
@@ -5,56 +5,56 @@
 java_library(
     name = "codec",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_codec_commons_codec"],
+    exports = ["@external_deps//:commons_codec_commons_codec"],
 )
 
 java_library(
     name = "compress",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_commons_commons_compress"],
+    exports = ["@external_deps//:org_apache_commons_commons_compress"],
     runtime_deps = [":io"],
 )
 
 java_library(
     name = "lang3",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_commons_commons_lang3"],
+    exports = ["@external_deps//:org_apache_commons_commons_lang3"],
 )
 
 java_library(
     name = "net",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_net_commons_net"],
+    exports = ["@external_deps//:commons_net_commons_net"],
 )
 
 java_library(
     name = "dbcp",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_dbcp_commons_dbcp"],
+    exports = ["@external_deps//:commons_dbcp_commons_dbcp"],
     runtime_deps = [":pool"],
 )
 
 java_library(
     name = "pool",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_pool_commons_pool"],
+    exports = ["@external_deps//:commons_pool_commons_pool"],
 )
 
 java_library(
     name = "text",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_apache_commons_commons_text"],
+    exports = ["@external_deps//:org_apache_commons_commons_text"],
 )
 
 java_library(
     name = "validator",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_validator_commons_validator"],
+    exports = ["@external_deps//:commons_validator_commons_validator"],
 )
 
 java_library(
     name = "io",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:commons_io_commons_io"],
+    exports = ["@external_deps//:commons_io_commons_io"],
 )
diff --git a/lib/dropwizard/BUILD b/lib/dropwizard/BUILD
index 95c16354..fd78cb2 100644
--- a/lib/dropwizard/BUILD
+++ b/lib/dropwizard/BUILD
@@ -4,5 +4,5 @@
     name = "dropwizard-core",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:io_dropwizard_metrics_metrics_core"],
+    exports = ["@external_deps//:io_dropwizard_metrics_metrics_core"],
 )
diff --git a/lib/errorprone/BUILD b/lib/errorprone/BUILD
index 8113be8..9bc08b1 100644
--- a/lib/errorprone/BUILD
+++ b/lib/errorprone/BUILD
@@ -5,5 +5,5 @@
     data = ["//lib:LICENSE-Apache2.0"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_errorprone_error_prone_annotations"],
+    exports = ["@external_deps//:com_google_errorprone_error_prone_annotations"],
 )
diff --git a/lib/flogger/BUILD b/lib/flogger/BUILD
index 79f7188..e0fada6 100644
--- a/lib/flogger/BUILD
+++ b/lib/flogger/BUILD
@@ -5,9 +5,9 @@
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
     exports = [
-        "@gerrit_deps//:com_google_flogger_flogger",
-        "@gerrit_deps//:com_google_flogger_flogger_log4j_backend",
-        "@gerrit_deps//:com_google_flogger_flogger_system_backend",
-        "@gerrit_deps//:com_google_flogger_google_extensions",
+        "@external_deps//:com_google_flogger_flogger",
+        "@external_deps//:com_google_flogger_flogger_log4j_backend",
+        "@external_deps//:com_google_flogger_flogger_system_backend",
+        "@external_deps//:com_google_flogger_google_extensions",
     ],
 )
diff --git a/lib/gitiles/BUILD b/lib/gitiles/BUILD
index 4bfc9e8..3457828 100644
--- a/lib/gitiles/BUILD
+++ b/lib/gitiles/BUILD
@@ -19,35 +19,35 @@
     name = "cm-autolink",
     data = ["//lib:LICENSE-commonmark"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_commonmark_commonmark_ext_autolink"],
+    exports = ["@external_deps//:org_commonmark_commonmark_ext_autolink"],
 )
 
 java_library(
     name = "commonmark",
     data = ["//lib:LICENSE-commonmark"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_commonmark_commonmark"],
+    exports = ["@external_deps//:org_commonmark_commonmark"],
 )
 
 java_library(
     name = "gfm-strikethrough",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_commonmark_commonmark_ext_gfm_strikethrough"],
+    exports = ["@external_deps//:org_commonmark_commonmark_ext_gfm_strikethrough"],
 )
 
 java_library(
     name = "gfm-tables",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_commonmark_commonmark_ext_gfm_tables"],
+    exports = ["@external_deps//:org_commonmark_commonmark_ext_gfm_tables"],
 )
 
 java_library(
     name = "gitiles-servlet",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_gitiles_gitiles_servlet"],
+    exports = ["@external_deps//:com_google_gitiles_gitiles_servlet"],
 )
 
 java_library(
diff --git a/lib/greenmail/BUILD b/lib/greenmail/BUILD
index 644e0a1..007f257 100644
--- a/lib/greenmail/BUILD
+++ b/lib/greenmail/BUILD
@@ -6,13 +6,13 @@
     name = "javax-activation",
     testonly = True,
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
-    exports = ["@gerrit_deps//:javax_activation_activation"],
+    exports = ["@external_deps//:javax_activation_activation"],
 )
 
 java_library(
     name = "greenmail",
     testonly = True,
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:com_icegreen_greenmail"],
+    exports = ["@external_deps//:com_icegreen_greenmail"],
     runtime_deps = [":javax-activation"],
 )
diff --git a/lib/guice/BUILD b/lib/guice/BUILD
index b80b74a..8e4272b 100644
--- a/lib/guice/BUILD
+++ b/lib/guice/BUILD
@@ -15,7 +15,7 @@
     name = "guice-library",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_inject_guice"],
+    exports = ["@external_deps//:com_google_inject_guice"],
     runtime_deps = ["aopalliance"],
 )
 
@@ -23,7 +23,7 @@
     name = "guice-assistedinject",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_inject_extensions_guice_assistedinject"],
+    exports = ["@external_deps//:com_google_inject_extensions_guice_assistedinject"],
     runtime_deps = [":guice"],
 )
 
@@ -31,26 +31,26 @@
     name = "guice-servlet",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_inject_extensions_guice_servlet"],
+    exports = ["@external_deps//:com_google_inject_extensions_guice_servlet"],
     runtime_deps = [":guice"],
 )
 
 java_library(
     name = "aopalliance",
     data = ["//lib:LICENSE-PublicDomain"],
-    exports = ["@gerrit_deps//:aopalliance_aopalliance"],
+    exports = ["@external_deps//:aopalliance_aopalliance"],
 )
 
 java_library(
     name = "jakarta-inject",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:jakarta_inject_jakarta_inject_api"],
+    exports = ["@external_deps//:jakarta_inject_jakarta_inject_api"],
 )
 
 java_library(
     name = "javax_inject",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:javax_inject_javax_inject"],
+    exports = ["@external_deps//:javax_inject_javax_inject"],
 )
diff --git a/lib/httpcomponents/BUILD b/lib/httpcomponents/BUILD
index 5bf3e4a..8ead589 100644
--- a/lib/httpcomponents/BUILD
+++ b/lib/httpcomponents/BUILD
@@ -5,14 +5,14 @@
 java_library(
     name = "fluent-hc",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_httpcomponents_fluent_hc"],
+    exports = ["@external_deps//:org_apache_httpcomponents_fluent_hc"],
     runtime_deps = [":httpclient"],
 )
 
 java_library(
     name = "httpclient",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_httpcomponents_httpclient"],
+    exports = ["@external_deps//:org_apache_httpcomponents_httpclient"],
     runtime_deps = [
         ":httpcore",
         "//lib/commons:codec",
@@ -23,5 +23,5 @@
 java_library(
     name = "httpcore",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_httpcomponents_httpcore"],
+    exports = ["@external_deps//:org_apache_httpcomponents_httpcore"],
 )
diff --git a/lib/jetty/BUILD b/lib/jetty/BUILD
index 544381e..fc029ed 100644
--- a/lib/jetty/BUILD
+++ b/lib/jetty/BUILD
@@ -6,7 +6,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":util-ajax",
-        "@gerrit_deps//:org_eclipse_jetty_jetty_servlet",
+        "@external_deps//:org_eclipse_jetty_jetty_servlet",
     ],
     runtime_deps = [":security"],
 )
@@ -15,7 +15,7 @@
     name = "security",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_eclipse_jetty_jetty_security"],
+    exports = ["@external_deps//:org_eclipse_jetty_jetty_security"],
     runtime_deps = [":server"],
 )
 
@@ -25,7 +25,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":http",
-        "@gerrit_deps//:org_eclipse_jetty_jetty_server",
+        "@external_deps//:org_eclipse_jetty_jetty_server",
     ],
 )
 
@@ -35,7 +35,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":http",
-        "@gerrit_deps//:org_eclipse_jetty_jetty_jmx",
+        "@external_deps//:org_eclipse_jetty_jetty_jmx",
     ],
 )
 
@@ -45,7 +45,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":io",
-        "@gerrit_deps//:org_eclipse_jetty_jetty_http",
+        "@external_deps//:org_eclipse_jetty_jetty_http",
     ],
 )
 
@@ -54,18 +54,18 @@
     data = ["//lib:LICENSE-Apache2.0"],
     exports = [
         ":util",
-        "@gerrit_deps//:org_eclipse_jetty_jetty_io",
+        "@external_deps//:org_eclipse_jetty_jetty_io",
     ],
 )
 
 java_library(
     name = "util",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_eclipse_jetty_jetty_util"],
+    exports = ["@external_deps//:org_eclipse_jetty_jetty_util"],
 )
 
 java_library(
     name = "util-ajax",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_eclipse_jetty_jetty_util_ajax"],
+    exports = ["@external_deps//:org_eclipse_jetty_jetty_util_ajax"],
 )
diff --git a/lib/jsoup/BUILD b/lib/jsoup/BUILD
index 6388e84..57a16f6 100644
--- a/lib/jsoup/BUILD
+++ b/lib/jsoup/BUILD
@@ -4,5 +4,5 @@
     name = "jsoup",
     data = ["//lib:LICENSE-jsoup"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_jsoup_jsoup"],
+    exports = ["@external_deps//:org_jsoup_jsoup"],
 )
diff --git a/lib/log/BUILD b/lib/log/BUILD
index b2db766..9dbd55c 100644
--- a/lib/log/BUILD
+++ b/lib/log/BUILD
@@ -7,21 +7,21 @@
         "//lib:__pkg__",
         "//plugins:__pkg__",
     ],
-    exports = ["@gerrit_deps//:org_slf4j_slf4j_api"],
+    exports = ["@external_deps//:org_slf4j_slf4j_api"],
 )
 
 java_library(
     name = "ext",
     data = ["//lib:LICENSE-slf4j"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_slf4j_slf4j_ext"],
+    exports = ["@external_deps//:org_slf4j_slf4j_ext"],
 )
 
 java_library(
     name = "impl-log4j",
     data = ["//lib:LICENSE-slf4j"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_slf4j_slf4j_reload4j"],
+    exports = ["@external_deps//:org_slf4j_slf4j_reload4j"],
     runtime_deps = [":log4j"],
 )
 
@@ -29,19 +29,19 @@
     name = "jcl-over-slf4j",
     data = ["//lib:LICENSE-slf4j"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_slf4j_jcl_over_slf4j"],
+    exports = ["@external_deps//:org_slf4j_jcl_over_slf4j"],
 )
 
 java_library(
     name = "log4j",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:ch_qos_reload4j_reload4j"],
+    exports = ["@external_deps//:ch_qos_reload4j_reload4j"],
 )
 
 java_library(
     name = "json-smart",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:net_minidev_json_smart"],
+    exports = ["@external_deps//:net_minidev_json_smart"],
 )
diff --git a/lib/lucene/BUILD b/lib/lucene/BUILD
index 5a4be78..d001d30 100644
--- a/lib/lucene/BUILD
+++ b/lib/lucene/BUILD
@@ -5,33 +5,33 @@
 java_library(
     name = "lucene-analyzers-common",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_lucene_lucene_analysis_common"],
+    exports = ["@external_deps//:org_apache_lucene_lucene_analysis_common"],
     runtime_deps = [":lucene-core"],
 )
 
 java_library(
     name = "lucene-backward-codecs",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_lucene_lucene_backward_codecs"],
+    exports = ["@external_deps//:org_apache_lucene_lucene_backward_codecs"],
 )
 
 java_library(
     name = "lucene-core",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_lucene_lucene_core"],
+    exports = ["@external_deps//:org_apache_lucene_lucene_core"],
     runtime_deps = [":lucene-backward-codecs"],
 )
 
 java_library(
     name = "lucene-misc",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_lucene_lucene_misc"],
+    exports = ["@external_deps//:org_apache_lucene_lucene_misc"],
     runtime_deps = [":lucene-core"],
 )
 
 java_library(
     name = "lucene-queryparser",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_apache_lucene_lucene_queryparser"],
+    exports = ["@external_deps//:org_apache_lucene_lucene_queryparser"],
     runtime_deps = [":lucene-core"],
 )
diff --git a/lib/mail/BUILD b/lib/mail/BUILD
index 4dac3ee..c8f6dd4 100644
--- a/lib/mail/BUILD
+++ b/lib/mail/BUILD
@@ -4,5 +4,5 @@
     name = "mail",
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_sun_mail_javax_mail"],
+    exports = ["@external_deps//:com_sun_mail_javax_mail"],
 )
diff --git a/lib/mime4j/BUILD b/lib/mime4j/BUILD
index ed5556e..ea8e9d5 100644
--- a/lib/mime4j/BUILD
+++ b/lib/mime4j/BUILD
@@ -4,12 +4,12 @@
     name = "core",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_apache_james_apache_mime4j_core"],
+    exports = ["@external_deps//:org_apache_james_apache_mime4j_core"],
 )
 
 java_library(
     name = "dom",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_apache_james_apache_mime4j_dom"],
+    exports = ["@external_deps//:org_apache_james_apache_mime4j_dom"],
 )
diff --git a/lib/mina/BUILD b/lib/mina/BUILD
index 44a2d04..00cc2e5 100644
--- a/lib/mina/BUILD
+++ b/lib/mina/BUILD
@@ -5,8 +5,8 @@
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
     exports = [
-        "@gerrit_deps//:org_apache_sshd_sshd_mina",
-        "@gerrit_deps//:org_apache_sshd_sshd_osgi",
+        "@external_deps//:org_apache_sshd_sshd_mina",
+        "@external_deps//:org_apache_sshd_sshd_osgi",
     ],
     runtime_deps = [":core"],
 )
@@ -15,12 +15,12 @@
     name = "sshd-sftp",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_apache_sshd_sshd_sftp"],
+    exports = ["@external_deps//:org_apache_sshd_sshd_sftp"],
 )
 
 java_library(
     name = "core",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_apache_mina_mina_core"],
+    exports = ["@external_deps//:org_apache_mina_mina_core"],
 )
diff --git a/lib/mockito/BUILD b/lib/mockito/BUILD
index caf8d4f..215f5ff 100644
--- a/lib/mockito/BUILD
+++ b/lib/mockito/BUILD
@@ -9,7 +9,7 @@
     name = "mockito",
     data = ["//lib:LICENSE-mockito"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_mockito_mockito_core"],
+    exports = ["@external_deps//:org_mockito_mockito_core"],
     runtime_deps = [
         ":byte-buddy",
         ":byte-buddy-agent",
@@ -20,17 +20,17 @@
 java_library(
     name = "byte-buddy",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:net_bytebuddy_byte_buddy"],
+    exports = ["@external_deps//:net_bytebuddy_byte_buddy"],
 )
 
 java_library(
     name = "byte-buddy-agent",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:net_bytebuddy_byte_buddy_agent"],
+    exports = ["@external_deps//:net_bytebuddy_byte_buddy_agent"],
 )
 
 java_library(
     name = "objenesis",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:org_objenesis_objenesis"],
+    exports = ["@external_deps//:org_objenesis_objenesis"],
 )
diff --git a/lib/openid/BUILD b/lib/openid/BUILD
index 10996b3..dfab6a5 100644
--- a/lib/openid/BUILD
+++ b/lib/openid/BUILD
@@ -4,7 +4,7 @@
     name = "consumer",
     data = ["//lib:LICENSE-Apache2.0"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_openid4java_openid4java"],
+    exports = ["@external_deps//:org_openid4java_openid4java"],
     runtime_deps = [
         ":nekohtml",
         ":xerces",
@@ -17,12 +17,12 @@
 java_library(
     name = "nekohtml",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:net_sourceforge_nekohtml_nekohtml"],
+    exports = ["@external_deps//:net_sourceforge_nekohtml_nekohtml"],
     runtime_deps = [":xerces"],
 )
 
 java_library(
     name = "xerces",
     data = ["//lib:LICENSE-Apache2.0"],
-    exports = ["@gerrit_deps//:xerces_xercesImpl"],
+    exports = ["@external_deps//:xerces_xercesImpl"],
 )
diff --git a/lib/ow2/BUILD b/lib/ow2/BUILD
index 71da39b..529f090 100644
--- a/lib/ow2/BUILD
+++ b/lib/ow2/BUILD
@@ -4,21 +4,21 @@
     name = "ow2-asm",
     data = ["//lib:LICENSE-ow2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_ow2_asm_asm"],
+    exports = ["@external_deps//:org_ow2_asm_asm"],
 )
 
 java_library(
     name = "ow2-asm-analysis",
     data = ["//lib:LICENSE-ow2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_ow2_asm_asm_analysis"],
+    exports = ["@external_deps//:org_ow2_asm_asm_analysis"],
 )
 
 java_library(
     name = "ow2-asm-commons",
     data = ["//lib:LICENSE-ow2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_ow2_asm_asm_commons"],
+    exports = ["@external_deps//:org_ow2_asm_asm_commons"],
     runtime_deps = [":ow2-asm-tree"],
 )
 
@@ -26,12 +26,12 @@
     name = "ow2-asm-tree",
     data = ["//lib:LICENSE-ow2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_ow2_asm_asm_tree"],
+    exports = ["@external_deps//:org_ow2_asm_asm_tree"],
 )
 
 java_library(
     name = "ow2-asm-util",
     data = ["//lib:LICENSE-ow2"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:org_ow2_asm_asm_util"],
+    exports = ["@external_deps//:org_ow2_asm_asm_util"],
 )
diff --git a/lib/prolog/BUILD b/lib/prolog/BUILD
index 724b628..6b99765 100644
--- a/lib/prolog/BUILD
+++ b/lib/prolog/BUILD
@@ -4,7 +4,7 @@
     name = "runtime",
     data = ["//lib:LICENSE-prologcafe"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_googlecode_prolog_cafe_prolog_runtime"],
+    exports = ["@external_deps//:com_googlecode_prolog_cafe_prolog_runtime"],
 )
 
 java_library(
@@ -12,14 +12,14 @@
     data = ["//lib:LICENSE-prologcafe"],
     neverlink = 1,
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_googlecode_prolog_cafe_prolog_runtime"],
+    exports = ["@external_deps//:com_googlecode_prolog_cafe_prolog_runtime"],
 )
 
 java_library(
     name = "compiler",
     data = ["//lib:LICENSE-prologcafe"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_googlecode_prolog_cafe_prolog_compiler"],
+    exports = ["@external_deps//:com_googlecode_prolog_cafe_prolog_compiler"],
     runtime_deps = [
         ":io",
         ":runtime",
@@ -29,14 +29,14 @@
 java_library(
     name = "io",
     data = ["//lib:LICENSE-prologcafe"],
-    exports = ["@gerrit_deps//:com_googlecode_prolog_cafe_prolog_io"],
+    exports = ["@external_deps//:com_googlecode_prolog_cafe_prolog_io"],
 )
 
 java_library(
     name = "cafeteria",
     data = ["//lib:LICENSE-prologcafe"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_googlecode_prolog_cafe_prolog_cafeteria"],
+    exports = ["@external_deps//:com_googlecode_prolog_cafe_prolog_cafeteria"],
     runtime_deps = [
         "io",
         "runtime",
diff --git a/lib/truth/BUILD b/lib/truth/BUILD
index 151c15b..ce9922c 100644
--- a/lib/truth/BUILD
+++ b/lib/truth/BUILD
@@ -5,7 +5,7 @@
     testonly = True,
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_truth_truth"],
+    exports = ["@external_deps//:com_google_truth_truth"],
     runtime_deps = [
         ":diffutils",
         "//lib:guava",
@@ -18,7 +18,7 @@
     testonly = True,
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:public"],
-    exports = ["@gerrit_deps//:com_google_truth_extensions_truth_java8_extension"],
+    exports = ["@external_deps//:com_google_truth_extensions_truth_java8_extension"],
     runtime_deps = [
         ":truth",
         "//lib:guava",
@@ -30,7 +30,7 @@
     testonly = True,
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:private"],
-    exports = ["@gerrit_deps//:com_google_truth_extensions_truth_liteproto_extension"],
+    exports = ["@external_deps//:com_google_truth_extensions_truth_liteproto_extension"],
     runtime_deps = [
         ":truth",
         "//lib:guava",
@@ -43,7 +43,7 @@
     testonly = True,
     data = ["//lib:LICENSE-DO_NOT_DISTRIBUTE"],
     visibility = ["//visibility:private"],
-    exports = ["@gerrit_deps//:io_github_java_diff_utils_java_diff_utils"],
+    exports = ["@external_deps//:io_github_java_diff_utils_java_diff_utils"],
 )
 
 java_library(
@@ -53,7 +53,7 @@
     visibility = ["//visibility:public"],
     exports = [
         ":truth-liteproto-extension",
-        "@gerrit_deps//:com_google_truth_extensions_truth_proto_extension",
+        "@external_deps//:com_google_truth_extensions_truth_proto_extension",
     ],
     runtime_deps = [
         ":truth",
diff --git a/modules/jgit b/modules/jgit
index 4e67a23..d95b54f 160000
--- a/modules/jgit
+++ b/modules/jgit
@@ -1 +1 @@
-Subproject commit 4e67a230612b894160aecd786388519bec17f5fe
+Subproject commit d95b54f6080eb2aa9421e01188d25ab4a4a0c6bf
diff --git a/plugins/BUILD b/plugins/BUILD
index c98130d..5df73bb 100644
--- a/plugins/BUILD
+++ b/plugins/BUILD
@@ -74,6 +74,7 @@
     "//lib/commons:dbcp",
     "//lib/commons:lang3",
     "//lib/commons:io",
+    "//lib/commons:net",
     "//lib/dropwizard:dropwizard-core",
     "//lib/flogger:api",
     "//lib/guice:guice",
diff --git a/plugins/gitiles b/plugins/gitiles
index 88cfccd..c423243 160000
--- a/plugins/gitiles
+++ b/plugins/gitiles
@@ -1 +1 @@
-Subproject commit 88cfccd5602ddb091a73c0a2559f23c0e67cd42a
+Subproject commit c42324332aa1357bd9dfdf2de14593a36ffbe3e0
diff --git a/polygerrit-ui/app/constants/reporting.ts b/polygerrit-ui/app/constants/reporting.ts
index f95148b..bae1c58 100644
--- a/polygerrit-ui/app/constants/reporting.ts
+++ b/polygerrit-ui/app/constants/reporting.ts
@@ -169,4 +169,21 @@
   COMMENT_COMPLETION_SUGGESTION_FETCHED = 'comment-completion-suggestion-fetched',
 
   COPY_AI_PROMPT = 'copy-ai-prompt',
+
+  // AI agent suggests comments/fixes to user.
+  AI_AGENT_SUGGESTIONS_SHOWN = 'ai-agent-suggestions-shown',
 }
+
+/**
+ * EventDetails to be passed to the reportInteraction method for AI agent
+ * interactions.
+ */
+export type AiAgentEventDetails = {
+  host: string;
+  agentId: string;
+  conversationId: string;
+  // Each agent response in a conversation is a turn.
+  turnIndex: number;
+  // commentCount is 0 if agent ran but didn't suggest any comments/fixes.
+  commentCount: number;
+};
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-hashtag-flow/gr-change-list-hashtag-flow.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-hashtag-flow/gr-change-list-hashtag-flow.ts
index 2d8022b..9b7209f 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-hashtag-flow/gr-change-list-hashtag-flow.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-hashtag-flow/gr-change-list-hashtag-flow.ts
@@ -28,6 +28,7 @@
 import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
 import '@material/web/menu/menu';
 import {MdMenu} from '@material/web/menu/menu';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 @customElement('gr-change-list-hashtag-flow')
 export class GrChangeListHashtagFlow extends LitElement {
@@ -58,6 +59,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       spinnerStyles,
       css`
         md-menu {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-topic-flow/gr-change-list-topic-flow.ts b/polygerrit-ui/app/elements/change-list/gr-change-list-topic-flow/gr-change-list-topic-flow.ts
index 2a5d5fe..b3d7a35 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-topic-flow/gr-change-list-topic-flow.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-topic-flow/gr-change-list-topic-flow.ts
@@ -29,6 +29,7 @@
 import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
 import '@material/web/menu/menu';
 import {MdMenu} from '@material/web/menu/menu';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 @customElement('gr-change-list-topic-flow')
 export class GrChangeListTopicFlow extends LitElement {
@@ -59,6 +60,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       spinnerStyles,
       css`
         md-menu {
diff --git a/polygerrit-ui/app/elements/change/gr-copy-links/gr-copy-links.ts b/polygerrit-ui/app/elements/change/gr-copy-links/gr-copy-links.ts
index 35352c3..72050dc 100644
--- a/polygerrit-ui/app/elements/change/gr-copy-links/gr-copy-links.ts
+++ b/polygerrit-ui/app/elements/change/gr-copy-links/gr-copy-links.ts
@@ -15,6 +15,7 @@
 import '@material/web/menu/menu';
 import {MdMenu} from '@material/web/menu/menu';
 import {MdOutlinedTextField} from '@material/web/textfield/outlined-text-field';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 export interface CopyLink {
   label: string;
@@ -49,6 +50,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       formStyles,
       css`
         md-menu {
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
index 110ac1c..f0c8bfb 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-create-flow.ts
@@ -115,6 +115,8 @@
 
   private readonly restApiService = getAppContext().restApiService;
 
+  private readonly reportingService = getAppContext().reportingService;
+
   private readonly getConfigModel = resolve(this, configModelToken);
 
   private readonly getFlowsModel = resolve(this, flowsModelToken);
@@ -491,6 +493,10 @@
       target="_blank"
       rel="noopener noreferrer"
       tabindex="-1"
+      @click=${() =>
+        this.reportingService.reportInteraction(
+          'flows-documentation-link-clicked'
+        )}
     >
       <md-icon-button touch-target="none" type="button">
         <gr-icon icon="help" title="read documentation"></gr-icon>
diff --git a/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts b/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
index fab658a..d7cd9e1 100644
--- a/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
+++ b/polygerrit-ui/app/elements/change/gr-flows/gr-flows.ts
@@ -24,6 +24,7 @@
 import {formatActionName} from '../../../utils/flows-util';
 import './gr-flow-rule';
 import {computeFlowStringFromFlowStageInfo} from '../../../utils/flows-util';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 @customElement('gr-flows')
 export class GrFlows extends LitElement {
@@ -46,6 +47,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       grFormStyles,
       css`
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_screenshot_test.ts b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_screenshot_test.ts
index 39d681c..d8d1926 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_screenshot_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_screenshot_test.ts
@@ -11,6 +11,7 @@
 import {visualDiff} from '@web/test-runner-visual-regression';
 import {GrLabelScoreRow} from './gr-label-score-row';
 import {visualDiffDarkTheme} from '../../../test/test-utils';
+import {setViewport} from '@web/test-runner-commands';
 
 suite('gr-label-score-row screenshot tests', () => {
   let element: GrLabelScoreRow;
@@ -40,10 +41,12 @@
   });
 
   test('label score row screenshot', async () => {
+    await setViewport({width: 1200, height: 800});
+
     // Create a container with a fixed width to stabilize the component's dimensions.
     const container = document.createElement('div');
 
-    container.style.width = '392px';
+    container.style.width = '700px';
     container.style.display = 'inline-block';
     container.appendChild(element);
 
diff --git a/polygerrit-ui/app/elements/chat-panel/context-chip.ts b/polygerrit-ui/app/elements/chat-panel/context-chip.ts
index 3647e34..1917fd2 100644
--- a/polygerrit-ui/app/elements/chat-panel/context-chip.ts
+++ b/polygerrit-ui/app/elements/chat-panel/context-chip.ts
@@ -18,6 +18,7 @@
 import {fire} from '../../utils/event-util';
 import {subscribe} from '../lit/subscription-controller';
 import {classMap} from 'lit/directives/class-map.js';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 @customElement('context-chip')
 export class ContextChip extends LitElement {
@@ -50,78 +51,81 @@
     );
   }
 
-  static override styles = css`
-    :host {
-      overflow: hidden;
-      max-width: 300px;
-    }
-    md-filter-chip.suggested-chip {
-      opacity: 0.5;
-      border-style: dashed;
-      border-width: 1px;
-      border-color: var(--border-color);
-      --md-filter-chip-outline-color: transparent;
-    }
-    md-filter-chip.suggested-chip:hover {
-      opacity: 0.7;
-    }
-    md-filter-chip.custom-action-chip {
-      --md-sys-color-primary: var(--custom-action-context-chip-color);
-      --md-filter-chip-selected-container-color: transparent;
-    }
-    md-filter-chip {
-      --md-sys-color-primary: var(--primary-text-color);
-      --md-filter-chip-label-text-color: var(--primary-text-color);
-      --md-filter-chip-container-height: 20px;
-      --md-filter-chip-label-text-size: var(--font-size-small);
-      --md-filter-chip-label-text-weight: var(--font-weight-medium);
-      --md-filter-chip-unselected-container-color: transparent;
-      --md-filter-chip-outline-color: var(--border-color);
-      --md-filter-chip-hover-label-text-color: var(--primary-text-color);
-      --md-filter-chip-focus-label-text-color: var(--primary-text-color);
-      --md-filter-chip-pressed-label-text-color: var(--primary-text-color);
-      overflow: hidden;
-      margin: 0;
-      border-radius: 8px;
-    }
-    md-filter-chip.no-link {
-      --md-filter-chip-unselected-hover-state-layer-color: transparent;
-      --md-ripple-hover-color: transparent;
-      --md-ripple-pressed-color: transparent;
-      --md-ripple-focus-color: transparent;
-    }
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        overflow: hidden;
+        max-width: 300px;
+      }
+      md-filter-chip.suggested-chip {
+        opacity: 0.5;
+        border-style: dashed;
+        border-width: 1px;
+        border-color: var(--border-color);
+        --md-filter-chip-outline-color: transparent;
+      }
+      md-filter-chip.suggested-chip:hover {
+        opacity: 0.7;
+      }
+      md-filter-chip.custom-action-chip {
+        --md-sys-color-primary: var(--custom-action-context-chip-color);
+        --md-filter-chip-selected-container-color: transparent;
+      }
+      md-filter-chip {
+        --md-sys-color-primary: var(--primary-text-color);
+        --md-filter-chip-label-text-color: var(--primary-text-color);
+        --md-filter-chip-container-height: 20px;
+        --md-filter-chip-label-text-size: var(--font-size-small);
+        --md-filter-chip-label-text-weight: var(--font-weight-medium);
+        --md-filter-chip-unselected-container-color: transparent;
+        --md-filter-chip-outline-color: var(--border-color);
+        --md-filter-chip-hover-label-text-color: var(--primary-text-color);
+        --md-filter-chip-focus-label-text-color: var(--primary-text-color);
+        --md-filter-chip-pressed-label-text-color: var(--primary-text-color);
+        overflow: hidden;
+        margin: 0;
+        border-radius: 8px;
+      }
+      md-filter-chip.no-link {
+        --md-filter-chip-unselected-hover-state-layer-color: transparent;
+        --md-ripple-hover-color: transparent;
+        --md-ripple-pressed-color: transparent;
+        --md-ripple-focus-color: transparent;
+      }
 
-    .context-chip-icon-base {
-      width: 12px;
-      height: 12px;
-    }
-    .custom-action-icon {
-      color: var(--custom-action-context-chip-color);
-    }
-    .external-context-text,
-    .custom-action-text {
-      margin-left: var(--spacing-s);
-    }
-    .custom-action-text {
-      color: var(--custom-action-context-chip-color);
-    }
-    .subtext {
-      color: var(--deemphasized-text-color);
-    }
-    .hidden {
-      visibility: hidden;
-      pointer-events: none;
-    }
-    .context-chip-container {
-      display: flex;
-      flex-direction: row;
-      flex-wrap: nowrap;
-      align-items: center;
-    }
-    .context-chip-title {
-      padding-top: 2px;
-    }
-  `;
+      .context-chip-icon-base {
+        width: 12px;
+        height: 12px;
+      }
+      .custom-action-icon {
+        color: var(--custom-action-context-chip-color);
+      }
+      .external-context-text,
+      .custom-action-text {
+        margin-left: var(--spacing-s);
+      }
+      .custom-action-text {
+        color: var(--custom-action-context-chip-color);
+      }
+      .subtext {
+        color: var(--deemphasized-text-color);
+      }
+      .hidden {
+        visibility: hidden;
+        pointer-events: none;
+      }
+      .context-chip-container {
+        display: flex;
+        flex-direction: row;
+        flex-wrap: nowrap;
+        align-items: center;
+      }
+      .context-chip-title {
+        padding-top: 2px;
+      }
+    `,
+  ];
 
   override render() {
     const type = this.getChatModel().contextItemToType(this.contextItem);
diff --git a/polygerrit-ui/app/elements/chat-panel/context-input-chip.ts b/polygerrit-ui/app/elements/chat-panel/context-input-chip.ts
index b3af66d..eec7918 100644
--- a/polygerrit-ui/app/elements/chat-panel/context-input-chip.ts
+++ b/polygerrit-ui/app/elements/chat-panel/context-input-chip.ts
@@ -21,6 +21,7 @@
 import {fire, fireAlert} from '../../utils/event-util';
 import {subscribe} from '../lit/subscription-controller';
 import {classMap} from 'lit/directives/class-map.js';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 @customElement('context-input-chip')
 export class ContextInputChip extends LitElement {
@@ -58,80 +59,83 @@
     );
   }
 
-  static override styles = css`
-    .context-input-container {
-      position: relative;
-    }
-    /* .mat-mdc-standard-chip replaced by md-assist-chip */
-    md-assist-chip {
-      --md-assist-chip-container-height: 22px;
-      --md-assist-chip-label-text-size: var(--font-size-small);
-      --md-assist-chip-label-text-weight: var(--font-weight-medium);
-      --md-assist-chip-label-text-color: var(--primary-text-color);
-      --md-assist-chip-outline-color: var(--border-color);
-      --md-assist-chip-hover-label-text-color: var(--primary-text-color);
-      --md-assist-chip-focus-label-text-color: var(--primary-text-color);
-      --md-assist-chip-pressed-label-text-color: var(--primary-text-color);
-      --md-assist-chip-hover-icon-color: var(--primary-text-color);
-      --md-assist-chip-focus-icon-color: var(--primary-text-color);
-      --md-assist-chip-pressed-icon-color: var(--primary-text-color);
-      overflow: hidden;
-      margin: 0;
-      border-color: var(--border-color);
-      background-color: transparent;
-      border-radius: 8px;
-    }
-    .add-icon {
-      color: var(--primary-text-color);
-    }
-    .add-link-container {
-      position: absolute;
-      text-align: center;
-      width: 200px;
-      left: 0;
-      bottom: 25px;
-    }
-    .add-link-input {
-      padding: var(--spacing-m);
-      margin-left: var(--spacing-m);
-      margin-right: var(--spacing-m);
-      border: 1px solid var(--border-color);
-      border-radius: 10px;
-      background-color: var(--background-color-primary);
-      font-family: var(--font-family);
-      font-size: var(--font-size-normal);
-      /* input color often defaults to browser/os default which might be dark even on dark mode if not set */
-      color: var(--primary-text-color);
-      outline: none;
-      width: 100%;
-      height: 23px;
-      max-width: 100%;
-    }
-    .add-link-input::placeholder {
-      color: var(--chat-card-placeholder-text-color);
-    }
-    .add-link-input:focus {
-      background-color: var(--background-color-primary);
-      border: 1px solid var(--border-color);
-    }
-    .context-menu-icon {
-      width: 14px;
-      height: 14px;
-      margin-left: var(--spacing-m);
-    }
-    .hidden {
-      visibility: hidden;
-      pointer-events: none;
-    }
-    md-menu-item {
-      white-space: nowrap;
-      --md-menu-item-top-space: var(--spacing-s);
-      --md-menu-item-bottom-space: var(--spacing-s);
-      --md-menu-item-leading-space: var(--spacing-m);
-      --md-menu-item-trailing-space: var(--spacing-m);
-      --md-menu-item-one-line-container-height: 24px;
-    }
-  `;
+  static override styles = [
+    materialStyles,
+    css`
+      .context-input-container {
+        position: relative;
+      }
+      /* .mat-mdc-standard-chip replaced by md-assist-chip */
+      md-assist-chip {
+        --md-assist-chip-container-height: 22px;
+        --md-assist-chip-label-text-size: var(--font-size-small);
+        --md-assist-chip-label-text-weight: var(--font-weight-medium);
+        --md-assist-chip-label-text-color: var(--primary-text-color);
+        --md-assist-chip-outline-color: var(--border-color);
+        --md-assist-chip-hover-label-text-color: var(--primary-text-color);
+        --md-assist-chip-focus-label-text-color: var(--primary-text-color);
+        --md-assist-chip-pressed-label-text-color: var(--primary-text-color);
+        --md-assist-chip-hover-icon-color: var(--primary-text-color);
+        --md-assist-chip-focus-icon-color: var(--primary-text-color);
+        --md-assist-chip-pressed-icon-color: var(--primary-text-color);
+        overflow: hidden;
+        margin: 0;
+        border-color: var(--border-color);
+        background-color: transparent;
+        border-radius: 8px;
+      }
+      .add-icon {
+        color: var(--primary-text-color);
+      }
+      .add-link-container {
+        position: absolute;
+        text-align: center;
+        width: 200px;
+        left: 0;
+        bottom: 25px;
+      }
+      .add-link-input {
+        padding: var(--spacing-m);
+        margin-left: var(--spacing-m);
+        margin-right: var(--spacing-m);
+        border: 1px solid var(--border-color);
+        border-radius: 10px;
+        background-color: var(--background-color-primary);
+        font-family: var(--font-family);
+        font-size: var(--font-size-normal);
+        /* input color often defaults to browser/os default which might be dark even on dark mode if not set */
+        color: var(--primary-text-color);
+        outline: none;
+        width: 100%;
+        height: 23px;
+        max-width: 100%;
+      }
+      .add-link-input::placeholder {
+        color: var(--chat-card-placeholder-text-color);
+      }
+      .add-link-input:focus {
+        background-color: var(--background-color-primary);
+        border: 1px solid var(--border-color);
+      }
+      .context-menu-icon {
+        width: 14px;
+        height: 14px;
+        margin-left: var(--spacing-m);
+      }
+      .hidden {
+        visibility: hidden;
+        pointer-events: none;
+      }
+      md-menu-item {
+        white-space: nowrap;
+        --md-menu-item-top-space: var(--spacing-s);
+        --md-menu-item-bottom-space: var(--spacing-s);
+        --md-menu-item-leading-space: var(--spacing-m);
+        --md-menu-item-trailing-space: var(--spacing-m);
+        --md-menu-item-one-line-container-height: 24px;
+      }
+    `,
+  ];
 
   override render() {
     return html`
diff --git a/polygerrit-ui/app/elements/chat-panel/gemini-message.ts b/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
index 7fed806..8f0dbee 100644
--- a/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
+++ b/polygerrit-ui/app/elements/chat-panel/gemini-message.ts
@@ -13,10 +13,11 @@
 import './references-dropdown';
 import './message-actions';
 
-import {css, html, LitElement} from 'lit';
+import {css, html, LitElement, PropertyValues} from 'lit';
 import {customElement, property, state} from 'lit/decorators.js';
 import {when} from 'lit/directives/when.js';
 
+import {AiAgentEventDetails, Interaction} from '../../constants/reporting';
 import {changeModelToken} from '../../models/change/change-model';
 import {
   filesModelToken,
@@ -31,6 +32,7 @@
 } from '../../models/chat/chat-model';
 import {commentsModelToken} from '../../models/comments/comments-model';
 import {resolve} from '../../models/dependency';
+import {getAppContext} from '../../services/app-context';
 import {NumericChangeId, PatchSetNumber} from '../../types/common';
 import {
   compareComments,
@@ -40,6 +42,7 @@
 import {assert} from '../../utils/common-util';
 import {fire} from '../../utils/event-util';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 @customElement('gemini-message')
 export class GeminiMessage extends LitElement {
@@ -63,6 +66,10 @@
 
   @state() latestPatchNum?: PatchSetNumber;
 
+  @state() private conversationId?: string;
+
+  private reportedSuggestionsShown = false;
+
   private readonly getChatModel = resolve(this, chatModelToken);
 
   private readonly getCommentsModel = resolve(this, commentsModelToken);
@@ -71,7 +78,10 @@
 
   private readonly getFilesModel = resolve(this, filesModelToken);
 
+  private readonly reportingService = getAppContext().reportingService;
+
   static override styles = [
+    materialStyles,
     css`
       :host {
         display: block;
@@ -210,6 +220,11 @@
       () => this.getChangeModel().latestPatchNum$,
       x => (this.latestPatchNum = x)
     );
+    subscribe(
+      this,
+      () => this.getChatModel().conversationId$,
+      x => (this.conversationId = x)
+    );
   }
 
   private async onAddAsComment(part: CreateCommentPart) {
@@ -240,6 +255,17 @@
     fire(this, 'open-diff-in-change-view', {path, lineNum});
   }
 
+  override updated(changedProperties: PropertyValues) {
+    if (changedProperties.has('turns') && !this.reportedSuggestionsShown) {
+      if (
+        this.turnIndex < this.turns.length &&
+        this.message()?.responseComplete
+      ) {
+        this.reportSuggestionsShown();
+      }
+    }
+  }
+
   override render() {
     if (this.turnIndex >= this.turns.length) return;
     const message = this.message();
@@ -403,10 +429,9 @@
   }
 
   private sortedComments() {
-    return this.message()
-      .responseParts.filter(
-        part => part.type === ResponsePartType.CREATE_COMMENT
-      )
+    const parts = this.message()?.responseParts ?? [];
+    return parts
+      .filter(part => part.type === ResponsePartType.CREATE_COMMENT)
       .sort((p1, p2) => {
         const c1 = {...createNew(p1.comment.message), ...p1.comment};
         const c2 = {...createNew(p2.comment.message), ...p2.comment};
@@ -417,9 +442,27 @@
   private turnId() {
     return {
       turnIndex: this.turnIndex,
-      regenerationIndex: this.message().regenerationIndex,
+      regenerationIndex: this.message()?.regenerationIndex ?? 0,
     };
   }
+
+  private reportSuggestionsShown() {
+    if (!this.conversationId) return;
+    this.reportedSuggestionsShown = true;
+
+    const agentId = this.turns[this.turnIndex]?.userMessage?.actionId ?? '';
+    const details: AiAgentEventDetails = {
+      host: window.location.host,
+      agentId,
+      conversationId: this.conversationId,
+      turnIndex: this.turnIndex,
+      commentCount: this.sortedComments().length,
+    };
+    this.reportingService.reportInteraction(
+      Interaction.AI_AGENT_SUGGESTIONS_SHOWN,
+      details
+    );
+  }
 }
 
 declare global {
diff --git a/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts b/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
index dcf2904..57401f3 100644
--- a/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
+++ b/polygerrit-ui/app/elements/chat-panel/gemini-message_test.ts
@@ -12,6 +12,7 @@
   CreateCommentPart,
   GeminiMessage as GeminiMessageModel,
   ResponsePartType,
+  TextPart,
   Turn,
   UserType,
 } from '../../models/chat/chat-model';
@@ -25,6 +26,8 @@
 import {chatProvider, createChange} from '../../test/test-data-generators';
 import {ParsedChangeInfo} from '../../types/types';
 import {CommentsModel} from '../../models/comments/comments-model';
+import {AiAgentEventDetails, Interaction} from '../../constants/reporting';
+import {getAppContext} from '../../services/app-context';
 
 suite('gemini-message tests', () => {
   let element: GeminiMessage;
@@ -71,6 +74,22 @@
     };
   }
 
+  const RESPONSE_TEXT: TextPart = {
+    id: 0,
+    type: ResponsePartType.TEXT,
+    content: 'test message',
+  };
+  const RESPONSE_CREATE_COMMENT: CreateCommentPart = {
+    id: 1,
+    type: ResponsePartType.CREATE_COMMENT,
+    content: 'test comment',
+    commentCreationId: 'test-id',
+    comment: {
+      message: 'test comment',
+      path: '/test/path',
+    },
+  };
+
   test('renders thinking', async () => {
     const turn = createTurn({responseComplete: false});
     chatModel.updateState({...chatModel.getState(), turns: [turn]});
@@ -113,9 +132,7 @@
   test('renders text response', async () => {
     const turn = createTurn({
       responseComplete: true,
-      responseParts: [
-        {id: 0, type: ResponsePartType.TEXT, content: 'test message'},
-      ],
+      responseParts: [RESPONSE_TEXT],
     });
     chatModel.updateState({...chatModel.getState(), turns: [turn]});
     await element.updateComplete;
@@ -151,19 +168,9 @@
   });
 
   test('renders suggested comment', async () => {
-    const comment: CreateCommentPart = {
-      id: 1,
-      type: ResponsePartType.CREATE_COMMENT,
-      content: 'test comment',
-      commentCreationId: 'test-id',
-      comment: {
-        message: 'test comment',
-        path: '/test/path',
-      },
-    };
     const turn = createTurn({
       responseComplete: true,
-      responseParts: [comment],
+      responseParts: [RESPONSE_CREATE_COMMENT],
     });
     chatModel.updateState({...chatModel.getState(), turns: [turn]});
     await element.updateComplete;
@@ -190,9 +197,7 @@
   test('renders citations', async () => {
     const turn = createTurn({
       responseComplete: true,
-      responseParts: [
-        {id: 0, type: ResponsePartType.TEXT, content: 'test message'},
-      ],
+      responseParts: [RESPONSE_TEXT],
       citations: ['http://example.com'],
     });
     chatModel.updateState({...chatModel.getState(), turns: [turn]});
@@ -213,9 +218,7 @@
     ];
     const turn = createTurn({
       responseComplete: true,
-      responseParts: [
-        {id: 0, type: ResponsePartType.TEXT, content: 'test message'},
-      ],
+      responseParts: [RESPONSE_TEXT],
       references,
     });
     chatModel.updateState({...chatModel.getState(), turns: [turn]});
@@ -227,4 +230,40 @@
     );
     assert.isOk(referencesDropdown);
   });
+
+  test('reports AI_AGENT_SUGGESTIONS_SHOWN interaction', async () => {
+    chatModel.updateState({
+      ...chatModel.getState(),
+      id: 'test-conversation-id',
+      selectedModelId: 'gemini-model-id',
+    });
+
+    const reportStub = sinon.stub(
+      getAppContext().reportingService,
+      'reportInteraction'
+    );
+
+    const turn = createTurn({
+      responseComplete: true,
+      responseParts: [RESPONSE_TEXT, RESPONSE_CREATE_COMMENT],
+    });
+    const updatedTurn = {
+      ...turn,
+      userMessage: {...turn.userMessage, actionId: 'custom-agent-id'},
+    };
+
+    chatModel.updateState({...chatModel.getState(), turns: [updatedTurn]});
+    await element.updateComplete;
+
+    assert.isTrue(reportStub.calledOnce);
+    assert.equal(
+      reportStub.firstCall.args[0],
+      Interaction.AI_AGENT_SUGGESTIONS_SHOWN
+    );
+    const details = reportStub.firstCall.args[1] as AiAgentEventDetails;
+    assert.equal(details.host, window.location.host);
+    assert.equal(details.conversationId, 'test-conversation-id');
+    assert.equal(details.agentId, 'custom-agent-id');
+    assert.equal(details.commentCount, 1);
+  });
 });
diff --git a/polygerrit-ui/app/elements/chat-panel/message-actions.ts b/polygerrit-ui/app/elements/chat-panel/message-actions.ts
index 2031bf2..78f6b66 100644
--- a/polygerrit-ui/app/elements/chat-panel/message-actions.ts
+++ b/polygerrit-ui/app/elements/chat-panel/message-actions.ts
@@ -18,6 +18,7 @@
 } from '../../models/chat/chat-model';
 import {resolve} from '../../models/dependency';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 /**
  * Component to display message actions for a Gemini message (e.g. thumbs up,
@@ -25,31 +26,34 @@
  */
 @customElement('message-actions')
 export class MessageActions extends LitElement {
-  static override styles = css`
-    :host {
-      display: flex;
-    }
-    md-icon-button {
-      margin-left: var(--spacing-l);
-      --md-icon-button-icon-size: 24px;
-      --md-icon-size: 24px;
-    }
-    .copy-button {
-      --gr-icon-size: 24px;
-      margin: auto 0;
-    }
-    .feedback-button.thumbs-up-icon {
-      margin-left: auto;
-    }
-    md-icon-button {
-      color: var(--primary-text-color);
-      --md-icon-button-icon-color: var(--primary-text-color);
-      --md-icon-button-hover-icon-color: var(--primary-text-color);
-    }
-    md-icon-button md-icon {
-      color: var(--primary-text-color);
-    }
-  `;
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        display: flex;
+      }
+      md-icon-button {
+        margin-left: var(--spacing-l);
+        --md-icon-button-icon-size: 24px;
+        --md-icon-size: 24px;
+      }
+      .copy-button {
+        --gr-icon-size: 24px;
+        margin: auto 0;
+      }
+      .feedback-button.thumbs-up-icon {
+        margin-left: auto;
+      }
+      md-icon-button {
+        color: var(--primary-text-color);
+        --md-icon-button-icon-color: var(--primary-text-color);
+        --md-icon-button-hover-icon-color: var(--primary-text-color);
+      }
+      md-icon-button md-icon {
+        color: var(--primary-text-color);
+      }
+    `,
+  ];
 
   @property({type: Object}) turnId!: UniqueTurnId;
 
diff --git a/polygerrit-ui/app/elements/chat-panel/prompt-box.ts b/polygerrit-ui/app/elements/chat-panel/prompt-box.ts
index d86f8aa..4a154e5 100644
--- a/polygerrit-ui/app/elements/chat-panel/prompt-box.ts
+++ b/polygerrit-ui/app/elements/chat-panel/prompt-box.ts
@@ -30,6 +30,7 @@
 import {debounce, DelayedTask} from '../../utils/async-util';
 import {fire} from '../../utils/event-util';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 const MAX_VISIBLE_CONTEXT_ITEMS_COLLAPSED = 3;
 const MAX_VISIBLE_SUGGESTED_CONTEXT_ITEMS_COLLAPSED = 1;
@@ -238,93 +239,96 @@
     return this.showAllContextItems ? '▲' : `+${this.numExcessContextItems}`;
   }
 
-  static override styles = css`
-    :host {
-      background-color: var(--background-color-tertiary);
-      border-radius: 8px;
-      display: flex;
-      flex-direction: column;
-      /* For high contrast mode. */
-      outline: 1px solid transparent;
-      padding: var(--spacing-l) var(--spacing-l) var(--spacing-m)
-        var(--spacing-xl);
-      transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
-    }
-    :host(:focus-within) {
-      background: var(
-        --search-box-focus-bg-color,
-        var(--background-color-primary)
-      );
-      box-shadow: 0px 1px 2px 0px var(--elevation-color),
-        0px 2px 6px 2px var(--elevation-color);
-    }
-    .tab-chip-set md-assist-chip.tab-chip {
-      --md-assist-chip-container-height: 16px;
-      --md-assist-chip-label-text-size: 10px;
-      --md-assist-chip-label-text-color: var(--primary-fg-color);
-      --md-assist-chip-label-line-height: 16px;
-      background-color: var(--tab-chip-bg-color);
-      border-radius: 4px;
-      margin: 0;
-      padding: 0;
-    }
-    gr-icon,
-    md-icon {
-      font-size: 20px;
-      line-height: 24px;
-    }
-    .prompt-box-inner-container {
-      display: flex;
-      height: auto;
-      min-height: 32px;
-      flex-direction: row;
-      align-items: center;
-      justify-content: space-between;
-      padding-bottom: 8px;
-    }
-    .prompt-input-container {
-      flex-grow: 1;
-      height: inherit;
-      margin-right: var(--spacing-xs);
-      position: relative;
-    }
-    .prompt-input {
-      background: transparent;
-      color: var(--primary-text-color);
-      font: inherit;
-      font-size: 16px; /* $font-size-large */
-      /* Explicitly set line-height to ensure consistent height in tests (e.g. 20px). */
-      line-height: 20px;
-      border: none;
-      outline: none;
-      resize: none;
-      padding: 0;
-      margin: 0;
-      height: auto;
-      width: 100%;
-      max-width: 100%;
-    }
-    .prompt-input::placeholder {
-      color: var(--deemphasized-text-color);
-    }
-    .context-chip-set {
-      gap: 4px;
-    }
-    .context-chip-set md-assist-chip.context-toggle-chip {
-      --md-assist-chip-container-height: 20px;
-      --md-assist-chip-label-text-size: 12px;
-      --md-assist-chip-label-text-weight: 500;
-      --md-assist-chip-label-line-height: 16px;
-      --md-assist-chip-label-text-color: var(--primary-text-color);
-      margin: 0;
-      margin-left: auto;
-      border-color: var(--border-color);
-      background-color: var(--elevation-2);
-      border-radius: 8px;
-      display: flex;
-      padding: 0 4px;
-    }
-  `;
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        background-color: var(--background-color-tertiary);
+        border-radius: 8px;
+        display: flex;
+        flex-direction: column;
+        /* For high contrast mode. */
+        outline: 1px solid transparent;
+        padding: var(--spacing-l) var(--spacing-l) var(--spacing-m)
+          var(--spacing-xl);
+        transition: box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1);
+      }
+      :host(:focus-within) {
+        background: var(
+          --search-box-focus-bg-color,
+          var(--background-color-primary)
+        );
+        box-shadow: 0px 1px 2px 0px var(--elevation-color),
+          0px 2px 6px 2px var(--elevation-color);
+      }
+      .tab-chip-set md-assist-chip.tab-chip {
+        --md-assist-chip-container-height: 16px;
+        --md-assist-chip-label-text-size: 10px;
+        --md-assist-chip-label-text-color: var(--primary-fg-color);
+        --md-assist-chip-label-line-height: 16px;
+        background-color: var(--tab-chip-bg-color);
+        border-radius: 4px;
+        margin: 0;
+        padding: 0;
+      }
+      gr-icon,
+      md-icon {
+        font-size: 20px;
+        line-height: 24px;
+      }
+      .prompt-box-inner-container {
+        display: flex;
+        height: auto;
+        min-height: 32px;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+        padding-bottom: 8px;
+      }
+      .prompt-input-container {
+        flex-grow: 1;
+        height: inherit;
+        margin-right: var(--spacing-xs);
+        position: relative;
+      }
+      .prompt-input {
+        background: transparent;
+        color: var(--primary-text-color);
+        font: inherit;
+        font-size: 16px; /* $font-size-large */
+        /* Explicitly set line-height to ensure consistent height in tests (e.g. 20px). */
+        line-height: 20px;
+        border: none;
+        outline: none;
+        resize: none;
+        padding: 0;
+        margin: 0;
+        height: auto;
+        width: 100%;
+        max-width: 100%;
+      }
+      .prompt-input::placeholder {
+        color: var(--deemphasized-text-color);
+      }
+      .context-chip-set {
+        gap: 4px;
+      }
+      .context-chip-set md-assist-chip.context-toggle-chip {
+        --md-assist-chip-container-height: 20px;
+        --md-assist-chip-label-text-size: 12px;
+        --md-assist-chip-label-text-weight: 500;
+        --md-assist-chip-label-line-height: 16px;
+        --md-assist-chip-label-text-color: var(--primary-text-color);
+        margin: 0;
+        margin-left: auto;
+        border-color: var(--border-color);
+        background-color: var(--elevation-2);
+        border-radius: 8px;
+        display: flex;
+        padding: 0 4px;
+      }
+    `,
+  ];
 
   override render() {
     return html`
diff --git a/polygerrit-ui/app/elements/chat-panel/references-dropdown.ts b/polygerrit-ui/app/elements/chat-panel/references-dropdown.ts
index 25e15a2..9f8d34c 100644
--- a/polygerrit-ui/app/elements/chat-panel/references-dropdown.ts
+++ b/polygerrit-ui/app/elements/chat-panel/references-dropdown.ts
@@ -15,6 +15,7 @@
 import {chatModelToken, Turn} from '../../models/chat/chat-model';
 import {resolve} from '../../models/dependency';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 /**
  * A component to display a dropdown with references used by the model.
@@ -34,6 +35,7 @@
   @state() private listWarnings = false;
 
   static override styles = [
+    materialStyles,
     css`
       :host {
         display: block;
diff --git a/polygerrit-ui/app/elements/chat-panel/splash-page-action.ts b/polygerrit-ui/app/elements/chat-panel/splash-page-action.ts
index 715e455..07a03bc 100644
--- a/polygerrit-ui/app/elements/chat-panel/splash-page-action.ts
+++ b/polygerrit-ui/app/elements/chat-panel/splash-page-action.ts
@@ -22,6 +22,7 @@
 import {isDefined} from '../../types/types';
 import {fireAlert} from '../../utils/event-util';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 /**
  * A component that renders a single action as a clickable chip on the chat
@@ -49,110 +50,113 @@
     );
   }
 
-  static override styles = css`
-    :host {
-      display: flex;
-      justify-content: center;
-      flex-wrap: wrap;
-      width: 100%;
-      position: relative;
-    }
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        display: flex;
+        justify-content: center;
+        flex-wrap: wrap;
+        width: 100%;
+        position: relative;
+      }
 
-    .action-chip {
-      display: flex;
-      background-color: var(--background-color-tertiary);
-      color: var(--primary-default);
-      height: 60px;
-      align-items: center;
-      border-radius: 4px;
-      margin: 0;
-      width: 100%;
-      overflow: hidden;
-      cursor: pointer;
-      --md-assist-chip-outline-width: 0;
-    }
+      .action-chip {
+        display: flex;
+        background-color: var(--background-color-tertiary);
+        color: var(--primary-default);
+        height: 60px;
+        align-items: center;
+        border-radius: 4px;
+        margin: 0;
+        width: 100%;
+        overflow: hidden;
+        cursor: pointer;
+        --md-assist-chip-outline-width: 0;
+      }
 
-    .action-chip[disabled] {
-      opacity: 0.6;
-      cursor: default;
-    }
+      .action-chip[disabled] {
+        opacity: 0.6;
+        cursor: default;
+      }
 
-    .action-chip.first-action-chip {
-      border-top-left-radius: 16px;
-      border-top-right-radius: 16px;
-    }
+      .action-chip.first-action-chip {
+        border-top-left-radius: 16px;
+        border-top-right-radius: 16px;
+      }
 
-    .action-chip.last-action-chip {
-      border-bottom-left-radius: 16px;
-      border-bottom-right-radius: 16px;
-    }
+      .action-chip.last-action-chip {
+        border-bottom-left-radius: 16px;
+        border-bottom-right-radius: 16px;
+      }
 
-    .action-chip.custom-action-chip {
-      background-color: var(--custom-action-chip-bg-color);
-    }
+      .action-chip.custom-action-chip {
+        background-color: var(--custom-action-chip-bg-color);
+      }
 
-    .action-icon {
-      padding: 4px;
-      border-radius: 8px;
-      background-color: var(--background-color-primary);
-      flex-shrink: 0;
-    }
-    .action-text-container {
-      display: flex;
-      flex-direction: column;
-      height: 100%;
-      overflow-x: hidden;
-    }
-    .main-action-text-container {
-      margin-left: 20px;
-      font-weight: 400;
-      display: flex;
-      align-items: center;
-    }
-    .main-action-text-container.has-subtext {
-      margin-top: 12px;
-      margin-bottom: -2px;
-    }
-    .action-text {
-      font-family: var(--font-family);
-      font-size: var(--font-size-normal);
-      font-weight: var(--font-weight-normal);
-      line-height: var(--line-height-normal);
-      color: var(--primary-text-color);
-      overflow-x: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-    .action-subtext {
-      vertical-align: super;
-      margin-left: 5px;
-      padding: 0px 15px 8px;
-      font-size: 0.8em;
-      color: var(--chat-splash-page-question-color);
-      overflow-x: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-    }
-    .action-subtext.is-passed {
-      color: var(--file-reviewed-color);
-    }
-    .action-subtext.is-actionable {
-      color: var(--tonal-red);
-    }
-    .info-button {
-      margin-left: 10px;
-      margin-right: 10px;
-      font-size: 24px;
-      --button-background-color: transparent;
-    }
-    .info-button gr-icon {
-      color: inherit;
-    }
-    .chip-content {
-      display: flex;
-      align-items: center;
-    }
-  `;
+      .action-icon {
+        padding: 4px;
+        border-radius: 8px;
+        background-color: var(--background-color-primary);
+        flex-shrink: 0;
+      }
+      .action-text-container {
+        display: flex;
+        flex-direction: column;
+        height: 100%;
+        overflow: hidden;
+      }
+      .main-action-text-container {
+        margin-left: 20px;
+        font-weight: 400;
+        display: flex;
+        align-items: center;
+      }
+      .main-action-text-container.has-subtext {
+        margin-top: 12px;
+        margin-bottom: -2px;
+      }
+      .action-text {
+        font-family: var(--font-family);
+        font-size: var(--font-size-normal);
+        font-weight: var(--font-weight-normal);
+        line-height: var(--line-height-normal);
+        color: var(--primary-text-color);
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+      .action-subtext {
+        vertical-align: super;
+        margin-left: 5px;
+        padding: 0px 15px 8px;
+        font-size: 0.8em;
+        color: var(--chat-splash-page-question-color);
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+      .action-subtext.is-passed {
+        color: var(--file-reviewed-color);
+      }
+      .action-subtext.is-actionable {
+        color: var(--tonal-red);
+      }
+      .info-button {
+        margin-left: 10px;
+        margin-right: 10px;
+        font-size: 24px;
+        --button-background-color: transparent;
+      }
+      .info-button gr-icon {
+        color: inherit;
+      }
+      .chip-content {
+        display: flex;
+        align-items: center;
+      }
+    `,
+  ];
 
   override render() {
     if (!this.action) return;
diff --git a/polygerrit-ui/app/elements/chat-panel/splash-page.ts b/polygerrit-ui/app/elements/chat-panel/splash-page.ts
index f2ec173..f44c838 100644
--- a/polygerrit-ui/app/elements/chat-panel/splash-page.ts
+++ b/polygerrit-ui/app/elements/chat-panel/splash-page.ts
@@ -23,6 +23,7 @@
 import {AccountDetailInfo, ServerInfo} from '../../types/common';
 import {subscribe} from '../lit/subscription-controller';
 import {getDisplayName} from '../../utils/display-name-util';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 /**
  * A component for displaying a splash page when there are no chat messages.
@@ -99,124 +100,132 @@
     return turn?.userMessage.isBackgroundRequest ? turn : undefined;
   }
 
-  static override styles = css`
-    :host {
-      overflow: auto;
-      padding-left: 20px;
-      padding-right: 20px;
-      padding-top: 20px;
-    }
-    .splash-container {
-      display: flex;
-      justify-content: center;
-      flex-flow: column nowrap;
-    }
-    .splash-greeting {
-      background: linear-gradient(135deg, #217bfe 0, #078efb 33%, #ac87eb 100%);
-      -webkit-background-clip: text;
-      background-clip: text;
-      -webkit-text-fill-color: transparent;
-      -webkit-box-orient: vertical;
-      color: transparent;
-      display: -webkit-inline-box;
-      font-size: 24px;
-      font-weight: 400;
-      margin-block-end: var(--spacing-s);
-    }
-    .material-icon {
-      color: var(--deemphasized-text-color);
-    }
-    .splash-question {
-      color: var(--chat-splash-page-question-color);
-      margin-bottom: 16px;
-      margin-top: 0px;
-      font-family: var(--header-font-family);
-      font-size: var(--font-size-h1);
-      font-weight: var(--font-weight-h1);
-      line-height: var(--line-height-h1);
-    }
-    .background-request-container {
-      background-color: var(--chat-splash-page-info-panel-bg-color);
-      padding: 15px;
-      border-radius: 15px;
-      margin-bottom: 12px;
-      display: flex;
-      flex-direction: column;
-    }
-    .background-request-container-inner {
-      position: relative;
-      max-height: 10em;
-      min-height: 10em;
-      overflow: hidden;
-    }
-    .background-request-container-inner.expanded {
-      max-height: none;
-      overflow: auto;
-    }
-    .background-request-container-overlay {
-      position: absolute;
-      top: 0;
-      left: 0;
-      width: 100%;
-      height: 100%;
-      background: linear-gradient(
-        to top,
-        var(--chat-splash-page-info-panel-bg-color),
-        transparent 50%
-      );
-    }
-    .user-background-question {
-      font-family: var(--header-font-family);
-      font-size: var(--font-size-normal);
-      font-weight: var(--font-weight-normal);
-      line-height: var(--line-height-normal);
-    }
-    .expansion-button-container {
-      display: flex;
-      justify-content: center;
-      align-items: center;
-    }
-    .info-panel-expansion-button {
-      top: 10px;
-      font-size: 1.5em;
-      border: none;
-      background-color: transparent;
-      color: var(--primary-default);
-      cursor: pointer;
-    }
-    .background-request-header {
-      display: flex;
-      align-items: center;
-      gap: 5px;
-      margin-bottom: 12px;
-      font-weight: bold;
-    }
-    .background-request-header .thinking-spinner {
-      margin-left: auto;
-    }
-    .action-container {
-      background-color: transparent;
-      margin-bottom: 20px;
-      display: flex;
-      justify-content: center;
-      flex-wrap: wrap;
-      width: 100%;
-    }
-    .action-container-title {
-      height: 28px;
-      display: flex;
-      align-items: center;
-      vertical-align: middle;
-      font-size: 0.9em;
-      font-weight: 500;
-      color: var(--chat-splash-page-action-set-title-color);
-    }
-    .action-container-title .autoreview-run-all-button {
-      margin-left: auto;
-      margin-right: 8px;
-    }
-    /* TODO: find small-icon styles equivalent for .small-icon */
-  `;
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        overflow: auto;
+        padding-left: 20px;
+        padding-right: 20px;
+        padding-top: 20px;
+      }
+      .splash-container {
+        display: flex;
+        justify-content: center;
+        flex-flow: column nowrap;
+      }
+      .splash-greeting {
+        background: linear-gradient(
+          135deg,
+          #217bfe 0,
+          #078efb 33%,
+          #ac87eb 100%
+        );
+        -webkit-background-clip: text;
+        background-clip: text;
+        -webkit-text-fill-color: transparent;
+        -webkit-box-orient: vertical;
+        color: transparent;
+        display: -webkit-inline-box;
+        font-size: 24px;
+        font-weight: 400;
+        margin-block-end: var(--spacing-s);
+      }
+      .material-icon {
+        color: var(--deemphasized-text-color);
+      }
+      .splash-question {
+        color: var(--chat-splash-page-question-color);
+        margin-bottom: 16px;
+        margin-top: 0px;
+        font-family: var(--header-font-family);
+        font-size: var(--font-size-h1);
+        font-weight: var(--font-weight-h1);
+        line-height: var(--line-height-h1);
+      }
+      .background-request-container {
+        background-color: var(--chat-splash-page-info-panel-bg-color);
+        padding: 15px;
+        border-radius: 15px;
+        margin-bottom: 12px;
+        display: flex;
+        flex-direction: column;
+      }
+      .background-request-container-inner {
+        position: relative;
+        max-height: 10em;
+        min-height: 10em;
+        overflow: hidden;
+      }
+      .background-request-container-inner.expanded {
+        max-height: none;
+        overflow: auto;
+      }
+      .background-request-container-overlay {
+        position: absolute;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background: linear-gradient(
+          to top,
+          var(--chat-splash-page-info-panel-bg-color),
+          transparent 50%
+        );
+      }
+      .user-background-question {
+        font-family: var(--header-font-family);
+        font-size: var(--font-size-normal);
+        font-weight: var(--font-weight-normal);
+        line-height: var(--line-height-normal);
+      }
+      .expansion-button-container {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+      .info-panel-expansion-button {
+        top: 10px;
+        font-size: 1.5em;
+        border: none;
+        background-color: transparent;
+        color: var(--primary-default);
+        cursor: pointer;
+      }
+      .background-request-header {
+        display: flex;
+        align-items: center;
+        gap: 5px;
+        margin-bottom: 12px;
+        font-weight: bold;
+      }
+      .background-request-header .thinking-spinner {
+        margin-left: auto;
+      }
+      .action-container {
+        background-color: transparent;
+        margin-bottom: 20px;
+        display: flex;
+        justify-content: center;
+        flex-wrap: wrap;
+        width: 100%;
+      }
+      .action-container-title {
+        height: 28px;
+        display: flex;
+        align-items: center;
+        vertical-align: middle;
+        font-size: 0.9em;
+        font-weight: 500;
+        color: var(--chat-splash-page-action-set-title-color);
+      }
+      .action-container-title .autoreview-run-all-button {
+        margin-left: auto;
+        margin-right: 8px;
+      }
+      /* TODO: find small-icon styles equivalent for .small-icon */
+    `,
+  ];
 
   override render() {
     const config = {user: {anonymous_coward_name: ''}} as ServerInfo;
diff --git a/polygerrit-ui/app/elements/chat-panel/user-message.ts b/polygerrit-ui/app/elements/chat-panel/user-message.ts
index 1683a68..4dc7aef 100644
--- a/polygerrit-ui/app/elements/chat-panel/user-message.ts
+++ b/polygerrit-ui/app/elements/chat-panel/user-message.ts
@@ -17,6 +17,7 @@
 import {userModelToken} from '../../models/user/user-model';
 import {AccountDetailInfo} from '../../types/common';
 import {subscribe} from '../lit/subscription-controller';
+import {materialStyles} from '../../styles/gr-material-styles';
 
 const MAX_VISIBLE_CONTEXT_ITEMS_COLLAPSED = 3;
 
@@ -82,56 +83,59 @@
     return this.showAllContextItems ? '▲' : `+${this.numExcessContextItems}`;
   }
 
-  static override styles = css`
-    :host {
-      display: flex;
-      flex-direction: column;
-      padding-bottom: var(--spacing-xl);
-    }
+  static override styles = [
+    materialStyles,
+    css`
+      :host {
+        display: flex;
+        flex-direction: column;
+        padding-bottom: var(--spacing-xl);
+      }
 
-    .user-input-container {
-      padding-top: var(--spacing-m);
-    }
+      .user-input-container {
+        padding-top: var(--spacing-m);
+      }
 
-    .text-content {
-      white-space: pre-wrap;
-      margin: 0px;
-    }
+      .text-content {
+        white-space: pre-wrap;
+        margin: 0px;
+      }
 
-    .context-chip-set {
-      margin-top: var(--spacing-m);
-      display: flex;
-      flex-wrap: wrap;
-      align-items: center;
-      gap: 4px;
-    }
+      .context-chip-set {
+        margin-top: var(--spacing-m);
+        display: flex;
+        flex-wrap: wrap;
+        align-items: center;
+        gap: 4px;
+      }
 
-    gr-avatar {
-      display: block;
-      height: 24px;
-      width: 24px;
-      margin-right: 10px;
-    }
+      gr-avatar {
+        display: block;
+        height: 24px;
+        width: 24px;
+        margin-right: 10px;
+      }
 
-    md-filter-chip.context-toggle-chip {
-      margin: 0;
-      margin-left: auto;
-      --md-filter-chip-unselected-outline-color: var(--border-color);
-      --md-filter-chip-unselected-container-color: var(--elevation-2);
-      --md-filter-chip-container-shape: 8px;
-      --md-filter-chip-container-height: 20px;
+      md-filter-chip.context-toggle-chip {
+        margin: 0;
+        margin-left: auto;
+        --md-filter-chip-unselected-outline-color: var(--border-color);
+        --md-filter-chip-unselected-container-color: var(--elevation-2);
+        --md-filter-chip-container-shape: 8px;
+        --md-filter-chip-container-height: 20px;
 
-      /* from @include mat.chips-overrides */
-      --md-filter-chip-label-text-line-height: var(
-        --line-height-small,
-        1.25rem
-      );
-      --md-filter-chip-label-text-size: var(--font-size-small, 0.75rem);
-      --md-filter-chip-label-text-weight: var(--font-weight-medium, 500);
-      --md-filter-chip-label-text-color: var(--primary-default, purple);
-      cursor: pointer;
-    }
-  `;
+        /* from @include mat.chips-overrides */
+        --md-filter-chip-label-text-line-height: var(
+          --line-height-small,
+          1.25rem
+        );
+        --md-filter-chip-label-text-size: var(--font-size-small, 0.75rem);
+        --md-filter-chip-label-text-weight: var(--font-weight-medium, 500);
+        --md-filter-chip-label-text-color: var(--primary-default, purple);
+        cursor: pointer;
+      }
+    `,
+  ];
 
   override render() {
     if (!this.message) {
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.ts b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.ts
index 70780cd..3085ecc 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.ts
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown.ts
@@ -16,6 +16,7 @@
 import {configModelToken} from '../../../models/config/config-model';
 import {subscribe} from '../../lit/subscription-controller';
 import '@material/web/icon/icon';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 const INTERPOLATE_URL_PATTERN = /\${([\w]+)}/g;
 
@@ -90,6 +91,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         gr-dropdown {
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
index 49df24e..8c6078b 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header.ts
@@ -36,6 +36,7 @@
 import '@material/web/iconbutton/icon-button';
 import {when} from 'lit/directives/when.js';
 import {isElementTarget, isFirefox, isSafari} from '../../../utils/dom-util';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 type MainHeaderLink = RequireProperties<DropdownLink, 'url' | 'name'>;
 
@@ -240,6 +241,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         :host {
diff --git a/polygerrit-ui/app/elements/core/gr-search-autocomplete/gr-search-autocomplete.ts b/polygerrit-ui/app/elements/core/gr-search-autocomplete/gr-search-autocomplete.ts
index a84247a..852e549 100644
--- a/polygerrit-ui/app/elements/core/gr-search-autocomplete/gr-search-autocomplete.ts
+++ b/polygerrit-ui/app/elements/core/gr-search-autocomplete/gr-search-autocomplete.ts
@@ -27,6 +27,7 @@
 import {getDocUrl} from '../../../utils/url-util';
 import '@material/web/iconbutton/icon-button';
 import {when} from 'lit/directives/when.js';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 // Possible static search options for auto complete, without negations.
 const SEARCH_OPERATORS: ReadonlyArray<string> = [
@@ -195,6 +196,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         form {
diff --git a/polygerrit-ui/app/elements/shared/gr-autosubmit-checkbox/gr-autosubmit-checkbox.ts b/polygerrit-ui/app/elements/shared/gr-autosubmit-checkbox/gr-autosubmit-checkbox.ts
index ee42afd..c1b0d56 100644
--- a/polygerrit-ui/app/elements/shared/gr-autosubmit-checkbox/gr-autosubmit-checkbox.ts
+++ b/polygerrit-ui/app/elements/shared/gr-autosubmit-checkbox/gr-autosubmit-checkbox.ts
@@ -20,6 +20,7 @@
 import {ParsedChangeInfo} from '../../../types/types';
 import {fire} from '../../../utils/event-util';
 import {changeIsMerged} from '../../../utils/change-util';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 export interface AutosubmitCheckedChangedEventDetail {
   checked: boolean;
@@ -60,6 +61,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       formStyles,
       sharedStyles,
       css`
@@ -178,6 +180,8 @@
       target="_blank"
       rel="noopener noreferrer"
       tabindex="-1"
+      @click=${() =>
+        this.reporting.reportInteraction('flows-documentation-link-clicked')}
     >
       <md-icon-button touch-target="none" type="button">
         <gr-icon icon="help" title="read documentation"></gr-icon>
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button.ts b/polygerrit-ui/app/elements/shared/gr-button/gr-button.ts
index 9be2f0c..eaf5c8c 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button.ts
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button.ts
@@ -14,6 +14,7 @@
 import {Interaction} from '../../../constants/reporting';
 import '@material/web/button/elevated-button';
 import '@material/web/button/text-button';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 declare global {
   interface HTMLElementTagNameMap {
@@ -59,6 +60,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       votingStyles,
       spinnerStyles,
       css`
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.ts b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.ts
index 4e65b99..c913c8c 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.ts
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list.ts
@@ -28,6 +28,7 @@
 import {MdMenu} from '@material/web/menu/menu';
 import {isSafari, Key} from '../../../utils/dom-util';
 import {GrCursorManager} from '../gr-cursor-manager/gr-cursor-manager';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 /**
  * Required values are text and value. mobileText and triggerText will
@@ -110,6 +111,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         :host {
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.ts b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.ts
index 910d481..65efb57 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.ts
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown.ts
@@ -23,6 +23,7 @@
 import '@material/web/menu/menu';
 import '@material/web/menu/menu-item';
 import {MdMenu} from '@material/web/menu/menu';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 const REL_NOOPENER = 'noopener';
 const REL_EXTERNAL = 'external';
@@ -51,6 +52,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         :host {
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
index 634a83d..6c2661f 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label.ts
@@ -23,6 +23,7 @@
 import {MdMenu} from '@material/web/menu/menu';
 import '@material/web/textfield/filled-text-field';
 import {MdFilledTextField} from '@material/web/textfield/filled-text-field';
+import {materialStyles} from '../../../styles/gr-material-styles';
 
 const AWAIT_MAX_ITERS = 10;
 const AWAIT_STEP = 5;
@@ -87,6 +88,7 @@
 
   static override get styles() {
     return [
+      materialStyles,
       sharedStyles,
       css`
         :host {
diff --git a/polygerrit-ui/app/utils/change-util.ts b/polygerrit-ui/app/utils/change-util.ts
index 1a6f8d2..446c098 100644
--- a/polygerrit-ui/app/utils/change-util.ts
+++ b/polygerrit-ui/app/utils/change-util.ts
@@ -89,17 +89,22 @@
 ): ChangeStates[] {
   const states: ChangeStates[] = [];
 
+  if (change.is_private) {
+    states.push(ChangeStates.PRIVATE);
+  }
+
   if (change.status === ChangeStatus.MERGED) {
+    states.push(ChangeStates.MERGED);
     if (options?.revertingChangeStatus === ChangeStatus.MERGED) {
-      return [ChangeStates.MERGED, ChangeStates.REVERT_SUBMITTED];
+      states.push(ChangeStates.REVERT_SUBMITTED);
+    } else if (options?.revertingChangeStatus !== undefined) {
+      states.push(ChangeStates.REVERT_CREATED);
     }
-    if (options?.revertingChangeStatus !== undefined) {
-      return [ChangeStates.MERGED, ChangeStates.REVERT_CREATED];
-    }
-    return [ChangeStates.MERGED];
+    return states;
   }
   if (change.status === ChangeStatus.ABANDONED) {
-    return [ChangeStates.ABANDONED];
+    states.push(ChangeStates.ABANDONED);
+    return states;
   }
 
   if (change.revert_of) {
@@ -114,9 +119,6 @@
   if (change.work_in_progress) {
     states.push(ChangeStates.WIP);
   }
-  if (change.is_private) {
-    states.push(ChangeStates.PRIVATE);
-  }
 
   // The gr-change-list table does not want READY TO SUBMIT or ACTIVE and it
   // does not pass options.
diff --git a/polygerrit-ui/app/utils/change-util_test.ts b/polygerrit-ui/app/utils/change-util_test.ts
index b17cc1c..45762a7 100644
--- a/polygerrit-ui/app/utils/change-util_test.ts
+++ b/polygerrit-ui/app/utils/change-util_test.ts
@@ -83,6 +83,15 @@
     assert.deepEqual(statuses, [ChangeStates.MERGE_CONFLICT]);
   });
 
+  test('Git conflict', () => {
+    const change = {
+      ...createChangeWithStatus(ChangeStatus.NEW, true),
+      contains_git_conflicts: true,
+    };
+    const statuses = changeStatuses(change);
+    assert.deepEqual(statuses, [ChangeStates.GIT_CONFLICT]);
+  });
+
   test('Merge conflict', () => {
     const change = createChangeWithStatus(ChangeStatus.NEW, false);
     const statuses = changeStatuses(change);
@@ -99,9 +108,15 @@
     const change = createChangeWithStatus(ChangeStatus.MERGED);
     assert.deepEqual(changeStatuses(change), [ChangeStates.MERGED]);
     change.is_private = true;
-    assert.deepEqual(changeStatuses(change), [ChangeStates.MERGED]);
+    assert.deepEqual(changeStatuses(change), [
+      ChangeStates.PRIVATE,
+      ChangeStates.MERGED,
+    ]);
     change.work_in_progress = true;
-    assert.deepEqual(changeStatuses(change), [ChangeStates.MERGED]);
+    assert.deepEqual(changeStatuses(change), [
+      ChangeStates.PRIVATE,
+      ChangeStates.MERGED,
+    ]);
   });
 
   test('Merged and Reverted status', () => {
@@ -132,9 +147,15 @@
     const change = createChangeWithStatus(ChangeStatus.ABANDONED, false);
     assert.deepEqual(changeStatuses(change), [ChangeStates.ABANDONED]);
     change.is_private = true;
-    assert.deepEqual(changeStatuses(change), [ChangeStates.ABANDONED]);
+    assert.deepEqual(changeStatuses(change), [
+      ChangeStates.PRIVATE,
+      ChangeStates.ABANDONED,
+    ]);
     change.work_in_progress = true;
-    assert.deepEqual(changeStatuses(change), [ChangeStates.ABANDONED]);
+    assert.deepEqual(changeStatuses(change), [
+      ChangeStates.PRIVATE,
+      ChangeStates.ABANDONED,
+    ]);
   });
 
   test('Revert status', () => {
@@ -145,8 +166,8 @@
     assert.deepEqual(changeStatuses(change), [ChangeStates.REVERT]);
     change.is_private = true;
     assert.deepEqual(changeStatuses(change), [
-      ChangeStates.REVERT,
       ChangeStates.PRIVATE,
+      ChangeStates.REVERT,
     ]);
   });
 
@@ -174,7 +195,7 @@
       labels: {},
     };
     const statuses = changeStatuses(change);
-    assert.deepEqual(statuses, [ChangeStates.WIP, ChangeStates.PRIVATE]);
+    assert.deepEqual(statuses, [ChangeStates.PRIVATE, ChangeStates.WIP]);
   });
 
   test('Merge conflict with private and wip', () => {
@@ -190,12 +211,48 @@
     };
     const statuses = changeStatuses(change);
     assert.deepEqual(statuses, [
+      ChangeStates.PRIVATE,
       ChangeStates.MERGE_CONFLICT,
       ChangeStates.WIP,
-      ChangeStates.PRIVATE,
     ]);
   });
 
+  test('Private prevents READY_TO_SUBMIT', () => {
+    const change = {
+      ...createChange(),
+      status: ChangeStatus.NEW,
+      mergeable: true,
+      is_private: true,
+      submittable: true,
+    };
+    const statuses = changeStatuses(change, {mergeable: true});
+    assert.deepEqual(statuses, [ChangeStates.PRIVATE]);
+  });
+
+  test('WIP prevents READY_TO_SUBMIT', () => {
+    const change = {
+      ...createChange(),
+      status: ChangeStatus.NEW,
+      mergeable: true,
+      work_in_progress: true,
+      submittable: true,
+    };
+    const statuses = changeStatuses(change, {mergeable: true});
+    assert.deepEqual(statuses, [ChangeStates.WIP]);
+  });
+
+  test('Git conflict prevents READY_TO_SUBMIT', () => {
+    const change = {
+      ...createChange(),
+      status: ChangeStatus.NEW,
+      mergeable: true,
+      contains_git_conflicts: true,
+      submittable: true,
+    };
+    const statuses = changeStatuses(change, {mergeable: true});
+    assert.deepEqual(statuses, [ChangeStates.GIT_CONFLICT]);
+  });
+
   test('hasHumanReviewer', () => {
     const owner = createAccountWithId(1);
     const change = {
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row-dark.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row-dark.png
index 49cbcf6..a26b67f 100644
--- a/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row-dark.png
+++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row-dark.png
Binary files differ
diff --git a/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row.png b/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row.png
index 4fa6f74..ab28bdf 100644
--- a/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row.png
+++ b/polygerrit-ui/screenshots/Chromium/baseline/gr-label-score-row.png
Binary files differ
diff --git a/resources/com/google/gerrit/pgm/init/gerrit.service b/resources/com/google/gerrit/pgm/init/gerrit.service
index 750dbb4..2d275fd 100644
--- a/resources/com/google/gerrit/pgm/init/gerrit.service
+++ b/resources/com/google/gerrit/pgm/init/gerrit.service
@@ -12,6 +12,7 @@
 User=gerritsrv
 SyslogIdentifier=GerritCodeReview
 StandardInput=socket
+OOMScoreAdjust=-1000
 
 [Install]
 WantedBy=multi-user.target
diff --git a/resources/com/google/gerrit/pgm/init/gerrit.sh b/resources/com/google/gerrit/pgm/init/gerrit.sh
index 8c958c9..67d95b2 100755
--- a/resources/com/google/gerrit/pgm/init/gerrit.sh
+++ b/resources/com/google/gerrit/pgm/init/gerrit.sh
@@ -536,7 +536,11 @@
                 echo -16 > "/proc/${PID}/oom_adj"
             fi
         fi
-    elif [ "$(uname -s)"=="Linux" ] && test -d "/proc/${PID}"; then
+    elif test -f "/proc/${PID}/oom_score_adj" && ! test "$(cat "/proc/${PID}/oom_score_adj")" = "0" ; then
+        : # Do nothing. OOM score already adjusted.
+    elif test -f "/proc/${PID}/oom_adj" && ! test "$(cat "/proc/${PID}/oom_adj")" = "0" ; then
+        : # Do nothing. OOM score already adjusted.
+    elif test "$(uname -s)" = "Linux" && test -d "/proc/${PID}"; then
         echo "WARNING: Could not adjust Gerrit's process for the kernel's out-of-memory killer."
         echo "         This may be caused by ${0} not being run as root."
         echo "         Consider changing the OOM score adjustment manually for Gerrit's PID=${PID} with e.g.:"
diff --git a/tools/BUILD b/tools/BUILD
index e306a0a..9529ec7 100644
--- a/tools/BUILD
+++ b/tools/BUILD
@@ -14,7 +14,7 @@
     name = "protoc_java_toolchain",
     command_line = "--java_out=%s",
     progress_message = "Generating Java proto_library %{label}",
-    runtime = "@gerrit_deps//:com_google_protobuf_protobuf_java",
+    runtime = "@external_deps//:com_google_protobuf_protobuf_java",
     toolchain_type = "@rules_java//java/proto:toolchain_type",
 )
 
diff --git a/tools/bzl/classpath.bzl b/tools/bzl/classpath.bzl
index e196c10..9b24a4d 100644
--- a/tools/bzl/classpath.bzl
+++ b/tools/bzl/classpath.bzl
@@ -1,27 +1,102 @@
+# Utility rule for IDE integration (Eclipse, IntelliJ, etc.).
+#
+# This rule produces metadata files:
+#
+#   - %{name}.runtime_classpath
+#       One runtime jar path per line. Used to construct the IDE classpath.
+#
+#   - %{name}.source_classpath
+#       One source-jar path per line. Used to attach sources to libraries in
+#       the IDE.
+#
+# Important implementation details:
+#
+# * With rules_jvm_external, many Maven artifacts (including sources) are
+#   resolved lazily. A jar may appear in a provider but not exist on disk
+#   unless it is consumed by an action.
+#
+# * IDEs require real files on disk. Simply listing paths is insufficient.
+#
+# * To ensure jars are materialized under the Bazel execution root, this rule
+#   declares them as inputs to small, no-op actions ("stamp" actions).
+#
+# * A param file is used for source jars to avoid command-line length limits.
+#   Bazel does not automatically expand "@paramfile" in run_shell, so the
+#   script explicitly strips the '@' prefix and reads the file.
+
 load("@rules_java//java:defs.bzl", "JavaInfo")
 
-def _classpath_collector(ctx):
-    all = []
+def _classpath_collector_impl(ctx):
+    runtime_sets = []
+    source_sets = []
+
     for d in ctx.attr.deps:
         if JavaInfo in d:
-            all.append(d[JavaInfo].transitive_runtime_jars)
-            if hasattr(d[JavaInfo].compilation_info, "runtime_classpath"):
-                all.append(d[JavaInfo].compilation_info.runtime_classpath)
-        elif hasattr(d, "files"):
-            all.append(d.files)
+            j = d[JavaInfo]
 
-    as_strs = [c.path for c in depset(transitive = all).to_list()]
+            runtime_sets.append(j.transitive_runtime_jars)
+
+            ci = j.compilation_info
+            if ci and hasattr(ci, "runtime_classpath"):
+                runtime_sets.append(ci.runtime_classpath)
+
+            source_sets.append(j.transitive_source_jars)
+
+        elif hasattr(d, "files"):
+            runtime_sets.append(d.files)
+
+    runtime_files = depset(transitive = runtime_sets).to_list()
+    source_files = depset(transitive = source_sets).to_list()
+
+    # Runtime classpath: metadata file.
     ctx.actions.write(
         output = ctx.outputs.runtime,
-        content = "\n".join(sorted(as_strs)),
+        content = "\n".join(sorted([f.path for f in runtime_files])),
+    )
+
+    # Force runtime jars to be present on disk.
+    runtime_stamp = ctx.actions.declare_file(ctx.label.name + ".runtime_materialized")
+    ctx.actions.run_shell(
+        inputs = runtime_files,
+        outputs = [runtime_stamp],
+        arguments = [runtime_stamp.path],
+        command = r"""
+set -euo pipefail
+: > "$1"
+""",
+    )
+
+    # Source classpath: write stable sorted list, and materialize jars by
+    # declaring them as inputs.
+    pf = ctx.actions.args()
+    pf.set_param_file_format("multiline")
+    pf.use_param_file("%s", use_always = True)
+    pf.add_all([f.path for f in source_files])
+
+    ctx.actions.run_shell(
+        inputs = source_files,
+        outputs = [ctx.outputs.sources],
+        arguments = [ctx.outputs.sources.path, pf],
+        command = r"""
+set -euo pipefail
+OUT="$1"
+PF="$2"
+PF="${PF#@}"
+if [ -n "$PF" ] && [ -f "$PF" ]; then
+  sort "$PF" > "$OUT"
+else
+  : > "$OUT"
+fi
+""",
     )
 
 classpath_collector = rule(
+    implementation = _classpath_collector_impl,
     attrs = {
         "deps": attr.label_list(),
     },
     outputs = {
         "runtime": "%{name}.runtime_classpath",
+        "sources": "%{name}.source_classpath",
     },
-    implementation = _classpath_collector,
 )
diff --git a/tools/bzl/pkg_war.bzl b/tools/bzl/pkg_war.bzl
index 61b3bb8..7151766 100644
--- a/tools/bzl/pkg_war.bzl
+++ b/tools/bzl/pkg_war.bzl
@@ -62,10 +62,6 @@
     ]
 
 def _should_skip_runtime_jar(dep):
-    # Do not package any jars coming from jgit_deps.
-    if "jgit_deps" in dep.path:
-        return True
-
     raw = dep.basename
     if raw.startswith(PROCESSED_PREFIX):
         raw = raw[len(PROCESSED_PREFIX):]
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
index 175fd46..07dd5bd 100644
--- a/tools/eclipse/BUILD
+++ b/tools/eclipse/BUILD
@@ -45,17 +45,17 @@
     name = "autovalue_classpath_collect",
     deps = [
         "//lib/auto:auto-value",
-        "@gerrit_deps//:com_google_auto_auto_common",
-        "@gerrit_deps//:com_google_auto_factory_auto_factory",
-        "@gerrit_deps//:com_google_auto_service_auto_service_annotations",
-        "@gerrit_deps//:com_google_auto_value_auto_value_annotations",
-        "@gerrit_deps//:com_google_code_gson_gson",
-        "@gerrit_deps//:com_google_guava_guava",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_extension",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_factory",
-        "@gerrit_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
-        "@gerrit_deps//:com_squareup_javapoet",
-        "@gerrit_deps//:io_sweers_autotransient_autotransient",
-        "@gerrit_deps//:javax_inject_javax_inject",
+        "@external_deps//:com_google_auto_auto_common",
+        "@external_deps//:com_google_auto_factory_auto_factory",
+        "@external_deps//:com_google_auto_service_auto_service_annotations",
+        "@external_deps//:com_google_auto_value_auto_value_annotations",
+        "@external_deps//:com_google_code_gson_gson",
+        "@external_deps//:com_google_guava_guava",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_extension",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_factory",
+        "@external_deps//:com_ryanharter_auto_value_auto_value_gson_runtime",
+        "@external_deps//:com_squareup_javapoet",
+        "@external_deps//:io_sweers_autotransient_autotransient",
+        "@external_deps//:javax_inject_javax_inject",
     ],
 )
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index 2302ead..eaf7c83 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -105,6 +105,10 @@
     return subprocess.check_output(_build_bazel_cmd('info', 'output_base')).strip()
 
 
+def retrieve_exec_root():
+    return subprocess.check_output(_build_bazel_cmd('info', 'execution_root')).strip()
+
+
 def gen_bazel_path(ext_location):
     bazel = subprocess.check_output(['which', bazel_exe]).strip().decode('UTF-8')
     with open(os.path.join(ROOT, ".bazel_path"), 'w') as fd:
@@ -114,15 +118,33 @@
 
 
 def _query_classpath(target):
-    deps = []
     t = cp_targets[target]
     try:
         subprocess.check_call(_build_bazel_cmd('build', t))
     except subprocess.CalledProcessError:
         exit(1)
-    name = 'bazel-bin/tools/eclipse/' + t.split(':')[1] + '.runtime_classpath'
-    deps = [line.rstrip('\n') for line in open(name)]
-    return deps
+
+    base = 'bazel-bin/tools/eclipse/' + t.split(':')[1]
+
+    runtime_name = base + '.runtime_classpath'
+    runtime = [line.rstrip('\n') for line in open(runtime_name)]
+
+    sources = []
+    sources_name = base + '.source_classpath'
+    if os.path.exists(sources_name):
+        sources = [line.rstrip('\n') for line in open(sources_name)]
+
+    return runtime, sources
+
+
+def _normalize_jar_basename(p):
+    b = os.path.basename(p)
+    for pref in ('processed_', 'header_'):
+        if b.startswith(pref):
+            b = b[len(pref):]
+    if b.endswith('-sources.jar'):
+        b = b[:-len('-sources.jar')] + '.jar'
+    return b
 
 
 def gen_project(name='gerrit', root=ROOT):
@@ -227,13 +249,19 @@
     # Classpath entries are absolute for cross-cell support
     java_library = re.compile('bazel-out/.*?-fastbuild/bin/(.*)/[^/]+[.]jar$')
     proto_library = re.compile('bazel-out/.*?-fastbuild/bin/(.*)proto/(.*)_proto-speed[.]jar$')
-    srcs = re.compile('(.*/external/[^/]+)/jar/(.*)[.]jar')
-    for p in _query_classpath(MAIN):
+
+    runtime_cp, source_cp = _query_classpath(MAIN)
+
+    source_by_basename = {}
+    for p in source_cp:
+        source_by_basename[_normalize_jar_basename(p)] = p
+
+    for p in runtime_cp:
         if p.endswith('-src.jar'):
             continue
 
         m = java_library.match(p)
-        if m:
+        if m and "/external/" not in p:
             src.add(m.group(1))
             # Exceptions: both source and lib
             if p.endswith('libquery_parser.jar') or \
@@ -291,13 +319,17 @@
     for libs in [lib]:
         for j in sorted(libs):
             s = None
-            m = srcs.match(j)
-            if m:
-                prefix = m.group(1)
-                suffix = m.group(2)
-                p = os.path.join(prefix, "jar", "%s-src.jar" % suffix)
-                if os.path.exists(p):
-                    s = p
+
+            # Attach sources using the classpath_collector output from rules_jvm_external.
+            # This replaces the previous heuristic-based source lookup.
+            key = _normalize_jar_basename(j)
+            if key in source_by_basename:
+                sp = source_by_basename[key]
+                if sp.startswith("external"):
+                    s = os.path.join(ext, sp)
+                else:
+                    s = sp
+
             if args.plugins:
                 classpathentry('lib', j, s, exported=True)
             else:
@@ -332,7 +364,10 @@
 def gen_factorypath(ext):
     doc = xml.dom.minidom.getDOMImplementation().createDocument(
         None, 'factorypath', None)
-    for jar in _query_classpath(AUTO):
+
+    runtime, _ = _query_classpath(AUTO)
+
+    for jar in runtime:
         e = doc.createElement('factorypathentry')
         e.setAttribute('kind', 'EXTJAR')
         e.setAttribute('id', os.path.join(ext, jar))
@@ -346,11 +381,12 @@
 
 
 try:
-    ext_location = retrieve_ext_location().decode("utf-8")
+    output_base = retrieve_ext_location().decode("utf-8")
+    exec_root = retrieve_exec_root().decode("utf-8")
     gen_project(args.project_name)
-    gen_classpath(ext_location)
-    gen_factorypath(ext_location)
-    gen_bazel_path(ext_location)
+    gen_classpath(exec_root)
+    gen_factorypath(output_base)
+    gen_bazel_path(output_base)
 
     try:
         subprocess.check_call(_build_bazel_cmd('build', MAIN))
@@ -359,3 +395,4 @@
 except KeyboardInterrupt:
     print('Interrupted by user', file=sys.stderr)
     exit(1)
+