diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 36b011a469c9428e7a48ed6faf574ca4d9e4f0e5..bee7aa11543c092ac46d22be8d820b2006a8d2a1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-# cspell:ignore codequality Micheh micheh webide updatedb stylelintrc unshallow
+# cspell:ignore codequality Micheh micheh webide testdox updatedb stylelintrc
 
 ################
 # Drupal GitLabCI template.
@@ -103,6 +103,25 @@ default:
   rules:
     - if: $PERFORMANCE_TEST != "1"
 
+.default-phpunit-job-settings: &default-phpunit-job-settings
+  stage: 🪄 Lint
+  before_script:
+    - composer validate
+    - composer install --optimize-autoloader
+    - mkdir -p ./sites/simpletest ./sites/default/files ./build/logs/junit /var/www/.composer
+    - chown -R www-data:www-data ./sites ./build/logs/junit ./vendor /var/www/
+  script:
+    - sudo -u www-data -E -H php ./core/scripts/run-tests.sh --color --keep-results --types "$TESTSUITE" --concurrency "$CONCURRENCY" --repeat "1" --sqlite "./sites/default/files/tests.sqlite" --verbose --non-html --all
+  after_script:
+    - sed -i "s#$CI_PROJECT_DIR/##" ./sites/default/files/simpletest/phpunit-*.xml || true
+  artifacts:
+    when: always
+    expire_in: 6 mos
+    reports:
+      junit: ./sites/default/files/simpletest/phpunit-*.xml
+    paths:
+      - ./sites/default/files/simpletest/phpunit-*.xml
+
 .prepare-lint-directory: &prepare-lint-directory
   # PHPStan and yarn linting use absolute paths to determine cache validity. Because GitLab CI
   # working directories are not consistent, work around this by running linting in a separate,
@@ -312,40 +331,30 @@ default:
 # Lint Jobs
 ################
 
-
-'Lint cache warming':
+'📔 Spell-checking':
   <<: [ *default-job-settings-lint ]
   stage: 🪄 Lint
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project"
-    - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" && $DAILY_TEST == "1"
-    - when: manual
-      allow_failure: true
   variables:
-    KUBERNETES_CPU_REQUEST: "4"
+    KUBERNETES_CPU_REQUEST: "2"
   script:
     - *prepare-lint-directory
-    - *phpstan-cache
     - *cspell-cache
-    - *eslint-cache
-    - *stylelint-cache
-    - composer install
-    - vendor/bin/phpstan --version
-    - php vendor/bin/phpstan -vvv analyze --configuration=./core/phpstan.neon.dist
     - *core-spellcheck
-    - yarn run lint:core-js-passing --cache --cache-strategy content
-    - yarn run build:css --check
-    - yarn run lint:css --cache --cache-location .stylelintcache --cache-strategy content
-    - mv -f /build/core/phpstan-tmp $CI_PROJECT_DIR/core
-    - mv -f /build/core/.cspellcache $CI_PROJECT_DIR/core
-    - mv -f  /build/core/.eslintcache $CI_PROJECT_DIR/core
-    - mv -f  /build/core/.stylelintcache $CI_PROJECT_DIR/core
+    - mv -f /build/core/package.json $CI_PROJECT_DIR/core/package.json
+    - mv -f /build/core/yarn.lock $CI_PROJECT_DIR/core/yarn.lock
+    - mv /build/core/node_modules $CI_PROJECT_DIR/core
+  cache:
+    key:
+      files:
+        - ./core/package.json
+        - ./core/yarn.lock
+    paths:
+      - ./core/node_modules
   artifacts:
+    expire_in: 1 week
+    expose_as: 'yarn-vendor'
     paths:
-      - core/phpstan-tmp/resultCache.php
-      - core/.cspellcache
-      - core/.eslintcache
-      - core/.stylelintcache
+      - core/node_modules/
 
 '📔 Spell-checking':
   <<: [ *default-job-settings-lint ]
@@ -489,6 +498,48 @@ default:
     reports:
       codequality: gl-codequality.json
 
+'⚡️ PHPUnit Unit tests on PHP 8.3':
+  <<: [ *default-job-settings-lint, *default-phpunit-job-settings ]
+  variables:
+    TESTSUITE: PHPUnit-Unit
+    KUBERNETES_CPU_REQUEST: "8"
+    CONCURRENCY: 24
+    _TARGET_PHP: "8.3-ubuntu"
+
+'⚡️ PHPUnit Unit tests on PHP 8.4':
+  <<: [ *default-job-settings-lint, *default-phpunit-job-settings ]
+  variables:
+    TESTSUITE: PHPUnit-Unit
+    KUBERNETES_CPU_REQUEST: "8"
+    CONCURRENCY: 24
+    _TARGET_PHP: "8.4-ubuntu"
+
+'✅️ PHPStan rules tests':
+  <<: [ *default-job-settings-lint ]
+  stage: 🪄 Lint
+  variables:
+    KUBERNETES_CPU_REQUEST: "2"
+  # Run if PHPStan files have changed, or manually.
+  rules:
+    - if: $PERFORMANCE_TEST != "1"
+      changes:
+        - core/tests/PHPStan/**/*
+        - composer/Metapackage/PinnedDevDependencies/composer.json
+    - when: manual
+      allow_failure: true
+  script:
+    - docker-php-ext-enable pcov
+    - cd core/tests/PHPStan
+    - composer install
+    - vendor/bin/phpunit tests --testdox --coverage-text --colors=always --coverage-cobertura=coverage.cobertura.xml --log-junit junit.xml
+  artifacts:
+    when: always
+    reports:
+      junit: core/tests/PHPStan/junit.xml
+      coverage_report:
+        coverage_format: cobertura
+        path: core/tests/PHPStan/coverage.cobertura.xml
+
 '📔 Validatable config':
   <<: [ *default-job-settings-lint ]
   stage: 🪄 Lint
@@ -549,3 +600,36 @@ default:
          $impact = array_map(fn (float $h, float $m) => $m-$h, $head, $mr);
          exit((int) (min($impact) < 0));
       '
+
+'Lint cache warming':
+  <<: [ *default-job-settings-lint ]
+  stage: 🪄 Lint
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project"
+    - if: $CI_PIPELINE_SOURCE == "schedule" && $CI_PROJECT_ROOT_NAMESPACE == "project" && $DAILY_TEST == "1"
+  variables:
+    KUBERNETES_CPU_REQUEST: "4"
+  script:
+    - *prepare-lint-directory
+    - *phpstan-cache
+    - *cspell-cache
+    - *eslint-cache
+    - *stylelint-cache
+    - composer install
+    - vendor/bin/phpstan --version
+    - php vendor/bin/phpstan -vvv analyze --configuration=./core/phpstan.neon.dist
+    - *core-spellcheck
+    - yarn run lint:core-js-passing --cache --cache-strategy content
+    - yarn run build:css --check
+    - yarn run lint:css --cache --cache-location .stylelintcache --cache-strategy content
+    - mv -f /build/core/phpstan-tmp $CI_PROJECT_DIR/core
+    - mv -f /build/core/.cspellcache $CI_PROJECT_DIR/core
+    - mv -f  /build/core/.eslintcache $CI_PROJECT_DIR/core
+    - mv -f  /build/core/.stylelintcache $CI_PROJECT_DIR/core
+  artifacts:
+    paths:
+      - core/phpstan-tmp/resultCache.php
+      - core/.cspellcache
+      - core/.eslintcache
+      - core/.stylelintcache
+
diff --git a/.gitlab-ci/pipeline.yml b/.gitlab-ci/pipeline.yml
index 3ed4a14a65c7b474757e45bbc26693fdae5b41ba..ee6f1e0e1769214f4a64d8075734239d2d7c60ab 100644
--- a/.gitlab-ci/pipeline.yml
+++ b/.gitlab-ci/pipeline.yml
@@ -1,4 +1,4 @@
-# cspell:ignore cobertura drupaltestbot drupaltestbotpw Dwebdriver logfile testdox XVFB
+# cspell:ignore drupaltestbot drupaltestbotpw Dwebdriver logfile XVFB
 
 stages:
   - 🗜️ Test
@@ -180,42 +180,6 @@ variables:
   services:
     - <<: *with-database
 
