diff --git a/composer.json b/composer.json
index b9536cfe35..97c131f9c4 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
         "wikimedia/composer-merge-plugin": "^1.4"
     },
     "replace": {
-        "drupal/core": "^8.4"
+        "drupal/core": "^8.5"
     },
     "minimum-stability": "dev",
     "prefer-stable": true,
diff --git a/composer.lock b/composer.lock
index 6622a70a91..310254b2e0 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "bec46eaaa9fa07a4cbd8c84302f0d275",
+    "content-hash": "97de1708c79f6205a295cfc9808c0c72",
     "packages": [
         {
             "name": "asm89/stack-cors",
diff --git a/core/CHANGELOG.txt b/core/CHANGELOG.txt
index 4caa24c0af..10e824f9e3 100644
--- a/core/CHANGELOG.txt
+++ b/core/CHANGELOG.txt
@@ -1,412 +1,3 @@
-Drupal 8.4.x, xxxx-xx-xx
-------------------------
-### Drush users: Update to Drush 8.1.12
-
-[Versions of Drush earlier than 8.1.12 will not work with Drupal 8.4.x](https://www.drupal.org/node/2874827).
-Update Drush to 8.1.12 before using it to update to Drupal core 8.4.x or you
- will encounter fatal errors.
-
-### Updated browser requirements: Internet Explorer 9 and 10 no longer supported
-
-In April 2017, Microsoft discontinued all support for Internet Explorer 9 and
-10. Therefore, [Drupal 8.4 has as well](https://www.drupal.org/node/2897971).
-Drupal 8.4 still mostly works in these browser versions, but bugs that affect
-them only will no longer be fixed, and existing workarounds for them will
-be removed beginning in Drupal 8.5.
-
-Additionally, Drupal 8's [browser requirements documentation page](https://www.drupal.org/docs/8/system-requirements/browser-requirements)
-currently lists incorrect information regarding very outdated browser versions
-such as Safari 5 and Firefox 5. [Clarifications to the browser policy and documentation](https://www.drupal.org/node/2390621)
-are underway and we hope to finalize it before 8.4.0-rc1.
-
-### Known Issues
-
-* Drupal 8.4.0-alpha1 includes major version updates for two dependencies:
-  Symfony 3.2 and jQuery 3. Both updates may introduce backwards compatibility
-  issues for some sites or modules, so test carefully.
-  For more information, see the "Third-party library updates" section below.
-* [Modal tour tips provided by the Tour module are not displayed correctly](https://www.drupal.org/node/2898808)
-  because the third-party Joyride library has an incompatibility with jQuery 3.
-  Tour tips are no longer centered and may be displayed entirely off-screen for
-   many screen sizes. Work is underway on an upstream bug fix.
-* Some sites that have files with 0 recorded usages may encounter
-  [validation errors when saving content referencing these files](https://www.drupal.org/node/2896480).
-  If your site's users report errors when saving content, you can
-  [set the `file.settings.make_unused_managed_files_temporary` setting to `true`](https://www.drupal.org/node/2891902),
-  but make sure you also set "Delete orphaned files" to "Never" on
-  `/admin/config/media/file-system`
-  to avoid permanent deletion of the affected files.
-
-### Important fixes since 8.3.x
-
-Translators should take note of several [string additions and changes since the last release](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&issue_tags_op=%3D&issue_tags=String+change+in+8.4.0).
-
-#### File usage tracking
-
-Drupal 8 has several longstanding [file usage tracking
-bugs](https://www.drupal.org/node/2821423). To prevent further data loss,
-Drupal 8.4 has [disabled the automatic deletion of files with no known remaining usages](https://www.drupal.org/node/2801777).
-This will result of the accumulation of unused files on sites, but ensures that
-files erroneously reporting 0 usages are not deleted while in use.
-[The change record explains how sites can opt back into marking files temporary](https://www.drupal.org/node/2891902).
-If you choose to enable the setting, you can also set "Delete orphaned files"
-to "Never" on `/admin/config/media/file-system` to avoid permanent deletion of
-the affected files.
-
-While the files will no longer be deleted by default, file usage is still not
-tracked correctly in several scenarios, regardless of the setting. Discussion
-on [how to evolve the file usage tracking system](https://www.drupal.org/node/2821423)
-is underway.
-
-#### Configuration export sorting
-
-* [#2361539: Config export key order is not predictable for sequences, add orderby property to config schema](https://www.drupal.org/node/2361539)
-  resolves an issue where sequences in configuration were not sorted unless
-  the code responsible for saving configuration explicitly performed a sort.
-  This resulted in unpredictable changes in configuration ordering and
-  confusing diffs even when nothing had changed. To resolve this issue, we've
-  [added an `orderby` key to the config schema](https://www.drupal.org/node/2852566)
-  that allows it to be sorted either by key or by value. Adding a preferred
-  sort is strongly recommended.
-* Two related issues remain open:
-    * [#2860531: Add orderby key to third party settings](https://www.drupal.org/node/2860531)
-      relates to unsorted sequences which result in unexpected discrepancies
-      in configuration during a configuration import.
-    * [#2885368: Config export key order for sequences: "orderedby" does not support cases where the order actually matters](https://www.drupal.org/node/2885368)
-      relates to various sequences in core and contributed modules in which
-      the source order is important.
-
-#### Revision data integrity fixes
-
-* Previously, data from draft revisions for [path aliases](https://www.drupal.org/node/2856363),
-  [menus](https://www.drupal.org/node/2858434), and [books](https://www.drupal.org/node/2858431)
-  could leak into the live site. Drupal 8.4.0-alpha1 hotfixes all three issues
-  by preventing changes to this data from being saved on any revision that is
-  not the default revision. These fixes improve revision support for both
-  stable features and the experimental Content Moderation module.
-* Correspondingly, [Content Moderation now avoids such scenarios with non-default revisions](https://www.drupal.org/node/2883868)
-  by setting the 'default revision' flag earlier.
-* Previously, [saving a revision of an entity translation could cause draft revisions to go "missing"](https://www.drupal.org/node/2766957).
-  Drupal 8.4. prevents this by preventing the moderation state from being set
-  to anything that would make the revision go "missing".
-  [A similar but unrelated bug in Content Moderation](https://www.drupal.org/node/2862988)
-  has also been fixed in this release.
-
-### New stable modules
-
-The following modules, previously considered experimental, are now stable and
-safe for use on production sites, with full backwards compatibility and upgrade
-paths from 8.4.0 to future releases:
-
-#### Datetime Range
-
-The [Datetime Range module](https://www.drupal.org/node/2893128) provides a
-field type that allows end dates to support contributed modules like
-[Calendar](https://www.drupal.org/project/calendar). This stable release is
-backwards-compatible with the 8.3.x experimental version and shares a
-consistent API with other Datetime fields.
-
-Future releases may improve Views support, usability, Datetime Range field
-validation, and REST support. For bugs or feature requests for this
-module, [see the core Datetime issue queue](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=Open&version%5B%5D=8.x&component%5B%5D=datetime.module&issue_tags_op=%3D).
-
-#### Layout Discovery
-
-The [Layout Discovery module](https://www.drupal.org/node/2834025) provides
-an API for modules or themes to register layouts as well as five common
-layouts. Providing this API in core enables
-core and contributed layout solutions to be compatible with each other. This
-stable release is backwards-compatible with the 8.3.x experimental version
-and introduces [support for per-region attributes](https://www.drupal.org/node/2885877).
-
-#### Media
-
-The new core [Media module](https://www.drupal.org/node/2831274) provides an
-API for reusable media entities and references. It is based on the contributed
-[Media Entity module](https://www.drupal.org/project/media_entity).
-
-Since there is a rich ecosystem of Drupal contributed modules built on Media
-Entity, the top priority for this release is to
-[provide a stable core API and data model](https://www.drupal.org/node/2895059)
-for a smoother transition for these modules. Developers and expert
-site builders can now add Media as a dependency. Work is underway to
-[provide an update path for existing sites' Media Entity data](https://www.drupal.org/node/2880334)
-and to [port existing contributed modules to the refined core API](https://www.drupal.org/node/2860796).
-
-Note that **the core Media module is currently marked hidden** and will not
-appear on the 'Extend' (module administration) page. (Enabling a contributed
-module that depends on the core Media module will also enable Media
-automatically.) The module will be displayed to site builders normally once
-user experience issues with it are resolved in a future release.
-
-Similarly, the REST API and normalizations for Media is not final and support
-for decoupled applications will be improved in a future release.
-
-#### Inline Form Errors
-
-The [Inline Form Errors module](https://www.drupal.org/node/2897652) provides a
-summary of any validation errors at the top of a form and places the individual
-error messages next to the form elements themselves. This helps users
-understand which entries need to be fixed, and how. Inline Form Errors was
-provided as an experimental module from Drupal 8.0.0 on, but it is now stable
-and polished enough for production use. See the core
-[Inline Form Errors module issue queue](https://www.drupal.org/project/issues/drupal?text=&status=Open&priorities=All&categories=All&version=All&component=inline_form_errors.module)
-for outstanding issues.
-
-### Content authoring and site administration improvements
-
-* The "Save and keep (un)published" dropbutton has been replaced with [a "Published" checkbox and single "Save" button](https://www.drupal.org/node/2068063).
-  The "Save and..." dropbutton was a new design in Drupal 8, but users found it
-  confusing, so we have restored a design that is more similar to the user
-  interface for Drupal 7 and earlier.
-* Previously, deleting a field on a content type would also delete any views
-  depending on the field. While the confirmation form did indicate that the
-  view would be deleted, users did not expect the behavior and often missed the
-  message, leading to data loss.
-  [Now, the view is disabled instead](https://www.drupal.org/node/2468045). In
-  the future, we intend to
-  [notify users that configuration has been disabled](https://www.drupal.org/node/2832558)
-  (as in this fix) as well as
-  [give users clearer warnings for other highly destructive operations](https://www.drupal.org/node/2773205).
-* The [Drupal toolbar no longer flickers](https://www.drupal.org/node/2542050)
-  during page rendering, thus improving perceived front-end performance.
-* Options in [timezones selector are now grouped by regions](https://www.drupal.org/node/2847651)
-  and labeled by cities instead of timezone names, making it much easier for users to find and select the specific timezone they need.
-* Both the ["Comments" administration page at `/admin/content/comment`](https://www.drupal.org/node/1986606) and the ["Recent log messages" report provided by dblog](https://www.drupal.org/node/2015149) are now configurable views.
-* Useful meta information about a node's status is typically displayed at the
-  top of the node sidebar. Previously, this meta information was provided by
-  the Seven theme, so it was not available in other administrative themes.
-  [This meta information is now provided by node.module itself](https://www.drupal.org/node/2803875)
-  so other administration themes can access it.
-
-### REST and API-first improvements
-
-* Authenticated REST API performance increased by 15% by
-  [utilizing the Dynamic Page Cache](https://www.drupal.org/node/2827797).
-* POSTing entities [can now happen at `/node`, `/taxonomy/term` and so on](https://www.drupal.org/node/2293697),
-  instead of `/entity/node`, `/entity/taxonomy_term`. Instead of confusingly
-  different URLs, they therefore now use the URLs you'd expect. Backwards
-  compatibility is maintained.
-* There is now a dedicated resource for [resetting a user's password](https://www.drupal.org/node/2847708).
-* Time fields now are [normalized to RFC3339 timestamps by default](https://www.drupal.org/node/2768651), fixing
-  time ambiguity. Existing sites continue to receive UNIX timestamps, but can
-  opt in. [See the change record for more information about backwards compatibility and on how to opt in](https://www.drupal.org/node/2859657).
-* [Path alias fields now are normalized too](https://www.drupal.org/node/2846554).
-  [See the change record for information about how this impacts API-first modules and other features relying on serialized entities](https://www.drupal.org/node/2856220).
-* When denormalization fails, a [422 response is now returned](https://www.drupal.org/node/2827084)
-  instead of a 400, per the HTTP specification.
-* With CORS enabled to allow origins besides the site's own host,
-  [submitting forms was broken](https://www.drupal.org/node/2853201) unless the
-  site's own host was also explicitly allowed.
-* Fatal errors and exceptions [now show a backtrace](https://www.drupal.org/node/2853300)
-  for all non-HTML requests as well as HTML requests, which makes for easier
-  debugging and better bug reports.
-* Massive expansion of test coverage.
-
-### Performance and scalability improvements
-
-* The internal page cache now [has a dedicated cache bin](https://www.drupal.org/node/2889603)
-  distinct from the rest of the render cache (a significant scalability
-  improvement).
-* The service collector pattern instantiates all services it collects, which is expensive, and unnecessary for some use cases.   For those use cases, a [new service ID collector](https://www.drupal.org/node/2472337)
-  pattern was added. The theme negotiator was updated to use it.
-  [See the change record for information about how to use the service ID collector](https://www.drupal.org/node/2598944) for improved performance.
-* The maximum time in-progress forms are cached [is now customizable](https://www.drupal.org/node/1286154)
-  rather than being limited to a default cache lifetime of 6 hours. Sites can
-  decrease the lifetime to reduce cache footprint, or increase it if needed for
-  a particular site's usecase.
-  [See the change record to learn how to access this new setting](https://www.drupal.org/node/2886836).
-* If there are no status messages, the corresponding rendering
-  [is now skipped](https://www.drupal.org/node/2853509). On simple sites, this
-  can result in a 10% improvement when there are no messages!
-* [Optimized the early Drupal installer](https://www.drupal.org/node/2872611)
-  to check whether any themes are installed first before invoking an
-  unnecessary function, which improves Drupal install time measurably for
-  both sites and automated tests.
-
-### Developer experience improvements
-
-* [Adopted Airbnb JavaScript style guide 14.1](https://www.drupal.org/node/2815077) as the new baseline set of
-  coding standards for Drupal core and contributed modules.
-  [See the change record for information about how to configure your project for eslint](https://www.drupal.org/node/2873849).
-* Field type definitions can now [enforce the cardinality of the field](https://www.drupal.org/node/2403703).
-  [See the change record for information about how to specify a cardinality via the annotation](https://www.drupal.org/node/2869873).
-* [Added new methods](https://www.drupal.org/node/2869809) to make getting
-  typed configuration entity representations easier.
-  [See the change record for more information about how to invoke these methods](https://www.drupal.org/node/2877282).
-* The `html_tag` render element now [supports nested render arrays](https://www.drupal.org/node/2694535),
-  enabling the creation of dynamic SVGs.
-  [See the change record for information about how you can use this in your theme](https://www.drupal.org/node/2887146).
-* [Added more helpful errors](https://www.drupal.org/node/2705037) when CSS
-  is not properly nested under an existing category in asset libraries.
-* Also see the [change records for the 8.4.x branch](https://www.drupal.org/list-changes/drupal/published?keywords_description=&to_branch=8.4.x&version=&created_op=%3E%3D&created%5Bvalue%5D=&created%5Bmin%5D=&created%5Bmax%5D=)
-  for other changes for developers.
-
-### Automated testing improvements
-
-* [PHPUnit has been updated from 4.8.28 to 4.8.35](https://www.drupal.org/node/2850797)
-  in order to incorporate a forward compatibility layer for PHPUnit 4.8, useful
-  during a future migration to PHPUnit 5 or PHPUnit 6.
-* Many former WebTestBase tests were converted to BrowserTestBase.
-  [Track current progress](http://simpletest-countdown.org/).
-* The default approach for testing deprecated code has changed to
-  [require use of the Drupal core deprecation policy](https://www.drupal.org/node/2488860)
-  (`@trigger_error()`) to mark code deprecated; otherwise a test error will
-  be thrown.
-  [See the change record for information about how to update `phpunit.xml` and how to test deprecated code](https://www.drupal.org/node/2811561).
-* [Resolved random test failures](https://www.drupal.org/node/2866056) due to
-  ResourceTestBase's HTTP client timeout of 30 seconds.
-
-### Third-party library updates
-
-* [Drupal's Symfony dependency has been updated from Symfony 2.8 to Symfony
-  3.2](https://www.drupal.org/node/2712647). This major version update is
-  necessary because Symfony 2.8 support will end around the release of Drupal
-  8.6.0 next year. See the change record for information about [Symfony 3 backwards compatibility
-  breaks that affected Drupal core](https://www.drupal.org/node/2743809).
-  [Drupal 8 also requires Symfony 3.2.8](https://www.drupal.org/node/2871253)
-  because of a bug in Symfony 3.2.7.
-* [#2533498: Update jQuery to version 3](https://www.drupal.org/node/2533498).
-  Now that jQuery 3.0 has been released, jQuery 2.x will only be receiving
-  security updates, so Drupal 8.4.0 ships with this library update. jQuery 3
-  features numerous improvements, including better error reporting. See the
-  [jQuery Core 3.0 Upgrade Guide](https://jquery.com/upgrade-guide/3.0/) for
-  information on jQuery 3 backwards compatibility breaks that might affect the
-  JavaScript code in your modules, themes, and sites. Note that we may consider
-  rolling back this library update if the [bug affecting tours](https://www.drupal.org/node/2898808) is not resolved in time for Drupal 8.4.0-beta1.
-* [zendframework/zend-diactoros has been updated from 1.3.10 to 1.4.0](https://www.drupal.org/node/2874817).
-* [jQuery UI has been updated from 1.11.4 to 1.12.1](https://www.drupal.org/node/2809427).
-* [CKEditor has been updated from 4.6.2 to 4.7.1](https://www.drupal.org/node/2893566).
-* [asm89/stack-cors has been updated from 1.0 to 1.1](https://www.drupal.org/node/2853201).
-
-### Experimental modules
-
-#### Migrate ([beta stability](https://www.drupal.org/core/experimental#beta))
-
-Migrate provides a general API for migrations. It will be considered completely
-stable once all  issues tagged [Migrate critical](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=Open&version%5B%5D=8.x&issue_tags_op=%3D&issue_tags=Migrate+critical) are resolved.
-
-* Renamed [`migration` process plugin to `migration_lookup`](https://www.drupal.org/node/2845486)
-  and
-  [`iterator` process plugin to `sub_process`](https://www.drupal.org/node/2845483)
-  to better capture their purposes. (Backwards compatibility is provided for
-  both process plugins since Migrate is in beta.)
-
-#### Migrate Drupal and Migrate Drupal UI ([alpha stability](https://www.drupal.org/core/experimental#alpha))
-
-Migrate Drupal module provides API support for Drupal-to-Drupal migrations, and
-Migrate Drupal UI offers a simple user interface to run migrations from older
-Drupal versions.
-
-* This release adds [date](https://www.drupal.org/node/2566779) and
-  [node reference](https://www.drupal.org/node/2814949) support for Drupal 6 to
-  8 migrations.
-* Core provides migrations for most Drupal 6 data and can be used for migrating
-  Drupal 6 sites to Drupal 8, and the Drupal 6 to 8 migration path is nearing
-  beta stability. Some gaps remain, such as for some internationalization data.
-  ([Outstanding issues for the Drupal 6 to Drupal 8 migration](https://www.drupal.org/project/issues/search/drupal?project_issue_followers=&status%5B%5D=1&status%5B%5D=13&status%5B%5D=8&status%5B%5D=14&status%5B%5D=15&status%5B%5D=4&issue_tags_op=%3D&issue_tags=migrate-d6-d8))
-* The Drupal 7 to Drupal 8 migration is incomplete but is suitable for
-  developers who would like to help improve the migration and can be used to
-  test upgrades especially for simple Drupal 7 sites. Most high-priority
-  migrations are available.
-  ([Outstanding issues for the Drupal 7 to Drupal 8 migration](https://www.drupal.org/node/2456259))
-* Drush support for Migrate is currently only available in the
-  [Drupal Upgrade](https://www.drupal.org/project/migrate_upgrade) contributed
-  module. (See the
-  [pull request to add support to Drush](https://github.com/drush-ops/drush/issues/2140).)
-* [Added field plugin](https://www.drupal.org/node/2814949) to handle
-  migration of node reference field values from Drupal 6 to Drupal 8.
-* [Added date field plugin](https://www.drupal.org/node/2566779) to handle
-  migration of CCK date fields in Drupal 6 to Drupal 8.
-* [Renamed migration field plugins and classes](https://www.drupal.org/node/2683435)
-  referring to custom fields provided by the Drupal 6 module CCK, which was
-  replaced in Drupal 7 by the core Field API. [See the change record for more information about how this impacts your migration plugins](https://www.drupal.org/node/2751897).
-
-#### Workflows ([beta stability](https://www.drupal.org/core/experimental#beta))
-
-The Workflows module provides an abstract system of states (like Draft,
-Archived, and Published) and transitions between them. Workflows can be used by
-modules that implement non-publishing workflows (such as for users or products)
-as well as content publishing workflows.
-
-Drupal 8.4 introduces a final significant backwards compatibility and data
-model break for this module,
-[moving responsibility for workflow states and transitions from the Workflow entity to the Workflow type plugin](https://www.drupal.org/node/2849827).
-Read [Workflow type plugins are now responsible for state and transition schema](https://www.drupal.org/node/2897706)
-for full details on the API and data model changes related to this fix. Now
-that this change is complete, the Workflows module has reached beta stability,
-and it may furthermore be marked stable in time for Drupal 8.4.0!
-
-#### Content Moderation ([beta stability](https://www.drupal.org/core/experimental#beta))
-
-Content Moderation allows workflows from the Workflows module to be applied to
-content. Content Moderation has beta stability in 8.4.0-alpha1, but may become
-stable in time for 8.4.0! Notable improvements in this release:
-
-* Workflow states are now [selected from a select list, rather than under a drop-button](https://www.drupal.org/node/2753717), which represents a significant
-  usability improvement.
-* Now that workflows can be applied to any revisionable entity type, Content
-  Moderation [adds entity type checkboxes to the workflow form](https://www.drupal.org/node/2843083).
-  This allows site administrators to configure which entity types should have
-  the workflow at the same time as they configure the workflow itself, for a
-  more intuitive user experience.
-* Content Moderation now [prevents the deletion of workflows that are currently in use](https://www.drupal.org/node/2830740)
-  to prevent fatal errors and data integrity problems.
-* The confusing terminology of
-  ["forward revisions" has been replaced with that of "pending revisions"](https://www.drupal.org/node/2890364).
-  If your contributed module refers to revisions that are not yet published, it
-  should use this new term.
-
-#### Field Layout ([alpha stability](https://www.drupal.org/core/experimental#alpha))
-
-This module provides the ability for site builders to rearrange fields on
-content types, block types, etc. into new regions, for both the form and
-display, on the same forms provided by the normal field user interface.  Field
-Layout has had several bugfixes since 8.3.0, but no significant changes. See
-the [entity display layout roadmap](https://www.drupal.org/node/2795833) for
-the next steps for this module, which needs to become stable by 8.5.0 to remain
-in Drupal core.
-
-#### Settings Tray ([alpha stability](https://www.drupal.org/core/experimental#alpha))
-
-The Settings Tray module allows configuring page elements such as blocks and
-menus from the frontend of your site. Settings Tray has improved significantly
-since Drupal 8.3.0. The goal for this release is to get Settings Tray to beta
-stability. Only two issues remain before that milestone: to
-[move the off-canvas dialog renderer into a core component](https://www.drupal.org/node/2784443), and to
-[rename the machine name of the module to settings_tray](https://www.drupal.org/node/2803375),
-to match its user-facing name. We hope to make Settings Tray stable by 8.5.0.
-To track progress, see the ["outside in" roadmap issue](https://www.drupal.org/node/2762505).
-
-* [A CSS reset has been added to the Settings Tray](https://www.drupal.org/node/2826722) to improve the themer experience.
-* Form validation messages now [appear in the Settings Tray instead of main page](https://www.drupal.org/node/2785047).
-* [The toolbar background in Edit mode now matches the edit button](https://www.drupal.org/node/2894427),
-  instead of the white background that many users found distracting or
-  misunderstood to be an indication that something was broken.
-* The block title field in the tray is now [labeled more clearly and only shown when the block title itself is shown](https://www.drupal.org/node/2882729).
-* In the contextual links, ["Quick edit" is now listed before "Configure"](https://www.drupal.org/node/2784567),
-  and the [custom blocks instead have a "Quick edit settings" link](https://www.drupal.org/node/2786193)
-  (to distinguish them from the links provided by the Quick Edit module, which
-  allow editing the content of the custom block itself).
-* Edit mode [now behaves the same way whether accessed by clicking "Quick edit" or clicking through the toolbar](https://www.drupal.org/node/2847664)
-* Users can now [escape from Edit mode with the ESC key](https://www.drupal.org/node/2784571), for better accessibility.
-
-#### Place Blocks ([alpha stability](https://www.drupal.org/core/experimental#alpha))
-
-This feature allows the user to place a block on any page and see the region
-where it will be displayed, without having to navigate to a backend
-administration form.
-[8.4.0-alpha1 was the deadline for Place Blocks to stabilize](https://www.drupal.org/core/experimental#versions),
-but the module's roadmap was not completed. Furthermore, the module is not
-intended as a standalone feature and should instead be a built-in part of the
-Block system. For these reasons,
-[Place Blocks module has been marked hidden in this release](https://www.drupal.org/node/2898267)
-(it can still be enabled with Drush). The Place Blocks module itself will be
-turned into an empty module in Drupal 8.5.x, since ideally the core Block
-system will offer the same functionality in 8.5.0 (though this depends on
-completion of a [core patch for the feature](https://www.drupal.org/node/2739075).)
-
-
 Drupal 8.3.0, 2017-04-05
 ------------------------
 - Added modules:
diff --git a/core/core.services.yml b/core/core.services.yml
index 76088786cd..a7997ea66b 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1152,7 +1152,7 @@ services:
     arguments: ['@state', '@current_user']
   maintenance_mode_subscriber:
     class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber
-    arguments: ['@maintenance_mode', '@config.factory', '@string_translation', '@url_generator', '@current_user', '@bare_html_page_renderer']
+    arguments: ['@maintenance_mode', '@config.factory', '@string_translation', '@url_generator', '@current_user', '@bare_html_page_renderer', '@messenger']
     tags:
       - { name: event_subscriber }
   path_subscriber:
@@ -1660,3 +1660,6 @@ services:
     class: Drupal\Core\EventSubscriber\RssResponseRelativeUrlFilter
     tags:
       - { name: event_subscriber }
+  messenger:
+    class: Drupal\Core\Messenger\LegacyMessenger
+    arguments: ['@page_cache_kill_switch']
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 52f574212a..5a1cfbe7c0 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -11,8 +11,6 @@
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Config\BootstrapConfigStorageFactory;
 use Drupal\Core\Logger\RfcLogLevel;
-use Drupal\Core\Render\Markup;
-use Drupal\Component\Render\MarkupInterface;
 use Drupal\Core\Test\TestDatabase;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Site\Settings;
@@ -459,28 +457,10 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
  * @see status-messages.html.twig
  */
 function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) {
-  if (isset($message)) {
-    if (!isset($_SESSION['messages'][$type])) {
-      $_SESSION['messages'][$type] = [];
-    }
-
-    // Convert strings which are safe to the simplest Markup objects.
-    if (!($message instanceof Markup) && $message instanceof MarkupInterface) {
-      $message = Markup::create((string) $message);
-    }
-
-    // Do not use strict type checking so that equivalent string and
-    // MarkupInterface objects are detected.
-    if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
-      $_SESSION['messages'][$type][] = $message;
-    }
-
-    // Mark this page as being uncacheable.
-    \Drupal::service('page_cache_kill_switch')->trigger();
-  }
-
-  // Messages not set when DB connection fails.
-  return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;
+  /* @var \Drupal\Core\Messenger\MessengerInterface $messenger */
+  $messenger = \Drupal::service('messenger');
+  $messenger->addMessage($message, $type, $repeat);
+  return $messenger->all();
 }
 
 /**
@@ -509,10 +489,12 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE)
  * @see status-messages.html.twig
  */
 function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
-  if ($messages = drupal_set_message()) {
+  /** @var \Drupal\Core\Messenger\MessengerInterface $messenger */
+  $messenger = \Drupal::hasService('messenger') ? \Drupal::service('messenger') : NULL;
+  if ($messenger && ($messages = $messenger->all())) {
     if ($type) {
       if ($clear_queue) {
-        unset($_SESSION['messages'][$type]);
+        $messenger->deleteByType($type);
       }
       if (isset($messages[$type])) {
         return [$type => $messages[$type]];
@@ -520,7 +502,7 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) {
     }
     else {
       if ($clear_queue) {
-        unset($_SESSION['messages']);
+        $messenger->deleteAll();
       }
       return $messages;
     }
diff --git a/core/includes/errors.inc b/core/includes/errors.inc
index 40e290338d..284d1835e9 100644
--- a/core/includes/errors.inc
+++ b/core/includes/errors.inc
@@ -164,7 +164,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
   // installer.
   if (\Drupal::hasService('logger.factory')) {
     try {
-      \Drupal::logger('php')->log($error['severity_level'], '%type: @message in %function (line %line of %file) @backtrace_string.', $error);
+      // Provide the PHP backtrace to logger implementations.
+      \Drupal::logger('php')->log($error['severity_level'], '%type: @message in %function (line %line of %file) @backtrace_string.', $error + ['backtrace' => $backtrace]);
     }
     catch (\Exception $e) {
       // We can't log, for example because the database connection is not
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 1acfc12e9a..07dc12f1f3 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -81,7 +81,7 @@ class Drupal {
   /**
    * The current system version.
    */
-  const VERSION = '8.4.0-dev';
+  const VERSION = '8.5.0-dev';
 
   /**
    * Core API compatibility.
diff --git a/core/lib/Drupal/Core/Access/AccessResult.php b/core/lib/Drupal/Core/Access/AccessResult.php
index 1cd6b8bacd..f4962ec596 100644
--- a/core/lib/Drupal/Core/Access/AccessResult.php
+++ b/core/lib/Drupal/Core/Access/AccessResult.php
@@ -87,13 +87,16 @@ public static function allowedIf($condition) {
    *
    * @param bool $condition
    *   The condition to evaluate.
+   * @param string|null $reason
+   *   (optional) The reason why access is forbidden. Intended for developers,
+   *   hence not translatable
    *
    * @return \Drupal\Core\Access\AccessResult
    *   If $condition is TRUE, isForbidden() will be TRUE, otherwise isNeutral()
    *   will be TRUE.
    */
-  public static function forbiddenIf($condition) {
-    return $condition ? static::forbidden() : static::neutral();
+  public static function forbiddenIf($condition, $reason = NULL) {
+    return $condition ? static::forbidden($reason) : static::neutral();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php
index 38b7fa87a1..e26a03ca85 100644
--- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php
+++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityListBuilder.php
@@ -37,14 +37,14 @@ public function getDefaultOperations(EntityInterface $entity) {
         $operations['enable'] = [
           'title' => t('Enable'),
           'weight' => -10,
-          'url' => $entity->urlInfo('enable'),
+          'url' => $this->ensureDestination($entity->toUrl('enable')),
         ];
       }
       elseif ($entity->hasLinkTemplate('disable')) {
         $operations['disable'] = [
           'title' => t('Disable'),
           'weight' => 40,
-          'url' => $entity->urlInfo('disable'),
+          'url' => $this->ensureDestination($entity->toUrl('disable')),
         ];
       }
     }
diff --git a/core/lib/Drupal/Core/Entity/EntityListBuilder.php b/core/lib/Drupal/Core/Entity/EntityListBuilder.php
index 7f46915ae9..c1654362d0 100644
--- a/core/lib/Drupal/Core/Entity/EntityListBuilder.php
+++ b/core/lib/Drupal/Core/Entity/EntityListBuilder.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Core\Routing\RedirectDestinationTrait;
+use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -11,6 +13,8 @@
  */
 class EntityListBuilder extends EntityHandlerBase implements EntityListBuilderInterface, EntityHandlerInterface {
 
+  use RedirectDestinationTrait;
+
   /**
    * The entity storage class.
    *
@@ -143,14 +147,14 @@ protected function getDefaultOperations(EntityInterface $entity) {
       $operations['edit'] = [
         'title' => $this->t('Edit'),
         'weight' => 10,
-        'url' => $entity->urlInfo('edit-form'),
+        'url' => $this->ensureDestination($entity->toUrl('edit-form')),
       ];
     }
     if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
       $operations['delete'] = [
         'title' => $this->t('Delete'),
         'weight' => 100,
-        'url' => $entity->urlInfo('delete-form'),
+        'url' => $this->ensureDestination($entity->toUrl('delete-form')),
       ];
     }
 
@@ -250,4 +254,17 @@ protected function getTitle() {
     return;
   }
 
+  /**
+   * Ensures that a destination is present on the given URL.
+   *
+   * @param \Drupal\Core\Url $url
+   *   The URL object to which the destination should be added.
+   *
+   * @return \Drupal\Core\Url
+   *   The updated URL object.
+   */
+  protected function ensureDestination(Url $url) {
+    return $url->mergeOptions(['query' => $this->getRedirectDestination()->getAsArray()]);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
index ba82988a14..c2688edeae 100644
--- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Render\BareHtmlPageRendererInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Routing\UrlGeneratorInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -58,6 +59,13 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
    */
   protected $bareHtmlPageRenderer;
 
+  /**
+   * The messenger.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
   /**
    * Constructs a new MaintenanceModeSubscriber.
    *
@@ -73,14 +81,17 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface {
    *   The current user.
    * @param \Drupal\Core\Render\BareHtmlPageRendererInterface $bare_html_page_renderer
    *   The bare HTML page renderer.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
    */
-  public function __construct(MaintenanceModeInterface $maintenance_mode, ConfigFactoryInterface $config_factory, TranslationInterface $translation, UrlGeneratorInterface $url_generator, AccountInterface $account, BareHtmlPageRendererInterface $bare_html_page_renderer) {
+  public function __construct(MaintenanceModeInterface $maintenance_mode, ConfigFactoryInterface $config_factory, TranslationInterface $translation, UrlGeneratorInterface $url_generator, AccountInterface $account, BareHtmlPageRendererInterface $bare_html_page_renderer, MessengerInterface $messenger) {
     $this->maintenanceMode = $maintenance_mode;
     $this->config = $config_factory;
     $this->stringTranslation = $translation;
     $this->urlGenerator = $url_generator;
     $this->account = $account;
     $this->bareHtmlPageRenderer = $bare_html_page_renderer;
+    $this->messenger = $messenger;
   }
 
   /**
@@ -118,10 +129,10 @@ public function onKernelRequestMaintenance(GetResponseEvent $event) {
         // settings page.
         if ($route_match->getRouteName() != 'system.site_maintenance_mode') {
           if ($this->account->hasPermission('administer site configuration')) {
-            $this->drupalSetMessage($this->t('Operating in maintenance mode. <a href=":url">Go online.</a>', [':url' => $this->urlGenerator->generate('system.site_maintenance_mode')]), 'status', FALSE);
+            $this->messenger->addMessage($this->t('Operating in maintenance mode. <a href=":url">Go online.</a>', [':url' => $this->urlGenerator->generate('system.site_maintenance_mode')]), 'status', FALSE);
           }
           else {
-            $this->drupalSetMessage($this->t('Operating in maintenance mode.'), 'status', FALSE);
+            $this->messenger->addMessage($this->t('Operating in maintenance mode.'), 'status', FALSE);
           }
         }
       }
@@ -140,13 +151,6 @@ protected function getSiteMaintenanceMessage() {
     ]);
   }
 
-  /**
-   * Wraps the drupal_set_message function.
-   */
-  protected function drupalSetMessage($message = NULL, $type = 'status', $repeat = FALSE) {
-    return drupal_set_message($message, $type, $repeat);
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
index 25df63b5bd..991385f78b 100644
--- a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
+++ b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
@@ -838,4 +838,21 @@ public function setStorageRequired($required) {
     return $this;
   }
 
+  /**
+   * Magic method: Implements a deep clone.
+   */
+  public function __clone() {
+    parent::__clone();
+
+    // The itemDefinition (\Drupal\Core\Field\TypedData\FieldItemDataDefinition)
+    // has a property fieldDefinition, which is a recursive reference to the
+    // parent BaseFieldDefinition, therefore the reference to the old object has
+    // to be overwritten with a reference to the cloned one.
+    $this->itemDefinition->setFieldDefinition($this);
+    // Reset the static cache of the field property definitions in order to
+    // ensure that the clone will reference different field property definitions
+    // objects.
+    $this->propertyDefinitions = NULL;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinition.php b/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinition.php
index 4a6d8775b1..bc8f9c0a2b 100644
--- a/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinition.php
+++ b/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinition.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\Field\TypedData;
 
 use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 
 /**
@@ -14,7 +13,7 @@
  * by the field definitions, this class does not benefit and thus does not
  * extend from MapDefinition or ComplexDataDefinitionBase.
  */
-class FieldItemDataDefinition extends DataDefinition implements ComplexDataDefinitionInterface {
+class FieldItemDataDefinition extends DataDefinition implements FieldItemDataDefinitionInterface {
 
   /**
    * The field definition the item definition belongs to.
@@ -74,13 +73,18 @@ public function getMainPropertyName() {
   }
 
   /**
-   * Gets the field item's field definition.
-   *
-   * @return \Drupal\Core\Field\FieldDefinitionInterface
-   *   The field definition for this field item.
+   * {@inheritdoc}
    */
   public function getFieldDefinition() {
     return $this->fieldDefinition;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setFieldDefinition($field_definition) {
+    $this->fieldDefinition = $field_definition;
+    return $this;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinitionInterface.php b/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinitionInterface.php
new file mode 100644
index 0000000000..e7571194ea
--- /dev/null
+++ b/core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinitionInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\Core\Field\TypedData;
+
+use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
+
+/**
+ * Interface for field item data definitions.
+ *
+ * @ingroup typed_data
+ */
+interface FieldItemDataDefinitionInterface extends ComplexDataDefinitionInterface {
+
+  /**
+   * Gets the field item's field definition.
+   *
+   * @return \Drupal\Core\Field\FieldDefinitionInterface
+   *   The field definition for this field item.
+   */
+  public function getFieldDefinition();
+
+  /**
+   * Sets the field item's field definition.
+   *
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The new field definition to assign to this item definition.
+   *
+   * @return static
+   *   The object itself for chaining.
+   *
+   * @internal
+   *   Should not be used in user code. It allows to overwrite the item
+   *   definition property of the cloned field definition.
+   */
+  public function setFieldDefinition($field_definition);
+
+}
diff --git a/core/lib/Drupal/Core/Messenger/LegacyMessenger.php b/core/lib/Drupal/Core/Messenger/LegacyMessenger.php
new file mode 100644
index 0000000000..8c9751f3d8
--- /dev/null
+++ b/core/lib/Drupal/Core/Messenger/LegacyMessenger.php
@@ -0,0 +1,212 @@
+<?php
+
+namespace Drupal\Core\Messenger;
+
+use Drupal\Component\Render\MarkupInterface;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Core\Render\Markup;
+
+/**
+ * A legacy implementation of the messenger interface.
+ *
+ * @internal
+ */
+class LegacyMessenger implements MessengerInterface {
+
+  /**
+   * The page cache kill switch.
+   *
+   * @var \Drupal\Core\PageCache\ResponsePolicy\KillSwitch
+   */
+  protected $killSwitch;
+
+  /**
+   * LegacyMessenger constructor.
+   *
+   * @param \Drupal\Core\PageCache\ResponsePolicy\KillSwitch $killSwitch
+   *   (optional) The page cache kill switch.
+   */
+  public function __construct(KillSwitch $killSwitch) {
+    $this->killSwitch = $killSwitch;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE) {
+    $this->setMessage($message, $type, $repeat);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addStatus($message, $repeat = FALSE) {
+    return $this->addMessage($message, static::TYPE_STATUS);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addError($message, $repeat = FALSE) {
+    return $this->addMessage($message, static::TYPE_ERROR);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addWarning($message, $repeat = FALSE) {
+    return $this->addMessage($message, static::TYPE_WARNING);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function all() {
+    return $this->getMessages(NULL, FALSE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function messagesByType($type) {
+    return $this->getMessages($type, FALSE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteAll() {
+    return $this->getMessages(NULL, TRUE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function deleteByType($type) {
+    return $this->getMessages($type, TRUE);
+  }
+
+  /**
+   * Sets a message to display to the user.
+   *
+   * Messages are stored in a session variable and displayed in the page template
+   * via the $messages theme variable.
+   *
+   * Example usage:
+   * @code
+   * drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
+   * @endcode
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter and
+   *   end with a period.
+   * @param string $type
+   *   (optional) The message's type. Defaults to 'status'. These values are
+   *   supported:
+   *   - 'status'
+   *   - 'warning'
+   *   - 'error'
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return array|null
+   *   A multidimensional array with keys corresponding to the set message types.
+   *   The indexed array values of each contain the set messages for that type,
+   *   and each message is an associative array with the following format:
+   *   - safe: Boolean indicating whether the message string has been marked as
+   *     safe. Non-safe strings will be escaped automatically.
+   *   - message: The message string.
+   *   So, the following is an example of the full return array structure:
+   *   @code
+   *     array(
+   *       'status' => array(
+   *         array(
+   *           'safe' => TRUE,
+   *           'message' => 'A <em>safe</em> markup string.',
+   *         ),
+   *         array(
+   *           'safe' => FALSE,
+   *           'message' => "$arbitrary_user_input to escape.",
+   *         ),
+   *       ),
+   *     );
+   *   @endcode
+   *   If there are no messages set, the function returns NULL.
+   *
+   * @internal
+   */
+  private function setMessage($message = NULL, $type = 'status', $repeat = FALSE) {
+    if (isset($message)) {
+      if (!isset($_SESSION['messages'][$type])) {
+        $_SESSION['messages'][$type] = [];
+      }
+
+      // Convert strings which are safe to the simplest Markup objects.
+      if (!($message instanceof Markup) && $message instanceof MarkupInterface) {
+        $message = Markup::create((string) $message);
+      }
+
+      // Do not use strict type checking so that equivalent string and
+      // MarkupInterface objects are detected.
+      if ($repeat || !in_array($message, $_SESSION['messages'][$type])) {
+        $_SESSION['messages'][$type][] = $message;
+      }
+
+      // Mark this page as being uncacheable.
+      $this->killSwitch->trigger();
+    }
+
+    // Messages not set when DB connection fails.
+    return isset($_SESSION['messages']) ? $_SESSION['messages'] : NULL;
+  }
+
+  /**
+   * Returns all messages that have been set with drupal_set_message().
+   *
+   * @param string $type
+   *   (optional) Limit the messages returned by type. Defaults to NULL, meaning
+   *   all types. These values are supported:
+   *   - NULL
+   *   - 'status'
+   *   - 'warning'
+   *   - 'error'
+   * @param bool $clear_queue
+   *   (optional) If this is TRUE, the queue will be cleared of messages of the
+   *   type specified in the $type parameter. Otherwise the queue will be left
+   *   intact. Defaults to TRUE.
+   *
+   * @return array
+   *   An associative, nested array of messages grouped by message type, with
+   *   the top-level keys as the message type. The messages returned are
+   *   limited to the type specified in the $type parameter, if any. If there
+   *   are no messages of the specified type, an empty array is returned. See
+   *   drupal_set_message() for the array structure of individual messages.
+   *
+   * @see drupal_set_message()
+   * @see status-messages.html.twig
+   *
+   * @internal
+   */
+  private function getMessages($type = NULL, $clear_queue = TRUE) {
+    if ($messages = $this->setMessage()) {
+      if ($type) {
+        if ($clear_queue) {
+          unset($_SESSION['messages'][$type]);
+        }
+        if (isset($messages[$type])) {
+          return [$type => $messages[$type]];
+        }
+      }
+      else {
+        if ($clear_queue) {
+          unset($_SESSION['messages']);
+        }
+        return $messages;
+      }
+    }
+    return [];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Messenger/MessengerInterface.php b/core/lib/Drupal/Core/Messenger/MessengerInterface.php
new file mode 100644
index 0000000000..216835bcea
--- /dev/null
+++ b/core/lib/Drupal/Core/Messenger/MessengerInterface.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace Drupal\Core\Messenger;
+
+/**
+ * Stores runtime messages sent out to individual users on the page.
+ *
+ * An example for these messages is for example: "Content X got saved".
+ *
+ * @internal
+ */
+interface MessengerInterface {
+
+  /**
+   * A status message.
+   */
+  const TYPE_STATUS = 'status';
+
+  /**
+   * A warning.
+   */
+  const TYPE_WARNING = 'warning';
+
+  /**
+   * An error.
+   */
+  const TYPE_ERROR = 'error';
+
+  /**
+   * Adds a new message to the queue.
+   *
+   * The messages will be displayed in the order they got added later.
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter
+   *   and end with a period.
+   * @param string $type
+   *   (optional) The message's type. Either self::TYPE_STATUS,
+   *   self::TYPE_WARNING, or self::TYPE_ERROR.
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return $this
+   */
+  public function addMessage($message, $type = self::TYPE_STATUS, $repeat = FALSE);
+
+  /**
+   * Adds a new status message to the queue.
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter
+   *   and end with a period.
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return $this
+   */
+  public function addStatus($message, $repeat = FALSE);
+
+  /**
+   * Adds a new error message to the queue.
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter
+   *   and end with a period.
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return $this
+   */
+  public function addError($message, $repeat = FALSE);
+
+  /**
+   * Adds a new warning message to the queue.
+   *
+   * @param string|\Drupal\Component\Render\MarkupInterface $message
+   *   (optional) The translated message to be displayed to the user. For
+   *   consistency with other messages, it should begin with a capital letter
+   *   and end with a period.
+   * @param bool $repeat
+   *   (optional) If this is FALSE and the message is already set, then the
+   *   message won't be repeated. Defaults to FALSE.
+   *
+   * @return $this
+   */
+  public function addWarning($message, $repeat = FALSE);
+
+  /**
+   * Gets all messages.
+   *
+   * @return string[][]|\Drupal\Component\Render\MarkupInterface[][]
+   *   Keys are message types and values are indexed arrays of messages. Message
+   *   types are either self::TYPE_STATUS, self::TYPE_WARNING, or
+   *   self::TYPE_ERROR.
+   */
+  public function all();
+
+  /**
+   * Gets all messages of a certain type.
+   *
+   * @param string $type
+   *   The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING,
+   *   or self::TYPE_ERROR.
+   *
+   * @return string[]|\Drupal\Component\Render\MarkupInterface[]
+   */
+  public function messagesByType($type);
+
+  /**
+   * Deletes all messages.
+   */
+  public function deleteAll();
+
+  /**
+   * Deletes all messages of a certain type.
+   *
+   * @param string $type
+   *   The messages' type. Either self::TYPE_STATUS, self::TYPE_WARNING, or
+   *   self::TYPE_ERROR.
+   */
+  public function deleteByType($type);
+
+}
diff --git a/core/lib/Drupal/Core/Render/Element/Container.php b/core/lib/Drupal/Core/Render/Element/Container.php
index 212000d7be..357e6a5484 100644
--- a/core/lib/Drupal/Core/Render/Element/Container.php
+++ b/core/lib/Drupal/Core/Render/Element/Container.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Html as HtmlUtility;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 
 /**
  * Provides a render element that wraps child elements in a container.
@@ -11,6 +12,10 @@
  * Surrounds child elements with a <div> and adds attributes such as classes or
  * an HTML ID.
  *
+ * Properties:
+ * - #optional: Indicates whether the container should render when it has no
+ *   visible children. Defaults to FALSE.
+ *
  * Usage example:
  * @code
  * $form['needs_accommodation'] = array(
@@ -46,12 +51,14 @@ class Container extends RenderElement {
   public function getInfo() {
     $class = get_class($this);
     return [
+      '#optional' => FALSE,
       '#process' => [
         [$class, 'processGroup'],
         [$class, 'processContainer'],
       ],
       '#pre_render' => [
         [$class, 'preRenderGroup'],
+        [$class, 'preRenderContainer'],
       ],
       '#theme_wrappers' => ['container'],
     ];
@@ -79,4 +86,22 @@ public static function processContainer(&$element, FormStateInterface $form_stat
     return $element;
   }
 
+  /**
+   * Prevents optional containers from rendering if they have no children.
+   *
+   * @param array $element
+   *   An associative array containing the properties and children of the
+   *   container.
+   *
+   * @return array
+   *   The modified element.
+   */
+  public static function preRenderContainer($element) {
+    // Do not render optional container elements if there are no children.
+    if (empty($element['#printed']) && !empty($element['#optional']) && !Element::getVisibleChildren($element)) {
+      $element['#printed'] = TRUE;
+    }
+    return $element;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/TypedData/ListDataDefinition.php b/core/lib/Drupal/Core/TypedData/ListDataDefinition.php
index 3109cd2115..25258a48e6 100644
--- a/core/lib/Drupal/Core/TypedData/ListDataDefinition.php
+++ b/core/lib/Drupal/Core/TypedData/ListDataDefinition.php
@@ -108,4 +108,13 @@ public function setItemDefinition(DataDefinitionInterface $definition) {
     return $this;
   }
 
+  /**
+   * Magic method: Implements a deep clone.
+   */
+  public function __clone() {
+    // Ensure the itemDefinition property is actually cloned by overwriting the
+    // original reference.
+    $this->itemDefinition = clone $this->itemDefinition;
+  }
+
 }
diff --git a/core/modules/action/tests/src/Functional/ConfigurationTest.php b/core/modules/action/tests/src/Functional/ConfigurationTest.php
index 472ba17125..a260c079cf 100644
--- a/core/modules/action/tests/src/Functional/ConfigurationTest.php
+++ b/core/modules/action/tests/src/Functional/ConfigurationTest.php
@@ -44,14 +44,15 @@ public function testActionConfiguration() {
     $this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('action_goto_action'), $edit, t('Save'));
     $this->assertResponse(200);
 
+    $action_id = $edit['id'];
+
     // Make sure that the new complex action was saved properly.
     $this->assertText(t('The action has been successfully saved.'), "Make sure we get a confirmation that we've successfully saved the complex action.");
     $this->assertText($action_label, "Make sure the action label appears on the configuration page after we've saved the complex action.");
 
     // Make another POST request to the action edit page.
     $this->clickLink(t('Configure'));
-    preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
-    $aid = $matches[1];
+
     $edit = [];
     $new_action_label = $this->randomMachineName();
     $edit['label'] = $new_action_label;
@@ -73,7 +74,7 @@ public function testActionConfiguration() {
     $this->clickLink(t('Delete'));
     $this->assertResponse(200);
     $edit = [];
-    $this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
+    $this->drupalPostForm(NULL, $edit, t('Delete'));
     $this->assertResponse(200);
 
     // Make sure that the action was actually deleted.
@@ -82,7 +83,7 @@ public function testActionConfiguration() {
     $this->assertResponse(200);
     $this->assertNoText($new_action_label, "Make sure the action label does not appear on the overview page after we've deleted the action.");
 
-    $action = Action::load($aid);
+    $action = Action::load($action_id);
     $this->assertFalse($action, 'Make sure the action is gone after being deleted.');
   }
 
diff --git a/core/modules/block_content/src/BlockContentListBuilder.php b/core/modules/block_content/src/BlockContentListBuilder.php
index 96259173cd..7a4bdfc4c8 100644
--- a/core/modules/block_content/src/BlockContentListBuilder.php
+++ b/core/modules/block_content/src/BlockContentListBuilder.php
@@ -4,7 +4,6 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
-use Drupal\Core\Routing\RedirectDestinationTrait;
 
 /**
  * Defines a class to build a listing of custom block entities.
@@ -13,8 +12,6 @@
  */
 class BlockContentListBuilder extends EntityListBuilder {
 
-  use RedirectDestinationTrait;
-
   /**
    * {@inheritdoc}
    */
@@ -31,15 +28,4 @@ public function buildRow(EntityInterface $entity) {
     return $row + parent::buildRow($entity);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultOperations(EntityInterface $entity) {
-    $operations = parent::getDefaultOperations($entity);
-    if (isset($operations['edit'])) {
-      $operations['edit']['query']['destination'] = $this->getRedirectDestination()->get();
-    }
-    return $operations;
-  }
-
 }
diff --git a/core/modules/comment/tests/src/Kernel/CommentBundlesTest.php b/core/modules/comment/tests/src/Kernel/CommentBundlesTest.php
new file mode 100644
index 0000000000..d907233409
--- /dev/null
+++ b/core/modules/comment/tests/src/Kernel/CommentBundlesTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\Tests\comment\Kernel;
+
+use Drupal\comment\Entity\CommentType;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests that comment bundles behave as expected.
+ *
+ * @group comment
+ */
+class CommentBundlesTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['comment', 'node', 'taxonomy', 'user'];
+
+  /**
+   * Entity type ids to use for target_entity_type_id on comment bundles.
+   *
+   * @var array
+   */
+  protected $targetEntityTypes;
+
+  /**
+   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
+   */
+  protected $entityFieldManager;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->entityFieldManager = $this->container->get('entity_field.manager');
+
+    $this->installEntitySchema('comment');
+
+    // Create multiple comment bundles,
+    // each of which has a different target entity type.
+    $this->targetEntityTypes = [
+      'comment' => 'Comment',
+      'node' => 'Node',
+      'taxonomy_term' => 'Taxonomy Term',
+    ];
+    foreach ($this->targetEntityTypes as $id => $label) {
+      CommentType::create([
+        'id' => 'comment_on_' . $id,
+        'label' => 'Comment on ' . $label,
+        'target_entity_type_id' => $id,
+      ])->save();
+    }
+  }
+
+  /**
+   * Test that the entity_id field is set correctly for each comment bundle.
+   */
+  public function testEntityIdField() {
+    $field_definitions = [];
+
+    foreach (array_keys($this->targetEntityTypes) as $id) {
+      $bundle = 'comment_on_' . $id;
+      $field_definitions[$bundle] = $this->entityFieldManager
+        ->getFieldDefinitions('comment', $bundle);
+    }
+    // Test that the value of the entity_id field for each bundle is correct.
+    foreach ($field_definitions as $bundle => $definition) {
+      $entity_type_id = str_replace('comment_on_', '', $bundle);
+      $target_type = $definition['entity_id']->getSetting('target_type');
+      $this->assertEquals($entity_type_id, $target_type);
+
+      // Verify that the target type remains correct
+      // in the deeply-nested object properties.
+      $nested_target_type = $definition['entity_id']->getItemDefinition()->getFieldDefinition()->getSetting('target_type');
+      $this->assertEquals($entity_type_id, $nested_target_type);
+    }
+
+  }
+
+}
diff --git a/core/modules/config/src/Tests/ConfigEntityListTest.php b/core/modules/config/src/Tests/ConfigEntityListTest.php
index e9950ea424..46c0c064b6 100644
--- a/core/modules/config/src/Tests/ConfigEntityListTest.php
+++ b/core/modules/config/src/Tests/ConfigEntityListTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Routing\RedirectDestinationTrait;
 use Drupal\simpletest\WebTestBase;
 use Drupal\config_test\Entity\ConfigTest;
 use Drupal\Core\Entity\EntityStorageInterface;
@@ -13,6 +14,8 @@
  */
 class ConfigEntityListTest extends WebTestBase {
 
+  use RedirectDestinationTrait;
+
   /**
    * Modules to enable.
    *
@@ -54,17 +57,17 @@ public function testList() {
       'edit' => [
         'title' => t('Edit'),
         'weight' => 10,
-        'url' => $entity->urlInfo(),
+        'url' => $entity->toUrl()->setOption('query', $this->getRedirectDestination()->getAsArray()),
       ],
       'disable' => [
         'title' => t('Disable'),
         'weight' => 40,
-        'url' => $entity->urlInfo('disable'),
+        'url' => $entity->toUrl('disable')->setOption('query', $this->getRedirectDestination()->getAsArray()),
       ],
       'delete' => [
         'title' => t('Delete'),
         'weight' => 100,
-        'url' => $entity->urlInfo('delete-form'),
+        'url' => $entity->toUrl('delete-form')->setOption('query', $this->getRedirectDestination()->getAsArray()),
       ],
     ];
 
@@ -129,12 +132,12 @@ public function testList() {
       'edit' => [
         'title' => t('Edit'),
         'weight' => 10,
-        'url' => $entity->urlInfo(),
+        'url' => $entity->toUrl()->setOption('query', $this->getRedirectDestination()->getAsArray()),
       ],
       'delete' => [
         'title' => t('Delete'),
         'weight' => 100,
-        'url' => $entity->urlInfo('delete-form'),
+        'url' => $entity->toUrl('delete-form')->setOption('query', $this->getRedirectDestination()->getAsArray()),
       ],
     ];
 
diff --git a/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php b/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
index b4add538ee..85d6b0bfc4 100644
--- a/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
+++ b/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Tests\field\Kernel;
 
+use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Extension\Extension;
 use Drupal\KernelTests\KernelTestBase;
 
@@ -21,8 +22,8 @@ class FieldDefinitionIntegrityTest extends KernelTestBase {
    * Tests the integrity of field plugin definitions.
    */
   public function testFieldPluginDefinitionIntegrity() {
-
-    // Enable all core modules that provide field plugins.
+    // Enable all core modules that provide field plugins, and their
+    // dependencies.
     $modules = system_rebuild_module_data();
     $modules = array_filter($modules, function (Extension $module) {
       // Filter contrib, hidden, already enabled modules and modules in the
@@ -36,7 +37,13 @@ public function testFieldPluginDefinitionIntegrity() {
       }
       return FALSE;
     });
-    $this->enableModules(array_keys($modules));
+    // Gather the dependencies of the modules.
+    $dependencies = NestedArray::mergeDeepArray(array_map(function (Extension $module) {
+      return array_keys($module->requires);
+    }, $modules));
+    $modules = array_unique(NestedArray::mergeDeep(array_keys($modules), $dependencies));
+
+    $this->enableModules($modules);
 
     /** @var \Drupal\Component\Plugin\Discovery\DiscoveryInterface $field_type_manager */
     $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
diff --git a/core/modules/filter/tests/src/Functional/FilterAdminTest.php b/core/modules/filter/tests/src/Functional/FilterAdminTest.php
index 21431e7969..a6e429304e 100644
--- a/core/modules/filter/tests/src/Functional/FilterAdminTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterAdminTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Url;
 use Drupal\filter\Entity\FilterFormat;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
@@ -135,16 +136,9 @@ public function testFormatAdmin() {
 
     // Edit text format.
     $this->drupalGet('admin/config/content/formats');
-    // Cannot use the assertNoLinkByHref method as it does partial url matching
-    // and 'admin/config/content/formats/manage/' . $format_id . '/disable'
-    // exists.
-    // @todo: See https://www.drupal.org/node/2031223 for the above.
-    $edit_link = $this->xpath('//a[@href=:href]', [
-      ':href' => \Drupal::url('entity.filter_format.edit_form', ['filter_format' => $format_id])
-    ]);
-    $this->assertNotEmpty($edit_link, format_string('Link href %href found.',
-      ['%href' => 'admin/config/content/formats/manage/' . $format_id]
-    ));
+    $destination = Url::fromRoute('filter.admin_overview')->toString();
+    $edit_href = Url::fromRoute('entity.filter_format.edit_form', ['filter_format' => $format_id], ['query' => ['destination' => $destination]])->toString();
+    $this->assertSession()->linkByHrefExists($edit_href);
     $this->drupalGet('admin/config/content/formats/manage/' . $format_id);
     $this->drupalPostForm(NULL, [], t('Save configuration'));
 
diff --git a/core/modules/node/src/NodeListBuilder.php b/core/modules/node/src/NodeListBuilder.php
index 4dbdf27bf2..eac48fda31 100644
--- a/core/modules/node/src/NodeListBuilder.php
+++ b/core/modules/node/src/NodeListBuilder.php
@@ -25,13 +25,6 @@ class NodeListBuilder extends EntityListBuilder {
    */
   protected $dateFormatter;
 
-  /**
-   * The redirect destination service.
-   *
-   * @var \Drupal\Core\Routing\RedirectDestinationInterface
-   */
-  protected $redirectDestination;
-
   /**
    * Constructs a new NodeListBuilder object.
    *
@@ -128,17 +121,4 @@ public function buildRow(EntityInterface $entity) {
     return $row + parent::buildRow($entity);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function getDefaultOperations(EntityInterface $entity) {
-    $operations = parent::getDefaultOperations($entity);
-
-    $destination = $this->redirectDestination->getAsArray();
-    foreach ($operations as $key => $operation) {
-      $operations[$key]['query'] = $destination;
-    }
-    return $operations;
-  }
-
 }
diff --git a/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php b/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php
index fbfda8f169..c2c7617bf6 100644
--- a/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php
+++ b/core/modules/node/tests/src/Functional/NodeActionsConfigurationTest.php
@@ -43,14 +43,14 @@ public function testAssignOwnerNodeActionConfiguration() {
     $this->drupalPostForm('admin/config/system/actions/add/' . Crypt::hashBase64('node_assign_owner_action'), $edit, t('Save'));
     $this->assertResponse(200);
 
+    $action_id = $edit['id'];
+
     // Make sure that the new action was saved properly.
     $this->assertText(t('The action has been successfully saved.'), 'The node_assign_owner_action action has been successfully saved.');
     $this->assertText($action_label, 'The label of the node_assign_owner_action action appears on the actions administration page after saving.');
 
     // Make another POST request to the action edit page.
     $this->clickLink(t('Configure'));
-    preg_match('|admin/config/system/actions/configure/(.+)|', $this->getUrl(), $matches);
-    $aid = $matches[1];
     $edit = [];
     $new_action_label = $this->randomMachineName();
     $edit['label'] = $new_action_label;
@@ -68,7 +68,7 @@ public function testAssignOwnerNodeActionConfiguration() {
     $this->clickLink(t('Delete'));
     $this->assertResponse(200);
     $edit = [];
-    $this->drupalPostForm("admin/config/system/actions/configure/$aid/delete", $edit, t('Delete'));
+    $this->drupalPostForm(NULL, $edit, t('Delete'));
     $this->assertResponse(200);
 
     // Make sure that the action was actually deleted.
@@ -77,7 +77,7 @@ public function testAssignOwnerNodeActionConfiguration() {
     $this->assertResponse(200);
     $this->assertNoText($new_action_label, 'The label for the node_assign_owner_action action does not appear on the actions administration page after deleting.');
 
-    $action = Action::load($aid);
+    $action = Action::load($action_id);
     $this->assertFalse($action, 'The node_assign_owner_action action is not available after being deleted.');
   }
 
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php
new file mode 100644
index 0000000000..c873ccc00e
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestComputedField.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\entity_test\Entity;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList;
+
+/**
+ * An entity used for testing computed field values.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_computed_field",
+ *   label = @Translation("Entity Test computed field"),
+ *   base_table = "entity_test_computed_field",
+ *   handlers = {
+ *     "views_data" = "Drupal\entity_test\EntityTestViewsData"
+ *   },
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "name",
+ *   },
+ *   admin_permission = "administer entity_test content",
+ *   links = {
+ *     "add-form" = "/entity_test_computed_field/add",
+ *   },
+ * )
+ */
+class EntityTestComputedField extends EntityTest {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    $fields['computed_string_field'] = BaseFieldDefinition::create('string')
+      ->setLabel('Computed Field Test')
+      ->setComputed(TRUE)
+      ->setClass(ComputedTestFieldItemList::class);
+
+    return $fields;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
index 3bb0d24c64..27a1186ada 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewsData.php
@@ -16,6 +16,17 @@ class EntityTestViewsData extends EntityViewsData {
   public function getViewsData() {
     $views_data = parent::getViewsData();
 
+    if ($this->entityType->id() === 'entity_test_computed_field') {
+      $views_data['entity_test_computed_field']['computed_string_field'] = [
+        'title' => $this->t('Computed String Field'),
+        'field' => [
+          'id' => 'field',
+          'default_formatter' => 'string',
+          'field_name' => 'computed_string_field',
+        ],
+      ];
+    }
+
     if ($this->entityType->id() != 'entity_test') {
       return $views_data;
     }
diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php
new file mode 100644
index 0000000000..864d33fe06
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/ComputedTestFieldItemList.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Drupal\entity_test\Plugin\Field;
+
+use Drupal\Core\Field\FieldItemList;
+
+/**
+ * A computed field item list.
+ */
+class ComputedTestFieldItemList extends FieldItemList {
+
+  /**
+   * Compute the list property from state.
+   */
+  protected function computedListProperty() {
+    foreach (\Drupal::state()->get('entity_test_computed_field_item_list_value', []) as $delta => $item) {
+      $this->list[$delta] = $this->createItem($delta, $item);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get($index) {
+    $this->computedListProperty();
+    return isset($this->list[$index]) ? $this->list[$index] : NULL;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIterator() {
+    $this->computedListProperty();
+    return parent::getIterator();
+  }
+
+}
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index 2250a0bb2f..b6887794cb 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -489,3 +489,11 @@ form_test.get_form:
     _form: '\Drupal\form_test\Form\FormTestGetForm'
   requirements:
     _access: 'TRUE'
+
+form_test.optional_container:
+  path: '/form-test/optional-container'
+  defaults:
+    _form: '\Drupal\form_test\Form\FormTestOptionalContainerForm'
+    _title: 'Optional container testing'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestOptionalContainerForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestOptionalContainerForm.php
new file mode 100644
index 0000000000..7cacf2e20c
--- /dev/null
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestOptionalContainerForm.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Drupal\form_test\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Builds a simple form to test the #optional property on #type 'container'.
+ */
+class FormTestOptionalContainerForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'form_test_optional_container';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    // Empty containers.
+    $form['empty_optional'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['empty_optional']],
+      '#optional' => TRUE,
+    ];
+    $form['empty_nonoptional'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['empty_nonoptional']],
+      '#optional' => FALSE,
+    ];
+
+    // Non-empty containers
+    $form['nonempty_optional'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['nonempty_optional']],
+      '#optional' => TRUE,
+    ];
+    $form['nonempty_optional']['child_1'] = [];
+
+    $form['nonempty_nonoptional'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['nonempty_nonoptional']],
+      '#optional' => FALSE,
+    ];
+    $form['nonempty_nonoptional']['child_2'] = [];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
diff --git a/core/modules/system/tests/src/Functional/Form/ElementsContainerTest.php b/core/modules/system/tests/src/Functional/Form/ElementsContainerTest.php
new file mode 100644
index 0000000000..a7d404b86b
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Form/ElementsContainerTest.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Form;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the container form element for expected behavior.
+ *
+ * @group Form
+ */
+class ElementsContainerTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['form_test'];
+
+  /**
+   * Tests the #optional container property.
+   */
+  public function testOptionalContainerElements() {
+    $this->drupalGet('form-test/optional-container');
+    $assertSession = $this->assertSession();
+    $assertSession->elementNotExists('css', 'div.empty_optional');
+    $assertSession->elementExists('css', 'div.empty_nonoptional');
+    $assertSession->elementExists('css', 'div.nonempty_optional');
+    $assertSession->elementExists('css', 'div.nonempty_nonoptional');
+  }
+
+}
diff --git a/core/modules/views/src/Plugin/views/field/EntityField.php b/core/modules/views/src/Plugin/views/field/EntityField.php
index f580e502a8..ee2882c3b5 100644
--- a/core/modules/views/src/Plugin/views/field/EntityField.php
+++ b/core/modules/views/src/Plugin/views/field/EntityField.php
@@ -316,24 +316,33 @@ public function clickSort($order) {
   }
 
   /**
-   * Gets the field storage of the used field.
+   * Gets the field storage definition.
    *
    * @return \Drupal\Core\Field\FieldStorageDefinitionInterface
+   *   The field storage definition used by this handler.
    */
   protected function getFieldStorageDefinition() {
     $entity_type_id = $this->definition['entity_type'];
     $field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
 
-    $field_storage = NULL;
     // @todo Unify 'entity field'/'field_name' instead of converting back and
     //   forth. https://www.drupal.org/node/2410779
-    if (isset($this->definition['field_name'])) {
-      $field_storage = $field_storage_definitions[$this->definition['field_name']];
+    if (isset($this->definition['field_name']) && isset($field_storage_definitions[$this->definition['field_name']])) {
+      return $field_storage_definitions[$this->definition['field_name']];
     }
-    elseif (isset($this->definition['entity field'])) {
-      $field_storage = $field_storage_definitions[$this->definition['entity field']];
+
+    if (isset($this->definition['entity field']) && isset($field_storage_definitions[$this->definition['entity field']])) {
+      return $field_storage_definitions[$this->definition['entity field']];
+    }
+
+    // The list of field storage definitions above does not include computed
+    // base fields, so we need to explicitly fetch a list of all base fields in
+    // order to support them.
+    // @see \Drupal\Core\Entity\EntityFieldManager::getFieldStorageDefinitions()
+    $base_fields = $this->entityManager->getBaseFieldDefinitions($entity_type_id);
+    if (isset($this->definition['field_name']) && isset($base_fields[$this->definition['field_name']])) {
+      return $base_fields[$this->definition['field_name']]->getFieldStorageDefinition();
     }
-    return $field_storage;
   }
 
   /**
diff --git a/core/modules/views/src/Plugin/views/field/EntityOperations.php b/core/modules/views/src/Plugin/views/field/EntityOperations.php
index c8a307bd1d..4ca28f6d92 100644
--- a/core/modules/views/src/Plugin/views/field/EntityOperations.php
+++ b/core/modules/views/src/Plugin/views/field/EntityOperations.php
@@ -84,7 +84,7 @@ public function defineOptions() {
     $options = parent::defineOptions();
 
     $options['destination'] = [
-      'default' => TRUE,
+      'default' => FALSE,
     ];
 
     return $options;
@@ -99,7 +99,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
     $form['destination'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Include destination'),
-      '#description' => $this->t('Include a <code>destination</code> parameter in the link to return the user to the original view upon completing the link action.'),
+      '#description' => $this->t('Enforce a <code>destination</code> parameter in the link to return the user to the original view upon completing the link action. Most operations include a destination by default and this setting is no longer needed.'),
       '#default_value' => $this->options['destination'],
     ];
   }
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml
new file mode 100644
index 0000000000..d8de3f1883
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.computed_field_view.yml
@@ -0,0 +1,171 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_test
+id: computed_field_view
+label: 'Computed Field View'
+module: views
+description: ''
+tag: ''
+base_table: entity_test_computed_field
+base_field: id
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: none
+        options: {  }
+      cache:
+        type: tag
+        options: {  }
+      query:
+        type: views_query
+        options:
+          disable_sql_rewrite: false
+          distinct: false
+          replica: false
+          query_comment: ''
+          query_tags: {  }
+      exposed_form:
+        type: basic
+        options:
+          submit_button: Apply
+          reset_button: false
+          reset_button_label: Reset
+          exposed_sorts_label: 'Sort by'
+          expose_sort_order: true
+          sort_asc_label: Asc
+          sort_desc_label: Desc
+      pager:
+        type: mini
+        options:
+          items_per_page: 10
+          offset: 0
+          id: 0
+          total_pages: null
+          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
+          tags:
+            previous: ‹‹
+            next: ››
+      style:
+        type: default
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          uses_fields: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        computed_string_field:
+          id: computed_string_field
+          table: entity_test_computed_field
+          field: computed_string_field
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          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: false
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: false
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: entity_test_computed_field
+          plugin_id: field
+      filters: {  }
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: foo
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
diff --git a/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
index 653ce11527..7ced4f7071 100644
--- a/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
@@ -73,7 +73,10 @@ public function testEntityOperations() {
         $this->assertTrue(count($operations) > 0, 'There are operations.');
         foreach ($operations as $operation) {
           $expected_destination = Url::fromUri('internal:/test-entity-operations')->toString();
-          $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', [':path' => $operation['url']->toString() . '?destination=' . $expected_destination, ':title' => (string) $operation['title']]);
+          // Update destination property of the URL as generating it in the
+          // test would by default point to the frontpage.
+          $operation['url']->setOption('query', ['destination' => $expected_destination]);
+          $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[@href=:path and text()=:title]', [':path' => $operation['url']->toString(), ':title' => (string) $operation['title']]);
           $this->assertEqual(count($result), 1, t('Found entity @operation link with destination parameter.', ['@operation' => $operation['title']]));
           // Entities which were created in Hungarian should link to the Hungarian
           // edit form, others to the English one (which has no path prefix here).
diff --git a/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php
new file mode 100644
index 0000000000..8f85f69018
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Handler/ComputedFieldTest.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Handler;
+
+use Drupal\entity_test\Entity\EntityTestComputedField;
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Provides some integration tests for the Field handler.
+ *
+ * @see \Drupal\views\Plugin\views\field\EntityField
+ * @group views
+ */
+class ComputedFieldTest extends ViewsKernelTestBase {
+
+  /**
+   * Views to be enabled.
+   *
+   * @var array
+   */
+  public static $testViews = ['computed_field_view'];
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['entity_test'];
+
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('entity_test_computed_field');
+  }
+
+  /**
+   * Test the computed field handler.
+   */
+  public function testComputedFieldHandler() {
+    \Drupal::state()->set('entity_test_computed_field_item_list_value', ['computed string']);
+
+    $entity = EntityTestComputedField::create([]);
+    $entity->save();
+
+    $view = Views::getView('computed_field_view');
+
+    $rendered_view = $view->preview();
+    $output = $this->container->get('renderer')->renderRoot($rendered_view);
+    $this->assertContains('computed string', (string) $output);
+  }
+
+}
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
index 6f4e9ceeed..9f2e6770fb 100644
--- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
@@ -267,7 +267,7 @@ public function getTransitions(array $transition_ids = NULL) {
   }
 
   /**
-   * Sort states or transitions by weight and label.
+   * Sort states or transitions by weight, label, and key.
    *
    * @param \Drupal\workflows\StateInterface[]|\Drupal\workflows\TransitionInterface[] $objects
    *   Objects to multi-sort.
@@ -277,15 +277,23 @@ public function getTransitions(array $transition_ids = NULL) {
    */
   protected static function labelWeightMultisort($objects) {
     if (count($objects) > 1) {
+      // Separate weights, labels, and keys into arrays.
       $weights = $labels = [];
+      $keys = array_keys($objects);
       foreach ($objects as $id => $object) {
         $weights[$id] = $object->weight();
         $labels[$id] = $object->label();
       }
+      // Sort weights, labels, and keys in the same order as each other.
       array_multisort(
         $weights, SORT_NUMERIC, SORT_ASC,
-        $labels, SORT_NATURAL, SORT_ASC
+        $labels, SORT_NATURAL, SORT_ASC,
+        $keys
       );
+      // Combine keys and weights to make sure the weights are keyed with the
+      // correct keys.
+      $weights = array_combine($keys, $weights);
+      // Return the objects sorted by weight.
       return array_replace($weights, $objects);
     }
     return $objects;
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php
index 679b314d19..a466a7d571 100644
--- a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeStateForm.php
@@ -22,7 +22,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#type' => 'textfield',
       '#title' => $this->t('Extra'),
       '#description' => $this->t('Extra information added to state'),
-      '#default_value' => isset($configuration['states'][$state->id()]['extra']) ? $configuration['states'][$state->id()]['extra'] : '',
+      '#default_value' => $state && isset($configuration['states'][$state->id()]['extra']) ? $configuration['states'][$state->id()]['extra'] : '',
     ];
     return $form;
   }
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php
index 45e15139b9..a88306c750 100644
--- a/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Form/ComplexTestTypeTransitionForm.php
@@ -22,7 +22,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#type' => 'textfield',
       '#title' => $this->t('Extra'),
       '#description' => $this->t('Extra information added to transition'),
-      '#default_value' => isset($configuration['transitions'][$transition->id()]['extra']) ? $configuration['transitions'][$transition->id()]['extra'] : '',
+      '#default_value' => $transition && isset($configuration['transitions'][$transition->id()]['extra']) ? $configuration['transitions'][$transition->id()]['extra'] : '',
     ];
     return $form;
   }
diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
index fcbcbd0448..886750161c 100644
--- a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
+++ b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
@@ -293,4 +293,29 @@ public function testWorkflowConfigurationForm() {
     $this->assertEquals('Extra global settings', $workflow->getTypePlugin()->getConfiguration()['example_setting']);
   }
 
+  /**
+   * Test a workflow, state, and transition can have a numeric ID and label.
+   */
+  public function testNumericIds() {
+    $this->drupalLogin($this->createUser(['administer workflows']));
+    $this->drupalGet('admin/config/workflow/workflows');
+    $this->clickLink('Add workflow');
+    $this->submitForm(['label' => 123, 'id' => 123, 'workflow_type' => 'workflow_type_complex_test'], 'Save');
+
+    $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/123/add_state');
+
+    $this->submitForm(['label' => 456, 'id' => 456], 'Save');
+    $this->assertSession()->pageTextContains('Created 456 state.');
+
+    $this->clickLink('Add a new transition');
+    $this->submitForm(['id' => 789, 'label' => 789, 'from[456]' => 456, 'to' => 456], 'Save');
+    $this->assertSession()->pageTextContains('Created 789 transition.');
+
+    $workflow = $this->container->get('entity_type.manager')->getStorage('workflow')->loadUnchanged(123);
+    $this->assertEquals(123, $workflow->id());
+    $this->assertEquals(456, $workflow->getTypePlugin()->getState(456)->id());
+    $this->assertEquals(789, $workflow->getTypePlugin()->getTransition(789)->id());
+    $this->assertEquals(456, $workflow->getTypePlugin()->getTransition(789)->to()->id());
+  }
+
 }
diff --git a/core/modules/workflows/tests/src/Unit/WorkflowTest.php b/core/modules/workflows/tests/src/Unit/WorkflowTest.php
index 4d28ab6cb4..8cf449367c 100644
--- a/core/modules/workflows/tests/src/Unit/WorkflowTest.php
+++ b/core/modules/workflows/tests/src/Unit/WorkflowTest.php
@@ -117,6 +117,27 @@ public function testGetStates() {
     $this->assertArrayEquals([], array_keys($workflow->getTypePlugin()->getStates([])));
   }
 
+  /**
+   * Test numeric IDs when added to a workflow.
+   */
+  public function testNumericIdSorting() {
+    $workflow = new Workflow(['id' => 'test', 'type' => 'test_type'], 'workflow');
+    $workflow_type = $workflow->getTypePlugin();
+
+    $workflow_type->addState('1', 'One');
+    $workflow_type->addState('2', 'Two');
+    $workflow_type->addState('3', 'ZZZ');
+    $workflow_type->addState('4', 'AAA');
+
+    $workflow_type->setStateWeight('1', 1);
+    $workflow_type->setStateWeight('2', 2);
+    $workflow_type->setStateWeight('3', 3);
+    $workflow_type->setStateWeight('4', 3);
+
+    // Ensure numeric states are correctly sorted by weight first, label second.
+    $this->assertEquals([1, 2, 4, 3], array_keys($workflow_type->getStates()));
+  }
+
   /**
    * @covers ::getStates
    */
diff --git a/core/scripts/js/babel-es6-watch.js b/core/scripts/js/babel-es6-watch.js
index 9b49482236..c9d1b147e0 100644
--- a/core/scripts/js/babel-es6-watch.js
+++ b/core/scripts/js/babel-es6-watch.js
@@ -39,8 +39,5 @@ watcher
     fs.stat(`${fileName}.js`, () => {
       fs.unlink(`${fileName}.js`, unlinkHandler);
     });
-    fs.stat(`${fileName}.js.map`, () => {
-      fs.unlink(`${fileName}.js.map`, unlinkHandler);
-    });
   })
   .on('ready', () => log(`Watching '${fileMatch}' for changes.`));
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
index e0bf6551ff..12c4c75855 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityFieldTest.php
@@ -16,6 +16,7 @@
 use Drupal\Core\TypedData\ListInterface;
 use Drupal\Core\TypedData\Type\StringInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
+use Drupal\entity_test\Entity\EntityTestComputedField;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
 
@@ -737,6 +738,16 @@ public function testComputedProperties() {
     }
   }
 
+  /**
+   * Test computed fields.
+   */
+  public function testComputedFields() {
+    \Drupal::state()->set('entity_test_computed_field_item_list_value', ['foo computed']);
+
+    $entity = EntityTestComputedField::create([]);
+    $this->assertEquals($entity->computed_string_field->value, 'foo computed');
+  }
+
   /**
    * Executes the computed properties tests for the given entity type.
    *
diff --git a/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php b/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php
index 583e55b7c4..590a96cd5f 100644
--- a/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Field/FieldSettingsTest.php
@@ -46,6 +46,34 @@ public function testBaseFieldSettings() {
     $this->assertEqual($base_field->getSettings(), $expected_settings);
   }
 
+  /**
+   * Tests the base field settings on a cloned base field definition object.
+   */
+  public function testBaseFieldSettingsOnClone() {
+    $base_field = BaseFieldDefinition::create('test_field');
+
+    // Check that the default settings have been populated.
+    $expected_settings = [
+      'test_field_storage_setting' => 'dummy test string',
+      'changeable' => 'a changeable field storage setting',
+      'unchangeable' => 'an unchangeable field storage setting',
+      'translatable_storage_setting' => 'a translatable field storage setting',
+      'test_field_setting' => 'dummy test string',
+      'translatable_field_setting' => 'a translatable field setting',
+    ];
+    $this->assertEquals($expected_settings, $base_field->getSettings());
+
+    // Clone the base field object and change one single setting using
+    // setSettings() on the cloned base field and check that it has been
+    // changed only on the cloned object.
+    $clone_base_field = clone $base_field;
+    $expected_settings_clone = $expected_settings;
+    $expected_settings_clone['changeable'] = $expected_settings['changeable'] . ' (clone)';
+    $clone_base_field->setSetting('changeable', $expected_settings_clone['changeable']);
+    $this->assertEquals($expected_settings, $base_field->getSettings());
+    $this->assertEquals($expected_settings_clone, $clone_base_field->getSettings());
+  }
+
   /**
    * @covers \Drupal\field\Entity\FieldStorageConfig::getSettings
    * @covers \Drupal\field\Entity\FieldStorageConfig::setSettings
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 09a82c3483..6d9c10a045 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -814,7 +814,7 @@ protected function enableModules(array $modules) {
 
     foreach ($modules as $module) {
       if ($module_handler->moduleExists($module)) {
-        throw new \LogicException("$module module is already enabled.");
+        continue;
       }
       $module_handler->addModule($module, $module_list[$module]->getPath());
       // Maintain the list of enabled modules in configuration.
diff --git a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php
index fc3722fd5e..5bd622061d 100644
--- a/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/AccessResultTest.php
@@ -128,6 +128,9 @@ public function testAccessForbiddenReason() {
     $reason = $this->getRandomGenerator()->string();
     $b = AccessResult::forbidden($reason);
     $verify($b, $reason);
+
+    $b = AccessResult::forbiddenIf(TRUE, $reason);
+    $verify($b, $reason);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
index 44e771ceaa..ad68e2df68 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityListBuilderTest.php
@@ -11,6 +11,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityListBuilder;
+use Drupal\Core\Routing\RedirectDestinationInterface;
 use Drupal\entity_test\EntityTestListBuilder;
 use Drupal\Tests\UnitTestCase;
 
@@ -62,6 +63,13 @@ class EntityListBuilderTest extends UnitTestCase {
    */
   protected $role;
 
+  /**
+   * The redirect destination service.
+   *
+   * @var \Drupal\Core\Routing\RedirectDestinationInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $redirectDestination;
+
   /**
    * The EntityListBuilder object to test.
    *
@@ -80,7 +88,8 @@ protected function setUp() {
     $this->moduleHandler = $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface');
     $this->entityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface');
     $this->translationManager = $this->getMock('\Drupal\Core\StringTranslation\TranslationInterface');
-    $this->entityListBuilder = new TestEntityListBuilder($this->entityType, $this->roleStorage, $this->moduleHandler);
+    $this->entityListBuilder = new TestEntityListBuilder($this->entityType, $this->roleStorage);
+    $this->redirectDestination = $this->getMock(RedirectDestinationInterface::class);
     $this->container = new ContainerBuilder();
     \Drupal::setContainer($this->container);
   }
@@ -117,12 +126,20 @@ public function testGetOperations() {
     $url->expects($this->any())
       ->method('toArray')
       ->will($this->returnValue([]));
+    $url->expects($this->atLeastOnce())
+      ->method('mergeOptions')
+      ->with(['query' => ['destination' => '/foo/bar']]);
     $this->role->expects($this->any())
-      ->method('urlInfo')
+      ->method('toUrl')
       ->will($this->returnValue($url));
 
-    $list = new EntityListBuilder($this->entityType, $this->roleStorage, $this->moduleHandler);
+    $this->redirectDestination->expects($this->atLeastOnce())
+      ->method('getAsArray')
+      ->willReturn(['destination' => '/foo/bar']);
+
+    $list = new EntityListBuilder($this->entityType, $this->roleStorage);
     $list->setStringTranslation($this->translationManager);
+    $list->setRedirectDestination($this->redirectDestination);
 
     $operations = $list->getOperations($this->role);
     $this->assertInternalType('array', $operations);