-'⚡️ PHPUnit Unit':
-  <<: [ *with-composer, *run-tests, *default-job-settings ]
-  variables:
-    TESTSUITE: PHPUnit-Unit
-    KUBERNETES_CPU_REQUEST: "1"
-    CONCURRENCY: 6
-
-'✅️ PHPStan Tests':
-  <<: [ *default-job-settings ]
-  variables:
-    KUBERNETES_CPU_REQUEST: "2"
-  # Run if PHPStan files have changed, or manually.
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "parent_pipeline" && $PERFORMANCE_TEST != "1"
-      changes:
-        - core/tests/PHPStan/*
-        - composer/Metapackage/PinnedDevDependencies/composer.json
-    - when: manual
-      allow_failure: true
-  # Default job settings runs a script that expects vendor to exist.
-  before_script: []
-  script:
-    - docker-php-ext-enable pcov
-    - cd core/tests/PHPStan
-    - composer install
-    - vendor/bin/phpunit tests --testdox --coverage-text --colors=never --coverage-cobertura=coverage.cobertura.xml --log-junit junit.xml
-  # Default job settings runs a script that junit files in a specific location..
-  after_script: []
-  artifacts:
-    when: always
-    reports:
-      junit: core/tests/PHPStan/junit.xml
-      coverage_report:
-        coverage_format: cobertura
-        path: core/tests/PHPStan/coverage.cobertura.xml
-
 '🦉️️️ Nightwatch':
   <<: [ *with-composer-and-yarn, *default-job-settings ]
   variables:
diff --git a/core/.phpstan-baseline.php b/core/.phpstan-baseline.php
index 39bf5eadfea132ce8e2fb1fc772225ac6e501a3e..40944cccb9eccd59591aa7c6d54472f2b6c01cb4 100644
--- a/core/.phpstan-baseline.php
+++ b/core/.phpstan-baseline.php
@@ -38817,42 +38817,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/modules/update/src/Controller/UpdateController.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateManagerUpdate\\:\\:create\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateManagerUpdate.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateManagerUpdate\\:\\:removeCheckboxFromRow\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateManagerUpdate.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateManagerUpdate\\:\\:submitForm\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateManagerUpdate.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateManagerUpdate\\:\\:validateForm\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateManagerUpdate.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateReady\\:\\:create\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateReady.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Form\\\\UpdateReady\\:\\:submitForm\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Form/UpdateReady.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method Drupal\\\\update\\\\ProjectCoreCompatibility\\:\\:setReleaseMessage\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
@@ -38865,12 +38829,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/modules/update/src/ProjectRelease.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\update\\\\Routing\\\\UpdateRouteSubscriber\\:\\:alterRoutes\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/src/Routing/UpdateRouteSubscriber.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method Drupal\\\\update\\\\UpdateManager\\:\\:fetchDataBatch\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
@@ -39069,24 +39027,12 @@
 	'count' => 1,
 	'path' => __DIR__ . '/modules/update/tests/src/Kernel/Migrate/d6/MigrateUpdateConfigsTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\Tests\\\\update\\\\Unit\\\\Menu\\\\UpdateLocalTasksTest\\:\\:getUpdateModuleRoutes\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method Drupal\\\\Tests\\\\update\\\\Unit\\\\Menu\\\\UpdateLocalTasksTest\\:\\:getUpdateReportRoutes\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
 	'count' => 1,
 	'path' => __DIR__ . '/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\Tests\\\\update\\\\Unit\\\\Menu\\\\UpdateLocalTasksTest\\:\\:getUpdateThemeRoutes\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Method Drupal\\\\Tests\\\\update\\\\Unit\\\\ProjectCoreCompatibilityTest\\:\\:providerSetProjectCoreCompatibilityRanges\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
@@ -39141,12 +39087,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/modules/update/update.manager.inc',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Function update_manager_download_batch_finished\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/modules/update/update.manager.inc',
-];
 $ignoreErrors[] = [
 	'message' => '#^Function _update_no_data\\(\\) has no return type specified\\.$#',
 	'identifier' => 'missingType.return',
@@ -54393,18 +54333,6 @@
 	'count' => 1,
 	'path' => __DIR__ . '/tests/Drupal/TestSite/TestSiteOliveroInstallTestScript.php',
 ];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\TestTools\\\\TestVarDumper\\:\\:cliHandler\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/Drupal/TestTools/TestVarDumper.php',
-];
-$ignoreErrors[] = [
-	'message' => '#^Method Drupal\\\\TestTools\\\\TestVarDumper\\:\\:htmlHandler\\(\\) has no return type specified\\.$#',
-	'identifier' => 'missingType.return',
-	'count' => 1,
-	'path' => __DIR__ . '/tests/Drupal/TestTools/TestVarDumper.php',
-];
 $ignoreErrors[] = [
 	'message' => '#^Call to deprecated method getConfig\\(\\) of class GuzzleHttp\\\\Client\\:
 Client\\:\\:getConfig will be removed in guzzlehttp/guzzle\\:8\\.0\\.$#',
diff --git a/core/lib/Drupal/Component/Utility/Html.php b/core/lib/Drupal/Component/Utility/Html.php
index dc9fbb26757601916cfdb1903339a1d4faa0a13f..38b328a4c61c9ab6544a8ca70fb9055be73241e7 100644
--- a/core/lib/Drupal/Component/Utility/Html.php
+++ b/core/lib/Drupal/Component/Utility/Html.php
@@ -441,11 +441,11 @@ public static function escape(string $text): string {
    * change other relative URLs because they would result in different absolute
    * URLs depending on the current path. For example: when the same content
    * containing such a relative URL (for example 'image.png'), is served from
-   * its canonical URL (for example 'http://example.com/some-article') or from
-   * a listing or feed (for example 'http://example.com/all-articles') their
+   * its canonical URL (for example 'https://example.com/some-article') or from
+   * a listing or feed (for example 'https://example.com/all-articles') their
    * "current path" differs, resulting in different absolute URLs:
-   * 'http://example.com/some-article/image.png' versus
-   * 'http://example.com/all-articles/image.png'. Only one can be correct.
+   * 'https://example.com/some-article/image.png' versus
+   * 'https://example.com/all-articles/image.png'. Only one can be correct.
    * Therefore relative URLs that are not root-relative cannot be safely
    * transformed and should generally be avoided.
    *
diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index 3b32dc9625e69330049cd9bf79b0ef74d8622cf6..9619dcf0703105754d04ad8d84a829822a44e6fd 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -216,7 +216,7 @@ public static function parse($url) {
     else {
       // parse_url() does not support relative URLs, so make it absolute. For
       // instance, the relative URL "foo/bar:1" isn't properly parsed.
-      $parts = parse_url('http://example.com/' . $url);
+      $parts = parse_url('https://example.com/' . $url);
       // Strip the leading slash that was just added.
       $options['path'] = substr($parts['path'], 1);
       if (isset($parts['query'])) {
@@ -248,13 +248,13 @@ public static function encodePath($path) {
   /**
    * Determines whether a path is external to Drupal.
    *
-   * An example of an external path is http://example.com. If a path cannot be
+   * An example of an external path is https://example.com. If a path cannot be
    * assessed by Drupal's menu handler, then we must treat it as potentially
    * insecure.
    *
    * @param string $path
    *   The internal path or external URL being linked to, such as "node/34" or
-   *   "http://example.com/foo".
+   *   "https://example.com/foo".
    *
    * @return bool
    *   TRUE or FALSE, where TRUE indicates an external path.
@@ -283,9 +283,9 @@ public static function isExternal($path) {
    * Determines if an external URL points to this installation.
    *
    * @param string $url
-   *   A string containing an external URL, such as "http://example.com/foo".
+   *   A string containing an external URL, such as "https://example.com/foo".
    * @param string $base_url
-   *   The base URL string to check against, such as "http://example.com/".
+   *   The base URL string to check against, such as "https://example.com/".
    *
    * @return bool
    *   TRUE if the URL has the same domain and base path.
diff --git a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
index bd88a31c27cb7c6e3fbeb32843e5bb54f78a828a..f1599b24fdbbe99e86a6cf9881c258bad02a5698 100644
--- a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
@@ -24,12 +24,12 @@
  */
 class CsrfAccessCheck implements RoutingAccessInterface {
 
+  use RoutePathGenerationTrait;
+
   /**
    * The CSRF token generator.
-   *
-   * @var \Drupal\Core\Access\CsrfTokenGenerator
    */
-  protected $csrfToken;
+  protected CsrfTokenGenerator $csrfToken;
 
   /**
    * Constructs a CsrfAccessCheck object.
@@ -55,13 +55,7 @@ public function __construct(CsrfTokenGenerator $csrf_token) {
    *   The access result.
    */
   public function access(Route $route, Request $request, RouteMatchInterface $route_match) {
-    $parameters = $route_match->getRawParameters();
-    $path = ltrim($route->getPath(), '/');
-    // Replace the path parameters with values from the parameters array.
-    foreach ($parameters as $param => $value) {
-      $path = str_replace("{{$param}}", $value, $path);
-    }
-
+    $path = $this->generateRoutePath($route, $route_match->getRawParameters()->all());
     if ($this->csrfToken->validate($request->query->get('token', ''), $path)) {
       $result = AccessResult::allowed();
     }
diff --git a/core/lib/Drupal/Core/Access/RoutePathGenerationTrait.php b/core/lib/Drupal/Core/Access/RoutePathGenerationTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ef1e8b609cd3fc2ba1fa809fcf4799314db9758
--- /dev/null
+++ b/core/lib/Drupal/Core/Access/RoutePathGenerationTrait.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\Core\Access;
+
+use Symfony\Component\Routing\Route;
+
+/**
+ * Provides a method for generating route paths.
+ */
+trait RoutePathGenerationTrait {
+
+  /**
+   * Generates a route path by replacing placeholders with their values.
+   *
+   * Placeholders without corresponding values in the parameters array
+   * are removed from the resulting path.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route object containing the path with placeholders.
+   * @param array $parameters
+   *   An associative array of parameters to replace in the route path,
+   *   where the keys are placeholders and the values are the replacement
+   *   values.
+   *   @code
+   *   Example:
+   *   [
+   *     'parameter1' => 'value1',
+   *   ]
+   *   @endcode
+   *   This will transform a route path such as
+   *   '/route/path/{parameter1}{parameter2}' into '/route/path/value1'.
+   *
+   * @return string
+   *   The generated path with all placeholders either replaced by their
+   *   corresponding values or removed if no matching parameter exists.
+   */
+  public function generateRoutePath(Route $route, array $parameters): string {
+    $path = ltrim($route->getPath(), '/');
+
+    // Replace path parameters with their corresponding values from the
+    // parameters array.
+    foreach ($parameters as $param => $value) {
+      if (NULL !== $value) {
+        $path = str_replace("{{$param}}", $value, $path);
+      }
+    }
+
+    // Remove placeholders that were not replaced.
+    $path = preg_replace('/\/{[^}]+}/', '', $path);
+
+    // Remove trailing slashes (multiple slashes may result from the removal of
+    // unreplaced placeholders).
+    $path = rtrim($path, '/');
+
+    return $path;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php b/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
index 15baa36f49117d7d0d0b03b3426a582bad0a4f65..901c30c56b64d175e176af9a1cacc6ff810d087d 100644
--- a/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
+++ b/core/lib/Drupal/Core/Access/RouteProcessorCsrf.php
@@ -14,6 +14,8 @@
  */
 class RouteProcessorCsrf implements OutboundRouteProcessorInterface, TrustedCallbackInterface {
 
+  use RoutePathGenerationTrait;
+
   /**
    * Constructs a RouteProcessorCsrf object.
    *
@@ -37,11 +39,7 @@ public function __construct(
    */
   public function processOutbound($route_name, Route $route, array &$parameters, ?BubbleableMetadata $bubbleable_metadata = NULL) {
     if ($route->hasRequirement('_csrf_token')) {
-      $path = ltrim($route->getPath(), '/');
-      // Replace the path parameters with values from the parameters array.
-      foreach ($parameters as $param => $value) {
-        $path = str_replace("{{$param}}", $value, $path);
-      }
+      $path = $this->generateRoutePath($route, $parameters);
       // Adding this to the parameters means it will get merged into the query
       // string when the route is compiled.
       if (!$bubbleable_metadata || $this->requestStack->getCurrentRequest()->getRequestFormat() !== 'html') {
@@ -63,7 +61,9 @@ public function processOutbound($route_name, Route $route, array &$parameters, ?
   }
 
   /**
-   * #lazy_builder callback; gets a CSRF token for the given path.
+   * Render API callback: Adds a CSRF token for the given path to the markup.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $path
    *   The path to get a CSRF token for.
diff --git a/core/lib/Drupal/Core/Action/Plugin/Action/GotoAction.php b/core/lib/Drupal/Core/Action/Plugin/Action/GotoAction.php
index 92e92e006489852594bb505c821b4eb138d27126..55b746de6cecb45fbeac11bb559d64c1b5b997df 100644
--- a/core/lib/Drupal/Core/Action/Plugin/Action/GotoAction.php
+++ b/core/lib/Drupal/Core/Action/Plugin/Action/GotoAction.php
@@ -116,7 +116,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $form['url'] = [
       '#type' => 'textfield',
       '#title' => $this->t('URL'),
-      '#description' => $this->t('The URL to which the user should be redirected. This can be an internal URL like /node/1234 or an external URL like @url.', ['@url' => 'http://example.com']),
+      '#description' => $this->t('The URL to which the user should be redirected. This can be an internal URL like /node/1234 or an external URL like @url.', ['@url' => 'https://example.com']),
       '#default_value' => $this->configuration['url'],
       '#required' => TRUE,
     ];
diff --git a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
index 78097760f493f5a775a56e2877ec922f88f0de79..197d935909deacfc655dfcb72aca91d11755eafc 100644
--- a/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
+++ b/core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php
@@ -261,7 +261,7 @@ public function buildByExtension($extension) {
             elseif ($this->streamWrapperManager->isValidUri($source)) {
               $options['data'] = $source;
             }
-            // A regular URI (e.g., http://example.com/example.js) without
+            // A regular URI (e.g., https://example.com/example.js) without
             // 'external' explicitly specified, which may happen if, e.g.
             // libraries-override is used.
             elseif ($this->isValidUri($source)) {
@@ -634,7 +634,7 @@ protected function setOverrideValue(array &$library, array $sub_key, array $over
   protected function resolveThemeAssetPath($theme_path, $overriding_asset) {
     if ($overriding_asset[0] !== '/' && !$this->isValidUri($overriding_asset)) {
       // The destination is not an absolute path and it's not a URI (e.g.
-      // public://generated_js/example.js or http://example.com/js/my_js.js), so
+      // public://generated_js/example.js or https://example.com/js/my_js.js), so
       // it's relative to the theme.
       return '/' . $theme_path . '/' . $overriding_asset;
     }
diff --git a/core/lib/Drupal/Core/Cache/Context/SiteCacheContext.php b/core/lib/Drupal/Core/Cache/Context/SiteCacheContext.php
index 16516c5e2f8226829cc9713ac14ceeb774948351..6291c084a3d55f9a8e5569132c62dc85eefdafb6 100644
--- a/core/lib/Drupal/Core/Cache/Context/SiteCacheContext.php
+++ b/core/lib/Drupal/Core/Cache/Context/SiteCacheContext.php
@@ -12,7 +12,7 @@
  * A "site" is defined as the combination of URI scheme, domain name, port and
  * base path. It allows for varying between the *same* site being accessed via
  * different entry points. (Different sites in a multisite setup have separate
- * databases.) For example: http://example.com and http://www.example.com.
+ * databases.) For example: https://example.com and http://www.example.com.
  *
  * @see \Symfony\Component\HttpFoundation\Request::getSchemeAndHttpHost()
  * @see \Symfony\Component\HttpFoundation\Request::getBaseUrl()
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 28a261697c468174e23d07ae8916c611446fcf87..b97bb5d5d1e2d760c2e584cec76a8a7757c0b11b 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -345,13 +345,13 @@ public function isNewRevision() {
    * {@inheritdoc}
    */
   public function isDefaultRevision($new_value = NULL) {
-    $return = $this->isDefaultRevision;
-    if (isset($new_value)) {
-      $this->isDefaultRevision = (bool) $new_value;
-    }
+    $current_value = $this->isDefaultRevision;
     // New entities should always ensure at least one default revision exists,
     // creating an entity without a default revision is an invalid state.
-    return $this->isNew() || $return;
+    if (isset($new_value) && (!$this->isNew() || $new_value === TRUE)) {
+      $this->isDefaultRevision = (bool) $new_value;
+    }
+    return (bool) $current_value;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
index d082919f11ba4d0cd777adac8a6e548e1a553fa8..e7b42bc2af742cee3ad7959bfbc3b101013313b0 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -759,6 +759,14 @@ protected function doPreSave(EntityInterface $entity) {
 
     $id = parent::doPreSave($entity);
 
+    $previously_default_revision = $entity->wasDefaultRevision();
+    $no_longer_default = !$entity->isDefaultRevision();
+    $original_same_as_current = $entity->getOriginal()?->getRevisionId() == $entity->getLoadedRevisionId();
+    $not_new_revision = !$entity->isNewRevision();
+    if ($previously_default_revision && $no_longer_default && $original_same_as_current && $not_new_revision) {
+      throw new EntityStorageException("An existing default revision of the '{$this->entityTypeId}' entity type can not be changed to a non-default revision.");
+    }
+
     if (!$entity->isNew()) {
       // If the ID changed then original can't be loaded, throw an exception
       // in that case.
diff --git a/core/lib/Drupal/Core/File/FileUrlGenerator.php b/core/lib/Drupal/Core/File/FileUrlGenerator.php
index 3f32d485a69ca6a083c5f078a74516a06053f306..82f080cb96f567571ea547be35dcbc90f34c6de2 100644
--- a/core/lib/Drupal/Core/File/FileUrlGenerator.php
+++ b/core/lib/Drupal/Core/File/FileUrlGenerator.php
@@ -119,9 +119,9 @@ protected function doGenerateString(string $uri, bool $relative): string {
    */
   protected function generatePath(string $base_url, string $uri): string {
     // Allow for:
-    // - root-relative URIs (e.g. /foo.jpg in http://example.com/foo.jpg)
+    // - root-relative URIs (e.g. /foo.jpg in https://example.com/foo.jpg)
     // - protocol-relative URIs (e.g. //bar.jpg, which is expanded to
-    //   http://example.com/bar.jpg by the browser when viewing a page over
+    //   https://example.com/bar.jpg by the browser when viewing a page over
     //   HTTP and to https://example.com/bar.jpg when viewing a HTTPS page)
     // Both types of relative URIs are characterized by a leading slash, hence
     // we can use a single check.
@@ -160,9 +160,9 @@ public function generate(string $uri): Url {
 
     if (!$scheme) {
       // Allow for:
-      // - root-relative URIs (e.g. /foo.jpg in http://example.com/foo.jpg)
+      // - root-relative URIs (e.g. /foo.jpg in https://example.com/foo.jpg)
       // - protocol-relative URIs (e.g. //bar.jpg, which is expanded to
-      //   http://example.com/bar.jpg by the browser when viewing a page over
+      //   https://example.com/bar.jpg by the browser when viewing a page over
       //   HTTP and to https://example.com/bar.jpg when viewing a HTTPS page)
       // Both types of relative URIs are characterized by a leading slash, hence
       // we can use a single check.
diff --git a/core/lib/Drupal/Core/Form/ConfigFormBase.php b/core/lib/Drupal/Core/Form/ConfigFormBase.php
index 00381d287baa89539240c56bed2a1202b705dd94..175ddf89b452c946d57a230b7102340c1c296a62 100644
--- a/core/lib/Drupal/Core/Form/ConfigFormBase.php
+++ b/core/lib/Drupal/Core/Form/ConfigFormBase.php
@@ -120,7 +120,9 @@ public function loadDefaultValuesFromConfig(array $element): array {
   }
 
   /**
-   * #after_build callback which stores a map of element names to config keys.
+   * Render API callback: Stores a map of element names to config keys.
+   *
+   * This function is assigned as a #after_build callback.
    *
    * This will store an array in the form state whose keys are strings in the
    * form of `CONFIG_NAME:PROPERTY_PATH`, and whose values are instances of
diff --git a/core/lib/Drupal/Core/Render/Element/Actions.php b/core/lib/Drupal/Core/Render/Element/Actions.php
index d136523989412c6e6d407a33241698a32ab7b80f..424cc6da85e424b381cb972ba495c421bbbb1cb1 100644
--- a/core/lib/Drupal/Core/Render/Element/Actions.php
+++ b/core/lib/Drupal/Core/Render/Element/Actions.php
@@ -62,7 +62,9 @@ public static function processActions(&$element, FormStateInterface $form_state,
   }
 
   /**
-   * #pre_render callback for #type 'actions'.
+   * Render API callback: Groups the elements with a #dropbutton property.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * This callback iterates over all child elements of the #type 'actions'
    * container to look for elements with a #dropbutton property, so as to group
diff --git a/core/lib/Drupal/Core/Render/Element/FormElementBase.php b/core/lib/Drupal/Core/Render/Element/FormElementBase.php
index 65d3793110c08d4081d930120d175502b7fab34a..581607d716afcc4196d0e92a1d93e1bd652cf291 100644
--- a/core/lib/Drupal/Core/Render/Element/FormElementBase.php
+++ b/core/lib/Drupal/Core/Render/Element/FormElementBase.php
@@ -104,7 +104,9 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
   }
 
   /**
-   * #process callback for #pattern form element property.
+   * Render API callback: Handles the #pattern form element property.
+   *
+   * This function is assigned as a #process callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
@@ -127,7 +129,9 @@ public static function processPattern(&$element, FormStateInterface $form_state,
   }
 
   /**
-   * #element_validate callback for #pattern form element property.
+   * Render API callback: Handles the #pattern form element property..
+   *
+   * This function is assigned as a #element_validate callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
diff --git a/core/lib/Drupal/Core/Render/Element/Link.php b/core/lib/Drupal/Core/Render/Element/Link.php
index e93deb23d7f8b8bcd5e61bbc27c024a9edd4f6a0..2a00e0526b6872640f18057a2e67585e00298df5 100644
--- a/core/lib/Drupal/Core/Render/Element/Link.php
+++ b/core/lib/Drupal/Core/Render/Element/Link.php
@@ -68,9 +68,12 @@ public static function preRenderLink($element) {
     $element += ['#options' => []];
     // However, within the scope of renderable elements, #attributes is a valid
     // way to specify attributes, too. Take them into account, but do not
-    // override attributes from #options.
+    // override attributes from #options. Merge class as a string or array.
     if (isset($element['#attributes'])) {
       $element['#options'] += ['attributes' => []];
+      $element_class = $element['#attributes']['class'] ?? [];
+      $option_class = $element['#options']['attributes']['class'] ?? [];
+      $element['#options']['attributes']['class'] = array_merge((array) $option_class, (array) $element_class);
       $element['#options']['attributes'] += $element['#attributes'];
     }
 
diff --git a/core/lib/Drupal/Core/Render/Element/Pager.php b/core/lib/Drupal/Core/Render/Element/Pager.php
index 1f23a11ebcea463f3c3d55a2ae19c012e516b677..a31c7f2f37190ff6768562c59aad7904dcd46d79 100644
--- a/core/lib/Drupal/Core/Render/Element/Pager.php
+++ b/core/lib/Drupal/Core/Render/Element/Pager.php
@@ -62,7 +62,9 @@ public function getInfo() {
   }
 
   /**
-   * #pre_render callback to associate the appropriate cache context.
+   * Render API callback: Associates the appropriate cache context.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * @param array $pager
    *   A renderable array of #type => pager.
diff --git a/core/lib/Drupal/Core/Render/Element/StatusMessages.php b/core/lib/Drupal/Core/Render/Element/StatusMessages.php
index 23048ef3dfd5607893c6d9116de2a99de4acf4da..4eecd9f42f1a793d6317fefdfb7259315115cc89 100644
--- a/core/lib/Drupal/Core/Render/Element/StatusMessages.php
+++ b/core/lib/Drupal/Core/Render/Element/StatusMessages.php
@@ -38,7 +38,9 @@ public function getInfo() {
   }
 
   /**
-   * #pre_render callback to generate a placeholder.
+   * Render API callback: Generates a placeholder.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param array $element
    *   A renderable array.
@@ -69,7 +71,9 @@ public static function generatePlaceholder(array $element) {
   }
 
   /**
-   * #lazy_builder callback; replaces placeholder with messages.
+   * Render API callback: Replaces placeholder with messages.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string|null $type
    *   Limit the messages returned by type. Defaults to NULL, meaning all types.
diff --git a/core/lib/Drupal/Core/Render/Element/StatusReport.php b/core/lib/Drupal/Core/Render/Element/StatusReport.php
index 185afaf14e98315905c32ffee3b1f3aa7817ce82..41fc7d7fda115e42ccad81ac83b1319ac727759e 100644
--- a/core/lib/Drupal/Core/Render/Element/StatusReport.php
+++ b/core/lib/Drupal/Core/Render/Element/StatusReport.php
@@ -29,7 +29,9 @@ public function getInfo() {
   }
 
   /**
-   * #pre_render callback to group requirements.
+   * Render API callback: Groups requirements.
+   *
+   * This function is assigned as a #pre_render callback.
    */
   public static function preRenderGroupRequirements($element) {
     $severities = static::getSeverities();
diff --git a/core/lib/Drupal/Core/Render/Element/Table.php b/core/lib/Drupal/Core/Render/Element/Table.php
index 4d87ace04dc237a5b9ddd9b67025d4a4b4a773f4..85111505e9bb4a7562c012852e29251fe4bd0ab3 100644
--- a/core/lib/Drupal/Core/Render/Element/Table.php
+++ b/core/lib/Drupal/Core/Render/Element/Table.php
@@ -170,7 +170,9 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
   }
 
   /**
-   * #process callback for #type 'table' to add tableselect support.
+   * Render API callback: Adds tableselect support to #type 'table'.
+   *
+   * This function is assigned as a #process callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
@@ -297,7 +299,9 @@ public static function processTable(&$element, FormStateInterface $form_state, &
   }
 
   /**
-   * #element_validate callback for #type 'table'.
+   * Render API callback: Validates the #type 'table'.
+   *
+   * This function is assigned as a #element_validate callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
@@ -325,7 +329,9 @@ public static function validateTable(&$element, FormStateInterface $form_state,
   }
 
   /**
-   * #pre_render callback to transform children of an element of #type 'table'.
+   * Render API callback: Transform children of an element of #type 'table'.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * This function converts sub-elements of an element of #type 'table' to be
    * suitable for table.html.twig:
@@ -335,6 +341,7 @@ public static function validateTable(&$element, FormStateInterface $form_state,
    *   corresponding first-level table row.
    *
    * Simple example usage:
+   *
    * @code
    * $form['table'] = [
    *   '#type' => 'table',
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index 7c54caf331f225712afcad527db8000969f593bf..1383c4261b430e1640426e210d726f964a767d52 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -607,6 +607,11 @@ public function executeInRenderContext(RenderContext $context, callable $callabl
    */
   protected function getCurrentRenderContext() {
     $request = $this->requestStack->getCurrentRequest();
+
+    if (is_null($request)) {
+      return NULL;
+    }
+
     return static::$contextCollection[$request] ?? NULL;
   }
 
diff --git a/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php b/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
index 521feaf19f93115db43be735681de4f7e07b34dc..1efd5d569f66be809056945a55d379b8dca617f9 100644
--- a/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
+++ b/core/lib/Drupal/Core/Routing/LocalAwareRedirectResponseTrait.php
@@ -21,7 +21,7 @@ trait LocalAwareRedirectResponseTrait {
    *
    * @param string $url
    *   The internal path or external URL being linked to, such as "node/34" or
-   *   "http://example.com/foo".
+   *   "https://example.com/foo".
    *
    * @return bool
    *   TRUE or FALSE, where TRUE indicates a local path.
diff --git a/core/lib/Drupal/Core/Routing/RequestContext.php b/core/lib/Drupal/Core/Routing/RequestContext.php
index 24f196079b9996080ccbf5620db7f46035220a8d..0f8948da175be7accd8205489585466fd855ea3a 100644
--- a/core/lib/Drupal/Core/Routing/RequestContext.php
+++ b/core/lib/Drupal/Core/Routing/RequestContext.php
@@ -12,7 +12,7 @@
 class RequestContext extends SymfonyRequestContext {
 
   /**
-   * The scheme, host and base path, for example "http://example.com/d8".
+   * The scheme, host and base path, for example "https://example.com/d8".
    *
    * @var string
    */
diff --git a/core/lib/Drupal/Core/Routing/RequestHelper.php b/core/lib/Drupal/Core/Routing/RequestHelper.php
index 23063901a0b2b004ad6a986f8ffa498efbbd16a0..c9dc980aceb78721f503a1a1bdf4275a0d4f2bd8 100644
--- a/core/lib/Drupal/Core/Routing/RequestHelper.php
+++ b/core/lib/Drupal/Core/Routing/RequestHelper.php
@@ -13,8 +13,8 @@ class RequestHelper {
    * Returns whether the request is using a clean URL.
    *
    * A clean URL is one that does not include the script name. For example,
-   * - http://example.com/node/1 is a clean URL.
-   * - http://example.com/index.php/node/1 is not a clean URL.
+   * - https://example.com/node/1 is a clean URL.
+   * - https://example.com/index.php/node/1 is not a clean URL.
    *
    * Unclean URLs are required on sites hosted by web servers that cannot be
    * configured to implicitly route URLs to index.php.
diff --git a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
index 53a860fdc02397d8896906fa300028bfc9b597ff..397443836b85d102ab3f09cf03c3bfef913b4993 100644
--- a/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
+++ b/core/lib/Drupal/Core/Test/PhpUnitTestRunner.php
@@ -121,11 +121,16 @@ protected function runCommand(
     bool $colors = FALSE,
   ): void {
     global $base_url;
-    // Setup an environment variable containing the database connection so that
-    // functional tests can connect to the database.
-    $process_environment_variables = [
-      'SIMPLETEST_DB' => Database::getConnectionInfoAsUrl(),
-    ];
+    $process_environment_variables = [];
+
+    // Setup an environment variable containing the database connection if
+    // available, so that non-unit tests can connect to the database.
+    try {
+      $process_environment_variables['SIMPLETEST_DB'] = Database::getConnectionInfoAsUrl();
+    }
+    catch (\RuntimeException) {
+      // Just continue with no variable set.
+    }
 
     // Setup an environment variable containing the base URL, if it is
     // available. This allows functional tests to browse the site under test.
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 9641284b0754a2321ab4d5a0b404b66ffe6c5bad..cf0c0949182702850bfa0b589784b0fe2e27f35c 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -753,7 +753,7 @@ public function setAbsolute($absolute = TRUE) {
    * If this Url object was constructed from a Drupal route or from an internal
    * URI (URIs using the internal:, base:, or entity: schemes), the returned
    * string will either be a relative URL like /node/1 or an absolute URL like
-   * http://example.com/node/1 depending on the options array, plus any
+   * https://example.com/node/1 depending on the options array, plus any
    * specified query string or fragment.
    *
    * @param bool $collect_bubbleable_metadata
diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
index e4c48eed0fc5efe32403a91948216852307d14b0..edfe809c7a03c06fa5c4d786251d1b7e6ef6a2bc 100644
--- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
@@ -17,7 +17,7 @@ interface LinkGeneratorInterface {
    * $link_generator = \Drupal::service('link_generator');
    * $installer_url = \Drupal\Core\Url::fromUri('base://core/install.php');
    * $installer_link = $link_generator->generate($text, $installer_url);
-   * $external_url = \Drupal\Core\Url::fromUri('http://example.com', ['query' => ['foo' => 'bar']]);
+   * $external_url = \Drupal\Core\Url::fromUri('https://example.com', ['query' => ['foo' => 'bar']]);
    * $external_link = $link_generator->generate($text, $external_url);
    * $internal_url = \Drupal\Core\Url::fromRoute('system.admin');
    * $internal_link = $link_generator->generate($text, $internal_url);
diff --git a/core/lib/Drupal/Core/Utility/UnroutedUrlAssemblerInterface.php b/core/lib/Drupal/Core/Utility/UnroutedUrlAssemblerInterface.php
index 51cdf18853500541b16977d9042cdb6bb30a41f2..5d087cf8b1366d7c559b463dd5ef7e8af3faa10f 100644
--- a/core/lib/Drupal/Core/Utility/UnroutedUrlAssemblerInterface.php
+++ b/core/lib/Drupal/Core/Utility/UnroutedUrlAssemblerInterface.php
@@ -15,7 +15,7 @@ interface UnroutedUrlAssemblerInterface {
    *
    * @param string $uri
    *   A local URI or an external URL being linked to, such as "base:foo"
-   *    or "http://example.com/foo".
+   *    or "https://example.com/foo".
    *   - If you provide a full URL, it will be considered an external URL as
    *     long as it has an allowed protocol.
    *   - If you provide only a local URI (e.g. "base:foo"), it will be
@@ -24,7 +24,7 @@ interface UnroutedUrlAssemblerInterface {
    *     is found) will be added to the path. Additional query arguments for
    *     local paths must be supplied in $options['query'], not part of $uri.
    *   - If your external URL contains a query (e.g.
-   *     http://example.com/foo?a=b), then you can either URL encode the query
+   *     https://example.com/foo?a=b), then you can either URL encode the query
    *     keys and values yourself and include them in $uri, or use
    *     $options['query'] to let this method URL encode them.
    * @param array $options
diff --git a/core/modules/big_pipe/src/Render/BigPipeResponse.php b/core/modules/big_pipe/src/Render/BigPipeResponse.php
index 64e9d04b6df987b5909dfb8e795c6e37adab6b2d..ab212cf789eccb3bd2980ac36d36b2f38eb66933 100644
--- a/core/modules/big_pipe/src/Render/BigPipeResponse.php
+++ b/core/modules/big_pipe/src/Render/BigPipeResponse.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\big_pipe\Render;
 
+use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Render\HtmlResponse;
 use Drupal\Core\Session\ResponseKeepSessionOpenInterface;
 
@@ -21,6 +22,8 @@
  */
 class BigPipeResponse extends HtmlResponse implements ResponseKeepSessionOpenInterface {
 
+  use DependencySerializationTrait;
+
   /**
    * The BigPipe service.
    *
diff --git a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
index 2d894da837ebe7ec364c0ffe9c7810d994203f53..e9d3b0541fedd3a5dfed51466b0f1869bcfc5d55 100644
--- a/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
+++ b/core/modules/big_pipe/tests/modules/big_pipe_regression_test/src/BigPipeRegressionTestController.php
@@ -84,7 +84,9 @@ public static function largeContentBuilder() {
   }
 
   /**
-   * #lazy_builder callback; builds <time> markup with current time.
+   * Render API callback: Builds <time> markup with current time.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   Render array with a <time> markup with current time and cache settings.
diff --git a/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php b/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
index c625f7d2d23d7c92d29000e057ce33051df9bd98..6d8aafc697a1f75186ee565fe298e37e40f5190f 100644
--- a/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
+++ b/core/modules/big_pipe/tests/modules/big_pipe_test/src/BigPipeTestController.php
@@ -130,7 +130,9 @@ public function placeholderPreview() {
   }
 
   /**
-   * #lazy_builder callback; builds <time> markup with current time.
+   * Render API callback: Builds <time> markup with current time.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * Note: does not actually use current time, that would complicate testing.
    *
@@ -146,7 +148,9 @@ public static function currentTime() {
   }
 
   /**
-   * #lazy_builder callback; suspends its own execution then returns markup.
+   * Render API callback: Suspends its own execution then returns markup.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   A render array with a pig-themed message wrapped in a <span>,
@@ -166,7 +170,9 @@ public static function piggy(): array {
   }
 
   /**
-   * #lazy_builder callback; says "hello" or "hi".
+   * Render API callback: Says "hello" or "hi".
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   A render array with a marquee message using BigPipeMarkup,
@@ -183,7 +189,7 @@ public static function helloOrHi() {
   }
 
   /**
-   * #lazy_builder callback; throws exception.
+   * The #lazy_builder callback; throws exception.
    *
    * @throws \Exception
    */
@@ -192,7 +198,7 @@ public static function exception() {
   }
 
   /**
-   * #lazy_builder callback; returns content that will trigger an exception.
+   * The #lazy_builder callback; returns content that will trigger an exception.
    *
    * @see \Drupal\big_pipe_test\EventSubscriber\BigPipeTestSubscriber::onRespondTriggerException()
    *
@@ -204,7 +210,7 @@ public static function responseException() {
   }
 
   /**
-   * #lazy_builder callback; returns the current count.
+   * The #lazy_builder callback; returns the current count.
    *
    * @see \Drupal\Tests\big_pipe\Functional\BigPipeTest::testBigPipeMultiOccurrencePlaceholders()
    *
diff --git a/core/modules/big_pipe/tests/src/Kernel/SerializeResponseTest.php b/core/modules/big_pipe/tests/src/Kernel/SerializeResponseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca232717b0d439f075b3c631c42e54fade04ddf8
--- /dev/null
+++ b/core/modules/big_pipe/tests/src/Kernel/SerializeResponseTest.php
@@ -0,0 +1,37 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\big_pipe\Kernel;
+
+use Drupal\big_pipe\Render\BigPipeResponse;
+use Drupal\Core\Render\HtmlResponse;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests that big_pipe responses can be serialized.
+ *
+ * @group big_pipe
+ */
+class SerializeResponseTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['big_pipe'];
+
+  /**
+   * Tests that big_pipe responses can be serialized.
+   *
+   * @throws \Exception
+   */
+  public function testSerialize(): void {
+    $response = new BigPipeResponse(new HtmlResponse());
+    $this->assertIsString(serialize($response));
+
+    // Checks that the response can be serialized after the big_pipe service is injected.
+    $response->setBigPipeService($this->container->get('big_pipe'));
+    $this->assertIsString(serialize($response));
+  }
+
+}
diff --git a/core/modules/big_pipe/tests/src/Unit/Render/FiberPlaceholderTest.php b/core/modules/big_pipe/tests/src/Unit/Render/FiberPlaceholderTest.php
index b64095ecbdc12847f1f118dc0645c21123575105..e6ce793e25790b423c52d77fbfce919e052cc463 100644
--- a/core/modules/big_pipe/tests/src/Unit/Render/FiberPlaceholderTest.php
+++ b/core/modules/big_pipe/tests/src/Unit/Render/FiberPlaceholderTest.php
@@ -116,9 +116,9 @@ public function testLongPlaceholderFiberSuspendingLoop(): void {
 class TurtleLazyBuilder implements TrustedCallbackInterface {
 
   /**
-   * #lazy_builder callback.
+   * Render API callback: Suspends execution twice to simulate a long operation.
    *
-   * Suspends its own execution twice to simulate long operation.
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   The lazy builder callback.
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index 852ad0c98f5712f8b74ee7fd7994319ceae84e35..1463390fc1bad3f7d2c9832a92d1ad480774bb40 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -144,7 +144,9 @@ public static function trustedCallbacks() {
   }
 
   /**
-   * #lazy_builder callback; builds a #pre_render-able block.
+   * Render API callback: Builds a block that can be pre-rendered.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $entity_id
    *   A block config entity ID.
@@ -159,7 +161,9 @@ public static function lazyBuilder($entity_id, $view_mode) {
   }
 
   /**
-   * #pre_render callback for building a block.
+   * Render API callback: Builds a block.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * Renders the content using the provided block plugin, and then:
    * - if there is no content, aborts rendering, and makes sure the block won't
diff --git a/core/modules/block/tests/modules/block_test/src/BlockRenderAlterContent.php b/core/modules/block/tests/modules/block_test/src/BlockRenderAlterContent.php
index b7567e3e894ccb2cfe7d2a76f435cd0238c9fa2d..850c064fce45e900dae3bac5d5a5186493f226eb 100644
--- a/core/modules/block/tests/modules/block_test/src/BlockRenderAlterContent.php
+++ b/core/modules/block/tests/modules/block_test/src/BlockRenderAlterContent.php
@@ -12,7 +12,9 @@
 class BlockRenderAlterContent implements RenderCallbackInterface {
 
   /**
-   * #pre_render callback for a block to alter its content.
+   * Render API callback: Alters the content of a block.
+   *
+   * This function is assigned as a #pre_render callback.
    */
   public static function preRender(array $build) {
     $build['#prefix'] = 'Hiya!<br>';
diff --git a/core/modules/block/tests/src/Kernel/ConfigActionsTest.php b/core/modules/block/tests/src/Kernel/ConfigActionsTest.php
index fd7fa6f34c92bff28baaeb629de8f1bcfad57bfa..cb41d78251315fa7bdf176eb35f043e7376ace07 100644
--- a/core/modules/block/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/block/tests/src/Kernel/ConfigActionsTest.php
@@ -49,6 +49,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of entity method actions on a block.
+   */
   public function testEntityMethodActions(): void {
     $block = $this->placeBlock('system_messages_block', ['theme' => 'olivero']);
     $this->assertSame('content', $block->getRegion());
@@ -80,6 +83,9 @@ public function testPlaceBlockActionOnlyWorksOnBlocks(string $action): void {
     $this->configActionManager->applyAction($action, 'user.role.anonymous', []);
   }
 
+  /**
+   * Verifies placeBlockInDefaultTheme action doesn't alter an existing block.
+   */
   public function testPlaceBlockActionDoesNotChangeExistingBlock(): void {
     $extant_region = Block::load('olivero_powered')->getRegion();
     $this->assertNotSame('content', $extant_region);
@@ -139,11 +145,17 @@ public function testPlaceBlockInStaticRegion(string $action, string $expected_th
     $this->assertSame('content', $block->getRegion());
   }
 
+  /**
+   * Tests placing a block in the default theme's region.
+   */
   public function testPlaceBlockInDefaultRegion(): void {
     $this->config('system.theme')->set('default', 'umami')->save();
     $this->testPlaceBlockInDynamicRegion('placeBlockInDefaultTheme', 'umami', 'content');
   }
 
+  /**
+   * Tests placing a block at the first and last position in a region.
+   */
   public function testPlaceBlockAtPosition(): void {
     // Ensure there's at least one block already in the region.
     $block = Block::create([
diff --git a/core/modules/ckeditor5/tests/src/Kernel/ConfigAction/AddItemToToolbarConfigActionTest.php b/core/modules/ckeditor5/tests/src/Kernel/ConfigAction/AddItemToToolbarConfigActionTest.php
index 836751ef813396ad4e0f4ee7e6e2b88d6af5ebd2..012743e855ed8b44adeef8cf3db0a8bb6afa68d0 100644
--- a/core/modules/ckeditor5/tests/src/Kernel/ConfigAction/AddItemToToolbarConfigActionTest.php
+++ b/core/modules/ckeditor5/tests/src/Kernel/ConfigAction/AddItemToToolbarConfigActionTest.php
@@ -95,6 +95,9 @@ public function testAddItemToToolbar(string|array $action, array $expected_toolb
     }
   }
 
+  /**
+   * Tests that adding non-existent toolbar item to CKEditor triggers an error.
+   */
   public function testAddNonExistentItem(): void {
     $recipe = $this->createRecipe([
       'name' => 'Add an invalid toolbar item',
@@ -112,6 +115,9 @@ public function testAddNonExistentItem(): void {
     RecipeRunner::processRecipe($recipe);
   }
 
+  /**
+   * Tests that the `addItemToToolbar` config action requires CKEditor 5.
+   */
   public function testActionRequiresCKEditor5(): void {
     $this->enableModules(['editor_test']);
     Editor::load('filter_test')?->setEditor('unicorn')->setSettings([])->save();
diff --git a/core/modules/ckeditor5/tests/src/Kernel/WildcardHtmlSupportTest.php b/core/modules/ckeditor5/tests/src/Kernel/WildcardHtmlSupportTest.php
index e1d57ed910a2239a9cd5059b5ff0cd9b90d1450a..1373bc0a66657fa8d09f49e4ce966b05e87a1489 100644
--- a/core/modules/ckeditor5/tests/src/Kernel/WildcardHtmlSupportTest.php
+++ b/core/modules/ckeditor5/tests/src/Kernel/WildcardHtmlSupportTest.php
@@ -101,6 +101,9 @@ function (ConstraintViolationInterface $v) {
     $this->assertEquals($expected_ghs_configuration, $ghs_configuration);
   }
 
+  /**
+   * Provides test cases for CKEditor 5 General HTML Support (GHS) configuration.
+   */
   public static function providerGhsConfiguration(): array {
     return [
       'empty source editing' => [
diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php
index 458e3689077a701cc82098533b828f6fb5a13261..5d949a32036163f96d218c87c65371f2791f06b3 100644
--- a/core/modules/comment/src/CommentLazyBuilders.php
+++ b/core/modules/comment/src/CommentLazyBuilders.php
@@ -89,7 +89,9 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Ent
   }
 
   /**
-   * #lazy_builder callback; builds the comment form.
+   * Render API callback: Builds the comment form.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $commented_entity_type_id
    *   The commented entity type ID.
@@ -116,7 +118,9 @@ public function renderForm($commented_entity_type_id, $commented_entity_id, $fie
   }
 
   /**
-   * #lazy_builder callback; builds a comment's links.
+   * Render API callback: Builds a comment's links.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $comment_entity_id
    *   The comment entity ID.
diff --git a/core/modules/config_translation/src/Controller/ConfigTranslationController.php b/core/modules/config_translation/src/Controller/ConfigTranslationController.php
index f6ec1a474aaa20d47f880156c648a7107d0500e3..1b8287d80cf1196a62988edfe0e9f6a11b3a75d7 100644
--- a/core/modules/config_translation/src/Controller/ConfigTranslationController.php
+++ b/core/modules/config_translation/src/Controller/ConfigTranslationController.php
@@ -6,6 +6,7 @@
 use Drupal\config_translation\ConfigMapperManagerInterface;
 use Drupal\config_translation\Exception\ConfigMapperLanguageException;
 use Drupal\Core\Access\AccessManagerInterface;
+use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
@@ -131,6 +132,8 @@ public static function create(ContainerInterface $container) {
    *   Page render array.
    */
   public function itemPage(Request $request, RouteMatchInterface $route_match, $plugin_id) {
+    $cacheable_metadata = new CacheableMetadata();
+
     /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
     $mapper = $this->configMapperManager->createInstance($plugin_id);
     $mapper->populateFromRouteMatch($route_match);
@@ -204,11 +207,12 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl
 
         // Check access for the path/route for editing, so we can decide to
         // include a link to edit or not.
-        $edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account);
+        $edit_access = $this->accessManager->checkNamedRoute($mapper->getBaseRouteName(), $route_match->getRawParameters()->all(), $this->account, TRUE);
+        $cacheable_metadata->addCacheableDependency($edit_access);
 
         // Build list of operations.
         $operations = [];
-        if ($edit_access) {
+        if ($edit_access->isAllowed()) {
           $operations['edit'] = [
             'title' => $this->t('Edit'),
             'url' => Url::fromRoute($mapper->getBaseRouteName(), $mapper->getBaseRouteParameters(), ['query' => ['destination' => $mapper->getOverviewPath()]]),
@@ -218,6 +222,14 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl
       else {
         $language_name = $language->getName();
 
+        // The translation check below might change if the configs change, so we
+        // need to add their cache tags.
+        $cache_tags = [];
+        foreach ($mapper->getConfigNames() as $configName) {
+          $cache_tags[] = "config:$configName";
+        }
+        $cacheable_metadata->addCacheTags($cache_tags);
+
         $operations = [];
         // If no translation exists for this language, link to add one.
         if (!$mapper->hasTranslation($language)) {
@@ -274,6 +286,7 @@ public function itemPage(Request $request, RouteMatchInterface $route_match, $pl
         '#attached' => ['library' => ['core/drupal.dialog.ajax']],
       ];
     }
+    $cacheable_metadata->applyTo($page);
     return $page;
   }
 
diff --git a/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiModulesTest.php b/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiModulesTest.php
index ccf0475d1312ab27bca2fbae89000aba65613af4..eb2af2b21451d82e3f1cb4dece8f0e15e8ba128f 100644
--- a/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiModulesTest.php
+++ b/core/modules/config_translation/tests/src/Functional/ConfigTranslationUiModulesTest.php
@@ -392,9 +392,8 @@ public function testNodeFieldTranslation(): void {
       'entity_type' => 'node',
       'type' => 'text',
     ]);
-
-    $field_storage->setSetting('translatable_storage_setting', 'translatable_storage_setting');
     $field_storage->save();
+
     $field = FieldConfig::create([
       'field_name' => $field_name,
       'entity_type' => 'node',
diff --git a/core/modules/contact/tests/src/Kernel/ConfigActionsTest.php b/core/modules/contact/tests/src/Kernel/ConfigActionsTest.php
index 31210efca43544f8ce1dc04970d84a3a18c79387..a01027f482a38bc53ef4dab4e6503df5b769a657 100644
--- a/core/modules/contact/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/contact/tests/src/Kernel/ConfigActionsTest.php
@@ -34,6 +34,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of configuration actions on a contact form.
+   */
   public function testConfigActions(): void {
     $form = ContactForm::load('personal');
     $this->assertSame('Your message has been sent.', $form->getMessage());
diff --git a/core/modules/content_moderation/tests/src/Kernel/ConfigAction/AddModerationConfigActionTest.php b/core/modules/content_moderation/tests/src/Kernel/ConfigAction/AddModerationConfigActionTest.php
index 069390e1dd8e017eb4d9aa6e2dca7fe8a85a9409..df0e76408350ff31804f4cd0d130b268f2dc3136 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ConfigAction/AddModerationConfigActionTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ConfigAction/AddModerationConfigActionTest.php
@@ -40,6 +40,9 @@ class AddModerationConfigActionTest extends KernelTestBase {
     'user',
   ];
 
+  /**
+   * Tests adding entity types and bundles to a workflow.
+   */
   public function testAddEntityTypeAndBundle(): void {
     $this->installEntitySchema('node');
     $this->installConfig('node');
@@ -58,6 +61,9 @@ public function testAddEntityTypeAndBundle(): void {
     $this->assertSame(['tags'], $plugin->getBundlesForEntityType('taxonomy_term'));
   }
 
+  /**
+   * Tests that the workflow must be of type Content Moderation.
+   */
   public function testWorkflowMustBeContentModeration(): void {
     $this->enableModules(['workflows', 'workflow_type_test']);
 
@@ -74,6 +80,9 @@ public function testWorkflowMustBeContentModeration(): void {
     RecipeRunner::processRecipe($recipe);
   }
 
+  /**
+   * Tests that the action only targets workflows.
+   */
   public function testActionOnlyTargetsWorkflows(): void {
     $recipe = $this->createRecipe('user.role.anonymous');
     $this->expectException(PluginNotFoundException::class);
@@ -81,6 +90,9 @@ public function testActionOnlyTargetsWorkflows(): void {
     RecipeRunner::processRecipe($recipe);
   }
 
+  /**
+   * Tests that the derived config action definitions have correct admin labels.
+   */
   public function testDeriverAdminLabel(): void {
     $this->enableModules(['workflows', 'content_moderation']);
 
@@ -92,6 +104,9 @@ public function testDeriverAdminLabel(): void {
     $this->assertSame('Add moderation to all vocabularies', (string) $definitions['add_moderation:addTaxonomyVocabularies']['admin_label']);
   }
 
+  /**
+   * Creates a recipe configuration for adding entity types and bundles to a workflow.
+   */
   private function createRecipe(string $config_name): Recipe {
     $recipe = <<<YAML
 name: 'Add entity types and bundles to workflow'
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
index b0f3ea7be7da865e3c9d62cc82274b0b80981497..bad9edd736014bc2b53559f94b613455a6a4afba 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldWidget/DateRangeWidgetBase.php
@@ -102,7 +102,9 @@ public function massageFormValues(array $values, array $form, FormStateInterface
   }
 
   /**
-   * #element_validate callback to ensure that the start date <= the end date.
+   * Render API callback: Validates that the start date <= the end date.
+   *
+   * This function is assigned as a #element_validate callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
diff --git a/core/modules/editor/editor.module b/core/modules/editor/editor.module
index d760fafbd31874af6c0f996e619b1f0a117db480..450946f3ddf4b8b6e0ed770e3d3aa70eb1c8d0e7 100644
--- a/core/modules/editor/editor.module
+++ b/core/modules/editor/editor.module
@@ -80,7 +80,7 @@ function editor_form_filter_admin_format_submit($form, FormStateInterface $form_
   // Delete the existing editor if disabling or switching between editors.
   $format = $form_state->getFormObject()->getEntity();
   $format_id = $format->isNew() ? NULL : $format->id();
-  $original_editor = editor_load($format_id);
+  $original_editor = $format_id ? Editor::load($format_id) : NULL;
   if ($original_editor && $original_editor->getEditor() != $form_state->getValue(['editor', 'editor'])) {
     $original_editor->delete();
   }
@@ -116,19 +116,24 @@ function editor_form_filter_admin_format_submit($form, FormStateInterface $form_
 /**
  * Loads an individual configured text editor based on text format ID.
  *
- * @param int $format_id
+ * @param string $format_id
  *   A text format ID.
  *
  * @return \Drupal\editor\Entity\Editor|null
  *   A text editor object, or NULL.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use
+ *   \Drupal::entityTypeManager()->getStorage('editor')->load($format_id)
+ *   instead.
+ * @see https://www.drupal.org/node/3509245
  */
 function editor_load($format_id) {
-  // Load all the editors at once here, assuming that either no editors or more
-  // than one editor will be needed on a page (such as having multiple text
-  // formats for administrators). Loading a small number of editors all at once
-  // is more efficient than loading multiple editors individually.
-  $editors = Editor::loadMultiple();
-  return $editors[$format_id] ?? NULL;
+  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use \Drupal::entityTypeManager()->getStorage(\'editor\')->load($format_id) instead. See https://www.drupal.org/node/3509245', E_USER_DEPRECATED);
+  // While loading multiple editors at once is a more efficient query, on warm
+  // caches, loading editor configuration from APCu is fast and avoids a call to
+  // ConfigFactory::listAll() in a loadMultiple() call with no IDs passed.
+  // @see Drupal\Core\Config\Entity\ConfigEntityStorage::doLoadMultiple()
+  return $format_id ? Editor::load($format_id) : NULL;
 }
 
 /**
@@ -156,7 +161,7 @@ function editor_load($format_id) {
  * @see https://www.drupal.org/node/2099741
  */
 function editor_filter_xss($html, ?FilterFormatInterface $format = NULL, ?FilterFormatInterface $original_format = NULL) {
-  $editor = $format ? editor_load($format->id()) : NULL;
+  $editor = $format ? Editor::load($format->id()) : NULL;
 
   // If no text editor is associated with this text format or the previously
   // defined text format is now disabled, then we don't need text editor XSS
diff --git a/core/modules/editor/editor.services.yml b/core/modules/editor/editor.services.yml
index e74f4668dab5b455c10751207102c81ea876b02c..0db1dc61968c125e498166810a44d7d2b709ddac 100644
--- a/core/modules/editor/editor.services.yml
+++ b/core/modules/editor/editor.services.yml
@@ -7,6 +7,8 @@ services:
   plugin.manager.editor:
     class: Drupal\editor\Plugin\EditorManager
     parent: default_plugin_manager
+    arguments:
+      $entityTypeManager: '@entity_type.manager'
   element.editor:
     class: Drupal\editor\Element
     arguments: ['@plugin.manager.editor']
diff --git a/core/modules/editor/src/Hook/EditorHooks.php b/core/modules/editor/src/Hook/EditorHooks.php
index 952dbff1db5e469820a3b252db5aa010239998a8..7a94b630c75bc2312cf0adb958372e4586d24ada 100644
--- a/core/modules/editor/src/Hook/EditorHooks.php
+++ b/core/modules/editor/src/Hook/EditorHooks.php
@@ -97,7 +97,7 @@ public function formFilterAdminOverviewAlter(&$form, FormStateInterface $form_st
     // Then splice in the name of each text editor for each text format.
     $editors = \Drupal::service('plugin.manager.editor')->getDefinitions();
     foreach (Element::children($form['formats']) as $format_id) {
-      $editor = editor_load($format_id);
+      $editor = \Drupal::entityTypeManager()->getStorage('editor')->load($format_id);
       $editor_name = $editor && isset($editors[$editor->getEditor()]) ? $editors[$editor->getEditor()]['label'] : '—';
       $editor_column['editor'] = ['#markup' => $editor_name];
       $position = array_search('name', array_keys($form['formats'][$format_id])) + 1;
@@ -115,7 +115,7 @@ public function formFilterFormatFormAlter(&$form, FormStateInterface $form_state
     if ($editor === NULL) {
       $format = $form_state->getFormObject()->getEntity();
       $format_id = $format->isNew() ? NULL : $format->id();
-      $editor = editor_load($format_id);
+      $editor = $format_id ? \Drupal::entityTypeManager()->getStorage('editor')->load($format_id) : NULL;
       $form_state->set('editor', $editor);
     }
     // Associate a text editor with this text format.
@@ -319,7 +319,7 @@ public function fileDownload($uri): array|int|null {
       }
     }
     // Access is granted.
-    $headers = file_get_content_headers($file);
+    $headers = $file->getDownloadHeaders();
     return $headers;
   }
 
diff --git a/core/modules/editor/src/Plugin/EditorManager.php b/core/modules/editor/src/Plugin/EditorManager.php
index 6a4f8a153410bbbcf7f7575623d18c20b821596c..eb17549ba741ba61f313e1bd1e3a9b8aa8306d2c 100644
--- a/core/modules/editor/src/Plugin/EditorManager.php
+++ b/core/modules/editor/src/Plugin/EditorManager.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\editor\Plugin;
 
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -18,20 +19,27 @@
 class EditorManager extends DefaultPluginManager {
 
   /**
-   * Constructs an EditorManager object.
+   * Static cache of attachments.
    *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations.
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler to invoke the alter hook with.
+   * @var array
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+  protected array $attachments = ['library' => []];
+
+  /**
+   * Editors.
+   *
+   * @var array
+   */
+  protected array $editors = [];
+
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, protected ?EntityTypeManagerInterface $entityTypeManager = NULL) {
     parent::__construct('Plugin/Editor', $namespaces, $module_handler, EditorPluginInterface::class, Editor::class, 'Drupal\editor\Annotation\Editor');
     $this->alterInfo('editor_info');
     $this->setCacheBackend($cache_backend, 'editor_plugins');
+    if ($this->entityTypeManager === NULL) {
+      @trigger_error('Calling ' . __METHOD__ . '() without the $entityTypeManager argument is deprecated in drupal:11.2.0 and will be required in drupal:12.0.0. See https://www.drupal.org/project/drupal/issues/3447794', E_USER_DEPRECATED);
+      $this->entityTypeManager = \Drupal::entityTypeManager();
+    }
   }
 
   /**
@@ -60,41 +68,42 @@ public function listOptions() {
    * @see \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments()
    */
   public function getAttachments(array $format_ids) {
-    $attachments = ['library' => []];
-
-    $settings = [];
-    foreach ($format_ids as $format_id) {
-      $editor = editor_load($format_id);
-      if (!$editor) {
-        continue;
-      }
+    $settings = $this->attachments['drupalSettings'] ?? [];
 
-      $plugin = $this->createInstance($editor->getEditor());
-      $plugin_definition = $plugin->getPluginDefinition();
+    if (($editor_ids_to_load = array_diff($format_ids, array_keys($this->editors)))) {
+      $editors = $this->entityTypeManager->getStorage('editor')
+        ->loadMultiple($editor_ids_to_load);
+      // Statically cache the editors and include NULL entries for formats that
+      // do not have editors.
+      $this->editors += $editors + array_fill_keys($editor_ids_to_load, NULL);
+      foreach ($editors as $format_id => $editor) {
+        $plugin = $this->createInstance($editor->getEditor());
+        $plugin_definition = $plugin->getPluginDefinition();
 
-      // Libraries.
-      $attachments['library'] = array_merge($attachments['library'], $plugin->getLibraries($editor));
+        // Libraries.
+        $this->attachments['library'] = array_merge($this->attachments['library'], $plugin->getLibraries($editor));
 
-      // Format-specific JavaScript settings.
-      $settings['editor']['formats'][$format_id] = [
-        'format' => $format_id,
-        'editor' => $editor->getEditor(),
-        'editorSettings' => $plugin->getJSSettings($editor),
-        'editorSupportsContentFiltering' => $plugin_definition['supports_content_filtering'],
-        'isXssSafe' => $plugin_definition['is_xss_safe'],
-      ];
+        // Format-specific JavaScript settings.
+        $settings['editor']['formats'][$format_id] = [
+          'format' => $format_id,
+          'editor' => $editor->getEditor(),
+          'editorSettings' => $plugin->getJSSettings($editor),
+          'editorSupportsContentFiltering' => $plugin_definition['supports_content_filtering'],
+          'isXssSafe' => $plugin_definition['is_xss_safe'],
+        ];
+      }
     }
 
     // Allow other modules to alter all JavaScript settings.
     $this->moduleHandler->alter('editor_js_settings', $settings);
 
-    if (empty($attachments['library']) && empty($settings)) {
+    if (empty($this->attachments['library']) && empty($settings)) {
       return [];
     }
 
-    $attachments['drupalSettings'] = $settings;
+    $this->attachments['drupalSettings'] = $settings;
 
-    return $attachments;
+    return $this->attachments;
   }
 
 }
diff --git a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php
index cab720a6e59ce7bf4af142a88220fbe17dc0ef4a..5b7235009a5bc4677e1231bc14871ae65e0095c0 100644
--- a/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php
+++ b/core/modules/editor/tests/modules/editor_test/src/Plugin/Editor/UnicornEditor.php
@@ -49,7 +49,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
   }
 
   /**
-   * #element_validate handler for "image_upload" in buildConfigurationForm().
+   * Render API callback: Image upload handler for confirmation form.
+   *
+   * This function is assigned as a #element_validate callback.
    *
    * Moves the text editor's image upload settings into $editor->image_upload.
    *
diff --git a/core/modules/editor/tests/src/Functional/EditorAdminTest.php b/core/modules/editor/tests/src/Functional/EditorAdminTest.php
index 90c259516c6e0cb1c7cb6d197ac4140f1b89f024..639aa030618ae2ae21a2cc06d3a9da71c4d6231a 100644
--- a/core/modules/editor/tests/src/Functional/EditorAdminTest.php
+++ b/core/modules/editor/tests/src/Functional/EditorAdminTest.php
@@ -240,7 +240,7 @@ protected function selectUnicornEditor(): array {
    *   The expected value of the ponies_too setting.
    */
   protected function verifyUnicornEditorConfiguration($format_id, $ponies_too = TRUE): void {
-    $editor = editor_load($format_id);
+    $editor = \Drupal::entityTypeManager()->getStorage('editor')->load($format_id);
     $settings = $editor->getSettings();
     $this->assertSame('unicorn', $editor->getEditor(), 'The text editor is configured correctly.');
     $this->assertSame($ponies_too, $settings['ponies_too'], 'The text editor settings are stored correctly.');
diff --git a/core/modules/field/tests/src/Kernel/ConfigActionsTest.php b/core/modules/field/tests/src/Kernel/ConfigActionsTest.php
index 15dc362a8be57b4a74790e636304b4228449b061..384dc1f9ffa6033d342f0a24a88532a8c1fcfb32 100644
--- a/core/modules/field/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/field/tests/src/Kernel/ConfigActionsTest.php
@@ -41,6 +41,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of configuration actions on field settings.
+   */
   public function testConfigActions(): void {
     $field_storage = FieldStorageConfig::create([
       'field_name' => 'test',
diff --git a/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php b/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php
index 6b1af094365ffd4017d7b4fc0ab4225b5b178549..1d21ebd34b2a8bacbce5cb6ea7ca5e38e1ab00b3 100644
--- a/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php
+++ b/core/modules/field/tests/src/Kernel/FieldStorageCrudTest.php
@@ -372,6 +372,9 @@ public function testDeleteNoData(): void {
     }
   }
 
+  /**
+   * Tests that updating a field storage type is not allowed.
+   */
   public function testUpdateFieldType(): void {
     $field_storage = FieldStorageConfig::create([
       'field_name' => 'field_type',
diff --git a/core/modules/field_ui/tests/src/Functional/FieldUIDeleteTest.php b/core/modules/field_ui/tests/src/Functional/FieldUIDeleteTest.php
index b28b7037c45e22eebba8b898f93113676a08980d..1bed3f4d1f0b988d89feaee6fdb9330814352706 100644
--- a/core/modules/field_ui/tests/src/Functional/FieldUIDeleteTest.php
+++ b/core/modules/field_ui/tests/src/Functional/FieldUIDeleteTest.php
@@ -111,6 +111,8 @@ public function testDeleteField(): void {
     $this->assertSession()->pageTextNotContains('The listed configuration will be deleted.');
     $this->assertSession()->elementNotExists('xpath', '//ul[@data-drupal-selector="edit-view"]');
     $this->assertSession()->pageTextNotContains('test_view_field_delete');
+    // Test Breadcrumbs.
+    $this->assertSession()->linkExists($field_label, 0, 'Field label is correct in the breadcrumb of the field delete page.');
 
     // Delete the first field.
     $this->fieldUIDeleteField($bundle_path1, "node.$type_name1.$field_name", $field_label, $type_name1, 'content type');
diff --git a/core/modules/field_ui/tests/src/Functional/ManageFieldsTest.php b/core/modules/field_ui/tests/src/Functional/ManageFieldsTest.php
index a4278dab6a9e6698cdbdf337612cf38e12d0aa78..e732e009f43add62b3ecaba0601f829b8cb4d0e2 100644
--- a/core/modules/field_ui/tests/src/Functional/ManageFieldsTest.php
+++ b/core/modules/field_ui/tests/src/Functional/ManageFieldsTest.php
@@ -162,6 +162,8 @@ public function testAddField(): void {
       'field_name' => 'test_field',
     ];
     $this->submitForm($edit, 'Continue');
+    // Test Breadcrumbs.
+    $this->getSession()->getPage()->findLink('Test field');
     $this->assertSession()->statusMessageNotContains('Saved');
 
     // Change the storage form values.
diff --git a/core/modules/field_ui/tests/src/Traits/FieldUiTestTrait.php b/core/modules/field_ui/tests/src/Traits/FieldUiTestTrait.php
index 09b80e476d5446e3c83b560a62d06f4ddc952508..905c645083b228ed115a17a855fdb876c17671ac 100644
--- a/core/modules/field_ui/tests/src/Traits/FieldUiTestTrait.php
+++ b/core/modules/field_ui/tests/src/Traits/FieldUiTestTrait.php
@@ -78,8 +78,6 @@ public function fieldUIAddNewField($bundle_path, $field_name, $label = NULL, $fi
     $this->assertFieldDoesNotExist($bundle_path, $label);
     if ($save_settings) {
       $this->assertSession()->pageTextContains("These settings apply to the $label field everywhere it is used.");
-      // Test Breadcrumbs.
-      $this->getSession()->getPage()->findLink($label);
 
       // Ensure that each array key in $storage_edit is prefixed with
       // field_storage.
@@ -171,9 +169,6 @@ public function fieldUIDeleteField($bundle_path, $field_name, $label, $bundle_la
     $this->drupalGet("$bundle_path/fields/$field_name/delete");
     $this->assertSession()->pageTextContains("Are you sure you want to delete the field $label");
 
-    // Test Breadcrumbs.
-    $this->assertSession()->linkExists($label, 0, 'Field label is correct in the breadcrumb of the field delete page.');
-
     // Submit confirmation form.
     $this->submitForm([], 'Delete');
     $this->assertSession()->pageTextContains("The field $label has been deleted from the $bundle_label $source_label");
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 9c10140fa4ba6b7a6f0e0db718ff9696e2acbc95..120d553c5c6dd943642a94aa5e2f25d83bcb3ca6 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -35,13 +35,13 @@
  * @return array
  *   An associative array of headers, as expected by
  *   \Symfony\Component\HttpFoundation\StreamedResponse.
+ *
+ * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use Drupal\file\Entity\FileInterface::getDownloadHeaders() instead.
+ * @see https://www.drupal.org/node/3494172
  */
 function file_get_content_headers(FileInterface $file) {
-  return [
-    'Content-Type' => $file->getMimeType(),
-    'Content-Length' => $file->getSize(),
-    'Cache-Control' => 'private',
-  ];
+  @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0.  Use Drupal\file\Entity\FileInterface::getDownloadHeaders() instead. See https://www.drupal.org/node/3494172', E_USER_DEPRECATED);
+  return $file->getDownloadHeaders();
 }
 
 /**
diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php
index 6fab94f9179172b7e8d6ac13da37ad4ae05b4c6b..de0cdde7e710b7c0ec9fb20749cb83c53bd7f0a6 100644
--- a/core/modules/file/src/Element/ManagedFile.php
+++ b/core/modules/file/src/Element/ManagedFile.php
@@ -159,7 +159,7 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
   }
 
   /**
-   * #ajax callback for managed_file upload forms.
+   * The #ajax callback for managed_file upload forms.
    *
    * This ajax callback takes care of the following things:
    *   - Ensures that broken requests due to too big files are caught.
diff --git a/core/modules/file/src/Entity/File.php b/core/modules/file/src/Entity/File.php
index 0022fec6add1d1137c844ae4391483a74b0626e1..bc310eeb7f22c62bd9b81d4f085f323350e24652 100644
--- a/core/modules/file/src/Entity/File.php
+++ b/core/modules/file/src/Entity/File.php
@@ -300,4 +300,15 @@ protected function invalidateTagsOnSave($update) {
     Cache::invalidateTags($tags);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getDownloadHeaders(): array {
+    return [
+      'Content-Type' => $this->getMimeType(),
+      'Content-Length' => $this->getSize(),
+      'Cache-Control' => 'private',
+    ];
+  }
+
 }
diff --git a/core/modules/file/src/FileInterface.php b/core/modules/file/src/FileInterface.php
index 588009cb475b1e558bc93ccbc7c3f9a003948055..efa6627790fec8201ebd2581d04955b27f74d05d 100644
--- a/core/modules/file/src/FileInterface.php
+++ b/core/modules/file/src/FileInterface.php
@@ -142,4 +142,13 @@ public function setTemporary();
    */
   public function getCreatedTime();
 
+  /**
+   * Examines a file entity and returns content headers for download.
+   *
+   * @return array
+   *   An associative array of headers, as expected by
+   *   \Symfony\Component\HttpFoundation\StreamedResponse.
+   */
+  public function getDownloadHeaders(): array;
+
 }
diff --git a/core/modules/file/src/Hook/FileDownloadHook.php b/core/modules/file/src/Hook/FileDownloadHook.php
index 21086c5eb1144a99cc5ff3eb44911df1e25800dd..1dee2310d57fae2cb1fdb675fffcbb63564407c3 100644
--- a/core/modules/file/src/Hook/FileDownloadHook.php
+++ b/core/modules/file/src/Hook/FileDownloadHook.php
@@ -58,7 +58,7 @@ public function __invoke($uri): array|int|null {
       return -1;
     }
     // Access is granted.
-    return file_get_content_headers($file);
+    return $file->getDownloadHeaders();
   }
 
 }
diff --git a/core/modules/file/tests/file_test/src/Hook/FileTestHooks.php b/core/modules/file/tests/file_test/src/Hook/FileTestHooks.php
index 1f274d9ed0ab903275ed0285c8787288718592cc..267e2ada834cc0de08789bc953919226ebf976e8 100644
--- a/core/modules/file/tests/file_test/src/Hook/FileTestHooks.php
+++ b/core/modules/file/tests/file_test/src/Hook/FileTestHooks.php
@@ -38,7 +38,7 @@ public function fileDownload($uri): array|int|null {
     if (\Drupal::state()->get('file_test.allow_all', FALSE)) {
       $files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $uri]);
       $file = reset($files);
-      return file_get_content_headers($file);
+      return $file->getDownloadHeaders();
     }
     FileTestHelper::logCall('download', [$uri]);
     return $this->getReturn('download');
diff --git a/core/modules/file/tests/src/Kernel/SaveTest.php b/core/modules/file/tests/src/Kernel/SaveTest.php
index cd38137f977a969364b9476afc272d4170024f8f..674236bbd1a58aea91ab10f61b080108ff7c3737 100644
--- a/core/modules/file/tests/src/Kernel/SaveTest.php
+++ b/core/modules/file/tests/src/Kernel/SaveTest.php
@@ -17,6 +17,9 @@ class SaveTest extends FileManagedUnitTestBase {
 
   use UserCreationTrait;
 
+  /**
+   * Tests the saving process of file entities.
+   */
   public function testFileSave(): void {
     $account = $this->createUser();
     // Create a new file entity.
diff --git a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
index d3bf2dd04285bec2bea1f0bb1775dc2e1ab8c60f..e1ddf55218775b6ef5d5aab9216c42c61dd5ec88 100644
--- a/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
+++ b/core/modules/filter/tests/filter_test/src/Plugin/Filter/FilterTestPlaceholders.php
@@ -35,7 +35,9 @@ public function process($text, $langcode) {
   }
 
   /**
-   * #lazy_builder callback; builds a render array containing the dynamic thing.
+   * Render API callback: Builds a render array containing the dynamic thing.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $thing
    *   A "thing" string.
@@ -50,7 +52,9 @@ public static function renderDynamicThing($thing) {
   }
 
   /**
-   * #lazy_builder callback; builds a render array.
+   * Render API callback: Builds a render array.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   A renderable array.
diff --git a/core/modules/history/src/HistoryRenderCallback.php b/core/modules/history/src/HistoryRenderCallback.php
index c6a92eda68b03a13bf155c5b03870d330fbfe7bc..5650fa0d8b758da4ccc9cfe2b9416d086331d5d2 100644
--- a/core/modules/history/src/HistoryRenderCallback.php
+++ b/core/modules/history/src/HistoryRenderCallback.php
@@ -10,7 +10,9 @@
 class HistoryRenderCallback implements RenderCallbackInterface {
 
   /**
-   * #lazy_builder callback; attaches the last read timestamp for a node.
+   * Render API callback: Attaches the last read timestamp for a node.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param int $node_id
    *   The node ID for which to attach the last read timestamp.
diff --git a/core/modules/image/tests/src/Kernel/ConfigActionsTest.php b/core/modules/image/tests/src/Kernel/ConfigActionsTest.php
index 1334d832f61ae6e4c322c7b838e3e91d88f9059a..dda3aa1acc55e6d65034a83b0ceee3a821acfb10 100644
--- a/core/modules/image/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/image/tests/src/Kernel/ConfigActionsTest.php
@@ -32,6 +32,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests adding an image effect using the configuration action manager.
+   */
   public function testConfigActions(): void {
     $style = ImageStyle::load('large');
     $this->assertCount(2, $style->getEffects());
diff --git a/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiTopLevelResourceNormalizerTest.php b/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiTopLevelResourceNormalizerTest.php
index ced2507e1384a8ff9d788dd824c58ee75510fa40..38b7310972f9ef2b42057650f7a6611f31502ee5 100644
--- a/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiTopLevelResourceNormalizerTest.php
+++ b/core/modules/jsonapi/tests/src/Kernel/Normalizer/JsonApiTopLevelResourceNormalizerTest.php
@@ -909,6 +909,9 @@ public function testConfigEntityResourceObjectSchema(): void {
     $this->assertSame([], $validator->getErrors(), 'Validation errors on object ' . print_r($normalized, TRUE) . ' with schema ' . print_r($schema, TRUE));
   }
 
+  /**
+   * Tests the serialization of a top-level JSON:API document with a single resource.
+   */
   public function testTopLevelResourceWithSingleResource(): void {
     [, $resource_object] = $this->getTestContentEntityResource();
     $serializer = $this->container->get('jsonapi.serializer');
diff --git a/core/modules/language/tests/src/Kernel/ConfigActionsTest.php b/core/modules/language/tests/src/Kernel/ConfigActionsTest.php
index 0b159f7463865d91e4d37c3f0dc82f7d126f47f4..1a9474ed3ae123fd081b5733b0e72bbcce87be8b 100644
--- a/core/modules/language/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/language/tests/src/Kernel/ConfigActionsTest.php
@@ -32,6 +32,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of configuration actions on a language.
+   */
   public function testConfigActions(): void {
     $language = ConfigurableLanguage::load('en');
     $this->assertSame('English', $language->getName());
diff --git a/core/modules/layout_builder/tests/src/Kernel/InlineBlockUsageTest.php b/core/modules/layout_builder/tests/src/Kernel/InlineBlockUsageTest.php
index fd2d93945d199e8fc89ef48a3723d7e5d10bb097..2c890e222ce633ea225208bcbaefabd56995600d 100644
--- a/core/modules/layout_builder/tests/src/Kernel/InlineBlockUsageTest.php
+++ b/core/modules/layout_builder/tests/src/Kernel/InlineBlockUsageTest.php
@@ -44,6 +44,9 @@ class InlineBlockUsageTest extends KernelTestBase {
    */
   protected EntityTest $entity;
 
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp(): void {
     parent::setUp();
     $this->database = $this->container->get('database');
diff --git a/core/modules/locale/tests/src/Kernel/LocaleConfigurableLanguageManagerTest.php b/core/modules/locale/tests/src/Kernel/LocaleConfigurableLanguageManagerTest.php
index 49c598596f6dd6fc6f6894faeb36300324363ec8..5a2a07706b1904a0050b0a2ed1d20224e12369b2 100644
--- a/core/modules/locale/tests/src/Kernel/LocaleConfigurableLanguageManagerTest.php
+++ b/core/modules/locale/tests/src/Kernel/LocaleConfigurableLanguageManagerTest.php
@@ -22,6 +22,9 @@ class LocaleConfigurableLanguageManagerTest extends KernelTestBase {
    */
   protected static $modules = ['language', 'locale'];
 
+  /**
+   * Tests retrieving languages from the language manager.
+   */
   public function testGetLanguages(): void {
     $this->installSchema('locale', ['locales_source', 'locales_target', 'locales_location']);
     $default_language = ConfigurableLanguage::create(['label' => $this->randomMachineName(), 'id' => 'default', 'weight' => 0]);
diff --git a/core/modules/locale/tests/src/Kernel/LocaleDefaultConfigStorageTest.php b/core/modules/locale/tests/src/Kernel/LocaleDefaultConfigStorageTest.php
index 34666b8b7fa098590ea9c6ea0756feb1a4f35d79..c0b76119e2b951a3752c3b745a26b218c84e0c22 100644
--- a/core/modules/locale/tests/src/Kernel/LocaleDefaultConfigStorageTest.php
+++ b/core/modules/locale/tests/src/Kernel/LocaleDefaultConfigStorageTest.php
@@ -23,6 +23,9 @@ class LocaleDefaultConfigStorageTest extends KernelTestBase {
     'locale_test_translate',
   ];
 
+  /**
+   * Tests retrieval of component names from locale default config storage.
+   */
   public function testGetComponentNames(): void {
     $storage = new LocaleDefaultConfigStorage(
       new NullStorage(),
diff --git a/core/modules/media/tests/src/Functional/MediaRequirementsTest.php b/core/modules/media/tests/src/Functional/MediaRequirementsTest.php
index 119c147ee95f46f9a43c9e50ea1aed19300746ef..5efceb52f85241853d791c613d109a6b63157d59 100644
--- a/core/modules/media/tests/src/Functional/MediaRequirementsTest.php
+++ b/core/modules/media/tests/src/Functional/MediaRequirementsTest.php
@@ -11,14 +11,6 @@
  */
 class MediaRequirementsTest extends MediaFunctionalTestBase {
 
-  /**
-   * {@inheritdoc}
-   *
-   * @todo Remove and fix test to not rely on super user.
-   * @see https://www.drupal.org/project/drupal/issues/3437620
-   */
-  protected bool $usesSuperUserAccessPolicy = TRUE;
-
   /**
    * {@inheritdoc}
    */
@@ -38,7 +30,10 @@ public function testMissingSourceFieldDefinition(): void {
     $field_storage_definition->delete();
     $valid_media_type = $this->createMediaType('test');
 
-    $this->drupalLogin($this->rootUser);
+    $permissions = [
+      'administer site configuration',
+    ];
+    $this->drupalLogin($this->drupalCreateUser($permissions));
     $this->drupalGet('/admin/reports/status');
     $this->assertSession()->statusCodeEquals(200);
     $this->assertSession()->pageTextContains("The source field definition for the {$media_type->label()} media type is missing.");
diff --git a/core/modules/media/tests/src/Kernel/ConfigActionsTest.php b/core/modules/media/tests/src/Kernel/ConfigActionsTest.php
index 98e765c689a2d131a8a59d70e11e845fd3590dab..6da5d4d1419fb4c0d2026b51b208a199435f7b11 100644
--- a/core/modules/media/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/media/tests/src/Kernel/ConfigActionsTest.php
@@ -35,6 +35,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of configuration actions on a media type.
+   */
   public function testConfigActions(): void {
     $media_type = MediaType::load('test');
     $this->assertSame('Test type.', $media_type->getDescription());
diff --git a/core/modules/media/tests/src/Kernel/OEmbedResourceConstraintValidatorTest.php b/core/modules/media/tests/src/Kernel/OEmbedResourceConstraintValidatorTest.php
index 65ae4fe37f65d36c971540e5deb6b997f32d96d4..4edf12fd2f6de946ffb72049a42c20994d048c60 100644
--- a/core/modules/media/tests/src/Kernel/OEmbedResourceConstraintValidatorTest.php
+++ b/core/modules/media/tests/src/Kernel/OEmbedResourceConstraintValidatorTest.php
@@ -118,6 +118,9 @@ public function __construct($entity) {
         $this->entity = $entity;
       }
 
+      /**
+       * Returns the test entity.
+       */
       public function getEntity(): Media {
         return $this->entity;
       }
diff --git a/core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php b/core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php
index 2d0460b0b29771f9837f6b55322e7cc5c763c0e5..28f123a946c42b3c085581682ed83c507397afcb 100644
--- a/core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php
+++ b/core/modules/media_library/tests/src/FunctionalJavascript/ContentModerationTest.php
@@ -39,14 +39,6 @@ class ContentModerationTest extends WebDriverTestBase {
     'views',
   ];
 
-  /**
-   * {@inheritdoc}
-   *
-   * @todo Remove and fix test to not rely on super user.
-   * @see https://www.drupal.org/project/drupal/issues/3437620
-   */
-  protected bool $usesSuperUserAccessPolicy = TRUE;
-
   /**
    * {@inheritdoc}
    */
@@ -189,11 +181,6 @@ protected function setUp(): void {
    * Tests the media library widget only shows published media.
    */
   public function testAdministrationPage(): void {
-    // User 1 should be able to see all media items.
-    $this->drupalLogin($this->rootUser);
-    $this->drupalGet('admin/content/media');
-    $this->assertAllMedia();
-
     // The media admin user should be able to see all media items.
     $this->drupalLogin($this->userAdmin);
     $this->drupalGet('admin/content/media');
@@ -225,11 +212,6 @@ public function testAdministrationPage(): void {
       $media->save();
     }
 
-    // User 1 should still be able to see all media items.
-    $this->drupalLogin($this->rootUser);
-    $this->drupalGet('admin/content/media');
-    $this->assertAllMedia();
-
     // The media admin user should still be able to see all media items.
     $this->drupalLogin($this->userAdmin);
     $this->drupalGet('admin/content/media');
@@ -262,11 +244,6 @@ public function testWidget(): void {
     $assert_session = $this->assertSession();
 
     // All users should only be able to see published media items.
-    $this->drupalLogin($this->rootUser);
-    $this->drupalGet('node/add/article');
-    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')->click();
-    $assert_session->assertWaitOnAjaxRequest();
-    $this->assertOnlyPublishedMedia();
     $this->drupalLogin($this->userAdmin);
     $this->drupalGet('node/add/article');
     $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')->click();
@@ -295,11 +272,6 @@ public function testWidget(): void {
       $media->save();
     }
 
-    $this->drupalLogin($this->rootUser);
-    $this->drupalGet('node/add/article');
-    $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')->click();
-    $assert_session->assertWaitOnAjaxRequest();
-    $this->assertOnlyPublishedMedia();
     $this->drupalLogin($this->userAdmin);
     $this->drupalGet('node/add/article');
     $assert_session->elementExists('css', '.js-media-library-open-button[name^="field_media"]')->click();
diff --git a/core/modules/menu_ui/menu_ui.module b/core/modules/menu_ui/menu_ui.module
index 2976cad4dc86fe304f77642767aa7b9f158d9b6b..f4406bfb1f1477b4396aa2fe0a1a0a03516757cb 100644
--- a/core/modules/menu_ui/menu_ui.module
+++ b/core/modules/menu_ui/menu_ui.module
@@ -20,7 +20,7 @@
 function _menu_ui_node_save(NodeInterface $node, array $values) {
   /** @var \Drupal\menu_link_content\MenuLinkContentInterface $entity */
   if (!empty($values['entity_id'])) {
-    $entity = MenuLinkContent::load($values['entity_id']);
+    $entity = \Drupal::service('entity.repository')->getActive('menu_link_content', $values['entity_id']);
     if ($entity->isTranslatable() && $node->isTranslatable()) {
       if (!$entity->hasTranslation($node->language()->getId())) {
         $entity = $entity->addTranslation($node->language()->getId(), $entity->toArray());
@@ -48,7 +48,26 @@ function _menu_ui_node_save(NodeInterface $node, array $values) {
   $entity->menu_name->value = $values['menu_name'];
   $entity->parent->value = $values['parent'];
   $entity->weight->value = $values['weight'] ?? 0;
-  $entity->isDefaultRevision($node->isDefaultRevision());
+  if ($entity->isNew()) {
+    // @todo The menu link doesn't need to be changed in a workspace context.
+    //   Fix this in https://www.drupal.org/project/drupal/issues/3511204.
+    if (!$node->isDefaultRevision() && $node->hasLinkTemplate('latest-version')) {
+      // If a new menu link is created while saving the node as a pending draft
+      // (non-default revision), store it as a link to the latest version.
+      // That ensures that there is a regular, valid link target that is
+      // only visible to users with permission to view the latest version.
+      $entity->get('link')->uri = 'internal:/node/' . $node->id() . '/latest';
+    }
+  }
+  else {
+    $entity->isDefaultRevision($node->isDefaultRevision());
+    if (!$entity->isDefaultRevision()) {
+      $entity->setNewRevision(TRUE);
+    }
+    elseif ($entity->get('link')->uri !== 'entity:node/' . $node->id()) {
+      $entity->get('link')->uri = 'entity:node/' . $node->id();
+    }
+  }
   $entity->save();
 }
 
@@ -69,12 +88,17 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) {
   $defaults = FALSE;
   if ($node->id()) {
     $id = FALSE;
-    // Give priority to the default menu
+    // Give priority to the default menu.
     $type_menus = $node_type->getThirdPartySetting('menu_ui', 'available_menus', ['main']);
+    // An existing menu link either points to the canonical or the latest path,
+    // in case of a new menu link that was creating while saving as a pending
+    // draft.
+    $uri_candidates = ['entity:node/' . $node->id(), 'internal:/node/' . $node->id() . '/latest'];
+
     if (in_array($menu_name, $type_menus)) {
       $query = \Drupal::entityQuery('menu_link_content')
         ->accessCheck(TRUE)
-        ->condition('link.uri', 'entity:node/' . $node->id())
+        ->condition('link.uri', $uri_candidates, 'IN')
         ->condition('menu_name', $menu_name)
         ->sort('id', 'ASC')
         ->range(0, 1);
@@ -86,7 +110,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) {
     if (!$id && !empty($type_menus)) {
       $query = \Drupal::entityQuery('menu_link_content')
         ->accessCheck(TRUE)
-        ->condition('link.uri', 'entity:node/' . $node->id())
+        ->condition('link.uri', $uri_candidates, 'IN')
         ->condition('menu_name', array_values($type_menus), 'IN')
         ->sort('id', 'ASC')
         ->range(0, 1);
@@ -95,8 +119,7 @@ function menu_ui_get_menu_link_defaults(NodeInterface $node) {
       $id = (!empty($result)) ? reset($result) : FALSE;
     }
     if ($id) {
-      $menu_link = MenuLinkContent::load($id);
-      $menu_link = \Drupal::service('entity.repository')->getTranslationFromContext($menu_link);
+      $menu_link = \Drupal::service('entity.repository')->getActive('menu_link_content', $id);
       $defaults = [
         'entity_id' => $menu_link->id(),
         'id' => $menu_link->getPluginId(),
@@ -150,7 +173,7 @@ function menu_ui_form_node_form_submit($form, FormStateInterface $form_state) {
     $values = $form_state->getValue('menu');
     if (empty($values['enabled'])) {
       if ($values['entity_id']) {
-        $entity = MenuLinkContent::load($values['entity_id']);
+        $entity = \Drupal::service('entity.repository')->getActive('menu_link_content', $values['entity_id']);
         $entity->delete();
       }
     }
diff --git a/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php b/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php
index 4960b738a5a485db032958a0f36ad26975976607..95dc030ba80462f5100df749086bba4a81b1e318 100644
--- a/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php
+++ b/core/modules/menu_ui/tests/src/Functional/MenuUiContentModerationTest.php
@@ -177,8 +177,14 @@ public function testMenuUiWithPendingRevisions(): void {
     $this->drupalGet('node/' . $node->id() . '/edit');
     $this->submitForm($edit, 'Save');
     $this->assertSession()->pageTextContains("Page {$node->label()} has been updated.");
+
+    // The link is created to the latest page, which the editor is allowed
+    // see, but an anonymous visitor not.
+    $this->assertSession()->linkExists('Second test menu link');
+    $this->drupalLogout();
     $this->assertSession()->linkNotExists('Second test menu link');
 
+    $this->drupalLogin($editor);
     // Publish the content and ensure the new menu link shows up.
     $edit = [
       'moderation_state[0][state]' => 'published',
diff --git a/core/modules/menu_ui/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php b/core/modules/menu_ui/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php
index 002906f1ce9635ebf087c71427294c07aa40469a..fbdc925042db2c90ea8bdbd8b0ad9b0aa8a57a79 100644
--- a/core/modules/menu_ui/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php
+++ b/core/modules/menu_ui/tests/src/Kernel/Migrate/MigrateMenuSettingsTest.php
@@ -27,6 +27,9 @@ protected function setUp(): void {
     $this->executeMigration('menu_settings');
   }
 
+  /**
+   * Tests migration of menu_ui settings.
+   */
   public function testMigration(): void {
     $this->assertTrue(\Drupal::config('menu_ui.settings')->get('override_parent_selector'));
   }
diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
index ec18083c9ef7e17ad94b44ea251aaf8dcf4a20a4..07595c77bc788c4a9df13e55bae0aec25d210855 100644
--- a/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
+++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php
@@ -148,6 +148,11 @@ protected function getEntity(Row $row, array $old_destination_id_values) {
       }
     }
     if ($entity === NULL) {
+      // If the entity could not be loaded by revision then the given
+      // revision does not yet exist. Load the current default revision and
+      // prepare to save it as a new non-default revision. setNewRevision()
+      // will unset the current revision ID and the entity is then updated
+      // with the source revision ID and saved as that.
       $entity_id = $row->getDestinationProperty($this->getKey('id'));
       $entity = $this->storage->load($entity_id);
 
@@ -159,11 +164,11 @@ protected function getEntity(Row $row, array $old_destination_id_values) {
 
       $entity->enforceIsNew(FALSE);
       $entity->setNewRevision(TRUE);
+      $entity->isDefaultRevision(FALSE);
     }
     // We need to update the entity, so that the destination row IDs are
     // correct.
     $entity = $this->updateEntity($entity, $row);
-    $entity->isDefaultRevision(FALSE);
     return $entity;
   }
 
diff --git a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php
index 5c2258df3d8a938f131495aa5f556a308c0f55ec..8417075a075cd33315289e1214aef5879da1db0d 100644
--- a/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php
+++ b/core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php
@@ -114,7 +114,7 @@ public function testGetEntityUpdateRevision(): void {
       ->willReturn($entity->reveal());
     // Make sure its set as an update and not the default revision.
     $entity->setNewRevision(FALSE)->shouldBeCalled();
-    $entity->isDefaultRevision(FALSE)->shouldBeCalled();
+    $entity->isDefaultRevision()->shouldNotBeCalled();
 
     $row = new Row(['nid' => 1, 'vid' => 2], ['nid' => 1, 'vid' => 2]);
     $row->setDestinationProperty('vid', 2);
diff --git a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
index 5597a3580eca63d1f598d1bb7bb7c7743661bb14..03322adcf232b865d2a24a44f29683b6d3235aed 100644
--- a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
+++ b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php
@@ -88,13 +88,12 @@ public function testLogin(): void {
         'dynamic_page_cache' => 2,
       ],
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 3,
-      'CacheTagIsValidCount' => 30,
       'CacheTagInvalidationCount' => 0,
+      'CacheTagLookupQueryCount' => 20,
       'ScriptCount' => 2,
       'ScriptBytes' => 215500,
       'StylesheetCount' => 1,
-      'StylesheetBytes' => 47700,
+      'StylesheetBytes' => 46300,
     ];
     $this->assertMetrics($expected, $performance_data);
 
diff --git a/core/modules/node/src/NodeViewBuilder.php b/core/modules/node/src/NodeViewBuilder.php
index f077ad75dc5314ed82f20984cd3c4e70be456dfb..4d9c96f176d5fdbfbe463a38393830032c12078c 100644
--- a/core/modules/node/src/NodeViewBuilder.php
+++ b/core/modules/node/src/NodeViewBuilder.php
@@ -74,7 +74,9 @@ protected function getBuildDefaults(EntityInterface $entity, $view_mode) {
   }
 
   /**
-   * #lazy_builder callback; builds a node's links.
+   * Render API callback: Builds a node's links.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $node_entity_id
    *   The node entity ID.
diff --git a/core/modules/node/tests/src/Functional/NodeCreationTest.php b/core/modules/node/tests/src/Functional/NodeCreationTest.php
index ed151d7cd8829d46b52d255f007a53847adec358..f0192966a1b50c47982b440bc99f1f74c2d89c55 100644
--- a/core/modules/node/tests/src/Functional/NodeCreationTest.php
+++ b/core/modules/node/tests/src/Functional/NodeCreationTest.php
@@ -261,27 +261,26 @@ public function testAuthoredDate(): void {
    */
   public function testAuthorAutocomplete(): void {
     $admin_user = $this->drupalCreateUser([
-      'administer nodes',
       'create page content',
     ]);
     $this->drupalLogin($admin_user);
 
     $this->drupalGet('node/add/page');
-
-    // Verify that no autocompletion exists without access user profiles.
-    $this->assertSession()->elementNotExists('xpath', '//input[@id="edit-uid-0-value" and contains(@data-autocomplete-path, "user/autocomplete")]');
+    $this->assertSession()->statusCodeEquals(200);
+    // Verify that no autocompletion exists without administer nodes.
+    $selector = '//input[@id="edit-uid-0-target-id" and contains(@data-autocomplete-path, "/entity_reference_autocomplete/user/default")]';
+    $this->assertSession()->elementNotExists('xpath', $selector);
 
     $admin_user = $this->drupalCreateUser([
       'administer nodes',
       'create page content',
-      'access user profiles',
     ]);
     $this->drupalLogin($admin_user);
 
     $this->drupalGet('node/add/page');
 
     // Ensure that the user does have access to the autocompletion.
-    $this->assertSession()->elementsCount('xpath', '//input[@id="edit-uid-0-target-id" and contains(@data-autocomplete-path, "/entity_reference_autocomplete/user/default")]', 1);
+    $this->assertSession()->elementsCount('xpath', $selector, 1);
   }
 
   /**
diff --git a/core/modules/node/tests/src/Kernel/ConfigActionsTest.php b/core/modules/node/tests/src/Kernel/ConfigActionsTest.php
index 9a682cbe0d740431f9d9e8a6db4432e045a778a2..c24468451efa497c2a3a6d50ec72e30d5f38cb79 100644
--- a/core/modules/node/tests/src/Kernel/ConfigActionsTest.php
+++ b/core/modules/node/tests/src/Kernel/ConfigActionsTest.php
@@ -37,6 +37,9 @@ protected function setUp(): void {
     $this->configActionManager = $this->container->get('plugin.manager.config_action');
   }
 
+  /**
+   * Tests the application of configuration actions on a node type.
+   */
   public function testConfigActions(): void {
     $node_type = $this->createContentType();
 
diff --git a/core/modules/node/tests/src/Kernel/Views/RevisionCreateTimestampTest.php b/core/modules/node/tests/src/Kernel/Views/RevisionCreateTimestampTest.php
index b9004855b57ffdc5889ce12c3ad93b110371b202..34ccc0c3e8d5adff533677ef2cbfc8327d025151 100644
--- a/core/modules/node/tests/src/Kernel/Views/RevisionCreateTimestampTest.php
+++ b/core/modules/node/tests/src/Kernel/Views/RevisionCreateTimestampTest.php
@@ -42,6 +42,9 @@ protected function setUp($import_test_views = TRUE): void {
     }
   }
 
+  /**
+   * Tests the revision create timestamp view.
+   */
   public function testRevisionCreateTimestampView(): void {
     $node_type = NodeType::create([
       'type' => 'article',
diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
index 83b155a8f56d1992061e98d731f2b6fc54da8b94..8a5d317dc4d4a8bab26a9a6048a6faf0f913a5b4 100644
--- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
+++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php
@@ -334,7 +334,9 @@ public static function deleteAjax(array $form, FormStateInterface $form_state) {
   abstract protected function allowedValuesDescription();
 
   /**
-   * #element_validate callback for options field allowed values.
+   * Render API callback: Validates the allowed values of an options field.
+   *
+   * This function is assigned as a #element_validate callback.
    *
    * @param array $element
    *   An associative array containing the properties and children of the
diff --git a/core/modules/package_manager/tests/src/Kernel/PathExcluder/UnknownPathExcluderTest.php b/core/modules/package_manager/tests/src/Kernel/PathExcluder/UnknownPathExcluderTest.php
index d68da1cba9aac56db0cf965f9ded0781addd9746..03913aa6c2bf8554c0b4caf9fce842599ef3cb3a 100644
--- a/core/modules/package_manager/tests/src/Kernel/PathExcluder/UnknownPathExcluderTest.php
+++ b/core/modules/package_manager/tests/src/Kernel/PathExcluder/UnknownPathExcluderTest.php
@@ -228,6 +228,9 @@ public function testExcluderCanBeDisabled(): void {
     $this->assertFileDoesNotExist($stage->getStageDirectory() . '/unknown/file.txt');
   }
 
+  /**
+   * Tests that path repositories are included.
+   */
   public function testPathRepositoriesAreIncluded(): void {
     $this->createTestProjectForTemplate(TRUE);
 
diff --git a/core/modules/pgsql/src/Driver/Database/pgsql/Schema.php b/core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
index b6f669d24ba6be1cbdd2dae911c6937430b2537a..a4585e15da7abcb1e1bc5c3f251c2c223fd86905 100644
--- a/core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
+++ b/core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
@@ -580,7 +580,7 @@ public function renameTable($table, $new_name) {
       // exceed the 63 chars limit of PostgreSQL, we need to take care of that.
       // cSpell:disable-next-line
       // Example (drupal_Gk7Su_T1jcBHVuvSPeP22_I3Ni4GrVEgTYlIYnBJkro_idx).
-      if (str_contains($index->indexname, 'drupal_')) {
+      if (str_starts_with($index->indexname, 'drupal_')) {
         preg_match('/^drupal_(.*)_' . preg_quote($index_type, NULL) . '/', $index->indexname, $matches);
         $index_name = $matches[1];
       }
diff --git a/core/modules/pgsql/tests/src/Kernel/pgsql/SchemaTest.php b/core/modules/pgsql/tests/src/Kernel/pgsql/SchemaTest.php
index 6894968a9552e111d576b28401585a2ab444289f..e10ed33d1903613076e3631c591fce991313af80 100644
--- a/core/modules/pgsql/tests/src/Kernel/pgsql/SchemaTest.php
+++ b/core/modules/pgsql/tests/src/Kernel/pgsql/SchemaTest.php
@@ -365,6 +365,35 @@ public function testRenameTableWithNewIndexNameEqualsTableName(): void {
     $this->assertTrue($this->schema->tableExists($table_name_new));
   }
 
+  /**
+   * Tests renaming a table which name contains drupal_ with multiple indexes.
+   */
+  public function testRenameTableWithNameContainingDrupalUnderscoreAndMultipleIndexes(): void {
+    $table_name_old = 'field_drupal_foo';
+    $table_name_new = 'field_drupal_bar';
+    $table_specification = [
+      'fields' => [
+        'one'  => [
+          'type' => 'int',
+          'default' => NULL,
+        ],
+        'two'  => [
+          'type' => 'int',
+          'default' => NULL,
+        ],
+      ],
+      'indexes' => [
+        'one' => ['one'],
+        'two' => ['two'],
+      ],
+    ];
+    $this->schema->createTable($table_name_old, $table_specification);
+
+    $this->schema->renameTable($table_name_old, $table_name_new);
+
+    $this->assertTrue($this->schema->tableExists($table_name_new));
+  }
+
   /**
    * Tests column name escaping in field constraints.
    */
diff --git a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.install b/core/modules/rest/tests/modules/rest_test_views/rest_test_views.install
deleted file mode 100644
index edc5a585f84d90980be2d04936dc690aa932184b..0000000000000000000000000000000000000000
--- a/core/modules/rest/tests/modules/rest_test_views/rest_test_views.install
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-/**
- * @file
- * Install function for the Rest Test Views module.
- */
-
-declare(strict_types=1);
-
-use Drupal\views\Tests\ViewTestData;
-
-/**
- * Implements hook_install().
- */
-function rest_test_views_install(): void {
-
-  // Install the state and schema by for views test data.
-  \Drupal::state()->set('views_test_data_schema', ViewTestData::schemaDefinition());
-  \Drupal::state()->set('views_test_data_views_data', ViewTestData::viewsData());
-  drupal_flush_all_caches();
-}
diff --git a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
index 8612f65df475c01036c9b669b1eedcc126bd1785..9444338650fa0d9d3f02ca7962d40a0c0af6e0a7 100644
--- a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
+++ b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
@@ -2,9 +2,7 @@ langcode: en
 status: true
 dependencies:
   module:
-    - entity_test
     - rest
-    - serialization
     - user
 id: test_serializer_display_entity
 label: 'Test serialize display entity rows'
@@ -15,60 +13,42 @@ base_table: entity_test
 base_field: id
 display:
   default:
+    display_plugin: default
     id: default
     display_title: Default
-    display_plugin: default
     position: null
     display_options:
-      title: 'Test serialize'
-      exposed_form:
-        type: basic
       access:
         type: perm
         options:
           perm: 'access content'
       cache:
         type: tag
+      query:
+        type: views_query
+      exposed_form:
+        type: basic
+      style:
+        type: serializer
+      row:
+        type: data_entity
       sorts:
         id:
           id: standard
           table: entity_test
           field: id
+          order: DESC
+          plugin_id: date
           entity_type: entity_test
           entity_field: id
-          plugin_id: date
-          order: DESC
+      title: 'Test serialize'
       arguments: {  }
-      style:
-        type: serializer
-      row:
-        type: data_entity
-      query:
-        type: views_query
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - entity_test_view_grants
-        - 'languages:language_interface'
-        - request_format
-        - url.query_args
-        - user.permissions
-      tags: {  }
   rest_export_1:
+    display_plugin: rest_export
     id: rest_export_1
     display_title: serializer
-    display_plugin: rest_export
     position: null
     display_options:
       defaults:
         access: false
-      display_extenders: {  }
       path: test/serialize/entity
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - entity_test_view_grants
-        - 'languages:language_interface'
-        - request_format
-      tags: {  }
diff --git a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
index cac819a387279aee2395db8ab14ad0daa84bb511..414de42d6b19f87634eb0153bfdf71daa9b5386a 100644
--- a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
+++ b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
@@ -3,9 +3,7 @@ status: true
 dependencies:
   module:
     - rest
-    - serialization
     - user
-    - views_test_data
 id: test_serializer_display_field
 label: 'Test serializer display field rows'
 module: rest
@@ -15,19 +13,32 @@ base_table: views_test_data
 base_field: id
 display:
   default:
+    display_plugin: default
     id: default
     display_title: Default
-    display_plugin: default
     position: null
     display_options:
-      title: 'Test serialize'
+      access:
+        type: perm
+        options:
+          perm: 'access content'
+      cache:
+        type: tag
+      query:
+        type: views_query
+      exposed_form:
+        type: basic
+      style:
+        type: serializer
+      row:
+        type: data_field
       fields:
         name:
           id: name
           table: views_test_data
           field: name
-          plugin_id: string
           label: ''
+          plugin_id: string
         nothing:
           id: nothing
           table: views
@@ -45,71 +56,49 @@ display:
           id: created
           table: views_test_data
           field: created
-          plugin_id: date
-          date_format: timestamp
-          custom_date_format: ''
-          timezone: ''
-      exposed_form:
-        type: basic
-      access:
-        type: perm
-        options:
-          perm: 'access content'
-      cache:
-        type: tag
+          type: timestamp
+          settings:
+            date_format: medium
+            custom_date_format: ''
+            timezone: ''
+          plugin_id: field
       sorts:
         created:
           id: created
           table: views_test_data
           field: created
-          plugin_id: date
           order: DESC
+          plugin_id: date
+      title: 'Test serialize'
       arguments: {  }
-      style:
-        type: serializer
-      row:
-        type: data_field
-      query:
-        type: views_query
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - request_format
-        - url.query_args
-        - user.permissions
-      tags: {  }
   rest_export_1:
+    display_plugin: rest_export
     id: rest_export_1
     display_title: serializer
-    display_plugin: rest_export
     position: null
     display_options:
+      defaults:
+        access: false
+        style: false
+        row: false
+      path: test/serialize/field
       access:
         type: none
       style:
         type: serializer
       row:
         type: data_field
-      defaults:
-        access: false
-        style: false
-        row: false
-      display_extenders: {  }
-      path: test/serialize/field
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - request_format
-      tags: {  }
   rest_export_2:
+    display_plugin: rest_export
     id: rest_export_2
     display_title: 'serialize - access denied'
-    display_plugin: rest_export
     position: null
     display_options:
+      defaults:
+        access: false
+        style: false
+        row: false
+      path: test/serialize/denied
       access:
         type: perm
         options:
@@ -118,16 +107,3 @@ display:
         type: serializer
       row:
         type: data_field
-      defaults:
-        access: false
-        style: false
-        row: false
-      display_extenders: {  }
-      path: test/serialize/denied
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - request_format
-        - user.permissions
-      tags: {  }
diff --git a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
index 3ce0238cfd7b9c2397bb5a5e674e918a98ce56e1..3e5606b8645e27db6e9dc6aa0515e69efb164280 100644
--- a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
+++ b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
@@ -105,12 +105,24 @@ public function testHandle(): void {
  */
 class StubRequestHandlerResourcePlugin extends ResourceBase {
 
+  /**
+   * Handles a GET request.
+   */
   public function get($example = NULL, ?Request $request = NULL) {}
 
+  /**
+   * Handles a POST request.
+   */
   public function post() {}
 
+  /**
+   * Handles a PATCH request.
+   */
   public function patch($data, Request $request) {}
 
+  /**
+   * Handles a DELETE request.
+   */
   public function delete() {}
 
 }
diff --git a/core/modules/shortcut/src/ShortcutLazyBuilders.php b/core/modules/shortcut/src/ShortcutLazyBuilders.php
index 5a6c5ccde8cd369054501ab71ba23cee0f49ce07..8c99615ec2c7274aaff4b3533fe474332f620422 100644
--- a/core/modules/shortcut/src/ShortcutLazyBuilders.php
+++ b/core/modules/shortcut/src/ShortcutLazyBuilders.php
@@ -45,7 +45,9 @@ public static function trustedCallbacks() {
   }
 
   /**
-   * #lazy_builder callback; builds shortcut toolbar links.
+   * Render API callback: Builds shortcut toolbar links.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param bool $show_configure_link
    *   Boolean to indicate whether to include the configure link or not.
diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php
index 53cca91ced2840729250ba1c8cbdcc5baa4a383a..131b6a075d5bf70ad43bb7bda73993f396aa995f 100644
--- a/core/modules/system/src/Controller/DbUpdateController.php
+++ b/core/modules/system/src/Controller/DbUpdateController.php
@@ -710,6 +710,12 @@ protected function helpfulLinks(Request $request) {
         'url' => Url::fromRoute('system.admin')->setOption('base_url', $base_url),
       ];
     }
+    if ($this->account->hasPermission('administer site configuration')) {
+      $links['status-report'] = [
+        'title' => $this->t('Status report'),
+        'url' => Url::fromRoute('system.status')->setOption('base_url', $base_url),
+      ];
+    }
     return $links;
   }
 
diff --git a/core/modules/system/src/Element/StatusReportPage.php b/core/modules/system/src/Element/StatusReportPage.php
index 361ec22bbea3225cdc17f2a25d385a13d90af272..90a878831ead4294442233d5eac0ffe87345984c 100644
--- a/core/modules/system/src/Element/StatusReportPage.php
+++ b/core/modules/system/src/Element/StatusReportPage.php
@@ -28,7 +28,9 @@ public function getInfo() {
   }
 
   /**
-   * #pre_render callback to get general info out of requirements.
+   * Render API callback: Gets general info out of requirements.
+   *
+   * This function is assigned as a #pre_render callback.
    */
   public static function preRenderGeneralInfo($element) {
     $element['#general_info'] = [
@@ -70,7 +72,7 @@ public static function preRenderGeneralInfo($element) {
   }
 
   /**
-   * #pre_render callback to create counter elements.
+   * The #pre_render callback to create counter elements.
    */
   public static function preRenderCounters($element) {
     // Count number of items with different severity for summary.
@@ -126,12 +128,19 @@ public static function preRenderCounters($element) {
   }
 
   /**
-   * #pre_render callback to create status report requirements.
+   * Render API callback: Create status report requirements.
+   *
+   * This function is assigned as a #pre_render callback.
    */
   public static function preRenderRequirements($element) {
     $element['#requirements'] = [
       '#type' => 'status_report',
       '#requirements' => $element['#requirements'],
+      '#attached' => [
+        'library' => [
+          'system/status.report',
+        ],
+      ],
     ];
 
     return $element;
diff --git a/core/modules/system/system.libraries.yml b/core/modules/system/system.libraries.yml
index 11491f7a779aea85b6f404ecd93e49440dac8a92..3f3c00951be0a2a8b3881e4a71be6dd439f77d06 100644
--- a/core/modules/system/system.libraries.yml
+++ b/core/modules/system/system.libraries.yml
@@ -15,9 +15,6 @@ base:
       css/components/position-container.module.css: { weight: -10 }
       css/components/reset-appearance.module.css: { weight: -10 }
       css/components/resize.module.css: { weight: -10 }
-      css/components/system-status-counter.css: { weight: -10 }
-      css/components/system-status-report-counters.css: { weight: -10 }
-      css/components/system-status-report-general-info.css: { weight: -10 }
       css/components/tablesort.module.css: { weight: -10 }
 
 admin:
@@ -37,6 +34,27 @@ maintenance:
     - system/base
     - system/admin
 
+status.report:
+  version: VERSION
+  css:
+    component:
+      css/components/system-status-counter.css: { weight: -10 }
+      css/components/system-status-report-counters.css: { weight: -10 }
+      css/components/system-status-report-general-info.css: { weight: -10 }
+  moved_files:
+    system/base:
+      deprecation_version: 11.2.0
+      removed_version: 12.0.0
+      deprecation_link: https://www.drupal.org/node/3432346
+      css:
+        component:
+          css/components/system-status-counter.css:
+            base: css/components/system-status-counter.css
+          css/components/system-status-reports-counters.css:
+            base: css/components/system-status-reports-counters.css
+          css/components/system-status-report-general-info.css:
+            base: css/components/system-status-report-general-info.css
+
 drupal.system:
   version: VERSION
   js:
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index dc8f1649a50bc24a21bf85e98d21782d9307d9b3..e3f6c11ef03c1a42cf9e352a4e93b965d803e1ec 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -210,13 +210,6 @@ function template_preprocess_entity_add_list(&$variables): void {
  *   system_authorized_init($callback, $file, $arguments, $page_title);
  *   return new RedirectResponse(system_authorized_get_url()->toString());
  * @endcode
- * Example (Drupal\update\Form\UpdateReady::submitForm()):
- * @code
- *  system_authorized_init('update_authorize_run_update',
- *    __DIR__ . '/../../update.authorize.inc',
- *    [$updates], $this->t('Update manager'));
- *  $form_state->setRedirectUrl(system_authorized_get_url());
- * @endcode
  *
  * @param callable $callback
  *   The name of the function to invoke once the user authorizes the operation.
diff --git a/core/modules/system/templates/form-element.html.twig b/core/modules/system/templates/form-element.html.twig
index 3311ebcfad0af96c0972b171fb95a7d6cc8d0eca..9dce6eda8279313745d5ba6a15073fc54fdec0e9 100644
--- a/core/modules/system/templates/form-element.html.twig
+++ b/core/modules/system/templates/form-element.html.twig
@@ -72,7 +72,7 @@
     <span class="field-prefix">{{ prefix }}</span>
   {% endif %}
   {% if description_display == 'before' and description.content %}
-    <div{{ description.attributes }}>
+    <div{{ description.attributes.addClass(description_classes) }}>
       {{ description.content }}
     </div>
   {% endif %}
diff --git a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
index 71ee3dc613bad71ffb85cbc9d8592d6334497f08..bd8784b3e5208bebf72a6aac1ac4541e8eb4152e 100644
--- a/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
+++ b/core/modules/system/tests/modules/pager_test/src/Controller/PagerTestController.php
@@ -146,7 +146,9 @@ public function multiplePagers() {
   }
 
   /**
-   * #pre_render callback for #type => pager that shows the pager cache context.
+   * Render API callback: Shows the pager cache context for type pager.
+   *
+   * This function is assigned as a #pre_render callback.
    */
   public static function showPagerCacheContext(array $pager) {
     \Drupal::messenger()->addStatus(\Drupal::service('cache_contexts_manager')->convertTokensToKeys(['url.query_args.pagers:' . $pager['#element']])->getKeys()[0]);
diff --git a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
index 82cf68ddd3c886d6c2e56324b491a8611e4f2b1f..1528a08398163ed42e5489b404854f427a8cf83a 100644
--- a/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
+++ b/core/modules/system/tests/modules/render_placeholder_message_test/src/RenderPlaceholderMessageTestController.php
@@ -120,7 +120,9 @@ protected function build(array $placeholder_order) {
   }
 
   /**
-   * #lazy_builder callback; sets and prints a message.
+   * Render API callback: Sets and prints a message.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $message
    *   The message to send.
diff --git a/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php b/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
index 3f0de14a252aec78af0fcf6b64746382dd52cd82..210e41e840d5d933908f73159932a0ee0c6fb158 100644
--- a/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
+++ b/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
@@ -811,8 +811,9 @@ public function testSuccessfulMultilingualUpdateFunctionality(): void {
     $this->assertSession()->pageTextContains('Updates were attempted.');
     $this->assertSession()->linkExists('logged');
     $this->assertSession()->linkExists('Administration pages');
+    $this->assertSession()->linkExists('Status report');
     $this->assertSession()->elementNotExists('xpath', '//main//a[contains(@href, "update.php")]');
-    $this->clickLink('Administration pages');
+    $this->clickLink('Status report');
     $this->assertSession()->statusCodeEquals(200);
   }
 
diff --git a/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php
index 0d5483370be83fcb299fa1ce968b63003b0fcb34..6c8c42da59e89e7eafa40fa45422dfeb7e4878e4 100644
--- a/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php
+++ b/core/modules/system/tests/src/Kernel/DateFormatAccessControlHandlerTest.php
@@ -70,6 +70,12 @@ public function testAccess($permissions, $which_entity, $view_label_access_resul
     static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE));
   }
 
+  /**
+   * Provides test cases for access control based on user permissions and entity lock status.
+   *
+   * @return array
+   *   An array of test cases.
+   */
   public static function providerTestAccess(): array {
     $c = new ContainerBuilder();
     $cache_contexts_manager = (new Prophet())->prophesize(CacheContextsManager::class);
diff --git a/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php b/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php
index 57e1758cb8f85188ccfbe9f6556789ded3197ffb..b8fcf1c511840f94573abe6ed61b126e4a2fc580 100644
--- a/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php
+++ b/core/modules/system/tests/src/Kernel/MenuAccessControlHandlerTest.php
@@ -65,6 +65,12 @@ public function testAccess($permissions, $which_entity, $view_label_access_resul
     static::assertEquals($create_access_result, $this->accessControlHandler->createAccess(NULL, $user, [], TRUE));
   }
 
+  /**
+   * Provides test cases for menu access control based on user permissions and menu lock status.
+   *
+   * @return array
+   *   An array of test cases.
+   */
   public static function providerTestAccess(): array {
     // RefinableCacheableDependencyTrait::addCacheContexts() only needs the
     // container to perform an assertion, but we can't use the container here,
diff --git a/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php b/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php
index 0030b64b08c8a4085653884f3af250c5fff0dd07..981676fe0c2a022240d98d9f8fe34eda1265f208 100644
--- a/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/PendingRevisionTest.php
@@ -121,6 +121,9 @@ public function testTaxonomyIndexWithPendingRevision(): void {
     $this->assertEquals($term->id(), $taxonomy_index[$node->id()]->tid);
   }
 
+  /**
+   * Retrieves the taxonomy index from the database.
+   */
   protected function getTaxonomyIndex() {
     return \Drupal::database()->select('taxonomy_index')
       ->fields('taxonomy_index')
diff --git a/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyDefaultArgumentTest.php b/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyDefaultArgumentTest.php
index eea33c764b12c282eaa5f4e38ebfd36820d3716d..afa6fda05c394d27fa99d2e917a2c2fb638a77d8 100644
--- a/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyDefaultArgumentTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/Views/TaxonomyDefaultArgumentTest.php
@@ -65,6 +65,9 @@ public function testNodePath(): void {
     $view->destroy();
   }
 
+  /**
+   * Tests the entity reference field using a view for selection.
+   */
   public function testNodePathWithViewSelection(): void {
     // Change the term entity reference field to use a view as selection plugin.
     \Drupal::service('module_installer')->install(['entity_reference_test']);
@@ -87,6 +90,9 @@ public function testNodePathWithViewSelection(): void {
     $this->assertEquals($this->nodes[0]->getCacheTags(), $view->argument['tid']->getPlugin('argument_default')->getCacheTags());
   }
 
+  /**
+   * Tests the behavior of term ID argument when accessing a term path.
+   */
   public function testTermPath(): void {
     $view = $this->initViewWithRequest($this->term1->toUrl()->toString());
 
diff --git a/core/modules/toolbar/src/Controller/ToolbarController.php b/core/modules/toolbar/src/Controller/ToolbarController.php
index 687366fd925f2b15bf3457e3958b3c2956d46637..8d25465ffd083ced9e2e8230e717a373e34e682d 100644
--- a/core/modules/toolbar/src/Controller/ToolbarController.php
+++ b/core/modules/toolbar/src/Controller/ToolbarController.php
@@ -99,7 +99,9 @@ public static function preRenderAdministrationTray(array $element) {
   }
 
   /**
-   * #pre_render callback for toolbar_get_rendered_subtrees().
+   * Render API callback: Prepares the subtrees.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * @internal
    */
diff --git a/core/modules/update/src/Form/UpdateManagerUpdate.php b/core/modules/update/src/Form/UpdateManagerUpdate.php
deleted file mode 100644
index 6fb59d6cce490046e86fbbe81169ba282265ae62..0000000000000000000000000000000000000000
--- a/core/modules/update/src/Form/UpdateManagerUpdate.php
+++ /dev/null
@@ -1,395 +0,0 @@
-<?php
-
-namespace Drupal\update\Form;
-
-use Drupal\Core\Batch\BatchBuilder;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Link;
-use Drupal\Core\State\StateInterface;
-use Drupal\Core\Url;
-use Drupal\Core\Extension\ExtensionVersion;
-use Drupal\update\ProjectRelease;
-use Drupal\update\UpdateFetcherInterface;
-use Drupal\update\UpdateManagerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Configure update settings for this site.
- *
- * @internal
- */
-class UpdateManagerUpdate extends FormBase {
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The Drupal state storage service.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * Constructs a new UpdateManagerUpdate object.
-   *
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state service.
-   */
-  public function __construct(ModuleHandlerInterface $module_handler, StateInterface $state) {
-    $this->moduleHandler = $module_handler;
-    $this->state = $state;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'update_manager_update_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('module_handler'),
-      $container->get('state')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $this->moduleHandler->loadInclude('update', 'inc', 'update.manager');
-
-    $form['last_check'] = [
-      '#theme' => 'update_last_check',
-      '#last' => $this->state->get('update.last_check', 0),
-    ];
-
-    if (!_update_manager_check_backends($form, 'update')) {
-      return $form;
-    }
-
-    $available = update_get_available(TRUE);
-    if (empty($available)) {
-      $form['message'] = [
-        '#markup' => $this->t('There was a problem getting update information. Try again later.'),
-      ];
-      return $form;
-    }
-
-    $form['#attached']['library'][] = 'update/drupal.update.admin';
-
-    // This will be a nested array. The first key is the kind of project, which
-    // can be either 'installed', 'uninstalled', 'manual' (projects which
-    // require manual updates, such as core). Then, each subarray is an array of
-    // projects of that type, indexed by project short name, and containing an
-    // array of data for cells in that project's row in the appropriate table.
-    $projects = [];
-
-    // This stores the actual download link we're going to update from for each
-    // project in the form, regardless of if it's installed or uninstalled.
-    $form['project_downloads'] = ['#tree' => TRUE];
-    $this->moduleHandler->loadInclude('update', 'inc', 'update.compare');
-    $project_data = update_calculate_project_data($available);
-
-    $fetch_failed = FALSE;
-    foreach ($project_data as $name => $project) {
-      if ($project['status'] === UpdateFetcherInterface::NOT_FETCHED) {
-        $fetch_failed = TRUE;
-      }
-
-      // Filter out projects which are up to date already.
-      if ($project['status'] == UpdateManagerInterface::CURRENT) {
-        continue;
-      }
-      // The project name to display can vary based on the info we have.
-      if (!empty($project['title'])) {
-        if (!empty($project['link'])) {
-          $project_name = Link::fromTextAndUrl($project['title'], Url::fromUri($project['link']))->toString();
-        }
-        else {
-          $project_name = $project['title'];
-        }
-      }
-      elseif (!empty($project['info']['name'])) {
-        $project_name = $project['info']['name'];
-      }
-      else {
-        $project_name = $name;
-      }
-      if ($project['project_type'] == 'theme' || $project['project_type'] == 'theme-uninstalled') {
-        $project_name .= ' ' . $this->t('(Theme)');
-      }
-
-      if (empty($project['recommended'])) {
-        // If we don't know what to recommend they upgrade to, we should skip
-        // the project entirely.
-        continue;
-      }
-
-      $recommended_release = ProjectRelease::createFromArray($project['releases'][$project['recommended']]);
-      $recommended_version = '{{ release_version }} (<a href="{{ release_link }}" title="{{ project_title }}">{{ release_notes }}</a>)';
-      $recommended_version_parser = ExtensionVersion::createFromVersionString($recommended_release->getVersion());
-      if ($recommended_version_parser->getMajorVersion() != $project['existing_major']) {
-        $recommended_version .= '<div title="{{ major_update_warning_title }}" class="update-major-version-warning">{{ major_update_warning_text }}</div>';
-      }
-
-      $recommended_version = [
-        '#type' => 'inline_template',
-        '#template' => $recommended_version,
-        '#context' => [
-          'release_version' => $recommended_release->getVersion(),
-          'release_link' => $recommended_release->getReleaseUrl(),
-          'project_title' => $this->t('Release notes for @project_title', ['@project_title' => $project['title']]),
-          'major_update_warning_title' => $this->t('Major upgrade warning'),
-          'major_update_warning_text' => $this->t('This update is a major version update which means that it may not be backwards compatible with your currently running version. It is recommended that you read the release notes and proceed at your own risk.'),
-          'release_notes' => $this->t('Release notes'),
-        ],
-      ];
-
-      // Create an entry for this project.
-      $entry = [
-        'title' => $project_name,
-        'installed_version' => $project['existing_version'],
-        'recommended_version' => ['data' => $recommended_version],
-      ];
-
-      switch ($project['status']) {
-        case UpdateManagerInterface::NOT_SECURE:
-        case UpdateManagerInterface::REVOKED:
-          $entry['title'] .= ' ' . $this->t('(Security update)');
-          $entry['#weight'] = -2;
-          $type = 'security';
-          break;
-
-        case UpdateManagerInterface::NOT_SUPPORTED:
-          $type = 'unsupported';
-          $entry['title'] .= ' ' . $this->t('(Unsupported)');
-          $entry['#weight'] = -1;
-          break;
-
-        case UpdateFetcherInterface::UNKNOWN:
-        case UpdateFetcherInterface::NOT_FETCHED:
-        case UpdateFetcherInterface::NOT_CHECKED:
-        case UpdateManagerInterface::NOT_CURRENT:
-          $type = 'recommended';
-          break;
-
-        default:
-          // Jump out of the switch and onto the next project in foreach.
-          continue 2;
-      }
-
-      // Use the project title for the tableselect checkboxes.
-      $entry['title'] = [
-        'data' => [
-          '#title' => $entry['title'],
-          '#markup' => $entry['title'],
-        ],
-      ];
-      $entry['#attributes'] = ['class' => ['update-' . $type]];
-
-      // Drupal core needs to be upgraded manually.
-      $needs_manual = $project['project_type'] == 'core';
-
-      // If the recommended release for a contributed project is not compatible
-      // with the currently installed version of core, list that project in a
-      // separate table. If core compatibility is not defined, it means we can't
-      // determine compatibility requirements (or we're looking at core), so we
-      // assume it is compatible.
-      $compatible = $recommended_release->isCoreCompatible() ?? TRUE;
-
-      if ($needs_manual) {
-        $this->removeCheckboxFromRow($entry);
-        $projects['manual'][$name] = $entry;
-      }
-      elseif (!$compatible) {
-        $this->removeCheckboxFromRow($entry);
-        // If the release has a core_compatibility_message, inject it.
-        if ($core_compatibility_message = $recommended_release->getCoreCompatibilityMessage()) {
-          // @todo In https://www.drupal.org/project/drupal/issues/3121769
-          //   refactor this into something theme-friendly so we don't have a
-          //   classless <div> here.
-          $entry['data']['recommended_version']['data']['#template'] .= ' <div>{{ core_compatibility_message }}</div>';
-          $entry['data']['recommended_version']['data']['#context']['core_compatibility_message'] = $core_compatibility_message;
-        }
-        $projects['not-compatible'][$name] = $entry;
-      }
-      else {
-        $form['project_downloads'][$name] = [
-          '#type' => 'value',
-          '#value' => $recommended_release->getDownloadUrl(),
-        ];
-
-        // Based on what kind of project this is, save the entry into the
-        // appropriate subarray.
-        switch ($project['project_type']) {
-          case 'module':
-          case 'theme':
-            $projects['installed'][$name] = $entry;
-            break;
-
-          case 'module-uninstalled':
-          case 'theme-uninstalled':
-            $projects['uninstalled'][$name] = $entry;
-            break;
-        }
-      }
-    }
-
-    if ($fetch_failed) {
-      $message = ['#theme' => 'update_fetch_error_message'];
-      $this->messenger()->addError(\Drupal::service('renderer')->renderInIsolation($message));
-    }
-
-    if (empty($projects)) {
-      $form['message'] = [
-        '#markup' => $this->t('All of your projects are up to date.'),
-      ];
-      return $form;
-    }
-
-    $headers = [
-      'title' => [
-        'data' => $this->t('Name'),
-        'class' => ['update-project-name'],
-      ],
-      'installed_version' => $this->t('Site version'),
-      'recommended_version' => $this->t('Recommended version'),
-    ];
-
-    if (!empty($projects['installed'])) {
-      $form['projects'] = [
-        '#type' => 'tableselect',
-        '#header' => $headers,
-        '#options' => $projects['installed'],
-      ];
-      if (!empty($projects['uninstalled'])) {
-        $form['projects']['#prefix'] = '<h2>' . $this->t('Installed') . '</h2>';
-      }
-    }
-
-    if (!empty($projects['uninstalled'])) {
-      $form['uninstalled_projects'] = [
-        '#type' => 'tableselect',
-        '#header' => $headers,
-        '#options' => $projects['uninstalled'],
-        '#weight' => 1,
-        '#prefix' => '<h2>' . $this->t('Uninstalled') . '</h2>',
-      ];
-    }
-
-    // If either table has been printed yet, we need a submit button and to
-    // validate the checkboxes.
-    if (!empty($projects['installed']) || !empty($projects['uninstalled'])) {
-      $form['actions'] = ['#type' => 'actions'];
-      $form['actions']['submit'] = [
-        '#type' => 'submit',
-        '#value' => $this->t('Download these updates'),
-      ];
-    }
-
-    if (!empty($projects['manual'])) {
-      $prefix = '<h2>' . $this->t('Manual updates required') . '</h2>';
-      $prefix .= '<p>' . $this->t('Automatic updates of Drupal core are not supported at this time.') . '</p>';
-      $form['manual_updates'] = [
-        '#type' => 'table',
-        '#header' => $headers,
-        '#rows' => $projects['manual'],
-        '#prefix' => $prefix,
-        '#weight' => 120,
-      ];
-    }
-
-    if (!empty($projects['not-compatible'])) {
-      $form['not_compatible'] = [
-        '#type' => 'table',
-        '#header' => $headers,
-        '#rows' => $projects['not-compatible'],
-        '#prefix' => '<h2>' . $this->t('Not compatible') . '</h2>',
-        '#weight' => 150,
-      ];
-    }
-
-    return $form;
-  }
-
-  /**
-   * Prepares a row entry for use in a regular table, not a 'tableselect'.
-   *
-   * There are no checkboxes in the 'Manual updates' or 'Not compatible' tables,
-   * so they will be rendered by '#theme' => 'table', not 'tableselect'. Since
-   * the data formats are incompatible, this method converts to the format
-   * expected by '#theme' => 'table'. Generally, rows end up in the main tables
-   * that have a checkbox to allow the site admin to select which missing
-   * updates to install. This method is only used for the special case tables
-   * that have no such checkbox.
-   *
-   * @todo In https://www.drupal.org/project/drupal/issues/3121775 refactor
-   *   self::buildForm() so that we don't need this method at all.
-   *
-   * @param array[] $row
-   *   The render array for a table row.
-   */
-  protected function removeCheckboxFromRow(array &$row) {
-    unset($row['#weight']);
-    $attributes = $row['#attributes'];
-    unset($row['#attributes']);
-    $row = [
-      'data' => $row,
-    ] + $attributes;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    if (!$form_state->isValueEmpty('projects')) {
-      $installed = array_filter($form_state->getValue('projects'));
-    }
-    if (!$form_state->isValueEmpty('uninstalled_projects')) {
-      $uninstalled = array_filter($form_state->getValue('uninstalled_projects'));
-    }
-    if (empty($installed) && empty($uninstalled)) {
-      $form_state->setErrorByName('projects', $this->t('You must select at least one project to update.'));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $this->moduleHandler->loadInclude('update', 'inc', 'update.manager');
-    $projects = [];
-    foreach (['projects', 'uninstalled_projects'] as $type) {
-      if (!$form_state->isValueEmpty($type)) {
-        $projects = array_merge($projects, array_keys(array_filter($form_state->getValue($type))));
-      }
-    }
-    $batch_builder = (new BatchBuilder())
-      ->setFile($this->moduleHandler->getModule('update')->getPath() . '/update.manager.inc')
-      ->setTitle($this->t('Downloading updates'))
-      ->setInitMessage($this->t('Preparing to download selected updates'))
-      ->setFinishCallback('update_manager_download_batch_finished');
-    foreach ($projects as $project) {
-      $batch_builder->addOperation('update_manager_batch_project_get', [
-        $project,
-        $form_state->getValue(['project_downloads', $project]),
-      ]);
-    }
-    batch_set($batch_builder->toArray());
-  }
-
-}
diff --git a/core/modules/update/src/Form/UpdateReady.php b/core/modules/update/src/Form/UpdateReady.php
deleted file mode 100644
index 779ad5b5a1129dd9d86090ad600df5e3e4f85182..0000000000000000000000000000000000000000
--- a/core/modules/update/src/Form/UpdateReady.php
+++ /dev/null
@@ -1,174 +0,0 @@
-<?php
-
-namespace Drupal\update\Form;
-
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\FileTransfer\Local;
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\State\StateInterface;
-use Drupal\Core\Updater\Updater;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Response;
-
-/**
- * Configure update settings for this site.
- *
- * @internal
- */
-class UpdateReady extends FormBase {
-
-  /**
-   * The root location under which updated projects will be saved.
-   *
-   * @var string
-   */
-  protected $root;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The state key value store.
-   *
-   * @var \Drupal\Core\State\StateInterface
-   */
-  protected $state;
-
-  /**
-   * The Site path.
-   *
-   * @var string
-   */
-  protected $sitePath;
-
-  /**
-   * Constructs a new UpdateReady object.
-   *
-   * @param string $root
-   *   The root location under which updated projects will be saved.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The object that manages installed modules in a Drupal installation.
-   * @param \Drupal\Core\State\StateInterface $state
-   *   The state key value store.
-   * @param string $site_path
-   *   The site path.
-   */
-  public function __construct($root, ModuleHandlerInterface $module_handler, StateInterface $state, $site_path) {
-    $this->root = $root;
-    $this->moduleHandler = $module_handler;
-    $this->state = $state;
-    $this->sitePath = $site_path;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'update_manager_update_ready_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('update.root'),
-      $container->get('module_handler'),
-      $container->get('state'),
-      $container->getParameter('site.path')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $this->moduleHandler->loadInclude('update', 'inc', 'update.manager');
-    if (!_update_manager_check_backends($form, 'update')) {
-      return $form;
-    }
-
-    $form['backup'] = [
-      '#prefix' => '<strong>',
-      '#markup' => $this->t('Back up your database and site before you continue. <a href=":backup_url">Learn how</a>.', [':backup_url' => 'https://www.drupal.org/node/22281']),
-      '#suffix' => '</strong>',
-    ];
-
-    $form['maintenance_mode'] = [
-      '#title' => $this->t('Perform updates with site in maintenance mode (strongly recommended)'),
-      '#type' => 'checkbox',
-      '#default_value' => TRUE,
-    ];
-
-    $form['actions'] = ['#type' => 'actions'];
-    $form['actions']['submit'] = [
-      '#type' => 'submit',
-      '#value' => $this->t('Continue'),
-    ];
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    $session = $this->getRequest()->getSession();
-    // Store maintenance_mode setting so we can restore it when done.
-    $session->set('maintenance_mode', $this->state->get('system.maintenance_mode'));
-    if ($form_state->getValue('maintenance_mode') == TRUE) {
-      $this->state->set('system.maintenance_mode', TRUE);
-    }
-
-    $projects = $session->remove('update_manager_update_projects');
-    if ($projects) {
-      // Make sure the Updater registry is loaded.
-      drupal_get_updaters();
-
-      $updates = [];
-      $directory = _update_manager_extract_directory();
-
-      $project_real_location = NULL;
-      foreach ($projects as $project => $url) {
-        $project_location = $directory . '/' . $project;
-        $updater = Updater::factory($project_location, $this->root);
-        $project_real_location = \Drupal::service('file_system')->realpath($project_location);
-        $updates[] = [
-          'project' => $project,
-          'updater_name' => get_class($updater),
-          'local_url' => $project_real_location,
-        ];
-      }
-
-      // If the owner of the last directory we extracted is the same as the
-      // owner of our configuration directory (e.g. sites/default) where we're
-      // trying to install the code, there's no need to prompt for FTP/SSH
-      // credentials. Instead, we instantiate a Drupal\Core\FileTransfer\Local
-      // and invoke update_authorize_run_update() directly.
-      if (fileowner($project_real_location) == fileowner($this->sitePath)) {
-        $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize');
-        $filetransfer = new Local($this->root, \Drupal::service('file_system'));
-        $response = update_authorize_run_update($filetransfer, $updates);
-        if ($response instanceof Response) {
-          $form_state->setResponse($response);
-        }
-      }
-      // Otherwise, go through the regular workflow to prompt for FTP/SSH
-      // credentials and invoke update_authorize_run_update() indirectly with
-      // whatever FileTransfer object authorize.php creates for us.
-      else {
-        // The page title must be passed here to ensure it is initially used
-        // when authorize.php loads for the first time with the FTP/SSH
-        // credentials form.
-        system_authorized_init('update_authorize_run_update', __DIR__ . '/../../update.authorize.inc', [$updates], $this->t('Update manager'));
-        $form_state->setRedirectUrl(system_authorized_get_url());
-      }
-    }
-  }
-
-}
diff --git a/core/modules/update/src/Hook/UpdateHooks.php b/core/modules/update/src/Hook/UpdateHooks.php
index 85c19a5708ccfe802dc9a9470f5a78660b5b714c..c973db7b95f07a0b611bcbc9061a80b49469fd8c 100644
--- a/core/modules/update/src/Hook/UpdateHooks.php
+++ b/core/modules/update/src/Hook/UpdateHooks.php
@@ -28,10 +28,6 @@ public function help($route_name, RouteMatchInterface $route_match): ?string {
           ':update' => 'https://www.drupal.org/documentation/modules/update',
           ':modules' => Url::fromRoute('system.modules_list')->toString(),
         ]) . '</p>';
-        // Only explain the Update manager if it has not been uninstalled.
-        if (_update_manager_access()) {
-          $output .= '<p>' . $this->t('The Update Manager also allows administrators to add and update modules and themes through the administration interface.') . '</p>';
-        }
         $output .= '<h2>' . $this->t('Uses') . '</h2>';
         $output .= '<dl>';
         $output .= '<dt>' . $this->t('Checking for available updates') . '</dt>';
@@ -39,15 +35,6 @@ public function help($route_name, RouteMatchInterface $route_match): ?string {
           ':update-report' => Url::fromRoute('update.status')->toString(),
           ':update-settings' => Url::fromRoute('update.settings')->toString(),
         ]) . '</dd>';
-        // Only explain the Update manager if it has not been uninstalled.
-        if (_update_manager_access()) {
-          $output .= '<dt>' . $this->t('Performing updates through the Update page') . '</dt>';
-          $output .= '<dd>' . $this->t('The Update Manager module allows administrators to perform updates directly from the <a href=":update-page">Update page</a>. It lists all available updates, and you can confirm whether you want to download them. If you don\'t have sufficient access rights to your web server, you could be prompted for your FTP/SSH password. Afterwards the files are transferred into your site installation, overwriting your old files. Direct links to the Update page are also displayed on the <a href=":modules_page">Extend page</a> and the <a href=":themes_page">Appearance page</a>.', [
-            ':modules_page' => Url::fromRoute('system.modules_list')->toString(),
-            ':themes_page' => Url::fromRoute('system.themes_page')->toString(),
-            ':update-page' => Url::fromRoute('update.report_update')->toString(),
-          ]) . '</dd>';
-        }
         $output .= '</dl>';
         return $output;
 
@@ -75,14 +62,10 @@ public function pageTop(): void {
       $route_name = \Drupal::routeMatch()->getRouteName();
       switch ($route_name) {
         // These pages don't need additional nagging.
-        case 'update.theme_update':
-        case 'update.module_update':
         case 'update.status':
-        case 'update.report_update':
         case 'update.settings':
         case 'system.status':
         case 'system.theme_install':
-        case 'update.confirmation_page':
         case 'system.batch_page.html':
           return;
 
@@ -266,9 +249,6 @@ public function mail($key, &$message, $params): void {
       $message['body'][] = _update_message_text($msg_type, $msg_reason, $langcode);
     }
     $message['body'][] = $this->t('See the available updates page for more information:', [], ['langcode' => $langcode]) . "\n" . Url::fromRoute('update.status', [], ['absolute' => TRUE, 'language' => $language])->toString();
-    if (_update_manager_access()) {
-      $message['body'][] = $this->t('You can automatically download your missing updates using the Update manager:', [], ['langcode' => $langcode]) . "\n" . Url::fromRoute('update.report_update', [], ['absolute' => TRUE, 'language' => $language])->toString();
-    }
     $settings_url = Url::fromRoute('update.settings', [], ['absolute' => TRUE])->toString();
     if (\Drupal::config('update.settings')->get('notification.threshold') == 'all') {
       $message['body'][] = $this->t('Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, @url.', ['@url' => $settings_url]);
diff --git a/core/modules/update/src/Routing/UpdateRouteSubscriber.php b/core/modules/update/src/Routing/UpdateRouteSubscriber.php
deleted file mode 100644
index 57ff5f456116fea1f1b7312c2116cf976fbab708..0000000000000000000000000000000000000000
--- a/core/modules/update/src/Routing/UpdateRouteSubscriber.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\update\Routing;
-
-use Drupal\Core\Routing\RouteSubscriberBase;
-use Drupal\Core\Site\Settings;
-use Symfony\Component\Routing\RouteCollection;
-
-/**
- * Route subscriber for Update module routes.
- */
-class UpdateRouteSubscriber extends RouteSubscriberBase {
-
-  /**
-   * Constructs a new UpdateRouteSubscriber.
-   */
-  public function __construct(
-    protected Settings $settings,
-  ) {
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function alterRoutes(RouteCollection $collection) {
-    if ($this->settings->get('allow_authorize_operations', TRUE)) {
-      return;
-    }
-    $routes = [
-      'update.report_update',
-      'update.module_update',
-      'update.theme_update',
-      'update.confirmation_page',
-    ];
-    foreach ($routes as $route) {
-      $route = $collection->get($route);
-      $route->setRequirement('_access', 'FALSE');
-    }
-  }
-
-}
diff --git a/core/modules/update/src/UpdateManager.php b/core/modules/update/src/UpdateManager.php
index 06372fec3f5a7e436a5e5ee94eb35ce981a71576..3f46715b4ee6bba66dd6c1d98ef427ee465d98b2 100644
--- a/core/modules/update/src/UpdateManager.php
+++ b/core/modules/update/src/UpdateManager.php
@@ -178,16 +178,12 @@ public function projectStorage($key) {
     // On certain paths, we should clear the data and recompute the projects for
     // update status of the site to avoid presenting stale information.
     $route_names = [
-      'update.theme_update',
       'system.modules_list',
       'system.theme_install',
-      'update.module_update',
       'update.status',
-      'update.report_update',
       'update.settings',
       'system.status',
       'update.manual_status',
-      'update.confirmation_page',
       'system.themes_page',
     ];
     if (in_array(\Drupal::routeMatch()->getRouteName(), $route_names)) {
diff --git a/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_1.xml b/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_1.xml
deleted file mode 100644
index f442cd0fac180768f9d5ee3a0bb7411a9cc468da..0000000000000000000000000000000000000000
--- a/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_1.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-This fixture is used by Drupal\Tests\update\Functional\UpdateManagerUpdateTest.
-
-It contains 2 releases, 8.x-1.0 (which is the currently installed version) and
-8.x-1.1, which is the only available update.
-
-To ensure we've got test coverage for the case where the '<core_compatibility>'
-tag is not defined at all, this fixture does not include that value.
--->
-<project xmlns:dc="http://purl.org/dc/elements/1.1/">
-<title>BBB Update test</title>
-<short_name>bbb_update_test</short_name>
-<dc:creator>Drupal</dc:creator>
-<supported_branches>8.x-1.</supported_branches>
-<project_status>published</project_status>
-<link>http://example.com/project/bbb_update_test</link>
-  <terms>
-   <term><name>Projects</name><value>Modules</value></term>
-  </terms>
-<releases>
- <release>
-  <name>bbb_update_test 8.x-1.1</name>
-  <version>8.x-1.1</version>
-  <status>published</status>
-  <release_link>http://example.com/bbb_update_test-8-x-1-1-release</release_link>
-  <download_link>http://example.com/bbb_update_test-8.x-1.1.tar.gz</download_link>
-  <date>1250444521</date>
-  <terms>
-   <term><name>Release type</name><value>Bug fixes</value></term>
-  </terms>
- </release>
- <release>
-  <name>bbb_update_test 8.x-1.0</name>
-  <version>8.x-1.0</version>
-  <status>published</status>
-  <release_link>http://example.com/bbb_update_test-8-x-1-0-release</release_link>
-  <download_link>http://example.com/bbb_update_test-8.x-1.0.tar.gz</download_link>
-  <date>1250424521</date>
-  <terms>
-   <term><name>Release type</name><value>New features</value></term>
-   <term><name>Release type</name><value>Bug fixes</value></term>
-  </terms>
- </release>
-</releases>
-</project>
diff --git a/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_2.xml b/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_2.xml
deleted file mode 100644
index ea9c0ebb9509199c588b8f964138faeb9ffd0b5c..0000000000000000000000000000000000000000
--- a/core/modules/update/tests/fixtures/release-history/bbb_update_test.1_2.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-This fixture is used by Drupal\Tests\update\Functional\UpdateManagerUpdateTest.
-
-It contains 3 releases:
-- 8.x-1.0: The currently installed version in the test scenarios.
-- 8.x-1.1: An available update that does not specify '<core_compatibility>'.
-- 8.x-1.2: An available update that uses '<core_compatibility>' to require at
-    least Drupal core version 8.1.0. Since the currently installed Drupal core
-    for the tests is 8.0.0, this release will be flagged as 'Not compatible'.
--->
-<project xmlns:dc="http://purl.org/dc/elements/1.1/">
-<title>BBB Update test</title>
-<short_name>bbb_update_test</short_name>
-<dc:creator>Drupal</dc:creator>
-<supported_branches>8.x-1.</supported_branches>
-<project_status>published</project_status>
-<link>http://example.com/project/bbb_update_test</link>
-  <terms>
-   <term><name>Projects</name><value>Modules</value></term>
-  </terms>
-<releases>
- <release>
-  <name>bbb_update_test 8.x-1.2</name>
-  <version>8.x-1.2</version>
-  <core_compatibility>^8.1.0</core_compatibility>
-  <status>published</status>
-  <release_link>http://example.com/bbb_update_test-8-x-1-2-release</release_link>
-  <download_link>http://example.com/bbb_update_test-8.x-1.2.tar.gz</download_link>
-  <date>1250445521</date>
-  <terms>
-   <term><name>Release type</name><value>Bug fixes</value></term>
-  </terms>
- </release>
- <release>
-  <name>bbb_update_test 8.x-1.1</name>
-  <version>8.x-1.1</version>
-  <status>published</status>
-  <release_link>http://example.com/bbb_update_test-8-x-1-1-release</release_link>
-  <download_link>http://example.com/bbb_update_test-8.x-1.1.tar.gz</download_link>
-  <date>1250444521</date>
-  <terms>
-   <term><name>Release type</name><value>Bug fixes</value></term>
-  </terms>
- </release>
- <release>
-  <name>bbb_update_test 8.x-1.0</name>
-  <version>8.x-1.0</version>
-  <status>published</status>
-  <release_link>http://example.com/bbb_update_test-8-x-1-0-release</release_link>
-  <download_link>http://example.com/bbb_update_test-8.x-1.0.tar.gz</download_link>
-  <date>1250424521</date>
-  <terms>
-   <term><name>Release type</name><value>New features</value></term>
-   <term><name>Release type</name><value>Bug fixes</value></term>
-  </terms>
- </release>
-</releases>
-</project>
diff --git a/core/modules/update/tests/src/Functional/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php
index dd64cda629231e69c3184bd9088db3fef1290dc7..be3b512e00db1bddba70205bd59eb31a85c95151 100644
--- a/core/modules/update/tests/src/Functional/UpdateContribTest.php
+++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php
@@ -538,12 +538,12 @@ public function testHookUpdateStatusAlter(): void {
 
     // Turn the altering back on and visit the Update manager UI.
     $update_test_config->set('update_status', $update_status)->save();
-    $this->drupalGet('admin/modules/update');
+    $this->drupalGet('admin/reports/updates');
     $this->assertSession()->pageTextContains('Security update');
 
     // Turn the altering back off and visit the Update manager UI.
     $update_test_config->set('update_status', [])->save();
-    $this->drupalGet('admin/modules/update');
+    $this->drupalGet('admin/reports/updates');
     $this->assertSession()->pageTextNotContains('Security update');
   }
 
diff --git a/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php b/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php
deleted file mode 100644
index c5f89a7b1b067a50d84f334e88bb1749599a4dee..0000000000000000000000000000000000000000
--- a/core/modules/update/tests/src/Functional/UpdateManagerUpdateTest.php
+++ /dev/null
@@ -1,317 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\Tests\update\Functional;
-
-/**
- * Tests the Update Manager module's 'Update' form and functionality.
- *
- * @todo In https://www.drupal.org/project/drupal/issues/3117229 expand this.
- *
- * @group update
- */
-class UpdateManagerUpdateTest extends UpdateTestBase {
-  use UpdateTestTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = [
-    'aaa_update_test',
-    'bbb_update_test',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-    $admin_user = $this->drupalCreateUser([
-      'administer software updates',
-      'administer site configuration',
-    ]);
-    $this->drupalLogin($admin_user);
-
-    // The installed state of the system is the same for all test cases. What
-    // varies for each test scenario is which release history fixture we fetch,
-    // which in turn changes the expected state of the UpdateManagerUpdateForm.
-    $this->mockInstalledExtensionsInfo([
-      'aaa_update_test' => [
-        'project' => 'aaa_update_test',
-        'version' => '8.x-1.0',
-        'hidden' => FALSE,
-      ],
-      'bbb_update_test' => [
-        'project' => 'bbb_update_test',
-        'version' => '8.x-1.0',
-        'hidden' => FALSE,
-      ],
-      'ccc_update_test' => [
-        'project' => 'ccc_update_test',
-        'version' => '8.x-1.0',
-        'hidden' => FALSE,
-      ],
-    ]);
-    $this->mockDefaultExtensionsInfo(['version' => '8.0.0']);
-  }
-
-  /**
-   * Provides data for test scenarios involving incompatible updates.
-   *
-   * These test cases rely on the following fixtures containing the following
-   * releases:
-   * - aaa_update_test.8.x-1.2.xml
-   *   - 8.x-1.2 Compatible with 8.0.0 core.
-   * - aaa_update_test.core_compatibility.8.x-1.2_8.x-2.2.xml
-   *   - 8.x-1.2 Requires 8.1.0 and above.
-   * - bbb_update_test.1_0.xml
-   *   - 8.x-1.0 is the only available release.
-   * - bbb_update_test.1_1.xml
-   *   - 8.x-1.1 is available and compatible with everything (does not define
-   *     <core_compatibility> at all).
-   * - bbb_update_test.1_2.xml
-   *   - 8.x-1.1 is available and compatible with everything (does not define
-   *     <core_compatibility> at all).
-   *   - 8.x-1.2 is available and requires Drupal 8.1.0 and above.
-   *
-   * @return array[]
-   *   Test data.
-   */
-  public static function incompatibleUpdatesTableProvider() {
-    return [
-      'only one compatible' => [
-        'core_fixture' => '8.1.1',
-        // aaa_update_test.8.x-1.2.xml has core compatibility set and will test
-        // the case where $recommended_release['core_compatible'] === TRUE in
-        // \Drupal\update\Form\UpdateManagerUpdate.
-        'a_fixture' => '8.x-1.2',
-        // Use a fixture with only a 8.x-1.0 release so BBB is up to date.
-        'b_fixture' => '1_0',
-        'compatible' => [
-          'AAA' => '8.x-1.2',
-        ],
-        'incompatible' => [],
-      ],
-      'only one incompatible' => [
-        'core_fixture' => '8.1.1',
-        'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
-        // Use a fixture with only a 8.x-1.0 release so BBB is up to date.
-        'b_fixture' => '1_0',
-        'compatible' => [],
-        'incompatible' => [
-          'AAA' => [
-            'recommended' => '8.x-1.2',
-            'range' => '8.1.0 to 8.1.1',
-          ],
-        ],
-      ],
-      'two compatible, no incompatible' => [
-        'core_fixture' => '8.1.1',
-        'a_fixture' => '8.x-1.2',
-        // bbb_update_test.1_1.xml does not have core compatibility set and will
-        // test the case where $recommended_release['core_compatible'] === NULL
-        // in \Drupal\update\Form\UpdateManagerUpdate.
-        'b_fixture' => '1_1',
-        'compatible' => [
-          'AAA' => '8.x-1.2',
-          'BBB' => '8.x-1.1',
-        ],
-        'incompatible' => [],
-      ],
-      'two incompatible, no compatible' => [
-        'core_fixture' => '8.1.1',
-        'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
-        // bbb_update_test.1_2.xml has core compatibility set and will test the
-        // case where $recommended_release['core_compatible'] === FALSE in
-        // \Drupal\update\Form\UpdateManagerUpdate.
-        'b_fixture' => '1_2',
-        'compatible' => [],
-        'incompatible' => [
-          'AAA' => [
-            'recommended' => '8.x-1.2',
-            'range' => '8.1.0 to 8.1.1',
-          ],
-          'BBB' => [
-            'recommended' => '8.x-1.2',
-            'range' => '8.1.0 to 8.1.1',
-          ],
-        ],
-      ],
-      'one compatible, one incompatible' => [
-        'core_fixture' => '8.1.1',
-        'a_fixture' => 'core_compatibility.8.x-1.2_8.x-2.2',
-        'b_fixture' => '1_1',
-        'compatible' => [
-          'BBB' => '8.x-1.1',
-        ],
-        'incompatible' => [
-          'AAA' => [
-            'recommended' => '8.x-1.2',
-            'range' => '8.1.0 to 8.1.1',
-          ],
-        ],
-      ],
-    ];
-  }
-
-  /**
-   * Tests the Update form for a single test scenario of incompatible updates.
-   *
-   * @param string $core_fixture
-   *   The fixture file to use for Drupal core.
-   * @param string $a_fixture
-   *   The fixture file to use for the aaa_update_test module.
-   * @param string $b_fixture
-   *   The fixture file to use for the bbb_update_test module.
-   * @param string[] $compatible
-   *   Compatible recommended updates (if any). Keys are module identifier
-   *   ('AAA' or 'BBB') and values are the expected recommended release.
-   * @param string[][] $incompatible
-   *   Incompatible recommended updates (if any). Keys are module identifier
-   *   ('AAA' or 'BBB') and values are subarrays with the following keys:
-   *   - 'recommended': The recommended version.
-   *   - 'range': The versions of Drupal core required for that version.
-   *
-   * @dataProvider incompatibleUpdatesTableProvider
-   */
-  public function testIncompatibleUpdatesTable($core_fixture, $a_fixture, $b_fixture, array $compatible, array $incompatible): void {
-
-    $assert_session = $this->assertSession();
-    $compatible_table_locator = '[data-drupal-selector="edit-projects"]';
-    $incompatible_table_locator = '[data-drupal-selector="edit-not-compatible"]';
-
-    $this->refreshUpdateStatus(['drupal' => $core_fixture, 'aaa_update_test' => $a_fixture, 'bbb_update_test' => $b_fixture]);
-    $this->drupalGet('admin/reports/updates/update');
-
-    if ($compatible) {
-      // Verify the number of rows in the table.
-      $assert_session->elementsCount('css', "$compatible_table_locator tbody tr", count($compatible));
-      // We never want to see a compatibility range in the compatible table.
-      $assert_session->elementTextNotContains('css', $compatible_table_locator, 'Requires Drupal core');
-      foreach ($compatible as $module => $version) {
-        $compatible_row = "$compatible_table_locator tbody tr:contains('$module Update test')";
-        // First <td> is the checkbox, so start with td #2.
-        $assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(2)", "$module Update test");
-        // Both contrib modules use 8.x-1.0 as the currently installed version.
-        $assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(3)", '8.x-1.0');
-        $assert_session->elementTextContains('css', "$compatible_row td:nth-of-type(4)", $version);
-      }
-    }
-    else {
-      // Verify there is no compatible updates table.
-      $assert_session->elementNotExists('css', $compatible_table_locator);
-    }
-
-    if ($incompatible) {
-      // Verify the number of rows in the table.
-      $assert_session->elementsCount('css', "$incompatible_table_locator tbody tr", count($incompatible));
-      foreach ($incompatible as $module => $data) {
-        $incompatible_row = "$incompatible_table_locator tbody tr:contains('$module Update test')";
-        $assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(1)", "$module Update test");
-        // Both contrib modules use 8.x-1.0 as the currently installed version.
-        $assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(2)", '8.x-1.0');
-        $assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(3)", $data['recommended']);
-        $assert_session->elementTextContains('css', "$incompatible_row td:nth-of-type(3)", 'Requires Drupal core: ' . $data['range']);
-      }
-    }
-    else {
-      // Verify there is no incompatible updates table.
-      $assert_session->elementNotExists('css', $incompatible_table_locator);
-    }
-  }
-
-  /**
-   * Tests the Update form with an uninstalled module in the system.
-   */
-  public function testUninstalledUpdatesTable(): void {
-    $assert_session = $this->assertSession();
-    $compatible_table_locator = '[data-drupal-selector="edit-projects"]';
-    $uninstalled_table_locator = '[data-drupal-selector="edit-uninstalled-projects"]';
-
-    $fixtures = [
-      'drupal' => '8.1.1',
-      'aaa_update_test' => '8.x-1.2',
-      // Use a fixture with only a 8.x-1.0 release so BBB is up to date.
-      'bbb_update_test' => '1_0',
-      // CCC is not installed and is missing an update, 8.x-1.1.
-      'ccc_update_test' => '1_1',
-    ];
-    $this->refreshUpdateStatus($fixtures);
-    $this->drupalGet('admin/reports/updates/update');
-
-    // Confirm there is no table for uninstalled extensions.
-    $assert_session->pageTextNotContains('CCC Update test');
-    $assert_session->responseNotContains('<h2>Uninstalled</h2>');
-
-    // Confirm the table for installed modules exists without a header.
-    $assert_session->responseNotContains('<h2>Installed</h2>');
-    $assert_session->elementNotExists('css', $uninstalled_table_locator);
-    $assert_session->elementsCount('css', "$compatible_table_locator tbody tr", 1);
-    $compatible_headers = [
-      // First column has no header, it's the select-all checkbox.
-      'th:nth-of-type(2)' => 'Name',
-      'th:nth-of-type(3)' => 'Site version',
-      'th:nth-of-type(4)' => 'Recommended version',
-    ];
-    $this->checkTableHeaders($compatible_table_locator, $compatible_headers);
-
-    $installed_row = "$compatible_table_locator tbody tr";
-    $assert_session->elementsCount('css', $installed_row, 1);
-    $assert_session->elementTextContains('css', "$compatible_table_locator td:nth-of-type(2)", "AAA Update test");
-    $assert_session->elementTextContains('css', "$compatible_table_locator td:nth-of-type(3)", '8.x-1.0');
-    $assert_session->elementTextContains('css', "$compatible_table_locator td:nth-of-type(4)", '8.x-1.2');
-
-    // Change the setting so we check for uninstalled modules, too.
-    $this->config('update.settings')
-      ->set('check.disabled_extensions', TRUE)
-      ->save();
-
-    // Reload the page so the new setting goes into effect.
-    $this->drupalGet('admin/reports/updates/update');
-
-    // Confirm the table for installed modules exists with a header.
-    $assert_session->responseContains('<h2>Installed</h2>');
-    $assert_session->elementsCount('css', "$compatible_table_locator tbody tr", 1);
-    $this->checkTableHeaders($compatible_table_locator, $compatible_headers);
-
-    // Confirm the table for uninstalled extensions exists.
-    $assert_session->responseContains('<h2>Uninstalled</h2>');
-    $uninstalled_headers = [
-      // First column has no header, it's the select-all checkbox.
-      'th:nth-of-type(2)' => 'Name',
-      'th:nth-of-type(3)' => 'Site version',
-      'th:nth-of-type(4)' => 'Recommended version',
-    ];
-    $this->checkTableHeaders($uninstalled_table_locator, $uninstalled_headers);
-
-    $uninstalled_row = "$uninstalled_table_locator tbody tr";
-    $assert_session->elementsCount('css', $uninstalled_row, 1);
-    $assert_session->elementTextContains('css', "$uninstalled_row td:nth-of-type(2)", "CCC Update test");
-    $assert_session->elementTextContains('css', "$uninstalled_row td:nth-of-type(3)", '8.x-1.0');
-    $assert_session->elementTextContains('css', "$uninstalled_row td:nth-of-type(4)", '8.x-1.1');
-  }
-
-  /**
-   * Checks headers for a given table on the Update form.
-   *
-   * @param string $table_locator
-   *   CSS locator to find the table to check the headers on.
-   * @param string[] $expected_headers
-   *   Array of expected header texts, keyed by CSS selectors relative to the
-   *   thead tr (for example, "th:nth-of-type(3)").
-   */
-  private function checkTableHeaders($table_locator, array $expected_headers): void {
-    $assert_session = $this->assertSession();
-    $assert_session->elementExists('css', $table_locator);
-    foreach ($expected_headers as $locator => $header) {
-      $assert_session->elementTextContains('css', "$table_locator thead tr $locator", $header);
-    }
-  }
-
-}
diff --git a/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php b/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php
index f70cf012f004664d040692830d9f09bf7b18f908..e1e9b060aed6cfb315767afc96c8af49e4fbd677 100644
--- a/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php
+++ b/core/modules/update/tests/src/Unit/Menu/UpdateLocalTasksTest.php
@@ -28,7 +28,7 @@ protected function setUp(): void {
    */
   public function testUpdateReportLocalTasks($route): void {
     $this->assertLocalTasks($route, [
-      0 => ['update.status', 'update.settings', 'update.report_update'],
+      0 => ['update.status', 'update.settings'],
     ]);
   }
 
@@ -39,47 +39,6 @@ public static function getUpdateReportRoutes() {
     return [
       ['update.status'],
       ['update.settings'],
-      ['update.report_update'],
-    ];
-  }
-
-  /**
-   * Checks update module tasks.
-   *
-   * @dataProvider getUpdateModuleRoutes
-   */
-  public function testUpdateModuleLocalTasks($route): void {
-    $this->assertLocalTasks($route, [
-      0 => ['update.module_update'],
-    ]);
-  }
-
-  /**
-   * Provides a list of module routes to test.
-   */
-  public static function getUpdateModuleRoutes() {
-    return [
-      ['update.module_update'],
-    ];
-  }
-
-  /**
-   * Checks update theme tasks.
-   *
-   * @dataProvider getUpdateThemeRoutes
-   */
-  public function testUpdateThemeLocalTasks($route): void {
-    $this->assertLocalTasks($route, [
-      0 => ['update.theme_update'],
-    ]);
-  }
-
-  /**
-   * Provides a list of theme routes to test.
-   */
-  public static function getUpdateThemeRoutes() {
-    return [
-      ['update.theme_update'],
     ];
   }
 
diff --git a/core/modules/update/tests/src/Unit/UpdateMailTest.php b/core/modules/update/tests/src/Unit/UpdateMailTest.php
index 4481c8badf4ea67cd1ac57887cc245e30f9584be..3908b995c0b8bd60ef0138dfddf78a3cd1e34c48 100644
--- a/core/modules/update/tests/src/Unit/UpdateMailTest.php
+++ b/core/modules/update/tests/src/Unit/UpdateMailTest.php
@@ -120,24 +120,12 @@ public function testUpdateEmail($notification_threshold, $params, $authorized, a
         ['update.settings', $config_notification],
       ]);
 
-    // The calls to generateFromRoute differ if authorized.
-    $count = 2;
-    if ($authorized) {
-      $this->currentUser
-        ->expects($this->once())
-        ->method('hasPermission')
-        ->with('administer software updates')
-        ->willReturn(TRUE);
-      $count = 3;
-    }
-    // When authorized also get the URL for the route 'update.report_update'.
     $this->urlGenerator
-      ->expects($this->exactly($count))
+      ->expects($this->exactly(2))
       ->method('generateFromRoute')
       ->willReturnMap([
         ['update.status', [], ['absolute' => TRUE, 'language' => $langcode], FALSE, $update_settings_url],
         ['update.settings', [], ['absolute' => TRUE], FALSE, $available_updates_url],
-        ['update.report_update', [], ['absolute' => TRUE, 'language' => $langcode], FALSE, $available_updates_url],
       ]);
 
     // Set the container.
@@ -157,8 +145,7 @@ public function testUpdateEmail($notification_threshold, $params, $authorized, a
     // Confirm each part of the body.
     if ($authorized) {
       $this->assertSame($expected_body[0], $message['body'][0]);
-      $this->assertSame($expected_body[1], $message['body'][1]);
-      $this->assertSame($expected_body[2], $message['body'][2]->render());
+      $this->assertSame($expected_body[1], $message['body'][1]->render());
     }
     else {
       if (empty($params)) {
@@ -224,7 +211,6 @@ public static function providerTestUpdateEmail(): array {
         TRUE,
         [
           "See the available updates page for more information:\nhttps://example.com/admin/reports/updates/settings",
-          "You can automatically download your missing updates using the Update manager:\nhttps://example.com/admin/reports/updates",
           'Your site is currently configured to send these emails when any updates are available. To get notified only for security updates, https://example.com/admin/reports/updates.',
         ],
       ],
diff --git a/core/modules/update/update.install b/core/modules/update/update.install
index 454a198c909e3193a69551f37d7f70ec3b7df364..c4f22ef30c25788f0c241a326f00d8b7f5362a35 100644
--- a/core/modules/update/update.install
+++ b/core/modules/update/update.install
@@ -127,12 +127,7 @@ function _update_requirement_check($project, $type) {
     // strings together in a single paragraph.
     $requirement['description'][] = ['#markup' => _update_message_text($type, $status)];
     if (!in_array($status, [UpdateFetcherInterface::UNKNOWN, UpdateFetcherInterface::NOT_CHECKED, UpdateFetcherInterface::NOT_FETCHED, UpdateFetcherInterface::FETCH_PENDING])) {
-      if (_update_manager_access()) {
-        $requirement['description'][] = ['#prefix' => ' ', '#markup' => t('See the <a href=":available_updates">available updates</a> page for more information and to update your software.', [':available_updates' => Url::fromRoute('update.report_update')->toString()])];
-      }
-      else {
-        $requirement['description'][] = ['#prefix' => ' ', '#markup' => t('See the <a href=":available_updates">available updates</a> page for more information.', [':available_updates' => Url::fromRoute('update.status')->toString()])];
-      }
+      $requirement['description'][] = ['#prefix' => ' ', '#markup' => t('See the <a href=":available_updates">available updates</a> page for more information.', [':available_updates' => Url::fromRoute('update.status')->toString()])];
     }
   }
   switch ($status) {
@@ -167,7 +162,7 @@ function _update_requirement_check($project, $type) {
   if ($status != UpdateManagerInterface::CURRENT && $type == 'core' && isset($project['recommended'])) {
     $requirement_label .= ' ' . t('(version @version available)', ['@version' => $project['recommended']]);
   }
-  $requirement['value'] = Link::fromTextAndUrl($requirement_label, Url::fromRoute(_update_manager_access() ? 'update.report_update' : 'update.status'))->toString();
+  $requirement['value'] = Link::fromTextAndUrl($requirement_label, Url::fromRoute('update.status'))->toString();
   return $requirement;
 }
 
diff --git a/core/modules/update/update.links.task.yml b/core/modules/update/update.links.task.yml
index d831bf01c9ef9890ea1697147c006c281bac09b2..f34442e4a67854c9ecea0754c97918e4b9643a6d 100644
--- a/core/modules/update/update.links.task.yml
+++ b/core/modules/update/update.links.task.yml
@@ -7,20 +7,3 @@ update.settings:
   base_route: system.admin_reports
   title: Settings
   weight: 50
-update.report_update:
-  route_name: update.report_update
-  base_route: system.admin_reports
-  title: Update
-  weight: 10
-
-update.module_update:
-  route_name: update.module_update
-  base_route: system.modules_list
-  title: Update
-  weight: 10
-
-update.theme_update:
-  route_name: update.theme_update
-  base_route: system.themes_page
-  title: Update
-  weight: 10
diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc
index 8598e51b6c2f6e6ebf2222b72a79ad5a0fb479f6..bb23795577591b5c35f16171417569a8e99ec968 100644
--- a/core/modules/update/update.manager.inc
+++ b/core/modules/update/update.manager.inc
@@ -8,39 +8,7 @@
 use Drupal\Core\File\Exception\InvalidStreamWrapperException;
 use Drupal\Core\File\FileExists;
 use Drupal\Core\Hook\Attribute\StopProceduralHookScan;
-use Drupal\Core\Url;
 use Psr\Http\Client\ClientExceptionInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
-
-/**
- * Batch callback: Performs actions when the download batch is completed.
- *
- * @param bool $success
- *   TRUE if the batch operation was successful, FALSE if there were errors.
- * @param array $results
- *   An associative array of results from the batch operation.
- */
-#[StopProceduralHookScan]
-function update_manager_download_batch_finished($success, $results) {
-  if (!empty($results['errors'])) {
-    $item_list = [
-      '#theme' => 'item_list',
-      '#title' => t('Downloading updates failed:'),
-      '#items' => $results['errors'],
-    ];
-    \Drupal::messenger()->addError(\Drupal::service('renderer')->render($item_list));
-  }
-  elseif ($success) {
-    \Drupal::messenger()->addStatus(t('Updates downloaded successfully.'));
-    \Drupal::request()->getSession()->set('update_manager_update_projects', $results['projects']);
-    return new RedirectResponse(Url::fromRoute('update.confirmation_page', [], ['absolute' => TRUE])->toString());
-  }
-  else {
-    // Ideally we're catching all Exceptions, so they should never see this,
-    // but just in case, we have to tell them something.
-    \Drupal::messenger()->addError(t('Fatal error trying to download.'));
-  }
-}
 
 /**
  * Checks for file transfer backends and prepares a form fragment about them.
@@ -56,6 +24,7 @@ function update_manager_download_batch_finished($success, $results) {
  *   workflow, or FALSE if we've hit a fatal configuration and must halt the
  *   workflow.
  */
+#[StopProceduralHookScan]
 function _update_manager_check_backends(&$form, $operation) {
   // If file transfers will be performed locally, we do not need to display any
   // warnings or notices to the user and should automatically continue the
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index bef8ee1e44e6d1e26a66dc9389bf70eb64dd668a..cd5937d2ab807f17f9b5e948ccdd6af08a3a73ab 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -12,24 +12,10 @@
 use Drupal\update\UpdateFetcherInterface;
 use Drupal\update\UpdateManagerInterface;
 
-/**
- * Resolves if the current user can access updater menu items.
- *
- * It both enforces the 'administer software updates' permission and the global
- * kill switch for the authorize.php script.
- *
- * @return bool
- *   TRUE if the current user can access the updater menu items; FALSE
- *   otherwise.
- */
-#[StopProceduralHookScan]
-function _update_manager_access() {
-  return Settings::get('allow_authorize_operations', TRUE) && \Drupal::currentUser()->hasPermission('administer software updates');
-}
-
 /**
  * Returns a warning message when there is no data about available updates.
  */
+#[StopProceduralHookScan]
 function _update_no_data() {
   $destination = \Drupal::destination()->getAsArray();
   return t('No update information available. <a href=":run_cron">Run cron</a> or <a href=":check_manually">check manually</a>.', [
diff --git a/core/modules/update/update.routing.yml b/core/modules/update/update.routing.yml
index 4f1f2888d6d3808fcf4bd7b0bed6c241ebb18dae..64ffe3cc217f91f58eebcbf0591a1f3a2055e40d 100644
--- a/core/modules/update/update.routing.yml
+++ b/core/modules/update/update.routing.yml
@@ -22,35 +22,3 @@ update.manual_status:
   requirements:
     _permission: 'administer site configuration'
     _csrf_token: 'TRUE'
-
-update.report_update:
-  path: '/admin/reports/updates/update'
-  defaults:
-    _form: '\Drupal\update\Form\UpdateManagerUpdate'
-    _title: 'Update'
-  requirements:
-    _permission: 'administer software updates'
-
-update.module_update:
-  path: '/admin/modules/update'
-  defaults:
-    _form: '\Drupal\update\Form\UpdateManagerUpdate'
-    _title: 'Update'
-  requirements:
-    _permission: 'administer software updates'
-
-update.theme_update:
-  path: '/admin/appearance/update'
-  defaults:
-    _form: '\Drupal\update\Form\UpdateManagerUpdate'
-    _title: 'Update'
-  requirements:
-    _permission: 'administer software updates'
-
-update.confirmation_page:
-  path: '/admin/update/ready'
-  defaults:
-    _form: '\Drupal\update\Form\UpdateReady'
-    _title: 'Ready to update'
-  requirements:
-    _permission: 'administer software updates'
diff --git a/core/modules/update/update.services.yml b/core/modules/update/update.services.yml
index 3f96c81b8baf521dff5a5f5e93d66689aed451fb..465df135529a0e8e332285a2e30ee40cee48a64b 100644
--- a/core/modules/update/update.services.yml
+++ b/core/modules/update/update.services.yml
@@ -24,6 +24,3 @@ services:
   logger.channel.update:
     parent: logger.channel_base
     arguments: [ 'update' ]
-  update.route_subscriber:
-    class: Drupal\update\Routing\UpdateRouteSubscriber
-    arguments: ['@settings']
diff --git a/core/modules/user/src/Form/UserPermissionsForm.php b/core/modules/user/src/Form/UserPermissionsForm.php
index 0428925fa03228888d87c77c1b70a31bda8f1384..95409cbe227d2049e4279f955580e70e41918725 100644
--- a/core/modules/user/src/Form/UserPermissionsForm.php
+++ b/core/modules/user/src/Form/UserPermissionsForm.php
@@ -86,7 +86,7 @@ public function getFormId() {
    *   An array of role objects.
    */
   protected function getRoles() {
-    return $this->roleStorage->loadMultiple();
+    return $this->roleStorage->loadMultipleOverrideFree();
   }
 
   /**
diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index cb44c2834ab724722046131fbb401d915db12cff..6d29b1dca9cff688fe7246ce4ef2520a21e4316e 100644
--- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -152,7 +152,9 @@ public function build() {
   }
 
   /**
-   * #lazy_builder callback; renders a form action URL including destination.
+   * Render API callback: Renders a form action URL including destination.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @return array
    *   A renderable array representing the form action.
diff --git a/core/modules/user/tests/modules/user_config_override_test/src/ConfigOverrider.php b/core/modules/user/tests/modules/user_config_override_test/src/ConfigOverrider.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ba5ad89eaf4973ce0ae97b87fedc7013bf6a8a
--- /dev/null
+++ b/core/modules/user/tests/modules/user_config_override_test/src/ConfigOverrider.php
@@ -0,0 +1,49 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\user_config_override_test;
+
+use Drupal\Core\Config\StorableConfigBase;
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Config\ConfigFactoryOverrideInterface;
+use Drupal\Core\Config\StorageInterface;
+
+/**
+ * Tests overridden permissions.
+ */
+class ConfigOverrider implements ConfigFactoryOverrideInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function loadOverrides($names): array {
+    return [
+      'user.role.anonymous' => [
+        'permissions' => [9999 => 'access content'],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheSuffix(): string {
+    return 'user_config_override_test';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getCacheableMetadata($name): CacheableMetadata {
+    return new CacheableMetadata();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createConfigObject($name, $collection = StorageInterface::DEFAULT_COLLECTION): StorableConfigBase|null {
+    return NULL;
+  }
+
+}
diff --git a/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.info.yml b/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.info.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2ccb5cfb2672dc44ad34e4fcfed65f9360852f9d
--- /dev/null
+++ b/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.info.yml
@@ -0,0 +1,4 @@
+name: 'Permission config overrider'
+type: module
+package: Testing
+version: VERSION
diff --git a/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.services.yml b/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.services.yml
new file mode 100644
index 0000000000000000000000000000000000000000..3ed295dd8000be5e3bcbf547eaf3cc89224c922a
--- /dev/null
+++ b/core/modules/user/tests/modules/user_config_override_test/user_config_override_test.services.yml
@@ -0,0 +1,5 @@
+services:
+  user_config_override_test.overrider:
+    class: Drupal\user_config_override_test\ConfigOverrider
+    tags:
+      - { name: config.factory.override }
diff --git a/core/modules/user/tests/src/Functional/UserPermissionsTest.php b/core/modules/user/tests/src/Functional/UserPermissionsTest.php
index b9faf636318647628aeb41af1f24f8e31d926d97..456ec90675485f8dffff7ea3253ebc5cef8c57f0 100644
--- a/core/modules/user/tests/src/Functional/UserPermissionsTest.php
+++ b/core/modules/user/tests/src/Functional/UserPermissionsTest.php
@@ -37,6 +37,13 @@ class UserPermissionsTest extends BrowserTestBase {
    */
   protected $defaultTheme = 'stark';
 
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'user_config_override_test',
+  ];
+
   /**
    * {@inheritdoc}
    */
@@ -333,4 +340,16 @@ public function testBundlePermissionError(): void {
     $assert_session->pageTextNotContains("Entity view display 'node.article.default': Component");
   }
 
+  /**
+   * Verify that the permission form does not use overridden config.
+   *
+   * @see \Drupal\user_config_override_test\ConfigOverrider
+   */
+  public function testOverriddenPermission(): void {
+    $this->drupalLogin($this->adminUser);
+
+    $this->drupalGet('admin/people/permissions');
+    $this->assertSession()->checkboxNotChecked('anonymous[access content]');
+  }
+
 }
diff --git a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
index 11c0f5f8aa8f5322a3a07f064e448788280ba781..6a4695cfc5b914c81521a043a77241c32c4dd00f 100644
--- a/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
+++ b/core/modules/user/tests/src/Kernel/UserRoleEntityTest.php
@@ -31,6 +31,9 @@ public function register(ContainerBuilder $container): void {
       ->addTag('logger');
   }
 
+  /**
+   * Tests the order of granted permissions in a role.
+   */
   public function testOrderOfPermissions(): void {
     $role = Role::create(['id' => 'test_role', 'label' => 'Test role']);
     $role->grantPermission('b')
@@ -46,6 +49,9 @@ public function testOrderOfPermissions(): void {
     $this->assertEquals(['a', 'b', 'c'], $role->getPermissions());
   }
 
+  /**
+   * Tests granting non-existent permissions to a role.
+   */
   public function testGrantingNonExistentPermission(): void {
     $role = Role::create(['id' => 'test_role', 'label' => 'Test role']);
 
@@ -73,6 +79,9 @@ public function testGrantingNonExistentPermission(): void {
     $this->assertEmpty(array_intersect(['does not exist', 'also does not exist'], $permissions));
   }
 
+  /**
+   * Tests permission revocation during a configuration synchronization.
+   */
   public function testPermissionRevokeAndConfigSync(): void {
     $role = Role::create(['id' => 'test_role', 'label' => 'Test role']);
     $role->setSyncing(TRUE);
diff --git a/core/modules/user/tests/src/Kernel/Views/UserViewsFieldAccessTest.php b/core/modules/user/tests/src/Kernel/Views/UserViewsFieldAccessTest.php
index 2b7953cc9619a5e342bb0e26cdbbcc0b22026c36..fffda3d83451792ee383a810b8c46ab40d4aea83 100644
--- a/core/modules/user/tests/src/Kernel/Views/UserViewsFieldAccessTest.php
+++ b/core/modules/user/tests/src/Kernel/Views/UserViewsFieldAccessTest.php
@@ -29,6 +29,9 @@ protected function setUp($import_test_views = TRUE): void {
     $this->installEntitySchema('user');
   }
 
+  /**
+   * Tests the user fields.
+   */
   public function testUserFields(): void {
     ConfigurableLanguage::createFromLangcode('es')->save();
     ConfigurableLanguage::createFromLangcode('fr')->save();
diff --git a/core/modules/views/src/Plugin/ViewsHandlerManager.php b/core/modules/views/src/Plugin/ViewsHandlerManager.php
index 99502754f49b31e13beade8c030a866492d5dc6b..e1182507bf86f62499efecd2de356e527cdcb4dc 100644
--- a/core/modules/views/src/Plugin/ViewsHandlerManager.php
+++ b/core/modules/views/src/Plugin/ViewsHandlerManager.php
@@ -107,7 +107,6 @@ public function getHandler(array $item, ?string $override_plugin_id = NULL): Vie
         }
       }
 
-      // First priority is to use the override.
       // When aggregation is enabled, particular plugins need to be
       // replaced in order to override the query with a query that
       // can run the aggregate counts, sums, or averages for example.
@@ -115,24 +114,13 @@ public function getHandler(array $item, ?string $override_plugin_id = NULL): Vie
       // for example which aggressively overrides any filter used
       // by a number of mathematical-type queries regardless of the
       // original filter.
-      if ($override_plugin_id) {
-        $handler = $this->createInstance($override_plugin_id, $definition);
-        if (!method_exists($handler, 'broken') || !$handler->broken()) {
-          return $handler;
-        }
+      $plugin_id = $override_plugin_id ?: $definition['id'];
+      // Try to use the overridden handler.
+      $handler = $this->createInstance($plugin_id, $definition);
+      if ($override_plugin_id && method_exists($handler, 'broken') && $handler->broken()) {
+        $handler = $this->createInstance($definition['id'], $definition);
       }
-
-      // Then try the configuration provided for the handler.
-      if (isset($item['plugin_id'])) {
-        $handler = $this->createInstance($item['plugin_id'], $definition);
-        if (!method_exists($handler, 'broken') || !$handler->broken()) {
-          return $handler;
-        }
-      }
-
-      // Finally, fall back to the default configuration suggested
-      // by the view data.
-      return $this->createInstance($definition['id'], $definition);
+      return $handler;
     }
 
     // Finally, use the 'broken' handler.
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php
index f5a823e42104eb40441628cd7a8c433b75e4f65c..c1227c301b1b792eeb7c200e1dfa39e60a663d93 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginInterface.php
@@ -411,7 +411,9 @@ public function renderMoreLink();
   public function render();
 
   /**
-   * #pre_render callback for view display rendering.
+   * Render API callback: Performs view display rendering.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * @param array $element
    *   The element to #pre_render.
diff --git a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
index 189d2424cb85c76ed1ecce245bc00337dc2127b4..60ebb9ca5d39f0c9645ae37a725f01e8cf184378 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
@@ -7,7 +7,7 @@
 /**
  * Defines an interface for displays that can collect routes.
  *
- * In addition to implementing the interface, specify 'uses_routes' in the
+ * In addition to implementing the interface, specify 'uses_route' in the
  * plugin definition.
  */
 interface DisplayRouterInterface extends DisplayPluginInterface {
diff --git a/core/modules/views/src/Plugin/views/style/StylePluginBase.php b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
index 0d25e0fa8786618371df6335926125f66610c0c5..3f555cfec9fd0bc400255d97c35a3953e8972e39 100644
--- a/core/modules/views/src/Plugin/views/style/StylePluginBase.php
+++ b/core/modules/views/src/Plugin/views/style/StylePluginBase.php
@@ -760,7 +760,9 @@ public static function trustedCallbacks() {
   }
 
   /**
-   * #pre_render callback for view row field rendering.
+   * Render API callback: Performs view row field rendering.
+   *
+   * This function is assigned as a #pre_render callback.
    *
    * @param array $data
    *   The element to #pre_render.
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax.yml
index 69e49097ad171be7d6e9d341430df496964be44e..649b5fe8abdef6223e4f45f8bf4745cfe8d0090e 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax.yml
@@ -35,7 +35,7 @@ display:
           field: type
           id: type
           table: node_field_data
-          plugin_id: bundle
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax_with_page.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax_with_page.yml
index ab6321d8b6f2c5dfa07e993d743f21d6c2b6469b..c484c6b1389e7f4225c698245e928d4b7d191a15 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax_with_page.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_block_exposed_ajax_with_page.yml
@@ -35,7 +35,7 @@ display:
           field: type
           id: type
           table: node_field_data
-          plugin_id: bundle
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
index 5aaa351c1ae212d8597bc53d2555e2456fa27522..3ab5ecb6689400b5276c6c0e3ad40cf78bb0c62f 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
@@ -1,44 +1,40 @@
 langcode: en
 status: true
-dependencies:
-  module:
-    - user
-    - views_test_data
+dependencies: {  }
 id: test_click_sort
 label: test_click_sort
 module: views
 description: ''
 tag: ''
 base_table: views_test_data
-base_field: id
+base_field: nid
 display:
   default:
-    id: default
-    display_title: Default
-    display_plugin: default
-    position: null
     display_options:
       fields:
         id:
           id: id
           table: views_test_data
           field: id
-          plugin_id: numeric
           label: ID
+          plugin_id: numeric
         name:
           id: name
           table: views_test_data
           field: name
+          label: Name
           plugin_id: string
-          label: ''
         created:
           id: created
           table: views_test_data
           field: created
-          plugin_id: date
-          date_format: timestamp
-          custom_date_format: ''
-          timezone: ''
+          label: created
+          plugin_id: field
+          type: timestamp
+          settings:
+            date_format: medium
+            custom_date_format: ''
+            timezone: ''
       access:
         type: none
       cache:
@@ -55,17 +51,14 @@ display:
               default_sort_order: desc
             created:
               sortable: false
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url.query_args
-        - user.permissions
-      tags: {  }
-  page_1:
-    id: page_1
-    display_title: Page
-    display_plugin: page
+    display_plugin: default
+    display_title: Default
+    id: default
     position: 0
+  page_1:
     display_options:
       path: test_click_sort
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: 0
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort_ajax.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort_ajax.yml
index 534e3eaecbac31566b6ae2b69289be3b0a1cb5d5..bf65e0eaf3792bbbee1adb48e84b8b9eb682dcc8 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort_ajax.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort_ajax.yml
@@ -1,105 +1,41 @@
 langcode: en
 status: true
-dependencies:
-  module:
-    - views_test_data
+dependencies: {  }
 id: test_click_sort_ajax
 label: test_click_sort_ajax
 module: views
 description: ''
 tag: ''
 base_table: views_test_data
-base_field: id
+base_field: nid
 display:
   default:
-    id: default
-    display_title: Default
-    display_plugin: default
-    position: null
     display_options:
+      use_ajax: true
       fields:
         id:
           id: id
           table: views_test_data
           field: id
-          plugin_id: numeric
           label: ID
+          plugin_id: numeric
         name:
           id: name
           table: views_test_data
           field: name
-          relationship: none
-          group_type: group
-          admin_label: ''
-          plugin_id: string
           label: Name
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
+          plugin_id: string
         created:
           id: created
           table: views_test_data
           field: created
-          plugin_id: date
-          date_format: timestamp
-          custom_date_format: ''
-          timezone: ''
-      pager:
-        type: mini
-        options:
-          offset: 0
-          pagination_heading_level: h4
-          items_per_page: 1
-          total_pages: null
-          id: 0
-          tags:
-            next: 'Next ›'
-            previous: '‹ Previous'
-          expose:
-            items_per_page: false
-            items_per_page_label: 'Items per page'
-            items_per_page_options: '5, 10, 25, 50'
-            items_per_page_options_all: false
-            items_per_page_options_all_label: '- All -'
-            offset: false
-            offset_label: Offset
+          label: created
+          plugin_id: field
+          type: timestamp
+          settings:
+            date_format: medium
+            custom_date_format: ''
+            timezone: ''
       access:
         type: none
       cache:
@@ -107,61 +43,23 @@ display:
       style:
         type: table
         options:
-          grouping: {  }
-          row_class: ''
-          default_row_class: true
-          columns:
-            id: id
-            name: name
-            created: created
-          default: id
           info:
             id:
-              sortable: false
+              sortable: true
               default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
             name:
               sortable: true
               default_sort_order: desc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
             created:
               sortable: false
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-          override: true
-          sticky: false
-          summary: ''
-          empty_table: false
-          caption: ''
-          description: ''
-      use_ajax: true
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url.query_args
-      tags: {  }
-  page_1:
-    id: page_1
-    display_title: Page
-    display_plugin: page
+    display_plugin: default
+    display_title: Default
+    id: default
     position: 0
+  page_1:
     display_options:
-      display_extenders: {  }
       path: test_click_sort
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url.query_args
-      tags: {  }
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: 0
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
index 1a3bf61bc6880f14eee9aaed5122bb2dc02d7029..a41124d71e84c327c5fa4388fb944ffb746c6831 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
@@ -86,7 +86,7 @@ display:
           exclude: false
           entity_type: entity_test
           entity_field: test_text_access
-          plugin_id: field
+          plugin_id: standard
           empty: ''
           hide_empty: false
           empty_zero: false
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
index ebcf5c9f704d4f81eda759d7869344259a96df3c..2df02b0b6633756e16b957d4fffc8cbefef3d1c1 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
@@ -1,8 +1,6 @@
 langcode: en
 status: true
 dependencies:
-  config:
-    - core.entity_view_mode.node.teaser
   module:
     - node
 id: test_exposed_block
@@ -14,83 +12,66 @@ base_table: node_field_data
 base_field: nid
 display:
   default:
-    id: default
-    display_title: Default
-    display_plugin: default
-    position: 0
     display_options:
       title: 'Test Exposed Block'
-      pager:
-        type: full
-      exposed_form:
-        type: basic
-        options:
-          reset_button: true
       access:
         type: none
       cache:
         type: tag
+      exposed_form:
+        options:
+          reset_button: true
+        type: basic
       filters:
         type:
+          expose:
+            identifier: type
+            label: 'Content: Type'
+            operator_id: type_op
+            reduce: false
+          exposed: true
+          field: type
           id: type
           table: node_field_data
-          field: type
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
-          plugin_id: bundle
-          exposed: true
-          expose:
-            operator_id: type_op
-            label: 'Content: Type'
-            identifier: type
-            reduce: false
+      pager:
+        type: full
+      query:
+        options:
+          query_comment: ''
+        type: views_query
       style:
         type: default
       row:
         type: 'entity:node'
-      query:
-        type: views_query
-        options:
-          query_comment: ''
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - 'user.node_grants:view'
-      tags: {  }
+    display_plugin: default
+    display_title: Default
+    id: default
+    position: 0
+  page_1:
+    display_options:
+      path: test_exposed_block
+      exposed_block: true
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: 0
   block_1:
+    display_plugin: block
     id: block_1
     display_title: Block
-    display_plugin: block
     position: 2
     display_options:
-      exposed_block: true
       display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - 'user.node_grants:view'
-      tags: {  }
-  page_1:
-    id: page_1
-    display_title: Page
-    display_plugin: page
-    position: 0
-    display_options:
       exposed_block: true
-      display_extenders: {  }
-      path: test_exposed_block
     cache_metadata:
       max-age: -1
       contexts:
+        - 'languages:language_content'
         - 'languages:language_interface'
-        - url
         - url.query_args
         - 'user.node_grants:view'
+        - user.permissions
       tags: {  }
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
index 89b658d11dc30deecb6fcc92ac212ff7ba932d4a..9a3605845e80e46b34f856d3184f085471616c51 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
@@ -1,8 +1,6 @@
 langcode: en
 status: true
 dependencies:
-  config:
-    - core.entity_view_mode.node.teaser
   module:
     - node
 id: test_exposed_form_buttons
@@ -14,66 +12,48 @@ base_table: node_field_data
 base_field: nid
 display:
   default:
-    id: default
-    display_title: Default
-    display_plugin: default
-    position: 0
     display_options:
-      pager:
-        type: full
-      exposed_form:
-        type: basic
-        options:
-          reset_button: true
       access:
         type: none
       cache:
         type: tag
+      exposed_form:
+        options:
+          reset_button: true
+        type: basic
       filters:
         type:
+          expose:
+            identifier: type
+            label: 'Content: Type'
+            operator_id: type_op
+            reduce: false
+            description: 'Exposed description'
+          exposed: true
+          field: type
           id: type
           table: node_field_data
-          field: type
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
-          plugin_id: bundle
-          exposed: true
-          expose:
-            operator_id: type_op
-            label: 'Content: Type'
-            description: 'Exposed description'
-            identifier: type
-            reduce: false
+      pager:
+        type: full
+      query:
+        options:
+          query_comment: ''
+        type: views_query
       style:
         type: default
       row:
         type: 'entity:node'
-      query:
-        type: views_query
-        options:
-          query_comment: ''
-      display_extenders: {  }
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - 'user.node_grants:view'
-      tags: {  }
-  page_1:
-    id: page_1
-    display_title: Page
-    display_plugin: page
+    display_plugin: default
+    display_title: Default
+    id: default
     position: 0
+  page_1:
     display_options:
-      display_extenders: {  }
       path: test_exposed_form_buttons
-    cache_metadata:
-      max-age: -1
-      contexts:
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - 'user.node_grants:view'
-      tags: {  }
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: 0
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml
index 3707472faa9c56637ac08b10dd89ee9259cd71b4..f3caf6512a69d45784923c972cf4e8ca4f965e09 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_checkboxes.yml
@@ -2,8 +2,7 @@ langcode: en
 status: true
 dependencies:
   config:
-    - core.entity_view_mode.node.teaser
-    - taxonomy.vocabulary.tags
+    - taxonomy.vocabulary.test_exposed_checkboxes
   module:
     - node
     - taxonomy
@@ -16,44 +15,33 @@ base_table: node_field_data
 base_field: nid
 display:
   default:
-    id: default
-    display_title: Default
-    display_plugin: default
-    position: 0
     display_options:
-      pager:
-        type: full
-      exposed_form:
-        type: basic
-        options:
-          reset_button: true
       access:
         type: none
       cache:
         type: tag
+      exposed_form:
+        options:
+          reset_button: true
+        type: basic
       filters:
-        type_1:
-          id: type_1
+        type:
+          id: type
           table: node_field_data
           field: type
           relationship: none
           group_type: group
           admin_label: ''
-          entity_type: node
-          entity_field: type
-          plugin_id: bundle
           operator: in
           value: {  }
           group: 1
           exposed: true
           expose:
-            operator_id: type_1_op
-            label: 'Content type'
-            description: ''
+            operator_id: type_op
+            label: 'Content: Type'
+            description: 'Exposed description'
             use_operator: false
-            operator: type_1_op
-            operator_limit_selection: false
-            operator_list: {  }
+            operator: ''
             identifier: type
             required: false
             remember: false
@@ -73,6 +61,9 @@ display:
             default_group: All
             default_group_multiple: {  }
             group_items: {  }
+          plugin_id: in_operator
+          entity_type: node
+          entity_field: type
         tid:
           id: tid
           table: taxonomy_index
@@ -80,7 +71,6 @@ display:
           relationship: none
           group_type: group
           admin_label: ''
-          plugin_id: taxonomy_index_tid
           operator: and
           value: {  }
           group: 1
@@ -91,8 +81,6 @@ display:
             description: ''
             use_operator: false
             operator: tid_op
-            operator_limit_selection: false
-            operator_list: {  }
             identifier: tid
             required: false
             remember: false
@@ -113,45 +101,50 @@ display:
             default_group_multiple: {  }
             group_items: {  }
           reduce_duplicates: false
-          vid: tags
           type: select
-          hierarchy: false
           limit: true
+          vid: test_exposed_checkboxes
+          hierarchy: false
           error_message: true
-      filter_groups:
-        operator: AND
-        groups:
-          1: AND
+          plugin_id: taxonomy_index_tid
+      pager:
+        type: full
+      query:
+        options:
+          query_comment: ''
+        type: views_query
       style:
         type: default
       row:
         type: 'entity:node'
-      query:
-        type: views_query
-        options:
-          query_comment: ''
       display_extenders: {  }
+    display_plugin: default
+    display_title: Default
+    id: default
+    position: 0
     cache_metadata:
       max-age: -1
       contexts:
         - 'languages:language_interface'
         - url
         - url.query_args
+        - user
         - 'user.node_grants:view'
       tags: {  }
   page_1:
-    id: page_1
-    display_title: Page
-    display_plugin: page
-    position: 0
     display_options:
-      display_extenders: {  }
       path: test_exposed_form_checkboxes
+      display_extenders: {  }
+    display_plugin: page
+    display_title: Page
+    id: page_1
+    position: 0
     cache_metadata:
       max-age: -1
       contexts:
         - 'languages:language_interface'
         - url
         - url.query_args
+        - user
         - 'user.node_grants:view'
       tags: {  }
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_pager.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_pager.yml
index bbddc9f8d34c81c29f92064f7a0758e011d1ee54..49555262930794980bfc6c59d9b8ff4c5aab44da 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_pager.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_pager.yml
@@ -60,7 +60,7 @@ display:
             default_group: All
             default_group_multiple: {  }
             group_items: {  }
-          plugin_id: bundle
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
         created:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
index 8b072fb19193f6325c167b28e199a0378fcde3e0..46b4412664a3226ed2b406a01d493969148ee41f 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
@@ -63,7 +63,7 @@ display:
           field: type
           id: type
           table: node_field_data
-          plugin_id: bundle
+          plugin_id: in_operator
           entity_type: node
           entity_field: type
         nid:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
index d67f17051828080cee04ea9f20aef348bb4cf008..c2b25fff96970d27d332d644672b835ea28b1697 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
@@ -188,7 +188,8 @@ display:
           group_type: group
           admin_label: ''
           operator: '='
-          value: ''
+          value:
+            value: ''
           group: 1
           exposed: false
           expose:
@@ -215,7 +216,7 @@ display:
             default_group: All
             default_group_multiple: {  }
             group_items: {  }
-          plugin_id: history_user_timestamp
+          plugin_id: date
       defaults:
         filters: false
         filter_groups: false
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_remember_selected.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_remember_selected.yml
index 0d842e4c05a39dec61d0cc9aa5aa3221f1d0662d..6d3b049afceac156fce67866b7e90bdfb17165d4 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_remember_selected.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_remember_selected.yml
@@ -40,7 +40,7 @@ display:
           admin_label: ''
           entity_type: node
           entity_field: type
-          plugin_id: bundle
+          plugin_id: in_operator
           operator: in
           value: {  }
           group: 1
diff --git a/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
index af4ba35ed5dfd31054db01df05f2ef86826f5dc0..0e3f576837a9dfb5704f5f95478d7efc27b6a634 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Controller/ViewsTestDataController.php
@@ -29,7 +29,9 @@ public function errorFormPage() {
   }
 
   /**
-   * #lazy_builder callback; for testing purposes only.
+   * Render API callback: For testing placeholdering only.
+   *
+   * This function is assigned as a #lazy_builder callback.
    */
   public static function placeholderLazyBuilder() {
     // No-op.
diff --git a/core/modules/views/tests/modules/views_test_data_alter/src/Hook/ViewsTestDataAlterHooks.php b/core/modules/views/tests/modules/views_test_data_alter/src/Hook/ViewsTestDataAlterHooks.php
deleted file mode 100644
index 3b6cc1f35a3dfe1425b9a6fe2d309e25bd41315e..0000000000000000000000000000000000000000
--- a/core/modules/views/tests/modules/views_test_data_alter/src/Hook/ViewsTestDataAlterHooks.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\views_test_data_alter\Hook;
-
-use Drupal\Core\Hook\Attribute\Hook;
-
-/**
- * Hook implementations for views_test_data_alter.
- */
-class ViewsTestDataAlterHooks {
-
-  /**
-   * Implements hook_views_data_alter().
-   */
-  #[Hook('views_data_alter')]
-  public function viewsDataAlter(array &$data): void {
-    // Modify a filter to use a different filter handler plugin
-    // by default so that we can test that the handler used
-    // respects the handler plugin ID specified in the
-    // configuration.
-    $data['node_field_data']['status']['filter']['id'] = 'numeric';
-  }
-
-}
diff --git a/core/modules/views/tests/modules/views_test_data_alter/views_test_data_alter.info.yml b/core/modules/views/tests/modules/views_test_data_alter/views_test_data_alter.info.yml
deleted file mode 100644
index ac3d0bbb1217bf419672cb139d4d6064583ac357..0000000000000000000000000000000000000000
--- a/core/modules/views/tests/modules/views_test_data_alter/views_test_data_alter.info.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 'Views Test Data Alter'
-type: module
-description: 'Test module for Views to alter data.'
-package: Testing
-version: VERSION
-dependencies:
-  - drupal:views
diff --git a/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
index 14b713d8cd587390aa04d74a82bc08ee0f07b619..8ee795e5b60e344900ff3a029f3c3e59fc0e6fa8 100644
--- a/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
@@ -39,6 +39,15 @@ class BaseFieldAccessTest extends ViewTestBase {
   protected function setUp($import_test_views = TRUE, $modules = ['views_test_config', 'comment_test_views']): void {
     parent::setUp($import_test_views, $modules);
 
+    \Drupal::state()->set('entity_test.views_data', [
+      'entity_test' => [
+        'test_text_access' => [
+          'field' => [
+            'id' => 'standard',
+          ],
+        ],
+      ],
+    ]);
     $entity_1 = EntityTest::create([
       'test_text_access' => 'no access value',
     ]);
diff --git a/core/modules/views/tests/src/Functional/Handler/HandlerTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
index c6523c40c10042689b64830361db2f2c84220579..fa9af239ca3eb248913402ec437994ea2d3b507e 100644
--- a/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
@@ -333,12 +333,6 @@ public function testSetRelationship(): void {
    * @see \Drupal\views\Plugin\views\HandlerBase::placeholder()
    */
   public function testPlaceholder(): void {
-    // Change the test view to use the test field plugin which has the
-    // additional get placeholder method.
-    $config = $this->config('views.view.test_view');
-    $config->set('display.default.display_options.fields.name.plugin_id', 'test_field');
-    $config->save();
-
     $view = Views::getView('test_view');
     $view->initHandlers();
     $view->initQuery();
@@ -348,7 +342,7 @@ public function testPlaceholder(): void {
     $field = $handler->field;
     $string = ':' . $table . '_' . $field;
 
-    // Make sure the placeholder variables contain the expected values.
+    // Make sure the placeholder variables are like expected.
     $this->assertEquals($string, $handler->getPlaceholder());
     $this->assertEquals($string . 1, $handler->getPlaceholder());
     $this->assertEquals($string . 2, $handler->getPlaceholder());
@@ -375,7 +369,7 @@ public function testAccess(): void {
     $views_data = $this->viewsData();
     $views_data = $views_data['views_test_data'];
 
-    // Enable access only to the callback field and deny access for the callback and the arguments.
+    // Enable access to callback only field and deny for callback + arguments.
     $this->config('views_test_data.tests')->set('handler_access_callback', TRUE)->save();
     $this->config('views_test_data.tests')->set('handler_access_callback_argument', FALSE)->save();
     $view->initDisplay();
@@ -388,7 +382,7 @@ public function testAccess(): void {
       }
     }
 
-    // Enable access to the callback and the argument handlers and deny access for the callback.
+    // Enable access to the callback + argument handlers and deny for callback.
     $this->config('views_test_data.tests')->set('handler_access_callback', FALSE)->save();
     $this->config('views_test_data.tests')->set('handler_access_callback_argument', TRUE)->save();
     $view->destroy();
diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
index a5b1b27db056bd57f6565b51aee4fc4eecda788c..a6e39524c245ced4ac1967b3ba8384f1c127f227 100644
--- a/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormCheckboxesTest.php
@@ -61,7 +61,7 @@ protected function setUp($import_test_views = TRUE, $modules = []): void {
     // vocabulary is in place to meet the view dependencies.
     $vocabulary = Vocabulary::create([
       'name' => 'test_exposed_checkboxes',
-      'vid' => 'tags',
+      'vid' => 'test_exposed_checkboxes',
       'nodes' => ['article' => 'article'],
     ]);
     $vocabulary->save();
diff --git a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
index 933554003ff0c5dcf19b78561ff42e5516240c03..fa9995eea82ee2e04fe4756b14cbeaaf8df4372a 100644
--- a/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
@@ -116,7 +116,7 @@ public function testExposedIdentifier(): void {
         'field' => 'type',
         'id' => 'type',
         'table' => 'node_field_data',
-        'plugin_id' => 'bundle',
+        'plugin_id' => 'in_operator',
         'entity_type' => 'node',
         'entity_field' => 'type',
         'expose' => [
diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php
index 089c37c90288f35e598d8ba5d0ba116f190dfe75..a96bb66e65200e539f74b0707f55c9596d4dd688 100644
--- a/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/AreaTextTest.php
@@ -37,6 +37,9 @@ protected function setUp($import_test_views = TRUE): void {
     $this->installEntitySchema('user');
   }
 
+  /**
+   * Tests the rendering of a text area.
+   */
   public function testAreaText(): void {
     /** @var \Drupal\Core\Render\RendererInterface $renderer */
     $renderer = $this->container->get('renderer');
diff --git a/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php b/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php
index 8643ddcf0327af54bf8ab3012973c40c57112d0d..f48cbf89b40b37742abf9cd02ac70794ae1bba23 100644
--- a/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/ArgumentNullTest.php
@@ -21,6 +21,9 @@ class ArgumentNullTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Defines Views data, setting the 'id' argument to use the null handler.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['id']['argument']['id'] = 'null';
@@ -28,6 +31,9 @@ public function viewsData() {
     return $data;
   }
 
+  /**
+   * Tests the NullArgument handler for text areas.
+   */
   public function testAreaText(): void {
     // Test validation
     $view = Views::getView('test_view');
diff --git a/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php b/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php
index db630c9ac591cbc8e25245e6b0fe7734680208a0..09a489e3105cea728ccecc47baa28a84bfb35357 100644
--- a/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/EntityTestViewsFieldAccessTest.php
@@ -30,6 +30,9 @@ protected function setUp($import_test_views = TRUE): void {
     ConfigurableLanguage::create(['id' => 'es', 'title' => 'Spanish title', 'label' => 'Spanish label'])->save();
   }
 
+  /**
+   * Tests field access permissions for the 'entity_test' entity in Views.
+   */
   public function testEntityTestFields(): void {
     $entity_test = EntityTest::create([
       'name' => 'test entity name',
diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldBooleanTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldBooleanTest.php
index a60a3f13f50fc41407e0d80140db3fb7ed00475d..2d1c79b71c3574aa1dd56203a2bf60cc80c998b6 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldBooleanTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldBooleanTest.php
@@ -21,6 +21,9 @@ class FieldBooleanTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Modifies the default dataset by removing the age for specific entries.
+   */
   public function dataSet() {
     // Use default dataset but remove the age from john and paul
     $data = parent::dataSet();
@@ -29,12 +32,18 @@ public function dataSet() {
     return $data;
   }
 
+  /**
+   * Provides Views data definition for the 'age' field as a boolean.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['age']['field']['id'] = 'boolean';
     return $data;
   }
 
+  /**
+   * Tests different display formats for a boolean field in Views.
+   */
   public function testFieldBoolean(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php
index 5bf8f445fde945426cd757f6d950106a7f794b21..b9b934c9e7eca06f3ab22c94a2a19a3873aabb3b 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldCounterTest.php
@@ -26,6 +26,9 @@ class FieldCounterTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Tests the behavior of a simple View rendering with overridden field options.
+   */
   public function testSimple(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php
index f29de027ba4df18c70c5393c39d5560954cecda9..b897a7ad73ebba6fd55292594cb975e655b10f16 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldFileSizeTest.php
@@ -22,6 +22,9 @@ class FieldFileSizeTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Provides a dataset with various 'age' values representing file sizes.
+   */
   public function dataSet() {
     $data = parent::dataSet();
     $data[0]['age'] = 0;
@@ -32,6 +35,9 @@ public function dataSet() {
     return $data;
   }
 
+  /**
+   * Maps the 'age' field to the 'file_size' handler for Views.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['age']['field']['id'] = 'file_size';
@@ -39,6 +45,9 @@ public function viewsData() {
     return $data;
   }
 
+  /**
+   * Tests the FileSize field handler for correct formatting in Views.
+   */
   public function testFieldFileSize(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldTimeIntervalTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldTimeIntervalTest.php
index 25f1db02ecc16eab11b3134e4ce11e5c313349a3..9f4d930c6f780d8896860b84d6abb6b01e15baae 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldTimeIntervalTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldTimeIntervalTest.php
@@ -44,16 +44,13 @@ class FieldTimeIntervalTest extends ViewsKernelTestBase {
    * Tests the TimeInterval handler.
    */
   public function testFieldTimeInterval(): void {
-    $view_config = $this->config('views.view.test_view');
-    $view_config->set('display.default.display_options.fields.age.plugin_id', 'time_interval');
-    foreach (array_keys($this->ages) as $delta) {
+    $view = Views::getView('test_view');
+    $view->setDisplay();
+    $this->executeView($view);
+    foreach ($view->result as $delta => $row) {
       [, $formatted_value, $granularity] = $this->ages[$delta];
-      $view_config->set('display.default.display_options.fields.age.granularity', $granularity);
-      $view_config->save();
-      $view = Views::getView('test_view');
-      $view->setDisplay();
-      $this->executeView($view);
-      $this->assertEquals($formatted_value, $view->field['age']->advancedRender($view->result[$delta]));
+      $view->field['age']->options['granularity'] = $granularity;
+      $this->assertEquals($formatted_value, $view->field['age']->advancedRender($row));
     }
   }
 
diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php
index 71437e6e7e0fb77b50ed44a13b86e22bafd9e165..10386570842ccff31c57409c9bc175b1549cb134 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FieldUrlTest.php
@@ -28,12 +28,18 @@ class FieldUrlTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Defines the Views data for the test entity.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['name']['field']['id'] = 'url';
     return $data;
   }
 
+  /**
+   * Tests the rendering of a field as a plain text value and as a link.
+   */
   public function testFieldUrl(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php
index 4375484772266eda1b00d7aee3f77c57dcce290d..caf508cb95c200bc189e0633e6fd9f7c20458f94 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FilterCombineTest.php
@@ -48,6 +48,9 @@ protected function setUp($import_test_views = TRUE): void {
     $this->installEntitySchema('entity_test');
   }
 
+  /**
+   * Tests the Combine field filter with the 'contains' operator.
+   */
   public function testFilterCombineContains(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php
index a2ba005a0bdbd93eaab4b197535936e0c78078f6..aeb4d145c1e02b9d6de1e2b53a022ae3a418cddd 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FilterEqualityTest.php
@@ -35,12 +35,18 @@ class FilterEqualityTest extends ViewsKernelTestBase {
     'views_test_data_name' => 'name',
   ];
 
+  /**
+   * Defines Views data, mapping 'name' field to the equality filter.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['name']['filter']['id'] = 'equality';
     return $data;
   }
 
+  /**
+   * Tests filtering names where the value matches exactly.
+   */
   public function testEqual(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -66,6 +72,9 @@ public function testEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped, exposed equality filtering.
+   */
   public function testEqualGroupedExposed(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -86,6 +95,9 @@ public function testEqualGroupedExposed(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering names using a not-equal condition.
+   */
   public function testNotEqual(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -120,6 +132,9 @@ public function testNotEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped, non-exposed inequality filtering.
+   */
   public function testEqualGroupedNotExposed(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -149,6 +164,9 @@ public function testEqualGroupedNotExposed(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Provides grouped exposed filter options for the 'name' field.
+   */
   protected function getGroupedExposedFilters(): array {
     $filters = [
       'name' => [
diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php
index e16e6f2cff878de353de66df9c20c0578a8065a5..e812d2fd4170620cce1a92d0f331b4d55419a929 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FilterInOperatorTest.php
@@ -41,12 +41,18 @@ class FilterInOperatorTest extends ViewsKernelTestBase {
     'views_test_data_age' => 'age',
   ];
 
+  /**
+   * Defines Views data for the custom entity.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['age']['filter']['id'] = 'in_operator';
     return $data;
   }
 
+  /**
+   * Tests filtering using the "IN" and "NOT IN" operators on the age field.
+   */
   public function testFilterInOperatorSimple(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -113,6 +119,9 @@ public function testFilterInOperatorSimple(): void {
     $this->assertIdenticalResultset($view, $expected_result, $this->columnMap);
   }
 
+  /**
+   * Tests filtering with grouped exposed filters using the "IN" operator.
+   */
   public function testFilterInOperatorGroupedExposedSimple(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -139,6 +148,9 @@ public function testFilterInOperatorGroupedExposedSimple(): void {
     $this->assertIdenticalResultset($view, $expected_result, $this->columnMap);
   }
 
+  /**
+   * Tests filtering with grouped exposed filters using the "NOT IN" operator.
+   */
   public function testFilterNotInOperatorGroupedExposedSimple(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -202,6 +214,12 @@ public function testFilterGroupedChangedIdentifier(): void {
     $this->assertIdenticalResultset($view, $expected_result, $this->columnMap);
   }
 
+  /**
+   * Returns grouped exposed filter definitions for Views.
+   *
+   * @return array
+   *   An array of grouped exposed filters.
+   */
   protected function getGroupedExposedFilters(): array {
     $filters = [
       'age' => [
diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php
index 27deea250d00e8887eb5e4dc9318222abdc05819..b0a355f8dbdc2a82c0c416df9c5fc104040aa4da 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FilterNumericTest.php
@@ -37,6 +37,9 @@ class FilterNumericTest extends ViewsKernelTestBase {
     'views_test_data_age' => 'age',
   ];
 
+  /**
+   * Defines Views data, allowing 'age' to be empty and 'id' to be required.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['age']['filter']['allow empty'] = TRUE;
@@ -45,6 +48,9 @@ public function viewsData() {
     return $data;
   }
 
+  /**
+   * Tests filtering records using an exact match on a numeric field.
+   */
   public function testFilterNumericSimple(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -71,6 +77,9 @@ public function testFilterNumericSimple(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering using exposed grouped filters.
+   */
   public function testFilterNumericExposedGroupedSimple(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -195,6 +204,9 @@ public static function providerTestFilterNumericBetween() {
     ];
   }
 
+  /**
+   * Tests filtering records using a ranged condition on a numeric field.
+   */
   public function testFilterNumericExposedGroupedBetween(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -224,6 +236,9 @@ public function testFilterNumericExposedGroupedBetween(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering records outside a specified numeric range.
+   */
   public function testFilterNumericExposedGroupedNotBetween(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -388,6 +403,9 @@ public function testFilterNumericExposedGroupedNotRegularExpression(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering records based on empty and non-empty values.
+   */
   public function testFilterNumericEmpty(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -447,6 +465,9 @@ public function testFilterNumericEmpty(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering exposed grouped records based on empty values.
+   */
   public function testFilterNumericExposedGroupedEmpty(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -463,6 +484,9 @@ public function testFilterNumericExposedGroupedEmpty(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering exposed grouped records based on non-empty values.
+   */
   public function testFilterNumericExposedGroupedNotEmpty(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
@@ -500,6 +524,9 @@ public function testFilterNumericExposedGroupedNotEmpty(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests whether empty filters are allowed for specific fields.
+   */
   public function testAllowEmpty(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -530,6 +557,12 @@ public function testAllowEmpty(): void {
     $this->assertTrue(isset($age_operators['not empty']));
   }
 
+  /**
+   * Returns predefined grouped filter configurations for 'age'.
+   *
+   * @return array
+   *   An array of grouped exposed filters.
+   */
   protected function getGroupedExposedFilters(): array {
     $filters = [
       'age' => [
diff --git a/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php b/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php
index c05b04ad18ce186fdc7452fbd5415cbc1674a741..96d7f91c6fc9c0b5cb85751f727a593c93d0c1ec 100644
--- a/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/FilterStringTest.php
@@ -37,6 +37,9 @@ class FilterStringTest extends ViewsKernelTestBase {
     'views_test_data_name' => 'name',
   ];
 
+  /**
+   * Defines Views data for the custom entity.
+   */
   public function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['name']['filter']['allow empty'] = TRUE;
@@ -92,6 +95,9 @@ protected function getBasicPageView() {
     return $view;
   }
 
+  /**
+   * Tests the string filter with the 'equal' operator.
+   */
   public function testFilterStringEqual(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -156,6 +162,9 @@ public function testFilterStringEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Returns a set of grouped exposed filters.
+   */
   public function testFilterStringGroupedExposedEqual(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -177,6 +186,9 @@ public function testFilterStringGroupedExposedEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests the string filter with the 'not equal' operator.
+   */
   public function testFilterStringNotEqual(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -211,6 +223,9 @@ public function testFilterStringNotEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped, exposed filtering with not equal operator.
+   */
   public function testFilterStringGroupedExposedNotEqual(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -242,6 +257,9 @@ public function testFilterStringGroupedExposedNotEqual(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests the string filter with the 'contains' operator.
+   */
   public function testFilterStringContains(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -267,6 +285,9 @@ public function testFilterStringContains(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped, exposed filtering with contains operator.
+   */
   public function testFilterStringGroupedExposedContains(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -288,6 +309,9 @@ public function testFilterStringGroupedExposedContains(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by a word in the "description" field.
+   */
   public function testFilterStringWord(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -376,6 +400,9 @@ public function testFilterStringWord(): void {
     $this->assertIdenticalResultset($view, $resultset);
   }
 
+  /**
+   * Tests grouped and exposed filters with word-based filtering.
+   */
   public function testFilterStringGroupedExposedWord(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -417,6 +444,9 @@ public function testFilterStringGroupedExposedWord(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "starts with" operator.
+   */
   public function testFilterStringStarts(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -442,6 +472,9 @@ public function testFilterStringStarts(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "starts with" operator.
+   */
   public function testFilterStringGroupedExposedStarts(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -495,6 +528,9 @@ public function testFilterStringGroupedNotRegularExpression(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "does not start with" operator.
+   */
   public function testFilterStringNotStarts(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -527,6 +563,9 @@ public function testFilterStringNotStarts(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "does not start with" operator.
+   */
   public function testFilterStringGroupedExposedNotStarts(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -554,6 +593,9 @@ public function testFilterStringGroupedExposedNotStarts(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "ends with" operator.
+   */
   public function testFilterStringEnds(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -582,6 +624,9 @@ public function testFilterStringEnds(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "ends with" operator.
+   */
   public function testFilterStringGroupedExposedEnds(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -605,6 +650,9 @@ public function testFilterStringGroupedExposedEnds(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "does not end with" operator.
+   */
   public function testFilterStringNotEnds(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -634,6 +682,9 @@ public function testFilterStringNotEnds(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "does not end with" operator.
+   */
   public function testFilterStringGroupedExposedNotEnds(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -658,6 +709,9 @@ public function testFilterStringGroupedExposedNotEnds(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "does not contain" operator.
+   */
   public function testFilterStringNot(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -687,6 +741,9 @@ public function testFilterStringNot(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "does not contain" operator.
+   */
   public function testFilterStringGroupedExposedNot(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -712,6 +769,9 @@ public function testFilterStringGroupedExposedNot(): void {
 
   }
 
+  /**
+   * Tests filtering by string using the "shorter than" operator.
+   */
   public function testFilterStringShorter(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -740,6 +800,9 @@ public function testFilterStringShorter(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "shorter than" operator.
+   */
   public function testFilterStringGroupedExposedShorter(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -762,6 +825,9 @@ public function testFilterStringGroupedExposedShorter(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "longer than" operator.
+   */
   public function testFilterStringLonger(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -787,6 +853,9 @@ public function testFilterStringLonger(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "longer than" operator.
+   */
   public function testFilterStringGroupedExposedLonger(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -806,6 +875,9 @@ public function testFilterStringGroupedExposedLonger(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests filtering by string using the "empty" operator.
+   */
   public function testFilterStringEmpty(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
@@ -830,6 +902,9 @@ public function testFilterStringEmpty(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Tests grouped and exposed filters with the "empty" operator.
+   */
   public function testFilterStringGroupedExposedEmpty(): void {
     $filters = $this->getGroupedExposedFilters();
     $view = $this->getBasicPageView();
@@ -892,6 +967,9 @@ public function testFilterStringNotRegularExpression(): void {
     $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
   }
 
+  /**
+   * Returns a set of grouped exposed filters.
+   */
   protected function getGroupedExposedFilters(): array {
     $filters = [
       'name' => [
diff --git a/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php b/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php
index 26d9ab1c73653436a573b99d9ab0da450f0493af..a66bd9b4c89a8b42c1641f4a4f1da024b110d137 100644
--- a/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/HandlerAliasTest.php
@@ -48,6 +48,9 @@ protected function viewsData() {
     return $data;
   }
 
+  /**
+   * Tests the behavior of plugin aliases in Views filters.
+   */
   public function testPluginAliases(): void {
     $view = Views::getView('test_filter');
     $view->initDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php b/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php
index 65a4c892159974a3f134b962f1e95fcf44350ad3..a1d72775a75a36f9f19ef8e3f646affbb9362ddd 100644
--- a/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php
+++ b/core/modules/views/tests/src/Kernel/Handler/SortDateTest.php
@@ -21,6 +21,9 @@ class SortDateTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Generates an expected result set based on the specified granularity and order.
+   */
   protected function expectedResultSet($granularity, $reverse = TRUE): array {
     $expected = [];
     if (!$reverse) {
diff --git a/core/modules/views/tests/src/Kernel/ModuleTest.php b/core/modules/views/tests/src/Kernel/ModuleTest.php
index ff2d42e327e8b7f6670831a7011223f7d8d601ec..b3cdf6446d9deebeabf4f64ecd2d932bbdbdef7d 100644
--- a/core/modules/views/tests/src/Kernel/ModuleTest.php
+++ b/core/modules/views/tests/src/Kernel/ModuleTest.php
@@ -8,7 +8,6 @@
 use Drupal\Core\Form\FormState;
 use Drupal\views\Plugin\views\area\Broken as BrokenArea;
 use Drupal\views\Plugin\views\field\Broken as BrokenField;
-use Drupal\views\Plugin\views\filter\BooleanOperator;
 use Drupal\views\Plugin\views\filter\Broken as BrokenFilter;
 use Drupal\views\Plugin\views\filter\Standard;
 use Drupal\views\Plugin\views\ViewsHandlerInterface;
@@ -26,12 +25,12 @@ class ModuleTest extends ViewsKernelTestBase {
    *
    * @var array
    */
-  public static $testViews = ['test_view_status', 'test_view', 'test_argument', 'test_redirect_view'];
+  public static $testViews = ['test_view_status', 'test_view', 'test_argument'];
 
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['field', 'user', 'block', 'node', 'views_test_data_alter'];
+  protected static $modules = ['field', 'user', 'block'];
 
   /**
    * Stores the last triggered error.
@@ -110,14 +109,6 @@ public function testViewsGetHandler(): void {
     ];
     $handler = $this->container->get('plugin.manager.views.filter')->getHandler($item, 'standard');
     $this->assertInstanceOf(Standard::class, $handler);
-
-    // Test that the configuration is respected rather than overridden
-    // by views data. Using assertSame() here to make the error more clearly
-    // show what the result is when an error is caused.
-    $test_view_config = $this->config('views.view.test_redirect_view');
-    $item = $test_view_config->get('display.default.display_options.filters.status');
-    $handler = $this->container->get('plugin.manager.views.filter')->getHandler($item);
-    $this->assertSame(BooleanOperator::class, get_class($handler));
   }
 
   /**
diff --git a/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php b/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php
index 64d3b00e7b58f4cf22ffc9f613b39ab6c942b114..1b87608044a4eb33450eac122497a1ca7f9d84d4 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/ArgumentValidatorTest.php
@@ -22,6 +22,9 @@ class ArgumentValidatorTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view_argument_validate_numeric', 'test_view'];
 
+  /**
+   * Tests numeric argument validation in a view.
+   */
   public function testArgumentValidateNumeric(): void {
     $view = Views::getView('test_view_argument_validate_numeric');
     $view->initHandlers();
diff --git a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
index fa4969d1e9b6d6a43cd80a42e91f496eda86208d..97d670634b3f6f7e9986f94ea283a1120f288181 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
@@ -5,12 +5,8 @@
 namespace Drupal\Tests\views\Kernel\Plugin;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Core\Form\FormState;
-use Drupal\Core\Path\CurrentPathStack;
 use Drupal\node\Entity\NodeType;
 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
-use Drupal\views\ExposedFormCache;
-use Drupal\views\Form\ViewsExposedForm;
 use Drupal\views\Views;
 
 /**
@@ -24,7 +20,7 @@ class ExposedFormRenderTest extends ViewsKernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $testViews = ['test_exposed_form_buttons', 'test_exposed_admin_ui'];
+  public static $testViews = ['test_exposed_form_buttons'];
 
   /**
    * {@inheritdoc}
@@ -68,38 +64,85 @@ public function testExposedFormRawInput(): void {
       'name' => 'Article',
     ])->save();
 
-    // Build the form state.
-    $form = [];
-    $view = Views::getView('test_exposed_admin_ui');
+    $view = Views::getView('test_exposed_form_buttons');
     $view->setDisplay();
+    $view->displayHandlers->get('default')->overrideOption('filters', [
+      'type' => [
+        'exposed' => TRUE,
+        'field' => 'type',
+        'id' => 'type',
+        'table' => 'node_field_data',
+        'plugin_id' => 'in_operator',
+        'entity_type' => 'node',
+        'entity_field' => 'type',
+        'expose' => [
+          'identifier' => 'type',
+          'label' => 'Content: Type',
+          'operator_id' => 'type_op',
+          'reduce' => FALSE,
+          'multiple' => FALSE,
+        ],
+      ],
+      'type_with_default_value' => [
+        'exposed' => TRUE,
+        'field' => 'type',
+        'id' => 'type_with_default_value',
+        'table' => 'node_field_data',
+        'plugin_id' => 'in_operator',
+        'entity_type' => 'node',
+        'entity_field' => 'type',
+        'value' => ['article', 'article'],
+        'expose' => [
+          'identifier' => 'type_with_default_value',
+          'label' => 'Content: Type with value',
+          'operator_id' => 'type_op',
+          'reduce' => FALSE,
+          'multiple' => FALSE,
+        ],
+      ],
+      'multiple_types' => [
+        'exposed' => TRUE,
+        'field' => 'type',
+        'id' => 'multiple_types',
+        'table' => 'node_field_data',
+        'plugin_id' => 'in_operator',
+        'entity_type' => 'node',
+        'entity_field' => 'type',
+        'expose' => [
+          'identifier' => 'multiple_types',
+          'label' => 'Content: Type (multiple)',
+          'operator_id' => 'type_op',
+          'reduce' => FALSE,
+          'multiple' => TRUE,
+        ],
+      ],
+      'multiple_types_with_default_value' => [
+        'exposed' => TRUE,
+        'field' => 'type',
+        'id' => 'multiple_types_with_default_value',
+        'table' => 'node_field_data',
+        'plugin_id' => 'in_operator',
+        'entity_type' => 'node',
+        'entity_field' => 'type',
+        'value' => ['article', 'article'],
+        'expose' => [
+          'identifier' => 'multiple_types_with_default_value',
+          'label' => 'Content: Type with default value (multiple)',
+          'operator_id' => 'type_op',
+          'reduce' => FALSE,
+          'multiple' => TRUE,
+        ],
+      ],
+    ]);
+    $view->save();
     $this->executeView($view);
 
-    $form_state = new FormState();
-    $form_state->set('view', $view);
-    $form_state->setValue('type', 'article');
-
-    // Mock the exposed form.
-    $exposed_form_cache = $this->createMock(ExposedFormCache::class);
-    $current_path_stack = $this->createMock(CurrentPathStack::class);
-    $exposed_form = new ViewsExposedForm($exposed_form_cache, $current_path_stack);
-    $exposed_form->submitForm($form, $form_state);
-    $updated_view = $form_state->get('view');
-
     $expected = [
-      'type' => 'article',
-    ];
-    $this->assertSame($updated_view->exposed_raw_input, $expected);
-
-    $form_state->setValue('type', ['article', 'page']);
-    $exposed_form->submitForm($form, $form_state);
-    $updated_view = $form_state->get('view');
-    $expected = [
-      'type' => [
-        'article',
-        'page',
-      ],
+      'type' => 'All',
+      'type_with_default_value' => 'article',
+      'multiple_types_with_default_value' => ['article' => 'article'],
     ];
-    $this->assertSame($updated_view->exposed_raw_input, $expected);
+    $this->assertSame($view->exposed_raw_input, $expected);
   }
 
 }
diff --git a/core/modules/views/tests/src/Kernel/Plugin/PluginBaseTest.php b/core/modules/views/tests/src/Kernel/Plugin/PluginBaseTest.php
index 42a3624e25da2a93f38686b19874c172ab43052f..3a400ce4565bd01157e57505a67ac71044ecfcf9 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/PluginBaseTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/PluginBaseTest.php
@@ -88,6 +88,9 @@ public function __construct() {
     parent::__construct([], '', []);
   }
 
+  /**
+   * {@inheritdoc}
+   */
   public function viewsTokenReplace($text, $tokens) {
     return parent::viewsTokenReplace($text, $tokens);
   }
diff --git a/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php b/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php
index 22276d9e2dbb504431df1c07102e6c67f1c3be7b..bbd45990a2d9ecd82b0dee0e3cb9582f194dbca2 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/QueryTest.php
@@ -22,6 +22,9 @@ class QueryTest extends ViewsKernelTestBase {
    */
   public static $testViews = ['test_view'];
 
+  /**
+   * Provides Views metadata for the test data table.
+   */
   protected function viewsData() {
     $data = parent::viewsData();
     $data['views_test_data']['table']['base']['query_id'] = 'query_test';
@@ -49,6 +52,9 @@ public function _testInitQuery(): void {
     $this->assertInstanceOf(QueryTestPlugin::class, $view->query);
   }
 
+  /**
+   * Executes the views query, ensures it's not empty.
+   */
   public function _testQueryExecute(): void {
     $view = Views::getView('test_view');
     $view->setDisplay();
diff --git a/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php b/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php
index 571f8d0ce0857e868b5e200ad88acc23d00f7767..1b3a2a38ad5ce6010b8f7e3dc3bac2bf59dec30a 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/SqlEntityLoadingTest.php
@@ -39,6 +39,9 @@ protected function setUp($import_test_views = TRUE): void {
     $this->installSchema('node', 'node_access');
   }
 
+  /**
+   * Tests entity loading with a non-default pending revision in Views.
+   */
   public function testViewWithNonDefaultPendingRevision(): void {
     $node_type = NodeType::create([
       'type' => 'page',
diff --git a/core/modules/views/tests/src/Kernel/ViewExecutableTest.php b/core/modules/views/tests/src/Kernel/ViewExecutableTest.php
index 011d0af37542d4ecf68f5dab7cc495f0084dadd4..13232ef15452c4cee1bf5db6717594ed9226bf39 100644
--- a/core/modules/views/tests/src/Kernel/ViewExecutableTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewExecutableTest.php
@@ -92,6 +92,9 @@ class ViewExecutableTest extends ViewsKernelTestBase {
     'parent_views',
   ];
 
+  /**
+   * Sets up the necessary fixtures for the test environment.
+   */
   protected function setUpFixtures(): void {
     $this->installEntitySchema('user');
     $this->installEntitySchema('node');
@@ -207,6 +210,9 @@ public function testProperties(): void {
     $this->assertEquals([], $view->getExposedInput());
   }
 
+  /**
+   * Tests setting a display with an invalid display ID.
+   */
   public function testSetDisplayWithInvalidDisplay(): void {
     \Drupal::service('module_installer')->install(['dblog']);
     $view = Views::getView('test_executable_displays');
diff --git a/core/modules/views/views.module b/core/modules/views/views.module
index 1a147570fda043d059d5e53b41f343dc76537a2f..17f1e89d8f4dba9824e35d183285c572de73f073 100644
--- a/core/modules/views/views.module
+++ b/core/modules/views/views.module
@@ -218,8 +218,9 @@ function views_invalidate_cache() {
  * Set the current view that is being built/rendered so that it is
  * easy for other modules or items in drupal_eval to identify
  *
- * @return \Drupal\views\ViewExecutable
- *   The current view object, or NULL if no view is set.
+ * @return \Drupal\views\ViewExecutable|null|false
+ *   The current view object, NULL if no view is set yet,
+ *   or FALSE if the view was removed.
  */
 function &views_set_current_view($view = NULL) {
   static $cache = NULL;
@@ -236,8 +237,9 @@ function &views_set_current_view($view = NULL) {
  * Note that this returns a reference, so be careful! You can unintentionally
  * modify the $view object.
  *
- * @return \Drupal\views\ViewExecutable
- *   The current view object.
+ * @return \Drupal\views\ViewExecutable|null|false
+ *   The current view object, NULL if no view is set yet,
+ *    or FALSE if the view was removed.
  */
 function &views_get_current_view() {
   return views_set_current_view();
diff --git a/core/modules/views_ui/admin.inc b/core/modules/views_ui/admin.inc
index e275797bd6984ec9f21da1f05ade1fea5ff5d256..66e5aeef2ddb6565d195a8f9491c79f86a29e108 100644
--- a/core/modules/views_ui/admin.inc
+++ b/core/modules/views_ui/admin.inc
@@ -295,7 +295,9 @@ function views_ui_build_form_url(FormStateInterface $form_state) {
 }
 
 /**
- * #process callback for a button; determines if a button is the form's triggering element.
+ * The #process callback for a button.
+ *
+ * Determines if a button is the form's triggering element.
  *
  * The Form API has logic to determine the form's triggering element based on
  * the data in POST. However, it only checks buttons based on a single #value
diff --git a/core/phpcs.xml.dist b/core/phpcs.xml.dist
index b603987bf35893030d64ce0fe8a806cef6f7127f..56abaf1edc7fa06547ed7e2beddb34b31a552011 100644
--- a/core/phpcs.xml.dist
+++ b/core/phpcs.xml.dist
@@ -61,7 +61,9 @@
       TagsNotGrouped, ParamGroup -->
     <exclude name="Drupal.Commenting.DocComment.LongFullStop"/>
     <exclude name="Drupal.Commenting.DocComment.MissingShort"/>
-    <exclude name="Drupal.Commenting.DocComment.ShortNotCapital"/>
+  </rule>
+  <rule ref="Drupal.Commenting.DocComment">
+    <exclude-pattern>core/tests/*</exclude-pattern>
   </rule>
   <rule ref="Drupal.Commenting.DocCommentAlignment"/>
   <rule ref="Drupal.Commenting.DocCommentLongArraySyntax"/>
@@ -82,6 +84,7 @@
     <include-pattern>core/modules/*/Plugin/views/style/*</include-pattern>
     <include-pattern>*/Database/*</include-pattern>
     <include-pattern>*/FunctionalJavascript/*</include-pattern>
+    <include-pattern>*/Kernel/*</include-pattern>
     <include-pattern>*/Functional/*</include-pattern>
   </rule>
   <rule ref="Drupal.Commenting.FunctionComment.MissingParamType"/>
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index acdfc9df2ed5c3a65add92ee5c8e13cb2ecf10f0..d30459033dba23604db012c156a3caee301586ca 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -75,6 +75,11 @@
       -->
       <parameter name="verbose" value="true"/>
     </bootstrap>
+    <!-- Debug dump() printer. -->
+    <bootstrap class="Drupal\TestTools\Extension\Dump\DebugDump">
+      <parameter name="colors" value="true"/>
+      <parameter name="printCaller" value="true"/>
+    </bootstrap>
   </extensions>
   <testsuites>
     <testsuite name="unit">
diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php
index 9cb51a0598e8e6f88a75f204135a996794b8b540..896e825d62f22f47389f8c472b42ac5652d2a408 100644
--- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php
+++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php
@@ -30,7 +30,7 @@ public function testFrontAndRecipesPages(): void {
       'ScriptCount' => 1,
       'ScriptBytes' => 11700,
       'StylesheetCount' => 6,
-      'StylesheetBytes' => 124450,
+      'StylesheetBytes' => 121000,
     ];
     $this->assertMetrics($expected, $performance_data);
   }
diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
index c96d9fe2e2e70e223d88bfa1049fe09e6fe28840..4ff48563bbbb4ab6181e932938af05755192aed5 100644
--- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
+++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryAuthenticatedPerformanceTest.php
@@ -61,14 +61,12 @@ public function testFrontPageAuthenticatedWarmCache(): void {
       ],
       'CacheSetCount' => 0,
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 0,
-      'CacheTagIsValidCount' => 10,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 2,
       'ScriptCount' => 1,
       'ScriptBytes' => 123850,
       'StylesheetCount' => 2,
-      'StylesheetBytes' => 43600,
+      'StylesheetBytes' => 42500,
     ];
     $this->assertMetrics($expected, $performance_data);
   }
diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php
index ff5d5c79ea5ac7d79e4629c84cc98363ea4d2f21..1157448a7828094fbcb9f7b9271198462967b738 100644
--- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php
+++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryFrontPagePerformanceTest.php
@@ -73,14 +73,12 @@ protected function testFrontPageHotCache(): void {
       'CacheGetCount' => 1,
       'CacheSetCount' => 0,
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 0,
-      'CacheTagIsValidCount' => 1,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 1,
       'ScriptCount' => 1,
       'ScriptBytes' => 11850,
       'StylesheetCount' => 2,
-      'StylesheetBytes' => 41200,
+      'StylesheetBytes' => 40000,
     ];
     $this->assertMetrics($expected, $performance_data);
   }
diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php
index ce81a01c276f8d758445102fdc3297116f496226..b4afcab88a9fae564706494623597656123bc2ed 100644
--- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php
+++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/OpenTelemetryNodePagePerformanceTest.php
@@ -66,8 +66,7 @@ protected function testNodePageHotCache(): void {
       'CacheGetCount' => 1,
       'CacheSetCount' => 0,
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 0,
-      'CacheTagIsValidCount' => 1,
+      'CacheTagLookupQueryCount' => 1,
     ];
     $this->assertMetrics($expected, $performance_data);
   }
diff --git a/core/profiles/demo_umami/themes/umami/templates/classy/form/form-element.html.twig b/core/profiles/demo_umami/themes/umami/templates/classy/form/form-element.html.twig
index cb512f4582bc7f4d065779f868c4e2651e9238cd..a89d726c6f236a79e4399221db65b5e762c1ecb0 100644
--- a/core/profiles/demo_umami/themes/umami/templates/classy/form/form-element.html.twig
+++ b/core/profiles/demo_umami/themes/umami/templates/classy/form/form-element.html.twig
@@ -71,7 +71,7 @@
     <span class="field-prefix">{{ prefix }}</span>
   {% endif %}
   {% if description_display == 'before' and description.content %}
-    <div{{ description.attributes }}>
+    <div{{ description.attributes.addClass(description_classes) }}>
       {{ description.content }}
     </div>
   {% endif %}
diff --git a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
index c43fa6f9f7e2189d330e9f7b3aa254f3615c1549..0c3d7300ea33ef4af10df7600b7f834c837cf926 100644
--- a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
+++ b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
@@ -142,8 +142,6 @@ protected function testAnonymous(): void {
       ],
       'CacheSetCount' => 45,
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 38,
-      'CacheTagIsValidCount' => 43,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 21,
       'CacheTagGroupedLookups' => [
@@ -170,7 +168,7 @@ protected function testAnonymous(): void {
         ['config:user.role.anonymous'],
       ],
       'StylesheetCount' => 1,
-      'StylesheetBytes' => 3450,
+      'StylesheetBytes' => 2250,
     ];
     $this->assertMetrics($expected, $performance_data);
     $expected_default_cache_cids = [
@@ -202,8 +200,6 @@ protected function testAnonymous(): void {
     ];
     $recorded_queries = $performance_data->getQueries();
     $this->assertSame($expected_queries, $recorded_queries);
-    $this->assertCountBetween(24, 25, $performance_data->getCacheTagChecksumCount());
-    $this->assertCountBetween(38, 39, $performance_data->getCacheTagIsValidCount());
     $expected = [
       'QueryCount' => 10,
       'CacheGetCount' => 92,
@@ -232,7 +228,7 @@ protected function testAnonymous(): void {
         ['config:user.role.anonymous'],
       ],
       'StylesheetCount' => 1,
-      'StylesheetBytes' => 3150,
+      'StylesheetBytes' => 2250,
     ];
     $this->assertMetrics($expected, $performance_data);
 
@@ -266,12 +262,10 @@ protected function testAnonymous(): void {
       'CacheGetCount' => 80,
       'CacheSetCount' => 17,
       'CacheDeleteCount' => 0,
-      'CacheTagChecksumCount' => 23,
-      'CacheTagIsValidCount' => 33,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 16,
       'StylesheetCount' => 1,
-      'StylesheetBytes' => 3150,
+      'StylesheetBytes' => 1950,
     ];
     $this->assertMetrics($expected, $performance_data);
   }
@@ -323,8 +317,6 @@ protected function testLogin(): void {
       'CacheGetCount' => 84,
       'CacheSetCount' => 1,
       'CacheDeleteCount' => 1,
-      'CacheTagChecksumCount' => 1,
-      'CacheTagIsValidCount' => 37,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 17,
       'CacheTagGroupedLookups' => [
@@ -402,8 +394,6 @@ protected function testLoginBlock(): void {
       'CacheGetCount' => 103,
       'CacheSetCount' => 1,
       'CacheDeleteCount' => 1,
-      'CacheTagChecksumCount' => 1,
-      'CacheTagIsValidCount' => 41,
       'CacheTagInvalidationCount' => 0,
       'CacheTagLookupQueryCount' => 19,
     ];
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 04e1f2c05258b7f2fdd7975d5bf6d93892c6399b..17a9e294295be5fbfc67a630eb90c043d125ac35 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -659,12 +659,9 @@ function simpletest_script_setup_database($new = FALSE) {
     $databases['default'] = Database::getConnectionInfo('default');
   }
 
-  // If there is no default database connection for tests, we cannot continue.
-  if (!isset($databases['default']['default'])) {
-    simpletest_script_print_error('Missing default database connection for tests. Use --dburl to specify one.');
-    exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
+  if (isset($databases['default']['default'])) {
+    Database::addConnectionInfo('default', 'default', $databases['default']['default']);
   }
-  Database::addConnectionInfo('default', 'default', $databases['default']['default']);
 }
 
 /**
diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
index b817f270486c0e83b1d3626fa29571e87b8794b2..e074fb1a162271553468b682bfa80a83b742cb82 100644
--- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
+++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
@@ -9,10 +9,9 @@
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Url;
 use Drupal\Tests\BrowserTestBase;
-use Drupal\Tests\StreamCapturer;
 use Drupal\Tests\Traits\Core\CronRunTrait;
 use Drupal\Tests\Traits\Core\PathAliasTestTrait;
-use Drupal\user\Entity\Role;
+use Drupal\TestTools\Extension\Dump\DebugDump;
 use PHPUnit\Framework\ExpectationFailedException;
 
 // cspell:ignore htkey
@@ -601,20 +600,19 @@ public function testDeprecationHeaders(): void {
    * Tests the dump() function provided by the var-dumper Symfony component.
    */
   public function testVarDump(): void {
-    // Append the stream capturer to the STDERR stream, so that we can test the
-    // dump() output and also prevent it from actually outputting in this
-    // particular test.
-    stream_filter_register("capture", StreamCapturer::class);
-    stream_filter_append(STDERR, "capture");
+    // Dump some variables.
+    $object = (object) [
+      'Aldebaran' => 'Betelgeuse',
+    ];
+    dump($object);
+    dump('Alpheratz');
 
-    // Dump some variables to check that dump() in test code produces output
-    // on the command line that is running the test.
-    $role = Role::load('authenticated');
-    dump($role);
-    dump($role->id());
+    $dumpString = json_encode(DebugDump::getDumps());
 
-    $this->assertStringContainsString('Drupal\user\Entity\Role', StreamCapturer::$cache);
-    $this->assertStringContainsString('authenticated', StreamCapturer::$cache);
+    $this->assertStringContainsString('BrowserTestBaseTest::testVarDump', $dumpString);
+    $this->assertStringContainsString('Aldebaran', $dumpString);
+    $this->assertStringContainsString('Betelgeuse', $dumpString);
+    $this->assertStringContainsString('Alpheratz', $dumpString);
 
     // Visit a Drupal page with call to the dump() function to check that dump()
     // in site code produces output in the requested web page's HTML.
@@ -630,6 +628,9 @@ public function testVarDump(): void {
     $this->assertStringContainsString('  #<span class=sf-dump-protected title="Protected property">permissions</span>: []', $body);
     $this->assertStringContainsString('  #<span class=sf-dump-protected title="Protected property">uuid</span>: "', $body);
     $this->assertStringContainsString('</samp>}', $body);
+
+    // Check that dump() in SUT did not leak into the test's dumps.
+    $this->assertSame($dumpString, json_encode(DebugDump::getDumps()));
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php b/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php
index e878000fd3cde144a2dfdca2bcc5314d7be9d06a..8047dc5401647789851aba4d9300e35c8550a44a 100644
--- a/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php
+++ b/core/tests/Drupal/KernelTests/Core/Cache/GenericCacheBackendUnitTestBase.php
@@ -148,7 +148,6 @@ protected function tearDown(): void {
   public function testSetGet(): void {
     $backend = $this->getCacheBackend();
 
-    $this->assertFalse($backend->get('test1'), "Backend does not contain data for cache id test1.");
     $with_backslash = ['foo' => '\Drupal\foo\Bar'];
     $backend->set('test1', $with_backslash);
     $cached = $backend->get('test1');
@@ -160,7 +159,6 @@ public function testSetGet(): void {
     $this->assertLessThanOrEqual(round(microtime(TRUE), 3), $cached->created);
     $this->assertEquals(Cache::PERMANENT, $cached->expire, 'Expire time is correct.');
 
-    $this->assertFalse($backend->get('test2'), "Backend does not contain data for cache id test2.");
     $backend->set('test2', ['value' => 3], \Drupal::time()->getRequestTime() + 3);
     $cached = $backend->get('test2');
     $this->assertIsObject($cached);
@@ -179,7 +177,6 @@ public function testSetGet(): void {
     $this->assertLessThanOrEqual(round(microtime(TRUE), 3), $cached->created);
     $this->assertEquals(\Drupal::time()->getRequestTime() - 3, $cached->expire, 'Expire time is correct.');
 
-    $this->assertFalse($backend->get('test4'), "Backend does not contain data for cache id test4.");
     $with_eof = ['foo' => "\nEOF\ndata"];
     $backend->set('test4', $with_eof);
     $cached = $backend->get('test4');
@@ -190,7 +187,6 @@ public function testSetGet(): void {
     $this->assertLessThanOrEqual(round(microtime(TRUE), 3), $cached->created);
     $this->assertEquals(Cache::PERMANENT, $cached->expire, 'Expire time is correct.');
 
-    $this->assertFalse($backend->get('test5'), "Backend does not contain data for cache id test5.");
     $with_eof_and_semicolon = ['foo' => "\nEOF;\ndata"];
     $backend->set('test5', $with_eof_and_semicolon);
     $cached = $backend->get('test5');
@@ -265,11 +261,9 @@ public function testSetGet(): void {
   public function testDelete(): void {
     $backend = $this->getCacheBackend();
 
-    $this->assertFalse($backend->get('test1'), "Backend does not contain data for cache id test1.");
     $backend->set('test1', 7);
     $this->assertIsObject($backend->get('test1'));
 
-    $this->assertFalse($backend->get('test2'), "Backend does not contain data for cache id test2.");
     $backend->set('test2', 3);
     $this->assertIsObject($backend->get('test2'));
 
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
index d560fd3eee64766866b934098c18a9dbff6c5553..d6116be9480a92f7dcfe88e917c7c34275148089 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
@@ -6,6 +6,7 @@
 
 use Drupal\Core\Database\Database;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityStorageException;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog;
 use Drupal\user\Entity\User;
@@ -152,6 +153,8 @@ public function testWasDefaultRevision(): void {
     $this->assertTrue($entity->wasDefaultRevision());
 
     // Check that the "revision_default" flag cannot be changed once set.
+    $this->expectException(EntityStorageException::class);
+    $this->expectExceptionMessage("An existing default revision of the 'entity_test_mul_revlog' entity type can not be changed to a non-default revision.");
     /** @var \Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog $entity2 */
     $entity2 = EntityTestMulWithRevisionLog::create([
       'type' => $entity_type_id,
diff --git a/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php b/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php
index b381db560e9a8d7dfa1eb4a343cbf66fb94a1879..0af94a8d8dc34f39c8a5ed73d4c1e2e6bc79cb84 100644
--- a/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Render/Element/RenderElementTypesTest.php
@@ -237,4 +237,99 @@ public function testSystemCompactLink(): void {
     $this->assertNotEmpty($result, '"' . $element['name'] . '" is rendered correctly.');
   }
 
+  /**
+   * Tests system #type 'link'.
+   */
+  public function testLink(): void {
+    $elements = [
+      [
+        'name' => "#type 'link' simple anchor tag",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org'),
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and text()="title"]',
+      ],
+      [
+        'name' => "#type 'link' anchor tag with extra classes in ['#attributes']",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org'),
+          '#attributes' => [
+            'class' => ['attributes-class'],
+          ],
+          '#options' => [],
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and @class="attributes-class" and text()="title"]',
+      ],
+      [
+        'name' => "#type 'link' anchor tag with extra classes in ['#options']['attributes']",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org'),
+          '#attributes' => [],
+          '#options' => [
+            'attributes' => [
+              'class' => ['options-attributes-class'],
+            ],
+          ],
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and @class="options-attributes-class" and text()="title"]',
+      ],
+      [
+        'name' => "#type 'link' anchor tag with extra classes in both ['#attributes'] and ['#options']['attributes']",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org'),
+          '#attributes' => [
+            'class' => ['attributes-class'],
+          ],
+          '#options' => [
+            'attributes' => [
+              'class' => ['options-attributes-class'],
+            ],
+          ],
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and @class="options-attributes-class attributes-class" and text()="title"]',
+      ],
+      [
+        'name' => "#type 'link' anchor tag with extra classes in both ['#attributes'] and ['#options']['attributes'] as strings",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org'),
+          '#attributes' => [
+            'class' => 'attributes-class',
+          ],
+          '#options' => [
+            'attributes' => [
+              'class' => 'options-attributes-class',
+            ],
+          ],
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and contains(@class,"options-attributes-class") and contains(@class,"attributes-class") and text()="title"]',
+      ],
+      [
+        'name' => "#type 'link' anchor tag with extra classes in Url object ['#options']['attributes'] which are ignored",
+        'value' => [
+          '#type' => 'link',
+          '#title' => 'title',
+          '#url' => Url::fromUri('https://www.drupal.org')->setOption('attributes', ['class' => 'url-options-attributes-class']),
+          '#attributes' => [],
+          '#options' => [],
+        ],
+        'expected' => '//a[@href="https://www.drupal.org" and not(@class) and text()="title"]',
+      ],
+    ];
+    foreach ($elements as $element) {
+      $xml = new \SimpleXMLElement((string) \Drupal::service('renderer')->renderRoot($element['value']));
+      $result = $xml->xpath($element['expected']);
+      $this->assertNotEmpty($result, '"' . $element['name'] . '" input rendered correctly.');
+    }
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 941ead868bd36c5065fcd9b27968920cdc02a5f0..801a6ad7b3ff225702a097b70c94ab77a54043e3 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -26,9 +26,10 @@
 use Drupal\Tests\TestRequirementsTrait;
 use Drupal\TestTools\Comparator\MarkupInterfaceComparator;
 use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait;
+use Drupal\TestTools\Extension\Dump\DebugDump;
 use Drupal\TestTools\Extension\SchemaInspector;
-use Drupal\TestTools\TestVarDumper;
 use PHPUnit\Framework\Attributes\After;
+use PHPUnit\Framework\Attributes\BeforeClass;
 use PHPUnit\Framework\Exception;
 use PHPUnit\Framework\TestCase;
 use Prophecy\PhpUnit\ProphecyTrait;
@@ -209,11 +210,13 @@ public function __construct(string $name) {
   protected bool $usesSuperUserAccessPolicy;
 
   /**
-   * {@inheritdoc}
+   * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
-  public static function setUpBeforeClass(): void {
-    parent::setUpBeforeClass();
-    VarDumper::setHandler(TestVarDumper::class . '::cliHandler');
+  #[BeforeClass]
+  public static function setDebugDumpHandler(): void {
+    if (DebugDump::isEnabled()) {
+      VarDumper::setHandler(DebugDump::class . '::cliHandler');
+    }
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
index 155a0bee2a8e7b16517a4a965a62d38d776defd7..db658255c82ac84adc1ef60382bfd0d1de608174 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
@@ -6,8 +6,7 @@
 
 use Drupal\Component\FileCache\FileCacheFactory;
 use Drupal\Core\Database\Database;
-use Drupal\Tests\StreamCapturer;
-use Drupal\user\Entity\Role;
+use Drupal\TestTools\Extension\Dump\DebugDump;
 use org\bovigo\vfs\vfsStream;
 use org\bovigo\vfs\visitor\vfsStreamStructureVisitor;
 use PHPUnit\Framework\Attributes\DoesNotPerformAssertions;
@@ -305,20 +304,19 @@ public function testProfileModules(): void {
    * Tests the dump() function provided by the var-dumper Symfony component.
    */
   public function testVarDump(): void {
-    // Append the stream capturer to the STDERR stream, so that we can test the
-    // dump() output and also prevent it from actually outputting in this
-    // particular test.
-    stream_filter_register("capture", StreamCapturer::class);
-    stream_filter_append(STDERR, "capture");
-
     // Dump some variables.
-    $this->enableModules(['system', 'user']);
-    $role = Role::create(['id' => 'test_role', 'label' => 'Test role']);
-    dump($role);
-    dump($role->id());
+    $object = (object) [
+      'Aldebaran' => 'Betelgeuse',
+    ];
+    dump($object);
+    dump('Alpheratz');
+
+    $dumpString = json_encode(DebugDump::getDumps());
 
-    $this->assertStringContainsString('Drupal\user\Entity\Role', StreamCapturer::$cache);
-    $this->assertStringContainsString('test_role', StreamCapturer::$cache);
+    $this->assertStringContainsString('KernelTestBaseTest::testVarDump', $dumpString);
+    $this->assertStringContainsString('Aldebaran', $dumpString);
+    $this->assertStringContainsString('Betelgeuse', $dumpString);
+    $this->assertStringContainsString('Alpheratz', $dumpString);
   }
 
   /**
diff --git a/core/tests/Drupal/TestTools/Extension/Dump/DebugDump.php b/core/tests/Drupal/TestTools/Extension/Dump/DebugDump.php
new file mode 100644
index 0000000000000000000000000000000000000000..2289c4f54d4906c772fe61536724b6277561a538
--- /dev/null
+++ b/core/tests/Drupal/TestTools/Extension/Dump/DebugDump.php
@@ -0,0 +1,244 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\TestTools\Extension\Dump;
+
+use PHPUnit\Event\TestRunner\Finished as TestRunnerFinished;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Runner\Extension\Extension;
+use PHPUnit\Runner\Extension\Facade;
+use PHPUnit\Runner\Extension\ParameterCollection;
+use PHPUnit\TextUI\Configuration\Configuration;
+use Symfony\Component\VarDumper\Cloner\VarCloner;
+use Symfony\Component\VarDumper\Dumper\CliDumper;
+
+/**
+ * Drupal's extension for printing dump() output results.
+ *
+ * @internal
+ */
+final class DebugDump implements Extension {
+
+  /**
+   * The path to the dump staging file.
+   */
+  private static string $stagingFilePath;
+
+  /**
+   * Whether colors should be used for printing.
+   */
+  private static bool $colors = FALSE;
+
+  /**
+   * Whether the caller of dump should be included in the report.
+   */
+  private static bool $printCaller = FALSE;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bootstrap(
+    Configuration $configuration,
+    Facade $facade,
+    ParameterCollection $parameters,
+  ): void {
+    // Determine staging file path.
+    self::$stagingFilePath = tempnam(sys_get_temp_dir(), 'dpd');
+
+    // Determine color output.
+    $colors = $parameters->has('colors') ? $parameters->get('colors') : FALSE;
+    self::$colors = filter_var($colors, \FILTER_VALIDATE_BOOLEAN);
+
+    // Print caller.
+    $printCaller = $parameters->has('printCaller') ? $parameters->get('printCaller') : FALSE;
+    self::$printCaller = filter_var($printCaller, \FILTER_VALIDATE_BOOLEAN);
+
+    // Set the environment variable with the configuration.
+    $config = json_encode([
+      'stagingFilePath' => self::$stagingFilePath,
+      'colors' => self::$colors,
+      'printCaller' => self::$printCaller,
+    ]);
+    putenv('DRUPAL_PHPUNIT_DUMPER_CONFIG=' . $config);
+
+    $facade->registerSubscriber(new TestRunnerFinishedSubscriber($this));
+  }
+
+  /**
+   * Determines if the extension is enabled.
+   *
+   * @return bool
+   *   TRUE if enabled, FALSE if disabled.
+   */
+  public static function isEnabled(): bool {
+    return getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG') !== FALSE;
+  }
+
+  /**
+   * A CLI handler for \Symfony\Component\VarDumper\VarDumper.
+   *
+   * @param mixed $var
+   *   The variable to be dumped.
+   */
+  public static function cliHandler(mixed $var): void {
+    if (!self::isEnabled()) {
+      return;
+    }
+    $config = (array) json_decode(getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG'));
+
+    $caller = self::getCaller();
+
+    $cloner = new VarCloner();
+    $dumper = new CliDumper();
+    $dumper->setColors($config['colors']);
+    $dump = [];
+    $dumper->dump(
+      $cloner->cloneVar($var),
+      function ($line, $depth, $indent_pad) use (&$dump) {
+        // A negative depth means "end of dump".
+        if ($depth >= 0) {
+          // Adds a two spaces indentation to the line.
+          $dump[] = str_repeat($indent_pad, $depth) . $line;
+        }
+      }
+    );
+
+    file_put_contents(
+      $config['stagingFilePath'],
+      self::encodeDump($caller['test']->id(), $caller['file'], $caller['line'], $dump) . "\n",
+      FILE_APPEND,
+    );
+  }
+
+  /**
+   * Encodes the dump for storing.
+   *
+   * @param string $testId
+   *   The id of the test from where the dump was called.
+   * @param string|null $file
+   *   The path of the file from where the dump was called.
+   * @param int|null $line
+   *   The line number from where the dump was called.
+   * @param array $dump
+   *   The dump as an array of lines.
+   *
+   * @return string
+   *   An encoded string.
+   */
+  private static function encodeDump(string $testId, ?string $file, ?int $line, array $dump): string {
+    $data = [
+      'test' => $testId,
+      'file' => $file,
+      'line' => $line,
+      'dump' => $dump,
+    ];
+    $jsonData = json_encode($data);
+    return base64_encode($jsonData);
+  }
+
+  /**
+   * Decodes a dump retrieved from storage.
+   *
+   * @param string $encodedData
+   *   An encoded string.
+   *
+   * @return array{test: string, file: string|null, line: int|null, dump: string[]}
+   *   An encoded string.
+   */
+  private static function decodeDump(string $encodedData): array {
+    $jsonData = base64_decode($encodedData);
+    return (array) json_decode($jsonData);
+  }
+
+  /**
+   * Returns information about the caller of dump().
+   *
+   * @return array{test: \PHPUnit\Framework\Event\Code\TestMethod, file: string|null, line: int|null}
+   *   Caller information.
+   */
+  private static function getCaller(): array {
+    $backtrace = debug_backtrace();
+
+    while (!isset($backtrace[0]['function']) || $backtrace[0]['function'] !== 'dump') {
+      array_shift($backtrace);
+    }
+    $call['file'] = $backtrace[1]['file'] ?? NULL;
+    $call['line'] = $backtrace[1]['line'] ?? NULL;
+
+    while (!isset($backtrace[0]['object']) || !($backtrace[0]['object'] instanceof TestCase)) {
+      array_shift($backtrace);
+    }
+    $call['test'] = $backtrace[0]['object']->valueObjectForEvents();
+
+    return $call;
+  }
+
+  /**
+   * Retrieves dumps from storage.
+   *
+   * @return array{string, array{file: string|null, line: int|null, dump: string[]}}
+   *   Caller information.
+   */
+  public static function getDumps(): array {
+    if (!self::isEnabled()) {
+      return [];
+    }
+    $config = (array) json_decode(getenv('DRUPAL_PHPUNIT_DUMPER_CONFIG'));
+    $contents = rtrim(file_get_contents($config['stagingFilePath']));
+    if (empty($contents)) {
+      return [];
+    }
+    $encodedDumps = explode("\n", $contents);
+    $dumps = [];
+    foreach ($encodedDumps as $encodedDump) {
+      $dump = self::decodeDump($encodedDump);
+      $test = $dump['test'];
+      unset($dump['test']);
+      $dumps[$test][] = $dump;
+    }
+    return $dumps;
+  }
+
+  /**
+   * Prints the dumps generated during the test.
+   */
+  public function testRunnerFinished(TestRunnerFinished $event): void {
+    $dumps = self::getDumps();
+
+    // Cleanup.
+    unlink(self::$stagingFilePath);
+    putenv('DRUPAL_PHPUNIT_DUMPER_CONFIG');
+
+    if ($dumps === []) {
+      return;
+    }
+
+    print "\n\n";
+
+    print "dump() output\n";
+    print "-------------\n\n";
+
+    foreach ($dumps as $testId => $testDumps) {
+      if (self::$printCaller) {
+        print $testId . "\n";
+      }
+      foreach ($testDumps as $dump) {
+        if (self::$printCaller) {
+          print "in " . $dump['file'] . ", line " . $dump['line'] . ":\n";
+        }
+        foreach ($dump['dump'] as $line) {
+          print $line . "\n";
+        }
+        if (self::$printCaller) {
+          print "\n";
+        }
+      }
+      if (self::$printCaller) {
+        print "\n";
+      }
+    }
+
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/Extension/Dump/TestRunnerFinishedSubscriber.php b/core/tests/Drupal/TestTools/Extension/Dump/TestRunnerFinishedSubscriber.php
new file mode 100644
index 0000000000000000000000000000000000000000..141e33555a06bf55de3bbd1e82883a757b105c19
--- /dev/null
+++ b/core/tests/Drupal/TestTools/Extension/Dump/TestRunnerFinishedSubscriber.php
@@ -0,0 +1,26 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\TestTools\Extension\Dump;
+
+use PHPUnit\Event\TestRunner\Finished;
+use PHPUnit\Event\TestRunner\FinishedSubscriber;
+
+/**
+ * Event subscriber notifying end of test runner execution to HTML logging.
+ *
+ * @internal
+ */
+final class TestRunnerFinishedSubscriber implements FinishedSubscriber {
+
+  public function __construct(
+    private readonly DebugDump $dump,
+  ) {
+  }
+
+  public function notify(Finished $event): void {
+    $this->dump->testRunnerFinished($event);
+  }
+
+}
diff --git a/core/tests/Drupal/TestTools/TestVarDumper.php b/core/tests/Drupal/TestTools/TestVarDumper.php
deleted file mode 100644
index dbf5af90f971807d885bfc0ba82bfbc2fcb333bc..0000000000000000000000000000000000000000
--- a/core/tests/Drupal/TestTools/TestVarDumper.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\TestTools;
-
-use Symfony\Component\VarDumper\Cloner\VarCloner;
-use Symfony\Component\VarDumper\Dumper\CliDumper;
-use Symfony\Component\VarDumper\Dumper\HtmlDumper;
-
-/**
- * Provides handlers for the Symfony VarDumper to work within tests.
- *
- * This allows the dump() function to produce output on the terminal without
- * causing PHPUnit to complain.
- */
-class TestVarDumper {
-
-  /**
-   * A CLI handler for \Symfony\Component\VarDumper\VarDumper.
-   */
-  public static function cliHandler($var) {
-    $cloner = new VarCloner();
-    $dumper = new CliDumper();
-    fwrite(STDERR, "\n");
-    $dumper->setColors(TRUE);
-    $dumper->dump(
-      $cloner->cloneVar($var),
-      function ($line, $depth, $indent_pad) {
-        // A negative depth means "end of dump".
-        if ($depth >= 0) {
-          // Adds a two spaces indentation to the line.
-          fwrite(STDERR, str_repeat($indent_pad, $depth) . $line . "\n");
-        }
-      }
-    );
-  }
-
-  /**
-   * A HTML handler for \Symfony\Component\VarDumper\VarDumper.
-   */
-  public static function htmlHandler($var) {
-    $cloner = new VarCloner();
-    $dumper = new HtmlDumper();
-    $dumper->dump($cloner->cloneVar($var));
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 101de445b437289905ea293649036c936a6dd01e..457e22286f45a1adcfdd6d3ac62b6fc840c569db 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -22,8 +22,9 @@
 use Drupal\Tests\user\Traits\UserCreationTrait;
 use Drupal\TestTools\Comparator\MarkupInterfaceComparator;
 use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait;
-use Drupal\TestTools\TestVarDumper;
+use Drupal\TestTools\Extension\Dump\DebugDump;
 use GuzzleHttp\Cookie\CookieJar;
+use PHPUnit\Framework\Attributes\BeforeClass;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\VarDumper\VarDumper;
 
@@ -190,11 +191,13 @@ public function __construct(string $name) {
   }
 
   /**
-   * {@inheritdoc}
+   * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
-  public static function setUpBeforeClass(): void {
-    parent::setUpBeforeClass();
-    VarDumper::setHandler(TestVarDumper::class . '::cliHandler');
+  #[BeforeClass]
+  public static function setDebugDumpHandler(): void {
+    if (DebugDump::isEnabled()) {
+      VarDumper::setHandler(DebugDump::class . '::cliHandler');
+    }
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Access/CsrfAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Access/CsrfAccessCheckTest.php
index 34bb870ef4819360046949a9fe828fa172ce7d13..00758a9338d60ea0c0833856872e5b0345b5293f 100644
--- a/core/tests/Drupal/Tests/Core/Access/CsrfAccessCheckTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/CsrfAccessCheckTest.php
@@ -5,6 +5,9 @@
 namespace Drupal\Tests\Core\Access;
 
 use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Access\CsrfTokenGenerator;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 use Drupal\Core\Access\CsrfAccessCheck;
@@ -18,24 +21,23 @@ class CsrfAccessCheckTest extends UnitTestCase {
 
   /**
    * The mock CSRF token generator.
-   *
-   * @var \Drupal\Core\Access\CsrfTokenGenerator|\PHPUnit\Framework\MockObject\MockObject
    */
-  protected $csrfToken;
+  protected CsrfTokenGenerator $csrfToken;
 
   /**
    * The access checker.
-   *
-   * @var \Drupal\Core\Access\CsrfAccessCheck
    */
-  protected $accessCheck;
+  protected CsrfAccessCheck $accessCheck;
 
   /**
    * The mock route match.
-   *
-   * @var \Drupal\Core\Routing\RouteMatchInterface|\PHPUnit\Framework\MockObject\MockObject
    */
-  protected $routeMatch;
+  protected RouteMatchInterface $routeMatch;
+
+  /**
+   * The mock parameter bag.
+   */
+  protected ParameterBagInterface $parameterBag;
 
   /**
    * {@inheritdoc}
@@ -43,11 +45,13 @@ class CsrfAccessCheckTest extends UnitTestCase {
   protected function setUp(): void {
     parent::setUp();
 
-    $this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
+    $this->csrfToken = $this->getMockBuilder(CsrfTokenGenerator::class)
       ->disableOriginalConstructor()
       ->getMock();
 
-    $this->routeMatch = $this->createMock('Drupal\Core\Routing\RouteMatchInterface');
+    $this->parameterBag = $this->createMock(ParameterBagInterface::class);
+
+    $this->routeMatch = $this->createMock(RouteMatchInterface::class);
 
     $this->accessCheck = new CsrfAccessCheck($this->csrfToken);
   }
@@ -61,9 +65,13 @@ public function testAccessTokenPass(): void {
       ->with('test_query', 'test-path/42')
       ->willReturn(TRUE);
 
+    $this->parameterBag
+      ->method('all')
+      ->willReturn(['node' => 42]);
+
     $this->routeMatch->expects($this->once())
       ->method('getRawParameters')
-      ->willReturn(['node' => 42]);
+      ->willReturn($this->parameterBag);
 
     $route = new Route('/test-path/{node}', [], ['_csrf_token' => 'TRUE']);
     $request = Request::create('/test-path/42?token=test_query');
@@ -80,9 +88,13 @@ public function testCsrfTokenInvalid(): void {
       ->with('test_query', 'test-path')
       ->willReturn(FALSE);
 
+    $this->parameterBag
+      ->method('all')
+      ->willReturn([]);
+
     $this->routeMatch->expects($this->once())
       ->method('getRawParameters')
-      ->willReturn([]);
+      ->willReturn($this->parameterBag);
 
     $route = new Route('/test-path', [], ['_csrf_token' => 'TRUE']);
     $request = Request::create('/test-path?token=test_query');
@@ -99,9 +111,13 @@ public function testCsrfTokenMissing(): void {
       ->with('', 'test-path')
       ->willReturn(FALSE);
 
+    $this->parameterBag
+      ->method('all')
+      ->willReturn([]);
+
     $this->routeMatch->expects($this->once())
       ->method('getRawParameters')
-      ->willReturn([]);
+      ->willReturn($this->parameterBag);
 
     $route = new Route('/test-path', [], ['_csrf_token' => 'TRUE']);
     $request = Request::create('/test-path');
diff --git a/core/tests/Drupal/Tests/Core/Access/RoutePathGenerationTraitTest.php b/core/tests/Drupal/Tests/Core/Access/RoutePathGenerationTraitTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..56c4766bca8e569a0696b28888441c6dfc5f8803
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Access/RoutePathGenerationTraitTest.php
@@ -0,0 +1,132 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\Tests\Core\Access;
+
+use Drupal\Core\Access\AccessResultAllowed;
+use Drupal\Core\Access\CsrfAccessCheck;
+use Drupal\Core\Access\CsrfTokenGenerator;
+use Drupal\Core\Access\RouteProcessorCsrf;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
+use Symfony\Component\HttpFoundation\InputBag;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\Routing\Route;
+
+/**
+ * @covers \Drupal\Core\Access\RoutePathGenerationTrait
+ * @group Access
+ */
+class RoutePathGenerationTraitTest extends UnitTestCase {
+
+  /**
+   * The mock CSRF token generator.
+   */
+  protected CsrfTokenGenerator $csrfToken;
+
+  /**
+   * The request stack.
+   */
+  protected RequestStack $requestStack;
+
+  /**
+   * The route processor.
+   */
+  protected RouteProcessorCsrf $processor;
+
+  /**
+   * The CSRF access checker.
+   */
+  protected CsrfAccessCheck $accessCheck;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+    $this->csrfToken = $this->getMockBuilder(CsrfTokenGenerator::class)
+      ->disableOriginalConstructor()
+      ->getMock();
+    // Make CsrfTokenGenerator mock use a simple hash of the value passed as
+    // parameter, as it is enough for the sake of our tests.
+    $this->csrfToken->method('get')->willReturnCallback(function ($value) {
+      return hash('sha256', $value);
+    });
+    $this->csrfToken->method('validate')->willReturnCallback(function ($token, $value) {
+      return $token === hash('sha256', $value);
+    });
+    $this->requestStack = $this->createMock(RequestStack::class);
+    $this->processor = new RouteProcessorCsrf($this->csrfToken, $this->requestStack);
+    $this->accessCheck = new CsrfAccessCheck($this->csrfToken);
+  }
+
+  /**
+   * Tests that CSRF token creation and validation is consistent.
+   *
+   * This checks that CsrfAccessCheck() and RouteProcessorCsrf() produce the
+   * same results.
+   *
+   * Multiple cases are provided for an optional parameter (non-empty, empty,
+   * null, undefined).
+   *
+   * @dataProvider providerTestCsrfTokenCompleteLifeCycle
+   */
+  public function testCsrfTokenCompleteLifeCycle($params): void {
+
+    // Mock a route.
+    $route = $this->createMock(Route::class);
+    $route
+      ->method('getPath')
+      ->willReturn('test/example/{param}');
+    $route
+      ->method('hasRequirement')
+      ->with('_csrf_token')
+      ->willReturn(TRUE);
+
+    // Process the route so the "token" param is generated.
+    $routeParams = $params;
+    $this->processor->processOutbound('test.example', $route, $routeParams);
+
+    $requestParams = $params + ['token' => $routeParams['token']];
+
+    // Mock Parameter bag.
+    $parameterBag = $this->createMock(ParameterBagInterface::class);
+    $parameterBag->method('get')->willReturnCallback(function ($key, $default = NULL) use ($requestParams) {
+      return $requestParams[$key] ?? $default;
+    });
+    $parameterBag->method('all')->willReturn($requestParams);
+
+    // Get a real InputBag because it is a final class.
+    $inputBag = new InputBag($requestParams);
+
+    // Mock Request.
+    $request = $this->createMock(Request::class);
+    $request->query = $inputBag;
+
+    // Mock RouteMatch.
+    $routeMatch = $this->createMock(RouteMatchInterface::class);
+    $routeMatch->method('getRawParameters')->willReturn($parameterBag);
+
+    // Check for allowed access.
+    $this->assertInstanceOf(AccessResultAllowed::class, $this->accessCheck->access($route, $request, $routeMatch));
+  }
+
+  /**
+   * Data provider for testCsrfTokenCompleteLifeCycle().
+   *
+   * @return array
+   *   An array of route parameters.
+   */
+  public static function providerTestCsrfTokenCompleteLifeCycle(): array {
+    return [
+      [['param' => 'value']],
+      [['param' => '']],
+      [['param' => NULL]],
+      [[]],
+    ];
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
index ca505d6bd029dc032b5b9c474db08b890c56b0e4..2e8125f331d8ca564d06757b28b96dd8593374d7 100644
--- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
@@ -281,6 +281,7 @@ public function testIsDefaultRevision(): void {
     // The last call changed the return value for this call.
     $this->assertFalse($this->entity->isDefaultRevision());
     // The revision for a new entity should always be the default revision.
+    $this->entity->isDefaultRevision(TRUE);
     $this->entity->expects($this->any())
       ->method('isNew')
       ->willReturn(TRUE);
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
index c888be259205b314394b027dd4cc606f08c624be..91e21361a0f60a55cb7d5e5c97e7f33366f25ba5 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererBubblingTest.php
@@ -555,7 +555,9 @@ public function testOverWriteCacheKeys(): void {
 class BubblingTest implements TrustedCallbackInterface {
 
   /**
-   * #pre_render callback for testBubblingWithPrerender().
+   * Render API callback:Used for testing testBubblingWithPrerender().
+   *
+   * This function is assigned as an #pre_render callback.
    */
   public static function bubblingPreRender($elements) {
     $elements += [
@@ -594,7 +596,9 @@ public static function bubblingPreRender($elements) {
   }
 
   /**
-   * #pre_render callback for testBubblingWithPrerender().
+   * Render API callback: Used for testing testBubblingWithPrerender().
+   *
+   * This function is assigned as an #pre_render callback in
    */
   public static function bubblingNestedPreRenderUncached($elements) {
     \Drupal::state()->set('bubbling_nested_pre_render_uncached', TRUE);
@@ -603,7 +607,9 @@ public static function bubblingNestedPreRenderUncached($elements) {
   }
 
   /**
-   * #pre_render callback for testBubblingWithPrerender().
+   * Render API callback: Used for testing testBubblingWithPrerender().
+   *
+   * This function is assigned as an #pre_render callback in
    */
   public static function bubblingNestedPreRenderCached($elements) {
     \Drupal::state()->set('bubbling_nested_pre_render_cached', TRUE);
@@ -611,7 +617,9 @@ public static function bubblingNestedPreRenderCached($elements) {
   }
 
   /**
-   * #lazy_builder callback for testBubblingWithPrerender().
+   * Render API callback: Used for testing testBubblingWithPrerender().
+   *
+   * This function is assigned as an #lazy_builder callback in
    */
   public static function bubblingPlaceholder($foo, $baz) {
     return [
@@ -620,7 +628,9 @@ public static function bubblingPlaceholder($foo, $baz) {
   }
 
   /**
-   * #pre_render callback for testOverWriteCacheKeys().
+   * Render API callback: Used for testing testOverWriteCacheKeys().
+   *
+   * This function is assigned as an #pre_render callback in
    */
   public static function bubblingCacheOverwritePrerender($elements) {
     // Overwrite the #cache entry with new data.
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
index 1acd9123a834314750a2b0ee92e874f30c5d660f..2b897fe40a1ca5a4cc341420c371f75561043298 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererPlaceholdersTest.php
@@ -1183,7 +1183,9 @@ protected function setupThemeManagerForDetails() {
 class RecursivePlaceholdersTest implements TrustedCallbackInterface {
 
   /**
-   * #lazy_builder callback; bubbles another placeholder.
+   * Render API callback: Bubbles another placeholder.
+   *
+   * This function is assigned as a #lazy_builder callback.
    *
    * @param string $animal
    *   An animal.
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index 953a009069810a3a4b13c5c0cf76d7b3b1e29ea8..f6eb9b74598042496a207bf01994184d16af5074 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -4,6 +4,7 @@
 
 namespace Drupal\Tests\Core\Render;
 
+use Drupal\Core\Render\RenderContext;
 use Drupal\Component\Render\MarkupInterface;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Access\AccessResultInterface;
@@ -1074,6 +1075,23 @@ public static function providerTestAddCacheableDependency() {
     ];
   }
 
+  /**
+   * @covers ::hasRenderContext
+   */
+  public function testHasRenderContext(): void {
+    // Tests with no render context.
+    $this->assertFalse($this->renderer->hasRenderContext());
+
+    // Tests in a render context.
+    $this->renderer->executeInRenderContext(new RenderContext(), function () {
+      $this->assertTrue($this->renderer->hasRenderContext());
+    });
+
+    // Test that the method works with no current request.
+    $this->requestStack->pop();
+    $this->assertFalse($this->renderer->hasRenderContext());
+  }
+
 }
 
 /**
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
index fd8962a8755508093f7e80c27c882b2742c65acb..f6f678582d65de9510856455260094fdb6f2c1e7 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTestBase.php
@@ -292,7 +292,9 @@ protected function assertRenderCacheItem($keys, $data, $bin = 'render') {
 class PlaceholdersTest implements TrustedCallbackInterface {
 
   /**
-   * #lazy_builder callback; attaches setting, generates markup.
+   * Render API callback: Attaches setting and generates markup.
+   *
+   * This function is assigned as an #lazy_builder callback.
    *
    * @param string $animal
    *   An animal.
@@ -319,7 +321,7 @@ public static function callback($animal, $use_animal_as_array_key = FALSE) {
   }
 
   /**
-   * #lazy_builder callback; attaches setting, generates markup, user-specific.
+   * The #lazy_builder callback; attaches setting, generates markup, user-specific.
    *
    * @param string $animal
    *   An animal.
@@ -339,7 +341,7 @@ public static function callbackPerUser($animal) {
   }
 
   /**
-   * #lazy_builder callback; attaches setting, generates markup, cache tag.
+   * The #lazy_builder callback; attaches setting, generates markup, cache tag.
    *
    * @param string $animal
    *   An animal.
diff --git a/core/tests/Drupal/Tests/PerformanceData.php b/core/tests/Drupal/Tests/PerformanceData.php
index 17e01d1c1265a57dd140b4b2bc8b0b1ad6f3433b..a2f7bdd9718e0f0ea44a110c3b3838630a2b1ef9 100644
--- a/core/tests/Drupal/Tests/PerformanceData.php
+++ b/core/tests/Drupal/Tests/PerformanceData.php
@@ -331,8 +331,15 @@ public function setCacheTagChecksumCount(int $count): void {
    *
    * @return int
    *   The number of cache tag checksum checks recorded.
+   *
+   * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is
+   *   no direct replacement.
+   *
+   * @see https://www.drupal.org/node/3511149
    */
   public function getCacheTagChecksumCount(): int {
+    @trigger_error(__METHOD__ . 'is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no direct replacement. See https://www.drupal.org/node/3511149', E_DEPRECATED);
+
     return $this->cacheTagChecksumCount;
   }
 
@@ -351,8 +358,14 @@ public function setCacheTagIsValidCount(int $count): void {
    *
    * @return int
    *   The number of cache tag isValid checks recorded.
+   *
+   * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is
+   * no direct replacement.
+   *
+   * @see https://www.drupal.org/node/3511149
    */
   public function getCacheTagIsValidCount(): int {
+    @trigger_error(__METHOD__ . 'is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. There is no direct replacement. See https://www.drupal.org/node/3511149', E_DEPRECATED);
     return $this->cacheTagIsValidCount;
   }
 
diff --git a/core/tests/Drupal/Tests/PerformanceTestTrait.php b/core/tests/Drupal/Tests/PerformanceTestTrait.php
index 8eff364de15be33fbd56ed459f683cefa6fc9af9..a229719308d61e79599ad1806c7300d273365f35 100644
--- a/core/tests/Drupal/Tests/PerformanceTestTrait.php
+++ b/core/tests/Drupal/Tests/PerformanceTestTrait.php
@@ -699,8 +699,7 @@ protected function getMetrics(PerformanceData $performance_data): array {
       'CacheGetCount' => $performance_data->getCacheGetCount(),
       'CacheSetCount' => $performance_data->getCacheSetCount(),
       'CacheDeleteCount' => $performance_data->getCacheDeleteCount(),
-      'CacheTagChecksumCount' => $performance_data->getCacheTagChecksumCount(),
-      'CacheTagIsValidCount' => $performance_data->getCacheTagIsValidCount(),
+      'CacheTagLookupQueryCount' => $performance_data->getCacheTagLookupQueryCount(),
       'CacheTagInvalidationCount' => $performance_data->getCacheTagInvalidationCount(),
     ];
   }
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index 156b1e40204047688149cabde95eeb30c5b6547e..2257148d0698c6bf88b9b75e5f601ad2ce790f76 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -11,7 +11,8 @@
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\TestTools\Extension\DeprecationBridge\ExpectDeprecationTrait;
-use Drupal\TestTools\TestVarDumper;
+use Drupal\TestTools\Extension\Dump\DebugDump;
+use PHPUnit\Framework\Attributes\BeforeClass;
 use PHPUnit\Framework\TestCase;
 use Prophecy\PhpUnit\ProphecyTrait;
 use Symfony\Component\VarDumper\VarDumper;
@@ -47,11 +48,13 @@ abstract class UnitTestCase extends TestCase {
   protected $root;
 
   /**
-   * {@inheritdoc}
+   * Registers the dumper CLI handler when the DebugDump extension is enabled.
    */
-  public static function setUpBeforeClass(): void {
-    parent::setUpBeforeClass();
-    VarDumper::setHandler(TestVarDumper::class . '::cliHandler');
+  #[BeforeClass]
+  public static function setDebugDumpHandler(): void {
+    if (DebugDump::isEnabled()) {
+      VarDumper::setHandler(DebugDump::class . '::cliHandler');
+    }
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/UnitTestCaseTest.php b/core/tests/Drupal/Tests/UnitTestCaseTest.php
index 0ceeea843c5b8f4eed045e12cc15cc2d219c2e90..dc653a6bcbf35f7941185cb68dcaf747d9f2fb20 100644
--- a/core/tests/Drupal/Tests/UnitTestCaseTest.php
+++ b/core/tests/Drupal/Tests/UnitTestCaseTest.php
@@ -4,6 +4,8 @@
 
 namespace Drupal\Tests;
 
+use Drupal\TestTools\Extension\Dump\DebugDump;
+
 /**
  * Tests for the UnitTestCase class.
  *
@@ -15,21 +17,18 @@ class UnitTestCaseTest extends UnitTestCase {
    * Tests the dump() function in a test run in the same process.
    */
   public function testVarDumpSameProcess(): void {
-    // Append the stream capturer to the STDERR stream, so that we can test the
-    // dump() output and also prevent it from actually outputting in this
-    // particular test.
-    stream_filter_register("capture", StreamCapturer::class);
-    stream_filter_append(STDERR, "capture");
-
     // Dump some variables.
     $object = (object) [
-      'foo' => 'bar',
+      'Aldebaran' => 'Betelgeuse',
     ];
     dump($object);
-    dump('banana');
+    dump('Alpheratz');
+
+    $dumpString = json_encode(DebugDump::getDumps());
 
-    $this->assertStringContainsString('bar', StreamCapturer::$cache);
-    $this->assertStringContainsString('banana', StreamCapturer::$cache);
+    $this->assertStringContainsString('Aldebaran', $dumpString);
+    $this->assertStringContainsString('Betelgeuse', $dumpString);
+    $this->assertStringContainsString('Alpheratz', $dumpString);
   }
 
   /**
@@ -38,21 +37,23 @@ public function testVarDumpSameProcess(): void {
    * @runInSeparateProcess
    */
   public function testVarDumpSeparateProcess(): void {
-    // Append the stream capturer to the STDERR stream, so that we can test the
-    // dump() output and also prevent it from actually outputting in this
-    // particular test.
-    stream_filter_register("capture", StreamCapturer::class);
-    stream_filter_append(STDERR, "capture");
-
     // Dump some variables.
     $object = (object) [
-      'foo' => 'bar',
+      'Denebola' => 'Aspidiske',
     ];
     dump($object);
-    dump('banana');
+    dump('Schedar');
+
+    $dumpString = json_encode(DebugDump::getDumps());
+
+    $this->assertStringContainsString('Denebola', $dumpString);
+    $this->assertStringContainsString('Aspidiske', $dumpString);
+    $this->assertStringContainsString('Schedar', $dumpString);
 
-    $this->assertStringContainsString('bar', StreamCapturer::$cache);
-    $this->assertStringContainsString('banana', StreamCapturer::$cache);
+    // We should also find the dump of the previous test.
+    $this->assertStringContainsString('Aldebaran', $dumpString);
+    $this->assertStringContainsString('Betelgeuse', $dumpString);
+    $this->assertStringContainsString('Alpheratz', $dumpString);
   }
 
 }
diff --git a/core/tests/PHPStan/tests/EnsurePHPStanVersionsMatchTest.php b/core/tests/PHPStan/tests/EnsurePHPStanVersionsMatchTest.php
index 10c539db91ba0b5ddf8ba79aaf80f21e707986f9..c1ffc7df0def4c3fd41d59b33e7ad1a10483a38e 100644
--- a/core/tests/PHPStan/tests/EnsurePHPStanVersionsMatchTest.php
+++ b/core/tests/PHPStan/tests/EnsurePHPStanVersionsMatchTest.php
@@ -7,7 +7,7 @@
 use PHPUnit\Framework\TestCase;
 
 /**
- * Tests that PHPStan versions match.
+ * Tests that PHPStan version used for rules testing matches core.
  */
 class EnsurePHPStanVersionsMatchTest extends TestCase {
 
diff --git a/core/themes/claro/claro.info.yml b/core/themes/claro/claro.info.yml
index 4a0a326479fa0e33ff08b798abc82a13de5fd6f0..647a22a1568e8dfdbb856edddf6074b339bbce19 100644
--- a/core/themes/claro/claro.info.yml
+++ b/core/themes/claro/claro.info.yml
@@ -37,12 +37,7 @@ libraries-override:
       component:
         misc/components/autocomplete-loading.module.css: css/components/autocomplete-loading.module.css
 
-  system/base:
-    css:
-      component:
-        css/components/system-status-counter.css: css/components/system-status-counter.css
-        css/components/system-status-report-counters.css: css/components/system-status-report-counters.css
-        css/components/system-status-report-general-info.css: css/components/system-status-report-general-info.css
+  system/status.report: claro/status.report
 
   system/admin:
     css:
@@ -148,6 +143,8 @@ libraries-extend:
     - claro/form.password-confirm
   node/drupal.node.preview:
     - claro/drupal.node.preview
+  system/status.report:
+    - claro/status.report
   views/views.module:
     - claro/views
   views_ui/admin.styling:
diff --git a/core/themes/claro/claro.libraries.yml b/core/themes/claro/claro.libraries.yml
index 64b56ebaa4483e625dfffb5411466cc84dab5944..5d94d224c16cc5cb807d3b68ff0558b18085a1e8 100644
--- a/core/themes/claro/claro.libraries.yml
+++ b/core/themes/claro/claro.libraries.yml
@@ -51,10 +51,6 @@ global-styling:
       css/components/table--file-multiple-widget.css: {}
       css/components/search-admin-settings.css: {}
       css/components/tablesort-indicator.css: {}
-      css/components/system-status-report-general-info.css: {}
-      css/components/system-status-report.css: {}
-      css/components/system-status-report-counters.css: {}
-      css/components/system-status-counter.css: {}
       css/components/tableselect.css: {}
       css/components/tabs.css: {}
     theme:
@@ -220,6 +216,31 @@ form.password-confirm:
     - core/drupal
     - claro/global-styling
 
+
+status.report:
+  version: VERSION
+  css:
+    component:
+      css/components/system-status-report-general-info.css: {}
+      css/components/system-status-report.css: {}
+      css/components/system-status-report-counters.css: {}
+      css/components/system-status-counter.css: {}
+  moved_files:
+    claro/global-styling:
+      deprecation_version: 11.2.0
+      removed_version: 12.0.0
+      deprecation_link: https://www.drupal.org/node/3432346
+      css:
+        component:
+          css/components/system-status-report.css:
+            base: css/components/system-status-report.css
+          css/components/system-status-counter.css:
+            base: css/components/system-status-counter.css
+          css/components/system-status-report-counters.css:
+            base: css/components/system-status-report-counters.css
+          css/components/system-status-report-general-info.css:
+            base: css/components/system-status-report-general-info.css
+
 views:
   css:
     component:
diff --git a/core/themes/stable9/stable9.info.yml b/core/themes/stable9/stable9.info.yml
index 0314380fbdfb5730cd79b7f1f0014a0b041f300c..745ceffab0409434447cb7d87129cc8758b9f989 100644
--- a/core/themes/stable9/stable9.info.yml
+++ b/core/themes/stable9/stable9.info.yml
@@ -231,9 +231,6 @@ libraries-override:
         css/components/position-container.module.css: css/system/components/position-container.module.css
         css/components/reset-appearance.module.css: css/system/components/reset-appearance.module.css
         css/components/resize.module.css: css/system/components/resize.module.css
-        css/components/system-status-counter.css: css/system/components/system-status-counter.css
-        css/components/system-status-report-counters.css: css/system/components/system-status-report-counters.css
-        css/components/system-status-report-general-info.css: css/system/components/system-status-report-general-info.css
         css/components/tablesort.module.css: css/system/components/tablesort.module.css
   system/admin:
     css:
@@ -248,6 +245,13 @@ libraries-override:
       component:
         css/system.diff.css: css/system/system.diff.css
 
+  system/status.report:
+    css:
+      component:
+        css/components/system-status-counter.css: css/system/components/system-status-counter.css
+        css/components/system-status-report-counters.css: css/system/components/system-status-report-counters.css
+        css/components/system-status-report-general-info.css: css/system/components/system-status-report-general-info.css
+
   taxonomy/drupal.taxonomy:
     css:
       component:
diff --git a/core/themes/stable9/templates/form/form-element.html.twig b/core/themes/stable9/templates/form/form-element.html.twig
index a13ff8ca43d4e635e51b6f38d32304e2eb843581..b9cbd1ff1e352fcebab90a133384c0a0c9a0ae72 100644
--- a/core/themes/stable9/templates/form/form-element.html.twig
+++ b/core/themes/stable9/templates/form/form-element.html.twig
@@ -71,7 +71,7 @@
     <span class="field-prefix">{{ prefix }}</span>
   {% endif %}
   {% if description_display == 'before' and description.content %}
-    <div{{ description.attributes }}>
+    <div{{ description.attributes.addClass(description_classes) }}>
       {{ description.content }}
     </div>
   {% endif %}
diff --git a/core/themes/starterkit_theme/templates/form/form-element.html.twig b/core/themes/starterkit_theme/templates/form/form-element.html.twig
index 3bde4f711545eb771de7e4df4815bd726b818153..2db54bc6cc7149e6f9a8d182cfa3c6fa0d4f3a3b 100644
--- a/core/themes/starterkit_theme/templates/form/form-element.html.twig
+++ b/core/themes/starterkit_theme/templates/form/form-element.html.twig
@@ -71,7 +71,7 @@
     <span class="field-prefix">{{ prefix }}</span>
   {% endif %}
   {% if description_display == 'before' and description.content %}
-    <div{{ description.attributes }}>
+    <div{{ description.attributes.addClass(description_classes) }}>
       {{ description.content }}
     </div>
   {% endif %}