diff --git a/.editorconfig b/.editorconfig
index 242859d822..686c443cec 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -13,5 +13,5 @@ charset = utf-8
 trim_trailing_whitespace = true
 insert_final_newline = true
 
-[composer.json]
+[composer.{json,lock}]
 indent_size = 4
diff --git a/.eslintignore b/.eslintignore
index de133ba449..9c134873d4 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,5 +1,4 @@
-core/assets/vendor/**/*
-core/modules/locale/tests/locale_test.js
+core/**/*
 vendor/**/*
 sites/**/files/**/*
 libraries/**/*
diff --git a/composer.json b/composer.json
index 7a97a47995..38078d6b06 100644
--- a/composer.json
+++ b/composer.json
@@ -8,7 +8,7 @@
         "wikimedia/composer-merge-plugin": "~1.4"
     },
     "replace": {
-        "drupal/core": "~8.3"
+        "drupal/core": "~8.4"
     },
     "minimum-stability": "dev",
     "prefer-stable": true,
diff --git a/composer.lock b/composer.lock
index eb564b8e05..d7c3a26a81 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,31 +4,40 @@
         "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": "38fbd049e065401d0e3a8f7b92465485",
+    "content-hash": "5264cac45d935c61a1d48a32b71c9f15",
     "packages": [
         {
             "name": "asm89/stack-cors",
-            "version": "1.0.0",
+            "version": "1.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/asm89/stack-cors.git",
-                "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc"
+                "reference": "65ccbd455370f043c2e3b93482a3813603d68731"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/asm89/stack-cors/zipball/3ae8ef219bb4c9a6caf857421719aa07fa7776cc",
-                "reference": "3ae8ef219bb4c9a6caf857421719aa07fa7776cc",
+                "url": "https://api.github.com/repos/asm89/stack-cors/zipball/65ccbd455370f043c2e3b93482a3813603d68731",
+                "reference": "65ccbd455370f043c2e3b93482a3813603d68731",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.2",
-                "symfony/http-foundation": "~2.1|~3.0",
-                "symfony/http-kernel": "~2.1|~3.0"
+                "php": ">=5.5.9",
+                "symfony/http-foundation": "~2.7|~3.0",
+                "symfony/http-kernel": "~2.7|~3.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.0 || ^4.8.10",
+                "squizlabs/php_codesniffer": "^2.3"
             },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1-dev"
+                }
+            },
             "autoload": {
-                "psr-0": {
-                    "Asm89\\Stack": "src/"
+                "psr-4": {
+                    "Asm89\\Stack\\": "src/Asm89/Stack/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -47,7 +56,7 @@
                 "cors",
                 "stack"
             ],
-            "time": "2016-08-01T12:05:04+00:00"
+            "time": "2017-04-11T20:03:41+00:00"
         },
         {
             "name": "composer/installers",
@@ -909,48 +918,6 @@
             "time": "2017-03-20T17:10:46+00:00"
         },
         {
-            "name": "ircmaxell/password-compat",
-            "version": "v1.0.4",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/ircmaxell/password_compat.git",
-                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
-                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
-                "shasum": ""
-            },
-            "require-dev": {
-                "phpunit/phpunit": "4.*"
-            },
-            "type": "library",
-            "autoload": {
-                "files": [
-                    "lib/password.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Anthony Ferrara",
-                    "email": "ircmaxell@php.net",
-                    "homepage": "http://blog.ircmaxell.com"
-                }
-            ],
-            "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
-            "homepage": "https://github.com/ircmaxell/password_compat",
-            "keywords": [
-                "hashing",
-                "password"
-            ],
-            "time": "2014-11-20T16:49:30+00:00"
-        },
-        {
             "name": "masterminds/html5",
             "version": "2.2.2",
             "source": {
@@ -1270,29 +1237,32 @@
         },
         {
             "name": "symfony/class-loader",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/class-loader.git",
-                "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93"
+                "reference": "fc4c04bfd17130a9dccfded9578353f311967da7"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/class-loader/zipball/2c8de07a8a4cc4da9c018ab7a81888b80e762f93",
-                "reference": "2c8de07a8a4cc4da9c018ab7a81888b80e762f93",
+                "url": "https://api.github.com/repos/symfony/class-loader/zipball/fc4c04bfd17130a9dccfded9578353f311967da7",
+                "reference": "fc4c04bfd17130a9dccfded9578353f311967da7",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
-                "symfony/polyfill-apcu": "~1.1"
+                "php": ">=5.5.9"
             },
             "require-dev": {
-                "symfony/finder": "^2.0.5|~3.0.0"
+                "symfony/finder": "~2.8|~3.0",
+                "symfony/polyfill-apcu": "~1.1"
+            },
+            "suggest": {
+                "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1319,41 +1289,43 @@
             ],
             "description": "Symfony ClassLoader Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-18T19:13:35+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/console",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/console.git",
-                "reference": "81508e6fac4476771275a3f4f53c3fee9b956bfa"
+                "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/console/zipball/81508e6fac4476771275a3f4f53c3fee9b956bfa",
-                "reference": "81508e6fac4476771275a3f4f53c3fee9b956bfa",
+                "url": "https://api.github.com/repos/symfony/console/zipball/a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
+                "reference": "a7a17e0c6c3c4d70a211f80782e4b90ddadeaa38",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
-                "symfony/debug": "^2.7.2|~3.0.0",
+                "php": ">=5.5.9",
+                "symfony/debug": "~2.8|~3.0",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/event-dispatcher": "~2.1|~3.0.0",
-                "symfony/process": "~2.1|~3.0.0"
+                "symfony/event-dispatcher": "~2.8|~3.0",
+                "symfony/filesystem": "~2.8|~3.0",
+                "symfony/process": "~2.8|~3.0"
             },
             "suggest": {
                 "psr/log": "For using the console logger",
                 "symfony/event-dispatcher": "",
+                "symfony/filesystem": "",
                 "symfony/process": ""
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1380,37 +1352,37 @@
             ],
             "description": "Symfony Console Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-04T11:00:12+00:00"
+            "time": "2017-04-26T01:39:17+00:00"
         },
         {
             "name": "symfony/debug",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/debug.git",
-                "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc"
+                "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/debug/zipball/e90099a2958d4833a02d05b504cc06e1c234abcc",
-                "reference": "e90099a2958d4833a02d05b504cc06e1c234abcc",
+                "url": "https://api.github.com/repos/symfony/debug/zipball/fd6eeee656a5a7b384d56f1072243fe1c0e81686",
+                "reference": "fd6eeee656a5a7b384d56f1072243fe1c0e81686",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": ">=5.5.9",
                 "psr/log": "~1.0"
             },
             "conflict": {
                 "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
             },
             "require-dev": {
-                "symfony/class-loader": "~2.2|~3.0.0",
-                "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0"
+                "symfony/class-loader": "~2.8|~3.0",
+                "symfony/http-kernel": "~2.8|~3.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1437,32 +1409,32 @@
             ],
             "description": "Symfony Debug Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-18T19:13:35+00:00"
+            "time": "2017-04-19T20:17:50+00:00"
         },
         {
             "name": "symfony/dependency-injection",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dependency-injection.git",
-                "reference": "efdbeefa454a41154fd99a6f0489f0e9cb46c497"
+                "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/efdbeefa454a41154fd99a6f0489f0e9cb46c497",
-                "reference": "efdbeefa454a41154fd99a6f0489f0e9cb46c497",
+                "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59",
+                "reference": "5e00857475b6d1fa31ff4c76f1fddf1cfa9e8d59",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
             },
             "conflict": {
-                "symfony/expression-language": "<2.6"
+                "symfony/yaml": "<3.2"
             },
             "require-dev": {
-                "symfony/config": "~2.2|~3.0.0",
-                "symfony/expression-language": "~2.6|~3.0.0",
-                "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7"
+                "symfony/config": "~2.8|~3.0",
+                "symfony/expression-language": "~2.8|~3.0",
+                "symfony/yaml": "~3.2"
             },
             "suggest": {
                 "symfony/config": "",
@@ -1473,7 +1445,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1500,31 +1472,31 @@
             ],
             "description": "Symfony DependencyInjection Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-28T12:31:05+00:00"
+            "time": "2017-04-26T01:39:17+00:00"
         },
         {
             "name": "symfony/event-dispatcher",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/event-dispatcher.git",
-                "reference": "bb4ec47e8e109c1c1172145732d0aa468d967cd0"
+                "reference": "b8a401f733b43251e1d088c589368b2a94155e40"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bb4ec47e8e109c1c1172145732d0aa468d967cd0",
-                "reference": "bb4ec47e8e109c1c1172145732d0aa468d967cd0",
+                "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b8a401f733b43251e1d088c589368b2a94155e40",
+                "reference": "b8a401f733b43251e1d088c589368b2a94155e40",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/config": "^2.0.5|~3.0.0",
-                "symfony/dependency-injection": "~2.6|~3.0.0",
-                "symfony/expression-language": "~2.6|~3.0.0",
-                "symfony/stopwatch": "~2.3|~3.0.0"
+                "symfony/config": "~2.8|~3.0",
+                "symfony/dependency-injection": "~2.8|~3.0",
+                "symfony/expression-language": "~2.8|~3.0",
+                "symfony/stopwatch": "~2.8|~3.0"
             },
             "suggest": {
                 "symfony/dependency-injection": "",
@@ -1533,7 +1505,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1560,35 +1532,33 @@
             ],
             "description": "Symfony EventDispatcher Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-21T08:33:48+00:00"
+            "time": "2017-05-01T14:58:48+00:00"
         },
         {
             "name": "symfony/http-foundation",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-foundation.git",
-                "reference": "88af747e7af17d8d7d439ad4639dc3e23ddd3edd"
+                "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/88af747e7af17d8d7d439ad4639dc3e23ddd3edd",
-                "reference": "88af747e7af17d8d7d439ad4639dc3e23ddd3edd",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9de6add7f731e5af7f5b2e9c0da365e43383ebef",
+                "reference": "9de6add7f731e5af7f5b2e9c0da365e43383ebef",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
-                "symfony/polyfill-mbstring": "~1.1",
-                "symfony/polyfill-php54": "~1.0",
-                "symfony/polyfill-php55": "~1.0"
+                "php": ">=5.5.9",
+                "symfony/polyfill-mbstring": "~1.1"
             },
             "require-dev": {
-                "symfony/expression-language": "~2.4|~3.0.0"
+                "symfony/expression-language": "~2.8|~3.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1615,48 +1585,48 @@
             ],
             "description": "Symfony HttpFoundation Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-04T12:20:59+00:00"
+            "time": "2017-05-01T14:55:58+00:00"
         },
         {
             "name": "symfony/http-kernel",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/http-kernel.git",
-                "reference": "18d7a01ac14ffa5a652a635c402b9777f858fc1a"
+                "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/18d7a01ac14ffa5a652a635c402b9777f858fc1a",
-                "reference": "18d7a01ac14ffa5a652a635c402b9777f858fc1a",
+                "url": "https://api.github.com/repos/symfony/http-kernel/zipball/46e8b209abab55c072c47d72d5cd1d62c0585e05",
+                "reference": "46e8b209abab55c072c47d72d5cd1d62c0585e05",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": ">=5.5.9",
                 "psr/log": "~1.0",
-                "symfony/debug": "^2.6.2",
-                "symfony/event-dispatcher": "^2.6.7|~3.0.0",
-                "symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6"
+                "symfony/debug": "~2.8|~3.0",
+                "symfony/event-dispatcher": "~2.8|~3.0",
+                "symfony/http-foundation": "~2.8.13|~3.1.6|~3.2"
             },
             "conflict": {
-                "symfony/config": "<2.7"
+                "symfony/config": "<2.8"
             },
             "require-dev": {
-                "symfony/browser-kit": "~2.3|~3.0.0",
-                "symfony/class-loader": "~2.1|~3.0.0",
-                "symfony/config": "~2.8",
-                "symfony/console": "~2.3|~3.0.0",
-                "symfony/css-selector": "^2.0.5|~3.0.0",
-                "symfony/dependency-injection": "~2.8|~3.0.0",
-                "symfony/dom-crawler": "^2.0.5|~3.0.0",
-                "symfony/expression-language": "~2.4|~3.0.0",
-                "symfony/finder": "^2.0.5|~3.0.0",
-                "symfony/process": "^2.0.5|~3.0.0",
-                "symfony/routing": "~2.8|~3.0.0",
-                "symfony/stopwatch": "~2.3|~3.0.0",
-                "symfony/templating": "~2.2|~3.0.0",
-                "symfony/translation": "^2.0.5|~3.0.0",
-                "symfony/var-dumper": "~2.6|~3.0.0"
+                "symfony/browser-kit": "~2.8|~3.0",
+                "symfony/class-loader": "~2.8|~3.0",
+                "symfony/config": "~2.8|~3.0",
+                "symfony/console": "~2.8|~3.0",
+                "symfony/css-selector": "~2.8|~3.0",
+                "symfony/dependency-injection": "~2.8|~3.0",
+                "symfony/dom-crawler": "~2.8|~3.0",
+                "symfony/expression-language": "~2.8|~3.0",
+                "symfony/finder": "~2.8|~3.0",
+                "symfony/process": "~2.8|~3.0",
+                "symfony/routing": "~2.8|~3.0",
+                "symfony/stopwatch": "~2.8|~3.0",
+                "symfony/templating": "~2.8|~3.0",
+                "symfony/translation": "~2.8|~3.0",
+                "symfony/var-dumper": "~3.2"
             },
             "suggest": {
                 "symfony/browser-kit": "",
@@ -1670,7 +1640,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -1697,60 +1667,7 @@
             ],
             "description": "Symfony HttpKernel Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-06T03:54:35+00:00"
-        },
-        {
-            "name": "symfony/polyfill-apcu",
-            "version": "v1.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-apcu.git",
-                "reference": "5d4474f447403c3348e37b70acc2b95475b7befa"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/5d4474f447403c3348e37b70acc2b95475b7befa",
-                "reference": "5d4474f447403c3348e37b70acc2b95475b7befa",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.3-dev"
-                }
-            },
-            "autoload": {
-                "files": [
-                    "bootstrap.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "apcu",
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2016-11-14T01:06:16+00:00"
+            "time": "2017-05-01T17:46:48+00:00"
         },
         {
             "name": "symfony/polyfill-iconv",
@@ -1871,140 +1788,26 @@
             "time": "2016-11-14T01:06:16+00:00"
         },
         {
-            "name": "symfony/polyfill-php54",
-            "version": "v1.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php54.git",
-                "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php54/zipball/90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
-                "reference": "90e085822963fdcc9d1c5b73deb3d2e5783b16a0",
-                "shasum": ""
-            },
-            "require": {
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.3-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Php54\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ],
-                "classmap": [
-                    "Resources/stubs"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2016-11-14T01:06:16+00:00"
-        },
-        {
-            "name": "symfony/polyfill-php55",
-            "version": "v1.3.0",
-            "source": {
-                "type": "git",
-                "url": "https://github.com/symfony/polyfill-php55.git",
-                "reference": "03e3f0350bca2220e3623a0e340eef194405fc67"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-php55/zipball/03e3f0350bca2220e3623a0e340eef194405fc67",
-                "reference": "03e3f0350bca2220e3623a0e340eef194405fc67",
-                "shasum": ""
-            },
-            "require": {
-                "ircmaxell/password-compat": "~1.0",
-                "php": ">=5.3.3"
-            },
-            "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-master": "1.3-dev"
-                }
-            },
-            "autoload": {
-                "psr-4": {
-                    "Symfony\\Polyfill\\Php55\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ]
-            },
-            "notification-url": "https://packagist.org/downloads/",
-            "license": [
-                "MIT"
-            ],
-            "authors": [
-                {
-                    "name": "Nicolas Grekas",
-                    "email": "p@tchwork.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "polyfill",
-                "portable",
-                "shim"
-            ],
-            "time": "2016-11-14T01:06:16+00:00"
-        },
-        {
             "name": "symfony/process",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/process.git",
-                "reference": "41336b20b52f5fd5b42a227e394e673c8071118f"
+                "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/process/zipball/41336b20b52f5fd5b42a227e394e673c8071118f",
-                "reference": "41336b20b52f5fd5b42a227e394e673c8071118f",
+                "url": "https://api.github.com/repos/symfony/process/zipball/999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
+                "reference": "999c2cf5061e627e6cd551dc9ebf90dd1d11d9f0",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2031,7 +1834,7 @@
             ],
             "description": "Symfony Process Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-04T12:20:59+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/psr-http-message-bridge",
@@ -2095,32 +1898,32 @@
         },
         {
             "name": "symfony/routing",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/routing.git",
-                "reference": "d145cd396f702c497cb24b21785ddac90a23fe71"
+                "reference": "5029745d6d463585e8b487dbc83d6333f408853a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/routing/zipball/d145cd396f702c497cb24b21785ddac90a23fe71",
-                "reference": "d145cd396f702c497cb24b21785ddac90a23fe71",
+                "url": "https://api.github.com/repos/symfony/routing/zipball/5029745d6d463585e8b487dbc83d6333f408853a",
+                "reference": "5029745d6d463585e8b487dbc83d6333f408853a",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
             },
             "conflict": {
-                "symfony/config": "<2.7"
+                "symfony/config": "<2.8"
             },
             "require-dev": {
                 "doctrine/annotations": "~1.0",
                 "doctrine/common": "~2.2",
                 "psr/log": "~1.0",
-                "symfony/config": "~2.7|~3.0.0",
-                "symfony/expression-language": "~2.4|~3.0.0",
-                "symfony/http-foundation": "~2.3|~3.0.0",
-                "symfony/yaml": "^2.0.5|~3.0.0"
+                "symfony/config": "~2.8|~3.0",
+                "symfony/expression-language": "~2.8|~3.0",
+                "symfony/http-foundation": "~2.8|~3.0",
+                "symfony/yaml": "~2.8|~3.0"
             },
             "suggest": {
                 "doctrine/annotations": "For using the annotation loader",
@@ -2133,7 +1936,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2166,44 +1969,55 @@
                 "uri",
                 "url"
             ],
-            "time": "2017-03-02T15:56:34+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/serializer",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/serializer.git",
-                "reference": "df3d919f00177f599c8970e86112c7582b08a582"
+                "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/serializer/zipball/df3d919f00177f599c8970e86112c7582b08a582",
-                "reference": "df3d919f00177f599c8970e86112c7582b08a582",
+                "url": "https://api.github.com/repos/symfony/serializer/zipball/6eeae1ba82005b761a53b7b8cf960bbf40c95986",
+                "reference": "6eeae1ba82005b761a53b7b8cf960bbf40c95986",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
-                "symfony/polyfill-php55": "~1.0"
+                "php": ">=5.5.9"
+            },
+            "conflict": {
+                "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4",
+                "symfony/property-info": "<3.1",
+                "symfony/yaml": "<3.1"
             },
             "require-dev": {
                 "doctrine/annotations": "~1.0",
                 "doctrine/cache": "~1.0",
-                "symfony/config": "~2.2|~3.0.0",
-                "symfony/property-access": "~2.3|~3.0.0",
-                "symfony/yaml": "^2.0.5|~3.0.0"
+                "phpdocumentor/reflection-docblock": "~3.0",
+                "symfony/cache": "~3.1",
+                "symfony/config": "~2.8|~3.0",
+                "symfony/http-foundation": "~2.8|~3.0",
+                "symfony/property-access": "~2.8|~3.0",
+                "symfony/property-info": "~3.1",
+                "symfony/yaml": "~3.1"
             },
             "suggest": {
                 "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
                 "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
+                "psr/cache-implementation": "For using the metadata cache.",
                 "symfony/config": "For using the XML mapping loader.",
+                "symfony/http-foundation": "To use the DataUriNormalizer.",
                 "symfony/property-access": "For using the ObjectNormalizer.",
+                "symfony/property-info": "To deserialize relations.",
                 "symfony/yaml": "For using the default YAML mapping loader."
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2230,34 +2044,34 @@
             ],
             "description": "Symfony Serializer Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-05T17:40:13+00:00"
+            "time": "2017-05-01T14:55:58+00:00"
         },
         {
             "name": "symfony/translation",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/translation.git",
-                "reference": "b538355bc99db2ec7cc35284ec76d92ae7d1d256"
+                "reference": "f4a04d2df710f81515df576b2de06bdeee518b83"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/translation/zipball/b538355bc99db2ec7cc35284ec76d92ae7d1d256",
-                "reference": "b538355bc99db2ec7cc35284ec76d92ae7d1d256",
+                "url": "https://api.github.com/repos/symfony/translation/zipball/f4a04d2df710f81515df576b2de06bdeee518b83",
+                "reference": "f4a04d2df710f81515df576b2de06bdeee518b83",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": ">=5.5.9",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "conflict": {
-                "symfony/config": "<2.7"
+                "symfony/config": "<2.8"
             },
             "require-dev": {
                 "psr/log": "~1.0",
-                "symfony/config": "~2.8",
-                "symfony/intl": "~2.7.25|^2.8.18|~3.2.5",
-                "symfony/yaml": "~2.2|~3.0.0"
+                "symfony/config": "~2.8|~3.0",
+                "symfony/intl": "^2.8.18|^3.2.5",
+                "symfony/yaml": "~2.8|~3.0"
             },
             "suggest": {
                 "psr/log": "To use logging capability in translator",
@@ -2267,7 +2081,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2294,53 +2108,57 @@
             ],
             "description": "Symfony Translation Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-04T12:20:59+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/validator",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/validator.git",
-                "reference": "8d4bfa7ec24e70ebc28d0cea5f2702d3f1257a63"
+                "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/validator/zipball/8d4bfa7ec24e70ebc28d0cea5f2702d3f1257a63",
-                "reference": "8d4bfa7ec24e70ebc28d0cea5f2702d3f1257a63",
+                "url": "https://api.github.com/repos/symfony/validator/zipball/98bf011bf1f3b69bece3b79e19633e9c51545b2b",
+                "reference": "98bf011bf1f3b69bece3b79e19633e9c51545b2b",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": ">=5.5.9",
                 "symfony/polyfill-mbstring": "~1.0",
-                "symfony/translation": "~2.4|~3.0.0"
+                "symfony/translation": "~2.8|~3.0"
+            },
+            "conflict": {
+                "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
             },
             "require-dev": {
                 "doctrine/annotations": "~1.0",
                 "doctrine/cache": "~1.0",
-                "egulias/email-validator": "^1.2.1",
-                "symfony/config": "~2.2|~3.0.0",
-                "symfony/expression-language": "~2.4|~3.0.0",
-                "symfony/http-foundation": "~2.3|~3.0.0",
-                "symfony/intl": "~2.7.25|^2.8.18|~3.2.5",
-                "symfony/property-access": "~2.3|~3.0.0",
-                "symfony/yaml": "^2.0.5|~3.0.0"
+                "egulias/email-validator": "^1.2.8|~2.0",
+                "symfony/cache": "~3.1",
+                "symfony/config": "~2.8|~3.0",
+                "symfony/expression-language": "~2.8|~3.0",
+                "symfony/http-foundation": "~2.8|~3.0",
+                "symfony/intl": "^2.8.18|^3.2.5",
+                "symfony/yaml": "~2.8|~3.0"
             },
             "suggest": {
                 "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.",
                 "doctrine/cache": "For using the default cached annotation reader and metadata cache.",
                 "egulias/email-validator": "Strict (RFC compliant) email validation",
+                "psr/cache-implementation": "For using the metadata cache.",
                 "symfony/config": "",
-                "symfony/expression-language": "For using the 2.4 Expression validator",
+                "symfony/expression-language": "For using the Expression validator",
                 "symfony/http-foundation": "",
                 "symfony/intl": "",
-                "symfony/property-access": "For using the 2.4 Validator API",
+                "symfony/property-access": "For using the Expression validator",
                 "symfony/yaml": ""
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2367,29 +2185,35 @@
             ],
             "description": "Symfony Validator Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-28T02:24:56+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/yaml",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/yaml.git",
-                "reference": "2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d"
+                "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/yaml/zipball/2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d",
-                "reference": "2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d",
+                "url": "https://api.github.com/repos/symfony/yaml/zipball/acec26fcf7f3031e094e910b94b002fa53d4e4d6",
+                "reference": "acec26fcf7f3031e094e910b94b002fa53d4e4d6",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
+            },
+            "require-dev": {
+                "symfony/console": "~2.8|~3.0"
+            },
+            "suggest": {
+                "symfony/console": "For validating YAML files using the lint command"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -2416,33 +2240,34 @@
             ],
             "description": "Symfony Yaml Component",
             "homepage": "https://symfony.com",
-            "time": "2017-03-01T18:13:50+00:00"
+            "time": "2017-05-01T14:55:58+00:00"
         },
         {
             "name": "twig/twig",
-            "version": "v1.25.0",
+            "version": "v1.32.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "f16a634ab08d87e520da5671ec52153d627f10f6"
+                "reference": "9935b662e24d6e634da88901ab534cc12e8c728f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/f16a634ab08d87e520da5671ec52153d627f10f6",
-                "reference": "f16a634ab08d87e520da5671ec52153d627f10f6",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/9935b662e24d6e634da88901ab534cc12e8c728f",
+                "reference": "9935b662e24d6e634da88901ab534cc12e8c728f",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.2.7"
             },
             "require-dev": {
+                "psr/container": "^1.0",
                 "symfony/debug": "~2.7",
-                "symfony/phpunit-bridge": "~2.7"
+                "symfony/phpunit-bridge": "~3.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.25-dev"
+                    "dev-master": "1.32-dev"
                 }
             },
             "autoload": {
@@ -2477,7 +2302,7 @@
             "keywords": [
                 "templating"
             ],
-            "time": "2016-09-21T23:05:12+00:00"
+            "time": "2017-02-27T00:07:03+00:00"
         },
         {
             "name": "wikimedia/composer-merge-plugin",
@@ -2530,16 +2355,16 @@
         },
         {
             "name": "zendframework/zend-diactoros",
-            "version": "1.3.10",
+            "version": "1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-diactoros.git",
-                "reference": "83e8d98b9915de76c659ce27d683c02a0f99fa90"
+                "reference": "b03f285a333f51e58c95cce54109a4a9ed691436"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/83e8d98b9915de76c659ce27d683c02a0f99fa90",
-                "reference": "83e8d98b9915de76c659ce27d683c02a0f99fa90",
+                "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/b03f285a333f51e58c95cce54109a4a9ed691436",
+                "reference": "b03f285a333f51e58c95cce54109a4a9ed691436",
                 "shasum": ""
             },
             "require": {
@@ -2547,17 +2372,19 @@
                 "psr/http-message": "~1.0"
             },
             "provide": {
-                "psr/http-message-implementation": "~1.0.0"
+                "psr/http-message-implementation": "1.0"
             },
             "require-dev": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
                 "phpunit/phpunit": "^4.6 || ^5.5",
                 "zendframework/zend-coding-standard": "~1.0.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3-dev",
-                    "dev-develop": "1.4-dev"
+                    "dev-master": "1.4-dev",
+                    "dev-develop": "1.5-dev"
                 }
             },
             "autoload": {
@@ -2576,7 +2403,7 @@
                 "psr",
                 "psr-7"
             ],
-            "time": "2017-01-23T04:53:24+00:00"
+            "time": "2017-04-06T16:18:34+00:00"
         },
         {
             "name": "zendframework/zend-escaper",
@@ -3040,6 +2867,48 @@
             "time": "2017-01-03T13:21:43+00:00"
         },
         {
+            "name": "ircmaxell/password-compat",
+            "version": "v1.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/ircmaxell/password_compat.git",
+                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/ircmaxell/password_compat/zipball/5c5cde8822a69545767f7c7f3058cb15ff84614c",
+                "reference": "5c5cde8822a69545767f7c7f3058cb15ff84614c",
+                "shasum": ""
+            },
+            "require-dev": {
+                "phpunit/phpunit": "4.*"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "lib/password.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Anthony Ferrara",
+                    "email": "ircmaxell@php.net",
+                    "homepage": "http://blog.ircmaxell.com"
+                }
+            ],
+            "description": "A compatibility library for the proposed simplified password hashing algorithm: https://wiki.php.net/rfc/password_hash",
+            "homepage": "https://github.com/ircmaxell/password_compat",
+            "keywords": [
+                "hashing",
+                "password"
+            ],
+            "time": "2014-11-20T16:49:30+00:00"
+        },
+        {
             "name": "jcalderonzumba/gastonjs",
             "version": "v1.0.2",
             "source": {
@@ -4143,25 +4012,25 @@
         },
         {
             "name": "symfony/browser-kit",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/browser-kit.git",
-                "reference": "8827db04bcd8d9b9bf3114ea41081d8036ab209c"
+                "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/8827db04bcd8d9b9bf3114ea41081d8036ab209c",
-                "reference": "8827db04bcd8d9b9bf3114ea41081d8036ab209c",
+                "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9fab1ab6f77b77f3df5fc5250fc6956811699b57",
+                "reference": "9fab1ab6f77b77f3df5fc5250fc6956811699b57",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
-                "symfony/dom-crawler": "~2.1|~3.0.0"
+                "php": ">=5.5.9",
+                "symfony/dom-crawler": "~2.8|~3.0"
             },
             "require-dev": {
-                "symfony/css-selector": "^2.0.5|~3.0.0",
-                "symfony/process": "~2.3.34|^2.7.6|~3.0.0"
+                "symfony/css-selector": "~2.8|~3.0",
+                "symfony/process": "~2.8|~3.0"
             },
             "suggest": {
                 "symfony/process": ""
@@ -4169,7 +4038,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -4196,29 +4065,29 @@
             ],
             "description": "Symfony BrowserKit Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-21T08:33:48+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
         },
         {
             "name": "symfony/css-selector",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/css-selector.git",
-                "reference": "742bd688bd778dde8991ba696cb372570610afcd"
+                "reference": "02983c144038e697c959e6b06ef6666de759ccbc"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/css-selector/zipball/742bd688bd778dde8991ba696cb372570610afcd",
-                "reference": "742bd688bd778dde8991ba696cb372570610afcd",
+                "url": "https://api.github.com/repos/symfony/css-selector/zipball/02983c144038e697c959e6b06ef6666de759ccbc",
+                "reference": "02983c144038e697c959e6b06ef6666de759ccbc",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9"
+                "php": ">=5.5.9"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -4249,28 +4118,28 @@
             ],
             "description": "Symfony CssSelector Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-21T08:33:48+00:00"
+            "time": "2017-05-01T14:55:58+00:00"
         },
         {
             "name": "symfony/dom-crawler",
-            "version": "v2.8.18",
+            "version": "v3.2.8",
             "source": {
                 "type": "git",
                 "url": "https://github.com/symfony/dom-crawler.git",
-                "reference": "24b1a3ffa5b64e4f8b1c5f2cdffd16368640704a"
+                "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/24b1a3ffa5b64e4f8b1c5f2cdffd16368640704a",
-                "reference": "24b1a3ffa5b64e4f8b1c5f2cdffd16368640704a",
+                "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/f1ad34e8af09ed17570e027cf0c58a12eddec286",
+                "reference": "f1ad34e8af09ed17570e027cf0c58a12eddec286",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.9",
+                "php": ">=5.5.9",
                 "symfony/polyfill-mbstring": "~1.0"
             },
             "require-dev": {
-                "symfony/css-selector": "~2.8|~3.0.0"
+                "symfony/css-selector": "~2.8|~3.0"
             },
             "suggest": {
                 "symfony/css-selector": ""
@@ -4278,7 +4147,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.8-dev"
+                    "dev-master": "3.2-dev"
                 }
             },
             "autoload": {
@@ -4305,7 +4174,69 @@
             ],
             "description": "Symfony DomCrawler Component",
             "homepage": "https://symfony.com",
-            "time": "2017-02-21T08:33:48+00:00"
+            "time": "2017-04-12T14:13:17+00:00"
+        },
+        {
+            "name": "symfony/phpunit-bridge",
+            "version": "v3.2.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/phpunit-bridge.git",
+                "reference": "00916603c524b8048906de460b7ea0dfa1651281"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/00916603c524b8048906de460b7ea0dfa1651281",
+                "reference": "00916603c524b8048906de460b7ea0dfa1651281",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.3"
+            },
+            "conflict": {
+                "phpunit/phpunit": ">=6.0"
+            },
+            "suggest": {
+                "ext-zip": "Zip support is required when using bin/simple-phpunit",
+                "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
+            },
+            "bin": [
+                "bin/simple-phpunit"
+            ],
+            "type": "symfony-bridge",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.2-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Bridge\\PhpUnit\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony PHPUnit Bridge",
+            "homepage": "https://symfony.com",
+            "time": "2017-04-12T14:13:17+00:00"
         }
     ],
     "aliases": [],
diff --git a/core/.eslintignore b/core/.eslintignore
index a15282a9a4..ac3272e162 100644
--- a/core/.eslintignore
+++ b/core/.eslintignore
@@ -2,3 +2,5 @@ assets/vendor/**/*
 modules/locale/tests/locale_test.js
 node_modules/**/*
 **/js_test_files/**/*
+*.js
+!*.es6.js
diff --git a/core/.eslintrc.json b/core/.eslintrc.json
index 218d84f937..369539d27f 100644
--- a/core/.eslintrc.json
+++ b/core/.eslintrc.json
@@ -1,5 +1,6 @@
 {
-  "extends": "eslint:recommended",
+  "extends": "eslint-config-airbnb",
+  "root": true,
   "env": {
     "browser": true,
     "es6": true,
@@ -18,80 +19,23 @@
     "CKEDITOR": true
   },
   "rules": {
-    // Errors.
-    "array-bracket-spacing": [2, "never"],
-    "block-scoped-var": 2,
-    "brace-style": [2, "stroustrup", {"allowSingleLine": true}],
-    "comma-dangle": [2, "never"],
-    "comma-spacing": 2,
-    "comma-style": [2, "last"],
-    "computed-property-spacing": [2, "never"],
-    "curly": [2, "all"],
-    "eol-last": 2,
-    "eqeqeq": [2, "smart"],
-    "guard-for-in": 2,
-    "indent": [2, 2, {"SwitchCase": 1}],
-    "key-spacing": [2, {"beforeColon": false, "afterColon": true}],
-    "keyword-spacing": [2, {"before": true, "after": true}],
-    "linebreak-style": [2, "unix"],
-    "lines-around-comment": [2, {"beforeBlockComment": true, "afterBlockComment": false}],
-    "new-parens": 2,
-    "no-array-constructor": 2,
-    "no-caller": 2,
-    "no-catch-shadow": 2,
-    "no-eval": 2,
-    "no-extend-native": 2,
-    "no-extra-bind": 2,
-    "no-extra-parens": [2, "functions"],
-    "no-implied-eval": 2,
-    "no-iterator": 2,
-    "no-label-var": 2,
-    "no-labels": 2,
-    "no-lone-blocks": 2,
-    "no-loop-func": 2,
-    "no-multi-spaces": 2,
-    "no-multi-str": 2,
-    "no-native-reassign": 2,
-    "no-nested-ternary": 2,
-    "no-new-func": 2,
-    "no-new-object": 2,
-    "no-new-wrappers": 2,
-    "no-octal-escape": 2,
-    "no-process-exit": 2,
-    "no-proto": 2,
-    "no-return-assign": 2,
-    "no-script-url": 2,
-    "no-sequences": 2,
-    "no-shadow-restricted-names": 2,
-    "no-spaced-func": 2,
-    "no-trailing-spaces": 2,
-    "no-undef-init": 2,
-    "no-undefined": 2,
-    "no-unused-expressions": 2,
-    "no-unused-vars": [2, {"vars": "all", "args": "none"}],
-    "no-with": 2,
-    "object-curly-spacing": [2, "never"],
-    "one-var": [2, "never"],
-    "quote-props": [2, "consistent-as-needed"],
-    "quotes": [2, "single", "avoid-escape"],
-    "semi": [2, "always"],
-    "semi-spacing": [2, {"before": false, "after": true}],
-    "space-before-blocks": [2, "always"],
-    "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
-    "space-in-parens": [2, "never"],
-    "space-infix-ops": 2,
-    "space-unary-ops": [2, { "words": true, "nonwords": false }],
-    "spaced-comment": [2, "always"],
-    "strict": [2, "function"],
-    "yoda": [2, "never"],
-    // Warnings.
+    "consistent-return": [0],
+    "no-underscore-dangle": [0],
     "max-nested-callbacks": [1, 3],
+    "no-mutable-exports": [1],
+    "no-plusplus": [1, {
+      "allowForLoopAfterthoughts": true
+    }],
+    "no-param-reassign": [0],
+    "no-prototype-builtins": [0],
     "valid-jsdoc": [1, {
       "prefer": {
         "returns": "return",
         "property": "prop"
       },
       "requireReturn": false
-    }]
+    }],
+    "brace-style": ["error", "stroustrup"],
+    "no-unused-vars": [1]
   }
 }
diff --git a/core/.eslintrc.legacy.json b/core/.eslintrc.legacy.json
new file mode 100644
index 0000000000..9051bbfa5b
--- /dev/null
+++ b/core/.eslintrc.legacy.json
@@ -0,0 +1,94 @@
+{
+  "extends": "eslint:recommended",
+  "root": true,
+  "env": {
+    "browser": true
+  },
+  "globals": {
+    "Drupal": true,
+    "drupalSettings": true,
+    "drupalTranslations": true,
+    "domready": true,
+    "jQuery": true,
+    "_": true,
+    "matchMedia": true,
+    "Backbone": true,
+    "Modernizr": true,
+    "CKEDITOR": true
+  },
+  "rules": {
+    "array-bracket-spacing": [2, "never"],
+    "block-scoped-var": 2,
+    "brace-style": [2, "stroustrup", {"allowSingleLine": true}],
+    "comma-dangle": [2, "never"],
+    "comma-spacing": 2,
+    "comma-style": [2, "last"],
+    "computed-property-spacing": [2, "never"],
+    "curly": [2, "all"],
+    "eol-last": 2,
+    "eqeqeq": [2, "smart"],
+    "guard-for-in": 2,
+    "indent": [2, 2, {"SwitchCase": 1}],
+    "key-spacing": [2, {"beforeColon": false, "afterColon": true}],
+    "keyword-spacing": [2, {"before": true, "after": true}],
+    "linebreak-style": [2, "unix"],
+    "lines-around-comment": [2, {"beforeBlockComment": true, "afterBlockComment": false}],
+    "new-parens": 2,
+    "no-array-constructor": 2,
+    "no-caller": 2,
+    "no-catch-shadow": 2,
+    "no-eval": 2,
+    "no-extend-native": 2,
+    "no-extra-bind": 2,
+    "no-extra-parens": [2, "functions"],
+    "no-implied-eval": 2,
+    "no-iterator": 2,
+    "no-label-var": 2,
+    "no-labels": 2,
+    "no-lone-blocks": 2,
+    "no-loop-func": 2,
+    "no-multi-spaces": 2,
+    "no-multi-str": 2,
+    "no-native-reassign": 2,
+    "no-nested-ternary": 2,
+    "no-new-func": 2,
+    "no-new-object": 2,
+    "no-new-wrappers": 2,
+    "no-octal-escape": 2,
+    "no-process-exit": 2,
+    "no-proto": 2,
+    "no-return-assign": 2,
+    "no-script-url": 2,
+    "no-sequences": 2,
+    "no-shadow-restricted-names": 2,
+    "no-spaced-func": 2,
+    "no-trailing-spaces": 2,
+    "no-undef-init": 2,
+    "no-undefined": 2,
+    "no-unused-expressions": 2,
+    "no-unused-vars": [2, {"vars": "all", "args": "none"}],
+    "no-with": 2,
+    "object-curly-spacing": [2, "never"],
+    "one-var": [2, "never"],
+    "quote-props": [2, "consistent-as-needed"],
+    "quotes": [2, "single", "avoid-escape"],
+    "semi": [2, "always"],
+    "semi-spacing": [2, {"before": false, "after": true}],
+    "space-before-blocks": [2, "always"],
+    "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
+    "space-in-parens": [2, "never"],
+    "space-infix-ops": 2,
+    "space-unary-ops": [2, { "words": true, "nonwords": false }],
+    "spaced-comment": [2, "always"],
+    "strict": [2, "function"],
+    "yoda": [2, "never"],
+    "max-nested-callbacks": [1, 3],
+    "valid-jsdoc": [1, {
+      "prefer": {
+        "returns": "return",
+        "property": "prop"
+      },
+      "requireReturn": false
+    }]
+  }
+}
diff --git a/core/.gitignore b/core/.gitignore
new file mode 100644
index 0000000000..0ee3d5607c
--- /dev/null
+++ b/core/.gitignore
@@ -0,0 +1,7 @@
+# Ignore node_modules folder created when installing core's JavaScript
+# dependencies.
+node_modules
+
+# Ignore overrides of core's phpcs.xml.dist and phpunit.xml.dist.
+phpcs.xml
+phpunit.xml
diff --git a/core/CHANGELOG.txt b/core/CHANGELOG.txt
index 0436c10b09..10e824f9e3 100644
--- a/core/CHANGELOG.txt
+++ b/core/CHANGELOG.txt
@@ -1,7 +1,3 @@
-Drupal 8.3.1, 2017-04-19
-------------------------
-- Fixed security issues. See SA-CORE-2017-002.
-
 Drupal 8.3.0, 2017-04-05
 ------------------------
 - Added modules:
diff --git a/core/composer.json b/core/composer.json
index a7a6c6a43a..1f25c46635 100644
--- a/core/composer.json
+++ b/core/composer.json
@@ -5,19 +5,19 @@
     "license": "GPL-2.0+",
     "require": {
         "php": ">=5.5.9",
-        "symfony/class-loader": "~2.8",
-        "symfony/console": "~2.8",
-        "symfony/dependency-injection": "~2.8",
-        "symfony/event-dispatcher": "~2.8",
-        "symfony/http-foundation": "~2.8",
-        "symfony/http-kernel": "~2.8",
-        "symfony/routing": "~2.8",
-        "symfony/serializer": "~2.8",
-        "symfony/translation": "~2.8",
-        "symfony/validator": "~2.8",
-        "symfony/process": "~2.8",
+        "symfony/class-loader": "~3.2",
+        "symfony/console": "~3.2",
+        "symfony/dependency-injection": "~3.2",
+        "symfony/event-dispatcher": "~3.2",
+        "symfony/http-foundation": "~3.2",
+        "symfony/http-kernel": "~3.2",
+        "symfony/routing": "~3.2",
+        "symfony/serializer": "~3.2",
+        "symfony/translation": "~3.2",
+        "symfony/validator": "~3.2",
+        "symfony/process": "~3.2",
         "symfony/polyfill-iconv": "~1.0",
-        "symfony/yaml": "~2.8",
+        "symfony/yaml": "~3.2",
         "twig/twig": "^1.23.1",
         "doctrine/common": "^2.5",
         "doctrine/annotations": "1.2.*",
@@ -32,7 +32,7 @@
         "zendframework/zend-diactoros": "~1.1",
         "composer/semver": "~1.0",
         "paragonie/random_compat": "^1.0|^2.0",
-        "asm89/stack-cors": "~1.0"
+        "asm89/stack-cors": "~1.1"
     },
     "conflict": {
         "drush/drush": "<8.1.10"
@@ -44,9 +44,9 @@
         "jcalderonzumba/gastonjs": "~1.0.2",
         "jcalderonzumba/mink-phantomjs-driver": "~0.3.1",
         "mikey179/vfsStream": "~1.2",
-        "phpunit/phpunit": ">=4.8.28 <5",
-        "symfony/browser-kit": ">=2.8.13 <3.0",
-        "symfony/css-selector": "~2.8"
+        "phpunit/phpunit": ">=4.8.35 <5",
+        "symfony/css-selector": "~3.2",
+        "symfony/phpunit-bridge": "^3.2"
     },
     "replace": {
         "drupal/action": "self.version",
diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml
index eeac1aea06..92782406ca 100644
--- a/core/config/schema/core.data_types.schema.yml
+++ b/core/config/schema/core.data_types.schema.yml
@@ -46,7 +46,7 @@ mapping:
 sequence:
   label: Sequence
   class: '\Drupal\Core\Config\Schema\Sequence'
-  definition_class: '\Drupal\Core\TypedData\ListDataDefinition'
+  definition_class: '\Drupal\Core\Config\Schema\SequenceDataDefinition'
 
 # Simple extended data types:
 
@@ -72,6 +72,13 @@ text:
   label: 'Text'
   translatable: true
 
+# A UUID.
+uuid:
+  type: string
+  label: 'UUID'
+  constraints:
+    Uuid: {}
+
 # PHP Date format string that is translatable.
 date_format:
   type: string
@@ -275,7 +282,7 @@ config_entity:
   type: mapping
   mapping:
     uuid:
-      type: string
+      type: uuid
       label: 'UUID'
     langcode:
       type: string
@@ -336,8 +343,7 @@ condition.plugin:
       type: boolean
       label: 'Negate'
     uuid:
-      type: string
-      label: 'UUID'
+      type: uuid
     context_mapping:
       type: sequence
       label: 'Context assignments'
@@ -358,8 +364,7 @@ display_variant.plugin:
       type: integer
       label: 'Weight'
     uuid:
-      type: string
-      label: 'UUID'
+      type: uuid
 
 layout_plugin.settings:
   type: mapping
@@ -602,8 +607,7 @@ field.value.entity_reference:
       type: string
       label: 'Value'
     target_uuid:
-      type: string
-      label: 'Target UUID'
+      type: uuid
 
 # Schema for the configuration of the Boolean field type.
 
diff --git a/core/core.link_relation_types.yml b/core/core.link_relation_types.yml
index 88fea0e31c..fb340274d5 100644
--- a/core/core.link_relation_types.yml
+++ b/core/core.link_relation_types.yml
@@ -79,6 +79,9 @@ create-form:
 current:
   description: "Refers to a resource containing the most recent item(s) in a collection of resources."
   reference: '[RFC5005]'
+customize-form:
+  description: "The target URI points to a resource where a submission form for customizing associated resource can be obtained."
+  reference: '[RFC6861]'
 derivedfrom:
   description: 'The target IRI points to a resource from which this material was derived.'
   reference: '[draft-hoffman-xml2rfc]'
diff --git a/core/core.services.yml b/core/core.services.yml
index 2527845c75..fc0d99f6cd 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -331,9 +331,11 @@ services:
     arguments: ['@config.storage', 'config/schema', '', true, '%install_profile%']
   config.typed:
     class: Drupal\Core\Config\TypedConfigManager
-    arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler']
+    arguments: ['@config.storage', '@config.storage.schema', '@cache.discovery', '@module_handler', '@class_resolver']
     tags:
       - { name: plugin_manager_cache_clear }
+    calls:
+      - [setValidationConstraintManager, ['@validation.constraint']]
   context.handler:
     class: Drupal\Core\Plugin\Context\ContextHandler
     arguments: ['@typed_data_manager']
@@ -1042,8 +1044,8 @@ services:
     arguments: ['@class_resolver', '@current_route_match', '%main_content_renderers%']
     tags:
       - { name: event_subscriber }
-  accept_negotiation_406:
-    class: Drupal\Core\EventSubscriber\AcceptNegotiation406
+  renderer_non_html:
+    class: Drupal\Core\EventSubscriber\RenderArrayNonHtmlSubscriber
     tags:
       - { name: event_subscriber }
   main_content_renderer.html:
@@ -1143,7 +1145,7 @@ services:
     class: Drupal\Core\Access\CsrfRequestHeaderAccessCheck
     arguments: ['@session_configuration', '@csrf_token']
     tags:
-      - { name: access_check }
+      - { name: access_check, needs_incoming_request: TRUE }
   maintenance_mode:
     class: Drupal\Core\Site\MaintenanceMode
     arguments: ['@state', '@current_user']
@@ -1230,8 +1232,8 @@ services:
     tags:
       - { name: event_subscriber }
     arguments: ['@http_kernel', '@logger.channel.php', '@redirect.destination', '@router.no_access_checks']
-  exception.default:
-    class: Drupal\Core\EventSubscriber\DefaultExceptionSubscriber
+  exception.final:
+    class: Drupal\Core\EventSubscriber\FinalExceptionSubscriber
     tags:
       - { name: event_subscriber }
     arguments: ['@config.factory']
diff --git a/core/includes/schema.inc b/core/includes/schema.inc
index a2f9d23dc4..443cbf1934 100644
--- a/core/includes/schema.inc
+++ b/core/includes/schema.inc
@@ -119,7 +119,7 @@ function drupal_install_schema($module) {
   _drupal_schema_initialize($schema, $module, FALSE);
 
   foreach ($schema as $name => $table) {
-    db_create_table($name, $table);
+    \Drupal::database()->schema()->createTable($name, $table);
   }
 }
 
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 498c490beb..4cc6424f3e 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -240,8 +240,7 @@ function drupal_find_theme_templates($cache, $extension, $path) {
     // Match templates based on the 'template' filename.
     foreach ($cache as $hook => $info) {
       if (isset($info['template'])) {
-        $template_candidates = [$info['template'], str_replace($info['theme path'] . '/templates/', '', $info['template'])];
-        if (in_array($template, $template_candidates)) {
+        if ($template === $info['template']) {
           $implementations[$hook] = [
             'template' => $template,
             'path' => dirname($file->uri),
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 46f05471ec..1acfc12e9a 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -81,7 +81,7 @@ class Drupal {
   /**
    * The current system version.
    */
-  const VERSION = '8.3.3-dev';
+  const VERSION = '8.4.0-dev';
 
   /**
    * Core API compatibility.
diff --git a/core/lib/Drupal/Component/DependencyInjection/Container.php b/core/lib/Drupal/Component/DependencyInjection/Container.php
index 6737369545..45cc8b93ed 100644
--- a/core/lib/Drupal/Component/DependencyInjection/Container.php
+++ b/core/lib/Drupal/Component/DependencyInjection/Container.php
@@ -3,9 +3,7 @@
 namespace Drupal\Component\DependencyInjection;
 
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
 use Symfony\Component\DependencyInjection\ResettableContainerInterface;
-use Symfony\Component\DependencyInjection\ScopeInterface;
 use Symfony\Component\DependencyInjection\Exception\LogicException;
 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@@ -43,14 +41,10 @@
  *   getAServiceWithAnIdByCamelCase().
  * - The function getServiceIds() was added as it has a use-case in core and
  *   contrib.
- * - Scopes are explicitly not allowed, because Symfony 2.8 has deprecated
- *   them and they will be removed in Symfony 3.0.
- * - Synchronized services are explicitly not supported, because Symfony 2.8 has
- *   deprecated them and they will be removed in Symfony 3.0.
  *
  * @ingroup container
  */
-class Container implements IntrospectableContainerInterface, ResettableContainerInterface {
+class Container implements ContainerInterface, ResettableContainerInterface {
 
   /**
    * The parameters of the container.
@@ -311,12 +305,8 @@ protected function createService(array $definition, $id) {
       }
     }
 
-    // Share the service if it is public.
-    if (!isset($definition['public']) || $definition['public'] !== FALSE) {
-      // Forward compatibility fix for Symfony 2.8 update.
-      if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
-        $this->services[$id] = $service;
-      }
+    if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
+      $this->services[$id] = $service;
     }
 
     if (isset($definition['calls'])) {
@@ -361,11 +351,7 @@ protected function createService(array $definition, $id) {
   /**
    * {@inheritdoc}
    */
-  public function set($id, $service, $scope = ContainerInterface::SCOPE_CONTAINER) {
-    if (!in_array($scope, ['container', 'request']) || ('request' === $scope && 'request' !== $id)) {
-      @trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
-    }
-
+  public function set($id, $service) {
     $this->services[$id] = $service;
   }
 
@@ -587,61 +573,6 @@ protected function getParameterAlternatives($name) {
     return $this->getAlternatives($name, array_keys($this->parameters));
   }
 
-
-  /**
-   * {@inheritdoc}
-   */
-  public function enterScope($name) {
-    if ('request' !== $name) {
-      @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
-    }
-
-    throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function leaveScope($name) {
-    if ('request' !== $name) {
-      @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
-    }
-
-    throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addScope(ScopeInterface $scope) {
-
-    $name = $scope->getName();
-    if ('request' !== $name) {
-      @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
-    }
-    throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasScope($name) {
-    if ('request' !== $name) {
-      @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
-    }
-
-    throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isScopeActive($name) {
-    @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
-
-    throw new \BadMethodCallException(sprintf("'%s' is not supported by Drupal 8.", __FUNCTION__));
-  }
-
   /**
    * Gets all defined service IDs.
    *
diff --git a/core/lib/Drupal/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumper.php b/core/lib/Drupal/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumper.php
index 7673cef8ba..11768d0c20 100644
--- a/core/lib/Drupal/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumper.php
+++ b/core/lib/Drupal/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumper.php
@@ -237,18 +237,6 @@ protected function getServiceDefinition(Definition $definition) {
       $service['calls'] = $this->dumpMethodCalls($definition->getMethodCalls());
     }
 
-    if (($scope = $definition->getScope()) !== ContainerInterface::SCOPE_CONTAINER) {
-      if ($scope === ContainerInterface::SCOPE_PROTOTYPE) {
-        // Scope prototype has been replaced with 'shared' => FALSE.
-        // This is a Symfony 2.8 forward compatibility fix.
-        // Reference: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#dependencyinjection
-        $service['shared'] = FALSE;
-      }
-      else {
-        throw new InvalidArgumentException("The 'scope' definition is deprecated in Symfony 3.0 and not supported by Drupal 8.");
-      }
-    }
-
     // By default services are shared, so just provide the flag, when needed.
     if ($definition->isShared() === FALSE) {
       $service['shared'] = $definition->isShared();
diff --git a/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
index 83d558cbd3..5d615dbd05 100644
--- a/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
+++ b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
@@ -136,12 +136,8 @@ protected function createService(array $definition, $id) {
       }
     }
 
-    // Share the service if it is public.
-    if (!isset($definition['public']) || $definition['public'] !== FALSE) {
-      // Forward compatibility fix for Symfony 2.8 update.
-      if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
-        $this->services[$id] = $service;
-      }
+    if (!isset($definition['shared']) || $definition['shared'] !== FALSE) {
+      $this->services[$id] = $service;
     }
 
     if (isset($definition['calls'])) {
diff --git a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
index 6c1e200825..a23f333a0a 100644
--- a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
+++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\Component\EventDispatcher;
 
-use Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -36,7 +36,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
   /**
    * The service container.
    *
-   * @var \Symfony\Component\DependencyInjection\IntrospectableContainerInterface;
+   * @var \Symfony\Component\DependencyInjection\ContainerInterface;
    */
   protected $container;
 
@@ -66,7 +66,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
   /**
    * Constructs a container aware event dispatcher.
    *
-   * @param \Symfony\Component\DependencyInjection\IntrospectableContainerInterface $container
+   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
    *   The service container.
    * @param array $listeners
    *   A nested array of listener definitions keyed by event name and priority.
@@ -77,7 +77,7 @@ class ContainerAwareEventDispatcher implements EventDispatcherInterface {
    *   A service entry will be resolved to a callable only just before its
    *   invocation.
    */
-  public function __construct(IntrospectableContainerInterface $container, array $listeners = []) {
+  public function __construct(ContainerInterface $container, array $listeners = []) {
     $this->container = $container;
     $this->listeners = $listeners;
     $this->unsorted = [];
@@ -91,9 +91,6 @@ public function dispatch($event_name, Event $event = NULL) {
       $event = new Event();
     }
 
-    $event->setDispatcher($this);
-    $event->setName($event_name);
-
     if (isset($this->listeners[$event_name])) {
       // Sort listeners if necessary.
       if (isset($this->unsorted[$event_name])) {
diff --git a/core/lib/Drupal/Component/Serialization/YamlPecl.php b/core/lib/Drupal/Component/Serialization/YamlPecl.php
index 2383bf849a..ec48a29ca6 100644
--- a/core/lib/Drupal/Component/Serialization/YamlPecl.php
+++ b/core/lib/Drupal/Component/Serialization/YamlPecl.php
@@ -27,6 +27,13 @@ public static function encode($data) {
    * {@inheritdoc}
    */
   public static function decode($raw) {
+    static $init;
+    if (!isset($init)) {
+      // Decode binary, since Symfony YAML parser encodes binary from 3.1
+      // onwards.
+      ini_set('yaml.decode_binary', 1);
+      $init = TRUE;
+    }
     // yaml_parse() will error with an empty value.
     if (!trim($raw)) {
       return NULL;
diff --git a/core/lib/Drupal/Component/Serialization/YamlSymfony.php b/core/lib/Drupal/Component/Serialization/YamlSymfony.php
index 8818e52534..d35e09cd48 100644
--- a/core/lib/Drupal/Component/Serialization/YamlSymfony.php
+++ b/core/lib/Drupal/Component/Serialization/YamlSymfony.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Serialization\Exception\InvalidDataTypeException;
 use Symfony\Component\Yaml\Parser;
 use Symfony\Component\Yaml\Dumper;
+use Symfony\Component\Yaml\Yaml as SymfonyYaml;
 
 /**
  * Default serialization for YAML using the Symfony component.
@@ -16,9 +17,9 @@ class YamlSymfony implements SerializationInterface {
    */
   public static function encode($data) {
     try {
-      $yaml = new Dumper();
-      $yaml->setIndentation(2);
-      return $yaml->dump($data, PHP_INT_MAX, 0, TRUE, FALSE);
+      // Set the indentation to 2 to match Drupal's coding standards.
+      $yaml = new Dumper(2);
+      return $yaml->dump($data, PHP_INT_MAX, 0, SymfonyYaml::DUMP_EXCEPTION_ON_INVALID_TYPE);
     }
     catch (\Exception $e) {
       throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
@@ -33,7 +34,7 @@ public static function decode($raw) {
       $yaml = new Parser();
       // Make sure we have a single trailing newline. A very simple config like
       // 'foo: bar' with no newline will fail to parse otherwise.
-      return $yaml->parse($raw, TRUE, FALSE);
+      return $yaml->parse($raw, SymfonyYaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
     }
     catch (\Exception $e) {
       throw new InvalidDataTypeException($e->getMessage(), $e->getCode(), $e);
diff --git a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php
index cde7d5699c..3d372fe646 100644
--- a/core/lib/Drupal/Core/Action/ConfigurableActionBase.php
+++ b/core/lib/Drupal/Core/Action/ConfigurableActionBase.php
@@ -17,7 +17,7 @@
   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
-    $this->configuration += $this->defaultConfiguration();
+    $this->setConfiguration($configuration);
   }
 
   /**
@@ -38,7 +38,7 @@ public function getConfiguration() {
    * {@inheritdoc}
    */
   public function setConfiguration(array $configuration) {
-    $this->configuration = $configuration;
+    $this->configuration = $configuration + $this->defaultConfiguration();
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
index c507655447..b38a94b3c2 100644
--- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
+++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php
@@ -2,10 +2,12 @@
 
 namespace Drupal\Core\Config\Schema;
 
+use Drupal\Core\TypedData\ComplexDataInterface;
+
 /**
  * Defines a generic configuration element that contains multiple properties.
  */
-abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface {
+abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface, ComplexDataInterface {
 
   /**
    * Parsed elements.
@@ -161,4 +163,25 @@ public function isNullable() {
     return isset($this->definition['nullable']) && $this->definition['nullable'] == TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function set($property_name, $value, $notify = TRUE) {
+    $this->value[$property_name] = $value;
+    // Config schema elements do not make use of notifications. Thus, we skip
+    // notifying parents.
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getProperties($include_computed = FALSE) {
+    $properties = [];
+    foreach (array_keys($this->value) as $name) {
+      $properties[$name] = $this->get($name);
+    }
+    return $properties;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
index 9230281f55..80045d0303 100644
--- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
+++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php
@@ -55,9 +55,7 @@ public function checkConfigSchema(TypedConfigManagerInterface $typed_config, $co
     if (!$typed_config->hasConfigSchema($config_name)) {
       return FALSE;
     }
-    $definition = $typed_config->getDefinition($config_name);
-    $data_definition = $typed_config->buildDataDefinition($definition, $config_data);
-    $this->schema = $typed_config->create($data_definition, $config_data);
+    $this->schema = $typed_config->createFromNameAndData($config_name, $config_data);
     $errors = [];
     foreach ($config_data as $key => $value) {
       $errors = array_merge($errors, $this->checkValue($key, $value));
diff --git a/core/lib/Drupal/Core/Config/Schema/Sequence.php b/core/lib/Drupal/Core/Config/Schema/Sequence.php
index ce8dc1bc0b..547969bbcc 100644
--- a/core/lib/Drupal/Core/Config/Schema/Sequence.php
+++ b/core/lib/Drupal/Core/Config/Schema/Sequence.php
@@ -10,6 +10,12 @@
  *
  * Read https://www.drupal.org/node/1905070 for more details about configuration
  * schema, types and type resolution.
+ *
+ * Note that sequences implement the typed data ComplexDataInterface (via the
+ * parent ArrayElement) rather than the ListInterface. This is because sequences
+ * may have named keys, which is not supported by ListInterface. From the typed
+ * data API perspective sequences are handled as ordered mappings without
+ * metadata about existing properties.
  */
 class Sequence extends ArrayElement {
 
diff --git a/core/lib/Drupal/Core/Config/Schema/SequenceDataDefinition.php b/core/lib/Drupal/Core/Config/Schema/SequenceDataDefinition.php
new file mode 100644
index 0000000000..c317e29e02
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/Schema/SequenceDataDefinition.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\Core\Config\Schema;
+
+use Drupal\Core\TypedData\ListDataDefinition;
+
+/**
+ * A typed data definition class for defining sequences in configuration.
+ */
+class SequenceDataDefinition extends ListDataDefinition {
+
+  /**
+   * Gets the description of how the sequence should be sorted.
+   *
+   * Only the top level of the array should be sorted. Top-level keys should be
+   * discarded when using 'value' sorting. If the sequence is an associative
+   * array 'key' sorting is recommended, if not 'value' sorting is recommended.
+   *
+   * @return string|null
+   *   May be 'key' (to sort by key), 'value' (to sort by value, discarding
+   *   keys), or NULL (if the schema does not describe how the sequence should
+   *   be sorted).
+   */
+  public function getOrderBy() {
+    return isset($this->definition['orderby']) ? $this->definition['orderby'] : NULL;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php
index 4b227c9efb..bc81ab7cc1 100644
--- a/core/lib/Drupal/Core/Config/StorableConfigBase.php
+++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php
@@ -3,6 +3,8 @@
 namespace Drupal\Core\Config;
 
 use Drupal\Core\Config\Schema\Ignore;
+use Drupal\Core\Config\Schema\Sequence;
+use Drupal\Core\Config\Schema\SequenceDataDefinition;
 use Drupal\Core\TypedData\PrimitiveInterface;
 use Drupal\Core\TypedData\Type\FloatInterface;
 use Drupal\Core\TypedData\Type\IntegerInterface;
@@ -129,9 +131,7 @@ public function getStorage() {
    */
   protected function getSchemaWrapper() {
     if (!isset($this->schemaWrapper)) {
-      $definition = $this->typedConfigManager->getDefinition($this->name);
-      $data_definition = $this->typedConfigManager->buildDataDefinition($definition, $this->data);
-      $this->schemaWrapper = $this->typedConfigManager->create($data_definition, $this->data);
+      $this->schemaWrapper = $this->typedConfigManager->createFromNameAndData($this->name, $this->data);
     }
     return $this->schemaWrapper;
   }
@@ -210,6 +210,29 @@ protected function castValue($key, $value) {
       foreach ($value as $nested_value_key => $nested_value) {
         $value[$nested_value_key] = $this->castValue($key . '.' . $nested_value_key, $nested_value);
       }
+
+      if ($element instanceof Sequence) {
+        $data_definition = $element->getDataDefinition();
+        if ($data_definition instanceof SequenceDataDefinition) {
+          // Apply any sorting defined on the schema.
+          switch ($data_definition->getOrderBy()) {
+            case 'key':
+              ksort($value);
+              break;
+
+            case 'value':
+              // The PHP documentation notes that "Be careful when sorting
+              // arrays with mixed types values because sort() can produce
+              // unpredictable results". There is no risk here because
+              // \Drupal\Core\Config\StorableConfigBase::castValue() has
+              // already cast all values to the same type using the
+              // configuration schema.
+              sort($value);
+              break;
+
+          }
+        }
+      }
     }
     return $value;
   }
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php
index 22795ad6ff..c6ddfb5e9c 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManager.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\Schema\ConfigSchemaAlterException;
 use Drupal\Core\Config\Schema\ConfigSchemaDiscovery;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
 use Drupal\Core\Config\Schema\Undefined;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\TypedData\TypedDataManager;
@@ -45,13 +46,18 @@ class TypedConfigManager extends TypedDataManager implements TypedConfigManagerI
    *   The storage object to use for reading schema data
    * @param \Drupal\Core\Cache\CacheBackendInterface $cache
    *   The cache backend to use for caching the definitions.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
+   *   (optional) The class resolver.
    */
-  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler) {
+  public function __construct(StorageInterface $configStorage, StorageInterface $schemaStorage, CacheBackendInterface $cache, ModuleHandlerInterface $module_handler, ClassResolverInterface $class_resolver = NULL) {
     $this->configStorage = $configStorage;
     $this->schemaStorage = $schemaStorage;
     $this->setCacheBackend($cache, 'typed_config_definitions');
     $this->alterInfo('config_schema_info');
     $this->moduleHandler = $module_handler;
+    $this->classResolver = $class_resolver ?: \Drupal::service('class_resolver');
   }
 
   /**
@@ -69,9 +75,7 @@ protected function getDiscovery() {
    */
   public function get($name) {
     $data = $this->configStorage->read($name);
-    $type_definition = $this->getDefinition($name);
-    $data_definition = $this->buildDataDefinition($type_definition, $data);
-    return $this->create($data_definition, $data);
+    return $this->createFromNameAndData($name, $data);
   }
 
   /**
@@ -184,6 +188,7 @@ protected function getDefinitionWithReplacements($base_plugin_id, array $replace
     $definition += [
       'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
       'type' => $type,
+      'unwrap_for_canonical_representation' => TRUE,
     ];
     return $definition;
   }
@@ -380,4 +385,13 @@ protected function alterDefinitions(&$definitions) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function createFromNameAndData($config_name, array $config_data) {
+    $definition = $this->getDefinition($config_name);
+    $data_definition = $this->buildDataDefinition($definition, $config_data);
+    return $this->create($data_definition, $config_data);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php b/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
index 5beeb6f1cd..5c3779fd1a 100644
--- a/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
+++ b/core/lib/Drupal/Core/Config/TypedConfigManagerInterface.php
@@ -72,4 +72,18 @@ public function hasConfigSchema($name);
    */
   public function getDefinition($plugin_id, $exception_on_invalid = TRUE);
 
+  /**
+   * Gets typed data for a given configuration name and its values.
+   *
+   * @param string $config_name
+   *   The machine name of the configuration.
+   * @param array $config_data
+   *   The data associated with the configuration. Note: This configuration
+   *   doesn't yet have to be stored.
+   *
+   * @return \Drupal\Core\TypedData\TraversableTypedDataInterface
+   *   The typed configuration element.
+   */
+  public function createFromNameAndData($config_name, array $config_data);
+
 }
diff --git a/core/lib/Drupal/Core/Database/database.api.php b/core/lib/Drupal/Core/Database/database.api.php
index 885c6cba27..45a561872a 100644
--- a/core/lib/Drupal/Core/Database/database.api.php
+++ b/core/lib/Drupal/Core/Database/database.api.php
@@ -5,6 +5,8 @@
  * Hooks related to the Database system and the Schema API.
  */
 
+use Drupal\Core\Database\Query\Condition;
+
 /**
  * @defgroup database Database abstraction layer
  * @{
@@ -432,11 +434,11 @@ function hook_query_TAG_alter(Drupal\Core\Database\Query\AlterableInterface $que
     if (!\Drupal::currentUser()->hasPermission('bypass node access')) {
       // The node_access table has the access grants for any given node.
       $access_alias = $query->join('node_access', 'na', '%alias.nid = n.nid');
-      $or = db_or();
+      $or = new Condition('OR');
       // If any grant exists for the specified user, then user has access to the node for the specified operation.
       foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) {
         foreach ($gids as $gid) {
-          $or->condition(db_and()
+          $or->condition((new Condition('AND'))
             ->condition($access_alias . '.gid', $gid)
             ->condition($access_alias . '.realm', $realm)
           );
diff --git a/core/lib/Drupal/Core/DependencyInjection/Container.php b/core/lib/Drupal/Core/DependencyInjection/Container.php
index 4a491225b0..5643363316 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Container.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Container.php
@@ -3,7 +3,6 @@
 namespace Drupal\Core\DependencyInjection;
 
 use Drupal\Component\DependencyInjection\Container as DrupalContainer;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Extends the Drupal container to set the service ID on the created object.
@@ -13,8 +12,8 @@ class Container extends DrupalContainer {
   /**
    * {@inheritdoc}
    */
-  public function set($id, $service, $scope = ContainerInterface::SCOPE_CONTAINER) {
-    parent::set($id, $service, $scope);
+  public function set($id, $service) {
+    parent::set($id, $service);
 
     // Ensure that the _serviceId property is set on synthetic services as well.
     if (isset($this->services[$id]) && is_object($this->services[$id]) && !isset($this->services[$id]->_serviceId)) {
diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
index e45cb884aa..e0becc71e2 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
@@ -46,20 +46,12 @@ private function getProxyInstantiator()
   }
 
   /**
-   * Direct copy of the parent function.
+   * {@inheritdoc}
    */
   protected function shareService(Definition $definition, $service, $id)
   {
-    if ($definition->isShared() && self::SCOPE_PROTOTYPE !== $scope = $definition->getScope(false)) {
-      if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
-        throw new InactiveScopeException($id, $scope);
-      }
-
+    if ($definition->isShared()) {
       $this->services[$lowerId = strtolower($id)] = $service;
-
-      if (self::SCOPE_CONTAINER !== $scope) {
-        $this->scopedServices[$scope][$lowerId] = $service;
-      }
     }
   }
 
@@ -74,11 +66,11 @@ protected function shareService(Definition $definition, $service, $id)
    *   ContainerBuilder class should be fixed to allow setting synthetic
    *   services in a frozen builder.
    */
-  public function set($id, $service, $scope = self::SCOPE_CONTAINER) {
+  public function set($id, $service) {
     if (strtolower($id) !== $id) {
       throw new \InvalidArgumentException("Service ID names must be lowercase: $id");
     }
-    SymfonyContainer::set($id, $service, $scope);
+    SymfonyContainer::set($id, $service);
 
     // Ensure that the _serviceId property is set on synthetic services as well.
     if (isset($this->services[$id]) && is_object($this->services[$id]) && !isset($this->services[$id]->_serviceId)) {
diff --git a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
index da1c08c2f5..d999450b0a 100644
--- a/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
+++ b/core/lib/Drupal/Core/DependencyInjection/YamlFileLoader.php
@@ -168,21 +168,10 @@ private function parseDefinition($id, $service, $file)
             $definition->setShared($service['shared']);
         }
 
-        if (isset($service['scope'])) {
-            if ('request' !== $id) {
-                @trigger_error(sprintf('The "scope" key of service "%s" in file "%s" is deprecated since version 2.8 and will be removed in 3.0.', $id, $file), E_USER_DEPRECATED);
-            }
-            $definition->setScope($service['scope'], false);
-        }
-
         if (isset($service['synthetic'])) {
             $definition->setSynthetic($service['synthetic']);
         }
 
-        if (isset($service['synchronized'])) {
-            $definition->setSynchronized($service['synchronized'], 'request' !== $id);
-        }
-
         if (isset($service['lazy'])) {
             $definition->setLazy($service['lazy']);
         }
@@ -213,15 +202,15 @@ private function parseDefinition($id, $service, $file)
         }
 
         if (isset($service['factory_class'])) {
-            $definition->setFactoryClass($service['factory_class']);
+            $definition->setFactory($service['factory_class']);
         }
 
         if (isset($service['factory_method'])) {
-            $definition->setFactoryMethod($service['factory_method']);
+            $definition->setFactory($service['factory_method']);
         }
 
         if (isset($service['factory_service'])) {
-            $definition->setFactoryService($service['factory_service']);
+            $definition->setFactory($service['factory_service']);
         }
 
         if (isset($service['file'])) {
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index fc36f6644b..02c97f5edb 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -410,7 +410,7 @@ public static function findSitePath(Request $request, $require_settings = TRUE,
    * {@inheritdoc}
    */
   public function setSitePath($path) {
-    if ($this->booted) {
+    if ($this->booted && $path !== $this->sitePath) {
       throw new \LogicException('Site path cannot be changed after calling boot()');
     }
     $this->sitePath = $path;
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index c46126e363..afddb228b9 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -1285,20 +1285,15 @@ public static function bundleFieldDefinitions(EntityTypeInterface $entity_type,
    *   An array of field names.
    */
   protected function getFieldsToSkipFromTranslationChangesCheck() {
+    /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
+    $entity_type = $this->getEntityType();
     // A list of known revision metadata fields which should be skipped from
     // the comparision.
-    // @todo Replace the hard coded list of revision metadata fields with the
-    // solution from https://www.drupal.org/node/2615016.
     $fields = [
-      $this->getEntityType()->getKey('revision'),
+      $entity_type->getKey('revision'),
       'revision_translation_affected',
-      'revision_uid',
-      'revision_user',
-      'revision_timestamp',
-      'revision_created',
-      'revision_log',
-      'revision_log_message',
     ];
+    $fields = array_merge($fields, array_values($entity_type->getRevisionMetadataKeys()));
 
     return $fields;
   }
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityType.php b/core/lib/Drupal/Core/Entity/ContentEntityType.php
index 400374b009..0e26c3bb51 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityType.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityType.php
@@ -8,6 +8,13 @@
 class ContentEntityType extends EntityType implements ContentEntityTypeInterface {
 
   /**
+   * An array of entity revision metadata keys.
+   *
+   * @var array
+   */
+  protected $revision_metadata_keys = [];
+
+  /**
    * {@inheritdoc}
    */
   public function __construct($definition) {
@@ -41,4 +48,44 @@ protected function checkStorageClass($class) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionMetadataKeys($include_backwards_compatibility_field_names = TRUE) {
+    // Provide backwards compatibility in case the revision metadata keys are
+    // not defined in the entity annotation.
+    if (!$this->revision_metadata_keys && $include_backwards_compatibility_field_names) {
+      $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($this->id());
+      if ((isset($base_fields['revision_uid']) && $revision_user = 'revision_uid') || (isset($base_fields['revision_user']) && $revision_user = 'revision_user')) {
+        @trigger_error('The revision_user revision metadata key is not set.', E_USER_DEPRECATED);
+        $this->revision_metadata_keys['revision_user'] = $revision_user;
+      }
+      if ((isset($base_fields['revision_timestamp']) && $revision_timestamp = 'revision_timestamp') || (isset($base_fields['revision_created'])) && $revision_timestamp = 'revision_created') {
+        @trigger_error('The revision_created revision metadata key is not set.', E_USER_DEPRECATED);
+        $this->revision_metadata_keys['revision_created'] = $revision_timestamp;
+      }
+      if ((isset($base_fields['revision_log']) && $revision_log = 'revision_log') || (isset($base_fields['revision_log_message']) && $revision_log = 'revision_log_message')) {
+        @trigger_error('The revision_log_message revision metadata key is not set.', E_USER_DEPRECATED);
+        $this->revision_metadata_keys['revision_log_message'] = $revision_log;
+      }
+    }
+    return $this->revision_metadata_keys;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRevisionMetadataKey($key) {
+    $keys = $this->getRevisionMetadataKeys();
+    return isset($keys[$key]) ? $keys[$key] : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasRevisionMetadataKey($key) {
+    $keys = $this->getRevisionMetadataKeys();
+    return isset($keys[$key]);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
index f9ef160e3e..4c9e890147 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php
@@ -6,4 +6,50 @@
  * Provides an interface for a content entity type and its metadata.
  */
 interface ContentEntityTypeInterface extends EntityTypeInterface {
+
+  /**
+   * Gets an array of entity revision metadata keys.
+   *
+   * @param bool $include_backwards_compatibility_field_names
+   *   (optional and deprecated) Whether to provide the revision keys on a
+   *   best-effort basis by looking at the base fields defined by the entity
+   *   type. Note that this parameter will be removed in Drupal 9.0.0. Defaults
+   *   to TRUE.
+   *
+   * @return array
+   *   An array describing how the Field API can extract revision metadata
+   *   information of this entity type:
+   *   - revision_log_message: The name of the property that contains description
+   *     of the changes that were made in the current revision.
+   *   - revision_user: The name of the property that contains the user ID of
+   *     the author of the current revision.
+   *   - revision_created: The name of the property that contains the timestamp
+   *     of the current revision.
+   */
+  public function getRevisionMetadataKeys($include_backwards_compatibility_field_names = TRUE);
+
+  /**
+   * Gets a specific entity revision metadata key.
+   *
+   * @param string $key
+   *   The name of the entity revision metadata key to return.
+   *
+   * @return string|bool
+   *   The entity revision metadata key, or FALSE if it does not exist.
+   *
+   * @see self::getRevisionMetadataKeys()
+   */
+  public function getRevisionMetadataKey($key);
+
+  /**
+   * Indicates if a given entity revision metadata key exists.
+   *
+   * @param string $key
+   *   The name of the entity revision metadata key to check.
+   *
+   * @return bool
+   *   TRUE if a given entity revision metadata key exists, FALSE otherwise.
+   */
+  public function hasRevisionMetadataKey($key);
+
 }
diff --git a/core/lib/Drupal/Core/Entity/EditorialContentEntityBase.php b/core/lib/Drupal/Core/Entity/EditorialContentEntityBase.php
new file mode 100644
index 0000000000..ff6abcd0d5
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/EditorialContentEntityBase.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\Core\Entity;
+
+/**
+ * Provides a base entity class with extended revision and publishing support.
+ *
+ * @ingroup entity_api
+ */
+abstract class EditorialContentEntityBase extends ContentEntityBase implements EntityChangedInterface, EntityPublishedInterface, RevisionLogInterface {
+
+  use EntityChangedTrait;
+  use EntityPublishedTrait;
+  use RevisionLogEntityTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    // Add the revision metadata fields.
+    $fields += static::revisionLogBaseFieldDefinitions($entity_type);
+
+    // Add the published field.
+    $fields += static::publishedBaseFieldDefinitions($entity_type);
+
+    return $fields;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index f36f74fe67..95e85e21a4 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Link;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
 
 /**
  * Defines a base entity class.
@@ -323,7 +324,19 @@ protected function urlRouteParameters($rel) {
    * {@inheritdoc}
    */
   public function uriRelationships() {
-    return array_keys($this->linkTemplates());
+    return array_filter(array_keys($this->linkTemplates()), function ($link_relation_type) {
+      // It's not guaranteed that every link relation type also has a
+      // corresponding route. For some, additional modules or configuration may
+      // be necessary. The interface demands that we only return supported URI
+      // relationships.
+      try {
+        $this->toUrl($link_relation_type)->toString(TRUE)->getGeneratedUrl();
+      }
+      catch (RouteNotFoundException $e) {
+        return FALSE;
+      }
+      return TRUE;
+    });
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php b/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php
index 73928581d7..f935a8b510 100644
--- a/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php
+++ b/core/lib/Drupal/Core/Entity/RevisionLogEntityTrait.php
@@ -25,18 +25,18 @@
    * @see \Drupal\Core\Entity\FieldableEntityInterface::baseFieldDefinitions()
    */
   public static function revisionLogBaseFieldDefinitions(EntityTypeInterface $entity_type) {
-    $fields['revision_created'] = BaseFieldDefinition::create('created')
+    $fields[static::getRevisionMetadataKey($entity_type, 'revision_created')] = BaseFieldDefinition::create('created')
       ->setLabel(t('Revision create time'))
       ->setDescription(t('The time that the current revision was created.'))
       ->setRevisionable(TRUE);
 
-    $fields['revision_user'] = BaseFieldDefinition::create('entity_reference')
+    $fields[static::getRevisionMetadataKey($entity_type, 'revision_user')] = BaseFieldDefinition::create('entity_reference')
       ->setLabel(t('Revision user'))
       ->setDescription(t('The user ID of the author of the current revision.'))
       ->setSetting('target_type', 'user')
       ->setRevisionable(TRUE);
 
-    $fields['revision_log_message'] = BaseFieldDefinition::create('string_long')
+    $fields[static::getRevisionMetadataKey($entity_type, 'revision_log_message')] = BaseFieldDefinition::create('string_long')
       ->setLabel(t('Revision log message'))
       ->setDescription(t('Briefly describe the changes you have made.'))
       ->setRevisionable(TRUE)
@@ -56,14 +56,14 @@ public static function revisionLogBaseFieldDefinitions(EntityTypeInterface $enti
    * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionCreationTime().
    */
   public function getRevisionCreationTime() {
-    return $this->revision_created->value;
+    return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_created')}->value;
   }
 
   /**
    * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionCreationTime().
    */
   public function setRevisionCreationTime($timestamp) {
-    $this->revision_created->value = $timestamp;
+    $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_created')}->value = $timestamp;
     return $this;
   }
 
@@ -71,14 +71,14 @@ public function setRevisionCreationTime($timestamp) {
    * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionUser().
    */
   public function getRevisionUser() {
-    return $this->revision_user->entity;
+    return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->entity;
   }
 
   /**
    * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionUser().
    */
   public function setRevisionUser(UserInterface $account) {
-    $this->revision_user->entity = $account;
+    $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->entity = $account;
     return $this;
   }
 
@@ -86,14 +86,14 @@ public function setRevisionUser(UserInterface $account) {
    * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionUserId().
    */
   public function getRevisionUserId() {
-    return $this->revision_user->target_id;
+    return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->target_id;
   }
 
   /**
    * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionUserId().
    */
   public function setRevisionUserId($user_id) {
-    $this->revision_user->target_id = $user_id;
+    $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_user')}->target_id = $user_id;
     return $this;
   }
 
@@ -101,15 +101,41 @@ public function setRevisionUserId($user_id) {
    * Implements \Drupal\Core\Entity\RevisionLogInterface::getRevisionLogMessage().
    */
   public function getRevisionLogMessage() {
-    return $this->revision_log_message->value;
+    return $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_log_message')}->value;
   }
 
   /**
    * Implements \Drupal\Core\Entity\RevisionLogInterface::setRevisionLogMessage().
    */
   public function setRevisionLogMessage($revision_log_message) {
-    $this->revision_log_message->value = $revision_log_message;
+    $this->{static::getRevisionMetadataKey($this->getEntityType(), 'revision_log_message')}->value = $revision_log_message;
     return $this;
   }
 
+  /**
+   * Gets the name of a revision metadata field.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
+   *   A content entity type definition.
+   * @param string $key
+   *   The revision metadata key to get, must be one of 'revision_created',
+   *   'revision_user' or 'revision_log_message'.
+   *
+   * @return string
+   *   The name of the field for the specified $key.
+   */
+  protected static function getRevisionMetadataKey(EntityTypeInterface $entity_type, $key) {
+    // We need to prevent ContentEntityType::getRevisionMetadataKey() from
+    // providing fallback as that requires fetching the entity type's field
+    // definition leading to an infinite recursion.
+    /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
+    $revision_metadata_keys = $entity_type->getRevisionMetadataKeys(FALSE) + [
+      'revision_created' => 'revision_created',
+      'revision_user' => 'revision_user',
+      'revision_log_message' => 'revision_log_message',
+    ];
+
+    return $revision_metadata_keys[$key];
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
index a13a4b2d17..1172406e34 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -118,6 +118,13 @@ class SqlContentEntityStorage extends ContentEntityStorageBase implements SqlEnt
   protected $languageManager;
 
   /**
+   * Whether this storage should use the temporary table mapping.
+   *
+   * @var bool
+   */
+  protected $temporary = FALSE;
+
+  /**
    * {@inheritdoc}
    */
   public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
@@ -267,6 +274,31 @@ public function setEntityType(EntityTypeInterface $entity_type) {
   }
 
   /**
+   * Sets the wrapped table mapping definition.
+   *
+   * @param \Drupal\Core\Entity\Sql\TableMappingInterface $table_mapping
+   *   The table mapping.
+   *
+   * @internal Only to be used internally by Entity API. Expected to be removed
+   *   by https://www.drupal.org/node/2554235.
+   */
+  public function setTableMapping(TableMappingInterface $table_mapping) {
+    $this->tableMapping = $table_mapping;
+  }
+
+  /**
+   * Changes the temporary state of the storage.
+   *
+   * @param bool $temporary
+   *   Whether to use a temporary table mapping or not.
+   *
+   * @internal Only to be used internally by Entity API.
+   */
+  public function setTemporary($temporary) {
+    $this->temporary = $temporary;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getTableMapping(array $storage_definitions = NULL) {
@@ -279,8 +311,10 @@ public function getTableMapping(array $storage_definitions = NULL) {
     // @todo Clean-up this in https://www.drupal.org/node/2274017 so we can
     //   easily instantiate a new table mapping whenever needed.
     if (!isset($this->tableMapping) || $storage_definitions) {
+      $table_mapping_class = $this->temporary ? TemporaryTableMapping::class : DefaultTableMapping::class;
       $definitions = $storage_definitions ?: $this->entityManager->getFieldStorageDefinitions($this->entityTypeId);
-      $table_mapping = new DefaultTableMapping($this->entityType, $definitions);
+      /** @var \Drupal\Core\Entity\Sql\DefaultTableMapping|\Drupal\Core\Entity\Sql\TemporaryTableMapping $table_mapping */
+      $table_mapping = new $table_mapping_class($this->entityType, $definitions);
 
       $shared_table_definitions = array_filter($definitions, function (FieldStorageDefinitionInterface $definition) use ($table_mapping) {
         return $table_mapping->allowsSharedTableStorage($definition);
@@ -294,17 +328,11 @@ public function getTableMapping(array $storage_definitions = NULL) {
       // Make sure the key fields come first in the list of fields.
       $all_fields = array_merge($key_fields, array_diff($all_fields, $key_fields));
 
-      // Nodes have all three of these fields, while custom blocks only have
-      // log.
-      // @todo Provide automatic definitions for revision metadata fields in
-      //   https://www.drupal.org/node/2248983.
-      $revision_metadata_fields = array_intersect([
-        'revision_timestamp',
-        'revision_uid',
-        'revision_log',
-      ], $all_fields);
-
+      // If the entity is revisionable, gather the fields that need to be put
+      // in the revision table.
       $revisionable = $this->entityType->isRevisionable();
+      $revision_metadata_fields = $revisionable ? array_values($this->entityType->getRevisionMetadataKeys()) : [];
+
       $translatable = $this->entityType->isTranslatable();
       if (!$revisionable && !$translatable) {
         // The base layout stores all the base field values in the base table.
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
index f9dd0c0850..6327656eaa 100644
--- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -237,6 +237,12 @@ protected function getSchemaFromStorageDefinition(FieldStorageDefinitionInterfac
    * {@inheritdoc}
    */
   public function requiresEntityDataMigration(EntityTypeInterface $entity_type, EntityTypeInterface $original) {
+    // Check if the entity type specifies that data migration is being handled
+    // elsewhere.
+    if ($entity_type->get('requires_data_migration') === FALSE) {
+      return FALSE;
+    }
+
     // If the original storage has existing entities, or it is impossible to
     // determine if that is the case, require entity data to be migrated.
     $original_storage_class = $original->getStorageClass();
@@ -1212,10 +1218,14 @@ protected function deleteDedicatedTableSchema(FieldStorageDefinitionInterface $s
     $deleted = !$this->originalDefinitions;
     $table_mapping = $this->storage->getTableMapping();
     $table_name = $table_mapping->getDedicatedDataTableName($storage_definition, $deleted);
-    $this->database->schema()->dropTable($table_name);
+    if ($this->database->schema()->tableExists($table_name)) {
+      $this->database->schema()->dropTable($table_name);
+    }
     if ($this->entityType->isRevisionable()) {
-      $revision_name = $table_mapping->getDedicatedRevisionTableName($storage_definition, $deleted);
-      $this->database->schema()->dropTable($revision_name);
+      $revision_table_name = $table_mapping->getDedicatedRevisionTableName($storage_definition, $deleted);
+      if ($this->database->schema()->tableExists($revision_table_name)) {
+        $this->database->schema()->dropTable($revision_table_name);
+      }
     }
     $this->deleteFieldSchemaData($storage_definition);
   }
diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php
new file mode 100644
index 0000000000..30befd2e9f
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchemaConverter.php
@@ -0,0 +1,461 @@
+<?php
+
+namespace Drupal\Core\Entity\Sql;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Entity\ContentEntityTypeInterface;
+use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
+use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
+use Drupal\Core\Entity\EntityStorageException;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
+use Drupal\Core\Site\Settings;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+
+/**
+ * Defines a schema converter for entity types with existing data.
+ *
+ * For now, this can only be used to convert an entity type from
+ * non-revisionable to revisionable, however, it should be expanded so it can
+ * also handle converting an entity type to be translatable.
+ */
+class SqlContentEntityStorageSchemaConverter {
+
+  /**
+   * The entity type ID this schema converter is responsible for.
+   *
+   * @var string
+   */
+  protected $entityTypeId;
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity definition update manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
+   */
+  protected $entityDefinitionUpdateManager;
+
+  /**
+   * The last installed schema repository service.
+   *
+   * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
+   */
+  protected $lastInstalledSchemaRepository;
+
+  /**
+   * The key-value collection for tracking installed storage schema.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
+   */
+  protected $installedStorageSchema;
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $database;
+
+  /**
+   * SqlContentEntityStorageSchemaConverter constructor.
+   *
+   * @param string $entity_type_id
+   *   The ID of the entity type.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $entity_definition_update_manager
+   *   Entity definition update manager service.
+   * @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository
+   *   Last installed schema repository service.
+   * @param \Drupal\Core\Database\Connection $database
+   *   Database connection.
+   */
+  public function __construct($entity_type_id, EntityTypeManagerInterface $entity_type_manager, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository, KeyValueStoreInterface $installed_storage_schema, Connection $database) {
+    $this->entityTypeId = $entity_type_id;
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityDefinitionUpdateManager = $entity_definition_update_manager;
+    $this->lastInstalledSchemaRepository = $last_installed_schema_repository;
+    $this->installedStorageSchema = $installed_storage_schema;
+    $this->database = $database;
+  }
+
+  /**
+   * Converts an entity type with existing data to be revisionable.
+   *
+   * This process does the following tasks:
+   *   - creates the schema from scratch with the new revisionable entity type
+   *     definition (i.e. the current definition of the entity type from code)
+   *     using temporary table names;
+   *   - loads the initial entity data by using the last installed entity and
+   *     field storage definitions;
+   *   - saves the entity data to the temporary tables;
+   *   - at the end of the process:
+   *     - deletes the original tables and replaces them with the temporary ones
+   *       that hold the new (revisionable) entity data;
+   *     - updates the installed entity schema data;
+   *     - updates the entity type definition in order to trigger the
+   *       \Drupal\Core\Entity\EntityTypeEvents::UPDATE event;
+   *     - updates the field storage definitions in order to mark the
+   *       revisionable ones as such.
+   *
+   * In case of an error during the entity save process, the temporary tables
+   * are deleted and the original entity type and field storage definitions are
+   * restored.
+   *
+   * @param array $sandbox
+   *   The sandbox array from a hook_update_N() implementation.
+   * @param string[] $fields_to_update
+   *   (optional) An array of field names that should be converted to be
+   *   revisionable. Note that the 'langcode' field, if present, is updated
+   *   automatically. Defaults to an empty array.
+   *
+   * @throws \Exception
+   *   Re-throws any exception raised during the update process.
+   */
+  public function convertToRevisionable(array &$sandbox, array $fields_to_update = []) {
+    // If 'progress' is not set, then this will be the first run of the batch.
+    if (!isset($sandbox['progress'])) {
+      // Store the original entity type and field definitions in the $sandbox
+      // array so we can use them later in the update process.
+      $this->collectOriginalDefinitions($sandbox);
+
+      // Create a temporary environment in which the new data will be stored.
+      $this->createTemporaryDefinitions($sandbox, $fields_to_update);
+
+      // Create the updated entity schema using temporary tables.
+      /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
+      $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
+      $storage->setTemporary(TRUE);
+      $storage->setEntityType($sandbox['temporary_entity_type']);
+      $storage->onEntityTypeCreate($sandbox['temporary_entity_type']);
+    }
+
+    // Copy over the existing data to the new temporary tables.
+    $this->copyData($sandbox);
+
+    // If the data copying has finished successfully, we can drop the temporary
+    // tables and call the appropriate update mechanisms.
+    if ($sandbox['#finished'] == 1) {
+      $this->entityTypeManager->useCaches(FALSE);
+      $actual_entity_type = $this->entityTypeManager->getDefinition($this->entityTypeId);
+
+      // Rename the original tables so we can put them back in place in case
+      // anything goes wrong.
+      foreach ($sandbox['original_table_mapping']->getTableNames() as $table_name) {
+        $old_table_name = TemporaryTableMapping::getTempTableName($table_name, 'old_');
+        $this->database->schema()->renameTable($table_name, $old_table_name);
+      }
+
+      // Put the new tables in place and update the entity type and field
+      // storage definitions.
+      try {
+        $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
+        $storage->setEntityType($actual_entity_type);
+        $storage->setTemporary(FALSE);
+        $actual_table_names = $storage->getTableMapping()->getTableNames();
+
+        $table_name_mapping = [];
+        foreach ($actual_table_names as $new_table_name) {
+          $temp_table_name = TemporaryTableMapping::getTempTableName($new_table_name);
+          $table_name_mapping[$temp_table_name] = $new_table_name;
+          $this->database->schema()->renameTable($temp_table_name, $new_table_name);
+        }
+
+        // Rename the tables in the cached entity schema data.
+        $entity_schema_data = $this->installedStorageSchema->get($this->entityTypeId . '.entity_schema_data', []);
+        foreach ($entity_schema_data as $temp_table_name => $schema) {
+          if (isset($table_name_mapping[$temp_table_name])) {
+            $entity_schema_data[$table_name_mapping[$temp_table_name]] = $schema;
+            unset($entity_schema_data[$temp_table_name]);
+          }
+        }
+        $this->installedStorageSchema->set($this->entityTypeId . '.entity_schema_data', $entity_schema_data);
+
+        // Rename the tables in the cached field schema data.
+        foreach ($sandbox['updated_storage_definitions'] as $storage_definition) {
+          $field_schema_data = $this->installedStorageSchema->get($this->entityTypeId . '.field_schema_data.' . $storage_definition->getName(), []);
+          foreach ($field_schema_data as $temp_table_name => $schema) {
+            if (isset($table_name_mapping[$temp_table_name])) {
+              $field_schema_data[$table_name_mapping[$temp_table_name]] = $schema;
+              unset($field_schema_data[$temp_table_name]);
+            }
+          }
+          $this->installedStorageSchema->set($this->entityTypeId . '.field_schema_data.' . $storage_definition->getName(), $field_schema_data);
+        }
+
+        // Instruct the entity schema handler that data migration has been
+        // handled already and update the entity type.
+        $actual_entity_type->set('requires_data_migration', FALSE);
+        $this->entityDefinitionUpdateManager->updateEntityType($actual_entity_type);
+
+        // Update the field storage definitions.
+        $this->updateFieldStorageDefinitionsToRevisionable($actual_entity_type, $sandbox['original_storage_definitions'], $fields_to_update);
+      }
+      catch (\Exception $e) {
+        // Something went wrong, bring back the original tables.
+        foreach ($sandbox['original_table_mapping']->getTableNames() as $table_name) {
+          // We are in the 'original data recovery' phase, so we need to be sure
+          // that the initial tables can be properly restored.
+          if ($this->database->schema()->tableExists($table_name)) {
+            $this->database->schema()->dropTable($table_name);
+          }
+
+          $old_table_name = TemporaryTableMapping::getTempTableName($table_name, 'old_');
+          $this->database->schema()->renameTable($old_table_name, $table_name);
+        }
+
+        // Re-throw the original exception.
+        throw $e;
+      }
+
+      // At this point the update process either finished successfully or any
+      // error has been handled already, so we can drop the backup entity
+      // tables.
+      foreach ($sandbox['original_table_mapping']->getTableNames() as $table_name) {
+        $old_table_name = TemporaryTableMapping::getTempTableName($table_name, 'old_');
+        $this->database->schema()->dropTable($old_table_name);
+      }
+    }
+  }
+
+  /**
+   * Loads entities from the original storage and saves them to a temporary one.
+   *
+   * @param array &$sandbox
+   *   The sandbox array from a hook_update_N() implementation.
+   *
+   * @throws \Drupal\Core\Entity\EntityStorageException
+   *   Thrown in case of an error during the entity save process.
+   */
+  protected function copyData(array &$sandbox) {
+    /** @var \Drupal\Core\Entity\Sql\TemporaryTableMapping $temporary_table_mapping */
+    $temporary_table_mapping = $sandbox['temporary_table_mapping'];
+    $temporary_entity_type = $sandbox['temporary_entity_type'];
+    $original_table_mapping = $sandbox['original_table_mapping'];
+    $original_entity_type = $sandbox['original_entity_type'];
+
+    $original_base_table = $original_entity_type->getBaseTable();
+
+    $revision_id_key = $temporary_entity_type->getKey('revision');
+
+    // If 'progress' is not set, then this will be the first run of the batch.
+    if (!isset($sandbox['progress'])) {
+      $sandbox['progress'] = 0;
+      $sandbox['current_id'] = 0;
+      $sandbox['max'] = $this->database->select($original_base_table)
+        ->countQuery()
+        ->execute()
+        ->fetchField();
+    }
+
+    $id = $original_entity_type->getKey('id');
+
+    // Define the step size.
+    $step_size = Settings::get('entity_update_batch_size', 50);
+
+    // Get the next entity IDs to migrate.
+    $entity_ids = $this->database->select($original_base_table)
+      ->fields($original_base_table, [$id])
+      ->condition($id, $sandbox['current_id'], '>')
+      ->orderBy($id, 'ASC')
+      ->range(0, $step_size)
+      ->execute()
+      ->fetchAllKeyed(0, 0);
+
+    /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
+    $storage = $this->entityTypeManager->getStorage($temporary_entity_type->id());
+    $storage->setEntityType($original_entity_type);
+    $storage->setTableMapping($original_table_mapping);
+
+    $entities = $storage->loadMultiple($entity_ids);
+
+    // Now inject the temporary entity type definition and table mapping in the
+    // storage and re-save the entities.
+    $storage->setEntityType($temporary_entity_type);
+    $storage->setTableMapping($temporary_table_mapping);
+
+    foreach ($entities as $entity_id => $entity) {
+      try {
+        // Set the revision ID to be same as the entity ID.
+        $entity->set($revision_id_key, $entity_id);
+
+        // Treat the entity as new in order to make the storage do an INSERT
+        // rather than an UPDATE.
+        $entity->enforceIsNew(TRUE);
+
+        // Finally, save the entity in the temporary storage.
+        $storage->save($entity);
+      }
+      catch (\Exception $e) {
+        // In case of an error during the save process, we need to roll back the
+        // original entity type and field storage definitions and clean up the
+        // temporary tables.
+        $this->restoreOriginalDefinitions($sandbox);
+
+        foreach ($temporary_table_mapping->getTableNames() as $table_name) {
+          $this->database->schema()->dropTable($table_name);
+        }
+
+        // Re-throw the original exception with a helpful message.
+        throw new EntityStorageException("The entity update process failed while processing the entity {$original_entity_type->id()}:$entity_id.", $e->getCode(), $e);
+      }
+
+      $sandbox['progress']++;
+      $sandbox['current_id'] = $entity_id;
+    }
+
+    // If we're not in maintenance mode, the number of entities could change at
+    // any time so make sure that we always use the latest record count.
+    $sandbox['max'] = $this->database->select($original_base_table)
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+
+    $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']);
+  }
+
+  /**
+   * Updates field definitions to be revisionable.
+   *
+   * @param \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type
+   *   A content entity type definition.
+   * @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $storage_definitions
+   *   An array of field storage definitions.
+   * @param array $fields_to_update
+   *   (optional) An array of field names for which to enable revision support.
+   *   Defaults to an empty array.
+   * @param bool $update_cached_definitions
+   *   (optional) Whether to update the cached field storage definitions in the
+   *   entity definition update manager. Defaults to TRUE.
+   *
+   * @return \Drupal\Core\Field\FieldStorageDefinitionInterface[]
+   *   An array of updated field storage definitions.
+   */
+  protected function updateFieldStorageDefinitionsToRevisionable(ContentEntityTypeInterface $entity_type, array $storage_definitions, array $fields_to_update = [], $update_cached_definitions = TRUE) {
+    $updated_storage_definitions = array_map(function ($storage_definition) { return clone $storage_definition; }, $storage_definitions);
+
+    // Update the 'langcode' field manually, as it is configured in the base
+    // content entity field definitions.
+    if ($entity_type->hasKey('langcode')) {
+      $fields_to_update = array_merge([$entity_type->getKey('langcode')], $fields_to_update);
+    }
+
+    foreach ($fields_to_update as $field_name) {
+      if (!$updated_storage_definitions[$field_name]->isRevisionable()) {
+        $updated_storage_definitions[$field_name]->setRevisionable(TRUE);
+
+        if ($update_cached_definitions) {
+          $this->entityDefinitionUpdateManager->updateFieldStorageDefinition($updated_storage_definitions[$field_name]);
+        }
+      }
+    }
+
+    // Add the revision ID field.
+    $revision_field = BaseFieldDefinition::create('integer')
+      ->setName($entity_type->getKey('revision'))
+      ->setTargetEntityTypeId($entity_type->id())
+      ->setTargetBundle(NULL)
+      ->setLabel(new TranslatableMarkup('Revision ID'))
+      ->setReadOnly(TRUE)
+      ->setSetting('unsigned', TRUE);
+
+    if ($update_cached_definitions) {
+      $this->entityDefinitionUpdateManager->installFieldStorageDefinition($revision_field->getName(), $entity_type->id(), $entity_type->getProvider(), $revision_field);
+    }
+
+    $updated_storage_definitions[$entity_type->getKey('revision')] = $revision_field;
+
+    return $updated_storage_definitions;
+  }
+
+  /**
+   * Collects the original definitions of an entity type and its fields.
+   *
+   * @param array &$sandbox
+   *   A sandbox array from a hook_update_N() implementation.
+   */
+  protected function collectOriginalDefinitions(array &$sandbox) {
+    $original_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition($this->entityTypeId);
+    $original_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($this->entityTypeId);
+
+    /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
+    $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
+    $storage->setEntityType($original_entity_type);
+    $original_table_mapping = $storage->getTableMapping($original_storage_definitions);
+
+    $sandbox['original_entity_type'] = $original_entity_type;
+    $sandbox['original_storage_definitions'] = $original_storage_definitions;
+    $sandbox['original_table_mapping'] = $original_table_mapping;
+
+    $sandbox['original_entity_schema_data'] = $this->installedStorageSchema->get($this->entityTypeId . '.entity_schema_data', []);
+    foreach ($original_storage_definitions as $storage_definition) {
+      $sandbox['original_field_schema_data'][$storage_definition->getName()] = $this->installedStorageSchema->get($this->entityTypeId . '.field_schema_data.' . $storage_definition->getName(), []);
+    }
+  }
+
+  /**
+   * Restores the entity type, field storage definitions and their schema data.
+   *
+   * @param array $sandbox
+   *   The sandbox array from a hook_update_N() implementation.
+   */
+  protected function restoreOriginalDefinitions(array $sandbox) {
+    $original_entity_type = $sandbox['original_entity_type'];
+    $original_storage_definitions = $sandbox['original_storage_definitions'];
+    $original_entity_schema_data = $sandbox['original_entity_schema_data'];
+    $original_field_schema_data = $sandbox['original_field_schema_data'];
+
+    $this->lastInstalledSchemaRepository->setLastInstalledDefinition($original_entity_type);
+    $this->lastInstalledSchemaRepository->setLastInstalledFieldStorageDefinitions($original_entity_type->id(), $original_storage_definitions);
+
+    $this->installedStorageSchema->set($original_entity_type->id() . '.entity_schema_data', $original_entity_schema_data);
+    foreach ($original_field_schema_data as $field_name => $field_schema_data) {
+      $this->installedStorageSchema->set($original_entity_type->id() . '.field_schema_data.' . $field_name, $field_schema_data);
+    }
+  }
+
+  /**
+   * Creates temporary entity type, field storage and table mapping objects.
+   *
+   * @param array &$sandbox
+   *   A sandbox array from a hook_update_N() implementation.
+   * @param string[] $fields_to_update
+   *   (optional) An array of field names that should be converted to be
+   *   revisionable. Note that the 'langcode' field, if present, is updated
+   *   automatically. Defaults to an empty array.
+   */
+  protected function createTemporaryDefinitions(array &$sandbox, array $fields_to_update) {
+    // Make sure to get the latest entity type definition from code.
+    $this->entityTypeManager->useCaches(FALSE);
+    $actual_entity_type = $this->entityTypeManager->getDefinition($this->entityTypeId);
+
+    $temporary_entity_type = clone $actual_entity_type;
+    $temporary_entity_type->set('base_table', TemporaryTableMapping::getTempTableName($temporary_entity_type->getBaseTable()));
+    $temporary_entity_type->set('revision_table', TemporaryTableMapping::getTempTableName($temporary_entity_type->getRevisionTable()));
+    if ($temporary_entity_type->isTranslatable()) {
+      $temporary_entity_type->set('data_table', TemporaryTableMapping::getTempTableName($temporary_entity_type->getDataTable()));
+      $temporary_entity_type->set('revision_data_table', TemporaryTableMapping::getTempTableName($temporary_entity_type->getRevisionDataTable()));
+    }
+
+    /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
+    $storage = $this->entityTypeManager->getStorage($this->entityTypeId);
+    $storage->setTemporary(TRUE);
+    $storage->setEntityType($temporary_entity_type);
+
+    $updated_storage_definitions = $this->updateFieldStorageDefinitionsToRevisionable($temporary_entity_type, $sandbox['original_storage_definitions'], $fields_to_update, FALSE);
+    $temporary_table_mapping = $storage->getTableMapping($updated_storage_definitions);
+
+    $sandbox['temporary_entity_type'] = $temporary_entity_type;
+    $sandbox['temporary_table_mapping'] = $temporary_table_mapping;
+    $sandbox['updated_storage_definitions'] = $updated_storage_definitions;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/Sql/TemporaryTableMapping.php b/core/lib/Drupal/Core/Entity/Sql/TemporaryTableMapping.php
new file mode 100644
index 0000000000..c53e660cb1
--- /dev/null
+++ b/core/lib/Drupal/Core/Entity/Sql/TemporaryTableMapping.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\Core\Entity\Sql;
+
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+
+/**
+ * Defines a temporary table mapping class.
+ */
+class TemporaryTableMapping extends DefaultTableMapping {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function generateFieldTableName(FieldStorageDefinitionInterface $storage_definition, $revision) {
+    return static::getTempTableName(parent::generateFieldTableName($storage_definition, $revision));
+  }
+
+  /**
+   * Generates a temporary table name.
+   *
+   * The method accounts for a maximum table name length of 64 characters.
+   *
+   * @param string $table_name
+   *   The initial table name.
+   * @param string $prefix
+   *   (optional) The prefix to use for the new table name. Defaults to 'tmp_'.
+   *
+   * @return string
+   *   The final table name.
+   */
+  public static function getTempTableName($table_name, $prefix = 'tmp_') {
+    $tmp_table_name = $prefix . $table_name;
+
+    // Limit the string to 48 characters, keeping a 16 characters margin for db
+    // prefixes.
+    if (strlen($table_name) > 48) {
+      $short_table_name = substr($table_name, 0, 34);
+      $table_hash = substr(hash('sha256', $table_name), 0, 10);
+
+      $tmp_table_name = $prefix . $short_table_name . $table_hash;
+    }
+    return $tmp_table_name;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Entity/entity.api.php b/core/lib/Drupal/Core/Entity/entity.api.php
index f9f4271e3b..5387c7ef7e 100644
--- a/core/lib/Drupal/Core/Entity/entity.api.php
+++ b/core/lib/Drupal/Core/Entity/entity.api.php
@@ -271,6 +271,11 @@
  *   either \Drupal\Core\Config\Entity\ConfigEntityBase or
  *   \Drupal\Core\Entity\ContentEntityBase, with annotation for
  *   \@ConfigEntityType or \@ContentEntityType in its documentation block.
+ *   If you are defining a content entity type, it is recommended to extend the
+ *   \Drupal\Core\Entity\EditorialContentEntityBase base class in order to get
+ *   out-of-the-box support for Entity API's revisioning and publishing
+ *   features, which will allow your entity type to be used with Drupal's
+ *   editorial workflow provided by the Content Moderation module.
  * - The 'id' annotation gives the entity type ID, and the 'label' annotation
  *   gives the human-readable name of the entity type. If you are defining a
  *   content entity type that uses bundles, the 'bundle_label' annotation gives
diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
index 38cb8950d0..f168a02cad 100644
--- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
@@ -80,6 +80,18 @@ protected function getHandledFormats() {
   }
 
   /**
+   * Handles a 4xx error for HTML.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
+   *   The event to process.
+   */
+  public function on4xx(GetResponseForExceptionEvent $event) {
+    if (($exception = $event->getException()) && $exception instanceof HttpExceptionInterface) {
+      $this->makeSubrequest($event, '/system/4xx', $exception->getStatusCode());
+    }
+  }
+
+  /**
    * Handles a 401 error for HTML.
    *
    * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php
deleted file mode 100644
index 4737e8031a..0000000000
--- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionSubscriber.php
+++ /dev/null
@@ -1,245 +0,0 @@
-<?php
-
-namespace Drupal\Core\EventSubscriber;
-
-use Drupal\Component\Utility\SafeMarkup;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\Core\Utility\Error;
-use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-use Symfony\Component\HttpFoundation\JsonResponse;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
-use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
-use Symfony\Component\HttpKernel\KernelEvents;
-
-/**
- * Last-chance handler for exceptions.
- *
- * This handler will catch any exceptions not caught elsewhere and report
- * them as an error page.
- */
-class DefaultExceptionSubscriber implements EventSubscriberInterface {
-  use StringTranslationTrait;
-
-  /**
-   * @var string
-   *
-   * One of the error level constants defined in bootstrap.inc.
-   */
-  protected $errorLevel;
-
-  /**
-   * The config factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
-  /**
-   * Constructs a new DefaultExceptionSubscriber.
-   *
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
-   */
-  public function __construct(ConfigFactoryInterface $config_factory) {
-    $this->configFactory = $config_factory;
-  }
-
-  /**
-   * Gets the configured error level.
-   *
-   * @return string
-   */
-  protected function getErrorLevel() {
-    if (!isset($this->errorLevel)) {
-      $this->errorLevel = $this->configFactory->get('system.logging')->get('error_level');
-    }
-    return $this->errorLevel;
-  }
-
-  /**
-   * Handles any exception as a generic error page for HTML.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
-   *   The event to process.
-   */
-  protected function onHtml(GetResponseForExceptionEvent $event) {
-    $exception = $event->getException();
-    $error = Error::decodeException($exception);
-
-    // Display the message if the current error reporting level allows this type
-    // of message to be displayed, and unconditionally in update.php.
-    $message = '';
-    if (error_displayable($error)) {
-      // If error type is 'User notice' then treat it as debug information
-      // instead of an error message.
-      // @see debug()
-      if ($error['%type'] == 'User notice') {
-        $error['%type'] = 'Debug';
-      }
-
-      // Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
-      // in the message. This does not happen for (false) security.
-      $root_length = strlen(DRUPAL_ROOT);
-      if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
-        $error['%file'] = substr($error['%file'], $root_length + 1);
-      }
-
-      unset($error['backtrace']);
-
-      if ($this->getErrorLevel() != ERROR_REPORTING_DISPLAY_VERBOSE) {
-        // Without verbose logging, use a simple message.
-
-        // We call SafeMarkup::format directly here, rather than use t() since
-        // we are in the middle of error handling, and we don't want t() to
-        // cause further errors.
-        $message = SafeMarkup::format('%type: @message in %function (line %line of %file).', $error);
-      }
-      else {
-        // With verbose logging, we will also include a backtrace.
-
-        $backtrace_exception = $exception;
-        while ($backtrace_exception->getPrevious()) {
-          $backtrace_exception = $backtrace_exception->getPrevious();
-        }
-        $backtrace = $backtrace_exception->getTrace();
-        // First trace is the error itself, already contained in the message.
-        // While the second trace is the error source and also contained in the
-        // message, the message doesn't contain argument values, so we output it
-        // once more in the backtrace.
-        array_shift($backtrace);
-
-        // Generate a backtrace containing only scalar argument values.
-        $error['@backtrace'] = Error::formatBacktrace($backtrace);
-        $message = SafeMarkup::format('%type: @message in %function (line %line of %file). <pre class="backtrace">@backtrace</pre>', $error);
-      }
-    }
-
-    $content = $this->t('The website encountered an unexpected error. Please try again later.');
-    $content .= $message ? '</br></br>' . $message : '';
-    $response = new Response($content, 500);
-
-    if ($exception instanceof HttpExceptionInterface) {
-      $response->setStatusCode($exception->getStatusCode());
-      $response->headers->add($exception->getHeaders());
-    }
-    else {
-      $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR, '500 Service unavailable (with message)');
-    }
-
-    $event->setResponse($response);
-  }
-
-  /**
-   * Handles any exception as a generic error page for JSON.
-   *
-   * @todo This should probably check the error reporting level.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
-   *   The event to process.
-   */
-  protected function onJson(GetResponseForExceptionEvent $event) {
-    $exception = $event->getException();
-    $error = Error::decodeException($exception);
-
-    // Display the message if the current error reporting level allows this type
-    // of message to be displayed,
-    $data = NULL;
-    if (error_displayable($error) && $message = $exception->getMessage()) {
-      $data = ['message' => sprintf('A fatal error occurred: %s', $message)];
-    }
-
-    $response = new JsonResponse($data, Response::HTTP_INTERNAL_SERVER_ERROR);
-    if ($exception instanceof HttpExceptionInterface) {
-      $response->setStatusCode($exception->getStatusCode());
-      $response->headers->add($exception->getHeaders());
-    }
-
-    $event->setResponse($response);
-  }
-
-  /**
-   * Handles an HttpExceptionInterface exception for unknown formats.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
-   *   The event to process.
-   */
-  protected function onFormatUnknown(GetResponseForExceptionEvent $event) {
-    /** @var \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface|\Exception $exception */
-    $exception = $event->getException();
-
-    $response = new Response($exception->getMessage(), $exception->getStatusCode(), $exception->getHeaders());
-    $event->setResponse($response);
-  }
-
-  /**
-   * Handles errors for this subscriber.
-   *
-   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
-   *   The event to process.
-   */
-  public function onException(GetResponseForExceptionEvent $event) {
-    $format = $this->getFormat($event->getRequest());
-    $exception = $event->getException();
-
-    $method = 'on' . $format;
-    if (!method_exists($this, $method)) {
-      if ($exception instanceof HttpExceptionInterface) {
-        $this->onFormatUnknown($event);
-        $response = $event->getResponse();
-        $response->headers->set('Content-Type', 'text/plain');
-      }
-      else {
-        $this->onHtml($event);
-      }
-    }
-    else {
-      $this->$method($event);
-    }
-  }
-
-  /**
-   * Gets the error-relevant format from the request.
-   *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object.
-   *
-   * @return string
-   *   The format as which to treat the exception.
-   */
-  protected function getFormat(Request $request) {
-    $format = $request->query->get(MainContentViewSubscriber::WRAPPER_FORMAT, $request->getRequestFormat());
-
-    // These are all JSON errors for our purposes. Any special handling for
-    // them can/should happen in earlier listeners if desired.
-    if (in_array($format, ['drupal_modal', 'drupal_dialog', 'drupal_ajax'])) {
-      $format = 'json';
-    }
-
-    // Make an educated guess that any Accept header type that includes "json"
-    // can probably handle a generic JSON response for errors. As above, for
-    // any format this doesn't catch or that wants custom handling should
-    // register its own exception listener.
-    foreach ($request->getAcceptableContentTypes() as $mime) {
-      if (strpos($mime, 'html') === FALSE && strpos($mime, 'json') !== FALSE) {
-        $format = 'json';
-      }
-    }
-
-    return $format;
-  }
-
-  /**
-   * Registers the methods in this class that should be listeners.
-   *
-   * @return array
-   *   An array of event listener definitions.
-   */
-  public static function getSubscribedEvents() {
-    $events[KernelEvents::EXCEPTION][] = ['onException', -256];
-    return $events;
-  }
-
-}
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
index 76cc55ee3a..6ccb743356 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionJsonSubscriber.php
@@ -14,7 +14,7 @@ class ExceptionJsonSubscriber extends HttpExceptionSubscriberBase {
    * {@inheritdoc}
    */
   protected function getHandledFormats() {
-    return ['json'];
+    return ['json', 'drupal_modal', 'drupal_dialog', 'drupal_ajax'];
   }
 
   /**
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php
new file mode 100644
index 0000000000..4317ff08cb
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php
@@ -0,0 +1,195 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Utility\Error;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Last-chance handler for exceptions: the final exception subscriber.
+ *
+ * This handler will catch any exceptions not caught elsewhere and report
+ * them as an error page.
+ *
+ * Each format has its own way of handling exceptions:
+ * - html: exception.default_html, exception.custom_page_html and
+ *   exception.fast_404_html
+ * - json: exception.default_json
+ *
+ * And when the serialization module is installed, all serialization formats are
+ * handled by a single exception subscriber:: serialization.exception.default.
+ *
+ * This exception subscriber runs after all the above (it has a lower priority),
+ * which makes it the last-chance exception handler. It always sends a plain
+ * text response. If it's a displayable error and the error level is configured
+ * to be verbose, then a helpful backtrace is also printed.
+ */
+class FinalExceptionSubscriber implements EventSubscriberInterface {
+  use StringTranslationTrait;
+
+  /**
+   * @var string
+   *
+   * One of the error level constants defined in bootstrap.inc.
+   */
+  protected $errorLevel;
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs a new FinalExceptionSubscriber.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration factory.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory) {
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * Gets the configured error level.
+   *
+   * @return string
+   */
+  protected function getErrorLevel() {
+    if (!isset($this->errorLevel)) {
+      $this->errorLevel = $this->configFactory->get('system.logging')->get('error_level');
+    }
+    return $this->errorLevel;
+  }
+
+  /**
+   * Handles exceptions for this subscriber.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
+   *   The event to process.
+   */
+  public function onException(GetResponseForExceptionEvent $event) {
+    $exception = $event->getException();
+    $error = Error::decodeException($exception);
+
+    // Display the message if the current error reporting level allows this type
+    // of message to be displayed, and unconditionally in update.php.
+    $message = '';
+    if ($this->isErrorDisplayable($error)) {
+      // If error type is 'User notice' then treat it as debug information
+      // instead of an error message.
+      // @see debug()
+      if ($error['%type'] == 'User notice') {
+        $error['%type'] = 'Debug';
+      }
+
+      $error = $this->simplifyFileInError($error);
+
+      unset($error['backtrace']);
+
+      if (!$this->isErrorLevelVerbose()) {
+        // Without verbose logging, use a simple message.
+
+        // We call SafeMarkup::format directly here, rather than use t() since
+        // we are in the middle of error handling, and we don't want t() to
+        // cause further errors.
+        $message = SafeMarkup::format('%type: @message in %function (line %line of %file).', $error);
+      }
+      else {
+        // With verbose logging, we will also include a backtrace.
+
+        $backtrace_exception = $exception;
+        while ($backtrace_exception->getPrevious()) {
+          $backtrace_exception = $backtrace_exception->getPrevious();
+        }
+        $backtrace = $backtrace_exception->getTrace();
+        // First trace is the error itself, already contained in the message.
+        // While the second trace is the error source and also contained in the
+        // message, the message doesn't contain argument values, so we output it
+        // once more in the backtrace.
+        array_shift($backtrace);
+
+        // Generate a backtrace containing only scalar argument values.
+        $error['@backtrace'] = Error::formatBacktrace($backtrace);
+        $message = SafeMarkup::format('%type: @message in %function (line %line of %file). <pre class="backtrace">@backtrace</pre>', $error);
+      }
+    }
+
+    $content = $this->t('The website encountered an unexpected error. Please try again later.');
+    $content .= $message ? '</br></br>' . $message : '';
+    $response = new Response($content, 500, ['Content-Type' => 'text/plain']);
+
+    if ($exception instanceof HttpExceptionInterface) {
+      $response->setStatusCode($exception->getStatusCode());
+      $response->headers->add($exception->getHeaders());
+    }
+    else {
+      $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR, '500 Service unavailable (with message)');
+    }
+
+    $event->setResponse($response);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    // Run as the final (very late) KernelEvents::EXCEPTION subscriber.
+    $events[KernelEvents::EXCEPTION][] = ['onException', -256];
+    return $events;
+  }
+
+  /**
+   * Checks whether the error level is verbose or not.
+   *
+   * @return bool
+   */
+  protected function isErrorLevelVerbose() {
+    return $this->getErrorLevel() === ERROR_REPORTING_DISPLAY_VERBOSE;
+  }
+
+  /**
+   * Wrapper for error_displayable().
+   *
+   * @param $error
+   *   Optional error to examine for ERROR_REPORTING_DISPLAY_SOME.
+   *
+   * @return bool
+   *
+   * @see \error_displayable
+   */
+  protected function isErrorDisplayable($error) {
+    return error_displayable($error);
+  }
+
+  /**
+   * Attempts to reduce error verbosity in the error message's file path.
+   *
+   * Attempts to reduce verbosity by removing DRUPAL_ROOT from the file path in
+   * the message. This does not happen for (false) security.
+   *
+   * @param $error
+   *   Optional error to examine for ERROR_REPORTING_DISPLAY_SOME.
+   *
+   * @return
+   *   The updated $error.
+   */
+  protected function simplifyFileInError($error) {
+    // Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
+    // in the message. This does not happen for (false) security.
+    $root_length = strlen(DRUPAL_ROOT);
+    if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
+      $error['%file'] = substr($error['%file'], $root_length + 1);
+    }
+    return $error;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
index 9ea7a83023..747262c849 100644
--- a/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/FinishResponseSubscriber.php
@@ -189,9 +189,9 @@ public function onRespond(FilterResponseEvent $event) {
    *
    * When neither Cache-Control nor any of the ETag, Last-Modified, Expires
    * headers are set on the response, ::get('Cache-Control') returns the value
-   * 'no-cache'. If any of ETag, Last-Modified or Expires are set but not
-   * Cache-Control, then 'private, must-revalidate' (in exactly this order) is
-   * returned.
+   * 'no-cache, private'. If any of ETag, Last-Modified or Expires are set but
+   * not Cache-Control, then 'private, must-revalidate' (in exactly this order)
+   * is returned.
    *
    * @see \Symfony\Component\HttpFoundation\ResponseHeaderBag::computeCacheControlValue()
    *
@@ -202,7 +202,7 @@ public function onRespond(FilterResponseEvent $event) {
    */
   protected function isCacheControlCustomized(Response $response) {
     $cache_control = $response->headers->get('Cache-Control');
-    return $cache_control != 'no-cache' && $cache_control != 'private, must-revalidate';
+    return $cache_control != 'no-cache, private' && $cache_control != 'private, must-revalidate';
   }
 
   /**
diff --git a/core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php b/core/lib/Drupal/Core/EventSubscriber/RenderArrayNonHtmlSubscriber.php
similarity index 66%
rename from core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php
rename to core/lib/Drupal/Core/EventSubscriber/RenderArrayNonHtmlSubscriber.php
index 61309c64d5..afb9ef5b03 100644
--- a/core/lib/Drupal/Core/EventSubscriber/AcceptNegotiation406.php
+++ b/core/lib/Drupal/Core/EventSubscriber/RenderArrayNonHtmlSubscriber.php
@@ -8,25 +8,23 @@
 use Symfony\Component\HttpKernel\KernelEvents;
 
 /**
- * View subscriber rendering a 406 if we could not route or render a request.
- *
- * @todo fix or replace this in https://www.drupal.org/node/2364011
+ * Throws 406 if requesting non-HTML format and controller returns render array.
  */
-class AcceptNegotiation406 implements EventSubscriberInterface {
+class RenderArrayNonHtmlSubscriber implements EventSubscriberInterface {
 
   /**
-   * Throws an HTTP 406 error if we get this far, which we normally shouldn't.
+   * Throws an HTTP 406 error if client requested a non-HTML format.
    *
    * @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
    *   The event to process.
    */
-  public function onViewDetect406(GetResponseForControllerResultEvent $event) {
+  public function onRespond(GetResponseForControllerResultEvent $event) {
     $request = $event->getRequest();
     $result = $event->getControllerResult();
 
     // If this is a render array then we assume that the router went with the
     // generic controller and not one with a format. If the format requested is
-    // not HTML though we can also assume that the requested format is invalid
+    // not HTML though, we can also assume that the requested format is invalid
     // so we provide a 406 response.
     if (is_array($result) && $request->getRequestFormat() !== 'html') {
       throw new NotAcceptableHttpException('Not acceptable format: ' . $request->getRequestFormat());
@@ -37,8 +35,7 @@ public function onViewDetect406(GetResponseForControllerResultEvent $event) {
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
-    $events[KernelEvents::VIEW][] = ['onViewDetect406', -10];
-
+    $events[KernelEvents::VIEW][] = ['onRespond', -10];
     return $events;
   }
 
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index 2fd75e190c..d54ff1fa1a 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -216,10 +216,16 @@ public function addTheme(Extension $theme) {
    * {@inheritdoc}
    */
   public function refreshInfo() {
-    $this->reset();
     $extension_config = $this->configFactory->get('core.extension');
     $installed = $extension_config->get('theme');
+    // Only refresh the info if a theme has been installed. Modules are
+    // installed before themes by the installer and this method is called during
+    // module installation.
+    if (empty($installed) && empty($this->list)) {
+      return;
+    }
 
+    $this->reset();
     // @todo Avoid re-scanning all themes by retaining the original (unaltered)
     //   theme info somewhere.
     $list = $this->rebuildThemeData();
diff --git a/core/lib/Drupal/Core/Field/Annotation/FieldType.php b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
index de42c80ffc..8bf54cb585 100644
--- a/core/lib/Drupal/Core/Field/Annotation/FieldType.php
+++ b/core/lib/Drupal/Core/Field/Annotation/FieldType.php
@@ -91,4 +91,13 @@ class FieldType extends DataType {
    */
   public $list_class;
 
+  /**
+   * An integer defining a fixed cardinality for this field type.
+   *
+   * If this value is not set, cardinality can be configured in the field UI.
+   *
+   * @var int|null
+   */
+  public $cardinality;
+
 }
diff --git a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
index c7bb23306d..37cc103875 100644
--- a/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
+++ b/core/lib/Drupal/Core/Field/BaseFieldDefinition.php
@@ -89,7 +89,6 @@ public static function createFromFieldStorageDefinition(FieldStorageDefinitionIn
       ->setLabel($definition->getLabel())
       ->setName($definition->getName())
       ->setProvider($definition->getProvider())
-      ->setQueryable($definition->isQueryable())
       ->setRevisionable($definition->isRevisionable())
       ->setSettings($definition->getSettings())
       ->setTargetEntityTypeId($definition->getTargetEntityTypeId())
@@ -287,7 +286,8 @@ public function isMultiple() {
    * {@inheritdoc}
    */
   public function isQueryable() {
-    return isset($this->definition['queryable']) ? $this->definition['queryable'] : !$this->isComputed();
+    @trigger_error('BaseFieldDefinition::isQueryable() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal\Core\Field\BaseFieldDefinition::hasCustomStorage(). See https://www.drupal.org/node/2856563.', E_USER_DEPRECATED);
+    return !$this->hasCustomStorage();
   }
 
   /**
@@ -298,8 +298,14 @@ public function isQueryable() {
    *
    * @return static
    *   The object itself for chaining.
+   *
+   * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use
+   *   \Drupal\Core\Field\BaseFieldDefinition::setCustomStorage() instead.
+   *
+   * @see https://www.drupal.org/node/2856563
    */
   public function setQueryable($queryable) {
+    @trigger_error('BaseFieldDefinition::setQueryable() is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal\Core\Field\BaseFieldDefinition::setCustomStorage(). See https://www.drupal.org/node/2856563.', E_USER_DEPRECATED);
     $this->definition['queryable'] = $queryable;
     return $this;
   }
@@ -579,7 +585,7 @@ protected function getFieldItemClass() {
   public function __sleep() {
     // Do not serialize the statically cached property definitions.
     $vars = get_object_vars($this);
-    unset($vars['propertyDefinitions']);
+    unset($vars['propertyDefinitions'], $vars['typedDataManager']);
     return array_keys($vars);
   }
 
diff --git a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
index 1b842b9ef5..d703659bdb 100644
--- a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
+++ b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php
@@ -109,6 +109,12 @@ public function isRevisionable();
    *
    * @return bool
    *   TRUE if the field is queryable.
+   *
+   * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use
+   *   \Drupal\Core\Field\FieldStorageDefinitionInterface::hasCustomStorage()
+   *   instead.
+   *
+   * @see https://www.drupal.org/node/2856563
    */
   public function isQueryable();
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
index 8c3ffd2119..a5d6f38e2b 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/TimestampItem.php
@@ -2,8 +2,9 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldType;
 
-use Drupal\Core\Field\FieldStorageDefinitionInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\TypedData\DataDefinition;
 
 /**
@@ -53,4 +54,14 @@ public static function schema(FieldStorageDefinitionInterface $field_definition)
     ];
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function generateSampleValue(FieldDefinitionInterface $field_definition) {
+    // Pick a random timestamp in the past year.
+    $timestamp = \Drupal::time()->getRequestTime() - mt_rand(0, 86400 * 365);
+    $values['value'] = $timestamp;
+    return $values;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php
index 776e060ca2..0872ba3b20 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldWidget/LanguageSelectWidget.php
@@ -27,7 +27,32 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $element['value'] = $element + [
       '#type' => 'language_select',
       '#default_value' => $items[$delta]->value,
-      '#languages' => LanguageInterface::STATE_ALL,
+      '#languages' => $this->getSetting('include_locked') ? LanguageInterface::STATE_ALL : LanguageInterface::STATE_CONFIGURABLE,
+    ];
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    $settings = parent::defaultSettings();
+    $settings['include_locked'] = TRUE;
+
+    return $settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $element = parent::settingsForm($form, $form_state);
+
+    $element['include_locked'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Include locked languages such as <em>Not specified</em> and <em>Not applicable</em>'),
+      '#default_value' => $this->getSetting('include_locked'),
     ];
 
     return $element;
diff --git a/core/lib/Drupal/Core/FileTransfer/FTPExtension.php b/core/lib/Drupal/Core/FileTransfer/FTPExtension.php
index c5f1b22b30..9f189638ad 100644
--- a/core/lib/Drupal/Core/FileTransfer/FTPExtension.php
+++ b/core/lib/Drupal/Core/FileTransfer/FTPExtension.php
@@ -45,7 +45,7 @@ protected function createDirectoryJailed($directory) {
   protected function removeDirectoryJailed($directory) {
     $pwd = ftp_pwd($this->connection);
     if (!ftp_chdir($this->connection, $directory)) {
-      throw new FileTransferException("Unable to change to directory @directory", NULL, ['@directory' => $directory]);
+      throw new FileTransferException("Unable to change the current directory to @directory", NULL, ['@directory' => $directory]);
     }
     $list = @ftp_nlist($this->connection, '.');
     if (!$list) {
@@ -65,7 +65,7 @@ protected function removeDirectoryJailed($directory) {
     }
     ftp_chdir($this->connection, $pwd);
     if (!ftp_rmdir($this->connection, $directory)) {
-      throw new FileTransferException("Unable to remove to directory @directory", NULL, ['@directory' => $directory]);
+      throw new FileTransferException("Unable to remove the directory @directory", NULL, ['@directory' => $directory]);
     }
   }
 
@@ -74,7 +74,7 @@ protected function removeDirectoryJailed($directory) {
    */
   protected function removeFileJailed($destination) {
     if (!ftp_delete($this->connection, $destination)) {
-      throw new FileTransferException("Unable to remove to file @file", NULL, ['@file' => $destination]);
+      throw new FileTransferException("Unable to remove the file @file", NULL, ['@file' => $destination]);
     }
   }
 
diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index 7398053bc6..8e976f5a86 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -229,8 +229,12 @@ protected function finalizeValidation(&$form, FormStateInterface &$form_state, $
    *   theming, and hook_form_alter functions.
    */
   protected function doValidateForm(&$elements, FormStateInterface &$form_state, $form_id = NULL) {
-    // Recurse through all children.
-    foreach (Element::children($elements) as $key) {
+    // Recurse through all children, sorting the elements so that the order of
+    // error messages displayed to the user matches the order of elements in
+    // the form. Use a copy of $elements so that it is not modified by the
+    // sorting itself.
+    $elements_sorted = $elements;
+    foreach (Element::children($elements_sorted, TRUE) as $key) {
       if (isset($elements[$key]) && $elements[$key]) {
         $this->doValidateForm($elements[$key], $form_state);
       }
diff --git a/core/lib/Drupal/Core/Layout/LayoutPluginManager.php b/core/lib/Drupal/Core/Layout/LayoutPluginManager.php
index e11f1055ba..0a2878572a 100644
--- a/core/lib/Drupal/Core/Layout/LayoutPluginManager.php
+++ b/core/lib/Drupal/Core/Layout/LayoutPluginManager.php
@@ -3,13 +3,13 @@
 namespace Drupal\Core\Layout;
 
 use Drupal\Component\Annotation\Plugin\Discovery\AnnotationBridgeDecorator;
-use Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator;
 use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
 use Drupal\Core\Plugin\Discovery\AnnotatedClassDiscovery;
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeDiscoveryDecorator;
 use Drupal\Core\Plugin\Discovery\YamlDiscoveryDecorator;
 use Drupal\Core\Layout\Annotation\Layout;
 
@@ -66,7 +66,7 @@ protected function getDiscovery() {
       $discovery = new AnnotatedClassDiscovery($this->subdir, $this->namespaces, $this->pluginDefinitionAnnotationName, $this->additionalAnnotationNamespaces);
       $discovery = new YamlDiscoveryDecorator($discovery, 'layouts', $this->moduleHandler->getModuleDirectories() + $this->themeHandler->getThemeDirectories());
       $discovery = new AnnotationBridgeDecorator($discovery, $this->pluginDefinitionAnnotationName);
-      $discovery = new DerivativeDiscoveryDecorator($discovery);
+      $discovery = new ContainerDerivativeDiscoveryDecorator($discovery);
       $this->discovery = $discovery;
     }
     return $this->discovery;
diff --git a/core/lib/Drupal/Core/Lock/DatabaseLockBackend.php b/core/lib/Drupal/Core/Lock/DatabaseLockBackend.php
index 91077e7ad3..0984ffcb1f 100644
--- a/core/lib/Drupal/Core/Lock/DatabaseLockBackend.php
+++ b/core/lib/Drupal/Core/Lock/DatabaseLockBackend.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\Core\Lock;
 
+use Drupal\Component\Utility\Crypt;
 use Drupal\Core\Database\Connection;
 use Drupal\Core\Database\IntegrityConstraintViolationException;
 use Drupal\Core\Database\SchemaObjectExistsException;
@@ -42,6 +43,8 @@ public function __construct(Connection $database) {
    * {@inheritdoc}
    */
   public function acquire($name, $timeout = 30.0) {
+    $name = $this->normalizeName($name);
+
     // Insure that the timeout is at least 1 ms.
     $timeout = max($timeout, 0.001);
     $expire = microtime(TRUE) + $timeout;
@@ -106,6 +109,8 @@ public function acquire($name, $timeout = 30.0) {
    * {@inheritdoc}
    */
   public function lockMayBeAvailable($name) {
+    $name = $this->normalizeName($name);
+
     try {
       $lock = $this->database->query('SELECT expire, value FROM {semaphore} WHERE name = :name', [':name' => $name])->fetchAssoc();
     }
@@ -136,6 +141,8 @@ public function lockMayBeAvailable($name) {
    * {@inheritdoc}
    */
   public function release($name) {
+    $name = $this->normalizeName($name);
+
     unset($this->locks[$name]);
     try {
       $this->database->delete('semaphore')
@@ -204,6 +211,33 @@ protected function catchException(\Exception $e) {
   }
 
   /**
+   * Normalizes a lock name in order to comply with database limitations.
+   *
+   * @param string $name
+   *   The passed in lock name.
+   *
+   * @return string
+   *   An ASCII-encoded lock name that is at most 255 characters long.
+   */
+  protected function normalizeName($name) {
+    // Nothing to do if the name is a US ASCII string of 255 characters or less.
+    $name_is_ascii = mb_check_encoding($name, 'ASCII');
+
+    if (strlen($name) <= 255 && $name_is_ascii) {
+      return $name;
+    }
+    // Return a string that uses as much as possible of the original name with
+    // the hash appended.
+    $hash = Crypt::hashBase64($name);
+
+    if (!$name_is_ascii) {
+      return $hash;
+    }
+
+    return substr($name, 0, 255 - strlen($hash)) . $hash;
+  }
+
+  /**
    * Defines the schema for the semaphore table.
    */
   public function schemaDefinition() {
diff --git a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
index 0b11f86883..c50f7b431a 100644
--- a/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
+++ b/core/lib/Drupal/Core/Menu/MenuTreeStorage.php
@@ -282,27 +282,44 @@ public function save(array $link) {
    *   depth.
    */
   protected function doSave(array $link) {
-    $original = $this->loadFull($link['id']);
-    // @todo Should we just return here if the link values match the original
-    //   values completely?
-    //   https://www.drupal.org/node/2302137
     $affected_menus = [];
 
+    // Get the existing definition if it exists. This does not use
+    // self::loadFull() to avoid the unserialization of fields with 'serialize'
+    // equal to TRUE as defined in self::schemaDefinition(). The makes $original
+    // easier to compare with the return value of self::preSave().
+    $query = $this->connection->select($this->table, $this->options);
+    $query->fields($this->table);
+    $query->condition('id', $link['id']);
+    $original = $this->safeExecuteSelect($query)->fetchAssoc();
+
+    if ($original) {
+      $link['mlid'] = $original['mlid'];
+      $link['has_children'] = $original['has_children'];
+      $affected_menus[$original['menu_name']] = $original['menu_name'];
+      $fields = $this->preSave($link, $original);
+      // If $link matches the $original data then exit early as there are no
+      // changes to make. Use array_diff_assoc() to check if they match because:
+      // - Some of the data types of the values are not the same. The values
+      //   in $original are all strings because they have come from database but
+      //   $fields contains typed values.
+      // - MenuTreeStorage::preSave() removes the 'mlid' from $fields.
+      // - The order of the keys in $original and $fields is different.
+      if (array_diff_assoc($fields, $original) == [] && array_diff_assoc($original, $fields) == ['mlid' => $link['mlid']]) {
+        return $affected_menus;
+      }
+    }
+
     $transaction = $this->connection->startTransaction();
     try {
-      if ($original) {
-        $link['mlid'] = $original['mlid'];
-        $link['has_children'] = $original['has_children'];
-        $affected_menus[$original['menu_name']] = $original['menu_name'];
-      }
-      else {
+      if (!$original) {
         // Generate a new mlid.
         $options = ['return' => Database::RETURN_INSERT_ID] + $this->options;
         $link['mlid'] = $this->connection->insert($this->table, $options)
           ->fields(['id' => $link['id'], 'menu_name' => $link['menu_name']])
           ->execute();
+        $fields = $this->preSave($link, []);
       }
-      $fields = $this->preSave($link, $original);
       // We may be moving the link to a new menu.
       $affected_menus[$fields['menu_name']] = $fields['menu_name'];
       $query = $this->connection->update($this->table, $this->options);
diff --git a/core/lib/Drupal/Core/PageCache/RequestPolicy/CommandLineOrUnsafeMethod.php b/core/lib/Drupal/Core/PageCache/RequestPolicy/CommandLineOrUnsafeMethod.php
index bbf85a33e9..27a1f7120d 100644
--- a/core/lib/Drupal/Core/PageCache/RequestPolicy/CommandLineOrUnsafeMethod.php
+++ b/core/lib/Drupal/Core/PageCache/RequestPolicy/CommandLineOrUnsafeMethod.php
@@ -18,7 +18,7 @@ class CommandLineOrUnsafeMethod implements RequestPolicyInterface {
    * {@inheritdoc}
    */
   public function check(Request $request) {
-    if ($this->isCli() || !$request->isMethodSafe()) {
+    if ($this->isCli() || !$request->isMethodCacheable()) {
       return static::DENY;
     }
   }
diff --git a/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php b/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php
index 519e93d639..e2bff29422 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultSingleLazyPluginCollection.php
@@ -52,10 +52,7 @@ class DefaultSingleLazyPluginCollection extends LazyPluginCollection {
    */
   public function __construct(PluginManagerInterface $manager, $instance_id, array $configuration) {
     $this->manager = $manager;
-    $this->instanceId = $instance_id;
-    // This is still needed by the parent LazyPluginCollection class.
-    $this->instanceIDs = [$instance_id => $instance_id];
-    $this->configuration = $configuration;
+    $this->addInstanceId($instance_id, $configuration);
   }
 
   /**
@@ -95,6 +92,8 @@ public function setConfiguration($configuration) {
    */
   public function addInstanceId($id, $configuration = NULL) {
     $this->instanceId = $id;
+    // Reset the list of instance IDs since there can be only one.
+    $this->instanceIDs = [];
     parent::addInstanceId($id, $configuration);
     if ($configuration !== NULL) {
       $this->setConfiguration($configuration);
diff --git a/core/lib/Drupal/Core/Render/Element/StatusMessages.php b/core/lib/Drupal/Core/Render/Element/StatusMessages.php
index d16c245a1d..530457fd90 100644
--- a/core/lib/Drupal/Core/Render/Element/StatusMessages.php
+++ b/core/lib/Drupal/Core/Render/Element/StatusMessages.php
@@ -73,17 +73,22 @@ public static function generatePlaceholder(array $element) {
    * @see drupal_get_messages()
    */
   public static function renderMessages($type) {
-    // Render the messages.
-    return [
-      '#theme' => 'status_messages',
-      // @todo Improve when https://www.drupal.org/node/2278383 lands.
-      '#message_list' => drupal_get_messages($type),
-      '#status_headings' => [
-        'status' => t('Status message'),
-        'error' => t('Error message'),
-        'warning' => t('Warning message'),
-      ],
-    ];
+    $render = [];
+    $messages = drupal_get_messages($type);
+    if ($messages) {
+      // Render the messages.
+      $render = [
+        '#theme' => 'status_messages',
+        // @todo Improve when https://www.drupal.org/node/2278383 lands.
+        '#message_list' => $messages,
+        '#status_headings' => [
+          'status' => t('Status message'),
+          'error' => t('Error message'),
+          'warning' => t('Warning message'),
+        ],
+      ];
+    }
+    return $render;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Render/PlaceholderingRenderCache.php b/core/lib/Drupal/Core/Render/PlaceholderingRenderCache.php
index 42562834b8..0422ecf5eb 100644
--- a/core/lib/Drupal/Core/Render/PlaceholderingRenderCache.php
+++ b/core/lib/Drupal/Core/Render/PlaceholderingRenderCache.php
@@ -93,7 +93,7 @@ public function __construct(RequestStack $request_stack, CacheFactoryInterface $
    */
   public function get(array $elements) {
     // @todo remove this check when https://www.drupal.org/node/2367555 lands.
-    if (!$this->requestStack->getCurrentRequest()->isMethodSafe()) {
+    if (!$this->requestStack->getCurrentRequest()->isMethodCacheable()) {
       return FALSE;
     }
 
@@ -127,7 +127,7 @@ public function set(array &$elements, array $pre_bubbling_elements) {
     $result = parent::set($elements, $pre_bubbling_elements);
 
     // @todo remove this check when https://www.drupal.org/node/2367555 lands.
-    if (!$this->requestStack->getCurrentRequest()->isMethodSafe()) {
+    if (!$this->requestStack->getCurrentRequest()->isMethodCacheable()) {
       return FALSE;
     }
 
diff --git a/core/lib/Drupal/Core/Render/RenderCache.php b/core/lib/Drupal/Core/Render/RenderCache.php
index 12d52e936b..9ac338124c 100644
--- a/core/lib/Drupal/Core/Render/RenderCache.php
+++ b/core/lib/Drupal/Core/Render/RenderCache.php
@@ -61,9 +61,9 @@ public function __construct(RequestStack $request_stack, CacheFactoryInterface $
   public function get(array $elements) {
     // Form submissions rely on the form being built during the POST request,
     // and render caching of forms prevents this from happening.
-    // @todo remove the isMethodSafe() check when
+    // @todo remove the isMethodCacheable() check when
     //       https://www.drupal.org/node/2367555 lands.
-    if (!$this->requestStack->getCurrentRequest()->isMethodSafe() || !$cid = $this->createCacheID($elements)) {
+    if (!$this->requestStack->getCurrentRequest()->isMethodCacheable() || !$cid = $this->createCacheID($elements)) {
       return FALSE;
     }
     $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'render';
@@ -88,9 +88,9 @@ public function get(array $elements) {
   public function set(array &$elements, array $pre_bubbling_elements) {
     // Form submissions rely on the form being built during the POST request,
     // and render caching of forms prevents this from happening.
-    // @todo remove the isMethodSafe() check when
+    // @todo remove the isMethodCacheable() check when
     //       https://www.drupal.org/node/2367555 lands.
-    if (!$this->requestStack->getCurrentRequest()->isMethodSafe() || !$cid = $this->createCacheID($elements)) {
+    if (!$this->requestStack->getCurrentRequest()->isMethodCacheable() || !$cid = $this->createCacheID($elements)) {
       return FALSE;
     }
 
diff --git a/core/lib/Drupal/Core/Render/Renderer.php b/core/lib/Drupal/Core/Render/Renderer.php
index 257349f973..287ffbb1e9 100644
--- a/core/lib/Drupal/Core/Render/Renderer.php
+++ b/core/lib/Drupal/Core/Render/Renderer.php
@@ -338,9 +338,9 @@ protected function doRender(&$elements, $is_root_call = FALSE) {
     // If instructed to create a placeholder, and a #lazy_builder callback is
     // present (without such a callback, it would be impossible to replace the
     // placeholder), replace the current element with a placeholder.
-    // @todo remove the isMethodSafe() check when
+    // @todo remove the isMethodCacheable() check when
     //       https://www.drupal.org/node/2367555 lands.
-    if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === TRUE && $this->requestStack->getCurrentRequest()->isMethodSafe()) {
+    if (isset($elements['#create_placeholder']) && $elements['#create_placeholder'] === TRUE && $this->requestStack->getCurrentRequest()->isMethodCacheable()) {
       if (!isset($elements['#lazy_builder'])) {
         throw new \LogicException('When #create_placeholder is set, a #lazy_builder callback must be present as well.');
       }
diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
index 0acdba468d..0002497e94 100644
--- a/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
+++ b/core/lib/Drupal/Core/TypedData/ComplexDataDefinitionBase.php
@@ -42,7 +42,7 @@ public function getMainPropertyName() {
   public function __sleep() {
     // Do not serialize the cached property definitions.
     $vars = get_object_vars($this);
-    unset($vars['propertyDefinitions']);
+    unset($vars['propertyDefinitions'], $vars['typedDataManager']);
     return array_keys($vars);
   }
 
diff --git a/core/lib/Drupal/Core/TypedData/DataDefinition.php b/core/lib/Drupal/Core/TypedData/DataDefinition.php
index 7eec1a90c4..52a4394cd7 100644
--- a/core/lib/Drupal/Core/TypedData/DataDefinition.php
+++ b/core/lib/Drupal/Core/TypedData/DataDefinition.php
@@ -7,6 +7,8 @@
  */
 class DataDefinition implements DataDefinitionInterface, \ArrayAccess {
 
+  use TypedDataTrait;
+
   /**
    * The array holding values for all definition keys.
    *
@@ -258,7 +260,7 @@ public function setSetting($setting_name, $value) {
    */
   public function getConstraints() {
     $constraints = isset($this->definition['constraints']) ? $this->definition['constraints'] : [];
-    $constraints += \Drupal::typedDataManager()->getDefaultConstraints($this);
+    $constraints += $this->getTypedDataManager()->getDefaultConstraints($this);
     return $constraints;
   }
 
@@ -340,4 +342,14 @@ public function toArray() {
     return $this->definition;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function __sleep() {
+    // Never serialize the typed data manager.
+    $vars = get_object_vars($this);
+    unset($vars['typedDataManager']);
+    return array_keys($vars);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index 8c4f265ebd..dbf0d5fec5 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -117,7 +117,13 @@ public function createDataDefinition($data_type) {
       throw new \InvalidArgumentException("Invalid data type '$data_type' has been given");
     }
     $class = $type_definition['definition_class'];
-    return $class::createFromDataType($data_type);
+    $data_definition = $class::createFromDataType($data_type);
+
+    if (method_exists($data_definition, 'setTypedDataManager')) {
+      $data_definition->setTypedDataManager($this);
+    }
+
+    return $data_definition;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php b/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php
index c72cd55d40..b691e715c8 100644
--- a/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php
+++ b/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php
@@ -21,7 +21,7 @@
 class ExecutionContext implements ExecutionContextInterface {
 
   /**
-   * @var \Symfony\Component\Validator\ValidatorInterface
+   * @var \Symfony\Component\Validator\Validator\ValidatorInterface
    */
   protected $validator;
 
diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UuidConstraint.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UuidConstraint.php
new file mode 100644
index 0000000000..bf2e223799
--- /dev/null
+++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/UuidConstraint.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\Core\Validation\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraints\Uuid;
+use Symfony\Component\Validator\Constraints\UuidValidator;
+
+/**
+ * Validates a UUID.
+ *
+ * @Constraint(
+ *   id = "Uuid",
+ *   label = @Translation("Universally Unique Identifier", context = "Validation"),
+ * )
+ */
+class UuidConstraint extends Uuid {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validatedBy() {
+    return UuidValidator::class;
+  }
+
+}
diff --git a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
index f967ebaff9..3d9f45cf3e 100644
--- a/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
+++ b/core/modules/big_pipe/src/Render/Placeholder/BigPipeStrategy.php
@@ -109,7 +109,7 @@ public function processPlaceholders(array $placeholders) {
     $request = $this->requestStack->getCurrentRequest();
 
     // @todo remove this check when https://www.drupal.org/node/2367555 lands.
-    if (!$request->isMethodSafe()) {
+    if (!$request->isMethodCacheable()) {
       return [];
     }
 
diff --git a/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php b/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php
index 46377800bc..7b5c33f7ec 100644
--- a/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php
+++ b/core/modules/big_pipe/src/Tests/BigPipePlaceholderTestCases.php
@@ -9,7 +9,6 @@
 
 use Drupal\big_pipe\Render\BigPipeMarkup;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
 use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -88,33 +87,14 @@ public static function cases(ContainerInterface $container = NULL, AccountInterf
     if ($container && $user) {
       $status_messages->embeddedAjaxResponseCommands = [
         [
-          'command' => 'settings',
-          'settings' => [
-            'ajaxPageState' => [
-              'theme' => 'classy',
-              'libraries' => 'big_pipe/big_pipe,classy/base,classy/messages,core/drupal.active-link,core/html5shiv,core/normalize,system/base',
-            ],
-            'pluralDelimiter' => PluralTranslatableMarkup::DELIMITER,
-            'user' => [
-              'uid' => '1',
-              'permissionsHash' => $container->get('user_permissions_hash_generator')->generate($user),
-            ],
-          ],
-          'merge' => TRUE,
-        ],
-        [
-          'command' => 'add_css',
-          'data' => '<link rel="stylesheet" href="' . base_path() . 'core/themes/classy/css/components/messages.css?' . $container->get('state')->get('system.css_js_query_string') . '" media="all" />' . "\n"
-        ],
-        [
           'command' => 'insert',
           'method' => 'replaceWith',
           'selector' => '[data-big-pipe-placeholder-id="callback=Drupal%5CCore%5CRender%5CElement%5CStatusMessages%3A%3ArenderMessages&args%5B0%5D&token=_HAdUpwWmet0TOTe2PSiJuMntExoshbm1kh2wQzzzAA"]',
-          'data' => "\n" . '    <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    ",
+          'data' => '    <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    ",
           'settings' => NULL,
         ],
       ];
-      $status_messages->embeddedHtmlResponse = '<link rel="stylesheet" href="' . base_path() . 'core/themes/classy/css/components/messages.css?' . $container->get('state')->get('system.css_js_query_string') . '" media="all" />' . "\n" . "\n" . '    <div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    \n";
+      $status_messages->embeddedHtmlResponse = '<div role="contentinfo" aria-label="Status message" class="messages messages--status">' . "\n" . '                  <h2 class="visually-hidden">Status message</h2>' . "\n" . '                    Hello from BigPipe!' . "\n" . '            </div>' . "\n    \n";
     }
 
 
diff --git a/core/modules/big_pipe/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php b/core/modules/big_pipe/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
index f0f40ba29d..9de09424b8 100644
--- a/core/modules/big_pipe/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
+++ b/core/modules/big_pipe/tests/src/Unit/Render/Placeholder/BigPipeStrategyTest.php
@@ -47,7 +47,7 @@ public function testProcessPlaceholders(array $placeholders, $method, $route_mat
     $big_pipe_strategy = new BigPipeStrategy($session_configuration->reveal(), $request_stack->reveal(), $route_match->reveal());
     $processed_placeholders = $big_pipe_strategy->processPlaceholders($placeholders);
 
-    if ($request->isMethodSafe() && !$route_match_has_no_big_pipe_option && $request_has_session) {
+    if ($request->isMethodCacheable() && !$route_match_has_no_big_pipe_option && $request_has_session) {
       $this->assertSameSize($expected_big_pipe_placeholders, $processed_placeholders, 'BigPipe is able to deliver all placeholders.');
       foreach (array_keys($placeholders) as $placeholder) {
         $this->assertSame($expected_big_pipe_placeholders[$placeholder], $processed_placeholders[$placeholder], "Verifying how BigPipeStrategy handles the placeholder '$placeholder'");
diff --git a/core/modules/block/src/BlockInterface.php b/core/modules/block/src/BlockInterface.php
index 85e5b06dd6..f4ce6268c2 100644
--- a/core/modules/block/src/BlockInterface.php
+++ b/core/modules/block/src/BlockInterface.php
@@ -15,6 +15,8 @@
    *
    * @deprecated in Drupal 8.3.x, will be removed before Drupal 9.0.0.
    *   Use \Drupal\Core\Block\BlockPluginInterface::BLOCK_LABEL_VISIBLE.
+   *
+   * @see https://www.drupal.org/node/2829775
    */
   const BLOCK_LABEL_VISIBLE = BlockPluginInterface::BLOCK_LABEL_VISIBLE;
 
diff --git a/core/modules/block/src/Tests/Views/DisplayBlockTest.php b/core/modules/block/src/Tests/Views/DisplayBlockTest.php
index 64f4851aa1..3d3584579a 100644
--- a/core/modules/block/src/Tests/Views/DisplayBlockTest.php
+++ b/core/modules/block/src/Tests/Views/DisplayBlockTest.php
@@ -286,7 +286,7 @@ public function testBlockEmptyRendering() {
 
     $this->drupalGet($url);
     $this->assertEqual(0, count($this->xpath('//div[contains(@class, "block-views-blocktest-view-block-block-1")]')));
-    // Ensure that the view cachability metadata is propagated even, for an
+    // Ensure that the view cacheability metadata is propagated even, for an
     // empty block.
     $this->assertCacheTags(array_merge($block->getCacheTags(), ['block_view', 'config:block_list', 'config:views.view.test_view_block' , 'http_response', 'rendered']));
     $this->assertCacheContexts(['url.query_args:_wrapper_format']);
diff --git a/core/modules/block_content/block_content.module b/core/modules/block_content/block_content.module
index e2abb6e6af..3adc979d9f 100644
--- a/core/modules/block_content/block_content.module
+++ b/core/modules/block_content/block_content.module
@@ -18,7 +18,7 @@ function block_content_help($route_name, RouteMatchInterface $route_match) {
       $field_ui = \Drupal::moduleHandler()->moduleExists('field_ui') ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#';
       $output = '';
       $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The Custom Block module allows you to create and manage custom <em>block types</em> and <em>content-containing blocks</em> from the <a href = ":block-library" >Custom block library</a> page. Custom block types have fields; see the <a href=":field-help">Field module help</a> for more information. Once created, custom blocks can be placed in regions just like blocks provided by other modules; see the <a href=":blocks">Block module help</a> page for details. For more information, see the <a href=":online-help">online documentation for the Custom Block module</a>.', [':block-library' => \Drupal::url('entity.block_content.collection'), ':block-content' => \Drupal::url('entity.block_content.collection'), ':field-help' => \Drupal::url('help.page', ['name' => 'field']), ':blocks' => \Drupal::url('help.page', ['name' => 'block']), ':online-help' => 'https://www.drupal.org/documentation/modules/block_content']) . '</p>';
+      $output .= '<p>' . t('The Custom Block module allows you to create and manage custom <em>block types</em> and <em>content-containing blocks</em> from the <a href=":block-library">Custom block library</a> page. Custom block types have fields; see the <a href=":field-help">Field module help</a> for more information. Once created, custom blocks can be placed in regions just like blocks provided by other modules; see the <a href=":blocks">Block module help</a> page for details. For more information, see the <a href=":online-help">online documentation for the Custom Block module</a>.', [':block-library' => \Drupal::url('entity.block_content.collection'), ':block-content' => \Drupal::url('entity.block_content.collection'), ':field-help' => \Drupal::url('help.page', ['name' => 'field']), ':blocks' => \Drupal::url('help.page', ['name' => 'block']), ':online-help' => 'https://www.drupal.org/documentation/modules/block_content']) . '</p>';
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('Creating and managing custom block types') . '</dt>';
diff --git a/core/modules/block_content/src/Entity/BlockContent.php b/core/modules/block_content/src/Entity/BlockContent.php
index 9d0bf743b2..76071df2f4 100644
--- a/core/modules/block_content/src/Entity/BlockContent.php
+++ b/core/modules/block_content/src/Entity/BlockContent.php
@@ -42,6 +42,7 @@
  *     "delete-form" = "/block/{block_content}/delete",
  *     "edit-form" = "/block/{block_content}",
  *     "collection" = "/admin/structure/block/block-content",
+ *     "create" = "/block",
  *   },
  *   translatable = TRUE,
  *   entity_keys = {
@@ -52,6 +53,11 @@
  *     "langcode" = "langcode",
  *     "uuid" = "uuid"
  *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log"
+ *   },
  *   bundle_entity_type = "block_content_type",
  *   field_ui_base_route = "entity.block_content_type.edit_form",
  *   render_cache = FALSE,
diff --git a/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php b/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
index e00de6b5a9..59f111b965 100644
--- a/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
+++ b/core/modules/block_content/tests/src/Functional/BlockContentCacheTagsTest.php
@@ -76,7 +76,7 @@ public function testBlock() {
     // Render the block.
     // @todo The request stack manipulation won't be necessary once
     //   https://www.drupal.org/node/2367555 is fixed and the
-    //   corresponding $request->isMethodSafe() checks are removed from
+    //   corresponding $request->isMethodCacheable() checks are removed from
     //   Drupal\Core\Render\Renderer.
     $request_stack = $this->container->get('request_stack');
     $request_stack->push(new Request());
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index ee26510729..48e2ae9a3c 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -332,18 +332,6 @@ function comment_form_field_ui_display_overview_form_alter(&$form, FormStateInte
 }
 
 /**
- * Implements hook_form_FORM_ID_alter() for 'field_storage_config_edit_form'.
- */
-function comment_form_field_storage_config_edit_form_alter(&$form, FormStateInterface $form_state) {
-  if ($form_state->getFormObject()->getEntity()->getType() == 'comment') {
-    // We only support posting one comment at the time so it doesn't make sense
-    // to let the site builder choose anything else.
-    $form['cardinality_container']['cardinality']['#default_value'] = 1;
-    $form['cardinality_container']['#access'] = FALSE;
-  }
-}
-
-/**
  * Implements hook_entity_storage_load().
  *
  * @see \Drupal\comment\Plugin\Field\FieldType\CommentItem::propertyDefinitions()
@@ -353,8 +341,7 @@ function comment_entity_storage_load($entities, $entity_type) {
   if (!\Drupal::entityManager()->getDefinition($entity_type)->entityClassImplements(FieldableEntityInterface::class)) {
     return;
   }
-  // @todo Investigate in https://www.drupal.org/node/2527866 why we need that.
-  if (!\Drupal::hasService('comment.manager') || !\Drupal::service('comment.manager')->getFields($entity_type)) {
+  if (!\Drupal::service('comment.manager')->getFields($entity_type)) {
     // Do not query database when entity has no comment fields.
     return;
   }
diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php
index a5f1966469..821b30d0ba 100644
--- a/core/modules/comment/src/Entity/Comment.php
+++ b/core/modules/comment/src/Entity/Comment.php
@@ -57,6 +57,7 @@
  *     "canonical" = "/comment/{comment}",
  *     "delete-form" = "/comment/{comment}/delete",
  *     "edit-form" = "/comment/{comment}/edit",
+ *     "create" = "/comment",
  *   },
  *   bundle_entity_type = "comment_type",
  *   field_ui_base_route  = "entity.comment_type.edit_form",
diff --git a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
index e3fd2b060e..3fd0cda57c 100644
--- a/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
+++ b/core/modules/comment/src/Plugin/Field/FieldType/CommentItem.php
@@ -21,7 +21,8 @@
  *   description = @Translation("This field manages configuration and presentation of comments on an entity."),
  *   list_class = "\Drupal\comment\CommentFieldItemList",
  *   default_widget = "comment_default",
- *   default_formatter = "comment_default"
+ *   default_formatter = "comment_default",
+ *   cardinality = 1,
  * )
  */
 class CommentItem extends FieldItemBase implements CommentItemInterface {
diff --git a/core/modules/comment/src/Plugin/views/argument/UserUid.php b/core/modules/comment/src/Plugin/views/argument/UserUid.php
index 69621559c4..7023102d83 100644
--- a/core/modules/comment/src/Plugin/views/argument/UserUid.php
+++ b/core/modules/comment/src/Plugin/views/argument/UserUid.php
@@ -3,6 +3,7 @@
 namespace Drupal\comment\Plugin\views\argument;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\Condition;
 use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -90,7 +91,7 @@ public function query($group_by = FALSE) {
       $subselect->where("c.entity_id = $this->tableAlias.$entity_id");
       $subselect->condition('c.entity_type', $entity_type);
 
-      $condition = db_or()
+      $condition = (new Condition('OR'))
         ->condition("$this->tableAlias.uid", $this->argument, '=')
         ->exists($subselect);
 
diff --git a/core/modules/comment/src/Plugin/views/filter/UserUid.php b/core/modules/comment/src/Plugin/views/filter/UserUid.php
index adee320d44..248b4609c3 100644
--- a/core/modules/comment/src/Plugin/views/filter/UserUid.php
+++ b/core/modules/comment/src/Plugin/views/filter/UserUid.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\comment\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\views\Plugin\views\filter\FilterPluginBase;
 
 /**
@@ -26,7 +27,7 @@ public function query() {
     $subselect->where("c.entity_id = $this->tableAlias.$entity_id");
     $subselect->condition('c.entity_type', $entity_type);
 
-    $condition = db_or()
+    $condition = (new Condition('OR'))
       ->condition("$this->tableAlias.uid", $this->value, $this->operator)
       ->exists($subselect);
 
diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
index c10e2686bd..ce894c2439 100644
--- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
+++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml
@@ -297,3 +297,41 @@ test.double_brackets.breed:
   mapping:
     breed:
       type: string
+
+config_schema_test.schema_sequence_sort:
+  type: config_object
+  mapping:
+    keyed_sort:
+      type: sequence
+      orderby: key
+      sequence:
+        - type: string
+    value_sort:
+      type: sequence
+      orderby: value
+      sequence:
+        - type: string
+    no_sort:
+      type: sequence
+      sequence:
+        - type: string
+    complex_sort_value:
+      type: sequence
+      orderby: value
+      sequence:
+        - type: mapping
+          mapping:
+            foo:
+              type: string
+            bar:
+              type: string
+    complex_sort_key:
+      type: sequence
+      orderby: key
+      sequence:
+        - type: mapping
+          mapping:
+            foo:
+              type: string
+            bar:
+              type: string
diff --git a/core/modules/config/tests/config_test/config/install/config_test.validation.yml b/core/modules/config/tests/config_test/config/install/config_test.validation.yml
new file mode 100644
index 0000000000..fa84ff392b
--- /dev/null
+++ b/core/modules/config/tests/config_test/config/install/config_test.validation.yml
@@ -0,0 +1,8 @@
+llama: llama
+cat:
+  type: kitten
+  count: 2
+giraffe:
+  hum1: hum1
+  hum2: hum2
+uuid: '7C30C50E-641A-4E34-A7F1-46BCFB9BE5A3'
diff --git a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
index e5b75d1430..c25a577976 100644
--- a/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
+++ b/core/modules/config/tests/config_test/config/schema/config_test.schema.yml
@@ -135,8 +135,7 @@ config_test.new:
        type: string
        label: 'Test setting'
      uuid:
-       type: string
-       label: 'UUID'
+      type: uuid
 
 config_test.old:
   type: config_test.new
@@ -158,3 +157,41 @@ config_test.foo:
 
 config_test.bar:
   type: config_test.foo
+
+config_test.validation:
+  type: config_object
+  label: 'Configuration type'
+  constraints:
+    Callback:
+      callback: [\Drupal\config_test\ConfigValidation, validateMapping]
+  mapping:
+    llama:
+      type: string
+      constraints:
+        Callback:
+          callback: [\Drupal\config_test\ConfigValidation, validateLlama]
+    cat:
+      type: mapping
+      mapping:
+        type:
+          type: string
+          constraints:
+            Callback:
+              callback: [\Drupal\config_test\ConfigValidation, validateCats]
+        count:
+          type: integer
+          constraints:
+            Callback:
+              callback: [\Drupal\config_test\ConfigValidation, validateCatCount]
+    giraffe:
+      type: sequence
+      constraints:
+        Callback:
+          callback: [\Drupal\config_test\ConfigValidation, validateSequence]
+      sequence:
+        type: string
+        constraints:
+          Callback:
+            callback: [\Drupal\config_test\ConfigValidation, validateGiraffes]
+    uuid:
+      type: uuid
diff --git a/core/modules/config/tests/config_test/src/ConfigValidation.php b/core/modules/config/tests/config_test/src/ConfigValidation.php
new file mode 100644
index 0000000000..9c6939432e
--- /dev/null
+++ b/core/modules/config/tests/config_test/src/ConfigValidation.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Drupal\config_test;
+
+use Symfony\Component\Validator\Context\ExecutionContextInterface;
+
+/**
+ * Provides a collection of validation callbacks for testing purposes.
+ */
+class ConfigValidation {
+
+  /**
+   * Validates a llama.
+   *
+   * @param string $string
+   *   The string to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateLlama($string, ExecutionContextInterface $context) {
+    if (!in_array($string, ['llama', 'alpaca', 'guanaco', 'vicuÃ±a'], TRUE)) {
+      $context->addViolation('no valid llama');
+    }
+  }
+
+  /**
+   * Validates cats.
+   *
+   * @param string $string
+   *   The string to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateCats($string, ExecutionContextInterface $context) {
+    if (!in_array($string, ['kitten', 'cats', 'nyans'])) {
+      $context->addViolation('no valid cat');
+    }
+  }
+
+  /**
+   * Validates a number.
+   *
+   * @param int $count
+   *   The integer to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateCatCount($count, ExecutionContextInterface $context) {
+    if ($count <= 1) {
+      $context->addViolation('no enough cats');
+    }
+  }
+
+  /**
+   * Validates giraffes.
+   *
+   * @param string $string
+   *   The string to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateGiraffes($string, ExecutionContextInterface $context) {
+    if (strpos($string, 'hum') !== 0) {
+      $context->addViolation('Giraffes just hum');
+    }
+  }
+
+  /**
+   * Validates a mapping.
+   *
+   * @param array $mapping
+   *   The data to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateMapping($mapping, ExecutionContextInterface $context) {
+    if ($diff = array_diff(array_keys($mapping), ['llama', 'cat', 'giraffe', 'uuid', '_core'])) {
+      $context->addViolation('Missing giraffe.');
+    }
+  }
+
+  /**
+   * Validates a sequence.
+   *
+   * @param array $sequence
+   *   The data to validate.
+   * @param \Symfony\Component\Validator\Context\ExecutionContextInterface $context
+   *   The validation execution context.
+   */
+  public static function validateSequence($sequence, ExecutionContextInterface $context) {
+    if (isset($sequence['invalid-key'])) {
+      $context->addViolation('Invalid giraffe key.');
+    }
+  }
+
+}
diff --git a/core/modules/content_moderation/content_moderation.module b/core/modules/content_moderation/content_moderation.module
index 77d822be28..8a7ec6eb38 100644
--- a/core/modules/content_moderation/content_moderation.module
+++ b/core/modules/content_moderation/content_moderation.module
@@ -13,12 +13,12 @@
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityPublishedInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\workflows\WorkflowInterface;
-use Drupal\node\NodeInterface;
 use Drupal\node\Plugin\Action\PublishNode;
 use Drupal\node\Plugin\Action\UnpublishNode;
 use Drupal\workflows\Entity\Workflow;
@@ -63,15 +63,6 @@ function content_moderation_entity_type_alter(array &$entity_types) {
 }
 
 /**
- * Implements hook_entity_operation().
- */
-function content_moderation_entity_operation(EntityInterface $entity) {
-  return \Drupal::service('class_resolver')
-    ->getInstanceFromDefinition(EntityTypeInfo::class)
-    ->entityOperation($entity);
-}
-
-/**
  * Implements hook_entity_presave().
  */
 function content_moderation_entity_presave(EntityInterface $entity) {
@@ -138,34 +129,34 @@ function content_moderation_entity_view(array &$build, EntityInterface $entity,
 }
 
 /**
- * Implements hook_node_access().
+ * Implements hook_entity_access().
  *
  * Nodes in particular should be viewable if unpublished and the user has
  * the appropriate permission. This permission is therefore effectively
  * mandatory for any user that wants to moderate things.
  */
-function content_moderation_node_access(NodeInterface $node, $operation, AccountInterface $account) {
+function content_moderation_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
   /** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
   $moderation_info = Drupal::service('content_moderation.moderation_information');
 
   $access_result = NULL;
   if ($operation === 'view') {
-    $access_result = (!$node->isPublished())
+    $access_result = (($entity instanceof EntityPublishedInterface) && !$entity->isPublished())
       ? AccessResult::allowedIfHasPermission($account, 'view any unpublished content')
       : AccessResult::neutral();
 
-    $access_result->addCacheableDependency($node);
+    $access_result->addCacheableDependency($entity);
   }
-  elseif ($operation === 'update' && $moderation_info->isModeratedEntity($node) && $node->moderation_state) {
+  elseif ($operation === 'update' && $moderation_info->isModeratedEntity($entity) && $entity->moderation_state) {
     /** @var \Drupal\content_moderation\StateTransitionValidation $transition_validation */
     $transition_validation = \Drupal::service('content_moderation.state_transition_validation');
 
-    $valid_transition_targets = $transition_validation->getValidTransitions($node, $account);
+    $valid_transition_targets = $transition_validation->getValidTransitions($entity, $account);
     $access_result = $valid_transition_targets ? AccessResult::neutral() : AccessResult::forbidden();
 
-    $access_result->addCacheableDependency($node);
+    $access_result->addCacheableDependency($entity);
     $access_result->addCacheableDependency($account);
-    $workflow = \Drupal::service('content_moderation.moderation_information')->getWorkflowForEntity($node);
+    $workflow = \Drupal::service('content_moderation.moderation_information')->getWorkflowForEntity($entity);
     $access_result->addCacheableDependency($workflow);
     foreach ($valid_transition_targets as $valid_transition_target) {
       $access_result->addCacheableDependency($valid_transition_target);
diff --git a/core/modules/content_moderation/content_moderation.permissions.yml b/core/modules/content_moderation/content_moderation.permissions.yml
index af28bbf1ad..0bc555d7de 100644
--- a/core/modules/content_moderation/content_moderation.permissions.yml
+++ b/core/modules/content_moderation/content_moderation.permissions.yml
@@ -6,11 +6,6 @@ view any unpublished content:
   title: 'View content moderation'
   description: 'View content moderation.'
 
-'administer content moderation':
-  title: 'Administer content moderation'
-  description: 'Administer workflows on content entities.'
-  'restrict access': TRUE
-
 view latest version:
   title: 'View the latest version'
   description: 'View the latest version of an entity. (Also requires "View any unpublished content" permission)'
diff --git a/core/modules/content_moderation/content_moderation.routing.yml b/core/modules/content_moderation/content_moderation.routing.yml
new file mode 100644
index 0000000000..a7167ca96b
--- /dev/null
+++ b/core/modules/content_moderation/content_moderation.routing.yml
@@ -0,0 +1,7 @@
+content_moderation.workflow_type_edit_form:
+  path: '/admin/config/workflow/workflows/manage/{workflow}/type/{entity_type_id}'
+  defaults:
+    _form: '\Drupal\content_moderation\Form\WorkflowTypeEditForm'
+    _title_callback: '\Drupal\content_moderation\Form\WorkflowTypeEditForm::getTitle'
+  requirements:
+    _permission: 'administer workflows'
diff --git a/core/modules/content_moderation/src/EntityTypeInfo.php b/core/modules/content_moderation/src/EntityTypeInfo.php
index f11e471685..29ac68d4f8 100644
--- a/core/modules/content_moderation/src/EntityTypeInfo.php
+++ b/core/modules/content_moderation/src/EntityTypeInfo.php
@@ -3,7 +3,6 @@
 namespace Drupal\content_moderation;
 
 use Drupal\content_moderation\Plugin\Field\ModerationStateFieldItemList;
-use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
 use Drupal\Core\Entity\BundleEntityFormBase;
 use Drupal\Core\Entity\ContentEntityFormInterface;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
@@ -17,13 +16,10 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslationInterface;
-use Drupal\Core\Url;
 use Drupal\content_moderation\Entity\Handler\BlockContentModerationHandler;
 use Drupal\content_moderation\Entity\Handler\ModerationHandler;
 use Drupal\content_moderation\Entity\Handler\NodeModerationHandler;
-use Drupal\content_moderation\Form\BundleModerationConfigurationForm;
 use Drupal\content_moderation\Routing\EntityModerationRouteProvider;
-use Drupal\content_moderation\Routing\EntityTypeModerationRouteProvider;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -65,6 +61,13 @@ class EntityTypeInfo implements ContainerInjectionInterface {
   protected $currentUser;
 
   /**
+   * The state transition validation service.
+   *
+   * @var \Drupal\content_moderation\StateTransitionValidationInterface
+   */
+  protected $validator;
+
+  /**
    * A keyed array of custom moderation handlers for given entity types.
    *
    * Any entity not specified will use a common default.
@@ -90,12 +93,13 @@ class EntityTypeInfo implements ContainerInjectionInterface {
    * @param \Drupal\Core\Session\AccountInterface $current_user
    *   Current user.
    */
-  public function __construct(TranslationInterface $translation, ModerationInformationInterface $moderation_information, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info, AccountInterface $current_user) {
+  public function __construct(TranslationInterface $translation, ModerationInformationInterface $moderation_information, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info, AccountInterface $current_user, StateTransitionValidationInterface $validator) {
     $this->stringTranslation = $translation;
     $this->moderationInfo = $moderation_information;
     $this->entityTypeManager = $entity_type_manager;
     $this->bundleInfo = $bundle_info;
     $this->currentUser = $current_user;
+    $this->validator = $validator;
   }
 
   /**
@@ -107,7 +111,8 @@ public static function create(ContainerInterface $container) {
       $container->get('content_moderation.moderation_information'),
       $container->get('entity_type.manager'),
       $container->get('entity_type.bundle.info'),
-      $container->get('current_user')
+      $container->get('current_user'),
+      $container->get('content_moderation.state_transition_validation')
     );
   }
 
@@ -127,11 +132,6 @@ public function entityTypeAlter(array &$entity_types) {
       // The ContentModerationState entity type should never be moderated.
       if ($entity_type->isRevisionable() && $entity_type_id != 'content_moderation_state') {
         $entity_types[$entity_type_id] = $this->addModerationToEntityType($entity_type);
-        // Add additional moderation support to entity types whose bundles are
-        // managed by a config entity type.
-        if ($entity_type->getBundleEntityType()) {
-          $entity_types[$entity_type->getBundleEntityType()] = $this->addModerationToBundleEntityType($entity_types[$entity_type->getBundleEntityType()]);
-        }
       }
     }
   }
@@ -170,67 +170,6 @@ protected function addModerationToEntityType(ContentEntityTypeInterface $type) {
   }
 
   /**
-   * Configures moderation configuration support on a entity type definition.
-   *
-   * That "configuration support" includes a configuration form, a hypermedia
-   * link, and a route provider to tie it all together. There's also a
-   * moderation handler for per-entity-type variation.
-   *
-   * @param \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $type
-   *   The config entity definition to modify.
-   *
-   * @return \Drupal\Core\Config\Entity\ConfigEntityTypeInterface
-   *   The modified config entity definition.
-   */
-  protected function addModerationToBundleEntityType(ConfigEntityTypeInterface $type) {
-    if ($type->hasLinkTemplate('edit-form') && !$type->hasLinkTemplate('moderation-form')) {
-      $type->setLinkTemplate('moderation-form', $type->getLinkTemplate('edit-form') . '/moderation');
-    }
-
-    if (!$type->getFormClass('moderation')) {
-      $type->setFormClass('moderation', BundleModerationConfigurationForm::class);
-    }
-
-    // @todo Core forgot to add a direct way to manipulate route_provider, so
-    // we have to do it the sloppy way for now.
-    $providers = $type->getRouteProviderClasses() ?: [];
-    if (empty($providers['moderation'])) {
-      $providers['moderation'] = EntityTypeModerationRouteProvider::class;
-      $type->setHandlerClass('route_provider', $providers);
-    }
-
-    return $type;
-  }
-
-  /**
-   * Adds an operation on bundles that should have a Moderation form.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity on which to define an operation.
-   *
-   * @return array
-   *   An array of operation definitions.
-   *
-   * @see hook_entity_operation()
-   */
-  public function entityOperation(EntityInterface $entity) {
-    $operations = [];
-    $type = $entity->getEntityType();
-    $bundle_of = $type->getBundleOf();
-    if ($this->currentUser->hasPermission('administer content moderation') && $bundle_of &&
-      $this->moderationInfo->canModerateEntitiesOfEntityType($this->entityTypeManager->getDefinition($bundle_of))
-    ) {
-      $operations['manage-moderation'] = [
-        'title' => t('Manage moderation'),
-        'weight' => 27,
-        'url' => Url::fromRoute("entity.{$type->id()}.moderation", [$entity->getEntityTypeId() => $entity->id()]),
-      ];
-    }
-
-    return $operations;
-  }
-
-  /**
    * Gets the "extra fields" for a bundle.
    *
    * This is a hook bridge.
@@ -353,12 +292,41 @@ public function formAlter(array &$form, FormStateInterface $form_state, $form_id
         $this->entityTypeManager->getHandler($type->getBundleOf(), 'moderation')->enforceRevisionsBundleFormAlter($form, $form_state, $form_id);
       }
     }
-    elseif ($form_object instanceof ContentEntityFormInterface) {
+    elseif ($form_object instanceof ContentEntityFormInterface && in_array($form_object->getOperation(), ['edit', 'default'])) {
       $entity = $form_object->getEntity();
       if ($this->moderationInfo->isModeratedEntity($entity)) {
         $this->entityTypeManager
           ->getHandler($entity->getEntityTypeId(), 'moderation')
           ->enforceRevisionsEntityFormAlter($form, $form_state, $form_id);
+
+        // Prevent saving and display error when:
+        // - The revision is not translation affected.
+        // - There are more than one translation languages.
+        // - The entity has forward revisions.
+        if (!$entity->isRevisionTranslationAffected() && count($entity->getTranslationLanguages()) > 1 && $this->moderationInfo->hasForwardRevision($entity)) {
+          $latest_revision = $this->getTranslationAffectedRevision($this->moderationInfo->getLatestRevision($entity->getEntityTypeId(), $entity->id()));
+          drupal_set_message(\Drupal::translation()->translate('It is not possible to save this @entity_type_label, <a href="@latest_revision_edit_url">publish</a> or <a href="@latest_revision_delete_url">delete</a> the latest draft revision to allow all workflow transitions.', ['@entity_type_label' => $entity->getEntityType()->getLabel(), '@latest_revision_edit_url' => $latest_revision->toUrl('edit-form', ['language' => $latest_revision->language()])->toString(), '@latest_revision_delete_url' => $latest_revision->toUrl('delete-form', ['language' => $latest_revision->language()])->toString()]), 'error');
+          $form['actions']['#access'] = FALSE;
+          $form['invalid_transitions'] = [
+            'rule' => [
+              '#type' => 'item',
+              '#markup' => '<hr/>',
+            ],
+            'label' => [
+              '#type' => 'item',
+              '#prefix' => '<strong class="label">',
+              '#markup' => \Drupal::translation()->translate('It is not possible to save this @entity_type_label.', ['@entity_type_label' => $entity->getEntityType()->getLabel()]),
+              '#suffix' => '</strong>',
+            ],
+            'message' => [
+              '#type' => 'item',
+              '#markup' => \Drupal::translation()->translate('<a href="@latest_revision_edit_url">Publish</a> or <a href="@latest_revision_delete_url">delete</a> the latest draft revision to allow all workflow transitions.', ['@latest_revision_edit_url' => $latest_revision->toUrl('edit-form', ['language' => $latest_revision->language()])->toString(), '@latest_revision_delete_url' => $latest_revision->toUrl('delete-form', ['language' => $latest_revision->language()])->toString()]),
+            ],
+            '#weight' => 999,
+            '#no_valid_transitions' => TRUE,
+          ];
+        }
+
         // Submit handler to redirect to the latest version, if available.
         $form['actions']['submit']['#submit'][] = [EntityTypeInfo::class, 'bundleFormRedirect'];
       }
@@ -366,6 +334,23 @@ public function formAlter(array &$form, FormStateInterface $form_state, $form_id
   }
 
   /**
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   * @return \Drupal\Core\Entity\EntityInterface
+   */
+  protected function getTranslationAffectedRevision(EntityInterface $entity) {
+    if ($entity->isRevisionTranslationAffected()) {
+      return $entity;
+    }
+    /** @var \Drupal\Core\Language\LanguageInterface $language */
+    foreach ($entity->getTranslationLanguages() as $language) {
+      $translation = $entity->getTranslation($language->getId());
+      if ($translation->isRevisionTranslationAffected()) {
+        return $translation;
+      }
+    }
+  }
+
+  /**
    * Redirect content entity edit forms on save, if there is a forward revision.
    *
    * When saving their changes, editors should see those changes displayed on
diff --git a/core/modules/content_moderation/src/Form/BundleModerationConfigurationForm.php b/core/modules/content_moderation/src/Form/BundleModerationConfigurationForm.php
deleted file mode 100644
index 917ec5deda..0000000000
--- a/core/modules/content_moderation/src/Form/BundleModerationConfigurationForm.php
+++ /dev/null
@@ -1,155 +0,0 @@
-<?php
-
-namespace Drupal\content_moderation\Form;
-
-use Drupal\content_moderation\Plugin\WorkflowType\ContentModeration;
-use Drupal\workflows\WorkflowInterface;
-use Drupal\Core\Entity\EntityForm;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Form for configuring moderation usage on a given entity bundle.
- */
-class BundleModerationConfigurationForm extends EntityForm {
-
-  /**
-   * Entity Type Manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
-    $this->entityTypeManager = $entity_type_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static($container->get('entity_type.manager'));
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * Blank out the base form ID so that form alters that use the base form ID to
-   * target both add and edit forms don't pick up this form.
-   */
-  public function getBaseFormId() {
-    return NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    /* @var \Drupal\Core\Config\Entity\ConfigEntityInterface $bundle */
-    $bundle = $this->getEntity();
-    $bundle_of_entity_type = $this->entityTypeManager->getDefinition($bundle->getEntityType()->getBundleOf());
-    /* @var \Drupal\workflows\WorkflowInterface[] $workflows */
-    $workflows = $this->entityTypeManager->getStorage('workflow')->loadMultiple();
-
-    $options = array_map(function (WorkflowInterface $workflow) {
-      return $workflow->label();
-    }, array_filter($workflows, function (WorkflowInterface $workflow) {
-      return $workflow->status() && $workflow->getTypePlugin() instanceof ContentModeration;
-    }));
-
-    $selected_workflow = array_reduce($workflows, function ($carry, WorkflowInterface $workflow) use ($bundle_of_entity_type, $bundle) {
-      $plugin = $workflow->getTypePlugin();
-      if ($plugin instanceof ContentModeration && $plugin->appliesToEntityTypeAndBundle($bundle_of_entity_type->id(), $bundle->id())) {
-        return $workflow->id();
-      }
-      return $carry;
-    });
-    $form['workflow'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Select the workflow to apply'),
-      '#default_value' => $selected_workflow,
-      '#options' => $options,
-      '#required' => FALSE,
-      '#empty_value' => '',
-    ];
-
-    $form['original_workflow'] = [
-      '#type' => 'value',
-      '#value' => $selected_workflow,
-    ];
-
-    $form['bundle'] = [
-      '#type' => 'value',
-      '#value' => $bundle->id(),
-    ];
-
-    $form['entity_type'] = [
-      '#type' => 'value',
-      '#value' => $bundle_of_entity_type->id(),
-    ];
-
-    // Add a special message when moderation is being disabled.
-    if ($selected_workflow) {
-      $form['enable_workflow_note'] = [
-        '#type' => 'item',
-        '#description' => $this->t('After disabling moderation, any existing forward drafts will be accessible via the "Revisions" tab.'),
-        '#access' => !empty($selected_workflow)
-      ];
-    }
-
-    return parent::form($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    // If moderation is enabled, revisions MUST be enabled as well. Otherwise we
-    // can't have forward revisions.
-    drupal_set_message($this->t('Your settings have been saved.'));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function save(array $form, FormStateInterface $form_state) {
-    $entity_type_id = $form_state->getValue('entity_type');
-    $bundle_id = $form_state->getValue('bundle');
-    $new_workflow_id = $form_state->getValue('workflow');
-    $original_workflow_id = $form_state->getValue('original_workflow');
-    if ($new_workflow_id === $original_workflow_id) {
-      // Nothing to do.
-      return;
-    }
-    if ($original_workflow_id) {
-      /* @var \Drupal\workflows\WorkflowInterface $workflow */
-      $workflow = $this->entityTypeManager->getStorage('workflow')->load($original_workflow_id);
-      $workflow->getTypePlugin()->removeEntityTypeAndBundle($entity_type_id, $bundle_id);
-      $workflow->save();
-    }
-    if ($new_workflow_id) {
-      /* @var \Drupal\workflows\WorkflowInterface $workflow */
-      $workflow = $this->entityTypeManager->getStorage('workflow')->load($new_workflow_id);
-      $workflow->getTypePlugin()->addEntityTypeAndBundle($entity_type_id, $bundle_id);
-      $workflow->save();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function actions(array $form, FormStateInterface $form_state) {
-    $actions['submit'] = [
-      '#type' => 'submit',
-      '#value' => $this->t('Save'),
-      '#submit' => ['::submitForm', '::save'],
-    ];
-
-    return $actions;
-  }
-
-}
diff --git a/core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php b/core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php
new file mode 100644
index 0000000000..b1fe98cfde
--- /dev/null
+++ b/core/modules/content_moderation/src/Form/WorkflowTypeEditForm.php
@@ -0,0 +1,201 @@
+<?php
+
+namespace Drupal\content_moderation\Form;
+
+use Drupal\Component\Plugin\Exception\PluginNotFoundException;
+use Drupal\content_moderation\ModerationInformationInterface;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\CloseDialogCommand;
+use Drupal\Core\Ajax\HtmlCommand;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\WorkflowInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+/**
+ * The form for editing entity types associated with a workflow.
+ */
+class WorkflowTypeEditForm extends FormBase {
+
+  /**
+   * The entity type manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The entity type bundle information service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $bundleInfo;
+
+  /**
+   * The moderation information service.
+   *
+   * @var \Drupal\content_moderation\ModerationInformationInterface
+   */
+  protected $moderationInformation;
+
+  /**
+   * The workflow entity object.
+   *
+   * @var \Drupal\workflows\WorkflowInterface
+   */
+  protected $workflow;
+
+  /**
+   * The entity type definition object.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeInterface
+   */
+  protected $entityType;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity_type.manager'),
+      $container->get('entity_type.bundle.info'),
+      $container->get('content_moderation.moderation_information')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $bundle_info , ModerationInformationInterface $moderation_information) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->bundleInfo = $bundle_info;
+    $this->moderationInformation = $moderation_information;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'workflow_type_edit_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, WorkflowInterface $workflow = NULL, $entity_type_id = NULL) {
+    $this->workflow = $workflow;
+    try {
+      $this->entityType = $this->entityTypeManager->getDefinition($entity_type_id);
+    }
+    catch (PluginNotFoundException $e) {
+      throw new NotFoundHttpException();
+    }
+
+    $options = $defaults = [];
+    foreach ($this->bundleInfo->getBundleInfo($this->entityType->id()) as $bundle_id => $bundle) {
+      // Check if moderation is enabled for this bundle on any workflow.
+      $moderation_enabled = $this->moderationInformation->shouldModerateEntitiesOfBundle($this->entityType, $bundle_id);
+      // Check if moderation is enabled for this bundle on this workflow.
+      $workflow_moderation_enabled = $this->workflow->getTypePlugin()->appliesToEntityTypeAndBundle($this->entityType->id(), $bundle_id);
+      // Only show bundles that are not enabled anywhere, or enabled on this
+      // workflow.
+      if (!$moderation_enabled || $workflow_moderation_enabled) {
+        // Add the bundle to the options if it's not enabled on a workflow,
+        // unless the workflow it's enabled on is this one.
+        $options[$bundle_id] = [
+          'type' => $bundle['label'],
+        ];
+        // Add the bundle to the list of default values if it's enabled on this
+        // workflow.
+        $defaults[$bundle_id] = $workflow_moderation_enabled;
+      }
+    }
+
+    if (!empty($options)) {
+      $bundles_header = $this->t('All @entity_type types', ['@entity_type' => $this->entityType->getLabel()]);
+      if ($bundle_entity_type_id = $this->entityType->getBundleEntityType()) {
+        $bundles_header = $this->t('All @entity_type_plural_label', ['@entity_type_plural_label' => $this->entityTypeManager->getDefinition($bundle_entity_type_id)->getPluralLabel()]);
+      }
+      $form['bundles'] = [
+        '#type' => 'tableselect',
+        '#header' => [
+          'type' => $bundles_header,
+        ],
+        '#options' => $options,
+        '#default_value' => $defaults,
+        '#attributes' => ['class' => ['no-highlight']],
+      ];
+    }
+
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#button_type' => 'primary',
+      '#value' => $this->t('Save'),
+      '#ajax' => [
+        'callback' => [$this, 'ajaxcallback'],
+      ],
+    ];
+    $form['actions']['cancel'] = [
+      '#type' => 'button',
+      '#value' => $this->t('Cancel'),
+      '#ajax' => [
+        'callback' => [$this, 'ajaxcallback'],
+      ],
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    foreach ($form_state->getValue('bundles') as $bundle_id => $checked) {
+      if ($checked) {
+        $this->workflow->getTypePlugin()->addEntityTypeAndBundle($this->entityType->id(), $bundle_id);
+      }
+      else {
+        $this->workflow->getTypePlugin()->removeEntityTypeAndBundle($this->entityType->id(), $bundle_id);
+      }
+    }
+    $this->workflow->save();
+  }
+
+  /**
+   * Ajax callback to close the modal and update the selected text.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   An ajax response object.
+   */
+  public function ajaxCallback() {
+    $selected_bundles = [];
+    foreach ($this->bundleInfo->getBundleInfo($this->entityType->id()) as $bundle_id => $bundle) {
+      if ($this->workflow->getTypePlugin()->appliesToEntityTypeAndBundle($this->entityType->id(), $bundle_id)) {
+        $selected_bundles[$bundle_id] = $bundle['label'];
+      }
+    }
+    $response = new AjaxResponse();
+    $response->addCommand(new CloseDialogCommand());
+    $response->addCommand(new HtmlCommand('#selected-' . $this->entityType->id(), !empty($selected_bundles) ? implode(', ', $selected_bundles) : $this->t('none')));
+    return $response;
+  }
+
+  /**
+   * Route title callback.
+   */
+  public function getTitle(WorkflowInterface $workflow = NULL, $entity_type_id) {
+    $this->entityType = $this->entityTypeManager->getDefinition($entity_type_id);
+
+    $title = $this->t('Select the @entity_type types for the @workflow', ['@entity_type' => $this->entityType->getLabel(), '@workflow' => $workflow->label()]);
+    if ($bundle_entity_type_id = $this->entityType->getBundleEntityType()) {
+      $title = $this->t('Select the @entity_type_plural_label for the @workflow', ['@entity_type_plural_label' => $this->entityTypeManager->getDefinition($bundle_entity_type_id)->getPluralLabel(), '@workflow' => $workflow->label()]);
+    }
+
+    return $title;
+  }
+
+}
diff --git a/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php b/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
index eac1913fca..786d45f23d 100644
--- a/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
+++ b/core/modules/content_moderation/src/ParamConverter/EntityRevisionConverter.php
@@ -92,13 +92,12 @@ public function convert($value, $definition, $name, array $defaults) {
       $entity_type_id = $this->getEntityTypeFromDefaults($definition, $name, $defaults);
       $latest_revision = $this->moderationInformation->getLatestRevision($entity_type_id, $value);
 
-      // If the entity type is translatable, ensure we return the proper
-      // translation object for the current context.
-      if ($latest_revision instanceof EntityInterface && $entity instanceof TranslatableInterface) {
-        $latest_revision = $this->entityManager->getTranslationFromContext($latest_revision, NULL, ['operation' => 'entity_upcast']);
-      }
-
-      if ($latest_revision instanceof EntityInterface && $latest_revision->isRevisionTranslationAffected()) {
+      if ($latest_revision instanceof EntityInterface) {
+        // If the entity type is translatable, ensure we return the proper
+        // translation object for the current context.
+        if ($entity instanceof TranslatableInterface) {
+          $latest_revision = $this->entityManager->getTranslationFromContext($latest_revision, NULL, ['operation' => 'entity_upcast']);
+        }
         $entity = $latest_revision;
       }
     }
diff --git a/core/modules/content_moderation/src/Plugin/Derivative/DynamicLocalTasks.php b/core/modules/content_moderation/src/Plugin/Derivative/DynamicLocalTasks.php
index 7ff1fa5da5..9f09a9a890 100644
--- a/core/modules/content_moderation/src/Plugin/Derivative/DynamicLocalTasks.php
+++ b/core/modules/content_moderation/src/Plugin/Derivative/DynamicLocalTasks.php
@@ -76,19 +76,6 @@ public static function create(ContainerInterface $container, $base_plugin_id) {
   public function getDerivativeDefinitions($base_plugin_definition) {
     $this->derivatives = [];
 
-    foreach ($this->entityTypeManager->getDefinitions() as $entity_type_id => $entity_type) {
-      if ($this->moderationInfo->canModerateEntitiesOfEntityType($entity_type)) {
-        $bundle_id = $entity_type->getBundleEntityType();
-        $this->derivatives["$bundle_id.moderation_tab"] = [
-          'route_name' => "entity.$bundle_id.moderation",
-          'title' => $this->t('Manage moderation'),
-          // @todo - are we sure they all have an edit_form?
-          'base_route' => "entity.$bundle_id.edit_form",
-          'weight' => 30,
-        ] + $base_plugin_definition;
-      }
-    }
-
     $latest_version_entities = array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $type) {
       return $this->moderationInfo->canModerateEntitiesOfEntityType($type) && $type->hasLinkTemplate('latest-version');
     });
diff --git a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
index ab5a561360..74e305209c 100644
--- a/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
+++ b/core/modules/content_moderation/src/Plugin/Field/FieldWidget/ModerationStateWidget.php
@@ -110,7 +110,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $entity = $items->getEntity();
 
     /* @var \Drupal\Core\Config\Entity\ConfigEntityInterface $bundle_entity */
-    $bundle_entity = $this->entityTypeManager->getStorage($entity->getEntityType()->getBundleEntityType())->load($entity->bundle());
     if (!$this->moderationInformation->isModeratedEntity($entity)) {
       // @todo https://www.drupal.org/node/2779933 write a test for this.
       return $element + ['#access' => FALSE];
@@ -118,9 +117,6 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
 
     $workflow = $this->moderationInformation->getWorkflowForEntity($entity);
     $default = $items->get($delta)->value ? $workflow->getState($items->get($delta)->value) : $workflow->getTypePlugin()->getInitialState($workflow, $entity);
-    if (!$default) {
-      throw new \UnexpectedValueException(sprintf('The %s bundle has an invalid moderation state configuration, moderation states are enabled but no default is set.', $bundle_entity->label()));
-    }
 
     /** @var \Drupal\workflows\Transition[] $transitions */
     $transitions = $this->validator->getValidTransitions($entity, $this->currentUser);
diff --git a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
index 51605d5383..4a416312ea 100644
--- a/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
+++ b/core/modules/content_moderation/src/Plugin/WorkflowType/ContentModeration.php
@@ -2,7 +2,10 @@
 
 namespace Drupal\content_moderation\Plugin\WorkflowType;
 
+use Drupal\Component\Serialization\Json;
+use Drupal\content_moderation\ModerationInformationInterface;
 use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\EntityPublishedInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -10,7 +13,8 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\content_moderation\ContentModerationState;
-use Drupal\workflows\Plugin\WorkflowTypeBase;
+use Drupal\Core\Url;
+use Drupal\workflows\Plugin\WorkflowTypeFormBase;
 use Drupal\workflows\StateInterface;
 use Drupal\workflows\WorkflowInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -27,7 +31,7 @@
  *   },
  * )
  */
-class ContentModeration extends WorkflowTypeBase implements ContainerFactoryPluginInterface {
+class ContentModeration extends WorkflowTypeFormBase implements ContainerFactoryPluginInterface {
 
   use StringTranslationTrait;
 
@@ -39,11 +43,38 @@ class ContentModeration extends WorkflowTypeBase implements ContainerFactoryPlug
   protected $entityTypeManager;
 
   /**
-   * Creates an instance of the ContentModeration WorkflowType plugin.
+   * The entity type bundle info service.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeBundleInfoInterface
+   */
+  protected $entityTypeBundleInfo;
+
+  /**
+   * The moderation information service.
+   *
+   * @var \Drupal\content_moderation\ModerationInformationInterface
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
+  protected $moderationInfo;
+
+  /**
+   * Constructs a ContentModeration object.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\content_moderation\ModerationInformationInterface $moderation_info
+   *   Moderation information service.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info, ModerationInformationInterface $moderation_info) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->entityTypeManager = $entity_type_manager;
+    $this->entityTypeBundleInfo = $entity_type_bundle_info;
+    $this->moderationInfo = $moderation_info;
   }
 
   /**
@@ -54,7 +85,9 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('entity_type.manager')
+      $container->get('entity_type.manager'),
+      $container->get('entity_type.bundle.info'),
+      $container->get('content_moderation.moderation_information')
     );
   }
 
@@ -173,6 +206,9 @@ public function appliesToEntityTypeAndBundle($entity_type_id, $bundle_id) {
    *   The bundle ID to remove.
    */
   public function removeEntityTypeAndBundle($entity_type_id, $bundle_id) {
+    if (!isset($this->configuration['entity_types'][$entity_type_id])) {
+      return;
+    }
     $key = array_search($bundle_id, $this->configuration['entity_types'][$entity_type_id], TRUE);
     if ($key !== FALSE) {
       unset($this->configuration['entity_types'][$entity_type_id][$key]);
@@ -204,7 +240,7 @@ public function addEntityTypeAndBundle($entity_type_id, $bundle_id) {
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function defaultConfiguration() {
     // This plugin does not store anything per transition.
@@ -300,4 +336,68 @@ public function getInitialState(WorkflowInterface $workflow, $entity = NULL) {
     return parent::getInitialState($workflow);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state, WorkflowInterface $workflow = NULL) {
+    $header = [
+      'type' => $this->t('Items'),
+      'operations' => $this->t('Operations')
+    ];
+    $form['entity_types_container'] = [
+      '#type' => 'details',
+      '#title' => $this->t('This workflow applies to:'),
+      '#open' => TRUE,
+    ];
+    $form['entity_types_container']['entity_types'] = [
+      '#type' => 'table',
+      '#header' => $header,
+      '#empty' => $this->t('There are no entity types.'),
+    ];
+
+    $entity_types = $this->entityTypeManager->getDefinitions();
+    foreach ($entity_types as $entity_type) {
+      if (!$this->moderationInfo->canModerateEntitiesOfEntityType($entity_type)) {
+        continue;
+      }
+
+      $selected_bundles = [];
+      foreach ($this->entityTypeBundleInfo->getBundleInfo($entity_type->id()) as $bundle_id => $bundle) {
+        if ($this->appliesToEntityTypeAndBundle($entity_type->id(), $bundle_id)) {
+          $selected_bundles[$bundle_id] = $bundle['label'];
+        }
+      }
+
+      $form['entity_types_container']['entity_types'][$entity_type->id()] = [
+        'type' => [
+          'label' => ['#markup' => '<strong>' . $this->t('@bundle types', ['@bundle' => $entity_type->getLabel()]) . '</strong>'],
+          'selected' => [
+            '#prefix' => '<br/><span id="selected-' . $entity_type->id() . '">',
+            '#markup' => !empty($selected_bundles) ? implode(', ', $selected_bundles) : $this->t('none'),
+            '#suffix' => '</span>',
+          ],
+        ],
+        'operations' => [
+          '#type' => 'operations',
+          '#links' => [
+            'select' => [
+              'title' => $this->t('Select'),
+              'url' => Url::fromRoute('content_moderation.workflow_type_edit_form', ['workflow' => $workflow->id(), 'entity_type_id' => $entity_type->id()]),
+              'attributes' => [
+                'aria-label' => $this->t('Select'),
+                'class' => ['use-ajax'],
+                'data-dialog-type' => 'modal',
+                'data-dialog-options' => Json::encode([
+                  'width' => 700,
+                ]),
+              ],
+            ],
+          ],
+        ],
+      ];
+    }
+
+    return $form;
+  }
+
 }
diff --git a/core/modules/content_moderation/src/Routing/EntityTypeModerationRouteProvider.php b/core/modules/content_moderation/src/Routing/EntityTypeModerationRouteProvider.php
deleted file mode 100644
index d1dcd2b11f..0000000000
--- a/core/modules/content_moderation/src/Routing/EntityTypeModerationRouteProvider.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Drupal\content_moderation\Routing;
-
-use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\Core\Entity\Routing\EntityRouteProviderInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\Routing\RouteCollection;
-
-/**
- * Provides the moderation configuration routes for config entities.
- */
-class EntityTypeModerationRouteProvider implements EntityRouteProviderInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRoutes(EntityTypeInterface $entity_type) {
-    $collection = new RouteCollection();
-
-    if ($moderation_route = $this->getModerationFormRoute($entity_type)) {
-      $entity_type_id = $entity_type->id();
-      $collection->add("entity.{$entity_type_id}.moderation", $moderation_route);
-    }
-
-    return $collection;
-  }
-
-  /**
-   * Gets the moderation-form route.
-   *
-   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
-   *   The entity type.
-   *
-   * @return \Symfony\Component\Routing\Route|null
-   *   The generated route, if available.
-   */
-  protected function getModerationFormRoute(EntityTypeInterface $entity_type) {
-    if ($entity_type->hasLinkTemplate('moderation-form') && $entity_type->getFormClass('moderation')) {
-      $entity_type_id = $entity_type->id();
-
-      $route = new Route($entity_type->getLinkTemplate('moderation-form'));
-
-      // @todo Come up with a new permission.
-      $route
-        ->setDefaults([
-          '_entity_form' => "{$entity_type_id}.moderation",
-          '_title' => 'Moderation',
-        ])
-        ->setRequirement('_permission', 'administer content moderation')
-        ->setOption('parameters', [
-          $entity_type_id => ['type' => 'entity:' . $entity_type_id],
-        ]);
-
-      return $route;
-    }
-  }
-
-}
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php
index 9cf92ba4dd..746fbee5dd 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationFormTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\content_moderation\Functional;
 
+use Drupal\workflows\Entity\Workflow;
+
 /**
  * Tests the moderation form, specifically on nodes.
  *
@@ -9,6 +11,19 @@
  */
 class ModerationFormTest extends ModerationStateTestBase {
 
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'node',
+    'content_moderation',
+    'locale',
+    'content_translation',
+  ];
+
   /**
    * {@inheritdoc}
    */
@@ -115,4 +130,217 @@ public function testModerationForm() {
     $this->assertResponse(403);
   }
 
+  /**
+   * Test moderation non-bundle entity type.
+   */
+  public function testNonBundleModerationForm() {
+    $this->drupalLogin($this->rootUser);
+    $workflow = Workflow::load('editorial');
+    $workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
+    $workflow->save();
+
+    // Create new moderated content in draft.
+    $this->drupalPostForm('entity_test_mulrevpub/add', [], t('Save and Create New Draft'));
+
+    // The latest version page should not show, because there is no forward
+    // revision.
+    $this->drupalGet('/entity_test_mulrevpub/manage/1/latest');
+    $this->assertResponse(403);
+
+    // Update the draft.
+    $this->drupalPostForm('entity_test_mulrevpub/manage/1/edit', [], t('Save and Create New Draft'));
+
+    // The latest version page should not show, because there is still no
+    // forward revision.
+    $this->drupalGet('/entity_test_mulrevpub/manage/1/latest');
+    $this->assertResponse(403);
+
+    // Publish the draft.
+    $this->drupalPostForm('entity_test_mulrevpub/manage/1/edit', [], t('Save and Publish'));
+
+    // The published view should not have a moderation form, because it is the
+    // default revision.
+    $this->drupalGet('entity_test_mulrevpub/manage/1');
+    $this->assertResponse(200);
+    $this->assertNoText('Status', 'The node view page has no moderation form.');
+
+    // The latest version page should not show, because there is still no
+    // forward revision.
+    $this->drupalGet('entity_test_mulrevpub/manage/1/latest');
+    $this->assertResponse(403);
+
+    // Make a forward revision.
+    $this->drupalPostForm('entity_test_mulrevpub/manage/1/edit', [], t('Save and Create New Draft'));
+
+    // The published view should not have a moderation form, because it is the
+    // default revision.
+    $this->drupalGet('entity_test_mulrevpub/manage/1');
+    $this->assertResponse(200);
+    $this->assertNoText('Status', 'The node view page has no moderation form.');
+
+    // The latest version page should show the moderation form and have "Draft"
+    // status, because the forward revision is in "Draft".
+    $this->drupalGet('entity_test_mulrevpub/manage/1/latest');
+    $this->assertResponse(200);
+    $this->assertText('Status', 'Form text found on the latest-version page.');
+    $this->assertText('Draft', 'Correct status found on the latest-version page.');
+
+    // Submit the moderation form to change status to published.
+    $this->drupalPostForm('entity_test_mulrevpub/manage/1/latest', [
+      'new_state' => 'published',
+    ], t('Apply'));
+
+    // The latest version page should not show, because there is no
+    // forward revision.
+    $this->drupalGet('entity_test_mulrevpub/manage/1/latest');
+    $this->assertResponse(403);
+  }
+
+  public function testContentTranslationNodeForm() {
+    $this->drupalLogin($this->rootUser);
+
+    // Add French language.
+    $edit = [
+      'predefined_langcode' => 'fr',
+    ];
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add language'));
+
+    // Enable content translation on articles.
+    $this->drupalGet('admin/config/regional/content-language');
+    $edit = [
+      'entity_types[node]' => TRUE,
+      'settings[node][moderated_content][translatable]' => TRUE,
+      'settings[node][moderated_content][settings][language][language_alterable]' => TRUE,
+    ];
+    $this->drupalPostForm(NULL, $edit, t('Save configuration'));
+
+    // Adding languages requires a container rebuild in the test running
+    // environment so that multilingual services are used.
+    $this->rebuildContainer();
+
+    // Create new moderated content in draft (revision 1).
+    $this->drupalPostForm('node/add/moderated_content', [
+      'title[0][value]' => 'Some moderated content',
+      'body[0][value]' => 'First version of the content.',
+    ], t('Save and Create New Draft'));
+
+    $node = $this->drupalGetNodeByTitle('Some moderated content');
+    $this->assertTrue($node->language(), 'en');
+    $edit_path = sprintf('node/%d/edit', $node->id());
+    $translate_path = sprintf('node/%d/translations/add/en/fr', $node->id());
+
+    // Add french translation (revision 2).
+    $this->drupalGet($translate_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Second version of the content.',
+    ], t('Save and Publish (this translation)'));
+
+    // Add french forward revision (revision 3).
+    $this->drupalGet('fr/' . $edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Third version of the content.',
+    ], t('Save and Create New Draft (this translation)'));
+
+    // It should not be possible to add a new english revision.
+    $this->drupalGet($edit_path);
+    $this->assertFalse($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->assertText('It is not possible to save this Content.');
+
+    // Publish the french forward revision (revision 4).
+    $this->drupalGet('fr/' . $edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Fifth version of the content.',
+    ], t('Save and Publish (this translation)'));
+
+    // Now we can publish the english (revision 5).
+    $this->drupalGet($edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Sixth version of the content.',
+    ], t('Save and Publish (this translation)'));
+
+    // Make sure we're allowed to create a forward french revision.
+    $this->drupalGet('fr/' . $edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+
+    // Add a english forward revision (revision 6).
+    $this->drupalGet($edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Seventh version of the content.',
+    ], t('Save and Create New Draft (this translation)'));
+
+    // Make sure we're not allowed to create a forward french revision.
+    $this->drupalGet('fr/' . $edit_path);
+    $this->assertFalse($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->assertText('It is not possible to save this Content.');
+
+    // We should be able to publish the english forward revision (revision 7)
+    $this->drupalGet($edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Eighth version of the content.',
+    ], t('Save and Publish (this translation)'));
+
+    // Make sure we're allowed to create a forward french revision.
+    $this->drupalGet('fr/' . $edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+
+    // Make sure we're allowed to create a forward english revision.
+    $this->drupalGet($edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+
+    // Create new moderated content in draft (revision 1).
+    $this->drupalPostForm('node/add/moderated_content', [
+      'title[0][value]' => 'Second moderated content',
+      'body[0][value]' => 'First version of the content.',
+    ], t('Save and Publish'));
+
+    $node = $this->drupalGetNodeByTitle('Second moderated content');
+    $this->assertTrue($node->language(), 'en');
+    $edit_path = sprintf('node/%d/edit', $node->id());
+    $translate_path = sprintf('node/%d/translations/add/en/fr', $node->id());
+
+    // Add a forward revision (revision 2).
+    $this->drupalGet($edit_path);
+    $this->assertTrue($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertTrue($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->drupalPostForm(NULL, [
+      'body[0][value]' => 'Second version of the content.',
+    ], t('Save and Create New Draft (this translation)'));
+
+    // It shouldn't be possible to translate as we have a forward revision.
+    $this->drupalGet($translate_path);
+    $this->assertFalse($this->xpath('//input[@value="Save and Create New Draft (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Publish (this translation)"]'));
+    $this->assertFalse($this->xpath('//input[@value="Save and Archive (this translation)"]'));
+    $this->assertText('It is not possible to save this Content.');
+  }
+
 }
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
index a9d95f0b9f..7b506136c2 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationLocaleTest.php
@@ -144,17 +144,12 @@ public function testTranslateModeratedContent() {
     $this->assertTrue($french_node->isPublished());
     $this->assertEqual($french_node->getTitle(), 'Translated node', 'The default revision of the published translation remains the same.');
 
-    // Publish the draft.
-    $edit = [
-      'new_state' => 'published',
-    ];
-    $this->drupalPostForm('fr/node/' . $english_node->id() . '/latest', $edit, t('Apply'));
-    $this->assertText(t('The moderation state has been updated.'));
+    // Publish the French article before testing the archive transition.
+    $this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', [], t('Save and Publish (this translation)'));
+    $this->assertText(t('Article New draft of translated node has been updated.'));
     $english_node = $this->drupalGetNodeByTitle('Another node', TRUE);
     $french_node = $english_node->getTranslation('fr');
     $this->assertEqual($french_node->moderation_state->value, 'published');
-    $this->assertTrue($french_node->isPublished());
-    $this->assertEqual($french_node->getTitle(), 'New draft of translated node', 'The draft has replaced the published revision.');
 
     // Publish the English article before testing the archive transition.
     $this->drupalPostForm('node/' . $english_node->id() . '/edit', [], t('Save and Publish (this translation)'));
@@ -173,43 +168,6 @@ public function testTranslateModeratedContent() {
     $this->assertFalse($english_node->isPublished());
     $this->assertEqual($french_node->moderation_state->value, 'archived');
     $this->assertFalse($french_node->isPublished());
-
-    // Create another article with its translation. This time publishing english
-    // after creating a forward french revision.
-    $edit = [
-      'title[0][value]' => 'An english node',
-    ];
-    $this->drupalPostForm('node/add/article', $edit, t('Save and Create New Draft'));
-    $this->assertText(t('Article An english node has been created.'));
-    $english_node = $this->drupalGetNodeByTitle('An english node');
-    $this->assertFalse($english_node->isPublished());
-
-    // Add a French translation.
-    $this->drupalGet('node/' . $english_node->id() . '/translations');
-    $this->clickLink(t('Add'));
-    $edit = [
-      'title[0][value]' => 'A french node',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save and Publish (this translation)'));
-    $english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
-    $french_node = $english_node->getTranslation('fr');
-    $this->assertTrue($french_node->isPublished());
-    $this->assertFalse($english_node->isPublished());
-
-    // Create a forward revision
-    $this->drupalPostForm('fr/node/' . $english_node->id() . '/edit', [], t('Save and Create New Draft (this translation)'));
-    $english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
-    $french_node = $english_node->getTranslation('fr');
-    $this->assertTrue($french_node->isPublished());
-    $this->assertFalse($english_node->isPublished());
-
-    // Publish the english node and the default french node not the latest
-    // french node should be used.
-    $this->drupalPostForm('/node/' . $english_node->id() . '/edit', [], t('Save and Publish (this translation)'));
-    $english_node = $this->drupalGetNodeByTitle('An english node', TRUE);
-    $french_node = $english_node->getTranslation('fr');
-    $this->assertTrue($french_node->isPublished());
-    $this->assertTrue($english_node->isPublished());
   }
 
 }
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php
new file mode 100644
index 0000000000..7dac15667f
--- /dev/null
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationRevisionRevertTest.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Drupal\Tests\content_moderation\Functional;
+
+use Drupal\simpletest\ContentTypeCreationTrait;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\workflows\Entity\Workflow;
+
+/**
+ * Test revision revert.
+ *
+ * @group content_moderation
+ */
+class ModerationRevisionRevertTest extends BrowserTestBase {
+
+  use ContentTypeCreationTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'content_moderation',
+    'node',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $moderated_bundle = $this->createContentType(['type' => 'moderated_bundle']);
+    $moderated_bundle->save();
+
+    $workflow = Workflow::load('editorial');
+    $workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'moderated_bundle');
+    $workflow->save();
+
+    $admin = $this->drupalCreateUser([
+      'access content overview',
+      'administer nodes',
+      'bypass node access',
+      'view all revisions',
+      'view content moderation',
+      'use editorial transition create_new_draft',
+      'use editorial transition publish',
+    ]);
+    $this->drupalLogin($admin);
+  }
+
+  /**
+   * Test that reverting a revision works.
+   */
+  public function testEditingAfterRevertRevision() {
+    // Create a draft.
+    $this->drupalPostForm('node/add/moderated_bundle', ['title[0][value]' => 'First draft node'], t('Save and Create New Draft'));
+
+    // Now make it published.
+    $this->drupalPostForm('node/1/edit', ['title[0][value]' => 'Published node'], t('Save and Publish'));
+
+    // Check the editing form that show the published title.
+    $this->drupalGet('node/1/edit');
+    $this->assertSession()
+      ->pageTextContains('Published node');
+
+    // Revert the first revision.
+    $revision_url = 'node/1/revisions/1/revert';
+    $this->drupalGet($revision_url);
+    $this->assertSession()->elementExists('css', '.form-submit');
+    $this->click('.form-submit');
+
+    // Check that it reverted.
+    $this->drupalGet('node/1/edit');
+    $this->assertSession()
+      ->pageTextContains('First draft node');
+    // Try to save the node.
+    $this->click('.moderation-state-draft > input');
+
+    // Check if the submission passed the EntityChangedConstraintValidator.
+    $this->assertSession()
+      ->pageTextNotContains('The content has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+
+    // Check the node has been saved.
+    $this->assertSession()
+      ->pageTextContains('moderated_bundle First draft node has been updated');
+  }
+
+}
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationStateAccessTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationStateAccessTest.php
index 7d2f74666e..868049944f 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationStateAccessTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationStateAccessTest.php
@@ -69,7 +69,6 @@ public function testViewShowsCorrectStates() {
     $permissions = [
       'access content',
       'view all revisions',
-      'administer content moderation',
     ];
     $admin1 = $this->drupalCreateUser($permissions);
     $this->drupalLogin($admin1);
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationStateBlockTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationStateBlockTest.php
index d45fb7b337..1a8f78c504 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationStateBlockTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationStateBlockTest.php
@@ -51,17 +51,9 @@ protected function setUp() {
   public function testCustomBlockModeration() {
     $this->drupalLogin($this->rootUser);
 
-    $this->drupalGet('admin/structure/block/block-content/types');
-    $this->assertLinkByHref('admin/structure/block/block-content/manage/basic/moderation');
-    $this->drupalGet('admin/structure/block/block-content/manage/basic');
-    $this->assertLinkByHref('admin/structure/block/block-content/manage/basic/moderation');
-    $this->drupalGet('admin/structure/block/block-content/manage/basic/moderation');
-
-    // Enable moderation for custom blocks at
-    // admin/structure/block/block-content/manage/basic/moderation.
-    $edit = ['workflow' => 'editorial'];
-    $this->drupalPostForm(NULL, $edit, t('Save'));
-    $this->assertText(t('Your settings have been saved.'));
+    // Enable moderation for custom blocks.
+    $edit['bundles[basic]'] = TRUE;
+    $this->drupalPostForm('admin/config/workflow/workflows/manage/editorial/type/block_content', $edit, t('Save'));
 
     // Create a custom block at block/add and save it as draft.
     $body = 'Body of moderated block';
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTest.php
index 7579afa4e6..74129a1980 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTest.php
@@ -52,9 +52,8 @@ public function testCreatingContent() {
     $this->assertText(t('The Moderated content moderated content has been deleted.'));
 
     // Disable content moderation.
-    $this->drupalPostForm('admin/structure/types/manage/moderated_content/moderation', ['workflow' => ''], t('Save'));
-    $this->drupalGet('admin/structure/types/manage/moderated_content/moderation');
-    $this->assertOptionSelected('edit-workflow', '');
+    $edit['bundles[moderated_content]'] = FALSE;
+    $this->drupalPostForm('admin/config/workflow/workflows/manage/editorial/type/node', $edit, t('Save'));;
     // Ensure the parent environment is up-to-date.
     // @see content_moderation_workflow_insert()
     \Drupal::service('entity_type.bundle.info')->clearCachedBundles();
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTypeTest.php b/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTypeTest.php
index 8391dd0aae..de4a7c29a2 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTypeTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationStateNodeTypeTest.php
@@ -30,7 +30,7 @@ public function testNotModerated() {
    */
   public function testEnablingOnExistingContent() {
     $editor_permissions = [
-      'administer content moderation',
+      'administer workflows',
       'access administration pages',
       'administer content types',
       'administer nodes',
@@ -56,17 +56,8 @@ public function testEnablingOnExistingContent() {
     ], t('Save and publish'));
     $this->assertText('Not moderated Test has been created.');
 
-    // Now enable moderation state, ensuring all the expected links and tabs are
-    // present.
-    $this->drupalGet('admin/structure/types');
-    $this->assertLinkByHref('admin/structure/types/manage/not_moderated/moderation');
-    $this->drupalGet('admin/structure/types/manage/not_moderated');
-    $this->assertLinkByHref('admin/structure/types/manage/not_moderated/moderation');
-    $this->drupalGet('admin/structure/types/manage/not_moderated/moderation');
-    $this->assertOptionSelected('edit-workflow', '');
-    $this->assertNoLink('Delete');
-    $edit['workflow'] = 'editorial';
-    $this->drupalPostForm(NULL, $edit, t('Save'));
+    // Now enable moderation state.
+    $this->enableModerationThroughUi('not_moderated');
 
     // And make sure it works.
     $nodes = \Drupal::entityTypeManager()->getStorage('node')
diff --git a/core/modules/content_moderation/tests/src/Functional/ModerationStateTestBase.php b/core/modules/content_moderation/tests/src/Functional/ModerationStateTestBase.php
index 1319ecae1e..8a3a2d0cea 100644
--- a/core/modules/content_moderation/tests/src/Functional/ModerationStateTestBase.php
+++ b/core/modules/content_moderation/tests/src/Functional/ModerationStateTestBase.php
@@ -29,7 +29,7 @@
    * @var array
    */
   protected $permissions = [
-    'administer content moderation',
+    'administer workflows',
     'access administration pages',
     'administer content types',
     'administer nodes',
@@ -50,6 +50,7 @@
     'block',
     'block_content',
     'node',
+    'entity_test',
   ];
 
   /**
@@ -112,9 +113,11 @@ protected function createContentTypeFromUi($content_type_name, $content_type_id,
    * @param string $workflow_id
    *   The workflow to attach to the bundle.
    */
-  protected function enableModerationThroughUi($content_type_id, $workflow_id = 'editorial') {
-    $edit['workflow'] = $workflow_id;
-    $this->drupalPostForm('admin/structure/types/manage/' . $content_type_id . '/moderation', $edit, t('Save'));
+  public function enableModerationThroughUi($content_type_id, $workflow_id = 'editorial') {
+    $this->drupalGet('/admin/config/workflow/workflows');
+    $this->assertLinkByHref('admin/config/workflow/workflows/manage/' . $workflow_id);
+    $edit['bundles[' . $content_type_id . ']'] = TRUE;
+    $this->drupalPostForm('admin/config/workflow/workflows/manage/' . $workflow_id . '/type/node', $edit, t('Save'));
     // Ensure the parent environment is up-to-date.
     // @see content_moderation_workflow_insert()
     \Drupal::service('entity_type.bundle.info')->clearCachedBundles();
diff --git a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
index f3c27146d4..00e847d3a7 100644
--- a/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
+++ b/core/modules/content_moderation/tests/src/Functional/NodeAccessTest.php
@@ -28,7 +28,7 @@ class NodeAccessTest extends ModerationStateTestBase {
    * @var array
    */
   protected $permissions = [
-    'administer content moderation',
+    'administer workflows',
     'access administration pages',
     'administer content types',
     'administer nodes',
diff --git a/core/modules/content_moderation/tests/src/Kernel/ContentModerationWorkflowTypeApiTest.php b/core/modules/content_moderation/tests/src/Kernel/ContentModerationWorkflowTypeApiTest.php
index c2ea8c576d..220ac5d5a6 100644
--- a/core/modules/content_moderation/tests/src/Kernel/ContentModerationWorkflowTypeApiTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/ContentModerationWorkflowTypeApiTest.php
@@ -101,4 +101,26 @@ public function testAddEntityTypeAndBundle() {
     );
   }
 
+  /**
+   * @covers ::addEntityTypeAndBundle
+   * @covers ::removeEntityTypeAndBundle
+   */
+  public function testRemoveEntityTypeAndBundle() {
+    /** @var \Drupal\content_moderation\Plugin\WorkflowType\ContentModeration $workflow_plugin */
+    $workflow_plugin = $this->workflow->getTypePlugin();
+
+    // There should be no bundles for fake_node to start with.
+    $this->assertEquals([], $workflow_plugin->getBundlesForEntityType('fake_node'));
+    // Removing a bundle which is not set on the workflow should not throw an
+    // error and should still result in none being returned.
+    $workflow_plugin->removeEntityTypeAndBundle('fake_node', 'fake_page');
+    $this->assertEquals([], $workflow_plugin->getBundlesForEntityType('fake_node'));
+    // Adding a bundle for fake_node should result it in being returned, but
+    // then removing it will return no bundles for fake_node.
+    $workflow_plugin->addEntityTypeAndBundle('fake_node', 'fake_page');
+    $this->assertEquals(['fake_page'], $workflow_plugin->getBundlesForEntityType('fake_node'));
+    $workflow_plugin->removeEntityTypeAndBundle('fake_node', 'fake_page');
+    $this->assertEquals([], $workflow_plugin->getBundlesForEntityType('fake_node'));
+  }
+
 }
diff --git a/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php b/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php
index 1c45721d03..a5791c8840 100644
--- a/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php
+++ b/core/modules/content_moderation/tests/src/Kernel/EntityTypeInfoTest.php
@@ -20,6 +20,7 @@ class EntityTypeInfoTest extends KernelTestBase {
    */
   public static $modules = [
     'content_moderation',
+    'workflows',
     'entity_test',
   ];
 
diff --git a/core/modules/content_moderation/tests/src/Unit/ContentPreprocessTest.php b/core/modules/content_moderation/tests/src/Unit/ContentPreprocessTest.php
index 5de0b2a977..8084716346 100644
--- a/core/modules/content_moderation/tests/src/Unit/ContentPreprocessTest.php
+++ b/core/modules/content_moderation/tests/src/Unit/ContentPreprocessTest.php
@@ -5,13 +5,14 @@
 use Drupal\content_moderation\ContentPreprocess;
 use Drupal\Core\Routing\CurrentRouteMatch;
 use Drupal\node\Entity\Node;
+use Drupal\Tests\UnitTestCase;
 
 /**
  * @coversDefaultClass \Drupal\content_moderation\ContentPreprocess
  *
  * @group content_moderation
  */
-class ContentPreprocessTest extends \PHPUnit_Framework_TestCase {
+class ContentPreprocessTest extends UnitTestCase {
 
   /**
    * @covers ::isLatestVersionPage
diff --git a/core/modules/content_moderation/tests/src/Unit/LatestRevisionCheckTest.php b/core/modules/content_moderation/tests/src/Unit/LatestRevisionCheckTest.php
index 1f8838b774..412a0eacea 100644
--- a/core/modules/content_moderation/tests/src/Unit/LatestRevisionCheckTest.php
+++ b/core/modules/content_moderation/tests/src/Unit/LatestRevisionCheckTest.php
@@ -9,13 +9,14 @@
 use Drupal\node\Entity\Node;
 use Drupal\content_moderation\Access\LatestRevisionCheck;
 use Drupal\content_moderation\ModerationInformation;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Component\Routing\Route;
 
 /**
  * @coversDefaultClass \Drupal\content_moderation\Access\LatestRevisionCheck
  * @group content_moderation
  */
-class LatestRevisionCheckTest extends \PHPUnit_Framework_TestCase {
+class LatestRevisionCheckTest extends UnitTestCase {
 
   /**
    * Test the access check of the LatestRevisionCheck service.
diff --git a/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php b/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php
index 8d319ef319..57fe761ce1 100644
--- a/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php
+++ b/core/modules/content_moderation/tests/src/Unit/ModerationInformationTest.php
@@ -10,13 +10,14 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\content_moderation\ModerationInformation;
+use Drupal\Tests\UnitTestCase;
 use Drupal\workflows\WorkflowInterface;
 
 /**
  * @coversDefaultClass \Drupal\content_moderation\ModerationInformation
  * @group content_moderation
  */
-class ModerationInformationTest extends \PHPUnit_Framework_TestCase {
+class ModerationInformationTest extends UnitTestCase {
 
   /**
    * Builds a mock user.
diff --git a/core/modules/content_moderation/tests/src/Unit/StateTransitionValidationTest.php b/core/modules/content_moderation/tests/src/Unit/StateTransitionValidationTest.php
index 2e03447787..b7c3942d83 100644
--- a/core/modules/content_moderation/tests/src/Unit/StateTransitionValidationTest.php
+++ b/core/modules/content_moderation/tests/src/Unit/StateTransitionValidationTest.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\content_moderation\StateTransitionValidation;
+use Drupal\Tests\UnitTestCase;
 use Drupal\workflows\Entity\Workflow;
 use Drupal\workflows\WorkflowTypeInterface;
 use Drupal\workflows\WorkflowTypeManager;
@@ -16,7 +17,7 @@
  * @coversDefaultClass \Drupal\content_moderation\StateTransitionValidation
  * @group content_moderation
  */
-class StateTransitionValidationTest extends \PHPUnit_Framework_TestCase {
+class StateTransitionValidationTest extends UnitTestCase {
 
   /**
    * Verifies user-aware transition validation.
@@ -62,6 +63,9 @@ protected function setUpModerationInformation(ContentEntityInterface $entity) {
     // mocked.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
diff --git a/core/modules/contextual/contextual.module b/core/modules/contextual/contextual.module
index cf20318cb1..a814c391f1 100644
--- a/core/modules/contextual/contextual.module
+++ b/core/modules/contextual/contextual.module
@@ -36,6 +36,7 @@ function contextual_toolbar() {
       '#attributes' => [
         'class' => ['toolbar-icon', 'toolbar-icon-edit'],
         'aria-pressed' => 'false',
+        'type' => 'button',
       ],
     ],
     '#wrapper_attributes' => [
diff --git a/core/modules/contextual/src/ContextualController.php b/core/modules/contextual/src/ContextualController.php
index b1fe245c04..0451a10e21 100644
--- a/core/modules/contextual/src/ContextualController.php
+++ b/core/modules/contextual/src/ContextualController.php
@@ -2,8 +2,9 @@
 
 namespace Drupal\contextual;
 
-use Symfony\Component\DependencyInjection\ContainerAwareInterface;
-use Symfony\Component\DependencyInjection\ContainerAwareTrait;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\Core\Render\RendererInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -11,9 +12,32 @@
 /**
  * Returns responses for Contextual module routes.
  */
-class ContextualController implements ContainerAwareInterface {
+class ContextualController implements ContainerInjectionInterface {
 
-  use ContainerAwareTrait;
+  /**
+   * The renderer.
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $render;
+
+  /**
+   * Constructors a new ContextualController
+   *
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *    The renderer.
+   */
+  public function __construct(RendererInterface $renderer) {
+    $this->renderer = $renderer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('renderer')
+    );
+  }
 
   /**
    * Returns the requested rendered contextual links.
@@ -38,7 +62,7 @@ public function render(Request $request) {
         '#type' => 'contextual_links',
         '#contextual_links' => _contextual_id_to_links($id),
       ];
-      $rendered[$id] = $this->container->get('renderer')->renderRoot($element);
+      $rendered[$id] = $this->renderer->renderRoot($element);
     }
 
     return new JsonResponse($rendered);
diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php
index 445b7ee706..984423d07f 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeCustomFormatter.php
@@ -32,30 +32,18 @@ public static function defaultSettings() {
    * {@inheritdoc}
    */
   public function viewElements(FieldItemListInterface $items, $langcode) {
+    // @todo Evaluate removing this method in
+    // https://www.drupal.org/node/2793143 to determine if the behavior and
+    // markup in the base class implementation can be used instead.
     $elements = [];
 
     foreach ($items as $delta => $item) {
-      $output = '';
       if (!empty($item->date)) {
         /** @var \Drupal\Core\Datetime\DrupalDateTime $date */
         $date = $item->date;
 
-        if ($this->getFieldSetting('datetime_type') == 'date') {
-          // A date without time will pick up the current time, use the default.
-          datetime_date_default_time($date);
-        }
-        $this->setTimeZone($date);
-
-        $output = $this->formatDate($date);
+        $elements[$delta] = $this->buildDate($date);
       }
-      $elements[$delta] = [
-        '#markup' => $output,
-        '#cache' => [
-          'contexts' => [
-            'timezone',
-          ],
-        ],
-      ];
     }
 
     return $elements;
diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php
index 7ddecec551..0b75b4e57a 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeDefaultFormatter.php
@@ -3,7 +3,6 @@
 namespace Drupal\datetime\Plugin\Field\FieldFormatter;
 
 use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
@@ -31,59 +30,6 @@ public static function defaultSettings() {
   /**
    * {@inheritdoc}
    */
-  public function viewElements(FieldItemListInterface $items, $langcode) {
-    $elements = [];
-
-    foreach ($items as $delta => $item) {
-      $output = '';
-      $iso_date = '';
-
-      if ($item->date) {
-        /** @var \Drupal\Core\Datetime\DrupalDateTime $date */
-        $date = $item->date;
-
-        if ($this->getFieldSetting('datetime_type') == 'date') {
-          // A date without time will pick up the current time, use the default.
-          datetime_date_default_time($date);
-        }
-
-        // Create the ISO date in Universal Time.
-        $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
-
-        $this->setTimeZone($date);
-
-        $output = $this->formatDate($date);
-      }
-
-      // Display the date using theme datetime.
-      $elements[$delta] = [
-        '#cache' => [
-          'contexts' => [
-            'timezone',
-          ],
-        ],
-        '#theme' => 'time',
-        '#text' => $output,
-        '#html' => FALSE,
-        '#attributes' => [
-          'datetime' => $iso_date,
-        ],
-      ];
-      if (!empty($item->_attributes)) {
-        $elements[$delta]['#attributes'] += $item->_attributes;
-        // Unset field item attributes since they have been included in the
-        // formatter output and should not be rendered in the field template.
-        unset($item->_attributes);
-      }
-    }
-
-    return $elements;
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   protected function formatDate($date) {
     $format_type = $this->getSetting('format_type');
     $timezone = $this->getSetting('timezone_override') ?: $date->getTimezone()->getName();
diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php
index f4e5ff5353..71b94670f4 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\FormatterBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -118,6 +119,30 @@ public function settingsSummary() {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+
+    foreach ($items as $delta => $item) {
+      if ($item->date) {
+        /** @var \Drupal\Core\Datetime\DrupalDateTime $date */
+        $date = $item->date;
+        $elements[$delta] = $this->buildDateWithIsoAttribute($date);
+
+        if (!empty($item->_attributes)) {
+          $elements[$delta]['#attributes'] += $item->_attributes;
+          // Unset field item attributes since they have been included in the
+          // formatter output and should not be rendered in the field template.
+          unset($item->_attributes);
+        }
+      }
+    }
+
+    return $elements;
+  }
+
+  /**
    * Creates a formatted date value as a string.
    *
    * @param object $date
@@ -167,4 +192,69 @@ protected function getFormatSettings() {
     return $settings;
   }
 
+  /**
+   * Creates a render array from a date object.
+   *
+   * @param \Drupal\Core\Datetime\DrupalDateTime $date
+   *   A date object.
+   *
+   * @return array
+   *   A render array.
+   */
+  protected function buildDate(DrupalDateTime $date) {
+    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
+      // A date without time will pick up the current time, use the default.
+      datetime_date_default_time($date);
+    }
+    $this->setTimeZone($date);
+
+    $build = [
+      '#markup' => $this->formatDate($date),
+      '#cache' => [
+        'contexts' => [
+          'timezone',
+        ],
+      ],
+    ];
+
+    return $build;
+  }
+
+  /**
+   * Creates a render array from a date object with ISO date attribute.
+   *
+   * @param \Drupal\Core\Datetime\DrupalDateTime $date
+   *   A date object.
+   *
+   * @return array
+   *   A render array.
+   */
+  protected function buildDateWithIsoAttribute(DrupalDateTime $date) {
+    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
+      // A date without time will pick up the current time, use the default.
+      datetime_date_default_time($date);
+    }
+
+    // Create the ISO date in Universal Time.
+    $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
+
+    $this->setTimeZone($date);
+
+    $build = [
+      '#theme' => 'time',
+      '#text' => $this->formatDate($date),
+      '#html' => FALSE,
+      '#attributes' => [
+        'datetime' => $iso_date,
+      ],
+      '#cache' => [
+        'contexts' => [
+          'timezone',
+        ],
+      ],
+    ];
+
+    return $build;
+  }
+
 }
diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php
index d35d3801da..7f0dee2c31 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimePlainFormatter.php
@@ -25,27 +25,12 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
     $elements = [];
 
     foreach ($items as $delta => $item) {
-      $output = '';
       if (!empty($item->date)) {
         /** @var \Drupal\Core\Datetime\DrupalDateTime $date */
         $date = $item->date;
 
-        if ($this->getFieldSetting('datetime_type') == 'date') {
-          // A date without time will pick up the current time, use the default.
-          datetime_date_default_time($date);
-        }
-        $this->setTimeZone($date);
-
-        $output = $this->formatDate($date);
+        $elements[$delta] = $this->buildDate($date);
       }
-      $elements[$delta] = [
-        '#cache' => [
-          'contexts' => [
-            'timezone',
-          ],
-        ],
-        '#markup' => $output,
-      ];
     }
 
     return $elements;
diff --git a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
index f5c06e6e5d..330782b0d6 100644
--- a/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
+++ b/core/modules/datetime/src/Plugin/Field/FieldType/DateTimeItem.php
@@ -17,7 +17,8 @@
  *   description = @Translation("Create and store date values."),
  *   default_widget = "datetime_default",
  *   default_formatter = "datetime_default",
- *   list_class = "\Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList"
+ *   list_class = "\Drupal\datetime\Plugin\Field\FieldType\DateTimeFieldItemList",
+ *   constraints = {"DateTimeFormat" = {}}
  * )
  */
 class DateTimeItem extends FieldItemBase {
diff --git a/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraint.php b/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraint.php
new file mode 100644
index 0000000000..5ed340d44a
--- /dev/null
+++ b/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraint.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\datetime\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Validation constraint for DateTime items to ensure the format is correct.
+ *
+ * @Constraint(
+ *   id = "DateTimeFormat",
+ *   label = @Translation("Datetime format valid for datetime type.", context = "Validation"),
+ * )
+ */
+class DateTimeFormatConstraint extends Constraint {
+
+  /**
+   * Message for when the value isn't a string.
+   *
+   * @var string
+   */
+  public $badType = "The datetime value must be a string.";
+
+  /**
+   * Message for when the value isn't in the proper format.
+   *
+   * @var string
+   */
+  public $badFormat = "The datetime value '@value' is invalid for the format '@format'";
+
+  /**
+   * Message for when the value did not parse properly.
+   *
+   * @var string
+   */
+  public $badValue = "The datetime value '@value' did not parse properly for the format '@format'";
+
+}
diff --git a/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraintValidator.php b/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraintValidator.php
new file mode 100644
index 0000000000..a027a82f09
--- /dev/null
+++ b/core/modules/datetime/src/Plugin/Validation/Constraint/DateTimeFormatConstraintValidator.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\datetime\Plugin\Validation\Constraint;
+
+use Drupal\Component\Datetime\DateTimePlus;
+use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Constraint validator for DateTime items to ensure the format is correct.
+ */
+class DateTimeFormatConstraintValidator extends ConstraintValidator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($item, Constraint $constraint) {
+    /* @var $item \Drupal\datetime\Plugin\Field\FieldType\DateTimeItem */
+    if (isset($item)) {
+      $value = $item->getValue()['value'];
+      if (!is_string($value)) {
+        $this->context->addViolation($constraint->badType);
+      }
+      else {
+        $datetime_type = $item->getFieldDefinition()->getSetting('datetime_type');
+        $format = $datetime_type === DateTimeItem::DATETIME_TYPE_DATE ? DATETIME_DATE_STORAGE_FORMAT : DATETIME_DATETIME_STORAGE_FORMAT;
+        $date = NULL;
+        try {
+          $date = DateTimePlus::createFromFormat($format, $value, new \DateTimeZone(DATETIME_STORAGE_TIMEZONE));
+        }
+        catch (\InvalidArgumentException $e) {
+          $this->context->addViolation($constraint->badFormat, [
+            '@value' => $value,
+            '@format' => $format,
+          ]);
+          return;
+        }
+        catch (\UnexpectedValueException $e) {
+          $this->context->addViolation($constraint->badValue, [
+            '@value' => $value,
+            '@format' => $format,
+          ]);
+          return;
+        }
+        if ($date === NULL || $date->hasErrors()) {
+          $this->context->addViolation($constraint->badFormat, [
+            '@value' => $value,
+            '@format' => $format,
+          ]);
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php
index 42f309d6d7..0f068ab9ee 100644
--- a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php
+++ b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\datetime\Tests\Views;
 
+@trigger_error('\Drupal\datetime\Tests\Views\DateTimeHandlerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\BrowserTestBase', E_USER_DEPRECATED);
+
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\node\Entity\NodeType;
@@ -11,6 +13,9 @@
 
 /**
  * Base class for testing datetime handlers.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\BrowserTestBase.
  */
 abstract class DateTimeHandlerTestBase extends HandlerTestBase {
 
diff --git a/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDateonlyTest.php b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDateonlyTest.php
new file mode 100644
index 0000000000..1051ce45ff
--- /dev/null
+++ b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDateonlyTest.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace Drupal\Tests\datetime\Functional\EntityResource\EntityTest;
+
+use Drupal\Core\Url;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\EntityTest\EntityTestResourceTestBase;
+use GuzzleHttp\RequestOptions;
+
+/**
+ * Tests the datetime field constraint with 'date' items.
+ *
+ * @group datetime
+ */
+class EntityTestDateonlyTest extends EntityTestResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * The ISO date string to use throughout the test.
+   *
+   * @var string
+   */
+  protected static $dateString = '2017-03-01';
+
+  /**
+   * Datetime test field name.
+   *
+   * @var string
+   */
+  protected static $fieldName = 'field_dateonly';
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['datetime', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Add datetime field.
+    FieldStorageConfig::create([
+      'field_name' => static::$fieldName,
+      'type' => 'datetime',
+      'entity_type' => static::$entityTypeId,
+      'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATE],
+    ])
+      ->save();
+
+    FieldConfig::create([
+      'field_name' => static::$fieldName,
+      'entity_type' => static::$entityTypeId,
+      'bundle' => $this->entity->bundle(),
+      'settings' => ['default_value' => static::$dateString],
+    ])
+      ->save();
+
+    // Reload entity so that it has the new field.
+    $this->entity = $this->entityStorage->load($this->entity->id());
+    $this->entity->set(static::$fieldName, ['value' => static::$dateString]);
+    $this->entity->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $entity_test = EntityTest::create([
+      'name' => 'Llama',
+      'type' => static::$entityTypeId,
+      static::$fieldName => static::$dateString,
+    ]);
+    $entity_test->setOwnerId(0);
+    $entity_test->save();
+
+    return $entity_test;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return parent::getExpectedNormalizedEntity() + [
+      static::$fieldName => [
+        [
+          'value' => $this->entity->get(static::$fieldName)->value,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return parent::getNormalizedPostEntity() + [
+      static::$fieldName => [
+        [
+          'value' => static::$dateString,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {
+    parent::assertNormalizationEdgeCases($method, $url, $request_options);
+
+    if ($this->entity->getEntityType()->hasKey('bundle')) {
+      $fieldName = static::$fieldName;
+
+      // DX: 422 when date type is incorrect.
+      $normalization = $this->getNormalizedPostEntity();
+      $normalization[static::$fieldName][0]['value'] = [
+        '2017', '03', '01',
+      ];
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value must be a string.\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+
+      // DX: 422 when date format is incorrect.
+      $normalization = $this->getNormalizedPostEntity();
+      $value = '2017-03-01T01:02:03';
+      $normalization[static::$fieldName][0]['value'] = $value;
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' is invalid for the format 'Y-m-d'\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+
+      // DX: 422 when value is not a valid date.
+      $normalization = $this->getNormalizedPostEntity();
+      $value = '2017-13-55';
+      $normalization[static::$fieldName][0]['value'] = $value;
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' did not parse properly for the format 'Y-m-d'\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+    }
+  }
+
+}
diff --git a/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php
new file mode 100644
index 0000000000..ffce48c340
--- /dev/null
+++ b/core/modules/datetime/tests/src/Functional/EntityResource/EntityTest/EntityTestDatetimeTest.php
@@ -0,0 +1,154 @@
+<?php
+
+namespace Drupal\Tests\datetime\Functional\EntityResource\EntityTest;
+
+use Drupal\Core\Url;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\EntityTest\EntityTestResourceTestBase;
+use GuzzleHttp\RequestOptions;
+
+/**
+ * Tests the datetime field constraint with 'datetime' items.
+ *
+ * @group datetime
+ */
+class EntityTestDatetimeTest extends EntityTestResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * The ISO date string to use throughout the test.
+   *
+   * @var string
+   */
+  protected static $dateString = '2017-03-01T20:02:00';
+
+  /**
+   * Datetime test field name.
+   *
+   * @var string
+   */
+  protected static $fieldName = 'field_datetime';
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['datetime', 'entity_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    // Add datetime field.
+    FieldStorageConfig::create([
+      'field_name' => static::$fieldName,
+      'type' => 'datetime',
+      'entity_type' => static::$entityTypeId,
+      'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME],
+    ])
+      ->save();
+
+    FieldConfig::create([
+      'field_name' => static::$fieldName,
+      'entity_type' => static::$entityTypeId,
+      'bundle' => $this->entity->bundle(),
+      'settings' => ['default_value' => static::$dateString],
+    ])
+      ->save();
+
+    // Reload entity so that it has the new field.
+    $this->entity = $this->entityStorage->load($this->entity->id());
+    $this->entity->set(static::$fieldName, ['value' => static::$dateString]);
+    $this->entity->save();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $entity_test = EntityTest::create([
+      'name' => 'Llama',
+      'type' => static::$entityTypeId,
+      static::$fieldName => static::$dateString,
+    ]);
+    $entity_test->setOwnerId(0);
+    $entity_test->save();
+
+    return $entity_test;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return parent::getExpectedNormalizedEntity() + [
+      static::$fieldName => [
+        [
+          'value' => $this->entity->get(static::$fieldName)->value,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    return parent::getNormalizedPostEntity() + [
+      static::$fieldName => [
+        [
+          'value' => static::$dateString,
+        ],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function assertNormalizationEdgeCases($method, Url $url, array $request_options) {
+    parent::assertNormalizationEdgeCases($method, $url, $request_options);
+
+    if ($this->entity->getEntityType()->hasKey('bundle')) {
+      $fieldName = static::$fieldName;
+
+      // DX: 422 when date type is incorrect.
+      $normalization = $this->getNormalizedPostEntity();
+      $normalization[static::$fieldName][0]['value'] = [
+        '2017', '03', '01', '21', '53', '00',
+      ];
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value must be a string.\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+
+      // DX: 422 when date format is incorrect.
+      $normalization = $this->getNormalizedPostEntity();
+      $value = '2017-03-01';
+      $normalization[static::$fieldName][0]['value'] = $value;
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' is invalid for the format 'Y-m-d\\TH:i:s'\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+
+      // DX: 422 when date format is incorrect.
+      $normalization = $this->getNormalizedPostEntity();
+      $value = '2017-13-55T20:02:00';
+      $normalization[static::$fieldName][0]['value'] = $value;
+
+      $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
+      $response = $this->request($method, $url, $request_options);
+      $message = "Unprocessable Entity: validation failed.\n{$fieldName}.0: The datetime value '{$value}' did not parse properly for the format 'Y-m-d\\TH:i:s'\n{$fieldName}.0.value: This value should be of the correct primitive type.\n";
+      $this->assertResourceErrorResponse(422, $message, $response);
+    }
+  }
+
+}
diff --git a/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php b/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php
index e28667f072..98840078cb 100644
--- a/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php
+++ b/core/modules/datetime/tests/src/Kernel/DateTimeItemTest.php
@@ -80,16 +80,19 @@ public function testDateTime() {
     $this->assertTrue($entity->field_datetime[0] instanceof FieldItemInterface, 'Field item implements interface.');
     $this->assertEqual($entity->field_datetime->value, $value);
     $this->assertEqual($entity->field_datetime[0]->value, $value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Verify changing the date value.
     $new_value = '2016-11-04T00:21:00';
     $entity->field_datetime->value = $new_value;
     $this->assertEqual($entity->field_datetime->value, $new_value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Read changed entity and assert changed values.
     $this->entityValidateAndSave($entity);
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime->value, $new_value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test the generateSampleValue() method.
     $entity = EntityTest::create();
@@ -118,16 +121,19 @@ public function testDateOnly() {
     $this->assertTrue($entity->field_datetime[0] instanceof FieldItemInterface, 'Field item implements interface.');
     $this->assertEqual($entity->field_datetime->value, $value);
     $this->assertEqual($entity->field_datetime[0]->value, $value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Verify changing the date value.
     $new_value = '2016-11-04';
     $entity->field_datetime->value = $new_value;
     $this->assertEqual($entity->field_datetime->value, $new_value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Read changed entity and assert changed values.
     $this->entityValidateAndSave($entity);
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime->value, $new_value);
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test the generateSampleValue() method.
     $entity = EntityTest::create();
@@ -152,6 +158,7 @@ public function testSetValue() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, 'DateTimeItem::setValue() works with string value.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test DateTimeItem::setValue() using property array.
     $entity = EntityTest::create();
@@ -162,6 +169,7 @@ public function testSetValue() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, 'DateTimeItem::setValue() works with array value.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test a date-only field.
     $this->fieldStorage->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
@@ -176,6 +184,7 @@ public function testSetValue() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, 'DateTimeItem::setValue() works with string value.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test DateTimeItem::setValue() using property array.
     $entity = EntityTest::create();
@@ -186,6 +195,7 @@ public function testSetValue() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, 'DateTimeItem::setValue() works with array value.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
   }
 
   /**
@@ -205,6 +215,7 @@ public function testSetValueProperty() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, '"Value" property can be set directly.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
 
     // Test Date::setValue() with a date-only field.
     // Test a date+time field.
@@ -219,6 +230,107 @@ public function testSetValueProperty() {
     $id = $entity->id();
     $entity = EntityTest::load($id);
     $this->assertEqual($entity->field_datetime[0]->value, $value, '"Value" property can be set directly.');
+    $this->assertEquals(DATETIME_STORAGE_TIMEZONE, $entity->field_datetime->date->getTimeZone()->getName());
+  }
+
+  /**
+   * Tests the constraint validations for fields with date and time.
+   *
+   * @dataProvider datetimeValidationProvider
+   */
+  public function testDatetimeValidation($value) {
+    $this->setExpectedException(\PHPUnit_Framework_AssertionFailedError::class);
+
+    $this->fieldStorage->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATETIME);
+    $this->fieldStorage->save();
+    $entity = EntityTest::create();
+
+    $entity->set('field_datetime', $value);
+    $this->entityValidateAndSave($entity);
+  }
+
+  /**
+   * Provider for testDatetimeValidation().
+   */
+  public function datetimeValidationProvider() {
+    return [
+      // Valid ISO 8601 dates, but unsupported by DateTimeItem.
+      ['2014-01-01T20:00:00Z'],
+      ['2014-01-01T20:00:00+04:00'],
+      ['2014-01-01T20:00:00+0400'],
+      ['2014-01-01T20:00:00+04'],
+      ['2014-01-01T20:00:00.123'],
+      ['2014-01-01T200000'],
+      ['2014-01-01T2000'],
+      ['2014-01-01T20'],
+      ['20140101T20:00:00'],
+      ['2014-01T20:00:00'],
+      ['2014-001T20:00:00'],
+      ['2014001T20:00:00'],
+      // Valid date strings, but unsupported by DateTimeItem.
+      ['2016-11-03 20:52:00'],
+      ['Thu, 03 Nov 2014 20:52:00 -0400'],
+      ['Thursday, November 3, 2016 - 20:52'],
+      ['Thu, 11/03/2016 - 20:52'],
+      ['11/03/2016 - 20:52'],
+      // Invalid date strings.
+      ['YYYY-01-01T20:00:00'],
+      ['2014-MM-01T20:00:00'],
+      ['2014-01-DDT20:00:00'],
+      ['2014-01-01Thh:00:00'],
+      ['2014-01-01T20:mm:00'],
+      ['2014-01-01T20:00:ss'],
+      // Invalid dates.
+      ['2014-13-13T20:00:00'],
+      ['2014-01-55T20:00:00'],
+      ['2014-01-01T25:00:00'],
+      ['2014-01-01T00:70:00'],
+      ['2014-01-01T00:00:70'],
+      // Proper format for different field setting.
+      ['2014-01-01'],
+      // Wrong input type.
+      [['2014', '01', '01', '00', '00', '00']],
+    ];
+  }
+
+  /**
+   * Tests the constraint validations for fields with date only.
+   *
+   * @dataProvider dateonlyValidationProvider
+   */
+  public function testDateonlyValidation($value) {
+    $this->setExpectedException(\PHPUnit_Framework_AssertionFailedError::class);
+
+    $this->fieldStorage->setSetting('datetime_type', DateTimeItem::DATETIME_TYPE_DATE);
+    $this->fieldStorage->save();
+    $entity = EntityTest::create();
+
+    $entity->set('field_datetime', $value);
+    $this->entityValidateAndSave($entity);
+  }
+
+  /**
+   * Provider for testDatetimeValidation().
+   */
+  public function dateonlyValidationProvider() {
+    return [
+      // Valid date strings, but unsupported by DateTimeItem.
+      ['Thu, 03 Nov 2014'],
+      ['Thursday, November 3, 2016'],
+      ['Thu, 11/03/2016'],
+      ['11/03/2016'],
+      // Invalid date strings.
+      ['YYYY-01-01'],
+      ['2014-MM-01'],
+      ['2014-01-DD'],
+      // Invalid dates.
+      ['2014-13-01'],
+      ['2014-01-55'],
+      // Proper format for different field setting.
+      ['2014-01-01T20:00:00'],
+      // Wrong input type.
+      [['2014', '01', '01']],
+    ];
   }
 
 }
diff --git a/core/modules/datetime/src/Tests/Views/ArgumentDateTimeTest.php b/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php
similarity index 94%
rename from core/modules/datetime/src/Tests/Views/ArgumentDateTimeTest.php
rename to core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php
index e3a17bb9c4..6145483958 100644
--- a/core/modules/datetime/src/Tests/Views/ArgumentDateTimeTest.php
+++ b/core/modules/datetime/tests/src/Kernel/Views/ArgumentDateTimeTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\datetime\Tests\Views;
+namespace Drupal\Tests\datetime\Kernel\Views;
 
+use Drupal\node\Entity\Node;
 use Drupal\views\Views;
 
 /**
@@ -19,8 +20,8 @@ class ArgumentDateTimeTest extends DateTimeHandlerTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Add some basic test nodes.
     $dates = [
@@ -29,11 +30,15 @@ protected function setUp() {
       '2002-01-01',
     ];
     foreach ($dates as $date) {
-      $this->nodes[] = $this->drupalCreateNode([
+      $node = Node::create([
+        'title' => $this->randomMachineName(8),
+        'type' => 'page',
         'field_date' => [
           'value' => $date,
         ]
       ]);
+      $node->save();
+      $this->nodes[] = $node;
     }
   }
 
diff --git a/core/modules/datetime/tests/src/Kernel/Views/DateTimeHandlerTestBase.php b/core/modules/datetime/tests/src/Kernel/Views/DateTimeHandlerTestBase.php
new file mode 100644
index 0000000000..f0c9c78614
--- /dev/null
+++ b/core/modules/datetime/tests/src/Kernel/Views/DateTimeHandlerTestBase.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\Tests\datetime\Kernel\Views;
+
+use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\node\Entity\NodeType;
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Tests\ViewTestData;
+use Drupal\field\Entity\FieldStorageConfig;
+
+/**
+ * Base class for testing datetime handlers.
+ */
+abstract class DateTimeHandlerTestBase extends ViewsKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['datetime_test', 'node', 'datetime', 'field'];
+
+  /**
+   * Name of the field.
+   *
+   * Note, this is used in the default test view.
+   *
+   * @var string
+   */
+  protected static $field_name = 'field_date';
+
+  /**
+   * Nodes to test.
+   *
+   * @var \Drupal\node\NodeInterface[]
+   */
+  protected $nodes = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('node');
+    $this->installEntitySchema('user');
+
+    // Add a date field to page nodes.
+    $node_type = NodeType::create([
+      'type' => 'page',
+      'name' => 'page'
+    ]);
+    $node_type->save();
+    $fieldStorage = FieldStorageConfig::create([
+      'field_name' => static::$field_name,
+      'entity_type' => 'node',
+      'type' => 'datetime',
+      'settings' => ['datetime_type' => DateTimeItem::DATETIME_TYPE_DATETIME],
+    ]);
+    $fieldStorage->save();
+    $field = FieldConfig::create([
+      'field_storage' => $fieldStorage,
+      'bundle' => 'page',
+      'required' => TRUE,
+    ]);
+    $field->save();
+
+    // Views needs to be aware of the new field.
+    $this->container->get('views.views_data')->clear();
+
+    // Set column map.
+    $this->map = [
+      'nid' => 'nid',
+    ];
+
+    // Load test views.
+    ViewTestData::createTestViews(get_class($this), ['datetime_test']);
+  }
+
+}
diff --git a/core/modules/datetime/src/Tests/Views/FilterDateTest.php b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTest.php
similarity index 90%
rename from core/modules/datetime/src/Tests/Views/FilterDateTest.php
rename to core/modules/datetime/tests/src/Kernel/Views/FilterDateTest.php
index 2a8d7cdb29..566285e256 100644
--- a/core/modules/datetime/src/Tests/Views/FilterDateTest.php
+++ b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTest.php
@@ -1,8 +1,10 @@
 <?php
 
-namespace Drupal\datetime\Tests\Views;
+namespace Drupal\Tests\datetime\Kernel\Views;
+
 use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
 use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\node\Entity\Node;
 use Drupal\views\Views;
 
 /**
@@ -27,8 +29,8 @@ class FilterDateTest extends DateTimeHandlerTestBase {
    *
    * Create nodes with relative dates of yesterday, today, and tomorrow.
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Set to 'today'.
     static::$date = REQUEST_TIME;
@@ -48,11 +50,15 @@ protected function setUp() {
     ];
 
     foreach ($dates as $date) {
-      $this->nodes[] = $this->drupalCreateNode([
+      $node = Node::create([
+        'title' => $this->randomMachineName(8),
+        'type' => 'page',
         'field_date' => [
           'value' => $date,
         ]
       ]);
+      $node->save();
+      $this->nodes[] = $node;
     }
   }
 
diff --git a/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php
similarity index 94%
rename from core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php
rename to core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php
index a15263d57d..1e8e929f33 100644
--- a/core/modules/datetime/src/Tests/Views/FilterDateTimeTest.php
+++ b/core/modules/datetime/tests/src/Kernel/Views/FilterDateTimeTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\datetime\Tests\Views;
+namespace Drupal\Tests\datetime\Kernel\Views;
 
+use Drupal\node\Entity\Node;
 use Drupal\views\Views;
 
 /**
@@ -29,8 +30,8 @@ class FilterDateTimeTest extends DateTimeHandlerTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     static::$date = REQUEST_TIME + 86400;
 
@@ -47,11 +48,15 @@ protected function setUp() {
       \Drupal::service('date.formatter')->format(static::$date, 'custom', DATETIME_DATETIME_STORAGE_FORMAT, DATETIME_STORAGE_TIMEZONE),
     ];
     foreach ($dates as $date) {
-      $this->nodes[] = $this->drupalCreateNode([
+      $node = Node::create([
+        'title' => $this->randomMachineName(8),
+        'type' => 'page',
         'field_date' => [
           'value' => $date,
         ]
       ]);
+      $node->save();
+      $this->nodes[] = $node;
     }
   }
 
diff --git a/core/modules/datetime/src/Tests/Views/SortDateTimeTest.php b/core/modules/datetime/tests/src/Kernel/Views/SortDateTimeTest.php
similarity index 91%
rename from core/modules/datetime/src/Tests/Views/SortDateTimeTest.php
rename to core/modules/datetime/tests/src/Kernel/Views/SortDateTimeTest.php
index c1f23a04c2..7375c4db29 100644
--- a/core/modules/datetime/src/Tests/Views/SortDateTimeTest.php
+++ b/core/modules/datetime/tests/src/Kernel/Views/SortDateTimeTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\datetime\Tests\Views;
+namespace Drupal\Tests\datetime\Kernel\Views;
 
+use Drupal\node\Entity\Node;
 use Drupal\views\Views;
 
 /**
@@ -19,8 +20,8 @@ class SortDateTimeTest extends DateTimeHandlerTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Add some basic test nodes.
     $dates = [
@@ -33,11 +34,15 @@ protected function setUp() {
       '2000-10-10T00:03:03',
     ];
     foreach ($dates as $date) {
-      $this->nodes[] = $this->drupalCreateNode([
+      $node = Node::create([
+        'title' => $this->randomMachineName(8),
+        'type' => 'page',
         'field_date' => [
           'value' => $date,
         ]
       ]);
+      $node->save();
+      $this->nodes[] = $node;
     }
   }
 
diff --git a/core/modules/datetime_range/src/DateTimeRangeTrait.php b/core/modules/datetime_range/src/DateTimeRangeTrait.php
index 5a34f2c182..3f05b82189 100644
--- a/core/modules/datetime_range/src/DateTimeRangeTrait.php
+++ b/core/modules/datetime_range/src/DateTimeRangeTrait.php
@@ -2,8 +2,7 @@
 
 namespace Drupal\datetime_range;
 
-use Drupal\Core\Datetime\DrupalDateTime;
-use Drupal\datetime\Plugin\Field\FieldType\DateTimeItem;
+use Drupal\Core\Field\FieldItemListInterface;
 
 /**
  * Provides friendly methods for datetime range.
@@ -11,68 +10,40 @@
 trait DateTimeRangeTrait {
 
   /**
-   * Creates a render array from a date object.
-   *
-   * @param \Drupal\Core\Datetime\DrupalDateTime $date
-   *   A date object.
-   *
-   * @return array
-   *   A render array.
+   * {@inheritdoc}
    */
-  protected function buildDate(DrupalDateTime $date) {
-    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
-      // A date without time will pick up the current time, use the default.
-      datetime_date_default_time($date);
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+    $separator = $this->getSetting('separator');
+
+    foreach ($items as $delta => $item) {
+      if (!empty($item->start_date) && !empty($item->end_date)) {
+        /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
+        $start_date = $item->start_date;
+        /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
+        $end_date = $item->end_date;
+
+        if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
+          $elements[$delta] = [
+            'start_date' => $this->buildDateWithIsoAttribute($start_date),
+            'separator' => ['#plain_text' => ' ' . $separator . ' '],
+            'end_date' => $this->buildDateWithIsoAttribute($end_date),
+          ];
+        }
+        else {
+          $elements[$delta] = $this->buildDateWithIsoAttribute($start_date);
+
+          if (!empty($item->_attributes)) {
+            $elements[$delta]['#attributes'] += $item->_attributes;
+            // Unset field item attributes since they have been included in the
+            // formatter output and should not be rendered in the field template.
+            unset($item->_attributes);
+          }
+        }
+      }
     }
-    $this->setTimeZone($date);
 
-    $build = [
-      '#plain_text' => $this->formatDate($date),
-      '#cache' => [
-        'contexts' => [
-          'timezone',
-        ],
-      ],
-    ];
-
-    return $build;
-  }
-
-  /**
-   * Creates a render array from a date object with ISO date attribute.
-   *
-   * @param \Drupal\Core\Datetime\DrupalDateTime $date
-   *   A date object.
-   *
-   * @return array
-   *   A render array.
-   */
-  protected function buildDateWithIsoAttribute(DrupalDateTime $date) {
-    if ($this->getFieldSetting('datetime_type') == DateTimeItem::DATETIME_TYPE_DATE) {
-      // A date without time will pick up the current time, use the default.
-      datetime_date_default_time($date);
-    }
-
-    // Create the ISO date in Universal Time.
-    $iso_date = $date->format("Y-m-d\TH:i:s") . 'Z';
-
-    $this->setTimeZone($date);
-
-    $build = [
-      '#theme' => 'time',
-      '#text' => $this->formatDate($date),
-      '#html' => FALSE,
-      '#attributes' => [
-        'datetime' => $iso_date,
-      ],
-      '#cache' => [
-        'contexts' => [
-          'timezone',
-        ],
-      ],
-    ];
-
-    return $build;
+    return $elements;
   }
 
 }
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php
index a26bbef9ab..78aa8aafe2 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeCustomFormatter.php
@@ -38,6 +38,9 @@ public static function defaultSettings() {
    * {@inheritdoc}
    */
   public function viewElements(FieldItemListInterface $items, $langcode) {
+    // @todo Evaluate removing this method in
+    // https://www.drupal.org/node/2793143 to determine if the behavior and
+    // markup in the base class implementation can be used instead.
     $elements = [];
     $separator = $this->getSetting('separator');
 
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php
index f07e834325..b93851bbd0 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangeDefaultFormatter.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\datetime_range\Plugin\Field\FieldFormatter;
 
-use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\datetime\Plugin\Field\FieldFormatter\DateTimeDefaultFormatter;
 use Drupal\datetime_range\DateTimeRangeTrait;
@@ -38,42 +37,6 @@ public static function defaultSettings() {
   /**
    * {@inheritdoc}
    */
-  public function viewElements(FieldItemListInterface $items, $langcode) {
-    $elements = [];
-    $separator = $this->getSetting('separator');
-
-    foreach ($items as $delta => $item) {
-      if (!empty($item->start_date) && !empty($item->end_date)) {
-        /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
-        $start_date = $item->start_date;
-        /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
-        $end_date = $item->end_date;
-
-        if ($start_date->getTimestamp() !== $end_date->getTimestamp()) {
-          $elements[$delta] = [
-            'start_date' => $this->buildDateWithIsoAttribute($start_date),
-            'separator' => ['#plain_text' => ' ' . $separator . ' '],
-            'end_date' => $this->buildDateWithIsoAttribute($end_date),
-          ];
-        }
-        else {
-          $elements[$delta] = $this->buildDateWithIsoAttribute($start_date);
-          if (!empty($item->_attributes)) {
-            $elements[$delta]['#attributes'] += $item->_attributes;
-            // Unset field item attributes since they have been included in the
-            // formatter output and should not be rendered in the field template.
-            unset($item->_attributes);
-          }
-        }
-      }
-    }
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function settingsForm(array $form, FormStateInterface $form_state) {
     $form = parent::settingsForm($form, $form_state);
 
diff --git a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php
index 1fb4702cd0..0f74fba644 100644
--- a/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php
+++ b/core/modules/datetime_range/src/Plugin/Field/FieldFormatter/DateRangePlainFormatter.php
@@ -57,6 +57,13 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
         }
         else {
           $elements[$delta] = $this->buildDate($start_date);
+
+          if (!empty($item->_attributes)) {
+            $elements[$delta]['#attributes'] += $item->_attributes;
+            // Unset field item attributes since they have been included in the
+            // formatter output and should not be rendered in the field template.
+            unset($item->_attributes);
+          }
         }
       }
     }
diff --git a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
index ebeb4b8f2b..23ba8fab03 100644
--- a/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
+++ b/core/modules/datetime_range/tests/src/Functional/DateRangeFieldTest.php
@@ -170,6 +170,16 @@ public function testDateRangeField() {
       $output = $this->renderTestEntity($id);
       $this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', ['%expected' => $expected]));
 
+      // Test that allowed markup in custom format is preserved and XSS is
+      // removed.
+      $this->displayOptions['settings']['date_format'] = '\\<\\s\\t\\r\\o\\n\\g\\>m/d/Y\\<\\/\\s\\t\\r\\o\\n\\g\\>\\<\\s\\c\\r\\i\\p\\t\\>\\a\\l\\e\\r\\t\\(\\S\\t\\r\\i\\n\\g\\.\\f\\r\\o\\m\\C\\h\\a\\r\\C\\o\\d\\e\\(\\8\\8\\,\\8\\3\\,\\8\\3\\)\\)\\<\\/\\s\\c\\r\\i\\p\\t\\>';
+      entity_get_display($this->field->getTargetEntityTypeId(), $this->field->getTargetBundle(), 'full')
+        ->setComponent($field_name, $this->displayOptions)
+        ->save();
+      $expected = '<strong>' . $start_date->format('m/d/Y') . '</strong>alert(String.fromCharCode(88,83,83)) - <strong>' . $end_date->format('m/d/Y') . '</strong>alert(String.fromCharCode(88,83,83))';
+      $output = $this->renderTestEntity($id);
+      $this->assertContains($expected, $output, new FormattableMarkup('Formatted date field using daterange_custom format displayed as %expected.', ['%expected' => $expected]));
+
       // Test formatters when start date and end date are the same
       $this->drupalGet('entity_test/add');
       $value = '2012-12-31 00:00:00';
diff --git a/core/modules/dblog/config/schema/dblog.views.schema.yml b/core/modules/dblog/config/schema/dblog.views.schema.yml
index e504364e0e..a2e09af385 100644
--- a/core/modules/dblog/config/schema/dblog.views.schema.yml
+++ b/core/modules/dblog/config/schema/dblog.views.schema.yml
@@ -11,3 +11,7 @@ views.field.dblog_message:
 views.field.dblog_operations:
   type: views_field
   label: 'Operation link markup'
+
+views.filter.dblog_types:
+  type: 'views.filter.in_operator'
+  label: 'Types'
diff --git a/core/modules/dblog/dblog.install b/core/modules/dblog/dblog.install
index f226ed04d9..8da830b310 100644
--- a/core/modules/dblog/dblog.install
+++ b/core/modules/dblog/dblog.install
@@ -90,3 +90,69 @@ function dblog_schema() {
 
   return $schema;
 }
+
+/**
+ * Use standard plugin for wid and uid fields. Use dblog_types for type filter.
+ */
+function dblog_update_8400() {
+  $config_factory = \Drupal::configFactory();
+
+  foreach ($config_factory->listAll('views.view.') as $view_config_name) {
+    $view = $config_factory->getEditable($view_config_name);
+    if ($view->get('base_table') != 'watchdog') {
+      continue;
+    }
+
+    $save = FALSE;
+    foreach ($view->get('display') as $display_name => $display) {
+      // Iterate through all the fields of watchdog views based tables.
+      if (isset($display['display_options']['fields'])) {
+        foreach ($display['display_options']['fields'] as $field_name => $field) {
+          // We are only interested in wid and uid fields from the watchdog
+          // table that still use the numeric id.
+          if (isset($field['table']) &&
+              $field['table'] === 'watchdog' &&
+              $field['plugin_id'] == 'numeric' &&
+              in_array($field['field'], ['wid', 'uid'])) {
+
+            $save = TRUE;
+            $new_value = $field;
+            $new_value['plugin_id'] = 'standard';
+
+            // Delete all the attributes related to numeric fields.
+            unset(
+              $new_value['set_precision'],
+              $new_value['precision'],
+              $new_value['decimal'],
+              $new_value['separator'],
+              $new_value['format_plural'],
+              $new_value['format_plural_string'],
+              $new_value['prefix'],
+              $new_value['suffix']
+            );
+            $view->set("display.$display_name.display_options.fields.$field_name", $new_value);
+          }
+        }
+      }
+
+      // Iterate all filters looking for type filters to update.
+      if (isset($display['display_options']['filters'])) {
+        foreach ($display['display_options']['filters'] as $filter_name => $filter) {
+          if (isset($filter['table']) &&
+              $filter['table'] === 'watchdog' &&
+              $filter['plugin_id'] == 'in_operator' &&
+              $filter['field'] == 'type') {
+
+            $save = TRUE;
+            $filter['plugin_id'] = 'dblog_types';
+            $view->set("display.$display_name.display_options.filters.$filter_name", $filter);
+          }
+        }
+      }
+    }
+
+    if ($save) {
+      $view->save();
+    }
+  }
+}
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index ed92d6c8f2..f33f74902f 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -12,6 +12,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\views\ViewEntityInterface;
 
 /**
  * Implements hook_help().
@@ -115,3 +116,74 @@ function dblog_form_system_logging_settings_alter(&$form, FormStateInterface $fo
 function dblog_logging_settings_submit($form, FormStateInterface $form_state) {
   \Drupal::configFactory()->getEditable('dblog.settings')->set('row_limit', $form_state->getValue('dblog_row_limit'))->save();
 }
+
+/**
+ * Implements hook_ENTITY_TYPE_presave() for views entities.
+ *
+ * This hook ensures there are no views based that are using a wrong plugin for
+ * wid and uid fields on views that use watchdog as base table.
+ *
+ * @deprecated in Drupal 8.4.x and will be removed before 9.0.0.
+ *
+ * @see https://www.drupal.org/node/2876378
+ */
+function dblog_view_presave(ViewEntityInterface $view) {
+  // Only interested in watchdog based views.
+  if ($view->get('base_table') != 'watchdog') {
+    return;
+  }
+
+  $displays = $view->get('display');
+  $update = FALSE;
+  foreach ($displays as $display_name => $display) {
+
+    // Iterate through all the fields of watchdog views based tables.
+    if (isset($display['display_options']['fields'])) {
+      foreach ($display['display_options']['fields'] as $field_name => $field) {
+        // We are only interested in wid and uid fields from the watchdog table
+        // that still use the numeric id.
+        if (isset($field['table']) &&
+            $field['table'] === 'watchdog' &&
+            $field['plugin_id'] == 'numeric' &&
+            in_array($field['field'], ['wid', 'uid'], TRUE)) {
+
+          $displays[$display_name]['display_options']['fields'][$field_name]['plugin_id'] = 'standard';
+
+          // Delete all the attributes related to numeric fields.
+          unset(
+            $displays[$display_name]['display_options']['fields'][$field_name]['set_precision'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['precision'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['decimal'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['separator'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['format_plural'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['format_plural_string'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['prefix'],
+            $displays[$display_name]['display_options']['fields'][$field_name]['suffix']
+          );
+
+          $update = TRUE;
+          @trigger_error("The numeric plugin for watchdog.$field_name field is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Must use standard plugin instead. See https://www.drupal.org/node/2876378.", E_USER_DEPRECATED);
+        }
+      }
+    }
+
+    // Iterate all filters looking for type filters to update.
+    if (isset($display['display_options']['filters'])) {
+      foreach ($display['display_options']['filters'] as $filter_name => $filter) {
+        if (isset($filter['table']) &&
+            $filter['table'] === 'watchdog' &&
+            $filter['plugin_id'] == 'in_operator' &&
+            $filter['field'] == 'type') {
+
+          $displays[$display_name]['display_options']['filters'][$filter_name]['plugin_id'] = 'dblog_types';
+          $update = TRUE;
+          @trigger_error("The in_operator plugin for watchdog.type filter is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Must use dblog_types plugin instead. See https://www.drupal.org/node/2876378.", E_USER_DEPRECATED);
+        }
+      }
+    }
+  }
+
+  if ($update) {
+    $view->set('display', $displays);
+  }
+}
diff --git a/core/modules/dblog/dblog.views.inc b/core/modules/dblog/dblog.views.inc
index 20ad9ceb29..6ad9e68ce4 100644
--- a/core/modules/dblog/dblog.views.inc
+++ b/core/modules/dblog/dblog.views.inc
@@ -24,7 +24,7 @@ function dblog_views_data() {
     'title' => t('WID'),
     'help' => t('Unique watchdog event ID.'),
     'field' => [
-      'id' => 'numeric',
+      'id' => 'standard',
     ],
     'filter' => [
       'id' => 'numeric',
@@ -39,9 +39,9 @@ function dblog_views_data() {
 
   $data['watchdog']['uid'] = [
     'title' => t('UID'),
-    'help' => t('The user ID of the user on which the log entry was written..'),
+    'help' => t('The user ID of the user on which the log entry was written.'),
     'field' => [
-      'id' => 'numeric',
+      'id' => 'standard',
     ],
     'filter' => [
       'id' => 'numeric',
@@ -52,7 +52,7 @@ function dblog_views_data() {
     'relationship' => [
       'title' => t('User'),
       'help' => t('The user on which the log entry as written.'),
-      'base' => 'users',
+      'base' => 'users_field_data',
       'base field' => 'uid',
       'id' => 'standard',
     ],
@@ -68,8 +68,7 @@ function dblog_views_data() {
       'id' => 'string',
     ],
     'filter' => [
-      'id' => 'in_operator',
-      'options callback' => '_dblog_get_message_types',
+      'id' => 'dblog_types',
     ],
     'sort' => [
       'id' => 'standard',
@@ -120,7 +119,7 @@ function dblog_views_data() {
     ],
     'filter' => [
       'id' => 'in_operator',
-      'options callback' => 'Drupal\dblog\Controller\DbLogController::getLogLevelClassMap',
+      'options callback' => 'Drupal\Core\Logger\RfcLogLevel::getLevels',
     ],
     'sort' => [
       'id' => 'standard',
diff --git a/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php b/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php
new file mode 100644
index 0000000000..23ea736ea9
--- /dev/null
+++ b/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\dblog\Plugin\views\filter;
+
+use Drupal\views\Plugin\views\filter\InOperator;
+
+/**
+ * Exposes log types to views module.
+ *
+ * @ViewsFilter("dblog_types")
+ */
+class DblogTypes extends InOperator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValueOptions() {
+    if (!isset($this->valueOptions)) {
+      $this->valueOptions = _dblog_get_message_types();
+    }
+    return $this->valueOptions;
+  }
+
+}
diff --git a/core/modules/dblog/src/Tests/Update/DblogFiltersAndFieldsUpgradeTest.php b/core/modules/dblog/src/Tests/Update/DblogFiltersAndFieldsUpgradeTest.php
new file mode 100644
index 0000000000..d988d71e9d
--- /dev/null
+++ b/core/modules/dblog/src/Tests/Update/DblogFiltersAndFieldsUpgradeTest.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\dblog\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\views\Views;
+use Drupal\Core\Serialization\Yaml;
+
+/**
+ * Tests the upgrade path for views field and filter handlers.
+ *
+ * @see dblog_update_8400()
+ *
+ * @group Update
+ */
+class DblogFiltersAndFieldsUpgradeTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
+      __DIR__ . '/../../../tests/fixtures/update/dblog-2851293.php',
+    ];
+  }
+
+  /**
+   * Tests that field and filter handlers are updated properly.
+   */
+  public function testDblogUpgradePath() {
+
+    $this->runUpdates();
+
+    $view = Views::getView('dblog_2851293');
+    $data = $view->storage->toArray();
+    $fields = $data['display']['default']['display_options']['fields'];
+
+    // The 'wid' and 'uid' fields should use the standard plugin now.
+    $this->assertEqual('standard', $fields['wid']['plugin_id']);
+    $this->assertEqual('standard', $fields['uid']['plugin_id']);
+
+    $filters = $data['display']['default']['display_options']['filters'];
+    // The 'type' filter should use the dblog_types plugin now.
+    $this->assertEqual('dblog_types', $filters['type']['plugin_id']);
+
+    // Now that the view had been converted, try the same approach but using
+    // dblog_view_presave()
+    $config_factory = \Drupal::configFactory();
+    $config_view = $config_factory->getEditable('views.view.dblog_2851293');
+    $config_view->setData(Yaml::decode(file_get_contents('core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_2851293.yml')));
+    $config_view->save();
+
+    // Make sure we have a not upgraded view.
+    $view = Views::getView('dblog_2851293');
+    $data = $view->storage->toArray();
+    $fields = $data['display']['default']['display_options']['fields'];
+    $filters = $data['display']['default']['display_options']['filters'];
+
+    $this->assertEqual('numeric', $fields['wid']['plugin_id']);
+    $this->assertEqual('numeric', $fields['uid']['plugin_id']);
+    $this->assertEqual('in_operator', $filters['type']['plugin_id']);
+
+    // Now save the view. This trigger dblog_view_presave().
+    $view->save();
+
+    // Finally check the same convertion proccess ran.
+    $data = $view->storage->toArray();
+    $fields = $data['display']['default']['display_options']['fields'];
+    $filters = $data['display']['default']['display_options']['filters'];
+
+    $this->assertEqual('standard', $fields['wid']['plugin_id']);
+    $this->assertEqual('standard', $fields['uid']['plugin_id']);
+    $this->assertEqual('dblog_types', $filters['type']['plugin_id']);
+  }
+
+}
diff --git a/core/modules/dblog/tests/fixtures/update/dblog-2851293.php b/core/modules/dblog/tests/fixtures/update/dblog-2851293.php
new file mode 100644
index 0000000000..0a26031748
--- /dev/null
+++ b/core/modules/dblog/tests/fixtures/update/dblog-2851293.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @file
+ * Test fixture.
+ */
+
+use Drupal\Core\Database\Database;
+use Drupal\Core\Serialization\Yaml;
+
+$connection = Database::getConnection();
+
+$connection->insert('config')
+  ->fields([
+    'collection' => '',
+    'name' => 'views.view.dblog_2851293',
+    'data' => serialize(Yaml::decode(file_get_contents('core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_2851293.yml'))),
+  ])
+  ->execute();
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_2851293.yml b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_2851293.yml
new file mode 100644
index 0000000000..470a1f0251
--- /dev/null
+++ b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_2851293.yml
@@ -0,0 +1,148 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - user
+id: dblog_2851293
+label: dblog_2851293
+module: views
+description: 'Base view to test upgrade from issue #2851293'
+tag: ''
+base_table: watchdog
+base_field: wid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access site reports'
+      cache:
+        type: none
+        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: Filter
+          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: some
+        options:
+          items_per_page: 10
+          offset: 0
+      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:
+        wid:
+          table: watchdog
+          field: wid
+          id: wid
+          entity_type: null
+          entity_field: null
+          plugin_id: numeric
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          set_precision: false
+          precision: 0
+          decimal: .
+          separator: ','
+          format_plural: false
+          format_plural_string: "1\x03@count"
+          prefix: ''
+          suffix: ''
+        uid:
+          id: uid
+          table: watchdog
+          field: uid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: ''
+          exclude: false
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          set_precision: false
+          precision: 0
+          decimal: .
+          separator: ','
+          format_plural: false
+          format_plural_string: "1\x03@count"
+          prefix: ''
+          suffix: ''
+          plugin_id: numeric
+      filters:
+        type:
+          id: type
+          table: watchdog
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value: {  }
+          group: 1
+          exposed: true
+          expose:
+            operator_id: type_op
+            label: Type
+            description: ''
+            use_operator: false
+            operator: type_op
+            identifier: type
+            required: false
+            remember: false
+            multiple: true
+            reduce: false
+          plugin_id: in_operator
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_interface'
+        - user.permissions
+      tags: {  }
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_integration_test.yml b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_integration_test.yml
new file mode 100644
index 0000000000..5e701ab081
--- /dev/null
+++ b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.dblog_integration_test.yml
@@ -0,0 +1,505 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - dblog
+    - user
+id: dblog_integration_test
+label: dblog_integration_test
+module: views
+description: ''
+tag: ''
+base_table: watchdog
+base_field: wid
+core: 8.x
+display:
+  default:
+    display_plugin: default
+    id: default
+    display_title: Master
+    position: 0
+    display_options:
+      access:
+        type: perm
+        options:
+          perm: 'access site reports'
+      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: Filter
+          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
+      row:
+        type: fields
+      fields:
+        wid:
+          table: watchdog
+          field: wid
+          id: wid
+          entity_type: null
+          entity_field: null
+          plugin_id: standard
+          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: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+        message:
+          id: message
+          table: watchdog
+          field: message
+          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
+          replace_variables: true
+          plugin_id: dblog_message
+        link:
+          id: link
+          table: watchdog
+          field: link
+          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
+          plugin_id: dblog_operations
+        severity:
+          id: severity
+          table: watchdog
+          field: severity
+          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
+          machine_name: false
+          plugin_id: machine_name
+        type:
+          id: type
+          table: watchdog
+          field: type
+          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
+          plugin_id: standard
+        name:
+          id: name
+          table: users_field_data
+          field: name
+          relationship: uid
+          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: user_name
+          settings:
+            link_to_entity: true
+          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: user
+          entity_field: name
+          plugin_id: field
+      filters:
+        severity:
+          id: severity
+          table: watchdog
+          field: severity
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value: {  }
+          group: 1
+          exposed: true
+          expose:
+            operator_id: severity_op
+            label: 'Severity level'
+            description: ''
+            use_operator: false
+            operator: severity_op
+            identifier: severity
+            required: false
+            remember: false
+            multiple: true
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          plugin_id: in_operator
+        type:
+          id: type
+          table: watchdog
+          field: type
+          relationship: none
+          group_type: group
+          admin_label: ''
+          operator: in
+          value: {  }
+          group: 1
+          exposed: true
+          expose:
+            operator_id: type_op
+            label: Type
+            description: ''
+            use_operator: false
+            operator: type_op
+            identifier: type
+            required: false
+            remember: false
+            multiple: true
+            remember_roles:
+              authenticated: authenticated
+              anonymous: '0'
+              administrator: '0'
+            reduce: false
+          is_grouped: false
+          group_info:
+            label: ''
+            description: ''
+            identifier: ''
+            optional: true
+            widget: select
+            multiple: false
+            remember: false
+            default_group: All
+            default_group_multiple: {  }
+            group_items: {  }
+          plugin_id: dblog_types
+      sorts: {  }
+      title: dblog_integration_test
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships:
+        uid:
+          id: uid
+          table: watchdog
+          field: uid
+          relationship: none
+          group_type: group
+          admin_label: uid
+          required: false
+          plugin_id: standard
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
+  page_1:
+    display_plugin: page
+    id: page_1
+    display_title: Page
+    position: 1
+    display_options:
+      display_extenders: {  }
+      path: dblog-integration-test
+    cache_metadata:
+      max-age: -1
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url
+        - url.query_args
+        - user.permissions
+      tags: {  }
diff --git a/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php b/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php
index 7b63394d52..67d693fb8b 100644
--- a/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php
+++ b/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php
@@ -18,41 +18,161 @@
 class ViewsIntegrationTest extends ViewsKernelTestBase {
 
   /**
-   * Views used by this test.
-   *
-   * @var array
+   * {@inheritdoc}
    */
-  public static $testViews = ['test_dblog'];
+  public static $testViews = ['test_dblog', 'dblog_integration_test'];
 
   /**
-   * Modules to enable.
-   *
-   * @var array
+   * {@inheritdoc}
    */
   public static $modules = ['dblog', 'dblog_test_views', 'user'];
 
   /**
    * {@inheritdoc}
    */
+  protected $columnMap = ['watchdog_message' => 'message'];
+
+  /**
+   * {@inheritdoc}
+   */
   protected function setUp($import_test_views = TRUE) {
     parent::setUp();
 
-    // Rebuild the router, otherwise we can't generate links.
-    $this->container->get('router.builder')->rebuild();
-
+    $this->installEntitySchema('user');
     $this->installSchema('dblog', ['watchdog']);
 
     ViewTestData::createTestViews(get_class($this), ['dblog_test_views']);
   }
 
   /**
-   * Tests the integration.
+   * Tests the messages escaping functionality.
+   */
+  public function testMessages() {
+
+    // Remove the watchdog entries added by the potential batch process.
+    $this->container->get('database')->truncate('watchdog')->execute();
+
+    $entries = $this->createLogEntries();
+
+    $view = Views::getView('test_dblog');
+    $this->executeView($view);
+    $view->initStyle();
+
+    foreach ($entries as $index => $entry) {
+      if (!isset($entry['variables'])) {
+        continue;
+      }
+      $this->assertEqual($view->style_plugin->getField($index, 'message'), SafeMarkup::format($entry['message'], $entry['variables']));
+      $link_field = $view->style_plugin->getField($index, 'link');
+      // The 3rd entry contains some unsafe markup that needs to get filtered.
+      if ($index == 2) {
+        // Make sure that unsafe link differs from the rendered link, so we know
+        // that some filtering actually happened.
+        $this->assertNotEqual($link_field, $entry['variables']['link']);
+      }
+      $this->assertEqual($link_field, Xss::filterAdmin($entry['variables']['link']));
+    }
+
+    // Disable replacing variables and check that the tokens aren't replaced.
+    $view->destroy();
+    $view->storage->invalidateCaches();
+    $view->initHandlers();
+    $this->executeView($view);
+    $view->initStyle();
+    $view->field['message']->options['replace_variables'] = FALSE;
+    foreach ($entries as $index => $entry) {
+      $this->assertEqual($view->style_plugin->getField($index, 'message'), $entry['message']);
+    }
+  }
+
+  /**
+   * Tests the relationship with the users_field_data table.
    */
-  public function testIntegration() {
+  public function testRelationship() {
+    $view = Views::getView('dblog_integration_test');
+    $view->setDisplay('page_1');
+    // The uid relationship should now join to the {users_field_data} table.
+    $tables = array_keys($view->getBaseTables());
+    $this->assertTrue(in_array('users_field_data', $tables));
+    $this->assertFalse(in_array('users', $tables));
+    $this->assertTrue(in_array('watchdog', $tables));
+  }
 
+  /**
+   * Test views can be filtered by severity and log type.
+   */
+  public function testFiltering() {
     // Remove the watchdog entries added by the potential batch process.
     $this->container->get('database')->truncate('watchdog')->execute();
+    $this->createLogEntries();
+
+    $view = Views::getView('dblog_integration_test');
+
+    $filters = [
+      'severity' => [
+        'id' => 'severity',
+        'table' => 'watchdog',
+        'field' => 'severity',
+        'relationship' => 'none',
+        'group_type' => 'group',
+        'admin_label' => '',
+        'operator' => 'in',
+        'value' => [
+          RfcLogLevel::WARNING,
+        ],
+        'group' => 1,
+        'exposed' => FALSE,
+        'plugin_id' => 'in_operator',
+      ],
+    ];
+
+    $view->setDisplay('page_1');
+    $view->displayHandlers->get('page_1')->overrideOption('filters', $filters);
+    $view->save();
+
+    $this->executeView($view);
+
+    $resultset = [['message' => 'Warning message']];
+    $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
+
+    $view = Views::getView('dblog_integration_test');
+
+    $filters = [
+      'type' => [
+        'id' => 'type',
+        'table' => 'watchdog',
+        'field' => 'type',
+        'relationship' => 'none',
+        'group_type' => 'group',
+        'admin_label' => '',
+        'operator' => 'in',
+        'value' => [
+          'my-module' => 'my-module',
+        ],
+        'group' => '1',
+        'exposed' => FALSE,
+        'is_grouped' => FALSE,
+        'plugin_id' => 'dblog_types',
+      ],
+    ];
+
+    $view->setDisplay('page_1');
+    $view->displayHandlers->get('page_1')->overrideOption('filters', $filters);
+    $view->save();
+
+    $this->executeView($view);
+
+    $resultset = [['message' => 'My module message']];
+    $this->assertIdenticalResultset($view, $resultset, $this->columnMap);
+  }
 
+  /**
+   * Create a set of log entries.
+   *
+   * @return array
+   *   An array of data used to create the log entries.
+   */
+  protected function createLogEntries() {
     $entries = [];
     // Setup a watchdog entry without tokens.
     $entries[] = [
@@ -76,41 +196,28 @@ public function testIntegration() {
         'link' => '<a href="' . \Drupal::url('<front>') . '"><object>Link</object></a>',
       ],
     ];
+    // Setup a watchdog entry with severity WARNING.
+    $entries[] = [
+      'message' => 'Warning message',
+      'severity' => RfcLogLevel::WARNING,
+    ];
+    // Setup a watchdog entry with a different module.
+    $entries[] = [
+      'message' => 'My module message',
+      'severity' => RfcLogLevel::INFO,
+      'type' => 'my-module',
+    ];
+
     $logger_factory = $this->container->get('logger.factory');
     foreach ($entries as $entry) {
       $entry += [
         'type' => 'test-views',
         'severity' => RfcLogLevel::NOTICE,
+        'variables' => [],
       ];
       $logger_factory->get($entry['type'])->log($entry['severity'], $entry['message'], $entry['variables']);
     }
-
-    $view = Views::getView('test_dblog');
-    $this->executeView($view);
-    $view->initStyle();
-
-    foreach ($entries as $index => $entry) {
-      $this->assertEqual($view->style_plugin->getField($index, 'message'), SafeMarkup::format($entry['message'], $entry['variables']));
-      $link_field = $view->style_plugin->getField($index, 'link');
-      // The 3rd entry contains some unsafe markup that needs to get filtered.
-      if ($index == 2) {
-        // Make sure that unsafe link differs from the rendered link, so we know
-        // that some filtering actually happened.
-        $this->assertNotEqual($link_field, $entry['variables']['link']);
-      }
-      $this->assertEqual($link_field, Xss::filterAdmin($entry['variables']['link']));
-    }
-
-    // Disable replacing variables and check that the tokens aren't replaced.
-    $view->destroy();
-    $view->storage->invalidateCaches();
-    $view->initHandlers();
-    $this->executeView($view);
-    $view->initStyle();
-    $view->field['message']->options['replace_variables'] = FALSE;
-    foreach ($entries as $index => $entry) {
-      $this->assertEqual($view->style_plugin->getField($index, 'message'), $entry['message']);
-    }
+    return $entries;
   }
 
 }
diff --git a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
index 22a1f2c2ce..8316470876 100644
--- a/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
+++ b/core/modules/dynamic_page_cache/src/EventSubscriber/DynamicPageCacheSubscriber.php
@@ -82,7 +82,7 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface {
         // may be returning a domain object that a KernelEvents::VIEW subscriber
         // must turn into an actual response, but perhaps a format is being
         // requested that the subscriber does not support.
-        // @see \Drupal\Core\EventSubscriber\AcceptNegotiation406::onViewDetect406()
+        // @see \Drupal\Core\EventSubscriber\RenderArrayNonHtmlSubscriber::onResponse()
         'request_format',
       ],
       'bin' => 'dynamic_page_cache',
diff --git a/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php b/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
index 7141687bc7..a4515d5673 100644
--- a/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
+++ b/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
@@ -89,12 +89,12 @@ public function testUsersWithoutPermission() {
       $response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', [], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
       $this->assertResponse(403);
       if (!$user->hasPermission('access in-place editing')) {
-        $message = "A fatal error occurred: The 'access in-place editing' permission is required.";
-        $this->assertIdentical(Json::encode(['message' => $message]), $response);
+        $message = "The 'access in-place editing' permission is required.";
       }
       else {
-        $this->assertIdentical('{}', $response);
+        $message = '';
       }
+      $this->assertIdentical(Json::encode(['message' => $message]), $response);
     }
   }
 
diff --git a/core/modules/editor/tests/src/Kernel/QuickEditIntegrationTest.php b/core/modules/editor/tests/src/Kernel/QuickEditIntegrationTest.php
index 256d271778..276f559225 100644
--- a/core/modules/editor/tests/src/Kernel/QuickEditIntegrationTest.php
+++ b/core/modules/editor/tests/src/Kernel/QuickEditIntegrationTest.php
@@ -9,7 +9,7 @@
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\quickedit\MetadataGenerator;
 use Drupal\Tests\quickedit\Kernel\QuickEditTestBase;
-use Drupal\quickedit_test\MockEditEntityFieldAccessCheck;
+use Drupal\quickedit_test\MockQuickEditEntityFieldAccessCheck;
 use Drupal\editor\EditorController;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -52,7 +52,7 @@ class QuickEditIntegrationTest extends QuickEditTestBase {
   /**
    * The access checker object to be used by the metadata generator object.
    *
-   * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface
+   * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface
    */
   protected $accessChecker;
 
@@ -165,7 +165,7 @@ public function testEditorSelection() {
    */
   public function testMetadata() {
     $this->editorManager = $this->container->get('plugin.manager.quickedit.editor');
-    $this->accessChecker = new MockEditEntityFieldAccessCheck();
+    $this->accessChecker = new MockQuickEditEntityFieldAccessCheck();
     $this->editorSelector = $this->container->get('quickedit.editor.selector');
     $this->metadataGenerator = new MetadataGenerator($this->accessChecker, $this->editorSelector, $this->editorManager);
 
diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php
index a63e54f98b..78b3d602b6 100644
--- a/core/modules/field/src/Entity/FieldStorageConfig.php
+++ b/core/modules/field/src/Entity/FieldStorageConfig.php
@@ -18,6 +18,7 @@
  *   id = "field_storage_config",
  *   label = @Translation("Field storage"),
  *   handlers = {
+ *     "access" = "Drupal\field\FieldStorageConfigAccessControlHandler",
  *     "storage" = "Drupal\field\FieldStorageConfigStorage"
  *   },
  *   config_prefix = "storage",
@@ -627,7 +628,17 @@ public function getDescription() {
    * {@inheritdoc}
    */
   public function getCardinality() {
-    return $this->cardinality;
+    /** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
+    $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
+    $definition = $field_type_manager->getDefinition($this->getType());
+    $enforced_cardinality = isset($definition['cardinality']) ? $definition['cardinality'] : NULL;
+
+    // Enforced cardinality is a positive integer or -1.
+    if ($enforced_cardinality !== NULL && $enforced_cardinality < 1 && $enforced_cardinality !== FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
+      throw new FieldException("Invalid enforced cardinality '$enforced_cardinality'. Allowed values: a positive integer or -1.");
+    }
+
+    return $enforced_cardinality ?: $this->cardinality;
   }
 
   /**
diff --git a/core/modules/field/src/FieldConfigAccessControlHandler.php b/core/modules/field/src/FieldConfigAccessControlHandler.php
index e27f99cce6..6ee0e05cb6 100644
--- a/core/modules/field/src/FieldConfigAccessControlHandler.php
+++ b/core/modules/field/src/FieldConfigAccessControlHandler.php
@@ -2,13 +2,12 @@
 
 namespace Drupal\field;
 
-use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Entity\EntityAccessControlHandler;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
 
 /**
- * Defines the access control handler for the field entity type.
+ * Defines the access control handler for the field config entity type.
  *
  * @see \Drupal\field\Entity\FieldConfig
  */
@@ -18,16 +17,16 @@ class FieldConfigAccessControlHandler extends EntityAccessControlHandler {
    * {@inheritdoc}
    */
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
-    if ($operation == 'delete') {
-      $field_storage_entity = $entity->getFieldStorageDefinition();
-      if ($field_storage_entity->isLocked()) {
-        return AccessResult::forbidden()->addCacheableDependency($field_storage_entity);
-      }
-      else {
-        return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($field_storage_entity);
-      }
-    }
-    return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
+    // Delegate access control to the underlying field storage config entity:
+    // the field config entity merely handles configuration for a particular
+    // bundle of an entity type, the bulk of the logic and configuration is with
+    // the field storage config entity. Therefore, if an operation is allowed on
+    // a certain field storage config entity, it should also be allowed for all
+    // associated field config entities.
+    // @see \Drupal\Core\Field\FieldDefinitionInterface
+    /** \Drupal\field\FieldConfigInterface $entity */
+    $field_storage_entity = $entity->getFieldStorageDefinition();
+    return $field_storage_entity->access($operation, $account, TRUE);
   }
 
 }
diff --git a/core/modules/field/src/FieldStorageConfigAccessControlHandler.php b/core/modules/field/src/FieldStorageConfigAccessControlHandler.php
new file mode 100644
index 0000000000..da48556fab
--- /dev/null
+++ b/core/modules/field/src/FieldStorageConfigAccessControlHandler.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\field;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Entity\EntityAccessControlHandler;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Session\AccountInterface;
+
+/**
+ * Defines the access control handler for the field storage config entity type.
+ *
+ * @see \Drupal\field\Entity\FieldStorageConfig
+ */
+class FieldStorageConfigAccessControlHandler extends EntityAccessControlHandler {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
+    /** \Drupal\field\FieldStorageConfigInterface $entity */
+    if ($operation === 'delete') {
+      if ($entity->isLocked()) {
+        return AccessResult::forbidden()->addCacheableDependency($entity);
+      }
+      else {
+        return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields')->addCacheableDependency($entity);
+      }
+    }
+    return AccessResult::allowedIfHasPermission($account, 'administer ' . $entity->getTargetEntityTypeId() . ' fields');
+  }
+
+}
diff --git a/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php b/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
index 31d6503795..2b0be855dd 100644
--- a/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
+++ b/core/modules/field/tests/src/Kernel/EntityReference/Views/EntityReferenceRelationshipTest.php
@@ -34,7 +34,7 @@ class EntityReferenceRelationshipTest extends ViewsKernelTestBase {
     'test_entity_reference_entity_test_mul_view',
     'test_entity_reference_reverse_entity_test_mul_view',
     'test_entity_reference_group_by_empty_relationships',
-  ];
+    ];
 
   /**
    * Modules to install.
diff --git a/core/modules/field/tests/src/Kernel/Timestamp/TimestampItemTest.php b/core/modules/field/tests/src/Kernel/Timestamp/TimestampItemTest.php
new file mode 100644
index 0000000000..0aaa8d3414
--- /dev/null
+++ b/core/modules/field/tests/src/Kernel/Timestamp/TimestampItemTest.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace Drupal\Tests\field\Kernel\Timestamp;
+
+use Drupal\Core\Field\FieldItemInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\field\Kernel\FieldKernelTestBase;
+
+/**
+ * Tests the timestamp fields.
+ *
+ * @group field
+ */
+class TimestampItemTest extends FieldKernelTestBase {
+
+  /**
+   * A field storage to use in this test class.
+   *
+   * @var \Drupal\field\Entity\FieldStorageConfig
+   */
+  protected $fieldStorage;
+
+  /**
+   * The field used in this test class.
+   *
+   * @var \Drupal\field\Entity\FieldConfig
+   */
+  protected $field;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Create a field with settings to validate.
+    $this->fieldStorage = FieldStorageConfig::create([
+      'field_name' => 'field_timestamp',
+      'type' => 'timestamp',
+      'entity_type' => 'entity_test',
+    ]);
+    $this->fieldStorage->save();
+    $this->field = FieldConfig::create([
+      'field_storage' => $this->fieldStorage,
+      'bundle' => 'entity_test',
+    ]);
+    $this->field->save();
+  }
+
+  /**
+   * Tests using entity fields of the datetime field type.
+   */
+  public function testDateTime() {
+    // Verify entity creation.
+    $entity = EntityTest::create();
+    $value = 1488914208;
+    $entity->field_timestamp = $value;
+    $entity->name->value = $this->randomMachineName();
+    $this->entityValidateAndSave($entity);
+
+    // Verify entity has been created properly.
+    $id = $entity->id();
+    $entity = EntityTest::load($id);
+    $this->assertTrue($entity->field_timestamp instanceof FieldItemListInterface, 'Field implements interface.');
+    $this->assertTrue($entity->field_timestamp[0] instanceof FieldItemInterface, 'Field item implements interface.');
+    $this->assertEquals($entity->field_timestamp->value, $value);
+    $this->assertEquals($entity->field_timestamp[0]->value, $value);
+
+    // Verify changing the date value.
+    $new_value = 1488914000;
+    $entity->field_timestamp->value = $new_value;
+    $this->assertEquals($entity->field_timestamp->value, $new_value);
+
+    // Read changed entity and assert changed values.
+    $this->entityValidateAndSave($entity);
+    $entity = EntityTest::load($id);
+    $this->assertEquals($entity->field_timestamp->value, $new_value);
+
+    // Test sample item generation.
+    $entity = EntityTest::create();
+    $entity->field_timestamp->generateSampleItems();
+    $this->entityValidateAndSave($entity);
+
+    // Ensure there is sample value a generated for the field.
+    $this->assertNotNull($entity->field_timestamp->value);
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/FieldConfigAccessControlHandlerTest.php b/core/modules/field/tests/src/Unit/FieldConfigAccessControlHandlerTest.php
new file mode 100644
index 0000000000..0ad8265f89
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/FieldConfigAccessControlHandlerTest.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\Tests\field\Unit;
+
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\FieldConfigAccessControlHandler;
+
+/**
+ * Tests the field config access controller.
+ *
+ * @group field
+ *
+ * @coversDefaultClass \Drupal\field\FieldConfigAccessControlHandler
+ */
+class FieldConfigAccessControlHandlerTest extends FieldStorageConfigAccessControlHandlerTest {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->entity = new FieldConfig([
+      'field_name' => $this->fieldStorage->getName(),
+      'entity_type' => 'node',
+      'fieldStorage' => $this->fieldStorage,
+      'bundle' => 'test_bundle',
+      'field_type' => 'test_field',
+    ], 'node');
+
+    $this->accessControlHandler = new FieldConfigAccessControlHandler($this->entity->getEntityType());
+    $this->accessControlHandler->setModuleHandler($this->moduleHandler);
+  }
+
+  /**
+   * Ensures field config access is working properly.
+   */
+  public function testAccess() {
+    $this->assertAllowOperations([], $this->anon);
+    $this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/FieldStorageConfigAccessControlHandlerTest.php b/core/modules/field/tests/src/Unit/FieldStorageConfigAccessControlHandlerTest.php
new file mode 100644
index 0000000000..4ed7512333
--- /dev/null
+++ b/core/modules/field/tests/src/Unit/FieldStorageConfigAccessControlHandlerTest.php
@@ -0,0 +1,200 @@
+<?php
+
+namespace Drupal\Tests\field\Unit;
+
+use Drupal\Component\Uuid\UuidInterface;
+use Drupal\Core\Cache\Context\CacheContextsManager;
+use Drupal\Core\Config\Entity\ConfigEntityTypeInterface;
+use Drupal\Core\DependencyInjection\Container;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\field\FieldStorageConfigAccessControlHandler;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the field storage config access controller.
+ *
+ * @group field
+ *
+ * @coversDefaultClass \Drupal\field\FieldStorageConfigAccessControlHandler
+ */
+class FieldStorageConfigAccessControlHandlerTest extends UnitTestCase {
+
+  /**
+   * The field storage config access controller to test.
+   *
+   * @var \Drupal\field\FieldStorageConfigAccessControlHandler
+   */
+  protected $accessControlHandler;
+
+  /**
+   * The mock module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * The mock account without field storage config access.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $anon;
+
+  /**
+   * The mock account with field storage config access.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $member;
+
+  /**
+   * The mocked test field storage config.
+   *
+   * @var \Drupal\field\FieldStorageConfigInterface
+   */
+  protected $fieldStorage;
+
+  /**
+   * The main entity used for testing.
+   *
+   * @var \Drupal\Core\Config\Entity\ConfigEntityInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->anon = $this->getMock(AccountInterface::class);
+    $this->anon
+      ->expects($this->any())
+      ->method('hasPermission')
+      ->will($this->returnValue(FALSE));
+    $this->anon
+      ->expects($this->any())
+      ->method('id')
+      ->will($this->returnValue(0));
+
+    $this->member = $this->getMock(AccountInterface::class);
+    $this->member
+      ->expects($this->any())
+      ->method('hasPermission')
+      ->will($this->returnValueMap([
+        ['administer node fields', TRUE],
+      ]));
+    $this->member
+      ->expects($this->any())
+      ->method('id')
+      ->will($this->returnValue(2));
+
+    $storageType = $this->getMock(ConfigEntityTypeInterface::class);
+    $storageType
+      ->expects($this->any())
+      ->method('getProvider')
+      ->will($this->returnValue('field'));
+    $storageType
+      ->expects($this->any())
+      ->method('getConfigPrefix')
+      ->will($this->returnValue('field.storage'));
+
+    $entityType = $this->getMock(ConfigEntityTypeInterface::class);
+    $entityType
+      ->expects($this->any())
+      ->method('getProvider')
+      ->will($this->returnValue('node'));
+    $entityType
+      ->expects($this->any())
+      ->method('getConfigPrefix')
+      ->willReturn('node');
+
+    $this->moduleHandler = $this->getMock(ModuleHandlerInterface::class);
+    $this->moduleHandler
+      ->expects($this->any())
+      ->method('getImplementations')
+      ->will($this->returnValue([]));
+    $this->moduleHandler
+      ->expects($this->any())
+      ->method('invokeAll')
+      ->will($this->returnValue([]));
+
+    $storage_access_control_handler = new FieldStorageConfigAccessControlHandler($storageType);
+    $storage_access_control_handler->setModuleHandler($this->moduleHandler);
+
+    $entityManager = $this->getMock(EntityManagerInterface::class);
+    $entityManager
+      ->expects($this->any())
+      ->method('getDefinition')
+      ->willReturnMap([
+        ['field_storage_config', TRUE, $storageType],
+        ['node', TRUE, $entityType],
+      ]);
+    $entityManager
+      ->expects($this->any())
+      ->method('getStorage')
+      ->willReturnMap([
+        ['field_storage_config', $this->getMock(EntityStorageInterface::class)],
+      ]);
+    $entityManager
+      ->expects($this->any())
+      ->method('getAccessControlHandler')
+      ->willReturnMap([
+        ['field_storage_config', $storage_access_control_handler],
+      ]);
+
+    $container = new Container();
+    $container->set('entity.manager', $entityManager);
+    $container->set('uuid', $this->getMock(UuidInterface::class));
+    $container->set('cache_contexts_manager', $this->prophesize(CacheContextsManager::class));
+    \Drupal::setContainer($container);
+
+    $this->fieldStorage = new FieldStorageConfig([
+      'field_name' => 'test_field',
+      'entity_type' => 'node',
+      'type' => 'boolean',
+      'id' => 'node.test_field',
+      'uuid' => '6f2f259a-f3c7-42ea-bdd5-111ad1f85ed1',
+    ]);
+
+    $this->entity = $this->fieldStorage;
+    $this->accessControlHandler = $storage_access_control_handler;
+  }
+
+  /**
+   * Assert method to verify the access by operations.
+   *
+   * @param array $allow_operations
+   *   A list of allowed operations.
+   * @param \Drupal\Core\Session\AccountInterface $user
+   *   The account to use for get access.
+   */
+  public function assertAllowOperations(array $allow_operations, AccountInterface $user) {
+    foreach (['view', 'update', 'delete'] as $operation) {
+      $expected = in_array($operation, $allow_operations);
+      $actual = $this->accessControlHandler->access($this->entity, $operation, $user);
+      $this->assertSame($expected, $actual, "Access problem with '$operation' operation.");
+    }
+  }
+
+  /**
+   * Ensures field storage config access is working properly.
+   */
+  public function testAccess() {
+    $this->assertAllowOperations([], $this->anon);
+    $this->assertAllowOperations(['view', 'update', 'delete'], $this->member);
+
+    $this->fieldStorage->setLocked(TRUE)->save();
+    // Unfortunately, EntityAccessControlHandler has a static cache, which we
+    // therefore must reset manually.
+    $this->accessControlHandler->resetCache();
+
+    $this->assertAllowOperations([], $this->anon);
+    $this->assertAllowOperations(['view', 'update'], $this->member);
+  }
+
+}
diff --git a/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php b/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php
index 13ba3cf93d..89b73963ba 100644
--- a/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php
+++ b/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\field\Unit;
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Field\FieldException;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\field\Entity\FieldStorageConfig;
@@ -110,6 +111,104 @@ public function testCalculateDependencies() {
     $this->assertEquals(['stark'], $dependencies['theme']);
   }
 
+  /**
+   * Tests stored cardinality.
+   *
+   * @covers ::getCardinality
+   */
+  public function testStoredCardinality() {
+    $this->fieldTypeManager->expects($this->any())
+      ->method('getDefinition')
+      ->with('test_field_type')
+      ->willReturn([
+        'class' => TestFieldType::class,
+        // The field type definition has no enforced cardinality.
+        'cardinality' => NULL,
+      ]);
+
+    $field_storage = new FieldStorageConfig([
+      'entity_type' => 'entity_test',
+      'field_name' => 'test_field',
+      'type' => 'test_field_type',
+      'module' => 'test_module',
+    ]);
+    $field_storage->setCardinality(8);
+
+    // Check that the stored cardinality is returned.
+    $this->assertEquals(8, $field_storage->getCardinality());
+  }
+
+  /**
+   * Tests enforced cardinality.
+   *
+   * @covers ::getCardinality
+   */
+  public function testEnforcedCardinality() {
+    $this->fieldTypeManager->expects($this->any())
+      ->method('getDefinition')
+      ->with('test_field_type')
+      ->willReturn([
+        'class' => TestFieldType::class,
+        // This field type defines an enforced cardinality.
+        'cardinality' => 21,
+      ]);
+
+    $field_storage = new FieldStorageConfig([
+      'entity_type' => 'entity_test',
+      'field_name' => 'test_field',
+      'type' => 'test_field_type',
+      'module' => 'test_module',
+    ]);
+    // Custom cardinality tentative.
+    $field_storage->setCardinality(8);
+
+    // Check that the enforced cardinality is returned.
+    $this->assertEquals(21, $field_storage->getCardinality());
+  }
+
+  /**
+   * Tests invalid enforced cardinality.
+   *
+   * @covers ::getCardinality
+   * @dataProvider providerInvalidEnforcedCardinality
+   *
+   * @param mixed $enforced_cardinality
+   *   Enforced cardinality
+   */
+  public function testInvalidEnforcedCardinality($enforced_cardinality) {
+    $this->fieldTypeManager->expects($this->any())
+      ->method('getDefinition')
+      ->with('test_field_type')
+      ->willReturn([
+        'class' => TestFieldType::class,
+        'cardinality' => $enforced_cardinality,
+      ]);
+
+    $field_storage = new FieldStorageConfig([
+      'entity_type' => 'entity_test',
+      'field_name' => 'test_field',
+      'type' => 'test_field_type',
+      'module' => 'test_module',
+    ]);
+
+    $this->setExpectedException(FieldException::class, "Invalid enforced cardinality '$enforced_cardinality'. Allowed values: a positive integer or -1.");
+    $field_storage->getCardinality();
+  }
+
+  /**
+   * Data provider for ::testInvalidEnforcedCardinality()
+   *
+   * @return array
+   *   Test cases.
+   */
+  public function providerInvalidEnforcedCardinality() {
+    return [
+      'zero' => [0],
+      'negative_other_than_-1' => [-70],
+      'non_numeric' => ['abc%$#@!'],
+    ];
+  }
+
 }
 
 /**
diff --git a/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php b/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php
index a12ae18ac0..058e6c361a 100644
--- a/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php
+++ b/core/modules/field_layout/tests/src/Functional/FieldLayoutTest.php
@@ -50,7 +50,7 @@ public function testNodeView() {
     // By default, the one-column layout is used.
     $this->drupalGet('node/1');
     $this->assertSession()->elementExists('css', '.layout--onecol');
-    $this->assertSession()->elementExists('css', '.layout-region--content .field--name-body');
+    $this->assertSession()->elementExists('css', '.layout__region--content .field--name-body');
 
     $this->drupalGet('admin/structure/types/manage/article/display');
     $this->assertEquals(['Content', 'Disabled'], $this->getRegionTitles());
diff --git a/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php b/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php
index a0fd13c0fa..8ddbeafa0d 100644
--- a/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php
+++ b/core/modules/field_layout/tests/src/FunctionalJavascript/FieldLayoutTest.php
@@ -47,9 +47,9 @@ protected function setUp() {
   public function testEntityViewModes() {
     // By default, the field is not visible.
     $this->drupalGet('entity_test/1/test');
-    $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text');
+    $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
     $this->drupalGet('entity_test/1');
-    $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text');
+    $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
 
     // Change the layout for the "test" view mode. See
     // core.entity_view_mode.entity_test.test.yml.
@@ -65,9 +65,9 @@ public function testEntityViewModes() {
 
     // Each view mode has a different layout.
     $this->drupalGet('entity_test/1/test');
-    $this->assertSession()->elementExists('css', '.layout-region--content .field--name-field-test-text');
+    $this->assertSession()->elementExists('css', '.layout__region--content .field--name-field-test-text');
     $this->drupalGet('entity_test/1');
-    $this->assertSession()->elementNotExists('css', '.layout-region--content .field--name-field-test-text');
+    $this->assertSession()->elementNotExists('css', '.layout__region--content .field--name-field-test-text');
   }
 
   /**
@@ -90,46 +90,46 @@ public function testEntityForm() {
 
     // The field is moved to the default region for the new layout.
     $this->assertSession()->pageTextContains('Your settings have been saved.');
-    $this->assertEquals(['Top', 'Left', 'Right', 'Bottom', 'Disabled'], $this->getRegionTitles());
+    $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
 
     $this->drupalGet('entity_test/manage/1/edit');
     // No fields are visible, and the regions don't display when empty.
-    $this->assertFieldInRegion('field_test_text[0][value]', 'left');
-    $this->assertSession()->elementExists('css', '.layout-region--left .field--name-field-test-text');
+    $this->assertFieldInRegion('field_test_text[0][value]', 'first');
+    $this->assertSession()->elementExists('css', '.layout__region--first .field--name-field-test-text');
 
     // After a refresh the new regions are still there.
     $this->drupalGet('entity_test/structure/entity_test/form-display');
-    $this->assertEquals(['Top', 'Left', 'Right', 'Bottom', 'Disabled'], $this->getRegionTitles());
+    $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
 
-    // Drag the field to the right region.
+    // Drag the field to the second region.
     $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
-    $right_region_row = $this->getSession()->getPage()->find('css', '.region-right-message');
-    $field_test_text_row->find('css', '.handle')->dragTo($right_region_row);
+    $second_region_row = $this->getSession()->getPage()->find('css', '.region-second-message');
+    $field_test_text_row->find('css', '.handle')->dragTo($second_region_row);
     $this->assertSession()->assertWaitOnAjaxRequest();
     $this->submitForm([], 'Save');
     $this->assertSession()->pageTextContains('Your settings have been saved.');
 
     // The new layout is used.
     $this->drupalGet('entity_test/manage/1/edit');
-    $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text');
-    $this->assertFieldInRegion('field_test_text[0][value]', 'right');
+    $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
+    $this->assertFieldInRegion('field_test_text[0][value]', 'second');
 
-    // Move the field to the right region without tabledrag.
+    // Move the field to the second region without tabledrag.
     $this->drupalGet('entity_test/structure/entity_test/form-display');
     $this->getSession()->getPage()->pressButton('Show row weights');
-    $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'right');
+    $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
     $this->assertSession()->assertWaitOnAjaxRequest();
     $this->submitForm([], 'Save');
     $this->assertSession()->pageTextContains('Your settings have been saved.');
 
     // The updated region is used.
     $this->drupalGet('entity_test/manage/1/edit');
-    $this->assertFieldInRegion('field_test_text[0][value]', 'right');
+    $this->assertFieldInRegion('field_test_text[0][value]', 'second');
 
     // The layout is still in use without Field UI.
     $this->container->get('module_installer')->uninstall(['field_ui']);
     $this->drupalGet('entity_test/manage/1/edit');
-    $this->assertFieldInRegion('field_test_text[0][value]', 'right');
+    $this->assertFieldInRegion('field_test_text[0][value]', 'second');
   }
 
   /**
@@ -147,23 +147,23 @@ public function testEntityView() {
     $this->submitForm([], 'Save');
 
     $this->assertSession()->pageTextContains('Your settings have been saved.');
-    $this->assertEquals(['Top', 'Left', 'Right', 'Bottom', 'Disabled'], $this->getRegionTitles());
+    $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
 
     $this->drupalGet('entity_test/1');
     // No fields are visible, and the regions don't display when empty.
     $this->assertSession()->elementNotExists('css', '.layout--twocol');
-    $this->assertSession()->elementNotExists('css', '.layout-region');
+    $this->assertSession()->elementNotExists('css', '.layout__region');
     $this->assertSession()->elementNotExists('css', '.field--name-field-test-text');
 
     // After a refresh the new regions are still there.
     $this->drupalGet('entity_test/structure/entity_test/display');
-    $this->assertEquals(['Top', 'Left', 'Right', 'Bottom', 'Disabled'], $this->getRegionTitles());
+    $this->assertEquals(['Top', 'First', 'Second', 'Bottom', 'Disabled'], $this->getRegionTitles());
 
-    // Drag the field to the left region.
+    // Drag the field to the first region.
     $this->assertTrue($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
     $field_test_text_row = $this->getSession()->getPage()->find('css', '#field-test-text');
-    $left_region_row = $this->getSession()->getPage()->find('css', '.region-left-message');
-    $field_test_text_row->find('css', '.handle')->dragTo($left_region_row);
+    $first_region_row = $this->getSession()->getPage()->find('css', '.region-first-message');
+    $field_test_text_row->find('css', '.handle')->dragTo($first_region_row);
     $this->assertSession()->assertWaitOnAjaxRequest();
     $this->assertFalse($this->assertSession()->optionExists('fields[field_test_text][region]', 'hidden')->isSelected());
     $this->submitForm([], 'Save');
@@ -172,25 +172,25 @@ public function testEntityView() {
     // The new layout is used.
     $this->drupalGet('entity_test/1');
     $this->assertSession()->elementExists('css', '.layout--twocol');
-    $this->assertSession()->elementExists('css', '.layout-region--left .field--name-field-test-text');
+    $this->assertSession()->elementExists('css', '.layout__region--first .field--name-field-test-text');
 
-    // Move the field to the right region without tabledrag.
+    // Move the field to the second region without tabledrag.
     $this->drupalGet('entity_test/structure/entity_test/display');
     $this->getSession()->getPage()->pressButton('Show row weights');
-    $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'right');
+    $this->getSession()->getPage()->selectFieldOption('fields[field_test_text][region]', 'second');
     $this->assertSession()->assertWaitOnAjaxRequest();
     $this->submitForm([], 'Save');
     $this->assertSession()->pageTextContains('Your settings have been saved.');
 
     // The updated region is used.
     $this->drupalGet('entity_test/1');
-    $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text');
+    $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
 
     // The layout is still in use without Field UI.
     $this->container->get('module_installer')->uninstall(['field_ui']);
     $this->drupalGet('entity_test/1');
     $this->assertSession()->elementExists('css', '.layout--twocol');
-    $this->assertSession()->elementExists('css', '.layout-region--right .field--name-field-test-text');
+    $this->assertSession()->elementExists('css', '.layout__region--second .field--name-field-test-text');
   }
 
   /**
@@ -258,7 +258,7 @@ protected function getRegionTitles() {
    *   The machine name of the region.
    */
   protected function assertFieldInRegion($field_selector, $region_name) {
-    $region_element = $this->getSession()->getPage()->find('css', ".layout-region--$region_name");
+    $region_element = $this->getSession()->getPage()->find('css', ".layout__region--$region_name");
     $this->assertNotNull($region_element);
     $this->assertSession()->fieldExists($field_selector, $region_element);
   }
diff --git a/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php b/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php
index a0c1294d9d..49a45e1cd9 100644
--- a/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageConfigEditForm.php
@@ -89,9 +89,20 @@ public function form(array $form, FormStateInterface $form_state) {
     $item = $items->first() ?: $items->appendItem();
     $form['settings'] += $item->storageSettingsForm($form, $form_state, $this->entity->hasData());
 
-    // Build the configurable field values.
-    $cardinality = $this->entity->getCardinality();
-    $form['cardinality_container'] = [
+    // Add the cardinality sub-form.
+    $form['cardinality_container'] = $this->getCardinalityForm();
+
+    return $form;
+  }
+
+  /**
+   * Builds the cardinality form.
+   *
+   * @return array
+   *   The cardinality form render array.
+   */
+  protected function getCardinalityForm() {
+    $form = [
       // Reset #parents so the additional container does not appear.
       '#parents' => [],
       '#type' => 'fieldset',
@@ -99,35 +110,49 @@ public function form(array $form, FormStateInterface $form_state) {
       '#attributes' => ['class' => [
         'container-inline',
         'fieldgroup',
-        'form-composite'
+        'form-composite',
       ]],
     ];
-    $form['cardinality_container']['cardinality'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Allowed number of values'),
-      '#title_display' => 'invisible',
-      '#options' => [
-        'number' => $this->t('Limited'),
-        FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => $this->t('Unlimited'),
-      ],
-      '#default_value' => ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) ? FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED : 'number',
-    ];
-    $form['cardinality_container']['cardinality_number'] = [
-      '#type' => 'number',
-      '#default_value' => $cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ? $cardinality : 1,
-      '#min' => 1,
-      '#title' => $this->t('Limit'),
-      '#title_display' => 'invisible',
-      '#size' => 2,
-      '#states' => [
-        'visible' => [
-         ':input[name="cardinality"]' => ['value' => 'number'],
+
+    if ($enforced_cardinality = $this->getEnforcedCardinality()) {
+      if ($enforced_cardinality === FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) {
+        $markup = $this->t("This field cardinality is set to unlimited and cannot be configured.");
+      }
+      else {
+        $markup = $this->t("This field cardinality is set to @cardinality and cannot be configured.", ['@cardinality' => $enforced_cardinality]);
+      }
+      $form['cardinality'] = ['#markup' => $markup];
+    }
+    else {
+      $form['#element_validate'][] = '::validateCardinality';
+      $cardinality = $this->entity->getCardinality();
+      $form['cardinality'] = [
+        '#type' => 'select',
+        '#title' => $this->t('Allowed number of values'),
+        '#title_display' => 'invisible',
+        '#options' => [
+          'number' => $this->t('Limited'),
+          FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED => $this->t('Unlimited'),
         ],
-        'disabled' => [
-         ':input[name="cardinality"]' => ['value' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
+        '#default_value' => ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED) ? FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED : 'number',
+      ];
+      $form['cardinality_number'] = [
+        '#type' => 'number',
+        '#default_value' => $cardinality != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED ? $cardinality : 1,
+        '#min' => 1,
+        '#title' => $this->t('Limit'),
+        '#title_display' => 'invisible',
+        '#size' => 2,
+        '#states' => [
+          'visible' => [
+            ':input[name="cardinality"]' => ['value' => 'number'],
+          ],
+          'disabled' => [
+            ':input[name="cardinality"]' => ['value' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED],
+          ],
         ],
-      ],
-    ];
+      ];
+    }
 
     return $form;
   }
@@ -143,16 +168,19 @@ protected function actions(array $form, FormStateInterface $form_state) {
   }
 
   /**
-   * {@inheritdoc}
+   * Validates the cardinality.
+   *
+   * @param array $element
+   *   The cardinality form render array.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The form state.
    */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    parent::validateForm($form, $form_state);
-
+  public function validateCardinality(array &$element, FormStateInterface $form_state) {
     $field_storage_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($this->entity->getTargetEntityTypeId());
 
     // Validate field cardinality.
     if ($form_state->getValue('cardinality') === 'number' && !$form_state->getValue('cardinality_number')) {
-      $form_state->setErrorByName('cardinality_number', $this->t('Number of values is required.'));
+      $form_state->setError($element['cardinality_number'], $this->t('Number of values is required.'));
     }
     // If a specific cardinality is used, validate that there are no entities
     // with a higher delta.
@@ -166,7 +194,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
         ->count()
         ->execute();
       if ($entities_with_higher_delta) {
-        $form_state->setErrorByName('cardinality_number', $this->formatPlural($entities_with_higher_delta, 'There is @count entity with @delta or more values in this field.', 'There are @count entities with @delta or more values in this field.', ['@delta' => $form_state->getValue('cardinality') + 1]));
+        $form_state->setError($element['cardinality_number'], $this->formatPlural($entities_with_higher_delta, 'There is @count entity with @delta or more values in this field.', 'There are @count entities with @delta or more values in this field.', ['@delta' => $form_state->getValue('cardinality') + 1]));
       }
     }
   }
@@ -176,7 +204,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    */
   public function buildEntity(array $form, FormStateInterface $form_state) {
     // Save field cardinality.
-    if ($form_state->getValue('cardinality') === 'number' && $form_state->getValue('cardinality_number')) {
+    if (!$this->getEnforcedCardinality() && $form_state->getValue('cardinality') === 'number' && $form_state->getValue('cardinality_number')) {
       $form_state->setValue('cardinality', $form_state->getValue('cardinality_number'));
     }
 
@@ -205,4 +233,19 @@ public function save(array $form, FormStateInterface $form_state) {
     }
   }
 
+  /**
+   * Returns the cardinality enforced by the field type.
+   *
+   * Some field types choose to enforce a fixed cardinality. This method
+   * returns that cardinality or NULL if no cardinality has been enforced.
+   *
+   * @return int|null
+   */
+  protected function getEnforcedCardinality() {
+    /** @var \Drupal\Core\Field\FieldTypePluginManager $field_type_manager */
+    $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
+    $definition = $field_type_manager->getDefinition($this->entity->getType());
+    return isset($definition['cardinality']) ? $definition['cardinality'] : NULL;
+  }
+
 }
diff --git a/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php
index 2704157304..631d3368d0 100644
--- a/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php
+++ b/core/modules/field_ui/src/Tests/FieldUIDeleteTest.php
@@ -5,6 +5,7 @@
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\simpletest\WebTestBase;
+use Drupal\views\Entity\View;
 use Drupal\views\Tests\ViewTestData;
 
 /**
@@ -74,6 +75,13 @@ public function testDeleteField() {
     \Drupal::service('module_installer')->install(['views']);
     ViewTestData::createTestViews(get_class($this), ['field_test_views']);
 
+    $view = View::load('test_view_field_delete');
+    $this->assertNotNull($view);
+    $this->assertTrue($view->status());
+    // Test that the View depends on the field.
+    $dependencies = $view->getDependencies() + ['config' => []];
+    $this->assertTrue(in_array("field.storage.node.$field_name", $dependencies['config']));
+
     // Check the config dependencies of the first field, the field storage must
     // not be shown as being deleted yet.
     $this->drupalGet("$bundle_path1/fields/node.$type_name1.$field_name/delete");
@@ -91,13 +99,13 @@ public function testDeleteField() {
 
     // Check the config dependencies of the first field.
     $this->drupalGet("$bundle_path2/fields/node.$type_name2.$field_name/delete");
-    $this->assertText(t('The listed configuration will be deleted.'));
+    $this->assertText(t('The listed configuration will be updated.'));
     $this->assertText(t('View'));
     $this->assertText('test_view_field_delete');
 
     $xml = $this->cssSelect('#edit-entity-deletes');
-    // Remove the wrapping HTML.
-    $this->assertIdentical(FALSE, strpos($xml[0]->asXml(), $field_label), 'The currently being deleted field is not shown in the entity deletions.');
+    // Test that nothing is scheduled for deletion.
+    $this->assertFalse(isset($xml[0]), 'The field currently being deleted is not shown in the entity deletions.');
 
     // Delete the second field.
     $this->fieldUIDeleteField($bundle_path2, "node.$type_name2.$field_name", $field_label, $type_name2);
@@ -106,6 +114,14 @@ public function testDeleteField() {
     $this->assertNull(FieldConfig::loadByName('node', $type_name2, $field_name), 'Field was deleted.');
     // Check that the field storage was deleted too.
     $this->assertNull(FieldStorageConfig::loadByName('node', $field_name), 'Field storage was deleted.');
+
+    // Test that the View isn't deleted and has been disabled.
+    $view = View::load('test_view_field_delete');
+    $this->assertNotNull($view);
+    $this->assertFalse($view->status());
+    // Test that the View no longer depends on the deleted field.
+    $dependencies = $view->getDependencies() + ['config' => []];
+    $this->assertFalse(in_array("field.storage.node.$field_name", $dependencies['config']));
   }
 
 }
diff --git a/core/modules/file/config/optional/views.view.files.yml b/core/modules/file/config/optional/views.view.files.yml
index e5edee2e40..053b72df45 100644
--- a/core/modules/file/config/optional/views.view.files.yml
+++ b/core/modules/file/config/optional/views.view.files.yml
@@ -565,7 +565,7 @@ display:
           decimal: .
           separator: ','
           format_plural: true
-          format_plural_string: "1 place\x03@count places"
+          format_plural_string: !!binary MSBwbGFjZQNAY291bnQgcGxhY2Vz
           prefix: ''
           suffix: ''
           plugin_id: numeric
@@ -1007,7 +1007,7 @@ display:
           decimal: .
           separator: ','
           format_plural: false
-          format_plural_string: "1\x03@count"
+          format_plural_string: !!binary MQNAY291bnQ=
           prefix: ''
           suffix: ''
           plugin_id: numeric
diff --git a/core/modules/file/tests/src/Functional/FileFieldTestBase.php b/core/modules/file/tests/src/Functional/FileFieldTestBase.php
index 9ed447aaf2..d6096874d6 100644
--- a/core/modules/file/tests/src/Functional/FileFieldTestBase.php
+++ b/core/modules/file/tests/src/Functional/FileFieldTestBase.php
@@ -259,7 +259,7 @@ public function replaceNodeFile($file, $field_name, $nid, $new_revision = TRUE)
   /**
    * Asserts that a file exists physically on disk.
    *
-   * Overrides PHPUnit_Framework_Assert::assertFileExists() to also work with
+   * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
    * file entities.
    *
    * @param \Drupal\File\FileInterface|string $file
@@ -286,7 +286,7 @@ public function assertFileEntryExists($file, $message = NULL) {
   /**
    * Asserts that a file does not exist on disk.
    *
-   * Overrides PHPUnit_Framework_Assert::assertFileExists() to also work with
+   * Overrides PHPUnit\Framework\Assert::assertFileExists() to also work with
    * file entities.
    *
    * @param \Drupal\File\FileInterface|string $file
diff --git a/core/modules/forum/src/Form/ContainerForm.php b/core/modules/forum/src/Form/ContainerForm.php
index d12d0982a3..0b01124574 100644
--- a/core/modules/forum/src/Form/ContainerForm.php
+++ b/core/modules/forum/src/Form/ContainerForm.php
@@ -20,9 +20,8 @@ class ContainerForm extends ForumForm {
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
-    $taxonomy_term = $this->entity;
     // Build the bulk of the form from the parent forum form.
-    $form = parent::form($form, $form_state, $taxonomy_term);
+    $form = parent::form($form, $form_state);
 
     // Set the title and description of the name field.
     $form['name']['#title'] = $this->t('Container name');
diff --git a/core/modules/forum/src/Form/ForumForm.php b/core/modules/forum/src/Form/ForumForm.php
index ed0a7683a5..9e5895d0db 100644
--- a/core/modules/forum/src/Form/ForumForm.php
+++ b/core/modules/forum/src/Form/ForumForm.php
@@ -29,9 +29,8 @@ class ForumForm extends TermForm {
    * {@inheritdoc}
    */
   public function form(array $form, FormStateInterface $form_state) {
-    $taxonomy_term = $this->entity;
     // Build the bulk of the form from the parent taxonomy term form.
-    $form = parent::form($form, $form_state, $taxonomy_term);
+    $form = parent::form($form, $form_state);
 
     // Set the title and description of the name field.
     $form['name']['#title'] = $this->t('Forum name');
@@ -48,7 +47,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // Our parent field is different to the taxonomy term.
     $form['parent']['#tree'] = TRUE;
-    $form['parent'][0] = $this->forumParentSelect($taxonomy_term->id(), $this->t('Parent'));
+    $form['parent'][0] = $this->forumParentSelect($this->entity->id(), $this->t('Parent'));
 
     $form['#theme_wrappers'] = ['form__forum'];
     $this->forumFormType = $this->t('forum');
diff --git a/core/modules/hal/src/Normalizer/FieldNormalizer.php b/core/modules/hal/src/Normalizer/FieldNormalizer.php
index a4e175323a..167499a26f 100644
--- a/core/modules/hal/src/Normalizer/FieldNormalizer.php
+++ b/core/modules/hal/src/Normalizer/FieldNormalizer.php
@@ -11,9 +11,7 @@
 class FieldNormalizer extends SerializationFieldNormalizer {
 
   /**
-   * The formats that the Normalizer can handle.
-   *
-   * @var array
+   * {@inheritdoc}
    */
   protected $format = ['hal_json'];
 
diff --git a/core/modules/hal/src/Normalizer/NormalizerBase.php b/core/modules/hal/src/Normalizer/NormalizerBase.php
index 43a5a07161..8b18985b8b 100644
--- a/core/modules/hal/src/Normalizer/NormalizerBase.php
+++ b/core/modules/hal/src/Normalizer/NormalizerBase.php
@@ -11,35 +11,21 @@
 abstract class NormalizerBase extends SerializationNormalizerBase implements DenormalizerInterface {
 
   /**
-   * The formats that the Normalizer can handle.
-   *
-   * @var array
-   */
-  protected $formats = ['hal_json'];
-
-  /**
    * {@inheritdoc}
    */
-  public function supportsNormalization($data, $format = NULL) {
-    return in_array($format, $this->formats) && parent::supportsNormalization($data, $format);
-  }
+  protected $format = ['hal_json'];
 
   /**
    * {@inheritdoc}
    */
-  public function supportsDenormalization($data, $type, $format = NULL) {
-    if (in_array($format, $this->formats) && (class_exists($this->supportedInterfaceOrClass) || interface_exists($this->supportedInterfaceOrClass))) {
-      $target = new \ReflectionClass($type);
-      $supported = new \ReflectionClass($this->supportedInterfaceOrClass);
-      if ($supported->isInterface()) {
-        return $target->implementsInterface($this->supportedInterfaceOrClass);
-      }
-      else {
-        return ($target->getName() == $this->supportedInterfaceOrClass || $target->isSubclassOf($this->supportedInterfaceOrClass));
-      }
+  protected function checkFormat($format = NULL) {
+    if (isset($this->formats)) {
+      @trigger_error('::formats is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Use ::$format instead. See https://www.drupal.org/node/2868275', E_USER_DEPRECATED);
+
+      $this->format = $this->formats;
     }
 
-    return FALSE;
+    return parent::checkFormat($format);
   }
 
 }
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonAnonTest.php
new file mode 100644
index 0000000000..1b9019342a
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonAnonTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
+
+/**
+ * @group hal
+ */
+class FieldStorageConfigHalJsonAnonTest extends FieldStorageConfigResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonBasicAuthTest.php
new file mode 100644
index 0000000000..957e73be92
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonBasicAuthTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
+
+/**
+ * @group hal
+ */
+class FieldStorageConfigHalJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal', 'basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonCookieTest.php
new file mode 100644
index 0000000000..20d47a750a
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigHalJsonCookieTest.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig\FieldStorageConfigResourceTestBase;
+
+/**
+ * @group hal
+ */
+class FieldStorageConfigHalJsonCookieTest extends FieldStorageConfigResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/HalEntityNormalizationTrait.php b/core/modules/hal/tests/src/Functional/EntityResource/HalEntityNormalizationTrait.php
index 99ab3eb0c9..b64de67957 100644
--- a/core/modules/hal/tests/src/Functional/EntityResource/HalEntityNormalizationTrait.php
+++ b/core/modules/hal/tests/src/Functional/EntityResource/HalEntityNormalizationTrait.php
@@ -101,18 +101,18 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques
       $normalization['_links']['type'] = Url::fromUri('base:rest/type/' . static::$entityTypeId . '/bad_bundle_name');
       $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
 
-      // DX: 400 when incorrect entity type bundle is specified.
+      // DX: 422 when incorrect entity type bundle is specified.
       $response = $this->request($method, $url, $request_options);
-      $this->assertResourceErrorResponse(400, 'No entity type(s) specified', $response);
+      $this->assertResourceErrorResponse(422, 'No entity type(s) specified', $response);
 
 
       unset($normalization['_links']['type']);
       $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
 
 
-      // DX: 400 when no entity type bundle is specified.
+      // DX: 422 when no entity type bundle is specified.
       $response = $this->request($method, $url, $request_options);
-      $this->assertResourceErrorResponse(400, 'The type link relation must be specified.', $response);
+      $this->assertResourceErrorResponse(422, 'The type link relation must be specified.', $response);
     }
   }
 
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php
index e92a3d6643..d4ed47c37c 100644
--- a/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php
+++ b/core/modules/hal/tests/src/Functional/EntityResource/Node/NodeHalJsonAnonTest.php
@@ -59,20 +59,20 @@ protected function getExpectedNormalizedEntity() {
         'type' => [
           'href' => $this->baseUrl . '/rest/type/node/camelids',
         ],
-        $this->baseUrl . '/rest/relation/node/camelids/uid' => [
+        $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
           [
             'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
-            'lang' => 'en',
           ],
         ],
-        $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
+        $this->baseUrl . '/rest/relation/node/camelids/uid' => [
           [
             'href' => $this->baseUrl . '/user/' . $author->id() . '?_format=hal_json',
+            'lang' => 'en',
           ],
         ],
       ],
       '_embedded' => [
-        $this->baseUrl . '/rest/relation/node/camelids/uid' => [
+        $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
           [
             '_links' => [
               'self' => [
@@ -85,10 +85,9 @@ protected function getExpectedNormalizedEntity() {
             'uuid' => [
               ['value' => $author->uuid()]
             ],
-            'lang' => 'en',
           ],
         ],
-        $this->baseUrl . '/rest/relation/node/camelids/revision_uid' => [
+        $this->baseUrl . '/rest/relation/node/camelids/uid' => [
           [
             '_links' => [
               'self' => [
@@ -101,6 +100,7 @@ protected function getExpectedNormalizedEntity() {
             'uuid' => [
               ['value' => $author->uuid()]
             ],
+            'lang' => 'en',
           ],
         ],
       ],
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonAnonTest.php b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonAnonTest.php
new file mode 100644
index 0000000000..a1cdf2773c
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonAnonTest.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+use Drupal\Tests\rest\Functional\EntityResource\ShortcutSet\ShortcutSetResourceTestBase;
+
+/**
+ * @group hal
+ */
+class ShortcutSetHalJsonAnonTest extends ShortcutSetResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['hal'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'hal_json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/hal+json';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonBasicAuthTest.php b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonBasicAuthTest.php
new file mode 100644
index 0000000000..d6cce1d89f
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonBasicAuthTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class ShortcutSetHalJsonBasicAuthTest extends ShortcutSetHalJsonAnonTest {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonCookieTest.php b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonCookieTest.php
new file mode 100644
index 0000000000..e7bbf40d2e
--- /dev/null
+++ b/core/modules/hal/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetHalJsonCookieTest.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace Drupal\Tests\hal\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group hal
+ */
+class ShortcutSetHalJsonCookieTest extends ShortcutSetHalJsonAnonTest {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/image/config/schema/image.data_types.schema.yml b/core/modules/image/config/schema/image.data_types.schema.yml
index 33a902b033..9e4b9e1c16 100644
--- a/core/modules/image/config/schema/image.data_types.schema.yml
+++ b/core/modules/image/config/schema/image.data_types.schema.yml
@@ -14,8 +14,7 @@ field_default_image:
   type: mapping
   mapping:
     uuid:
-      type: string
-      label: 'Image'
+      type: uuid
     alt:
       type: label
       label: 'Alternative text'
diff --git a/core/modules/image/config/schema/image.schema.yml b/core/modules/image/config/schema/image.schema.yml
index 0006ad794e..924d454f91 100644
--- a/core/modules/image/config/schema/image.schema.yml
+++ b/core/modules/image/config/schema/image.schema.yml
@@ -21,7 +21,7 @@ image.style.*:
           weight:
             type: integer
           uuid:
-            type: string
+            type: uuid
 
 image.effect.*:
   type: mapping
diff --git a/core/modules/image/image.module b/core/modules/image/image.module
index 6107ecd909..89450cc6fe 100644
--- a/core/modules/image/image.module
+++ b/core/modules/image/image.module
@@ -292,10 +292,28 @@ function template_preprocess_image_style(&$variables) {
     '#width' => $dimensions['width'],
     '#height' => $dimensions['height'],
     '#attributes' => $variables['attributes'],
-    '#uri' => $style->buildUrl($variables['uri']),
     '#style_name' => $variables['style_name'],
   ];
 
+  // If the current image toolkit supports this file type, prepare the URI for
+  // the derivative image. If not, just use the original image resized to the
+  // dimensions specified by the style.
+  if ($style->supportsUri($variables['uri'])) {
+    $variables['image']['#uri'] = $style->buildUrl($variables['uri']);
+  }
+  else {
+    $variables['image']['#uri'] = $variables['uri'];
+    // Don't render the image by default, but allow other preprocess functions
+    // to override that if they need to.
+    $variables['image']['#access'] = FALSE;
+
+    // Inform the site builders why their image didn't work.
+    \Drupal::logger('image')->warning('Could not apply @style image style to @uri because the style does not support it.', [
+      '@style' => $style->label(),
+      '@uri' => $variables['uri'],
+    ]);
+  }
+
   if (isset($variables['alt']) || array_key_exists('alt', $variables)) {
     $variables['image']['#alt'] = $variables['alt'];
   }
diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php
index fb096a7fdb..dd261248a7 100644
--- a/core/modules/image/src/Entity/ImageStyle.php
+++ b/core/modules/image/src/Entity/ImageStyle.php
@@ -14,9 +14,11 @@
 use Drupal\image\ImageStyleInterface;
 use Drupal\Component\Utility\Crypt;
 use Drupal\Component\Utility\UrlHelper;
+use Drupal\Component\Utility\Unicode;
 use Drupal\Core\StreamWrapper\StreamWrapperInterface;
 use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
+
 /**
  * Defines an image style configuration entity.
  *
@@ -274,9 +276,8 @@ public function flush($path = NULL) {
    * {@inheritdoc}
    */
   public function createDerivative($original_uri, $derivative_uri) {
-
     // If the source file doesn't exist, return FALSE without creating folders.
-    $image = \Drupal::service('image.factory')->get($original_uri);
+    $image = $this->getImageFactory()->get($original_uri);
     if (!$image->isValid()) {
       return FALSE;
     }
@@ -343,6 +344,18 @@ public function deleteImageEffect(ImageEffectInterface $effect) {
   /**
    * {@inheritdoc}
    */
+  public function supportsUri($uri) {
+    // Only support the URI if its extension is supported by the current image
+    // toolkit.
+    return in_array(
+      Unicode::strtolower(pathinfo($uri, PATHINFO_EXTENSION)),
+      $this->getImageFactory()->getSupportedExtensions()
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getEffect($effect) {
     return $this->getEffects()->get($effect);
   }
@@ -409,6 +422,16 @@ protected function getImageEffectPluginManager() {
   }
 
   /**
+   * Returns the image factory.
+   *
+   * @return \Drupal\Core\Image\ImageFactory
+   *   The image factory.
+   */
+  protected function getImageFactory() {
+    return \Drupal::service('image.factory');
+  }
+
+  /**
    * Gets the Drupal private key.
    *
    * @return string
diff --git a/core/modules/image/src/ImageStyleInterface.php b/core/modules/image/src/ImageStyleInterface.php
index 89fd060a28..7dec361075 100644
--- a/core/modules/image/src/ImageStyleInterface.php
+++ b/core/modules/image/src/ImageStyleInterface.php
@@ -194,4 +194,15 @@ public function addImageEffect(array $configuration);
    */
   public function deleteImageEffect(ImageEffectInterface $effect);
 
+  /**
+   * Determines if this style can be applied to a given image.
+   *
+   * @param string $uri
+   *   The URI of the image.
+   *
+   * @return bool
+   *   TRUE if the image is supported, FALSE otherwise.
+   */
+  public function supportsUri($uri);
+
 }
diff --git a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
index f001743509..e994f12e27 100644
--- a/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
+++ b/core/modules/image/tests/src/Kernel/ImageFormatterTest.php
@@ -7,6 +7,8 @@
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\file\Entity\File;
+use Drupal\image\Entity\ImageStyle;
 use Drupal\Tests\field\Kernel\FieldKernelTestBase;
 
 /**
@@ -99,4 +101,89 @@ public function testImageFormatterCacheTags() {
     $this->assertEquals($entity->{$this->fieldName}[1]->entity->getCacheTags(), $build[$this->fieldName][1]['#cache']['tags'], 'Second image cache tags is as expected');
   }
 
+  /**
+   * Tests ImageFormatter's handling of SVG images.
+   *
+   * @requires extension gd
+   */
+  public function testImageFormatterSvg() {
+    // Install the default image styles.
+    $this->installConfig(['image']);
+
+    /** @var \Drupal\Core\Render\RendererInterface $renderer */
+    $renderer = $this->container->get('renderer');
+
+    $png = File::create([
+      'uri' => 'public://test-image.png',
+    ]);
+    $png->save();
+
+    // We need to create an actual empty PNG, or the GD toolkit will not
+    // consider the image valid.
+    $png_resource = imagecreate(300, 300);
+    imagefill($png_resource, 0, 0, imagecolorallocate($png_resource, 0, 0, 0));
+    imagepng($png_resource, $png->getFileUri());
+
+    $svg = File::create([
+      'uri' => 'public://test-image.svg',
+    ]);
+    $svg->save();
+    // We don't have to put any real SVG data in here, because the GD toolkit
+    // won't be able to load it anyway.
+    touch($svg->getFileUri());
+
+    $entity = EntityTest::create([
+      'name' => $this->randomMachineName(),
+      $this->fieldName => [$png, $svg],
+    ]);
+    $entity->save();
+
+    // Ensure that the display is using the medium image style.
+    $component = $this->display->getComponent($this->fieldName);
+    $component['settings']['image_style'] = 'medium';
+    $this->display->setComponent($this->fieldName, $component)->save();
+
+    $build = $this->display->build($entity);
+
+    // The first image is a PNG, so it is supported by the GD image toolkit.
+    // The image style should be applied with its cache tags, image derivative
+    // computed with its URI and dimensions.
+    $this->assertCacheTags($build[$this->fieldName][0], ImageStyle::load('medium')->getCacheTags());
+    $renderer->renderRoot($build[$this->fieldName][0]);
+    $this->assertEquals('medium', $build[$this->fieldName][0]['#image_style']);
+    // We check that the image URL contains the expected style directory
+    // structure.
+    $this->assertTrue(strpos($build[$this->fieldName][0]['#markup'], 'styles/medium/public/test-image.png') !== FALSE);
+    $this->assertTrue(strpos($build[$this->fieldName][0]['#markup'], 'width="220"') !== FALSE);
+    $this->assertTrue(strpos($build[$this->fieldName][0]['#markup'], 'height="220"') !== FALSE);
+
+    // The second image is an SVG, which is not supported by the GD toolkit.
+    // The image style should still be applied with its cache tags, but image
+    // derivative will not be available so <img> tag will point to the original
+    // image.
+    $this->assertCacheTags($build[$this->fieldName][1], ImageStyle::load('medium')->getCacheTags());
+    $renderer->renderRoot($build[$this->fieldName][1]);
+    $this->assertEquals('medium', $build[$this->fieldName][1]['#image_style']);
+    // We check that the image URL does not contain the style directory
+    // structure.
+    $this->assertFalse(strpos($build[$this->fieldName][1]['#markup'], 'styles/medium/public/test-image.svg'));
+    // Since we did not store original image dimensions, width and height
+    // HTML attributes will not be present.
+    $this->assertFalse(strpos($build[$this->fieldName][1]['#markup'], 'width'));
+    $this->assertFalse(strpos($build[$this->fieldName][1]['#markup'], 'height'));
+  }
+
+  /**
+   * Asserts that a renderable array has a set of cache tags.
+   *
+   * @param array $renderable
+   *   The renderable array. Must have a #cache[tags] element.
+   * @param array $cache_tags
+   *   The expected cache tags.
+   */
+  protected function assertCacheTags(array $renderable, array $cache_tags) {
+    $diff = array_diff($cache_tags, $renderable['#cache']['tags']);
+    $this->assertEmpty($diff);
+  }
+
 }
diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml
index 5e3f55b5f7..91ce2d1902 100644
--- a/core/modules/language/config/schema/language.schema.yml
+++ b/core/modules/language/config/schema/language.schema.yml
@@ -131,3 +131,11 @@ condition.plugin.language:
       type: sequence
       sequence:
         type: string
+
+field.widget.settings.language_select:
+  type: mapping
+  label: 'Language format settings'
+  mapping:
+    include_locked:
+      type: boolean
+      label: 'Include locked languages'
diff --git a/core/modules/language/language.post_update.php b/core/modules/language/language.post_update.php
new file mode 100644
index 0000000000..f7f9c29726
--- /dev/null
+++ b/core/modules/language/language.post_update.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for Language module.
+ */
+
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+
+/**
+ * Add the 'include_locked' settings to the 'language_select' widget.
+ */
+function language_post_update_language_select_widget() {
+  foreach (EntityFormDisplay::loadMultiple() as $display_form) {
+    $content = $display_form->get('content');
+    $changed = FALSE;
+    foreach (array_keys($content) as $element) {
+      if (isset($content[$element]['type']) && $content[$element]['type'] == 'language_select') {
+        $content[$element]['settings']['include_locked'] = TRUE;
+        $changed = TRUE;
+      }
+    }
+    if ($changed) {
+      $display_form->set('content', $content);
+      $display_form->save();
+    }
+  }
+}
diff --git a/core/modules/language/src/LanguageNegotiatorInterface.php b/core/modules/language/src/LanguageNegotiatorInterface.php
index 71f44b51b3..5c999c7f8b 100644
--- a/core/modules/language/src/LanguageNegotiatorInterface.php
+++ b/core/modules/language/src/LanguageNegotiatorInterface.php
@@ -91,7 +91,6 @@
  *     }
  *   }
  * }
- * ?>
  * @endcode
  *
  * For more information, see
diff --git a/core/modules/language/src/Tests/Update/LanguageSelectWidgetUpdateTest.php b/core/modules/language/src/Tests/Update/LanguageSelectWidgetUpdateTest.php
new file mode 100644
index 0000000000..b0559831a9
--- /dev/null
+++ b/core/modules/language/src/Tests/Update/LanguageSelectWidgetUpdateTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\language\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\Core\Entity\Entity\EntityFormDisplay;
+
+/**
+ * Tests the update path for the language_select widget.
+ *
+ * @group Update
+ */
+class LanguageSelectWidgetUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Tests language_post_update_language_select_widget().
+   */
+  public function testLanguagePostUpdateLanguageSelectWidget() {
+    // Tests before the update.
+    $content_before = EntityFormDisplay::load('node.page.default')->get('content');
+    $this->assertEqual([], $content_before['langcode']['settings']);
+
+    // Run the update.
+    $this->runUpdates();
+
+    // Tests after the update.
+    $content_after = EntityFormDisplay::load('node.page.default')->get('content');
+    $this->assertEqual(['include_locked' => TRUE], $content_after['langcode']['settings']);
+  }
+
+}
diff --git a/core/modules/language/src/Tests/EntityTypeWithoutLanguageFormTest.php b/core/modules/language/tests/src/Functional/EntityTypeWithoutLanguageFormTest.php
similarity index 87%
rename from core/modules/language/src/Tests/EntityTypeWithoutLanguageFormTest.php
rename to core/modules/language/tests/src/Functional/EntityTypeWithoutLanguageFormTest.php
index 97ccf2fd8c..f7b6191484 100644
--- a/core/modules/language/src/Tests/EntityTypeWithoutLanguageFormTest.php
+++ b/core/modules/language/tests/src/Functional/EntityTypeWithoutLanguageFormTest.php
@@ -1,8 +1,8 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests entity type without language support.
@@ -12,7 +12,7 @@
  *
  * @group language
  */
-class EntityTypeWithoutLanguageFormTest extends WebTestBase {
+class EntityTypeWithoutLanguageFormTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/language/src/Tests/LanguageConfigurationElementTest.php b/core/modules/language/tests/src/Functional/LanguageConfigurationElementTest.php
similarity index 98%
rename from core/modules/language/src/Tests/LanguageConfigurationElementTest.php
rename to core/modules/language/tests/src/Functional/LanguageConfigurationElementTest.php
index dc3eb260b6..87ad05bfd1 100644
--- a/core/modules/language/src/Tests/LanguageConfigurationElementTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageConfigurationElementTest.php
@@ -1,19 +1,19 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language\Entity\ContentLanguageSettings;
-use Drupal\simpletest\WebTestBase;
 use Drupal\taxonomy\Entity\Vocabulary;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the features of the language configuration element field.
  *
  * @group language
  */
-class LanguageConfigurationElementTest extends WebTestBase {
+class LanguageConfigurationElementTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/language/src/Tests/LanguageConfigurationTest.php b/core/modules/language/tests/src/Functional/LanguageConfigurationTest.php
similarity index 98%
rename from core/modules/language/src/Tests/LanguageConfigurationTest.php
rename to core/modules/language/tests/src/Functional/LanguageConfigurationTest.php
index 46d5ed74d1..9ed7abd1ef 100644
--- a/core/modules/language/src/Tests/LanguageConfigurationTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageConfigurationTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Adds and configures languages to check negotiation changes.
  *
  * @group language
  */
-class LanguageConfigurationTest extends WebTestBase {
+class LanguageConfigurationTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -169,10 +169,7 @@ public function testLanguageConfigurationWeight() {
     $this->checkConfigurableLanguageWeight('after re-ordering');
 
     // Remove predefined language.
-    $edit = [
-      'confirm' => 1,
-    ];
-    $this->drupalPostForm('admin/config/regional/language/delete/fr', $edit, 'Delete');
+    $this->drupalPostForm('admin/config/regional/language/delete/fr', [], 'Delete');
     $this->checkConfigurableLanguageWeight('after deleting a language');
   }
 
diff --git a/core/modules/language/src/Tests/LanguageCustomLanguageConfigurationTest.php b/core/modules/language/tests/src/Functional/LanguageCustomLanguageConfigurationTest.php
similarity index 96%
rename from core/modules/language/src/Tests/LanguageCustomLanguageConfigurationTest.php
rename to core/modules/language/tests/src/Functional/LanguageCustomLanguageConfigurationTest.php
index 2eb02df197..a0510beca7 100644
--- a/core/modules/language/src/Tests/LanguageCustomLanguageConfigurationTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageCustomLanguageConfigurationTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
-use Drupal\simpletest\WebTestBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Adds and configures custom languages.
  *
  * @group language
  */
-class LanguageCustomLanguageConfigurationTest extends WebTestBase {
+class LanguageCustomLanguageConfigurationTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/language/src/Tests/LanguageListTest.php b/core/modules/language/tests/src/Functional/LanguageListTest.php
similarity index 93%
rename from core/modules/language/src/Tests/LanguageListTest.php
rename to core/modules/language/tests/src/Functional/LanguageListTest.php
index 641ddc41e0..8c671cfccf 100644
--- a/core/modules/language/src/Tests/LanguageListTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageListTest.php
@@ -1,18 +1,18 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Adds a new language and tests changing its status and the default language.
  *
  * @group language
  */
-class LanguageListTest extends WebTestBase {
+class LanguageListTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -176,9 +176,20 @@ public function testLanguageList() {
     $this->assertResponse(403, 'Can not delete locked language');
 
     // Ensure that NL cannot be set default when it's not available.
+    // First create the NL language.
+    $edit = [
+      'predefined_langcode' => 'nl',
+    ];
+    $this->drupalPostForm('admin/config/regional/language/add', $edit, 'Add language');
+
+    // Load the form which has now the additional NL language option.
     $this->drupalGet('admin/config/regional/language');
-    $extra_values = '&site_default_language=nl';
-    $this->drupalPostForm(NULL, [], t('Save configuration'), [], [], NULL, $extra_values);
+
+    // Delete the NL language in the background.
+    $language_storage = $this->container->get('entity_type.manager')->getStorage('configurable_language');
+    $language_storage->load('nl')->delete();
+
+    $this->drupalPostForm(NULL, ['site_default_language' => 'nl'], 'Save configuration');
     $this->assertText(t('Selected default language no longer exists.'));
     $this->assertNoFieldChecked('edit-site-default-language-xx', 'The previous default language got deselected.');
   }
diff --git a/core/modules/language/src/Tests/LanguageLocaleListTest.php b/core/modules/language/tests/src/Functional/LanguageLocaleListTest.php
similarity index 84%
rename from core/modules/language/src/Tests/LanguageLocaleListTest.php
rename to core/modules/language/tests/src/Functional/LanguageLocaleListTest.php
index 5f96d89e5b..a39a112424 100644
--- a/core/modules/language/src/Tests/LanguageLocaleListTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageLocaleListTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Adds a new language with translations and tests language list order.
  *
  * @group language
  */
-class LanguageLocaleListTest extends WebTestBase {
+class LanguageLocaleListTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -57,9 +57,11 @@ public function testLanguageLocaleList() {
 
     // Get language list displayed in select list.
     $this->drupalGet('fr/admin/config/regional/language/add');
-    $select = $this->xpath('//select[@id="edit-predefined-langcode"]');
-    $select_element = (array) end($select);
-    $options = $select_element['option'];
+    $option_elements = $this->xpath('//select[@id="edit-predefined-langcode/option"]');
+    $options = [];
+    foreach ($option_elements as $option_element) {
+      $options[] = $option_element->getText();
+    }
     // Remove the 'Custom language...' option form the end.
     array_pop($options);
     // Order language list.
diff --git a/core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php b/core/modules/language/tests/src/Functional/LanguageSelectorTranslatableTest.php
similarity index 88%
rename from core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php
rename to core/modules/language/tests/src/Functional/LanguageSelectorTranslatableTest.php
index d13626cc45..3d027c3fb5 100644
--- a/core/modules/language/src/Tests/LanguageSelectorTranslatableTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageSelectorTranslatableTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the content translation settings language selector options.
  *
  * @group language
  */
-class LanguageSelectorTranslatableTest extends WebTestBase {
+class LanguageSelectorTranslatableTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -82,7 +82,7 @@ public function testLanguageStringSelector() {
     $elements = $this->xpath('//select[@id=:id]//option[@value=:option]', [':id' => 'edit-settings-user-user-settings-language-langcode', ':option' => 'en']);
 
     // Check that the language text is translated.
-    $this->assertEqual((string) $elements[0], $name_translation, 'Checking the option string English is translated to Spanish.');
+    $this->assertEqual($elements[0]->getText(), $name_translation, 'Checking the option string English is translated to Spanish.');
   }
 
 }
diff --git a/core/modules/language/src/Tests/LanguageSwitchingTest.php b/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php
similarity index 94%
rename from core/modules/language/src/Tests/LanguageSwitchingTest.php
rename to core/modules/language/tests/src/Functional/LanguageSwitchingTest.php
index 40015210eb..1303082c15 100644
--- a/core/modules/language/src/Tests/LanguageSwitchingTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageSwitchingTest.php
@@ -1,19 +1,19 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
 use Drupal\menu_link_content\Entity\MenuLinkContent;
 use Drupal\Core\Language\LanguageInterface;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Functional tests for the language switching feature.
  *
  * @group language
  */
-class LanguageSwitchingTest extends WebTestBase {
+class LanguageSwitchingTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -73,22 +73,24 @@ protected function doTestLanguageBlockAuthenticated($block_label) {
 
     // Assert that each list item and anchor element has the appropriate data-
     // attributes.
-    list($language_switcher) = $this->xpath('//div[@id=:id]', [':id' => 'block-test-language-block']);
+    $language_switchers = $this->xpath('//div[@id=:id]/ul/li', [':id' => 'block-test-language-block']);
     $list_items = [];
     $anchors = [];
     $labels = [];
-    foreach ($language_switcher->ul->li as $list_item) {
-      $classes = explode(" ", (string) $list_item['class']);
+    foreach ($language_switchers as $list_item) {
+      $classes = explode(" ", $list_item->getAttribute('class'));
       list($langcode) = array_intersect($classes, ['en', 'fr']);
       $list_items[] = [
         'langcode_class' => $langcode,
-        'data-drupal-link-system-path' => (string) $list_item['data-drupal-link-system-path'],
+        'data-drupal-link-system-path' => $list_item->getAttribute('data-drupal-link-system-path'),
       ];
+
+      $link = $list_item->find('xpath', 'a');
       $anchors[] = [
-        'hreflang' => (string) $list_item->a['hreflang'],
-        'data-drupal-link-system-path' => (string) $list_item->a['data-drupal-link-system-path'],
+         'hreflang' => $link->getAttribute('hreflang'),
+         'data-drupal-link-system-path' => $link->getAttribute('data-drupal-link-system-path'),
       ];
-      $labels[] = (string) $list_item->a;
+      $labels[] = $link->getText();
     }
     $expected_list_items = [
       0 => ['langcode_class' => 'en', 'data-drupal-link-system-path' => 'user/2'],
@@ -124,7 +126,7 @@ protected function doTestLanguageBlockAnonymous($block_label) {
     $this->assertText($block_label, 'Language switcher block found.');
 
     // Assert that only the current language is marked as active.
-    list($language_switcher) = $this->xpath('//div[@id=:id]', [':id' => 'block-test-language-block']);
+    $language_switchers = $this->xpath('//div[@id=:id]/ul/li', [':id' => 'block-test-language-block']);
     $links = [
       'active' => [],
       'inactive' => [],
@@ -134,8 +136,8 @@ protected function doTestLanguageBlockAnonymous($block_label) {
       'inactive' => [],
     ];
     $labels = [];
-    foreach ($language_switcher->ul->li as $link) {
-      $classes = explode(" ", (string) $link['class']);
+    foreach ($language_switchers as $list_item) {
+      $classes = explode(" ", $list_item->getAttribute('class'));
       list($langcode) = array_intersect($classes, ['en', 'fr']);
       if (in_array('is-active', $classes)) {
         $links['active'][] = $langcode;
@@ -143,14 +145,16 @@ protected function doTestLanguageBlockAnonymous($block_label) {
       else {
         $links['inactive'][] = $langcode;
       }
-      $anchor_classes = explode(" ", (string) $link->a['class']);
+
+      $link = $list_item->find('xpath', 'a');
+      $anchor_classes = explode(" ", $link->getAttribute('class'));
       if (in_array('is-active', $anchor_classes)) {
         $anchors['active'][] = $langcode;
       }
       else {
         $anchors['inactive'][] = $langcode;
       }
-      $labels[] = (string) $link->a;
+      $labels[] = $link->getText();
     }
     $this->assertIdentical($links, ['active' => ['en'], 'inactive' => ['fr']], 'Only the current language list item is marked as active on the language switcher block.');
     $this->assertIdentical($anchors, ['active' => ['en'], 'inactive' => ['fr']], 'Only the current language anchor is marked as active on the language switcher block.');
@@ -208,7 +212,7 @@ public function testLanguageBlockWithDomain() {
       ':hreflang' => 'en',
     ]);
     $english_url = $generator->generateFromRoute('entity.user.canonical', ['user' => 2], ['language' => $languages['en']]);
-    $this->assertEqual($english_url, (string) $english_link['href']);
+    $this->assertEqual($english_url, $english_link->getAttribute('href'));
 
     // Verify the Italian URL is correct
     list($italian_link) = $this->xpath('//div[@id=:id]/ul/li/a[@hreflang=:hreflang]', [
@@ -216,7 +220,7 @@ public function testLanguageBlockWithDomain() {
       ':hreflang' => 'it',
     ]);
     $italian_url = $generator->generateFromRoute('entity.user.canonical', ['user' => 2], ['language' => $languages['it']]);
-    $this->assertEqual($italian_url, (string) $italian_link['href']);
+    $this->assertEqual($italian_url, $italian_link->getAttribute('href'));
   }
 
   /**
diff --git a/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/tests/src/Functional/LanguageUILanguageNegotiationTest.php
similarity index 97%
rename from core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
rename to core/modules/language/tests/src/Functional/LanguageUILanguageNegotiationTest.php
index 3f54cf9bff..34f0c81f01 100644
--- a/core/modules/language/src/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageUILanguageNegotiationTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\Core\Url;
 use Drupal\language\Entity\ConfigurableLanguage;
@@ -8,9 +8,9 @@
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSelected;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationSession;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
+use Drupal\Tests\BrowserTestBase;
 use Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUser;
 use Drupal\user\Plugin\LanguageNegotiation\LanguageNegotiationUserAdmin;
-use Drupal\simpletest\WebTestBase;
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -37,7 +37,7 @@
  *
  * @group language
  */
-class LanguageUILanguageNegotiationTest extends WebTestBase {
+class LanguageUILanguageNegotiationTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -69,9 +69,9 @@ public function testUILanguageNegotiation() {
     // For testing path prefix.
     $langcode = 'zh-hans';
     // For setting browser language preference to 'vi'.
-    $http_header_browser_fallback = ["Accept-Language: $langcode_browser_fallback;q=1"];
+    $http_header_browser_fallback = ["Accept-Language" => "$langcode_browser_fallback;q=1"];
     // For setting browser language preference to some unknown.
-    $http_header_blah = ["Accept-Language: blah;q=1"];
+    $http_header_blah = ["Accept-Language" => "blah;q=1"];
 
     // Setup the site languages by installing two languages.
     // Set the default language in order for the translated string to be registered
@@ -107,7 +107,7 @@ public function testUILanguageNegotiation() {
     ];
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
     $textarea = current($this->xpath('//textarea'));
-    $lid = (string) $textarea[0]['name'];
+    $lid = $textarea->getAttribute('name');
     $edit = [
       $lid => $language_browser_fallback_string,
     ];
@@ -119,7 +119,7 @@ public function testUILanguageNegotiation() {
     ];
     $this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
     $textarea = current($this->xpath('//textarea'));
-    $lid = (string) $textarea[0]['name'];
+    $lid = $textarea->getAttribute('name');
     $edit = [
       $lid => $language_string,
     ];
@@ -398,7 +398,7 @@ public function testUrlLanguageFallback() {
 
     // Access the front page without specifying any valid URL language prefix
     // and having as browser language preference a non-default language.
-    $http_header = ["Accept-Language: $langcode_browser_fallback;q=1"];
+    $http_header = ["Accept-Language" => "$langcode_browser_fallback;q=1"];
     $language = new Language(['id' => '']);
     $this->drupalGet('', ['language' => $language], $http_header);
 
@@ -406,11 +406,11 @@ public function testUrlLanguageFallback() {
     // language.
     $args = [':id' => 'block-test-language-block', ':url' => \Drupal::url('<front>') . $langcode_browser_fallback];
     $fields = $this->xpath('//div[@id=:id]//a[@class="language-link is-active" and starts-with(@href, :url)]', $args);
-    $this->assertTrue($fields[0] == $languages[$langcode_browser_fallback]->getName(), 'The browser language is the URL active language');
+    $this->assertSame($fields[0]->getText(), $languages[$langcode_browser_fallback]->getName(), 'The browser language is the URL active language');
 
     // Check that URLs are rewritten using the given browser language.
     $fields = $this->xpath('//div[@class="site-name"]/a[@rel="home" and @href=:url]', $args);
-    $this->assertTrue($fields[0] == 'Drupal', 'URLs are rewritten using the browser language.');
+    $this->assertSame($fields[0]->getText(), 'Drupal', 'URLs are rewritten using the browser language.');
   }
 
   /**
diff --git a/core/modules/language/src/Tests/LanguageUrlRewritingTest.php b/core/modules/language/tests/src/Functional/LanguageUrlRewritingTest.php
similarity index 96%
rename from core/modules/language/src/Tests/LanguageUrlRewritingTest.php
rename to core/modules/language/tests/src/Functional/LanguageUrlRewritingTest.php
index 65ae64c37b..7021aa0027 100644
--- a/core/modules/language/src/Tests/LanguageUrlRewritingTest.php
+++ b/core/modules/language/tests/src/Functional/LanguageUrlRewritingTest.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\language\Tests;
+namespace Drupal\Tests\language\Functional;
 
 use Drupal\Core\Language\Language;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationUrl;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -14,7 +14,7 @@
  *
  * @group language
  */
-class LanguageUrlRewritingTest extends WebTestBase {
+class LanguageUrlRewritingTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -90,9 +90,8 @@ private function checkUrl(LanguageInterface $language, $message1, $message2) {
     // we can always check the prefixed URL.
     $prefixes = language_negotiation_url_prefixes();
     $stored_prefix = isset($prefixes[$language->getId()]) ? $prefixes[$language->getId()] : $this->randomMachineName();
-    if ($this->assertNotEqual($stored_prefix, $prefix, $message1)) {
-      $prefix = $stored_prefix;
-    }
+    $this->assertNotEqual($stored_prefix, $prefix, $message1);
+    $prefix = $stored_prefix;
 
     $this->drupalGet("$prefix/$path");
     $this->assertResponse(404, $message2);
diff --git a/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php b/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php
new file mode 100644
index 0000000000..966275caa3
--- /dev/null
+++ b/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Drupal\Tests\language\Kernel;
+
+use Drupal\entity_test\Entity\EntityTest;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests the language select widget.
+ *
+ * @group language
+ */
+class LanguageSelectWidgetTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'entity_test',
+    'language',
+    'user',
+    'system',
+  ];
+
+  /**
+   * The entity form display.
+   *
+   * @var \Drupal\Core\Entity\Entity\EntityFormDisplay
+   */
+  protected $entityFormDisplay;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installEntitySchema('entity_test');
+    $this->installEntitySchema('user');
+
+    $storage = $this->container->get('entity_type.manager')->getStorage('entity_form_display');
+    $this->entityFormDisplay = $storage->create([
+      'targetEntityType' => 'entity_test',
+      'bundle' => 'entity_test',
+      'mode' => 'default',
+      'status' => TRUE,
+    ]);
+  }
+
+  /**
+   * Tests the widget with the locked languages.
+   */
+  public function testWithIncludedLockedLanguage() {
+    $this->entityFormDisplay->setComponent('langcode', [
+      'type' => 'language_select',
+    ])->save();
+    $entity = EntityTest::create(['name' => $this->randomString()]);
+    $form = $this->container->get('entity.form_builder')->getForm($entity);
+    $options = array_keys($form['langcode']['widget'][0]['value']['#options']);
+    $this->assertSame(['en', 'und', 'zxx'], $options);
+  }
+
+  /**
+   * Test the widget without the locked languages.
+   */
+  public function testWithoutIncludedLockedLanguage() {
+    $this->entityFormDisplay->setComponent('langcode', [
+      'type' => 'language_select',
+      'settings' => ['include_locked' => FALSE],
+    ])->save();
+    $entity = EntityTest::create(['name' => $this->randomString()]);
+    $form = $this->container->get('entity.form_builder')->getForm($entity);
+    $options = array_keys($form['langcode']['widget'][0]['value']['#options']);
+    $this->assertSame(['en'], $options);
+  }
+
+}
diff --git a/core/modules/layout_discovery/layout_discovery.layouts.yml b/core/modules/layout_discovery/layout_discovery.layouts.yml
index 98b1ed6126..d1b0e5a3a8 100644
--- a/core/modules/layout_discovery/layout_discovery.layouts.yml
+++ b/core/modules/layout_discovery/layout_discovery.layouts.yml
@@ -15,14 +15,14 @@ layout_twocol:
   template: layout--twocol
   library: layout_discovery/twocol
   category: 'Columns: 2'
-  default_region: left
+  default_region: first
   regions:
     top:
       label: Top
-    left:
-      label: Left
-    right:
-      label: Right
+    first:
+      label: First
+    second:
+      label: Second
     bottom:
       label: Bottom
 
@@ -36,16 +36,16 @@ layout_twocol_bricks:
   regions:
     top:
       label: Top
-    left_above:
-      label: 'Left above'
-    right_above:
-      label: 'Right above'
+    first_above:
+      label: 'First above'
+    second_above:
+      label: 'Second above'
     middle:
       label: Middle
-    left_below:
-      label: 'Left below'
-    right_below:
-      label: 'Right below'
+    first_below:
+      label: 'First below'
+    second_below:
+      label: 'Second below'
     bottom:
       label: Bottom
 
@@ -55,16 +55,16 @@ layout_threecol_25_50_25:
   template: layout--threecol-25-50-25
   library: layout_discovery/threecol_25_50_25
   category: 'Columns: 3'
-  default_region: left
+  default_region: second
   regions:
     top:
       label: Top
-    left:
-      label: Left
-    middle:
-      label: Middle
-    right:
-      label: Right
+    first:
+      label: First
+    second:
+      label: Second
+    third:
+      label: Third
     bottom:
       label: Bottom
 
@@ -74,15 +74,15 @@ layout_threecol_33_34_33:
   template: layout--threecol-33-34-33
   library: layout_discovery/threecol_33_34_33
   category: 'Columns: 3'
-  default_region: left
+  default_region: first
   regions:
     top:
       label: Top
-    left:
-      label: Left
-    middle:
-      label: Middle
-    right:
-      label: Right
+    first:
+      label: First
+    second:
+      label: Second
+    third:
+      label: Third
     bottom:
       label: Bottom
diff --git a/core/modules/layout_discovery/layouts/onecol/layout--onecol.html.twig b/core/modules/layout_discovery/layouts/onecol/layout--onecol.html.twig
index eb553cdf8a..64b9b4e5b9 100644
--- a/core/modules/layout_discovery/layouts/onecol/layout--onecol.html.twig
+++ b/core/modules/layout_discovery/layouts/onecol/layout--onecol.html.twig
@@ -11,14 +11,15 @@
  */
 #}
 {%
-set classes = [
-'layout--onecol',
-]
+  set classes = [
+    'layout',
+    'layout--onecol',
+  ]
 %}
 {% if content %}
-<div{{ attributes.addClass(classes) }}>
-  <div class="layout-region layout-region--content">
-    {{ content.content }}
+  <div{{ attributes.addClass(classes) }}>
+    <div class="layout__region layout__region--content">
+      {{ content.content }}
+    </div>
   </div>
-</div>
 {% endif %}
diff --git a/core/modules/layout_discovery/layouts/onecol/onecol.css b/core/modules/layout_discovery/layouts/onecol/onecol.css
index 040b7f10c1..e2283c5888 100644
--- a/core/modules/layout_discovery/layouts/onecol/onecol.css
+++ b/core/modules/layout_discovery/layouts/onecol/onecol.css
@@ -1,3 +1,7 @@
-.layout--onecol .layout-region {
+/*
+ * @file
+ * Provides the layout styles for layout_onecol.
+ */
+.layout--onecol .layout__region {
   width: 100%;
 }
diff --git a/core/modules/layout_discovery/layouts/threecol_25_50_25/layout--threecol-25-50-25.html.twig b/core/modules/layout_discovery/layouts/threecol_25_50_25/layout--threecol-25-50-25.html.twig
index 78db2b4b32..85255252ce 100644
--- a/core/modules/layout_discovery/layouts/threecol_25_50_25/layout--threecol-25-50-25.html.twig
+++ b/core/modules/layout_discovery/layouts/threecol_25_50_25/layout--threecol-25-50-25.html.twig
@@ -14,34 +14,41 @@
  */
 #}
 {%
-set classes = [
-'layout--threecol',
-]
+  set classes = [
+    'layout',
+    'layout--threecol-25-50-25',
+  ]
 %}
 {% if content %}
-<div{{ attributes.addClass(classes) }}>
-  {% if content.top %}
-    <div class="layout-region layout-region--fullwidth">
-      {{ content.top }}
-    </div>
-  {% endif %}
+  <div{{ attributes.addClass(classes) }}>
+    {% if content.top %}
+      <div class="layout__region layout__region--top">
+        {{ content.top }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--side">
-    {{ content.left }}
-  </div>
+    {% if content.first %}
+      <div class="layout__region layout__region--first">
+        {{ content.first }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--middle">
-    {{ content.middle }}
-  </div>
+    {% if content.second %}
+      <div class="layout__region layout__region--second">
+        {{ content.second }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--side">
-    {{ content.right }}
-  </div>
+    {% if content.third %}
+      <div class="layout__region layout__region--third">
+        {{ content.third }}
+      </div>
+    {% endif %}
 
-  {% if content.bottom %}
-    <div class="layout-region layout-region--fullwidth">
-      {{ content.bottom }}
-    </div>
-  {% endif %}
-</div>
+    {% if content.bottom %}
+      <div class="layout__region layout__region--bottom">
+        {{ content.bottom }}
+      </div>
+    {% endif %}
+  </div>
 {% endif %}
diff --git a/core/modules/layout_discovery/layouts/threecol_25_50_25/threecol_25_50_25.css b/core/modules/layout_discovery/layouts/threecol_25_50_25/threecol_25_50_25.css
index 7472d55d66..1f41f46054 100644
--- a/core/modules/layout_discovery/layouts/threecol_25_50_25/threecol_25_50_25.css
+++ b/core/modules/layout_discovery/layouts/threecol_25_50_25/threecol_25_50_25.css
@@ -1,17 +1,26 @@
-.layout--threecol {
+/*
+ * @file
+ * Provides the layout styles for layout_threecol_25_50_25.
+ *
+ * @todo Using display: flex requires https://www.drupal.org/node/2842298 to be
+ * in before this can be marked as stable.
+ */
+.layout--threecol-25-50-25 {
   display: flex;
   flex-wrap: wrap;
-  justify-content: space-between;
 }
 
-.layout--threecol > .layout-region {
-  flex: 0 1 25%;
-}
-
-.layout--threecol > .layout-region--fullwidth {
+.layout--threecol-25-50-25 > .layout__region,
+.layout--threecol-25-50-25 > .layout__region--second {
   flex: 0 1 100%;
 }
 
-.layout--threecol > .layout-region--middle {
-  flex: 0 1 50%;
+@media screen and (min-width: 40em) {
+  .layout--threecol-25-50-25 > .layout__region--first,
+  .layout--threecol-25-50-25 > .layout__region--third {
+    flex: 0 1 25%;
+  }
+  .layout--threecol-25-50-25 > .layout__region--second {
+    flex: 0 1 50%;
+  }
 }
diff --git a/core/modules/layout_discovery/layouts/threecol_33_34_33/layout--threecol-33-34-33.html.twig b/core/modules/layout_discovery/layouts/threecol_33_34_33/layout--threecol-33-34-33.html.twig
index 59461f42c2..5eabb04078 100644
--- a/core/modules/layout_discovery/layouts/threecol_33_34_33/layout--threecol-33-34-33.html.twig
+++ b/core/modules/layout_discovery/layouts/threecol_33_34_33/layout--threecol-33-34-33.html.twig
@@ -14,34 +14,41 @@
  */
 #}
 {%
-set classes = [
-'layout--threecol-33',
-]
+  set classes = [
+    'layout',
+    'layout--threecol-33-34-33',
+  ]
 %}
 {% if content %}
-<div{{ attributes.addClass(classes) }}>
-  {% if content.top %}
-  <div class="layout-region layout-region--fullwidth">
-    {{ content.top }}
-  </div>
-  {% endif %}
+  <div{{ attributes.addClass(classes) }}>
+    {% if content.top %}
+      <div class="layout__region layout__region--top">
+        {{ content.top }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region">
-    {{ content.left }}
-  </div>
+    {% if content.first %}
+      <div class="layout__region layout__region--first">
+        {{ content.first }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region">
-    {{ content.middle }}
-  </div>
+    {% if content.second %}
+      <div class="layout__region layout__region--second">
+        {{ content.second }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region">
-    {{ content.right }}
-  </div>
+    {% if content.third %}
+      <div class="layout__region layout__region--third">
+        {{ content.third }}
+      </div>
+    {% endif %}
 
-  {% if content.bottom %}
-  <div class="layout-region layout-region--fullwidth">
-    {{ content.bottom }}
+    {% if content.bottom %}
+      <div class="layout__region layout__region--bottom">
+        {{ content.bottom }}
+      </div>
+    {% endif %}
   </div>
-  {% endif %}
-</div>
 {% endif %}
diff --git a/core/modules/layout_discovery/layouts/threecol_33_34_33/threecol_33_34_33.css b/core/modules/layout_discovery/layouts/threecol_33_34_33/threecol_33_34_33.css
index 7091416fdf..29a816fce5 100644
--- a/core/modules/layout_discovery/layouts/threecol_33_34_33/threecol_33_34_33.css
+++ b/core/modules/layout_discovery/layouts/threecol_33_34_33/threecol_33_34_33.css
@@ -1,13 +1,24 @@
-.layout--threecol-33 {
+/*
+ * @file
+ * Provides the layout styles for layout_threecol_33_34_33.
+ *
+ * @todo Using display: flex requires https://www.drupal.org/node/2842298 to be
+ * in before this can be marked as stable.
+ */
+
+.layout--threecol-33-34-33 {
   display: flex;
   flex-wrap: wrap;
-  justify-content: space-between;
 }
 
-.layout--threecol-33 > .layout-region {
-  flex: 0 1 33%;
+.layout--threecol-33-34-33 > .layout__region {
+  flex: 0 1 100%;
 }
 
-.layout--threecol-33 > .layout-region--fullwidth {
-  flex: 0 1 100%;
+@media screen and (min-width: 40em) {
+  .layout--threecol-33-34-33 > .layout__region--first,
+  .layout--threecol-33-34-33 > .layout__region--second,
+  .layout--threecol-33-34-33 > .layout__region--third {
+    flex: 0 1 33%;
+  }
 }
diff --git a/core/modules/layout_discovery/layouts/twocol/layout--twocol.html.twig b/core/modules/layout_discovery/layouts/twocol/layout--twocol.html.twig
index efebf0f95e..b416cbd471 100644
--- a/core/modules/layout_discovery/layouts/twocol/layout--twocol.html.twig
+++ b/core/modules/layout_discovery/layouts/twocol/layout--twocol.html.twig
@@ -11,26 +11,35 @@
  */
 #}
 {%
-set classes = [
-'layout--twocol',
-]
+  set classes = [
+    'layout',
+    'layout--twocol',
+  ]
 %}
 {% if content %}
   <div{{ attributes.addClass(classes) }}>
-    <div class="layout-region layout-region--fullwidth">
-      {{ content.top }}
-    </div>
+    {% if content.top %}
+      <div class="layout__region layout__region--top">
+        {{ content.top }}
+      </div>
+    {% endif %}
 
-    <div class="layout-region layout-region--left">
-      {{ content.left }}
-    </div>
+    {% if content.first %}
+      <div class="layout__region layout__region--first">
+        {{ content.first }}
+      </div>
+    {% endif %}
 
-    <div class="layout-region layout-region--right">
-      {{ content.right }}
-    </div>
+    {% if content.second %}
+      <div class="layout__region layout__region--second">
+        {{ content.second }}
+      </div>
+    {% endif %}
 
-    <div class="layout-region layout-region--fullwidth">
-      {{ content.bottom }}
-    </div>
+    {% if content.bottom %}
+      <div class="layout__region layout__region--bottom">
+        {{ content.bottom }}
+      </div>
+    {% endif %}
   </div>
 {% endif %}
diff --git a/core/modules/layout_discovery/layouts/twocol/twocol.css b/core/modules/layout_discovery/layouts/twocol/twocol.css
index 41e8883ddf..be9b59bb73 100644
--- a/core/modules/layout_discovery/layouts/twocol/twocol.css
+++ b/core/modules/layout_discovery/layouts/twocol/twocol.css
@@ -1,13 +1,23 @@
+/*
+ * @file
+ * Provides the layout styles for layout_twocol.
+ *
+ * @todo Using display: flex requires https://www.drupal.org/node/2842298 to be
+ * in before this can be marked as stable.
+ */
+
 .layout--twocol {
   display: flex;
   flex-wrap: wrap;
-  justify-content: space-between;
 }
 
-.layout--twocol > .layout-region {
-  flex: 0 1 50%;
+.layout--twocol > .layout__region {
+  flex: 0 1 100%;
 }
 
-.layout--twocol > .layout-region--fullwidth {
-  flex: 0 1 100%;
+@media screen and (min-width: 40em) {
+  .layout--twocol > .layout__region--first,
+  .layout--twocol > .layout__region--second {
+    flex: 0 1 50%;
+  }
 }
diff --git a/core/modules/layout_discovery/layouts/twocol_bricks/layout--twocol-bricks.html.twig b/core/modules/layout_discovery/layouts/twocol_bricks/layout--twocol-bricks.html.twig
index 9c6231b8b5..10995771bf 100644
--- a/core/modules/layout_discovery/layouts/twocol_bricks/layout--twocol-bricks.html.twig
+++ b/core/modules/layout_discovery/layouts/twocol_bricks/layout--twocol-bricks.html.twig
@@ -14,38 +14,53 @@
  */
 #}
 {%
-set classes = [
-'layout--twocol-bricks',
-]
+  set classes = [
+    'layout',
+    'layout--twocol-bricks',
+  ]
 %}
 {% if content %}
-<div{{ attributes.addClass(classes) }}>
-  <div class="layout-region layout-region--fullwidth">
-    {{ content.top }}
-  </div>
+  <div{{ attributes.addClass(classes) }}>
+    {% if content.top %}
+      <div class="layout__region layout__region--top">
+        {{ content.top }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--left_above">
-    {{ content.left_above }}
-  </div>
+    {% if content.first_above %}
+      <div class="layout__region layout__region--first-above">
+        {{ content.first_above }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--right_above">
-    {{ content.right_above }}
-  </div>
+    {% if content.second_above %}
+      <div class="layout__region layout__region--second-above">
+        {{ content.second_above }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--middle">
-    {{ content.middle }}
-  </div>
+    {% if content.middle %}
+      <div class="layout__region layout__region--middle">
+        {{ content.middle }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--left_below">
-    {{ content.left_below }}
-  </div>
+    {% if content.first_below %}
+      <div class="layout__region layout__region--first-below">
+        {{ content.first_below }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--right_below">
-    {{ content.right_below }}
-  </div>
+    {% if content.second_below %}
+      <div class="layout__region layout__region--second-below">
+        {{ content.second_below }}
+      </div>
+    {% endif %}
 
-  <div class="layout-region layout-region--fullwidth">
-    {{ content.bottom }}
+    {% if content.bottom %}
+      <div class="layout__region layout__region--bottom">
+        {{ content.bottom }}
+      </div>
+    {% endif %}
   </div>
-</div>
 {% endif %}
diff --git a/core/modules/layout_discovery/layouts/twocol_bricks/twocol_bricks.css b/core/modules/layout_discovery/layouts/twocol_bricks/twocol_bricks.css
index aef887a4ac..c8466aff7d 100644
--- a/core/modules/layout_discovery/layouts/twocol_bricks/twocol_bricks.css
+++ b/core/modules/layout_discovery/layouts/twocol_bricks/twocol_bricks.css
@@ -1,13 +1,25 @@
+/*
+ * @file
+ * Provides the layout styles for layout_twocol_bricks.
+ *
+ * @todo Using display: flex requires https://www.drupal.org/node/2842298 to be
+ * in before this can be marked as stable.
+ */
+
 .layout--twocol-bricks {
   display: flex;
   flex-wrap: wrap;
-  justify-content: space-between;
 }
 
-.layout--twocol-bricks > .layout-region {
-  flex: 0 1 50%;
+.layout--twocol-bricks > .layout__region {
+  flex: 0 1 100%;
 }
 
-.layout--twocol-bricks > .layout-region--fullwidth {
-  flex: 0 1 100%;
+@media screen and (min-width: 40em) {
+  .layout--twocol-bricks > .layout__region--first-above,
+  .layout--twocol-bricks > .layout__region--second-above,
+  .layout--twocol-bricks > .layout__region--first-below,
+  .layout--twocol-bricks > .layout__region--second-below {
+    flex: 0 1 50%;
+  }
 }
diff --git a/core/modules/layout_discovery/templates/layout.html.twig b/core/modules/layout_discovery/templates/layout.html.twig
index 88ea7457d4..6ba96d5ecd 100644
--- a/core/modules/layout_discovery/templates/layout.html.twig
+++ b/core/modules/layout_discovery/templates/layout.html.twig
@@ -4,15 +4,20 @@
  * Template for a generic layout.
  */
 #}
-{% set classes = [
-  'layout--' ~ layout.id|clean_class,
-] %}
+{%
+  set classes = [
+    'layout',
+    'layout--' ~ layout.id|clean_class,
+  ]
+%}
 {% if content %}
-<div{{ attributes.addClass(classes) }}>
-{% for region in layout.getRegionNames %}
-  <div class="{{ 'region--' ~ region|clean_class }}">
-    {{ content[region] }}
+  <div{{ attributes.addClass(classes) }}>
+    {% for region in layout.getRegionNames %}
+      {% if content[region] %}
+        <div class="{{ 'layout__region layout__region--' ~ region|clean_class }}">
+          {{ content[region] }}
+        </div>
+      {% endif %}
+    {% endfor %}
   </div>
-{% endfor %}
-</div>
 {% endif %}
diff --git a/core/modules/layout_discovery/tests/src/Kernel/LayoutTest.php b/core/modules/layout_discovery/tests/src/Kernel/LayoutTest.php
index 9d4c446d3c..fa8fdd6563 100644
--- a/core/modules/layout_discovery/tests/src/Kernel/LayoutTest.php
+++ b/core/modules/layout_discovery/tests/src/Kernel/LayoutTest.php
@@ -38,12 +38,11 @@ protected function setUp() {
    *
    * @dataProvider renderLayoutData
    */
-  public function testRenderLayout($layout_id, $config, $regions, $html) {
+  public function testRenderLayout($layout_id, $config, $regions, array $html) {
     $layout = $this->layoutPluginManager->createInstance($layout_id, $config);
     $built['layout'] = $layout->build($regions);
-    $built['layout']['#prefix'] = 'Test prefix';
-    $built['layout']['#suffix'] = 'Test suffix';
-    $html = 'Test prefix' . $html . "\n" . 'Test suffix';
+    $built['layout']['#prefix'] = 'Test prefix' . "\n";
+    $built['layout']['#suffix'] = 'Test suffix' . "\n";
 
     // Assume each layout is contained by a form, in order to ensure the
     // building of the layout does not interfere with form processing.
@@ -53,14 +52,40 @@ public function testRenderLayout($layout_id, $config, $regions, $html) {
     $form_builder->processForm('the_form_id', $built, $form_state);
 
     $this->render($built);
-    $this->assertRaw($html);
-    $this->assertRaw('<input data-drupal-selector="edit-the-form-id" type="hidden" name="form_id" value="the_form_id" />');
+
+    // Add in the wrapping form elements and prefix/suffix.
+    array_unshift($html, 'Test prefix');
+    array_unshift($html, '<form data-drupal-selector="the-form-id" action="/" method="post" id="the-form-id" accept-charset="UTF-8">');
+    // Retrieve the build ID from the rendered HTML since the string is random.
+    $build_id_input = $this->cssSelect('input[name="form_build_id"]')[0]->asXML();
+    $form_id_input = '<input data-drupal-selector="edit-the-form-id" type="hidden" name="form_id" value="the_form_id"/>';
+    $html[] = 'Test suffix';
+    $html[] = $build_id_input . $form_id_input . '</form>';
+
+    // Match the HTML to the full form element.
+    $this->assertSame(implode("\n", $html), $this->cssSelect('#the-form-id')[0]->asXML());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function render(array &$elements) {
+    $content = parent::render($elements);
+    // Strip leading whitespace from every line.
+    $this->content = preg_replace('/^\s+/m', '', $content);
+    return $this->content;
   }
 
   /**
    * Data provider for testRenderLayout().
    */
   public function renderLayoutData() {
+    $html = [];
+    $html[] = '<div data-drupal-selector="edit-layout" class="layout layout--onecol">';
+    $html[] = '<div class="layout__region layout__region--content">';
+    $html[] = 'This is the content';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_onecol'] = [
       'layout_onecol',
       [],
@@ -69,7 +94,18 @@ public function renderLayoutData() {
           '#markup' => 'This is the content',
         ],
       ],
+      $html,
     ];
+
+    $html = [];
+    $html[] = '<div class="layout-example-1col clearfix">';
+    $html[] = '<div class="region-top">';
+    $html[] = 'This string added by #process.';
+    $html[] = '</div>';
+    $html[] = '<div class="region-bottom">';
+    $html[] = 'This is the bottom';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_test_1col_with_form'] = [
       'layout_test_1col',
       [],
@@ -81,8 +117,18 @@ public function renderLayoutData() {
           '#markup' => 'This is the bottom',
         ],
       ],
+      $html,
     ];
 
+    $html = [];
+    $html[] = '<div class="layout-example-1col clearfix">';
+    $html[] = '<div class="region-top">';
+    $html[] = 'This is the top';
+    $html[] = '</div>';
+    $html[] = '<div class="region-bottom">';
+    $html[] = 'This is the bottom';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_test_1col'] = [
       'layout_test_1col',
       [],
@@ -94,8 +140,18 @@ public function renderLayoutData() {
           '#markup' => 'This is the bottom',
         ],
       ],
+      $html,
     ];
 
+    $html = [];
+    $html[] = '<div data-drupal-selector="edit-layout" class="layout layout--layout-test-1col-no-template">';
+    $html[] = '<div class="layout__region layout__region--top">';
+    $html[] = 'This is the top';
+    $html[] = '</div>';
+    $html[] = '<div class="layout__region layout__region--bottom">';
+    $html[] = 'This is the bottom';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_test_1col_no_template'] = [
       'layout_test_1col_no_template',
       [],
@@ -107,8 +163,18 @@ public function renderLayoutData() {
           '#markup' => 'This is the bottom',
         ],
       ],
+      $html,
     ];
 
+    $html = [];
+    $html[] = '<div class="layout-example-2col clearfix">';
+    $html[] = '<div class="region-left">';
+    $html[] = 'This is the left';
+    $html[] = '</div>';
+    $html[] = '<div class="region-right">';
+    $html[] = 'This is the right';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_test_2col'] = [
       'layout_test_2col',
       [],
@@ -120,8 +186,19 @@ public function renderLayoutData() {
           '#markup' => 'This is the right',
         ],
       ],
+      $html,
     ];
 
+    $html = [];
+    $html[] = '<div class="layout-test-plugin clearfix">';
+    $html[] = '<div>';
+    $html[] = '<span class="setting-1-label">Blah: </span>';
+    $html[] = 'Config value';
+    $html[] = '</div>';
+    $html[] = '<div class="region-main">';
+    $html[] = 'Main region';
+    $html[] = '</div>';
+    $html[] = '</div>';
     $data['layout_test_plugin'] = [
       'layout_test_plugin',
       [
@@ -132,72 +209,9 @@ public function renderLayoutData() {
           '#markup' => 'Main region',
         ],
       ],
+      $html,
     ];
 
-    $data['layout_onecol'][] = <<<'EOD'
-<div data-drupal-selector="edit-layout" class="layout--onecol">
-  <div class="layout-region layout-region--content">
-    This is the content
-  </div>
-</div>
-EOD;
-
-    $data['layout_test_1col_with_form'][] = <<<'EOD'
-<div class="layout-example-1col clearfix">
-  <div class="region-top">
-    This string added by #process.
-  </div>
-  <div class="region-bottom">
-    This is the bottom
-  </div>
-</div>
-EOD;
-
-    $data['layout_test_1col'][] = <<<'EOD'
-<div class="layout-example-1col clearfix">
-  <div class="region-top">
-    This is the top
-  </div>
-  <div class="region-bottom">
-    This is the bottom
-  </div>
-</div>
-EOD;
-
-    $data['layout_test_1col_no_template'][] = <<<'EOD'
-<div data-drupal-selector="edit-layout" class="layout--layout-test-1col-no-template">
-  <div class="region--top">
-    This is the top
-  </div>
-  <div class="region--bottom">
-    This is the bottom
-  </div>
-</div>
-EOD;
-
-    $data['layout_test_2col'][] = <<<'EOD'
-<div class="layout-example-2col clearfix">
-  <div class="region-left">
-    This is the left
-  </div>
-  <div class="region-right">
-    This is the right
-  </div>
-</div>
-EOD;
-
-    $data['layout_test_plugin'][] = <<<'EOD'
-<div class="layout-test-plugin clearfix">
-  <div>
-    <span class="setting-1-label">Blah: </span>
-    Config value
-  </div>
-  <div class="region-main">
-    Main region
-  </div>
-</div>
-EOD;
-
     return $data;
   }
 
diff --git a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
index fd17a64c95..1319dc3d22 100644
--- a/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
+++ b/core/modules/link/src/Plugin/Field/FieldWidget/LinkWidget.php
@@ -176,6 +176,7 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
       '#element_validate' => [[get_called_class(), 'validateUriElement']],
       '#maxlength' => 2048,
       '#required' => $element['#required'],
+      '#link_type' => $this->getFieldSetting('link_type'),
     ];
 
     // If the field is configured to support internal links, it cannot use the
diff --git a/core/modules/link/tests/src/Functional/LinkFieldTest.php b/core/modules/link/tests/src/Functional/LinkFieldTest.php
index 67aee9c3b9..c99ad0a931 100644
--- a/core/modules/link/tests/src/Functional/LinkFieldTest.php
+++ b/core/modules/link/tests/src/Functional/LinkFieldTest.php
@@ -606,6 +606,49 @@ public function testLinkSeparateFormatter() {
     }
   }
 
+  /**
+   * Test '#link_type' property exists on 'link_default' widget.
+   *
+   * Make sure the 'link_default' widget exposes a '#link_type' property on
+   * its element. Modules can use it to understand if a text form element is
+   * a link and also which LinkItemInterface::LINK_* is (EXTERNAL, GENERIC,
+   * INTERNAL).
+   */
+  public function testLinkTypeOnLinkWidget() {
+
+    $link_type = LinkItemInterface::LINK_EXTERNAL;
+    $field_name = Unicode::strtolower($this->randomMachineName());
+
+    // Create a field with settings to validate.
+    $this->fieldStorage = FieldStorageConfig::create([
+      'field_name' => $field_name,
+      'entity_type' => 'entity_test',
+      'type' => 'link',
+      'cardinality' => 1,
+    ]);
+    $this->fieldStorage->save();
+    FieldConfig::create([
+      'field_storage' => $this->fieldStorage,
+      'label' => 'Read more about this entity',
+      'bundle' => 'entity_test',
+      'settings' => [
+        'title' => DRUPAL_OPTIONAL,
+        'link_type' => $link_type,
+      ],
+    ])->save();
+
+    $this->container->get('entity.manager')
+      ->getStorage('entity_form_display')
+      ->load('entity_test.entity_test.default')
+      ->setComponent($field_name, [
+        'type' => 'link_default',
+      ])
+      ->save();
+
+    $form = \Drupal::service('entity.form_builder')->getForm(EntityTest::create());
+    $this->assertEqual($form[$field_name]['widget'][0]['uri']['#link_type'], $link_type);
+  }
+
 
   /**
    * Tests editing a link to a non-node entity.
diff --git a/core/modules/locale/src/LocaleConfigManager.php b/core/modules/locale/src/LocaleConfigManager.php
index e67f3bc4a2..18f335c10b 100644
--- a/core/modules/locale/src/LocaleConfigManager.php
+++ b/core/modules/locale/src/LocaleConfigManager.php
@@ -140,9 +140,7 @@ public function getTranslatableDefaultConfig($name) {
     if ($this->isSupported($name)) {
       // Create typed configuration wrapper based on install storage data.
       $data = $this->defaultConfigStorage->read($name);
-      $type_definition = $this->typedConfigManager->getDefinition($name);
-      $data_definition = $this->typedConfigManager->buildDataDefinition($type_definition, $data);
-      $typed_config = $this->typedConfigManager->create($data_definition, $data);
+      $typed_config = $this->typedConfigManager->createFromNameAndData($name, $data);
       if ($typed_config instanceof TraversableTypedDataInterface) {
         return $this->getTranslatableData($typed_config);
       }
diff --git a/core/modules/locale/src/StringDatabaseStorage.php b/core/modules/locale/src/StringDatabaseStorage.php
index 57358dc32a..45bf41d1ff 100644
--- a/core/modules/locale/src/StringDatabaseStorage.php
+++ b/core/modules/locale/src/StringDatabaseStorage.php
@@ -3,6 +3,7 @@
 namespace Drupal\locale;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\Condition;
 
 /**
  * Defines a class to store localized strings in the database.
@@ -416,7 +417,7 @@ protected function dbStringSelect(array $conditions, array $options = []) {
       elseif ($table_alias == 't' && $join === 'leftJoin') {
         // Conditions for target fields when doing an outer join only make
         // sense if we add also OR field IS NULL.
-        $query->condition(db_or()
+        $query->condition((new Condition('OR'))
           ->condition($field_alias, (array) $value, 'IN')
           ->isNull($field_alias)
         );
@@ -429,7 +430,7 @@ protected function dbStringSelect(array $conditions, array $options = []) {
     // Process other options, string filter, query limit, etc.
     if (!empty($options['filters'])) {
       if (count($options['filters']) > 1) {
-        $filter = db_or();
+        $filter = new Condition('OR');
         $query->condition($filter);
       }
       else {
diff --git a/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php b/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php
index eafac29662..7ba0168ee6 100644
--- a/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php
+++ b/core/modules/migrate/src/Plugin/MigrateIdMapInterface.php
@@ -213,6 +213,8 @@ public function lookupSourceID(array $destination_id_values);
    *
    * @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use
    *   lookupDestinationIds() instead.
+   *
+   * @see https://www.drupal.org/node/2725809
    */
   public function lookupDestinationId(array $source_id_values);
 
diff --git a/core/modules/migrate/src/Plugin/Migration.php b/core/modules/migrate/src/Plugin/Migration.php
index 13092e7775..c7457b2025 100644
--- a/core/modules/migrate/src/Plugin/Migration.php
+++ b/core/modules/migrate/src/Plugin/Migration.php
@@ -312,6 +312,8 @@ public function label() {
    *
    * @deprecated in Drupal 8.1.x, will be removed before Drupal 9.0.x. Use
    *   more specific getters instead.
+   *
+   * @see https://www.drupal.org/node/2873795
    */
   public function get($property) {
     return isset($this->$property) ? $this->$property : NULL;
diff --git a/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php b/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php
index 910058eb0f..90801ebdcb 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/DedupeBase.php
@@ -17,6 +17,8 @@
  *
  * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
  *   \Drupal\migrate\Plugin\migrate\process\MakeUniqueBase instead.
+ *
+ * @see https://www.drupal.org/node/2873762
  */
 abstract class DedupeBase extends MakeUniqueBase {
 }
diff --git a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
index afa31455d4..eda44b755c 100644
--- a/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
+++ b/core/modules/migrate/src/Plugin/migrate/process/DedupeEntity.php
@@ -19,5 +19,7 @@
  *
  * @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
  *   \Drupal\migrate\Plugin\migrate\process\MakeUniqueEntityField instead.
+ *
+ * @see https://www.drupal.org/node/2873762
  */
 class DedupeEntity extends MakeUniqueEntityField { }
diff --git a/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php b/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php
index 6a52ed6efe..b712d318b2 100644
--- a/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php
+++ b/core/modules/migrate/tests/src/Unit/Event/EventBaseTest.php
@@ -3,12 +3,13 @@
 namespace Drupal\Tests\migrate\Unit\Event;
 
 use Drupal\migrate\Event\EventBase;
+use Drupal\Tests\UnitTestCase;
 
 /**
  * @coversDefaultClass \Drupal\migrate\Event\EventBase
  * @group migrate
  */
-class EventBaseTest extends \PHPUnit_Framework_TestCase {
+class EventBaseTest extends UnitTestCase {
 
   /**
    * Test getMigration method.
diff --git a/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php b/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php
index 480fe85a70..d281433e03 100644
--- a/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php
+++ b/core/modules/migrate/tests/src/Unit/Event/MigrateImportEventTest.php
@@ -3,12 +3,13 @@
 namespace Drupal\Tests\migrate\Unit\Event;
 
 use Drupal\migrate\Event\MigrateImportEvent;
+use Drupal\Tests\UnitTestCase;
 
 /**
  * @coversDefaultClass \Drupal\migrate\Event\MigrateImportEvent
  * @group migrate
  */
-class MigrateImportEventTest extends \PHPUnit_Framework_TestCase {
+class MigrateImportEventTest extends UnitTestCase {
 
   /**
    * Test getMigration method.
diff --git a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
index a5daa72032..377533465f 100644
--- a/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/DedupeEntityTest.php
@@ -2,9 +2,6 @@
 
 namespace Drupal\Tests\migrate\Unit\process;
 
-@trigger_error('The ' . __NAMESPACE__ . '\DedupeEntityTest is deprecated in
-Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MakeUniqueEntityFieldTest', E_USER_DEPRECATED);
-
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Entity\Query\QueryInterface;
@@ -14,6 +11,7 @@
 /**
  * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\DedupeEntity
  * @group migrate
+ * @group legacy
  */
 class DedupeEntityTest extends MigrateProcessTestCase {
 
diff --git a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
index 843d1e558b..cade905a4d 100644
--- a/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
+++ b/core/modules/migrate/tests/src/Unit/process/MigrationTest.php
@@ -2,9 +2,6 @@
 
 namespace Drupal\Tests\migrate\Unit\process;
 
-@trigger_error('The ' . __NAMESPACE__ . '\MigrationTest is deprecated in
-Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookupTest', E_USER_DEPRECATED);
-
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\migrate\MigrateSkipProcessException;
 use Drupal\migrate\Plugin\MigrationInterface;
@@ -17,11 +14,9 @@
 use Prophecy\Argument;
 
 /**
- * @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use
- *   \Drupal\Tests\migrate\Unit\process\MigrationLookupTest instead.
- *
  * @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\Migration
  * @group migrate
+ * @group legacy
  */
 class MigrationTest extends MigrateProcessTestCase {
 
diff --git a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
index c64738f563..49f41a3817 100644
--- a/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
+++ b/core/modules/migrate_drupal/src/Plugin/MigrateCckFieldInterface.php
@@ -13,6 +13,8 @@
  *
  * @deprecated in Drupal 8.3.x, to be removed before Drupal 9.0.x. Use
  *   \Drupal\migrate_drupal\Annotation\MigrateField instead.
+ *
+ * @see https://www.drupal.org/node/2751897
  */
 interface MigrateCckFieldInterface extends MigrateFieldInterface {
 
diff --git a/core/modules/node/content_types.js b/core/modules/node/content_types.js
index eed93f01c9..4ec34aa05e 100644
--- a/core/modules/node/content_types.js
+++ b/core/modules/node/content_types.js
@@ -26,7 +26,7 @@
       });
       $context.find('#edit-workflow').drupalSetSummary(function (context) {
         var vals = [];
-        $(context).find('input[name^="options"]:checked').parent().each(function () {
+        $(context).find('input[name^="options"]:checked').next('label').each(function () {
           vals.push(Drupal.checkPlain($(this).text()));
         });
         if (!$(context).find('#edit-options-status').is(':checked')) {
diff --git a/core/modules/node/node.install b/core/modules/node/node.install
index 4e2c24098e..6469245c49 100644
--- a/core/modules/node/node.install
+++ b/core/modules/node/node.install
@@ -74,7 +74,7 @@ function node_schema() {
         'default' => 0,
       ],
       'realm' => [
-        'description' => 'The realm in which the user must possess the grant ID. Each node access node can define one or more realms.',
+        'description' => 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().',
         'type' => 'varchar_ascii',
         'length' => 255,
         'not null' => TRUE,
@@ -246,3 +246,12 @@ function node_update_8301() {
   $entity_type->set('entity_keys', $keys);
   $definition_update_manager->updateEntityType($entity_type);
 }
+
+/**
+ * Fix realm column description on the node_access table.
+ */
+function node_update_8400() {
+  $schema = drupal_get_module_schema('node', 'node_access');
+  $schema['fields']['realm']['description'] = 'The realm in which the user must possess the grant ID. Modules can define one or more realms by implementing hook_node_grants().';
+  Database::getConnection()->schema()->changeField('node_access', 'realm', 'realm', $schema['fields']['realm']);
+}
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index 40e5b4e293..466f510001 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1099,7 +1099,7 @@ function node_query_node_access_alter(AlterableInterface $query) {
   // context.
   $request = \Drupal::requestStack()->getCurrentRequest();
   $renderer = \Drupal::service('renderer');
-  if ($request->isMethodSafe() && $renderer->hasRenderContext()) {
+  if ($request->isMethodCacheable() && $renderer->hasRenderContext()) {
     $build = ['#cache' => ['contexts' => ['user.node_grants:' . $op]]];
     $renderer->render($build);
   }
diff --git a/core/modules/node/node.permissions.yml b/core/modules/node/node.permissions.yml
index 753ed40147..289227c71a 100644
--- a/core/modules/node/node.permissions.yml
+++ b/core/modules/node/node.permissions.yml
@@ -18,12 +18,13 @@ view own unpublished content:
   title: 'View own unpublished content'
 view all revisions:
   title: 'View all revisions'
+  description: 'To view a revision, you also need permission to view the content item.'
 revert all revisions:
   title: 'Revert all revisions'
-  description: 'Role requires permission <em>view revisions</em> and <em>edit rights</em> for nodes in question or <em>administer nodes</em>.'
+  description: 'To revert a revision, you also need permission to edit the content item.'
 delete all revisions:
   title: 'Delete all revisions'
-  description: 'Role requires permission to <em>view revisions</em> and <em>delete rights</em> for nodes in question or <em>administer nodes</em>.'
+  description: 'To delete a revision, you also need permission to delete the content item.'
 
 permission_callbacks:
   - \Drupal\node\NodePermissions::nodeTypePermissions
diff --git a/core/modules/node/src/Entity/Node.php b/core/modules/node/src/Entity/Node.php
index 4f8efe3c53..74a7c0bc3e 100644
--- a/core/modules/node/src/Entity/Node.php
+++ b/core/modules/node/src/Entity/Node.php
@@ -2,9 +2,7 @@
 
 namespace Drupal\node\Entity;
 
-use Drupal\Core\Entity\ContentEntityBase;
-use Drupal\Core\Entity\EntityChangedTrait;
-use Drupal\Core\Entity\EntityPublishedTrait;
+use Drupal\Core\Entity\EditorialContentEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
@@ -61,6 +59,11 @@
  *     "published" = "status",
  *     "uid" = "uid",
  *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_uid",
+ *     "revision_created" = "revision_timestamp",
+ *     "revision_log_message" = "revision_log"
+ *   },
  *   bundle_entity_type = "node_type",
  *   field_ui_base_route = "entity.node_type.edit_form",
  *   common_reference_target = TRUE,
@@ -71,13 +74,11 @@
  *     "edit-form" = "/node/{node}/edit",
  *     "version-history" = "/node/{node}/revisions",
  *     "revision" = "/node/{node}/revisions/{node_revision}/view",
+ *     "create" = "/node",
  *   }
  * )
  */
-class Node extends ContentEntityBase implements NodeInterface {
-
-  use EntityChangedTrait;
-  use EntityPublishedTrait;
+class Node extends EditorialContentEntityBase implements NodeInterface {
 
   /**
    * Whether the node is being previewed or not.
@@ -281,21 +282,6 @@ public function setOwner(UserInterface $account) {
   /**
    * {@inheritdoc}
    */
-  public function getRevisionCreationTime() {
-    return $this->get('revision_timestamp')->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionCreationTime($timestamp) {
-    $this->set('revision_timestamp', $timestamp);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function getRevisionAuthor() {
     return $this->getRevisionUser();
   }
@@ -303,13 +289,6 @@ public function getRevisionAuthor() {
   /**
    * {@inheritdoc}
    */
-  public function getRevisionUser() {
-    return $this->get('revision_uid')->entity;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function setRevisionAuthorId($uid) {
     $this->setRevisionUserId($uid);
     return $this;
@@ -318,47 +297,8 @@ public function setRevisionAuthorId($uid) {
   /**
    * {@inheritdoc}
    */
-  public function setRevisionUser(UserInterface $user) {
-    $this->set('revision_uid', $user);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionUserId() {
-    return $this->get('revision_uid')->entity->id();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionUserId($user_id) {
-    $this->set('revision_uid', $user_id);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionLogMessage() {
-    return $this->get('revision_log')->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionLogMessage($revision_log_message) {
-    $this->set('revision_log', $revision_log_message);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields = parent::baseFieldDefinitions($entity_type);
-    $fields += static::publishedBaseFieldDefinitions($entity_type);
 
     $fields['title'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Title'))
@@ -450,32 +390,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ])
       ->setDisplayConfigurable('form', TRUE);
 
-    $fields['revision_timestamp'] = BaseFieldDefinition::create('created')
-      ->setLabel(t('Revision timestamp'))
-      ->setDescription(t('The time that the current revision was created.'))
-      ->setQueryable(FALSE)
-      ->setRevisionable(TRUE);
-
-    $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('Revision user ID'))
-      ->setDescription(t('The user ID of the author of the current revision.'))
-      ->setSetting('target_type', 'user')
-      ->setQueryable(FALSE)
-      ->setRevisionable(TRUE);
-
-    $fields['revision_log'] = BaseFieldDefinition::create('string_long')
-      ->setLabel(t('Revision log message'))
-      ->setDescription(t('Briefly describe the changes you have made.'))
-      ->setRevisionable(TRUE)
-      ->setDefaultValue('')
-      ->setDisplayOptions('form', [
-        'type' => 'string_textarea',
-        'weight' => 25,
-        'settings' => [
-          'rows' => 4,
-        ],
-      ]);
-
     $fields['revision_translation_affected'] = BaseFieldDefinition::create('boolean')
       ->setLabel(t('Revision translation affected'))
       ->setDescription(t('Indicates if the last edit of a translation belongs to current revision.'))
diff --git a/core/modules/node/src/Form/NodeRevisionRevertForm.php b/core/modules/node/src/Form/NodeRevisionRevertForm.php
index 09aab6f543..8137c3f4fa 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Form;
 
+use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Form\ConfirmFormBase;
@@ -37,16 +38,26 @@ class NodeRevisionRevertForm extends ConfirmFormBase {
   protected $dateFormatter;
 
   /**
+   * The time service.
+   *
+   * @var \Drupal\Component\Datetime\TimeInterface
+   */
+  protected $time;
+
+  /**
    * Constructs a new NodeRevisionRevertForm.
    *
    * @param \Drupal\Core\Entity\EntityStorageInterface $node_storage
    *   The node storage.
    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
    *   The date formatter service.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
    */
-  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter) {
+  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, TimeInterface $time) {
     $this->nodeStorage = $node_storage;
     $this->dateFormatter = $date_formatter;
+    $this->time = $time;
   }
 
   /**
@@ -55,7 +66,8 @@ public function __construct(EntityStorageInterface $node_storage, DateFormatterI
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager')->getStorage('node'),
-      $container->get('date.formatter')
+      $container->get('date.formatter'),
+      $container->get('datetime.time')
     );
   }
 
@@ -114,6 +126,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     $this->revision = $this->prepareRevertedRevision($this->revision, $form_state);
     $this->revision->revision_log = t('Copy of the revision from %date.', ['%date' => $this->dateFormatter->format($original_revision_timestamp)]);
+    $this->revision->setRevisionCreationTime($this->time->getRequestTime());
+    $this->revision->setChangedTime($this->time->getRequestTime());
     $this->revision->save();
 
     $this->logger('content')->notice('@type: reverted %title revision %revision.', ['@type' => $this->revision->bundle(), '%title' => $this->revision->label(), '%revision' => $this->revision->getRevisionId()]);
diff --git a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
index fd20dadce1..d5da697abe 100644
--- a/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
+++ b/core/modules/node/src/Form/NodeRevisionRevertTranslationForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Form;
 
+use Drupal\Component\Datetime\TimeInterface;
 use Drupal\Core\Datetime\DateFormatterInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -37,9 +38,11 @@ class NodeRevisionRevertTranslationForm extends NodeRevisionRevertForm {
    *   The date formatter service.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
    */
-  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager) {
-    parent::__construct($node_storage, $date_formatter);
+  public function __construct(EntityStorageInterface $node_storage, DateFormatterInterface $date_formatter, LanguageManagerInterface $language_manager, TimeInterface $time) {
+    parent::__construct($node_storage, $date_formatter, $time);
     $this->languageManager = $language_manager;
   }
 
@@ -50,7 +53,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('entity.manager')->getStorage('node'),
       $container->get('date.formatter'),
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('datetime.time')
     );
   }
 
diff --git a/core/modules/node/src/NodePermissions.php b/core/modules/node/src/NodePermissions.php
index 5754d71eac..1996360ae1 100644
--- a/core/modules/node/src/NodePermissions.php
+++ b/core/modules/node/src/NodePermissions.php
@@ -62,14 +62,15 @@ protected function buildPermissions(NodeType $type) {
       ],
       "view $type_id revisions" => [
         'title' => $this->t('%type_name: View revisions', $type_params),
+        'description' => t('To view a revision, you also need permission to view the content item.'),
       ],
       "revert $type_id revisions" => [
         'title' => $this->t('%type_name: Revert revisions', $type_params),
-        'description' => t('Role requires permission <em>view revisions</em> and <em>edit rights</em> for nodes in question, or <em>administer nodes</em>.'),
+        'description' => t('To revert a revision, you also need permission to edit the content item.'),
       ],
       "delete $type_id revisions" => [
         'title' => $this->t('%type_name: Delete revisions', $type_params),
-        'description' => $this->t('Role requires permission to <em>view revisions</em> and <em>delete rights</em> for nodes in question, or <em>administer nodes</em>.'),
+        'description' => $this->t('To delete a revision, you also need permission to delete the content item.'),
       ],
     ];
   }
diff --git a/core/modules/node/src/Plugin/views/filter/Access.php b/core/modules/node/src/Plugin/views/filter/Access.php
index 73844e11d1..10ae9227ae 100644
--- a/core/modules/node/src/Plugin/views/filter/Access.php
+++ b/core/modules/node/src/Plugin/views/filter/Access.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\node\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\filter\FilterPluginBase;
 
@@ -27,10 +28,10 @@ public function query() {
     $account = $this->view->getUser();
     if (!$account->hasPermission('bypass node access')) {
       $table = $this->ensureMyTable();
-      $grants = db_or();
+      $grants = new Condition('OR');
       foreach (node_access_grants('view', $account) as $realm => $gids) {
         foreach ($gids as $gid) {
-          $grants->condition(db_and()
+          $grants->condition((new Condition('AND'))
             ->condition($table . '.gid', $gid)
             ->condition($table . '.realm', $realm)
           );
diff --git a/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php b/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php
new file mode 100644
index 0000000000..4760ee6509
--- /dev/null
+++ b/core/modules/node/tests/src/FunctionalJavascript/TestSettingSummariesContentType.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\Tests\node\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+
+/**
+ * Tests the JavaScript updating of summaries on content type form.
+ *
+ * @group node
+ */
+class TestSettingSummariesContentType extends JavascriptTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $admin_user = $this->drupalCreateUser(['administer content types']);
+    $this->drupalLogin($admin_user);
+    $this->drupalCreateContentType(['type' => 'test']);
+  }
+
+  /**
+   * Test a vertical tab 'Workflow' summary.
+   */
+  public function testWorkflowSummary() {
+    $this->drupalGet('admin/structure/types/manage/test');
+    $page = $this->getSession()->getPage();
+    $page->findField('options[status]')->uncheck();
+    $page->findField('options[sticky]')->check();
+    $page->findField('options[promote]')->check();
+    $page->findField('options[revision]')->check();
+    $locator = '[href="#edit-workflow"] .vertical-tabs__menu-item-summary';
+    $page->waitFor(10, function () use ($page, $locator) {
+      $summary = $page->find('css', $locator)->getText();
+      return strpos('Not published', $summary) !== FALSE;
+    });
+    $summary = $page->find('css', $locator)->getText();
+    $this->assertEquals('Not published, Promoted to front page, Sticky at top of lists, Create new revision', $summary);
+  }
+
+}
diff --git a/core/modules/quickedit/quickedit.services.yml b/core/modules/quickedit/quickedit.services.yml
index 692ba2f489..3d7d934378 100644
--- a/core/modules/quickedit/quickedit.services.yml
+++ b/core/modules/quickedit/quickedit.services.yml
@@ -3,7 +3,7 @@ services:
     class: Drupal\quickedit\Plugin\InPlaceEditorManager
     parent: default_plugin_manager
   access_check.quickedit.entity_field:
-    class: Drupal\quickedit\Access\EditEntityFieldAccessCheck
+    class: Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck
     tags:
       - { name: access_check, applies_to: _access_quickedit_entity_field }
   quickedit.editor.selector:
diff --git a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
index 7b3883833c..f93790863b 100644
--- a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
+++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheck.php
@@ -2,61 +2,9 @@
 
 namespace Drupal\quickedit\Access;
 
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Entity\EntityInterface;
-
 /**
- * Access check for editing entity fields.
+ * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0.
  */
-class EditEntityFieldAccessCheck implements AccessInterface, EditEntityFieldAccessCheckInterface {
-
-  /**
-   * Checks Quick Edit access to the field.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity containing the field.
-   * @param string $field_name
-   *   The field name.
-   * @param string $langcode
-   *   The langcode.
-   * @param \Drupal\Core\Session\AccountInterface $account
-   *   The currently logged in account.
-   *
-   * @return \Drupal\Core\Access\AccessResultInterface
-   *   The access result.
-   *
-   * @todo Use the $account argument: https://www.drupal.org/node/2266809.
-   */
-  public function access(EntityInterface $entity, $field_name, $langcode, AccountInterface $account) {
-    if (!$this->validateRequestAttributes($entity, $field_name, $langcode)) {
-      return AccessResult::forbidden();
-    }
-
-    return $this->accessEditEntityField($entity, $field_name);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function accessEditEntityField(EntityInterface $entity, $field_name) {
-    return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE));
-  }
-
-  /**
-   * Validates request attributes.
-   */
-  protected function validateRequestAttributes(EntityInterface $entity, $field_name, $langcode) {
-    // Validate the field name and language.
-    if (!$field_name || !$entity->hasField($field_name)) {
-      return FALSE;
-    }
-    if (!$langcode || !$entity->hasTranslation($langcode)) {
-      return FALSE;
-    }
-
-    return TRUE;
-  }
+class EditEntityFieldAccessCheck extends QuickEditEntityFieldAccessCheck {
 
 }
diff --git a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php
index c7f14e261a..cfdb32df57 100644
--- a/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php
+++ b/core/modules/quickedit/src/Access/EditEntityFieldAccessCheckInterface.php
@@ -2,24 +2,9 @@
 
 namespace Drupal\quickedit\Access;
 
-use Drupal\Core\Entity\EntityInterface;
-
 /**
- * Access check for editing entity fields.
+ * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0.
  */
-interface EditEntityFieldAccessCheckInterface {
-
-  /**
-   * Checks access to edit the requested field of the requested entity.
-   *
-   * @param \Drupal\Core\Entity\EntityInterface $entity
-   *   The entity.
-   * @param string $field_name
-   *   The field name.
-   *
-   * @return \Drupal\Core\Access\AccessResultInterface
-   *   The access result.
-   */
-  public function accessEditEntityField(EntityInterface $entity, $field_name);
+interface EditEntityFieldAccessCheckInterface extends QuickEditEntityFieldAccessCheckInterface {
 
 }
diff --git a/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php
new file mode 100644
index 0000000000..5404b04885
--- /dev/null
+++ b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheck.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Drupal\quickedit\Access;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Routing\Access\AccessInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Access check for in-place editing entity fields.
+ */
+class QuickEditEntityFieldAccessCheck implements AccessInterface, QuickEditEntityFieldAccessCheckInterface {
+
+  /**
+   * Checks Quick Edit access to the field.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity containing the field.
+   * @param string $field_name
+   *   The field name.
+   * @param string $langcode
+   *   The langcode.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return \Drupal\Core\Access\AccessResultInterface
+   *   The access result.
+   *
+   * @todo Use the $account argument: https://www.drupal.org/node/2266809.
+   */
+  public function access(EntityInterface $entity, $field_name, $langcode, AccountInterface $account) {
+    if (!$this->validateRequestAttributes($entity, $field_name, $langcode)) {
+      return AccessResult::forbidden();
+    }
+
+    return $this->accessEditEntityField($entity, $field_name);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function accessEditEntityField(EntityInterface $entity, $field_name) {
+    return $entity->access('update', NULL, TRUE)->andIf($entity->get($field_name)->access('edit', NULL, TRUE));
+  }
+
+  /**
+   * Validates request attributes.
+   */
+  protected function validateRequestAttributes(EntityInterface $entity, $field_name, $langcode) {
+    // Validate the field name and language.
+    if (!$field_name || !$entity->hasField($field_name)) {
+      return FALSE;
+    }
+    if (!$langcode || !$entity->hasTranslation($langcode)) {
+      return FALSE;
+    }
+
+    return TRUE;
+  }
+
+}
diff --git a/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php
new file mode 100644
index 0000000000..1428b4829a
--- /dev/null
+++ b/core/modules/quickedit/src/Access/QuickEditEntityFieldAccessCheckInterface.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\quickedit\Access;
+
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Access check for in-place editing entity fields.
+ */
+interface QuickEditEntityFieldAccessCheckInterface {
+
+  /**
+   * Checks access to edit the requested field of the requested entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity.
+   * @param string $field_name
+   *   The field name.
+   *
+   * @return \Drupal\Core\Access\AccessResultInterface
+   *   The access result.
+   */
+  public function accessEditEntityField(EntityInterface $entity, $field_name);
+
+}
diff --git a/core/modules/quickedit/src/MetadataGenerator.php b/core/modules/quickedit/src/MetadataGenerator.php
index 71b750d4a1..f01256fcbb 100644
--- a/core/modules/quickedit/src/MetadataGenerator.php
+++ b/core/modules/quickedit/src/MetadataGenerator.php
@@ -5,7 +5,7 @@
 use Drupal\Component\Plugin\PluginManagerInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Field\FieldItemListInterface;
-use Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface;
+use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface;
 use Drupal\Core\Entity\Entity\EntityViewDisplay;
 
 /**
@@ -16,7 +16,7 @@ class MetadataGenerator implements MetadataGeneratorInterface {
   /**
    * An object that checks if a user has access to edit a given entity field.
    *
-   * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface
+   * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface
    */
   protected $accessChecker;
 
@@ -37,14 +37,14 @@ class MetadataGenerator implements MetadataGeneratorInterface {
   /**
    * Constructs a new MetadataGenerator.
    *
-   * @param \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface $access_checker
+   * @param \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface $access_checker
    *   An object that checks if a user has access to edit a given field.
    * @param \Drupal\quickedit\EditorSelectorInterface $editor_selector
    *   An object that determines which editor to attach to a given field.
    * @param \Drupal\Component\Plugin\PluginManagerInterface $editor_manager
    *   The manager for editor plugins.
    */
-  public function __construct(EditEntityFieldAccessCheckInterface $access_checker, EditorSelectorInterface $editor_selector, PluginManagerInterface $editor_manager) {
+  public function __construct(QuickEditEntityFieldAccessCheckInterface $access_checker, EditorSelectorInterface $editor_selector, PluginManagerInterface $editor_manager) {
     $this->accessChecker = $access_checker;
     $this->editorSelector = $editor_selector;
     $this->editorManager = $editor_manager;
diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
index a6705f41e8..41f26a841f 100644
--- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -115,12 +115,12 @@ public function testUserWithoutPermission() {
     $this->assertIdentical(Json::encode(['message' => "The 'access in-place editing' permission is required."]), $response);
     $this->assertResponse(403);
 
-    // Quick Edit's JavaScript would SearchRankingTestnever hit these endpoints if the metadata
+    // Quick Edit's JavaScript would never hit these endpoints if the metadata
     // was empty as above, but we need to make sure that malicious users aren't
     // able to use any of the other endpoints either.
     $post = ['editors[0]' => 'form'] + $this->getAjaxPageStatePostData();
     $response = $this->drupalPost('quickedit/attachments', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
-    $message = Json::encode(['message' => "A fatal error occurred: The 'access in-place editing' permission is required."]);
+    $message = Json::encode(['message' => "The 'access in-place editing' permission is required."]);
     $this->assertIdentical($message, $response);
     $this->assertResponse(403);
     $post = ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData();
diff --git a/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php
index b5d94564b1..7596aa87c3 100644
--- a/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php
+++ b/core/modules/quickedit/tests/modules/src/MockEditEntityFieldAccessCheck.php
@@ -2,19 +2,9 @@
 
 namespace Drupal\quickedit_test;
 
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface;
-
 /**
- * Access check for editing entity fields.
+ * @deprecated in Drupal 8.4.x and will be removed before Drupal 9.0.0.
  */
-class MockEditEntityFieldAccessCheck implements EditEntityFieldAccessCheckInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function accessEditEntityField(EntityInterface $entity, $field_name) {
-    return TRUE;
-  }
+class MockEditEntityFieldAccessCheck extends MockQuickEditEntityFieldAccessCheck {
 
 }
diff --git a/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php
new file mode 100644
index 0000000000..2459c50f08
--- /dev/null
+++ b/core/modules/quickedit/tests/modules/src/MockQuickEditEntityFieldAccessCheck.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Drupal\quickedit_test;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface;
+
+/**
+ * Access check for in-place editing entity fields.
+ */
+class MockQuickEditEntityFieldAccessCheck implements QuickEditEntityFieldAccessCheckInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function accessEditEntityField(EntityInterface $entity, $field_name) {
+    return TRUE;
+  }
+
+}
diff --git a/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php b/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php
index a3bc7b52cc..9a453fb7ab 100644
--- a/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php
+++ b/core/modules/quickedit/tests/src/Kernel/MetadataGeneratorTest.php
@@ -5,7 +5,7 @@
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\quickedit\EditorSelector;
 use Drupal\quickedit\MetadataGenerator;
-use Drupal\quickedit_test\MockEditEntityFieldAccessCheck;
+use Drupal\quickedit_test\MockQuickEditEntityFieldAccessCheck;
 use Drupal\filter\Entity\FilterFormat;
 
 /**
@@ -44,7 +44,7 @@ class MetadataGeneratorTest extends QuickEditTestBase {
   /**
    * The access checker object to be used by the metadata generator object.
    *
-   * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheckInterface
+   * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheckInterface
    */
   protected $accessChecker;
 
@@ -52,7 +52,7 @@ protected function setUp() {
     parent::setUp();
 
     $this->editorManager = $this->container->get('plugin.manager.quickedit.editor');
-    $this->accessChecker = new MockEditEntityFieldAccessCheck();
+    $this->accessChecker = new MockQuickEditEntityFieldAccessCheck();
     $this->editorSelector = new EditorSelector($this->editorManager, $this->container->get('plugin.manager.field.formatter'));
     $this->metadataGenerator = new MetadataGenerator($this->accessChecker, $this->editorSelector, $this->editorManager);
   }
diff --git a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php
similarity index 91%
rename from core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
rename to core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php
index 7e7e0bbb99..0827436982 100644
--- a/core/modules/quickedit/tests/src/Unit/Access/EditEntityFieldAccessCheckTest.php
+++ b/core/modules/quickedit/tests/src/Unit/Access/QuickEditEntityFieldAccessCheckTest.php
@@ -5,21 +5,21 @@
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\DependencyInjection\Container;
-use Drupal\quickedit\Access\EditEntityFieldAccessCheck;
+use Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck;
 use Drupal\Tests\UnitTestCase;
 use Drupal\Core\Language\LanguageInterface;
 
 /**
- * @coversDefaultClass \Drupal\quickedit\Access\EditEntityFieldAccessCheck
+ * @coversDefaultClass \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck
  * @group Access
  * @group quickedit
  */
-class EditEntityFieldAccessCheckTest extends UnitTestCase {
+class QuickEditEntityFieldAccessCheckTest extends UnitTestCase {
 
   /**
    * The tested access checker.
    *
-   * @var \Drupal\quickedit\Access\EditEntityFieldAccessCheck
+   * @var \Drupal\quickedit\Access\QuickEditEntityFieldAccessCheck
    */
   protected $editAccessCheck;
 
@@ -27,7 +27,7 @@ class EditEntityFieldAccessCheckTest extends UnitTestCase {
    * {@inheritdoc}
    */
   protected function setUp() {
-    $this->editAccessCheck = new EditEntityFieldAccessCheck();
+    $this->editAccessCheck = new QuickEditEntityFieldAccessCheck();
 
     $cache_contexts_manager = $this->prophesize(CacheContextsManager::class);
     $cache_contexts_manager->assertValidTokens()->willReturn(TRUE);
@@ -40,7 +40,7 @@ protected function setUp() {
   /**
    * Provides test data for testAccess().
    *
-   * @see \Drupal\Tests\edit\Unit\quickedit\Access\EditEntityFieldAccessCheckTest::testAccess()
+   * @see \Drupal\Tests\edit\Unit\quickedit\Access\QuickEditEntityFieldAccessCheckTest::testAccess()
    */
   public function providerTestAccess() {
     $data = [];
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php
similarity index 95%
rename from core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
rename to core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php
index 0439771b19..eeaf793fa0 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageAdminUITest.php
+++ b/core/modules/responsive_image/tests/src/Functional/ResponsiveImageAdminUITest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\responsive_image\Tests;
+namespace Drupal\Tests\responsive_image\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Thoroughly test the administrative interface of the Responsive Image module.
  *
  * @group responsive_image
  */
-class ResponsiveImageAdminUITest extends WebTestBase {
+class ResponsiveImageAdminUITest extends BrowserTestBase {
 
   /**
    * Modules to enable.
@@ -78,11 +78,11 @@ public function testResponsiveImageAdmin() {
     );
     foreach ($cases as $case) {
       // Check if the radio buttons are present.
-      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping_type]', '');
+      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_mapping_type]', NULL);
       // Check if the image style dropdowns are present.
-      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_style]', '');
+      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][image_style]', NULL);
       // Check if the sizes textfields are present.
-      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes]', '');
+      $this->assertFieldByName('keyed_styles[responsive_image_test_module.' . $case[0] . '][' . $case[1] . '][sizes]', NULL);
 
       foreach ($image_styles as $image_style_name) {
         // Check if the image styles are available in the dropdowns.
diff --git a/core/modules/rest/rest.module b/core/modules/rest/rest.module
index afdb9ffe3c..edd74b9985 100644
--- a/core/modules/rest/rest.module
+++ b/core/modules/rest/rest.module
@@ -15,13 +15,13 @@ function rest_help($route_name, RouteMatchInterface $route_match) {
     case 'help.page.rest':
       $output = '';
       $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The RESTful Web Services module provides a framework for exposing REST resources on your site. It provides support for content entities (see the <a href=":field">Field module help page</a> for more information about entities) such as content, users, taxonomy terms, etc.; REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. Other modules may add support for other types of REST resources. For more information, see the <a href=":rest">online documentation for the RESTful Web Services module</a>.', [':rest' => 'https://www.drupal.org/documentation/modules/rest', ':field' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', ['name' => 'field']) : '#']) . '</p>';
+      $output .= '<p>' . t('The RESTful Web Services module provides a framework for exposing REST resources on your site. It provides support for content entity types such as the main site content, comments, custom blocks, taxonomy terms, and user accounts, etc. (see the <a href=":field">Field module help page</a> for more information about entities). REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. Other modules may add support for other types of REST resources. For more information, see the <a href=":rest">online documentation for the RESTful Web Services module</a>.', [':rest' => 'https://www.drupal.org/documentation/modules/rest', ':field' => (\Drupal::moduleHandler()->moduleExists('field')) ? \Drupal::url('help.page', ['name' => 'field']) : '#']) . '</p>';
       $output .= '<h3>' . t('Uses') . '</h3>';
       $output .= '<dl>';
       $output .= '<dt>' . t('Installing supporting modules') . '</dt>';
       $output .= '<dd>' . t('In order to use REST on a web site, you need to install modules that provide serialization and authentication services. You can use the Core module <a href=":hal">HAL</a> for serialization and <a href=":basic_auth">HTTP Basic Authentication</a> for authentication, or install a contributed or custom module.', [':hal' => (\Drupal::moduleHandler()->moduleExists('hal')) ? \Drupal::url('help.page', ['name' => 'hal']) : '#', ':basic_auth' => (\Drupal::moduleHandler()->moduleExists('basic_auth')) ? \Drupal::url('help.page', ['name' => 'basic_auth']) : '#']) . '</dd>';
       $output .= '<dt>' . t('Enabling REST support for an entity type') . '</dt>';
-      $output .= '<dd>' . t('REST support for content items of the Node module is enabled by default, and support for other types of content entities can be enabled. To enable support, you can use a <a href=":config">process based on configuration editing</a> or the contributed <a href=":restui">Rest UI module</a>.', [':config' => 'https://www.drupal.org/documentation/modules/rest', ':restui' => 'https://www.drupal.org/project/restui']) . '</dd>';
+      $output .= '<dd>' . t('REST support for content types (provided by the <a href=":node">Node</a> module) is enabled by default. To enable support for other content entity types, you can use a <a href=":config" target="blank">process based on configuration editing</a> or the contributed <a href=":restui">REST UI module</a>.', [':node' => (\Drupal::moduleHandler()->moduleExists('node')) ? \Drupal::url('help.page', ['name' => 'node']) : '#', ':config' => 'https://www.drupal.org/documentation/modules/rest', ':restui' => 'https://www.drupal.org/project/restui']) . '</dd>';
       $output .= '<dd>' . t('You will also need to grant anonymous users permission to perform each of the REST operations you want to be available, and set up authentication properly to authorize web requests.') . '</dd>';
       $output .= '</dl>';
       return $output;
diff --git a/core/modules/rest/rest.services.yml b/core/modules/rest/rest.services.yml
index 869eb19648..080a681afb 100644
--- a/core/modules/rest/rest.services.yml
+++ b/core/modules/rest/rest.services.yml
@@ -31,3 +31,15 @@ services:
     arguments: ['@router.builder']
     tags:
       - { name: event_subscriber }
+  rest.resource.entity.post_route.subscriber:
+    class: \Drupal\rest\EventSubscriber\EntityResourcePostRouteSubscriber
+    arguments: ['@entity_type.manager']
+    tags:
+      - { name: event_subscriber }
+
+  # @todo Remove in Drupal 9.0.0.
+  rest.path_processor_entity_resource_bc:
+    class: \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC
+    arguments: ['@entity_type.manager']
+    tags:
+      - { name: path_processor_inbound }
diff --git a/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php
new file mode 100644
index 0000000000..36a3f73117
--- /dev/null
+++ b/core/modules/rest/src/EventSubscriber/EntityResourcePostRouteSubscriber.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace Drupal\rest\EventSubscriber;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Routing\RouteBuildEvent;
+use Drupal\Core\Routing\RoutingEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Generates a 'create' route for an entity type if it has a REST POST route.
+ */
+class EntityResourcePostRouteSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The REST resource config storage.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $resourceConfigStorage;
+
+  /**
+   * Constructs a new EntityResourcePostRouteSubscriber instance.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+    $this->resourceConfigStorage = $entity_type_manager->getStorage('rest_resource_config');
+  }
+
+  /**
+   * Provides routes on route rebuild time.
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route build event.
+   */
+  public function onDynamicRouteEvent(RouteBuildEvent $event) {
+    $route_collection = $event->getRouteCollection();
+
+    $resource_configs = $this->resourceConfigStorage->loadMultiple();
+    // Iterate over all REST resource config entities.
+    foreach ($resource_configs as $resource_config) {
+      // We only care about REST resource config entities for the
+      // \Drupal\rest\Plugin\rest\resource\EntityResource plugin.
+      $plugin_id = $resource_config->toArray()['plugin_id'];
+      if (substr($plugin_id, 0, 6) !== 'entity') {
+        continue;
+      }
+
+      $entity_type_id = substr($plugin_id, 7);
+      $rest_post_route_name = "rest.entity.$entity_type_id.POST";
+      if ($rest_post_route = $route_collection->get($rest_post_route_name)) {
+        // Create a route for the 'create' link relation type for this entity
+        // type that uses the same route definition as the REST 'POST' route
+        // which use that entity type.
+        // @see \Drupal\Core\Entity\Entity::toUrl()
+        $entity_create_route_name = "entity.$entity_type_id.create";
+        $route_collection->add($entity_create_route_name, $rest_post_route);
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    // Priority -10, to run after \Drupal\rest\Routing\ResourceRoutes, which has
+    // priority 0.
+    $events[RoutingEvents::DYNAMIC][] = ['onDynamicRouteEvent', -10];
+    return $events;
+  }
+
+}
diff --git a/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
index 5cb887bec0..df77281f37 100644
--- a/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
+++ b/core/modules/rest/src/EventSubscriber/ResourceResponseSubscriber.php
@@ -96,7 +96,7 @@ public function getResponseFormat(RouteMatchInterface $route_match, Request $req
     $route = $route_match->getRouteObject();
     $acceptable_request_formats = $route->hasRequirement('_format') ? explode('|', $route->getRequirement('_format')) : [];
     $acceptable_content_type_formats = $route->hasRequirement('_content_type_format') ? explode('|', $route->getRequirement('_content_type_format')) : [];
-    $acceptable_formats = $request->isMethodSafe() ? $acceptable_request_formats : $acceptable_content_type_formats;
+    $acceptable_formats = $request->isMethodCacheable() ? $acceptable_request_formats : $acceptable_content_type_formats;
 
     $requested_format = $request->getRequestFormat();
     $content_type_format = $request->getContentType();
@@ -196,8 +196,9 @@ protected function flattenResponse(ResourceResponseInterface $response) {
    * {@inheritdoc}
    */
   public static function getSubscribedEvents() {
-    // Run shortly before \Drupal\Core\EventSubscriber\FinishResponseSubscriber.
-    $events[KernelEvents::RESPONSE][] = ['onResponse', 5];
+    // Run before \Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber
+    // (priority 100), so that Dynamic Page Cache can cache flattened responses.
+    $events[KernelEvents::RESPONSE][] = ['onResponse', 128];
     return $events;
   }
 
diff --git a/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php
new file mode 100644
index 0000000000..1f68691a2b
--- /dev/null
+++ b/core/modules/rest/src/PathProcessor/PathProcessorEntityResourceBC.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\rest\PathProcessor;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Path processor to maintain BC for entity REST resource URLs from Drupal 8.0.
+ */
+class PathProcessorEntityResourceBC implements InboundPathProcessorInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * Creates a new PathProcessorEntityResourceBC instance.
+   *
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager) {
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processInbound($path, Request $request) {
+    if ($request->getMethod() === 'POST' && strpos($path, '/entity/') === 0) {
+      $parts = explode('/', $path);
+      $entity_type_id = array_pop($parts);
+
+      // Until Drupal 8.3, no entity types specified a link template for the
+      // 'create' link relation type. As of Drupal 8.3, all core content entity
+      // types provide this link relation type. This inbound path processor
+      // provides automatic backwards compatibility: it allows both the old
+      // default from \Drupal\rest\Plugin\rest\resource\EntityResource, i.e.
+      // "/entity/{entity_type}" and the link template specified in a particular
+      // entity type. The former is rewritten to the latter
+      // specific one if it exists.
+      $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
+      if ($entity_type->hasLinkTemplate('create')) {
+        return $entity_type->getLinkTemplate('create');
+      }
+    }
+    return $path;
+  }
+
+}
diff --git a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
index 010fad7363..a74e8b2a61 100644
--- a/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
+++ b/core/modules/rest/src/Plugin/Deriver/EntityDeriver.php
@@ -74,7 +74,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
 
         $default_uris = [
           'canonical' => "/entity/$entity_type_id/" . '{' . $entity_type_id . '}',
-          'https://www.drupal.org/link-relations/create' => "/entity/$entity_type_id",
+          'create' => "/entity/$entity_type_id",
         ];
 
         foreach ($default_uris as $link_relation => $default_uri) {
diff --git a/core/modules/rest/src/Plugin/ResourceBase.php b/core/modules/rest/src/Plugin/ResourceBase.php
index 50d8d758ce..b40a03109b 100644
--- a/core/modules/rest/src/Plugin/ResourceBase.php
+++ b/core/modules/rest/src/Plugin/ResourceBase.php
@@ -100,7 +100,15 @@ public function routes() {
 
     $definition = $this->getPluginDefinition();
     $canonical_path = isset($definition['uri_paths']['canonical']) ? $definition['uri_paths']['canonical'] : '/' . strtr($this->pluginId, ':', '/') . '/{id}';
-    $create_path = isset($definition['uri_paths']['https://www.drupal.org/link-relations/create']) ? $definition['uri_paths']['https://www.drupal.org/link-relations/create'] : '/' . strtr($this->pluginId, ':', '/');
+    $create_path = isset($definition['uri_paths']['create']) ? $definition['uri_paths']['create'] : '/' . strtr($this->pluginId, ':', '/');
+    // BC: the REST module originally created the POST URL for a resource by
+    // reading the 'https://www.drupal.org/link-relations/create' URI path from
+    // the plugin annotation. For consistency with entity type definitions, that
+    // then changed to reading the 'create' URI path. For any REST Resource
+    // plugins that were using the old mechanism, we continue to support that.
+    if (!isset($definition['uri_paths']['create']) && isset($definition['uri_paths']['https://www.drupal.org/link-relations/create'])) {
+      $create_path = $definition['uri_paths']['https://www.drupal.org/link-relations/create'];
+    }
 
     $route_name = strtr($this->pluginId, ':', '.');
 
diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
index 9b1d15f005..5d9849ded4 100644
--- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -35,7 +35,7 @@
  *   deriver = "Drupal\rest\Plugin\Deriver\EntityDeriver",
  *   uri_paths = {
  *     "canonical" = "/entity/{entity_type}/{entity}",
- *     "https://www.drupal.org/link-relations/create" = "/entity/{entity_type}"
+ *     "create" = "/entity/{entity_type}"
  *   }
  * )
  */
@@ -431,8 +431,11 @@ public function calculateDependencies() {
    * @see https://tools.ietf.org/html/rfc5988#section-5
    */
   protected function addLinkHeaders(EntityInterface $entity, Response $response) {
-    foreach ($entity->getEntityType()->getLinkTemplates() as $relation_name => $link_template) {
-      if ($definition = $this->linkRelationTypeManager->getDefinition($relation_name, FALSE)) {
+    foreach ($entity->uriRelationships() as $relation_name) {
+      if ($this->linkRelationTypeManager->hasDefinition($relation_name)) {
+        /** @var \Drupal\Core\Http\LinkRelationTypeInterface $link_relation_type */
+        $link_relation_type = $this->linkRelationTypeManager->createInstance($relation_name);
+
         $generator_url = $entity->toUrl($relation_name)
           ->setAbsolute(TRUE)
           ->toString(TRUE);
@@ -440,10 +443,10 @@ protected function addLinkHeaders(EntityInterface $entity, Response $response) {
           $response->addCacheableDependency($generator_url);
         }
         $uri = $generator_url->getGeneratedUrl();
-        $relationship = $relation_name;
-        if (!empty($definition['uri'])) {
-          $relationship = $definition['uri'];
-        }
+
+        $relationship = $link_relation_type->isRegistered()
+          ? $link_relation_type->getRegisteredName()
+          : $link_relation_type->getExtensionUri();
 
         $link_header = '<' . $uri . '>; rel="' . $relationship . '"';
         $response->headers->set('Link', $link_header, FALSE);
diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php
index 15abaa6fdf..cd961954a4 100644
--- a/core/modules/rest/src/Plugin/views/display/RestExport.php
+++ b/core/modules/rest/src/Plugin/views/display/RestExport.php
@@ -435,7 +435,7 @@ public function render() {
       $build['#markup'] = ViewsRenderPipelineMarkup::create($build['#markup']);
     }
 
-    parent::applyDisplayCachablityMetadata($build);
+    parent::applyDisplayCacheabilityMetadata($build);
 
     return $build;
   }
diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php
index 20bcfe792e..e5437ccb68 100644
--- a/core/modules/rest/src/RequestHandler.php
+++ b/core/modules/rest/src/RequestHandler.php
@@ -11,7 +11,9 @@
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException;
 use Symfony\Component\Serializer\Exception\UnexpectedValueException;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
 
 /**
  * Acts as intermediate request forwarder for resource plugins.
@@ -58,22 +60,20 @@ public static function create(ContainerInterface $container) {
    *   The response object.
    */
   public function handle(RouteMatchInterface $route_match, Request $request) {
-    $method = strtolower($request->getMethod());
-
     // Symfony is built to transparently map HEAD requests to a GET request. In
     // the case of the REST module's RequestHandler though, we essentially have
     // our own light-weight routing system on top of the Drupal/symfony routing
-    // system. So, we have to do the same as what the UrlMatcher does: map HEAD
-    // requests to the logic for GET. This also guarantees response headers for
-    // HEAD requests are identical to those for GET requests, because we just
-    // return a GET response. Response::prepare() will transform it to a HEAD
-    // response at the very last moment.
+    // system. So, we have to respect the decision that the routing system made:
+    // we look not at the request method, but at the route's method. All REST
+    // routes are guaranteed to have _method set.
+    // Response::prepare() will transform it to a HEAD response at the very last
+    // moment.
     // @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4
     // @see \Symfony\Component\Routing\Matcher\UrlMatcher::matchCollection()
     // @see \Symfony\Component\HttpFoundation\Response::prepare()
-    if ($method === 'head') {
-      $method = 'get';
-    }
+    $method = strtolower($route_match->getRouteObject()->getMethods()[0]);
+    assert(count($route_match->getRouteObject()->getMethods()) === 1);
+
 
     $resource_config_id = $route_match->getRouteObject()->getDefault('_rest_resource_config');
     /** @var \Drupal\rest\RestResourceConfigInterface $resource_config */
@@ -89,19 +89,32 @@ public function handle(RouteMatchInterface $route_match, Request $request) {
       $format = $request->getContentType();
 
       $definition = $resource->getPluginDefinition();
+
+      // First decode the request data. We can then determine if the
+      // serialized data was malformed.
       try {
-        if (!empty($definition['serialization_class'])) {
-          $unserialized = $serializer->deserialize($received, $definition['serialization_class'], $format, ['request_method' => $method]);
-        }
-        // If the plugin does not specify a serialization class just decode
-        // the received data.
-        else {
-          $unserialized = $serializer->decode($received, $format, ['request_method' => $method]);
-        }
+        $unserialized = $serializer->decode($received, $format, ['request_method' => $method]);
       }
       catch (UnexpectedValueException $e) {
+        // If an exception was thrown at this stage, there was a problem
+        // decoding the data. Throw a 400 http exception.
         throw new BadRequestHttpException($e->getMessage());
       }
+
+      // Then attempt to denormalize if there is a serialization class.
+      if (!empty($definition['serialization_class'])) {
+        try {
+          $unserialized = $serializer->denormalize($unserialized, $definition['serialization_class'], $format, ['request_method' => $method]);
+        }
+        // These two serialization exception types mean there was a problem
+        // with the structure of the decoded data and it's not valid.
+        catch (UnexpectedValueException $e) {
+          throw new UnprocessableEntityHttpException($e->getMessage());
+        }
+        catch (InvalidArgumentException $e) {
+          throw new UnprocessableEntityHttpException($e->getMessage());
+        }
+      }
     }
 
     // Determine the request parameters that should be passed to the resource
diff --git a/core/modules/rest/src/Routing/ResourceRoutes.php b/core/modules/rest/src/Routing/ResourceRoutes.php
index c21f13cd96..5ba4c5da62 100644
--- a/core/modules/rest/src/Routing/ResourceRoutes.php
+++ b/core/modules/rest/src/Routing/ResourceRoutes.php
@@ -3,16 +3,18 @@
 namespace Drupal\rest\Routing;
 
 use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Routing\RouteSubscriberBase;
+use Drupal\Core\Routing\RouteBuildEvent;
+use Drupal\Core\Routing\RoutingEvents;
 use Drupal\rest\Plugin\Type\ResourcePluginManager;
 use Drupal\rest\RestResourceConfigInterface;
 use Psr\Log\LoggerInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 use Symfony\Component\Routing\RouteCollection;
 
 /**
  * Subscriber for REST-style routes.
  */
-class ResourceRoutes extends RouteSubscriberBase {
+class ResourceRoutes implements EventSubscriberInterface {
 
   /**
    * The plugin manager for REST plugins.
@@ -54,18 +56,18 @@ public function __construct(ResourcePluginManager $manager, EntityTypeManagerInt
   /**
    * Alters existing routes for a specific collection.
    *
-   * @param \Symfony\Component\Routing\RouteCollection $collection
-   *   The route collection for adding routes.
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The route build event.
    * @return array
    */
-  protected function alterRoutes(RouteCollection $collection) {
+  public function onDynamicRouteEvent(RouteBuildEvent $event) {
     // Iterate over all enabled REST resource config entities.
     /** @var \Drupal\rest\RestResourceConfigInterface[] $resource_configs */
     $resource_configs = $this->resourceConfigStorage->loadMultiple();
     foreach ($resource_configs as $resource_config) {
       if ($resource_config->status()) {
         $resource_routes = $this->getRoutesForResourceConfig($resource_config);
-        $collection->addCollection($resource_routes);
+        $event->getRouteCollection()->addCollection($resource_routes);
       }
     }
   }
@@ -131,4 +133,12 @@ protected function getRoutesForResourceConfig(RestResourceConfigInterface $rest_
     return $collection;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[RoutingEvents::DYNAMIC] = 'onDynamicRouteEvent';
+    return $events;
+  }
+
 }
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php
index 0be7622068..d86f9b1c41 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Block/BlockResourceTestBase.php
@@ -122,9 +122,7 @@ protected function getExpectedCacheContexts() {
   protected function getExpectedCacheTags() {
     // Because the 'user.permissions' cache context is missing, the cache tag
     // for the anonymous user role is never added automatically.
-    return array_values(array_filter(parent::getExpectedCacheTags(), function ($tag) {
-      return $tag !== 'config:user.role.anonymous';
-    }));
+    return array_values(array_diff(parent::getExpectedCacheTags(), ['config:user.role.anonymous']));
   }
 
   /**
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php
index 8355f86cc5..961441213a 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Comment/CommentResourceTestBase.php
@@ -280,8 +280,8 @@ public function testPostDxWithoutCriticalBaseFields() {
     $response = $this->request('POST', $url, $request_options);
     // @todo Uncomment, remove next 3 lines in https://www.drupal.org/node/2820364.
     $this->assertSame(500, $response->getStatusCode());
-    $this->assertSame(['application/json'], $response->getHeader('Content-Type'));
-    $this->assertSame('{"message":"A fatal error occurred: Internal Server Error"}', (string) $response->getBody());
+    $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
+    $this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\HttpKernel\Exception\HttpException</em>: Internal Server Error in <em class="placeholder">Drupal\rest\Plugin\rest\resource\EntityResource-&gt;post()</em>', (string) $response->getBody());
     //$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nentity_type: This value should not be null.\n", $response);
 
     // DX: 422 when missing 'entity_id' field.
@@ -303,10 +303,9 @@ public function testPostDxWithoutCriticalBaseFields() {
     // DX: 422 when missing 'entity_type' field.
     $request_options[RequestOptions::BODY] = $this->serializer->encode(array_diff_key($this->getNormalizedPostEntity(), ['field_name' => TRUE]), static::$format);
     $response = $this->request('POST', $url, $request_options);
-    // @todo Uncomment, remove next 3 lines in https://www.drupal.org/node/2820364.
+    // @todo Uncomment, remove next 2 lines in https://www.drupal.org/node/2820364.
     $this->assertSame(500, $response->getStatusCode());
-    $this->assertSame(['application/json'], $response->getHeader('Content-Type'));
-    $this->assertSame('{"message":"A fatal error occurred: Field  is unknown."}', (string) $response->getBody());
+    $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
     //$this->assertResourceErrorResponse(422, "Unprocessable Entity: validation failed.\nfield_name: This value should not be null.\n", $response);
   }
 
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
index 8b878e2ad0..6e34de2bf5 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceTestBase.php
@@ -4,11 +4,13 @@
 
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Cache\CacheableResponseInterface;
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
 use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Url;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\rest\ResourceResponseInterface;
 use Drupal\Tests\rest\Functional\ResourceTestBase;
 use GuzzleHttp\RequestOptions;
 use Psr\Http\Message\ResponseInterface;
@@ -386,6 +388,18 @@ public function testGet() {
     // 200 for well-formed HEAD request.
     $response = $this->request('HEAD', $url, $request_options);
     $this->assertResourceResponse(200, '', $response);
+    // @todo Entity resources with URLs that begin with '/admin/' are marked as
+    //   administrative (see https://www.drupal.org/node/2874938), which
+    //   excludes them from Dynamic Page Cache (see
+    //   https://www.drupal.org/node/2877528). When either of those issues is
+    //   fixed, remove the if-test and the 'else' block.
+    if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) {
+      $this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache'));
+      $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache'));
+    }
+    else {
+      $this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache'));
+    }
     if (!$this->account) {
       $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Cache'));
     }
@@ -395,13 +409,53 @@ public function testGet() {
     $head_headers = $response->getHeaders();
 
     // 200 for well-formed GET request. Page Cache hit because of HEAD request.
+    // Same for Dynamic Page Cache hit.
     $response = $this->request('GET', $url, $request_options);
     $this->assertResourceResponse(200, FALSE, $response);
-    if (!static::$auth) {
-      $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Cache'));
+    // @todo Entity resources with URLs that begin with '/admin/' are marked as
+    //   administrative (see https://www.drupal.org/node/2874938), which
+    //   excludes them from Dynamic Page Cache (see
+    //   https://www.drupal.org/node/2877528). When either of those issues is
+    //   fixed, remove the if-test and the 'else' block.
+    if (strpos($this->entity->getEntityType()->getLinkTemplate('canonical'), '/admin/') !== 0) {
+      $this->assertTrue($response->hasHeader('X-Drupal-Dynamic-Cache'));
+      if (!static::$auth) {
+        $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Cache'));
+        $this->assertSame(['MISS'], $response->getHeader('X-Drupal-Dynamic-Cache'));
+      }
+      else {
+        $this->assertFalse($response->hasHeader('X-Drupal-Cache'));
+        $this->assertSame(['HIT'], $response->getHeader('X-Drupal-Dynamic-Cache'));
+        // Assert that Dynamic Page Cache did not store a ResourceResponse object,
+        // which needs serialization after every cache hit. Instead, it should
+        // contain a flattened response. Otherwise performance suffers.
+        // @see \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::flattenResponse()
+        $cache_items = $this->container->get('database')
+          ->query("SELECT cid, data FROM {cache_dynamic_page_cache} WHERE cid LIKE :pattern", [
+            ':pattern' => '%[route]=rest.%',
+          ])
+          ->fetchAllAssoc('cid');
+        $this->assertCount(2, $cache_items);
+        $found_cache_redirect = FALSE;
+        $found_cached_response = FALSE;
+        foreach ($cache_items as $cid => $cache_item) {
+          $cached_data = unserialize($cache_item->data);
+          if (!isset($cached_data['#cache_redirect'])) {
+            $found_cached_response = TRUE;
+            $cached_response = $cached_data['#response'];
+            $this->assertNotInstanceOf(ResourceResponseInterface::class, $cached_response);
+            $this->assertInstanceOf(CacheableResponseInterface::class, $cached_response);
+          }
+          else {
+            $found_cache_redirect = TRUE;
+          }
+        }
+        $this->assertTrue($found_cache_redirect);
+        $this->assertTrue($found_cached_response);
+      }
     }
     else {
-      $this->assertFalse($response->hasHeader('X-Drupal-Cache'));
+      $this->assertFalse($response->hasHeader('X-Drupal-Dynamic-Cache'));
     }
     $cache_tags_header_value = $response->getHeader('X-Drupal-Cache-Tags')[0];
     $this->assertEquals($this->getExpectedCacheTags(), empty($cache_tags_header_value) ? [] : explode(' ', $cache_tags_header_value));
@@ -424,11 +478,11 @@ public function testGet() {
     if ($this->entity->getEntityType()->getLinkTemplates()) {
       $this->assertArrayHasKey('Link', $response->getHeaders());
       $link_relation_type_manager = $this->container->get('plugin.manager.link_relation_type');
-      $expected_link_relation_headers = array_map(function ($rel) use ($link_relation_type_manager) {
-        $definition = $link_relation_type_manager->getDefinition($rel, FALSE);
-        return (!empty($definition['uri']))
-          ? $definition['uri']
-          : $rel;
+      $expected_link_relation_headers = array_map(function ($relation_name) use ($link_relation_type_manager) {
+        $link_relation_type = $link_relation_type_manager->createInstance($relation_name);
+        return $link_relation_type->isRegistered()
+          ? $link_relation_type->getRegisteredName()
+          : $link_relation_type->getExtensionUri();
       }, array_keys($this->entity->getEntityType()->getLinkTemplates()));
       $parse_rel_from_link_header = function ($value) use ($link_relation_type_manager) {
         $matches = [];
@@ -531,17 +585,17 @@ public function testGet() {
     // DX: 406 when requesting unsupported format.
     $response = $this->request('GET', $url, $request_options);
     $this->assert406Response($response);
-    $this->assertNotSame([static::$mimeType], $response->getHeader('Content-Type'));
+    $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
 
 
     $request_options[RequestOptions::HEADERS]['Accept'] = static::$mimeType;
 
 
-    // DX: 406 when requesting unsupported format but specifying Accept header.
-    // @todo Update in https://www.drupal.org/node/2825347.
+    // DX: 406 when requesting unsupported format but specifying Accept header:
+    // should result in a text/plain response.
     $response = $this->request('GET', $url, $request_options);
     $this->assert406Response($response);
-    $this->assertSame(['application/json'], $response->getHeader('Content-Type'));
+    $this->assertSame(['text/plain; charset=UTF-8'], $response->getHeader('Content-Type'));
 
 
     $url = Url::fromRoute('rest.entity.' . static::$entityTypeId . '.GET.' . static::$format);
@@ -635,7 +689,7 @@ public function testPost() {
     $response = $this->request('POST', $url, $request_options);
     $this->assertSame(415, $response->getStatusCode());
     $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type'));
-    $this->assertContains(htmlspecialchars('No "Content-Type" request header specified'), (string) $response->getBody());
+    $this->assertContains('A client error happened', (string) $response->getBody());
 
 
     $url->setOption('query', ['_format' => static::$format]);
@@ -769,6 +823,17 @@ public function testPost() {
       $this->assertSame([], $response->getHeader('Location'));
     }
     $this->assertFalse($response->hasHeader('X-Drupal-Cache'));
+
+    // BC: old default POST URLs have their path updated by the inbound path
+    // processor \Drupal\rest\PathProcessor\PathProcessorEntityResourceBC to the
+    // new URL, which is derived from the 'create' link template if an entity
+    // type specifies it.
+    if ($this->entity->getEntityType()->hasLinkTemplate('create')) {
+      $this->entityStorage->load(static::$secondCreatedEntityId)->delete();
+      $old_url = Url::fromUri('base:entity/' . static::$entityTypeId);
+      $response = $this->request('POST', $old_url, $request_options);
+      $this->assertResourceResponse(201, FALSE, $response);
+    }
   }
 
   /**
@@ -807,6 +872,7 @@ public function testPatch() {
       $this->assertSame(405, $response->getStatusCode());
       $this->assertSame(['GET, POST, HEAD'], $response->getHeader('Allow'));
       $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type'));
+      $this->assertContains('A client error happened', (string) $response->getBody());
     }
     else {
       $this->assertSame(404, $response->getStatusCode());
@@ -836,7 +902,7 @@ public function testPatch() {
     $response = $this->request('PATCH', $url, $request_options);
     $this->assertSame(415, $response->getStatusCode());
     $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type'));
-    $this->assertTrue(FALSE !== strpos((string) $response->getBody(), htmlspecialchars('No "Content-Type" request header specified')));
+    $this->assertContains('A client error happened', (string) $response->getBody());
 
 
     $url->setOption('query', ['_format' => static::$format]);
@@ -902,19 +968,15 @@ public function testPatch() {
 
 
     // DX: 403 when sending PATCH request with read-only fields.
-    // First send all fields (the "maximum normalization"). Assert the expected
-    // error message for the first PATCH-protected field. Remove that field from
-    // the normalization, send another request, assert the next PATCH-protected
-    // field error message. And so on.
-    $max_normalization = $this->getNormalizedPatchEntity() + $this->serializer->normalize($this->entity, static::$format);
-    for ($i = 0; $i < count(static::$patchProtectedFieldNames); $i++) {
-      $max_normalization = $this->removeFieldsFromNormalization($max_normalization, array_slice(static::$patchProtectedFieldNames, 0, $i));
-      $request_options[RequestOptions::BODY] = $this->serializer->serialize($max_normalization, static::$format);
+    foreach (static::$patchProtectedFieldNames as $field_name) {
+      $normalization = $this->getNormalizedPatchEntity() + [$field_name => [['value' => $this->randomString()]]];
+      $request_options[RequestOptions::BODY] = $this->serializer->serialize($normalization, static::$format);
       $response = $this->request('PATCH', $url, $request_options);
-      $this->assertResourceErrorResponse(403, "Access denied on updating field '" . static::$patchProtectedFieldNames[$i] . "'.", $response);
+      $this->assertResourceErrorResponse(403, "Access denied on updating field '$field_name'.", $response);
     }
 
     // 200 for well-formed request that sends the maximum number of fields.
+    $max_normalization = $this->getNormalizedPatchEntity() + $this->serializer->normalize($this->entity, static::$format);
     $max_normalization = $this->removeFieldsFromNormalization($max_normalization, static::$patchProtectedFieldNames);
     $request_options[RequestOptions::BODY] = $this->serializer->serialize($max_normalization, static::$format);
     $response = $this->request('PATCH', $url, $request_options);
@@ -992,13 +1054,14 @@ public function testDelete() {
     $request_options = [];
 
 
-    // DX: 405 when resource not provisioned, but HTML if canonical route. Plain
+    // DX: 404 when resource not provisioned, but 405 if canonical route. Plain
     // text  or HTML response because missing ?_format query string.
     $response = $this->request('DELETE', $url, $request_options);
     if ($has_canonical_url) {
       $this->assertSame(405, $response->getStatusCode());
       $this->assertSame(['GET, POST, HEAD'], $response->getHeader('Allow'));
       $this->assertSame(['text/html; charset=UTF-8'], $response->getHeader('Content-Type'));
+      $this->assertContains('A client error happened', (string) $response->getBody());
     }
     else {
       $this->assertSame(404, $response->getStatusCode());
@@ -1099,10 +1162,9 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques
         $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
 
 
-        // DX: 400 when incorrect entity type bundle is specified.
-        // @todo Change to 422 in https://www.drupal.org/node/2827084.
+        // DX: 422 when incorrect entity type bundle is specified.
         $response = $this->request($method, $url, $request_options);
-        $this->assertResourceErrorResponse(400, '"bad_bundle_name" is not a valid bundle type for denormalization.', $response);
+        $this->assertResourceErrorResponse(422, '"bad_bundle_name" is not a valid bundle type for denormalization.', $response);
       }
 
 
@@ -1110,10 +1172,9 @@ protected function assertNormalizationEdgeCases($method, Url $url, array $reques
       $request_options[RequestOptions::BODY] = $this->serializer->encode($normalization, static::$format);
 
 
-      // DX: 400 when no entity type bundle is specified.
-      // @todo Change to 422 in https://www.drupal.org/node/2827084.
+      // DX: 422 when no entity type bundle is specified.
       $response = $this->request($method, $url, $request_options);
-      $this->assertResourceErrorResponse(400, sprintf('Could not determine entity type bundle: "%s" field is missing.', $bundle_field_name), $response);
+      $this->assertResourceErrorResponse(422, sprintf('Could not determine entity type bundle: "%s" field is missing.', $bundle_field_name), $response);
     }
   }
 
@@ -1135,8 +1196,8 @@ protected function getEntityResourceUrl() {
    *   The URL to POST to.
    */
   protected function getEntityResourcePostUrl() {
-    $has_canonical_url = $this->entity->hasLinkTemplate('https://www.drupal.org/link-relations/create');
-    return $has_canonical_url ? $this->entity->toUrl() : Url::fromUri('base:entity/' . static::$entityTypeId);
+    $has_create_url = $this->entity->hasLinkTemplate('create');
+    return $has_create_url ? Url::fromUri('internal:' . $this->entity->getEntityType()->getLinkTemplate('create')) : Url::fromUri('base:entity/' . static::$entityTypeId);
   }
 
   /**
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php
new file mode 100644
index 0000000000..582a0b0e55
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonAnonTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FieldStorageConfigJsonAnonTest extends FieldStorageConfigResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonBasicAuthTest.php
new file mode 100644
index 0000000000..4219cad288
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonBasicAuthTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FieldStorageConfigJsonBasicAuthTest extends FieldStorageConfigResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonCookieTest.php
new file mode 100644
index 0000000000..c40aa7d872
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigJsonCookieTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class FieldStorageConfigJsonCookieTest extends FieldStorageConfigResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigResourceTestBase.php
new file mode 100644
index 0000000000..aafc2531e7
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/FieldStorageConfig/FieldStorageConfigResourceTestBase.php
@@ -0,0 +1,104 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\FieldStorageConfig;
+
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+
+abstract class FieldStorageConfigResourceTestBase extends EntityResourceTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $entityTypeId = 'field_storage_config';
+
+  /**
+   * @var \Drupal\field\FieldConfigStorage
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+    $this->grantPermissionsToTestedRole(['administer node fields']);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $field_storage = FieldStorageConfig::create([
+      'field_name' => 'true_llama',
+      'entity_type' => 'node',
+      'type' => 'boolean',
+    ]);
+    $field_storage->save();
+    return $field_storage;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return [
+      'cardinality' => 1,
+      'custom_storage' => FALSE,
+      'dependencies' => [
+        'module' => ['node'],
+      ],
+      'entity_type' => 'node',
+      'field_name' => 'true_llama',
+      'id' => 'node.true_llama',
+      'indexes' => [],
+      'langcode' => 'en',
+      'locked' => FALSE,
+      'module' => 'core',
+      'persist_with_no_fields' => FALSE,
+      'settings' => [],
+      'status' => TRUE,
+      'translatable' => TRUE,
+      'type' => 'boolean',
+      'uuid' => $this->entity->uuid(),
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    // @todo Update in https://www.drupal.org/node/2300677.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedUnauthorizedAccessMessage($method) {
+    if ($this->config('rest.settings')->get('bc_entity_resource_permissions')) {
+      return parent::getExpectedUnauthorizedAccessMessage($method);
+    }
+
+    switch ($method) {
+      case 'GET':
+        return "The 'administer node fields' permission is required.";
+
+      default:
+        return parent::getExpectedUnauthorizedAccessMessage($method);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedCacheContexts() {
+    return [
+      'user.permissions',
+    ];
+  }
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php
index cfbd971611..92fad1e39d 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/Node/NodeResourceTestBase.php
@@ -23,7 +23,6 @@
    * {@inheritdoc}
    */
   protected static $patchProtectedFieldNames = [
-    'uid',
     'created',
     'changed',
     'promote',
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php
new file mode 100644
index 0000000000..3720ac608c
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonAnonTest.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutSetJsonAnonTest extends ShortcutSetResourceTestBase {
+
+  use AnonResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonBasicAuthTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonBasicAuthTest.php
new file mode 100644
index 0000000000..388b9def6f
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonBasicAuthTest.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutSetJsonBasicAuthTest extends ShortcutSetResourceTestBase {
+
+  use BasicAuthResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['basic_auth'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'basic_auth';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonCookieTest.php b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonCookieTest.php
new file mode 100644
index 0000000000..28df3ddfa4
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetJsonCookieTest.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\ShortcutSet;
+
+use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
+
+/**
+ * @group rest
+ */
+class ShortcutSetJsonCookieTest extends ShortcutSetResourceTestBase {
+
+  use CookieResourceTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $format = 'json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $mimeType = 'application/json';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $auth = 'cookie';
+
+}
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetResourceTestBase.php b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetResourceTestBase.php
new file mode 100644
index 0000000000..97ae1a66aa
--- /dev/null
+++ b/core/modules/rest/tests/src/Functional/EntityResource/ShortcutSet/ShortcutSetResourceTestBase.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Tests\rest\Functional\EntityResource\ShortcutSet;
+
+use Drupal\shortcut\Entity\ShortcutSet;
+use Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase;
+
+/**
+ * ResourceTestBase for ShortcutSet entity.
+ */
+abstract class ShortcutSetResourceTestBase extends EntityResourceTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['shortcut'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $entityTypeId = 'shortcut_set';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $patchProtectedFieldNames = [];
+
+  /**
+   * The ShortcutSet entity.
+   *
+   * @var \Drupal\shortcut\ShortcutSetInterface
+   */
+  protected $entity;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUpAuthorization($method) {
+    switch ($method) {
+      case 'GET':
+        $this->grantPermissionsToTestedRole(['access shortcuts']);
+        break;
+
+      case 'POST':
+      case 'PATCH':
+        $this->grantPermissionsToTestedRole(['access shortcuts', 'customize shortcut links']);
+        break;
+
+      case 'DELETE':
+        $this->grantPermissionsToTestedRole(['administer shortcuts']);
+        break;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function createEntity() {
+    $set = ShortcutSet::create([
+      'id' => 'llama_set',
+      'label' => 'Llama Set',
+    ]);
+    $set->save();
+    return $set;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getExpectedNormalizedEntity() {
+    return [
+      'id' => 'llama_set',
+      'uuid' => $this->entity->uuid(),
+      'label' => 'Llama Set',
+      'status' => TRUE,
+      'langcode' => 'en',
+      'dependencies' => [],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getNormalizedPostEntity() {
+    // @todo Update in https://www.drupal.org/node/2300677.
+  }
+
+}
diff --git a/core/modules/rest/tests/src/Functional/ResourceTestBase.php b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
index c9e4c443eb..74aa144f14 100644
--- a/core/modules/rest/tests/src/Functional/ResourceTestBase.php
+++ b/core/modules/rest/tests/src/Functional/ResourceTestBase.php
@@ -321,6 +321,9 @@ protected function grantPermissionsToTestedRole(array $permissions) {
    * 'http_errors = FALSE' request option, nor do we want them to have to
    * convert Drupal Url objects to strings.
    *
+   * We also don't want to follow redirects automatically, to ensure these tests
+   * are able to detect when redirects are added or removed.
+   *
    * @see \GuzzleHttp\ClientInterface::request()
    *
    * @param string $method
@@ -334,6 +337,7 @@ protected function grantPermissionsToTestedRole(array $permissions) {
    */
   protected function request($method, Url $url, array $request_options) {
     $request_options[RequestOptions::HTTP_ERRORS] = FALSE;
+    $request_options[RequestOptions::ALLOW_REDIRECTS] = FALSE;
     $request_options = $this->decorateWithXdebugCookie($request_options);
     $client = $this->getSession()->getDriver()->getClient()->getClient();
     return $client->request($method, $url->setAbsolute(TRUE)->toString(), $request_options);
diff --git a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
index b417e2acda..2b8855917e 100644
--- a/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
+++ b/core/modules/rest/tests/src/Kernel/RequestHandlerTest.php
@@ -49,7 +49,7 @@ public function setUp() {
    */
   public function testHandle() {
     $request = new Request();
-    $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_format' => 'json']));
+    $route_match = new RouteMatch('test', (new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_format' => 'json']))->setMethods(['GET']));
 
     $resource = $this->prophesize(StubRequestHandlerResourcePlugin::class);
     $resource->get(NULL, $request)
@@ -76,7 +76,7 @@ public function testHandle() {
     $this->assertEquals($response, $handler_response);
 
     // We will call the patch method this time.
-    $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_content_type_format' => 'json']));
+    $route_match = new RouteMatch('test', (new Route('/rest/test', ['_rest_resource_config' => 'restplugin'], ['_content_type_format' => 'json']))->setMethods(['PATCH']));
     $request->setMethod('PATCH');
     $response = new ResourceResponse([]);
     $resource->patch(NULL, $request)
diff --git a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
index 3ed6545316..3b1c1f7f39 100644
--- a/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
+++ b/core/modules/rest/tests/src/Unit/CollectRoutesTest.php
@@ -141,8 +141,8 @@ public function testRoutesRequirements() {
     $requirements_1 = $this->routes->get('test_1')->getRequirements();
     $requirements_2 = $this->routes->get('view.test_view.page_1')->getRequirements();
 
-    $this->assertEquals(count($requirements_1), 0, 'First route has no requirement.');
-    $this->assertEquals(count($requirements_2), 2, 'Views route with rest export had the format and method requirements added.');
+    $this->assertEquals(0, count($requirements_1), 'First route has no requirement.');
+    $this->assertEquals(1, count($requirements_2), 'Views route with rest export had the format requirement added.');
 
     // Check auth options.
     $auth = $this->routes->get('view.test_view.page_1')->getOption('_auth');
diff --git a/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php
index b16a13119f..d09fdced4c 100644
--- a/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php
+++ b/core/modules/rest/tests/src/Unit/EventSubscriber/ResourceResponseSubscriberTest.php
@@ -79,11 +79,6 @@ public function providerTestSerialization() {
    * @dataProvider providerTestResponseFormat
    */
   public function testResponseFormat($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) {
-    $parameters = [];
-    if ($request_format !== FALSE) {
-      $parameters['_format'] = $request_format;
-    }
-
     foreach ($request_headers as $key => $value) {
       unset($request_headers[$key]);
       $key = strtoupper(str_replace('-', '_', $key));
@@ -91,8 +86,13 @@ public function testResponseFormat($methods, array $supported_formats, $request_
     }
 
     foreach ($methods as $method) {
-      $request = Request::create('/rest/test', $method, $parameters, [], [], $request_headers, $request_body);
-      $route_requirement_key_format = $request->isMethodSafe() ? '_format' : '_content_type_format';
+      $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body);
+      // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care
+      // of this so we'll hard code it here.
+      if ($request_format) {
+        $request->setRequestFormat($request_format);
+      }
+      $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format';
       $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $this->randomMachineName()], [$route_requirement_key_format => implode('|', $supported_formats)]));
 
       $resource_response_subscriber = new ResourceResponseSubscriber(
@@ -116,11 +116,6 @@ public function testResponseFormat($methods, array $supported_formats, $request_
   public function testOnResponseWithCacheableResponse($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) {
     $rest_config_name = $this->randomMachineName();
 
-    $parameters = [];
-    if ($request_format !== FALSE) {
-      $parameters['_format'] = $request_format;
-    }
-
     foreach ($request_headers as $key => $value) {
       unset($request_headers[$key]);
       $key = strtoupper(str_replace('-', '_', $key));
@@ -128,8 +123,13 @@ public function testOnResponseWithCacheableResponse($methods, array $supported_f
     }
 
     foreach ($methods as $method) {
-      $request = Request::create('/rest/test', $method, $parameters, [], [], $request_headers, $request_body);
-      $route_requirement_key_format = $request->isMethodSafe() ? '_format' : '_content_type_format';
+      $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body);
+      // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care
+      // of this so we'll hard code it here.
+      if ($request_format) {
+        $request->setRequestFormat($request_format);
+      }
+      $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format';
       $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $rest_config_name], [$route_requirement_key_format => implode('|', $supported_formats)]));
 
       // The RequestHandler must return a ResourceResponseInterface object.
@@ -166,11 +166,6 @@ public function testOnResponseWithCacheableResponse($methods, array $supported_f
   public function testOnResponseWithUncacheableResponse($methods, array $supported_formats, $request_format, array $request_headers, $request_body, $expected_response_format, $expected_response_content_type, $expected_response_content) {
     $rest_config_name = $this->randomMachineName();
 
-    $parameters = [];
-    if ($request_format !== FALSE) {
-      $parameters['_format'] = $request_format;
-    }
-
     foreach ($request_headers as $key => $value) {
       unset($request_headers[$key]);
       $key = strtoupper(str_replace('-', '_', $key));
@@ -178,8 +173,13 @@ public function testOnResponseWithUncacheableResponse($methods, array $supported
     }
 
     foreach ($methods as $method) {
-      $request = Request::create('/rest/test', $method, $parameters, [], [], $request_headers, $request_body);
-      $route_requirement_key_format = $request->isMethodSafe() ? '_format' : '_content_type_format';
+      $request = Request::create('/rest/test', $method, [], [], [], $request_headers, $request_body);
+      // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care
+      // of this so we'll hard code it here.
+      if ($request_format) {
+        $request->setRequestFormat($request_format);
+      }
+      $route_requirement_key_format = $request->isMethodCacheable() ? '_format' : '_content_type_format';
       $route_match = new RouteMatch('test', new Route('/rest/test', ['_rest_resource_config' => $rest_config_name], [$route_requirement_key_format => implode('|', $supported_formats)]));
 
       // The RequestHandler must return a ResourceResponseInterface object.
diff --git a/core/modules/search/search.module b/core/modules/search/search.module
index bf00878d39..ae99a8731e 100644
--- a/core/modules/search/search.module
+++ b/core/modules/search/search.module
@@ -8,6 +8,7 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Cache\Cache;
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
 
@@ -218,7 +219,7 @@ function search_update_totals() {
   // search_total. We use a LEFT JOIN between the two tables and keep only the
   // rows which fail to join.
   $result = db_query("SELECT t.word AS realword, i.word FROM {search_total} t LEFT JOIN {search_index} i ON t.word = i.word WHERE i.word IS NULL", [], ['target' => 'replica']);
-  $or = db_or();
+  $or = new Condition('OR');
   foreach ($result as $word) {
     $or->condition('word', $word->realword);
   }
diff --git a/core/modules/search/src/Controller/SearchController.php b/core/modules/search/src/Controller/SearchController.php
index ac078e18eb..4beb8448fe 100644
--- a/core/modules/search/src/Controller/SearchController.php
+++ b/core/modules/search/src/Controller/SearchController.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Render\RendererInterface;
+use Drupal\search\Form\SearchPageForm;
 use Drupal\search\SearchPageInterface;
 use Drupal\search\SearchPageRepositoryInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -84,7 +85,7 @@ public function view(Request $request, SearchPageInterface $entity) {
     }
 
     $build['#title'] = $plugin->suggestedTitle();
-    $build['search_form'] = $this->entityFormBuilder()->getForm($entity, 'search');
+    $build['search_form'] = $this->formBuilder()->getForm(SearchPageForm::class, $entity);
 
     // Build search results, if keywords or other search parameters are in the
     // GET parameters. Note that we need to try the search if 'keys' is in
diff --git a/core/modules/search/src/Entity/SearchPage.php b/core/modules/search/src/Entity/SearchPage.php
index 298331fdf0..85ddc26082 100644
--- a/core/modules/search/src/Entity/SearchPage.php
+++ b/core/modules/search/src/Entity/SearchPage.php
@@ -22,7 +22,6 @@
  *     "form" = {
  *       "add" = "Drupal\search\Form\SearchPageAddForm",
  *       "edit" = "Drupal\search\Form\SearchPageEditForm",
- *       "search" = "Drupal\search\Form\SearchPageForm",
  *       "delete" = "Drupal\Core\Entity\EntityDeleteForm"
  *     }
  *   },
diff --git a/core/modules/search/src/Form/SearchPageForm.php b/core/modules/search/src/Form/SearchPageForm.php
index 88b99e55eb..e46195baea 100644
--- a/core/modules/search/src/Form/SearchPageForm.php
+++ b/core/modules/search/src/Form/SearchPageForm.php
@@ -2,9 +2,10 @@
 
 namespace Drupal\search\Form;
 
-use Drupal\Core\Entity\EntityForm;
+use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
+use Drupal\search\SearchPageInterface;
 
 /**
  * Provides a search form for site wide search.
@@ -15,10 +16,10 @@
  * trigger the search being processed by the controller, and adding in any
  * additional query parameters they need to execute search.
  */
-class SearchPageForm extends EntityForm {
+class SearchPageForm extends FormBase {
 
   /**
-   * {@inheritdoc}
+   * The search page entity.
    *
    * @var \Drupal\search\SearchPageInterface
    */
@@ -34,7 +35,9 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
-  public function form(array $form, FormStateInterface $form_state) {
+  public function buildForm(array $form, FormStateInterface $form_state, SearchPageInterface $search_page = NULL) {
+    $this->entity = $search_page;
+
     $plugin = $this->entity->getPlugin();
     $form_state->set('search_page_id', $this->entity->id());
 
@@ -72,16 +75,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // Allow the plugin to add to or alter the search form.
     $plugin->searchFormAlter($form, $form_state);
-
-    return parent::form($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function actions(array $form, FormStateInterface $form_state) {
-    // The submit button is added in the form directly.
-    return [];
+    return $form;
   }
 
   /**
diff --git a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php
index 50a44dbf3b..7ad95f1682 100644
--- a/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php
+++ b/core/modules/search/src/Plugin/ConfigurableSearchPluginBase.php
@@ -23,7 +23,7 @@
   public function __construct(array $configuration, $plugin_id, $plugin_definition) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
 
-    $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $this->configuration);
+    $this->setConfiguration($configuration);
   }
 
   /**
@@ -44,7 +44,7 @@ public function getConfiguration() {
    * {@inheritdoc}
    */
   public function setConfiguration(array $configuration) {
-    $this->configuration = $configuration;
+    $this->configuration = NestedArray::mergeDeep($this->defaultConfiguration(), $configuration);
   }
 
   /**
diff --git a/core/modules/search/src/Plugin/SearchInterface.php b/core/modules/search/src/Plugin/SearchInterface.php
index 2f2403c2fe..8f95ce8246 100644
--- a/core/modules/search/src/Plugin/SearchInterface.php
+++ b/core/modules/search/src/Plugin/SearchInterface.php
@@ -110,7 +110,7 @@ public function getHelp();
    *
    * The core search module only invokes this method on active module plugins
    * when building a form for them in
-   * \Drupal\search\Form\SearchPageForm::form(). A plugin implementing this
+   * \Drupal\search\Form\SearchPageForm::buildForm(). A plugin implementing this
    * will also need to implement the buildSearchUrlQuery() method.
    *
    * @param array $form
diff --git a/core/modules/search/src/Plugin/views/argument/Search.php b/core/modules/search/src/Plugin/views/argument/Search.php
index 82afbbfe6a..7e9f00d4bd 100644
--- a/core/modules/search/src/Plugin/views/argument/Search.php
+++ b/core/modules/search/src/Plugin/views/argument/Search.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\search\Plugin\views\argument;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
@@ -76,7 +77,7 @@ public function query($group_by = FALSE) {
     else {
       $search_index = $this->ensureMyTable();
 
-      $search_condition = db_and();
+      $search_condition = new Condition('AND');
 
       // Create a new join to relate the 'search_total' table to our current 'search_index' table.
       $definition = [
@@ -109,7 +110,7 @@ public function query($group_by = FALSE) {
       // Add the keyword conditions, as is done in
       // SearchQuery::prepareAndNormalize(), but simplified because we are
       // only concerned with relevance ranking so we do not need to normalize.
-      $or = db_or();
+      $or = new Condition('OR');
       foreach ($words as $word) {
         $or->condition("$search_index.word", $word);
       }
diff --git a/core/modules/search/src/Plugin/views/filter/Search.php b/core/modules/search/src/Plugin/views/filter/Search.php
index c95fd96ec2..ac0f671ae2 100644
--- a/core/modules/search/src/Plugin/views/filter/Search.php
+++ b/core/modules/search/src/Plugin/views/filter/Search.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\search\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\filter\FilterPluginBase;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -150,7 +151,7 @@ public function query() {
     else {
       $search_index = $this->ensureMyTable();
 
-      $search_condition = db_and();
+      $search_condition = new Condition('AND');
 
       // Create a new join to relate the 'search_total' table to our current
       // 'search_index' table.
@@ -184,7 +185,7 @@ public function query() {
       // Add the keyword conditions, as is done in
       // SearchQuery::prepareAndNormalize(), but simplified because we are
       // only concerned with relevance ranking so we do not need to normalize.
-      $or = db_or();
+      $or = new Condition('OR');
       foreach ($words as $word) {
         $or->condition("$search_index.word", $word);
       }
diff --git a/core/modules/search/src/SearchQuery.php b/core/modules/search/src/SearchQuery.php
index 7c4e07e207..dbd0534235 100644
--- a/core/modules/search/src/SearchQuery.php
+++ b/core/modules/search/src/SearchQuery.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\search;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Database\Query\SelectExtender;
 use Drupal\Core\Database\Query\SelectInterface;
@@ -205,7 +206,7 @@ public function searchExpression($expression, $type) {
     $this->addTag('search_' . $type);
 
     // Initialize conditions and status.
-    $this->conditions = db_and();
+    $this->conditions = new Condition('AND');
     $this->status = 0;
 
     return $this;
@@ -313,7 +314,7 @@ protected function parseSearchExpression() {
         }
         $has_or = TRUE;
         $has_new_scores = FALSE;
-        $queryor = db_or();
+        $queryor = new Condition('OR');
         foreach ($key as $or) {
           list($num_new_scores) = $this->parseWord($or);
           $has_new_scores |= $num_new_scores;
@@ -401,7 +402,7 @@ public function prepareAndNormalize() {
     }
 
     // Build the basic search query: match the entered keywords.
-    $or = db_or();
+    $or = new Condition('OR');
     foreach ($this->words as $word) {
       $or->condition('i.word', $word);
     }
diff --git a/core/modules/search/src/ViewsSearchQuery.php b/core/modules/search/src/ViewsSearchQuery.php
index ca4b16c71e..ca804a889b 100644
--- a/core/modules/search/src/ViewsSearchQuery.php
+++ b/core/modules/search/src/ViewsSearchQuery.php
@@ -74,8 +74,8 @@ public function conditionReplaceString($search, $replace, &$condition) {
       $conditions =& $condition['field']->conditions();
       foreach ($conditions as $key => &$subcondition) {
         if (is_numeric($key)) {
-          // As conditions can have subconditions, for example db_or(), the
-          // function has to be called recursively.
+          // As conditions can be nested, the function has to be called
+          // recursively.
           $this->conditionReplaceString($search, $replace, $subcondition);
         }
       }
diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml
index 3e47b005cb..3607182ee2 100644
--- a/core/modules/serialization/serialization.services.yml
+++ b/core/modules/serialization/serialization.services.yml
@@ -33,6 +33,7 @@ services:
       # this modules generic field item normalizer.
       # @todo Find a better way for this in https://www.drupal.org/node/2575761.
       - { name: normalizer, priority: 8 }
+    arguments: ['@entity.repository']
   serialization.normalizer.field_item:
     class: Drupal\serialization\Normalizer\FieldItemNormalizer
     tags:
diff --git a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php
index 4706bf403d..ea2e020bf0 100644
--- a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php
+++ b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php
@@ -2,12 +2,15 @@
 
 namespace Drupal\serialization\Normalizer;
 
+use Drupal\Core\Entity\EntityRepositoryInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 
 /**
  * Adds the file URI to embedded file entities.
  */
-class EntityReferenceFieldItemNormalizer extends ComplexDataNormalizer {
+class EntityReferenceFieldItemNormalizer extends FieldItemNormalizer {
 
   /**
    * The interface or class that this Normalizer supports.
@@ -17,6 +20,23 @@ class EntityReferenceFieldItemNormalizer extends ComplexDataNormalizer {
   protected $supportedInterfaceOrClass = EntityReferenceItem::class;
 
   /**
+   * The entity repository.
+   *
+   * @var \Drupal\Core\Entity\EntityRepositoryInterface
+   */
+  protected $entityRepository;
+
+  /**
+   * Constructs a EntityReferenceFieldItemNormalizer object.
+   *
+   * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
+   *   The entity repository.
+   */
+  public function __construct(EntityRepositoryInterface $entity_repository) {
+    $this->entityRepository = $entity_repository;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function normalize($field_item, $format = NULL, array $context = []) {
@@ -35,8 +55,32 @@ public function normalize($field_item, $format = NULL, array $context = []) {
         $values['url'] = $url;
       }
     }
-
     return $values;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function constructValue($data, $context) {
+    if (isset($data['target_uuid'])) {
+      /** @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem $field_item */
+      $field_item = $context['target_instance'];
+      if (empty($data['target_uuid'])) {
+        throw new InvalidArgumentException(sprintf('If provided "target_uuid" cannot be empty for field "%s".', $data['target_type'], $data['target_uuid'], $field_item->getName()));
+      }
+      $target_type = $field_item->getFieldDefinition()->getSetting('target_type');
+      if (!empty($data['target_type']) && $target_type !== $data['target_type']) {
+        throw new UnexpectedValueException(sprintf('The field "%s" property "target_type" must be set to "%s" or omitted.', $field_item->getFieldDefinition()->getName(), $target_type));
+      }
+      if ($entity = $this->entityRepository->loadEntityByUuid($target_type, $data['target_uuid'])) {
+        return ['target_id' => $entity->id()];
+      }
+      else {
+        // Unable to load entity by uuid.
+        throw new InvalidArgumentException(sprintf('No "%s" entity found with UUID "%s" for field "%s".', $data['target_type'], $data['target_uuid'], $field_item->getName()));
+      }
+    }
+    return parent::constructValue($data, $context);
+  }
+
 }
diff --git a/core/modules/serialization/src/Normalizer/NormalizerBase.php b/core/modules/serialization/src/Normalizer/NormalizerBase.php
index 90d9b75258..7916a9092a 100644
--- a/core/modules/serialization/src/Normalizer/NormalizerBase.php
+++ b/core/modules/serialization/src/Normalizer/NormalizerBase.php
@@ -18,6 +18,13 @@
   protected $supportedInterfaceOrClass;
 
   /**
+   * List of formats which supports (de-)normalization.
+   *
+   * @var string|string[]
+   */
+  protected $format;
+
+  /**
    * {@inheritdoc}
    */
   public function supportsNormalization($data, $format = NULL) {
@@ -71,7 +78,7 @@ protected function checkFormat($format = NULL) {
       return TRUE;
     }
 
-    return in_array($format, (array) $this->format);
+    return in_array($format, (array) $this->format, TRUE);
   }
 
 }
diff --git a/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php b/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php
index 630535dea7..f9a5b77298 100644
--- a/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php
+++ b/core/modules/serialization/tests/src/Unit/CompilerPass/RegisterSerializationClassesCompilerPassTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\serialization\RegisterSerializationClassesCompilerPass;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\Serializer\Serializer;
 
@@ -11,7 +12,7 @@
  * @coversDefaultClass \Drupal\serialization\RegisterSerializationClassesCompilerPass
  * @group serialization
  */
-class RegisterSerializationClassesCompilerPassTest extends \PHPUnit_Framework_TestCase {
+class RegisterSerializationClassesCompilerPassTest extends UnitTestCase {
 
   /**
    * @covers ::process
diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
index d010a0494e..e0561a1003 100644
--- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
+++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php
@@ -3,11 +3,18 @@
 namespace Drupal\Tests\serialization\Unit\Normalizer;
 
 use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
+use Drupal\Core\Entity\EntityRepositoryInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
+use Drupal\Core\Field\FieldItemInterface;
+use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
 use Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer;
 use Drupal\Tests\UnitTestCase;
 use Prophecy\Argument;
+use Symfony\Component\Serializer\Exception\InvalidArgumentException;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
 use Symfony\Component\Serializer\Serializer;
 
 /**
@@ -38,10 +45,25 @@ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
   protected $fieldItem;
 
   /**
+   * The mock entity repository.
+   *
+   * @var \Drupal\Core\Entity\EntityRepositoryInterface|\Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $entityRepository;
+
+  /**
+   * The mock field definition.
+   *
+   * @var \Drupal\Core\Field\FieldDefinitionInterface|\Prophecy\Prophecy\ObjectProphecy
+   */
+  protected $fieldDefinition;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
-    $this->normalizer = new EntityReferenceFieldItemNormalizer();
+    $this->entityRepository = $this->prophesize(EntityRepositoryInterface::class);
+    $this->normalizer = new EntityReferenceFieldItemNormalizer($this->entityRepository->reveal());
 
     $this->serializer = $this->prophesize(Serializer::class);
     // Set up the serializer to return an entity property.
@@ -53,6 +75,9 @@ protected function setUp() {
     $this->fieldItem = $this->prophesize(EntityReferenceItem::class);
     $this->fieldItem->getIterator()
       ->willReturn(new \ArrayIterator(['target_id' => []]));
+
+    $this->fieldDefinition = $this->prophesize(FieldDefinitionInterface::class);
+
   }
 
   /**
@@ -64,6 +89,14 @@ public function testSupportsNormalization() {
   }
 
   /**
+   * @covers ::supportsDenormalization
+   */
+  public function testSupportsDenormalization() {
+    $this->assertTrue($this->normalizer->supportsDenormalization([], EntityReferenceItem::class));
+    $this->assertFalse($this->normalizer->supportsDenormalization([], FieldItemInterface::class));
+  }
+
+  /**
    * @covers ::normalize
    */
   public function testNormalize() {
@@ -121,4 +154,149 @@ public function testNormalizeWithNoEntity() {
     $this->assertSame($expected, $normalized);
   }
 
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithTypeAndUuid() {
+    $data = [
+      'target_id' => ['value' => 'test'],
+      'target_type' => 'test_type',
+      'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
+    ];
+
+    $entity = $this->prophesize(FieldableEntityInterface::class);
+    $entity->id()
+      ->willReturn('test')
+      ->shouldBeCalled();
+    $this->entityRepository
+      ->loadEntityByUuid($data['target_type'], $data['target_uuid'])
+      ->willReturn($entity)
+      ->shouldBeCalled();
+
+    $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled();
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithUuidWithoutType() {
+    $data = [
+      'target_id' => ['value' => 'test'],
+      'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
+    ];
+
+    $entity = $this->prophesize(FieldableEntityInterface::class);
+    $entity->id()
+      ->willReturn('test')
+      ->shouldBeCalled();
+    $this->entityRepository
+      ->loadEntityByUuid('test_type', $data['target_uuid'])
+      ->willReturn($entity)
+      ->shouldBeCalled();
+
+    $this->fieldItem->setValue(['target_id' => 'test'])->shouldBeCalled();
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithUuidWithIncorrectType() {
+    $this->setExpectedException(UnexpectedValueException::class, 'The field "field_reference" property "target_type" must be set to "test_type" or omitted.');
+
+    $data = [
+      'target_id' => ['value' => 'test'],
+      'target_type' => 'wrong_type',
+      'target_uuid' => '080e3add-f9d5-41ac-9821-eea55b7b42fb',
+    ];
+
+    $this->fieldDefinition
+      ->getName()
+      ->willReturn('field_reference')
+      ->shouldBeCalled();
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithTypeWithIncorrectUuid() {
+    $this->setExpectedException(InvalidArgumentException::class, 'No "test_type" entity found with UUID "unique-but-none-non-existent" for field "field_reference"');
+
+    $data = [
+      'target_id' => ['value' => 'test'],
+      'target_type' => 'test_type',
+      'target_uuid' => 'unique-but-none-non-existent',
+    ];
+    $this->entityRepository
+      ->loadEntityByUuid($data['target_type'], $data['target_uuid'])
+      ->willReturn(NULL)
+      ->shouldBeCalled();
+    $this->fieldItem
+      ->getName()
+      ->willReturn('field_reference')
+      ->shouldBeCalled();
+
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithEmtpyUuid() {
+    $this->setExpectedException(InvalidArgumentException::class, 'If provided "target_uuid" cannot be empty for field "test_type".');
+
+    $data = [
+      'target_id' => ['value' => 'test'],
+      'target_type' => 'test_type',
+      'target_uuid' => '',
+    ];
+    $this->fieldItem
+      ->getName()
+      ->willReturn('field_reference')
+      ->shouldBeCalled();
+
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * @covers ::denormalize
+   */
+  public function testDenormalizeWithId() {
+    $data = [
+      'target_id' => ['value' => 'test'],
+    ];
+    $this->fieldItem->setValue($data)->shouldBeCalled();
+
+    $this->assertDenormalize($data);
+  }
+
+  /**
+   * Asserts denormalization process is correct for give data.
+   *
+   * @param array $data
+   *   The data to denormalize.
+   */
+  protected function assertDenormalize(array $data) {
+    $this->fieldItem->getParent()
+      ->willReturn($this->prophesize(FieldItemListInterface::class)->reveal());
+    $this->fieldItem->getFieldDefinition()->willReturn($this->fieldDefinition->reveal());
+    if (!empty($data['target_uuid'])) {
+      $this->fieldDefinition
+        ->getSetting('target_type')
+        ->willReturn('test_type')
+        ->shouldBeCalled();
+    }
+
+    $context = ['target_instance' => $this->fieldItem->reveal()];
+    $denormalized = $this->normalizer->denormalize($data, EntityReferenceItem::class, 'json', $context);
+    $this->assertSame($context['target_instance'], $denormalized);
+  }
+
 }
diff --git a/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php b/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php
index b5ce0e81eb..3a55f74999 100644
--- a/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php
+++ b/core/modules/shortcut/src/ShortcutSetAccessControlHandler.php
@@ -19,6 +19,8 @@ class ShortcutSetAccessControlHandler extends EntityAccessControlHandler {
    */
   protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
     switch ($operation) {
+      case 'view':
+        return AccessResult::allowedIf($account->hasPermission('access shortcuts'))->cachePerPermissions();
       case 'update':
         if ($account->hasPermission('administer shortcuts')) {
           return AccessResult::allowed()->cachePerPermissions();
diff --git a/core/modules/simpletest/simpletest.install b/core/modules/simpletest/simpletest.install
index b6cfc80e10..530228834a 100644
--- a/core/modules/simpletest/simpletest.install
+++ b/core/modules/simpletest/simpletest.install
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Component\Utility\Environment;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Minimum value of PHP memory_limit for SimpleTest.
@@ -18,7 +19,7 @@
 function simpletest_requirements($phase) {
   $requirements = [];
 
-  $has_phpunit = class_exists('\PHPUnit_Framework_TestCase');
+  $has_phpunit = class_exists(TestCase::class);
   $has_curl = function_exists('curl_init');
   $open_basedir = ini_get('open_basedir');
 
diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module
index 7d72aa44bc..e5c67d3954 100644
--- a/core/modules/simpletest/simpletest.module
+++ b/core/modules/simpletest/simpletest.module
@@ -13,6 +13,7 @@
 use Drupal\Core\Test\TestDatabase;
 use Drupal\simpletest\TestDiscovery;
 use Drupal\Tests\Listeners\SimpletestUiPrinter;
+use PHPUnit\Framework\TestCase;
 use Symfony\Component\Process\PhpExecutableFinder;
 use Drupal\Core\Test\TestStatus;
 
@@ -284,8 +285,15 @@ function simpletest_phpunit_xml_filepath($test_id) {
  *
  * @return string
  *   The path to core's phpunit.xml.dist configuration file.
+ *
+ * @deprecated in Drupal 8.4.x for removal before Drupal 9.0.0. PHPUnit test
+ *   runners should change directory into core/ and then run the phpunit tool.
+ *   See simpletest_phpunit_run_command() for an example.
+ *
+ * @see simpletest_phpunit_run_command()
  */
 function simpletest_phpunit_configuration_filepath() {
+  @trigger_error('The ' . __FUNCTION__ . ' function is deprecated since version 8.4.x and will be removed in 9.0.0.', E_USER_DEPRECATED);
   return \Drupal::root() . '/core/phpunit.xml.dist';
 }
 
@@ -412,7 +420,7 @@ function _simpletest_batch_operation($test_list_init, $test_id, &$context) {
 
   // Perform the next test.
   $test_class = array_shift($test_list);
-  if (is_subclass_of($test_class, \PHPUnit_Framework_TestCase::class)) {
+  if (is_subclass_of($test_class, TestCase::class)) {
     $phpunit_results = simpletest_run_phpunit_tests($test_id, [$test_class]);
     simpletest_process_phpunit_results($phpunit_results);
     $test_results[$test_class] = simpletest_summarize_phpunit_result($phpunit_results)[$test_class];
diff --git a/core/modules/simpletest/src/ContentTypeCreationTrait.php b/core/modules/simpletest/src/ContentTypeCreationTrait.php
index 9ad0a21792..ec15b9af77 100644
--- a/core/modules/simpletest/src/ContentTypeCreationTrait.php
+++ b/core/modules/simpletest/src/ContentTypeCreationTrait.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Render\FormattableMarkup;
 use Drupal\node\Entity\NodeType;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Provides methods to create content type from given values.
@@ -40,7 +41,7 @@ protected function createContentType(array $values = []) {
     $status = $type->save();
     node_add_body_field($type);
 
-    if ($this instanceof \PHPUnit_Framework_TestCase) {
+    if ($this instanceof TestCase) {
       $this->assertSame($status, SAVED_NEW, (new FormattableMarkup('Created content type %type.', ['%type' => $type->id()]))->__toString());
     }
     else {
diff --git a/core/modules/simpletest/src/Form/SimpletestTestForm.php b/core/modules/simpletest/src/Form/SimpletestTestForm.php
index f954546eb1..1bf43ce439 100644
--- a/core/modules/simpletest/src/Form/SimpletestTestForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestTestForm.php
@@ -71,7 +71,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['clean'] = [
       '#type' => 'fieldset',
       '#title' => $this->t('Clean test environment'),
-      '#description' => $this->t('Remove tables with the prefix "simpletest" and temporary directories that are left over from tests that crashed. This is intended for developers when creating tests.'),
+      '#description' => $this->t('Remove tables with the prefix "test" followed by digits and temporary directories that are left over from tests that crashed. This is intended for developers when creating tests.'),
       '#weight' => 200,
     ];
     $form['clean']['op'] = [
diff --git a/core/modules/simpletest/src/Tests/UiPhpUnitOutputTest.php b/core/modules/simpletest/src/Tests/UiPhpUnitOutputTest.php
index 324bf1d570..e032cef941 100644
--- a/core/modules/simpletest/src/Tests/UiPhpUnitOutputTest.php
+++ b/core/modules/simpletest/src/Tests/UiPhpUnitOutputTest.php
@@ -35,9 +35,9 @@ public function testOutput() {
 
     // Check that there are <br> tags for the HTML output by
     // SimpletestUiPrinter.
-    $this->assertEqual($output[18], 'HTML output was generated<br />');
+    $this->assertEqual($output[19], 'HTML output was generated<br />');
     // Check that URLs are printed as HTML links.
-    $this->assertIdentical(strpos($output[19], '<a href="http'), 0);
+    $this->assertIdentical(strpos($output[20], '<a href="http'), 0);
   }
 
 }
diff --git a/core/modules/simpletest/tests/fixtures/simpletest_phpunit_run_command_test.php b/core/modules/simpletest/tests/fixtures/simpletest_phpunit_run_command_test.php
index a4ffc7ae45..42dadfdb36 100644
--- a/core/modules/simpletest/tests/fixtures/simpletest_phpunit_run_command_test.php
+++ b/core/modules/simpletest/tests/fixtures/simpletest_phpunit_run_command_test.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\simpletest\Unit;
 
+use Drupal\Tests\UnitTestCase;
+
 /**
  * This test crashes PHP.
  *
@@ -11,7 +13,7 @@
  *
  * @see \Drupal\Tests\simpletest\Unit\SimpletestPhpunitRunCommandTest::testSimpletestPhpUnitRunCommand()
  */
-class SimpletestPhpunitRunCommandTestWillDie extends \PHPUnit_Framework_TestCase {
+class SimpletestPhpunitRunCommandTestWillDie extends UnitTestCase {
 
   /**
    * Performs the status specified by SimpletestPhpunitRunCommandTestWillDie.
diff --git a/core/modules/simpletest/tests/src/Unit/SimpletestPhpunitRunCommandTest.php b/core/modules/simpletest/tests/src/Unit/SimpletestPhpunitRunCommandTest.php
index a96db963c8..63fe1bb8a9 100644
--- a/core/modules/simpletest/tests/src/Unit/SimpletestPhpunitRunCommandTest.php
+++ b/core/modules/simpletest/tests/src/Unit/SimpletestPhpunitRunCommandTest.php
@@ -4,15 +4,19 @@
 
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\File\FileSystemInterface;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Tests simpletest_run_phpunit_tests() handles PHPunit fatals correctly.
  *
+ * We don't extend Drupal\Tests\UnitTestCase here because its $root property is
+ * not static and we need it to be static here.
+ *
  * @group simpletest
  *
  * @runTestsInSeparateProcesses
  */
-class SimpletestPhpunitRunCommandTest extends \PHPUnit_Framework_TestCase {
+class SimpletestPhpunitRunCommandTest extends TestCase {
 
   /**
    * Path to the app root.
diff --git a/core/modules/syslog/config/install/syslog.settings.yml b/core/modules/syslog/config/install/syslog.settings.yml
index 1aa5b90874..396b751798 100644
--- a/core/modules/syslog/config/install/syslog.settings.yml
+++ b/core/modules/syslog/config/install/syslog.settings.yml
@@ -1,3 +1,6 @@
 identity: drupal
-facility: ''
+# The default facility setting depends on the operating system, and will be
+# overwritten during installation.
+# @see syslog_install().
+facility: 8
 format: '!base_url|!timestamp|!type|!ip|!request_uri|!referer|!uid|!link|!message'
diff --git a/core/modules/syslog/config/schema/syslog.schema.yml b/core/modules/syslog/config/schema/syslog.schema.yml
index 5d2707a5a1..f980828f80 100644
--- a/core/modules/syslog/config/schema/syslog.schema.yml
+++ b/core/modules/syslog/config/schema/syslog.schema.yml
@@ -8,7 +8,7 @@ syslog.settings:
       type: string
       label: 'Identity'
     facility:
-      type: string
+      type: integer
       label: 'Facility'
     format:
       type: string
diff --git a/core/modules/syslog/src/Tests/Update/SyslogUpdateTest.php b/core/modules/syslog/src/Tests/Update/SyslogUpdateTest.php
new file mode 100644
index 0000000000..2b0482ff93
--- /dev/null
+++ b/core/modules/syslog/src/Tests/Update/SyslogUpdateTest.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\syslog\Tests\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+
+/**
+ * Tests that syslog settings are properly updated during database updates.
+ *
+ * @group syslog
+ */
+class SyslogUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.filled.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Tests that syslog.settings.facility has been converted from string to int.
+   *
+   * @see syslog_update_8400()
+   */
+  public function testSyslogSettingsFacilityDataType() {
+    $config = $this->config('syslog.settings');
+    $this->assertIdentical('128', $config->get('facility'));
+
+    // Run updates.
+    $this->runUpdates();
+
+    $config = $this->config('syslog.settings');
+    $this->assertIdentical(128, $config->get('facility'));
+  }
+
+}
diff --git a/core/modules/syslog/syslog.install b/core/modules/syslog/syslog.install
index e3377c8aeb..f0ce5cc68a 100644
--- a/core/modules/syslog/syslog.install
+++ b/core/modules/syslog/syslog.install
@@ -13,3 +13,12 @@ function syslog_install() {
   // to be set dynamically during installation.
   \Drupal::configFactory()->getEditable('syslog.settings')->set('facility', defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER)->save();
 }
+
+/**
+ * Convert syslog.settings.facility to an integer.
+ */
+function syslog_update_8400() {
+  $config = \Drupal::configFactory()->getEditable('syslog.settings');
+  $facility = (int) $config->get('facility');
+  $config->set('facility', $facility)->save(TRUE);
+}
diff --git a/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php b/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php
index aa66203113..935af8d8aa 100644
--- a/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php
+++ b/core/modules/syslog/tests/src/Kernel/Migrate/d6/MigrateSyslogConfigsTest.php
@@ -33,7 +33,7 @@ protected function setUp() {
   public function testSyslogSettings() {
     $config = $this->config('syslog.settings');
     $this->assertIdentical('drupal', $config->get('identity'));
-    $this->assertIdentical('128', $config->get('facility'));
+    $this->assertIdentical(128, $config->get('facility'));
     $this->assertConfigSchema(\Drupal::service('config.typed'), 'syslog.settings', $config->get());
   }
 
diff --git a/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php b/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php
index 2996b42419..ef5d8c305d 100644
--- a/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php
+++ b/core/modules/syslog/tests/src/Kernel/Migrate/d7/MigrateSyslogConfigsTest.php
@@ -36,7 +36,7 @@ protected function setUp() {
   public function testSyslogSettings() {
     $config = $this->config('syslog.settings');
     // 8 == LOG_USER
-    $this->assertIdentical('8', $config->get('facility'));
+    $this->assertIdentical(8, $config->get('facility'));
     $this->assertIdentical('!base_url|!timestamp|!type|!ip|!request_uri|!referer|!uid|!link|!message', $config->get('format'));
     $this->assertIdentical('drupal', $config->get('identity'));
   }
diff --git a/core/modules/system/config/schema/system.schema.yml b/core/modules/system/config/schema/system.schema.yml
index c23ed7e0ae..021840c256 100644
--- a/core/modules/system/config/schema/system.schema.yml
+++ b/core/modules/system/config/schema/system.schema.yml
@@ -5,8 +5,11 @@ system.site:
   label: 'Site information'
   mapping:
     uuid:
-      type: string
+      type: uuid
       label: 'Site UUID'
+      constraints:
+        Uuid: []
+        NotNull: []
     name:
       type: label
       label: 'Site name'
diff --git a/core/modules/system/src/Controller/Http4xxController.php b/core/modules/system/src/Controller/Http4xxController.php
index f8c97e4f54..ee8a9776d4 100644
--- a/core/modules/system/src/Controller/Http4xxController.php
+++ b/core/modules/system/src/Controller/Http4xxController.php
@@ -10,6 +10,18 @@
 class Http4xxController extends ControllerBase {
 
   /**
+   * The default 4xx error content.
+   *
+   * @return array
+   *   A render array containing the message to display for 4xx errors.
+   */
+  public function on4xx() {
+    return [
+      '#markup' => $this->t('A client error happened'),
+    ];
+  }
+
+  /**
    * The default 401 content.
    *
    * @return array
diff --git a/core/modules/system/src/Form/CronForm.php b/core/modules/system/src/Form/CronForm.php
index d4726aac57..0779c15fa8 100644
--- a/core/modules/system/src/Form/CronForm.php
+++ b/core/modules/system/src/Form/CronForm.php
@@ -131,7 +131,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'checkbox',
       '#title' => t('Detailed cron logging'),
       '#default_value' => $this->config('system.cron')->get('logging'),
-      '#description' => 'Run times of individual cron jobs will be written to watchdog',
+      '#description' => $this->t('Run times of individual cron jobs will be written to watchdog'),
     ];
 
     $form['actions']['#type'] = 'actions';
diff --git a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
index c142c86c8e..52daa098e4 100644
--- a/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
+++ b/core/modules/system/src/Plugin/Block/SystemMenuBlock.php
@@ -5,7 +5,6 @@
 use Drupal\Core\Block\BlockBase;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Menu\MenuActiveTrailInterface;
 use Drupal\Core\Menu\MenuLinkTreeInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -30,13 +29,6 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
   protected $menuTree;
 
   /**
-   * The active menu trail service.
-   *
-   * @var \Drupal\Core\Menu\MenuActiveTrailInterface
-   */
-  protected $menuActiveTrail;
-
-  /**
    * Constructs a new SystemMenuBlock.
    *
    * @param array $configuration
@@ -47,13 +39,10 @@ class SystemMenuBlock extends BlockBase implements ContainerFactoryPluginInterfa
    *   The plugin implementation definition.
    * @param \Drupal\Core\Menu\MenuLinkTreeInterface $menu_tree
    *   The menu tree service.
-   * @param \Drupal\Core\Menu\MenuActiveTrailInterface $menu_active_trail
-   *   The active menu trail service.
    */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, MenuLinkTreeInterface $menu_tree, MenuActiveTrailInterface $menu_active_trail) {
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, MenuLinkTreeInterface $menu_tree) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->menuTree = $menu_tree;
-    $this->menuActiveTrail = $menu_active_trail;
   }
 
   /**
@@ -64,8 +53,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('menu.link_tree'),
-      $container->get('menu.active_trail')
+      $container->get('menu.link_tree')
     );
   }
 
diff --git a/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php
new file mode 100644
index 0000000000..ba7e028ae0
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\system\Tests\Entity\Update;
+
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+use Drupal\views\Entity\View;
+
+/**
+ * Tests the upgrade path for moving the revision metadata fields.
+ *
+ * @group Update
+ */
+class MoveRevisionMetadataFieldsUpdateTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz',
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php',
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php',
+    ];
+  }
+
+  /**
+   * Tests that the revision metadata fields are moved correctly.
+   */
+  public function testSystemUpdate8400() {
+    $this->runUpdates();
+
+    foreach (['entity_test_revlog', 'entity_test_mul_revlog'] as $entity_type_id) {
+      /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
+      $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
+      /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
+      $entity_type = $storage->getEntityType();
+      $revision_metadata_field_names = $entity_type->getRevisionMetadataKeys();
+
+      $database_schema = \Drupal::database()->schema();
+
+      // Test that the revision metadata fields are present only in the
+      // revision table.
+      foreach ($revision_metadata_field_names as $revision_metadata_field_name) {
+        if ($entity_type->isTranslatable()) {
+          $this->assertFalse($database_schema->fieldExists($entity_type->getDataTable(), $revision_metadata_field_name));
+          $this->assertFalse($database_schema->fieldExists($entity_type->getRevisionDataTable(), $revision_metadata_field_name));
+        }
+        else {
+          $this->assertFalse($database_schema->fieldExists($entity_type->getBaseTable(), $revision_metadata_field_name));
+        }
+        $this->assertTrue($database_schema->fieldExists($entity_type->getRevisionTable(), $revision_metadata_field_name));
+      }
+
+      // Test that the revision metadata values have been transferred correctly
+      // and that the moved fields are accessible.
+      /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_first */
+      $entity_rev_first = $storage->loadRevision(1);
+      $this->assertEqual($entity_rev_first->getRevisionUserId(), '1');
+      $this->assertEqual($entity_rev_first->getRevisionLogMessage(), 'first revision');
+      $this->assertEqual($entity_rev_first->getRevisionCreationTime(), '1476268517');
+
+      /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_second */
+      $entity_rev_second = $storage->loadRevision(2);
+      $this->assertEqual($entity_rev_second->getRevisionUserId(), '1');
+      $this->assertEqual($entity_rev_second->getRevisionLogMessage(), 'second revision');
+      $this->assertEqual($entity_rev_second->getRevisionCreationTime(), '1476268518');
+
+
+      // Test that the views using revision metadata fields are updated
+      // properly.
+      $view = View::load($entity_type_id . '_for_2248983');
+      $displays = $view->get('display');
+      foreach ($displays as $display => $display_data) {
+        foreach ($display_data['display_options']['fields'] as $property_data) {
+          if (in_array($property_data['field'], $revision_metadata_field_names)) {
+            $this->assertEqual($property_data['table'], $entity_type->getRevisionTable());
+          }
+        }
+      }
+    }
+  }
+
+}
diff --git a/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php
new file mode 100644
index 0000000000..3a0aca2aef
--- /dev/null
+++ b/core/modules/system/src/Tests/Entity/Update/SqlContentEntityStorageSchemaConverterTest.php
@@ -0,0 +1,262 @@
+<?php
+
+namespace Drupal\system\Tests\Entity\Update;
+
+use Drupal\Core\Entity\Sql\TemporaryTableMapping;
+use Drupal\system\Tests\Entity\EntityDefinitionTestTrait;
+use Drupal\system\Tests\Update\UpdatePathTestBase;
+
+/**
+ * Tests updating an entity type with existing data to be revisionable.
+ *
+ * @group Entity
+ * @group Update
+ */
+class SqlContentEntityStorageSchemaConverterTest extends UpdatePathTestBase {
+
+  use EntityDefinitionTestTrait;
+
+  /**
+   * The entity manager service.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * The entity definition update manager.
+   *
+   * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
+   */
+  protected $entityDefinitionUpdateManager;
+
+  /**
+   * The last installed schema repository service.
+   *
+   * @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
+   */
+  protected $lastInstalledSchemaRepository;
+
+  /**
+   * The key-value collection for tracking installed storage schema.
+   *
+   * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface
+   */
+  protected $installedStorageSchema;
+
+  /**
+   * The state service.
+   *
+   * @var \Drupal\Core\State\StateInterface
+   */
+  protected $state;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->entityManager = \Drupal::entityManager();
+    $this->entityDefinitionUpdateManager = \Drupal::entityDefinitionUpdateManager();
+    $this->lastInstalledSchemaRepository = \Drupal::service('entity.last_installed_schema.repository');
+    $this->installedStorageSchema = \Drupal::keyValue('entity.storage_schema.sql');
+    $this->state = \Drupal::state();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.0.0-rc1-filled.standard.entity_test_update_mul.php.gz',
+      __DIR__ . '/../../../../tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php',
+    ];
+  }
+
+  /**
+   * Tests the conversion of an entity type to revisionable.
+   */
+  public function testMakeRevisionable() {
+    // Check that entity type is not revisionable prior to running the update
+    // process.
+    $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
+    $this->assertFalse($entity_test_update->isRevisionable());
+
+    // Make the entity type revisionable and translatable and run the updates.
+    $this->updateEntityTypeToRevisionableAndTranslatable();
+
+    $this->runUpdates();
+
+    /** @var \Drupal\Core\Entity\EntityTypeInterface $entity_test_update */
+    $entity_test_update = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
+    $this->assertTrue($entity_test_update->isRevisionable());
+
+    /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
+    $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
+    $this->assertEqual(count($storage->loadMultiple()), 102, 'All test entities were found.');
+
+    // Check that each field value was copied correctly to the revision tables.
+    for ($i = 1; $i <= 102; $i++) {
+      /** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
+      $revision = $storage->loadRevision($i);
+
+      $this->assertEqual($i, $revision->id());
+      $this->assertEqual($i, $revision->getRevisionId());
+
+      $this->assertEqual($i . ' - test single property', $revision->test_single_property->value);
+
+      $this->assertEqual($i . ' - test multiple properties - value1', $revision->test_multiple_properties->value1);
+      $this->assertEqual($i . ' - test multiple properties - value2', $revision->test_multiple_properties->value2);
+
+      $this->assertEqual($i . ' - test single property multiple values 0', $revision->test_single_property_multiple_values->value);
+      $this->assertEqual($i . ' - test single property multiple values 1', $revision->test_single_property_multiple_values[1]->value);
+
+      $this->assertEqual($i . ' - test multiple properties multiple values - value1 0', $revision->test_multiple_properties_multiple_values[0]->value1);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value2 0', $revision->test_multiple_properties_multiple_values[0]->value2);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value1 1', $revision->test_multiple_properties_multiple_values[1]->value1);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value2 1', $revision->test_multiple_properties_multiple_values[1]->value2);
+
+      $this->assertEqual($i . ' - field test configurable field - value1 0', $revision->field_test_configurable_field[0]->value1);
+      $this->assertEqual($i . ' - field test configurable field - value2 0', $revision->field_test_configurable_field[0]->value2);
+      $this->assertEqual($i . ' - field test configurable field - value1 1', $revision->field_test_configurable_field[1]->value1);
+      $this->assertEqual($i . ' - field test configurable field - value2 1', $revision->field_test_configurable_field[1]->value2);
+
+      $this->assertEqual($i . ' - test entity base field info', $revision->test_entity_base_field_info->value);
+
+      // Do the same checks for translated field values.
+      $translation = $revision->getTranslation('ro');
+
+      $this->assertEqual($i . ' - test single property - ro', $translation->test_single_property->value);
+
+      $this->assertEqual($i . ' - test multiple properties - value1 - ro', $translation->test_multiple_properties->value1);
+      $this->assertEqual($i . ' - test multiple properties - value2 - ro', $translation->test_multiple_properties->value2);
+
+      $this->assertEqual($i . ' - test single property multiple values 0 - ro', $translation->test_single_property_multiple_values[0]->value);
+      $this->assertEqual($i . ' - test single property multiple values 1 - ro', $translation->test_single_property_multiple_values[1]->value);
+
+      $this->assertEqual($i . ' - test multiple properties multiple values - value1 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value1);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value2 0 - ro', $translation->test_multiple_properties_multiple_values[0]->value2);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value1 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value1);
+      $this->assertEqual($i . ' - test multiple properties multiple values - value2 1 - ro', $translation->test_multiple_properties_multiple_values[1]->value2);
+
+      $this->assertEqual($i . ' - field test configurable field - value1 0 - ro', $translation->field_test_configurable_field[0]->value1);
+      $this->assertEqual($i . ' - field test configurable field - value2 0 - ro', $translation->field_test_configurable_field[0]->value2);
+      $this->assertEqual($i . ' - field test configurable field - value1 1 - ro', $translation->field_test_configurable_field[1]->value1);
+      $this->assertEqual($i . ' - field test configurable field - value2 1 - ro', $translation->field_test_configurable_field[1]->value2);
+
+      $this->assertEqual($i . ' - test entity base field info - ro', $translation->test_entity_base_field_info->value);
+    }
+
+    // Check that temporary tables have been removed at the end of the process.
+    $schema = \Drupal::database()->schema();
+    foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
+      $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name)));
+    }
+
+    // Check that backup tables have been removed at the end of the process.
+    $schema = \Drupal::database()->schema();
+    foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
+      $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name, 'old_')));
+    }
+  }
+
+  /**
+   * Tests that a failed "make revisionable" update preserves the existing data.
+   */
+  public function testMakeRevisionableErrorHandling() {
+    $original_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
+    $original_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update');
+
+    $original_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []);
+    foreach ($original_storage_definitions as $storage_definition) {
+      $original_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []);
+    }
+
+    // Check that entity type is not revisionable prior to running the update
+    // process.
+    $this->assertFalse($original_entity_type->isRevisionable());
+
+    // Make the update throw an exception during the entity save process.
+    \Drupal::state()->set('entity_test_update.throw_exception', TRUE);
+
+    // Since the update process is interrupted by the exception thrown above,
+    // we can not do the full post update testing offered by UpdatePathTestBase.
+    $this->checkFailedUpdates = FALSE;
+
+    // Make the entity type revisionable and run the updates.
+    $this->updateEntityTypeToRevisionableAndTranslatable();
+
+    $this->runUpdates();
+
+    // Check that the update failed.
+    $this->assertRaw('<strong>' . t('Failed:') . '</strong>');
+
+    // Check that the last installed entity type definition is kept as
+    // non-revisionable.
+    $new_entity_type = $this->lastInstalledSchemaRepository->getLastInstalledDefinition('entity_test_update');
+    $this->assertFalse($new_entity_type->isRevisionable(), 'The entity type is kept unchanged.');
+
+    // Check that the last installed field storage definitions did not change by
+    // looking at the 'langcode' field, which is updated automatically.
+    $new_storage_definitions = $this->lastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions('entity_test_update');
+    $langcode_key = $original_entity_type->getKey('langcode');
+    $this->assertEqual($original_storage_definitions[$langcode_key]->isRevisionable(), $new_storage_definitions[$langcode_key]->isRevisionable(), "The 'langcode' field is kept unchanged.");
+
+    /** @var \Drupal\Core\Entity\Sql\SqlEntityStorageInterface $storage */
+    $storage = \Drupal::entityTypeManager()->getStorage('entity_test_update');
+
+    // Check that installed storage schema did not change.
+    $new_entity_schema_data = $this->installedStorageSchema->get('entity_test_update.entity_schema_data', []);
+    $this->assertEqual($original_entity_schema_data, $new_entity_schema_data);
+
+    foreach ($new_storage_definitions as $storage_definition) {
+      $new_field_schema_data[$storage_definition->getName()] = $this->installedStorageSchema->get('entity_test_update.field_schema_data.' . $storage_definition->getName(), []);
+    }
+    $this->assertEqual($original_field_schema_data, $new_field_schema_data);
+
+    // Check that temporary tables have been removed.
+    $schema = \Drupal::database()->schema();
+    foreach ($storage->getTableMapping()->getTableNames() as $table_name) {
+      $this->assertFalse($schema->tableExists(TemporaryTableMapping::getTempTableName($table_name)));
+    }
+
+    // Check that the original tables still exist and their data is intact.
+    $this->assertTrue($schema->tableExists('entity_test_update'));
+    $this->assertTrue($schema->tableExists('entity_test_update_data'));
+
+    $base_table_count = \Drupal::database()->select('entity_test_update')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+    $this->assertEqual($base_table_count, 102);
+
+    $data_table_count = \Drupal::database()->select('entity_test_update_data')
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+    // There are two records for each entity, one for English and one for
+    // Romanian.
+    $this->assertEqual($data_table_count, 204);
+
+    $base_table_row = \Drupal::database()->select('entity_test_update')
+      ->fields('entity_test_update')
+      ->condition('id', 1, '=')
+      ->condition('langcode', 'en', '=')
+      ->execute()
+      ->fetchAllAssoc('id');
+    $this->assertEqual('843e9ac7-3351-4cc1-a202-2dbffffae21c', $base_table_row[1]->uuid);
+
+    $data_table_row = \Drupal::database()->select('entity_test_update_data')
+      ->fields('entity_test_update_data')
+      ->condition('id', 1, '=')
+      ->condition('langcode', 'en', '=')
+      ->execute()
+      ->fetchAllAssoc('id');
+    $this->assertEqual('1 - test single property', $data_table_row[1]->test_single_property);
+    $this->assertEqual('1 - test multiple properties - value1', $data_table_row[1]->test_multiple_properties__value1);
+    $this->assertEqual('1 - test multiple properties - value2', $data_table_row[1]->test_multiple_properties__value2);
+    $this->assertEqual('1 - test entity base field info', $data_table_row[1]->test_entity_base_field_info);
+  }
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 61b2650ad0..614ad9e340 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -12,6 +12,9 @@
 use Drupal\Core\Path\AliasStorage;
 use Drupal\Core\Url;
 use Drupal\Core\Database\Database;
+use Drupal\Core\Entity\ContentEntityTypeInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\DrupalKernel;
 use Drupal\Core\Site\Settings;
 use Drupal\Core\StreamWrapper\PrivateStream;
@@ -1789,3 +1792,138 @@ function system_update_8301() {
     ->set('profile', \Drupal::installProfile())
     ->save();
 }
+
+/**
+ * Move revision metadata fields to the revision table.
+ */
+function system_update_8400(&$sandbox) {
+  // Due to the fields from RevisionLogEntityTrait not being explicitly
+  // mentioned in the storage they might have been installed wrongly in the base
+  // table for revisionable untranslatable entities and in the data and revision
+  // data tables for revisionable and translatable entities.
+  $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
+  $database = \Drupal::database();
+  $database_schema = $database->schema();
+
+  if (!isset($sandbox['current'])) {
+    // This must be the first run. Initialize the sandbox.
+    $sandbox['current'] = 0;
+
+    $definitions = array_filter(\Drupal::entityTypeManager()->getDefinitions(), function (EntityTypeInterface $entity_type) use ($entity_definition_update_manager) {
+      if ($entity_type = $entity_definition_update_manager->getEntityType($entity_type->id())) {
+        return is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && ($entity_type instanceof ContentEntityTypeInterface) && $entity_type->isRevisionable();
+      }
+      return FALSE;
+    });
+    $sandbox['entity_type_ids'] = array_keys($definitions);
+    $sandbox['max'] = count($sandbox['entity_type_ids']);
+  }
+
+  $current_entity_type_key = $sandbox['current'];
+  for ($i = $current_entity_type_key; ($i < $current_entity_type_key + 1) && ($i < $sandbox['max']); $i++) {
+    $entity_type_id = $sandbox['entity_type_ids'][$i];
+    /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
+    $entity_type = $entity_definition_update_manager->getEntityType($entity_type_id);
+
+    $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id);
+    $revision_metadata_fields = $entity_type->getRevisionMetadataKeys();
+    $fields_to_update = array_intersect_key($base_fields, array_flip($revision_metadata_fields));
+
+    if (!empty($fields_to_update)) {
+      // Initialize the entity table names.
+      // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout()
+      $base_table = $entity_type->getBaseTable() ?: $entity_type_id;
+      $data_table = $entity_type->getDataTable() ?: $entity_type_id . '_field_data';
+      $revision_table = $entity_type->getRevisionTable() ?: $entity_type_id . '_revision';
+      $revision_data_table = $entity_type->getRevisionDataTable() ?: $entity_type_id . '_field_revision';
+      $revision_field = $entity_type->getKey('revision');
+
+      // No data needs to be migrated if the entity type is not translatable.
+      if ($entity_type->isTranslatable()) {
+        if (!isset($sandbox[$entity_type_id])) {
+          // This must be the first run for this entity type. Initialize the
+          // sub-sandbox for it.
+
+          // Calculate the number of revisions to process.
+          $count = \Drupal::entityQuery($entity_type_id)
+            ->allRevisions()
+            ->count()
+            ->accessCheck(FALSE)
+            ->execute();
+
+          $sandbox[$entity_type_id]['current'] = 0;
+          $sandbox[$entity_type_id]['max'] = $count;
+        }
+        // Define the step size.
+        $steps = Settings::get('entity_update_batch_size', 50);
+
+        // Collect the revision IDs to process.
+        $revisions = \Drupal::entityQuery($entity_type_id)
+          ->allRevisions()
+          ->range($sandbox[$entity_type_id]['current'], $sandbox[$entity_type_id]['current'] + $steps)
+          ->sort($revision_field, 'ASC')
+          ->accessCheck(FALSE)
+          ->execute();
+        $revisions = array_keys($revisions);
+
+        foreach ($fields_to_update as $revision_metadata_field_name => $definition) {
+          // If the revision metadata field is present in the data and the
+          // revision data table, install its definition again with the updated
+          // storage code in order for the field to be installed in the
+          // revision table. Afterwards, copy over the field values and remove
+          // the field from the data and the revision data tables.
+          if ($database_schema->fieldExists($data_table, $revision_metadata_field_name) && $database_schema->fieldExists($revision_data_table, $revision_metadata_field_name)) {
+            // Install the field in the revision table.
+            if (!isset($sandbox[$entity_type_id]['storage_definition_installed'][$revision_metadata_field_name])) {
+              $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition);
+              $sandbox[$entity_type_id]['storage_definition_installed'][$revision_metadata_field_name] = TRUE;
+            }
+
+            // Apply the field value from the revision data table to the
+            // revision table.
+            foreach ($revisions as $rev_id) {
+              $field_value = $database->select($revision_data_table, 't')
+                ->fields('t', [$revision_metadata_field_name])
+                ->condition($revision_field, $rev_id)
+                ->execute()
+                ->fetchField();
+              $database->update($revision_table)
+                ->condition($revision_field, $rev_id)
+                ->fields([$revision_metadata_field_name => $field_value])
+                ->execute();
+            }
+          }
+        }
+
+        $sandbox[$entity_type_id]['current'] += count($revisions);
+        $sandbox[$entity_type_id]['finished'] = ($sandbox[$entity_type_id]['current'] == $sandbox[$entity_type_id]['max']) || empty($revisions);
+
+        if ($sandbox[$entity_type_id]['finished']) {
+          foreach ($fields_to_update as $revision_metadata_field_name => $definition) {
+            // Drop the field from the data and revision data tables.
+            $database_schema->dropField($data_table, $revision_metadata_field_name);
+            $database_schema->dropField($revision_data_table, $revision_metadata_field_name);
+          }
+          $sandbox['current']++;
+        }
+      }
+      else {
+        foreach ($fields_to_update as $revision_metadata_field_name => $definition) {
+          if ($database_schema->fieldExists($base_table, $revision_metadata_field_name)) {
+            // Install the field in the revision table.
+            $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition);
+            // Drop the field from the base table.
+            $database_schema->dropField($base_table, $revision_metadata_field_name);
+          }
+        }
+        $sandbox['current']++;
+      }
+    }
+    else {
+      $sandbox['current']++;
+    }
+
+  }
+
+  $sandbox['#finished'] = $sandbox['current'] == $sandbox['max'];
+}
diff --git a/core/modules/system/system.post_update.php b/core/modules/system/system.post_update.php
index b96d3e3b3b..36039dff0d 100644
--- a/core/modules/system/system.post_update.php
+++ b/core/modules/system/system.post_update.php
@@ -65,3 +65,19 @@ function system_post_update_hashes_clear_cache() {
 function system_post_update_timestamp_plugins() {
   // Empty post-update hook.
 }
+
+/**
+ * Clear caches to ensure Classy's message library is always added.
+ */
+function system_post_update_classy_message_library() {
+  // Empty post-update hook.
+}
+
+/**
+ * Force field type plugin definitions to be cleared.
+ *
+ * @see https://www.drupal.org/node/2403703
+ */
+function system_post_update_field_type_plugins() {
+  // Empty post-update hook.
+}
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index ee9afc1516..9cfe2ca54c 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -22,6 +22,14 @@ system.404:
   requirements:
     _access: 'TRUE'
 
+system.4xx:
+  path: '/system/4xx'
+  defaults:
+    _controller: '\Drupal\system\Controller\Http4xxController:on4xx'
+    _title: 'Client error'
+  requirements:
+    _access: 'TRUE'
+
 system.admin:
   path: '/admin'
   defaults:
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz
new file mode 100644
index 0000000000..19772649a9
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php.gz
@@ -0,0 +1,517 @@
+‹ŠRX drupal-8.2.0.bare.standard_with_entity_test_revlog_enabled.php ì]isâº¶ýÞ¿‚JÝª>}ê(Çƒ<¥ß=ï&IIHB n%[28ÛØfÊ­ûßŸŒÍ3&ýŽ¿t¬akkí¥½·dñ?ÿë4œoþ™ú—fcÃª—|daäb/_·l—d“|ûó÷ß¿¥~OýK>Ð?ÎSùHEI!ZÊó-…;-'¥ÛnÊ'ô³UO9×±=âÒA¥§†á¥‚R=ä¥êÄ".ò	N©ƒ”ß ©ŒÛq™’O™VoÛ¦wJ%Kyšk8~ÐÈŸß¾u¼qÁ§©pÿÎŒÄ˜üñóÛ·h¶eÍ7l+õÏÔøÁÙYøéÉ“ß~Ì—yZƒ´Ðo?À_šK¨`OH5ÉoßUÓÖš5ZÐ'–ÿýr]4øí[*õ]7ˆ‰½ï©þ5ý’~màèWôKàá×ß=âÈüþÇø‰eû)«cšÃ§OÏ—“'žñ>ªCç¡5[§cyFÝ"8RçGøßw—tŽ©ö(F0 ¥rdÏoK{dÒÕ*	ºÈÕÈ­!O3Œ8:1‰U÷aežû>ß]§óÁ€wêŽåäH&²êÔf8DvnˆÃ¾;®ÑBî Õ$ƒeØ›ìXF»C‚r‹ CumˆäZ-Ð_­ÖEfgÙ†ÚWÀ|+µõ¸›}º0(ÃÂ¤ObÊ(—þ‹\jÑk0¾ÐIkàµÍZ0Hó‰[óˆª¹ãërK…´Æ­h¡VSm<ˆCjÇÂæA#O«`¢£Ž9cdê01‰O¶å‡<Ei°¢{&Ò?Õšá¶g¨¯Â”û‘ãðL2!Ëqá£OÕE`J+Ih*†OúÊ¡õ(]yVÀ§Ûv¶j©\Ñ›(Ãßyžç{hN6[3¦–¡†9DDƒºWQÝèÁ&–¸bíøP©³O¸„ëTà"ïÁaü»pà‘Åc;oCKÑí8Ýíjóô)mÆªo½¼ÇrÿðÄqû¤ñ û¹1ÎDßE–g¢€&jH×)aì]3þÕt½®åµXpÞÅ¡Û,Ùp©˜w¦ƒ($:®ÚºN:]¦©ÅÌ³Ï f‘Êª–æ¿¾Éyã8ú²7î>Yú¾ûŸ¬EÉZô·[‹Éú]”~¡5àÿ!û!cÿ	Àdô¦]?pîcsKÝÐ2×YßQQŸ$‚¸:Ú}’NÁñt‘$‚?9¼ÄJrÃ›/¢ßÓ…Áö=ê—;qVíÙS`¬ €@9†56…EÃ&¶×‰GGug+!}Çp÷CDhíÊ'†´:-êjq¤p\¢…®q¸@Ãi%OC#køÎ¯î”a¢†Ž)Üž×,ê(®’|T_€ïþ“Ö¤ü|£ˆÉ–Z,Wu%ˆGŽ@<´ (4a„uÖIXçh¬ã#Ã
+’O	ñ$Ä“OB<Ç!ž¸§nÎI8'áœ„söÂ9£éKh'¡„vÚ9ížfw‰kÃ1!ž„xâIˆgÄî&¬“°NÂ:	ë‹uZÄê$œ“pNÂ9	ç‹s‚kHT”lb%´“ÐNB;Ç¢áÅ Zî)g<Ñ†Õ¥ˆÆÃ·Öãê€¶ÿñäÊ:ÐœÙ­VÌË¡>Z$Žð®ÉHÚZr9Ó‘/gšgŸu·3§h«{™Ö“[¤éY0¬£l6‡¥ÀQOá’wj†‹ròNÍvr$ïÔ,’ÿß­™ëòxëå—zÅ%žr—•:
+…”ëùÔ9.	åÕ‰½–2èÇ4’îHÞSTNkñUñp%·PëÜGîíaƒyþÔ£1Z„â®å|âÎÐÆ”'®íö#·û³ìh,Ÿfw¬õÂ§H¸ÅÂ1Ë‹¶ùñŠ¾+
+n¦ßùçh¡ÈQÖ“Í.Ö;8}ÍHû.“p>û¦é]}†=‰áuÔ7
+åÃÐ<Œ(}{fßÓh·¢µa¤'Nˆjµa·ˆƒê‡ØâåXÛó¦ÇÅ¬Øn÷bÅ¡Åiúÿh·~áEgÛÌó÷[ùª½XIÌw2öf¬ÈÂÚ±Ç`bƒ^¿ÚÅaš±Í…a“¼åÆW…Mû[¦Œ©—ß¶÷”îb›Ãôº¦ *ÕJâ?Y^½wm¹‡áÌ*nD+Ú±:­šEzK‰:òK]ùåêŠöº0œÈäÎu<e”?¦ß°
+;ùøcÅPFÒ­ÔnCZÀƒùö±ï'°M3lìp®mì]ÏÃ&\b‹q„s1ør:1³ÚÙ/†å×Ÿ äÇ7ðWŒß¦H‰ô<í7TLÐ,­6Lt¯¨6UêtJ¿£Žo·3¦¼e[§TÜà¼™–ÃbgÜÙ¼3ùì„.JÄ¥Ýœü4ÎXFf˜ŸÞ™pvBÉØ%'?Ñ”c•³“±m…ƒª5×8¡e!v¢?7½Ç¢³zóüY¹xîµÛxº(•8ëéÎ­–à³Tþëüüï·ÜðêºÓÑ¿ÈõfiÃ4Àèˆet,HÏN‚­Æ@Z^<;áu"Â!@ˆŽ”02ÂN@
+¯H¼ ‹AYªœ1¹³bÐ&Bê<ù©ž±ô–´ãººZšA¼@mÃŽiÉP[#EgvezÏ'­Ó@êÓÑ¨f†5Z6î˜d®†8®0,CgÇ§|´P$ÔH àÍg0Ó#Ž§=Tñô\³ä<¿ãJGsïrP¸ªÝd¥ªÌ½ {ðPÊ@G*4hwÉTœüœ•sN¼á—Ôé, ³ã*¦6:©K‹ôˆQoø,™p2×î˜¸'?ïÂŽÙ©ÃF8a¬¡aµ!DÎ&ŠV›B 1PÉdÖ$¨ÄÊ+<SóNž§Æ"ÏI87g^€Ã°…àÍ'ÇDƒá—g'Ì¸uÒ%¡†Ÿ)šüFø™*›eÎN‚mÕ0éBÈÏœýg¿f¤ºÈ
+~B-¦	©²¬)b€F /b 
+Š$B"‹ªªBfgâF&ô)q—é!l’Û_y)©™g„šýA¥:ÈßUüfÖ/¾\•z6Ë9bÂÄ ÆJoôCƒºUmdìÅãŽC$/Á¿4ÿu5ç°OS2|’šÙÖ¸v<Róh‹Á]®ö³ØN3<ZYá£c	Íí´Ô%ëéR;ÑQ5SÒ¡ d CªÂÈPç‰NøkÛ‰ýú¬ò×ÕG®\^Š¸snãÑÐÒ^[`[éú­þ8è6È•(hš³yÆN&zÝ`Ý ó=­¸½ð3¨·³Òbà¼Å¬¯;g3îóÜÒbŽòÉïEÆ¸ÄbƒŒX¥¾”©/…0âD¨È*/‘_àÊ¥]~ánm_Ì¾”\ñaÃ¾©ïìmþµR¾»ùü}Å+÷/Úvàpð‘Nãƒ[:Žã:;ðPÆî2¬˜^Y+êüèÓTgNÍˆø¥!­Û¶?ºK>Ft H2K!ÀaQ¢ÑB ug$Àb™SY™$Y9ht ÏG¡ðŸ4›ùÒë%{ûÄe¯/íŠÕN»i‡d/ ç´®Z…~¡i¾4%÷AÓëà'&0Flz§„ujº¡ûm.së§‚¬	>¨¥øìðÉaƒæHöÒ ¦ÓZ89Mdt<K
+€DS"ð2upIU‰.!þ fÓ9ôå¼lœ§KˆñnŠ|“3»ÏWlœ«k7¯Òséúü¡b½w.êQè³è‡îúƒü™P#qY¡ø,°©vs#á#€žèýÐ;ý™5¤…oqÄÃ­H Ä# Äêˆú-*ŠŽu ^ÐdI»{ ;Ø!PÉòWÉ?å¯=‡mî-ãÕ/WõA6'K]•í÷¯Ó9C¿…Ïär•3AåœÖöO.<éÀæzŽ‹ÓÕõfD²÷£t/Â-ê¨ÌpÂ¡Î¿„}ä5ã˜çÏC– ¢B@^×€J$hºFIS¾0€_•<[¼`Ê|Ù,ûîHßiu±qWî!¹§²œœìT¬L5s¹2jœÑÙ~àã¹Ö3ý®¯¸àZ/­áÚ'´4>ŒÔáØF[ã9UfR«ÇL”ˆ2ò*C4QS "( ¨"È² Qä9	¬ë>¨Ï-ÎûÜüŸêq»}%ïâLWºÅl:È¬ž÷q#_Õ+yR,4Ø;Ð¾±ª½\4èœt<„Íœî„¶ÎÄsËüæP¡¹Ük«Î9ÜÂ(µP×¨_ß<˜Ó}4›!žGƒêØü¯°Ça0‚@™PãÑ`‰eeQÁ:Ï¿vâå&÷¿–^t“Ì§·÷¼&µó]«cx¾
+=®È4¯à[ÚÖ[ÍüÊüX©˜ ÅDƒÂÝ Oð6ÀÎÀ8ì>nVq]Í(þKÃÙKÍŽðK'a‚ŒQÍ7|“ÄÍCN'@×eŠpu€4LƒLY”DE†'Ü×õp$÷QÑ½×..p9¹X)œWúJõ¿º2ïnÕ©øê9ô•§h^\š wª²ý88B'ø4é6®s¾¢Òd)Âîƒ¤ád<_ØwìqG'¡bP1‘ˆeHaU q@R™gdñ’þkSñÛÃÃósùŽ{î»B»êkÊ»v}s‘î;7ÙvïØ—»oW*™(Osà#næŒ¬Í ²íñŒú¯©ƒÍ÷x–Õ¦ÅïÃ2)uÊ¸™_ž‘=œóŠ	r¤ ‰2® , 	a âXI•$SwË‡ùPÞƒü^ÁB9ó\_»ê ]²:/•KÒ
+°}sÝ/ËË>o á|e–{,blŒ£è )È]o	i³s¶4ÖÍðÙMö{–Õš6í§4Ò0Ož-³4‚p0•ÇtpéU\ZÓÈÊ:8™ºÑr
+P‰ÌMÒIG˜ƒ<<hÐ)ÍCÙ?5ê¼#¹’ÝnÁ×lû\ª1j¦õHµR­>øüí£Z-Ü=^?¼ì ¨Giž›XÀhû3€H~&nœ²>æ\_wÖèßO3mnÆë³¦ðÉ›<íÙÚâ,‹L­…‡‰C/\
+ s+iºŠ0d?ÙÍ	Îñ£Ûþår‡+>x½zúÝ7•"y}Ë°´¿~þ²PõJõûB%Óà:×W´E—}A«Q˜Ê–d9À7;Ç¢Kb	QFã Ät1P$ VU$¢rƒÅÝwý?Ü•ÇŠ(_—›èÙ¸"U³\è²Ö;É×3-¦Zí½VêNûÙ¹Í¾÷Î+‹ÞÍœFc;9Ä²G8o°'ÏòXWuEÂ€Â@fP?©¼¬LvwlvÙ“ßÉwÏÂy*­ÞmN÷„~ö½u«²Àô§þl›ýBI¹»ËòÝ.ŒÒ43Fò²ù•0žÙêÞÃ£½øP±ÛlÅCcF¡\+P/@A€*¨:À«</*² ï~„pužo70ærî úr­’C)[‹«´œ-6.ª­«É]±9ñ¦Ÿí€›V¢A£2ãÚømÈÄHŒ$ûðËáKÕ×æx8Ð*õ$Ug5€TQÓ(ðŒª˜e;Þè`à€Ïûf–nrõ>îäÞËînæºÖåsWó®Qlø¼x]yŒîÐ³S`×'[w;:žÅPa§ä­—UŠæ­‡¯ûLF³ßp>?	ª}ÃD‘• À˜!ƒ @P”V5¤CEWxPoáàžïëu»Ü»õÙÛLÚBïÚåøÐ¼n¥oßšð‘©Õ€ì1Å¢Ò'woÑ#|pŒäUÛˆ«cºdñ ØÞ|‘¨*/I¨Á^9ä$P\³@gFgFã…ÝÏ§Ê¹¨–ÏÛ%t‹™ûæÃYý·—û‹Â»ŸÇÞÎ‘¦R2®P»Z‹zºâ¹«·WbW\ùZ¬ó§ïÄ‘ÖGgh6?Öl¦°P.¯*C½
+^bŠeóœ(IêîÇ:…WŒlÑ»PËý·Þe^~¹e»FæE¥­ÝæŠÍŽ	/úêSûöâÉ‹K&x]ÔÜ€û©û‚ûÂþ¡Oø){<}a{sˆ#‰ç©@‚DÑ¿T‰ ³
+FŠÌBÝxïT/HÚ0trùÄ_‘²Xõ¯›—Fï±xžyª6ýlý¦Ü»7HF >É/ÕÝFž…ã’Ún™µCAû…£áíìÌ°îhÞX½§Ám$§*òF?º2‡ne	¸È«,Ò9  $ ¨³PTˆèG¨‰ŠLd–Ù=p‹ýíºùþÖªôæŠAu¥Pe¸s[º.b§üØ»îîkÅnÖ~Ë"gJ‡Çé¨f;Ø¤f!4¾ñyÆ &žæÎøœ&¤MŸ§ÔiÕa–—BáòžB¦·>ŸRa¶žÌÑ-Aá4N~ì"ÎDŠŠˆMæ€Œ:‘,G€Œˆ¼.ËˆÕD:ŸŸ4‘j»êÝñìg1Ïoš:H;Å{CÉpF‘ñÎ‹¹G)k]zJ»ÐE‘œÓ0Äê`a*©¸™°ÇÔ¨ˆ7Ž%F—gÍÜÂT›£³FÃ^2ÉÕÌ¹iÚ=oÜ"%–”mMî»L+…‹æŸNuB°Š´æ’å‡[–‡:ƒEN©‡¥k@¢¤†£&««˜…ä³,´;håÌúõ€/:yáêêMù×·Þ#ÓBšñ7xá”¯-»Ý›ŸX9tB-,›Ù2QƒR³eÚ~"Ê1Â¹ŽL&íþEú¨å˜CËGç.qÌ!MÓúKZyMŽ—½ŠÝqÇfŠŽ7¥b¥¼À.'œ*Œ?iwOÐpˆëÙÖèÖÅ¡¡F$žÚ¼*ð€Pá)y«pX%²ŽeB>Íæßl«[÷ùtó¹À‘ÂíS¶WÖs†IÊåLVþ½+kN\×Ö%už·úØ²,Ë»ŸBB˜É@*J¶%fLŒ«Î¿’±Mš0tÒûž—t2FZŸÖ¼´ä¿&ÇÙ^’¶ªÝFvokDTØÝA6»	év#é¿?VÿS¶ÀáÞW÷¹gIñhÕûŒÄ{®ë¬BX’|í~;X©þs¯–†•À —Çì‚Àbô~6ãœh_|ý6S·l<yçŸIU÷žóô¶“*>Bþ’¶\s‚|ÚuÞ*•9«¿–œ“´vXØûP^Ñî	»í‡”ó?¤‡þCXr}×¿qáË2¹m)@U î,2‰ Œ«T3LhË¸Œ­ Æ*ÔQK`ìÈSÌ~^¬Ýú¨ª/x½ìi¾Ÿª½¿ódÊãÍî½¤ÀpâŽß+í—†ì/â¯uËÒ•½»W%V*wGßÊHApGøù0äµ-öüÎà…ÎïÞpOðÅMôdŒÆÙ9`Æ÷qÛ[îW%¤ºïÑÁ¨' "ÙáçÚšjÁfÛ þÚG‚Ò¦ÿ.çµõ¥†ð*zË­'±é‹DÍêÜAc½¾¿ÿUæ- s9_ˆI8_…z–TŽˆ(«ë]·Çdç 3Eì~ÞIòƒ‡K8Î¸d¦n#¼_"3ôHW EÜ P3Ê,r¾|š¢1º½Šž}yõ¦‹gZ¾ÕÓ‰žÚ3Rƒé´újhîùÕÑd<¹Û·A6pÜÚ‰…t8v#©v³¤Z¸é¬e£dê™ºê—úë¦ÿoçßo7àæþïöEakùýžlÊ#Ïâpƒç„W ÉÞgÈ6@¹©
+ÏÀa:Á¶ðÎ/‚>·»B©ç×JÅ~ÓÆµôìôÚnôXòî¡£ÛJµTèŒ+`÷¼‰xíŠ
+»À‰±ûêSî&Žý,ñÕ7ÐÎu ’×E!ª·‚uMðQ€‰©ÊT‹ó/ƒ©3ãÉÞ´ž-¿f{òäÝðÒµë³T¦öì²wZ¥óåz/=ÞM«j8IRìúÚXÑ¿â.-Dì?UÁY
+—G®/”NÌƒ8Ø4U…¶ #*ŒÕÖ€@ %bŽâ˜ÎùçhNƒ­n<Ž“µéSãÅ©æ'9A
+üª5ˆF€¤ëÝj?6óÓ´ÂvÛc*!lö0SBÌž¢Ñ_ ¶Äëò(Ï[¦…fHp3„ûlRˆ0ò ¢ºƒFt‹ž_|HOÆü½m¿ukn•çúÐt¼ÍÜÞ¶[­ZJ-ÌÇ´ø djõ»xÇV‘¬ÇQâ«']¢)cGZ˜ÚVU@¬C#* ;€«›6¶ˆÀð‹ š>¦ÐËÈ}nLÓÍ	œ4³¨o'éJváÍ™jÌ»gêÃ.‹‡HRáD/áØ1Zê?//—‡hÎhL—±8ˆTuS£‚m°*5”D jÙTÇ¶BÎïÞqD…ë¶KãW³l=—`ƒt
+÷·9•›o9V|5¦CžÏ4íÒÂ;`HH*‚è-û•^]ž>að™š‘ƒ8°)ŠS˜ªc •0fBÓ¤6û*KBÒé“÷X¼+&»n½‹T©¦Òè4ÛÙ{^]´üi¯_›í VôØSMd2ùÔsœ(¦vi°çÆ5&Žå+…aÍB+]ªÀ‹PÀ‘ª«šnéúâ§áå6Éèåµu;¾·rOS-é¶oïêæ{eÞJß¦û¶U{iLs6Ï[;é$é½j"¼UÅ…ìåx<>Ê>oÉ—üu“¾éüus—ªÏœö¸¤¬&ƒ†"u[v…HøSB]é&Ô“3Å6¾
+®Á"'LNˆò×ìkƒT{U<N'Æ¦¡õú¼Û¿ïö’ ¶M/±cLÈ*·€{€™kÀ–OÙuàQËõŽÌŠ)º®P†9·„Œ!”ÖŸˆbYDQÇþ"À½›ÏýÉn›³lÆ¼‡µÔÃÛHKfLRïàyy”zì÷¬út'+&Sí’q0Â+xàh¸„úº$Va08¥æÉlg©ƒTêè²ýÐ¬W†!ÐãÐ’=—S°$L‹!
+mák©—;Î·ÍÂ(4+lÊµGç"ƒ²ßýXþ[µÌpjVüŠ¼
+úÄÆ§ÜœZ¸ø@RöS¥£w›#G‡ïÉì}Oug·©œÞH<õA“ìØB2çñDÁ.ÁQjõ.À·(ƒÓä›_‰½Ž÷næãQ°è(²¹ñúÍrêIð€XaD’&üQˆ—djÈ?Ôc´1mû­ÆhÜ_Ö_ì¢Ÿ{!Ú¨ÔÇs§#ùŒn‰ðès-ä±mÖr{aUÈ2ç³Œú­¶ç4†Ô“0oüDPØüH{ÀÝ¸u…¾'ØË•»föúþì#É«dä3X9sšËÙj;Žd—s‹RÊ¨À!ú÷s2@c¶0”tlËšHiÀ$*PÁšcõËµó=Åd€²ªHØ*Ñˆø)Ûü¿»ÚÍÛÁ¯%\÷¹Ãz¯•W«]ò‡ õf¹
+B“²^+€Ç÷1špDP³Y&;Iyy´ö <ñÿv‘ÆãoÉúQ:ö…ÛÌ—mvî’%põþÆ!A!¥Ó– Øã.U=Ì]‘ÐÏ–²šnycéÉb :UòOAŠQvX°{ì“2€;2Æ€MÙØÅ°m`™²üA×…tÐ8WìkØx%ÌmßZÊr†Æ üàÁÁc‡­g—	Áv?È„.’¦ÿòyŸ6ƒ½+UŸ¬œ¾ÿcäÏÅ~kÜ·´Ý[mnc3ï¾h_B¡ˆ›œ½j	±š!ü&y—"´sEš‘œ<§¦Å7×OÔÓ·TÃ}{øôX/ðçryØhgÆÅûá=¥“,ÞñmävÛjÉ³CYkYdÑåha¦*—5dbdÕï³c6A‘aúZoÐckú0F„-½§#~yãcìÏ‹×F©¦õMíG	Ñ£g É·ÅŒ1Óˆ8-zdç÷cÑ@Ö¨Ë¢ã¦'ã[íÓ¶©ïF]ÿý–çZVxfÏê©'m6]þD#`é0h¹ÁØG.i]p@7Nºl¬HC«Âqæ	!ÉòÖ>ö°Ç„[¾üæÎBµ3è¼’û³YíþÜ™;kUÉ¯œÃŒ†Ýbv×rgÿÚÿµ¥ “&KÕw„eßÛ»PÿyÔÄ]Õ¶»ñ¦Íæ…›—¬ü_žj:Ñ–ù¦LÚ‡±kþbSïÍ8Æ$¯Œuõ©o·îyL›,ä«‰l¾îÚ?ÒBŠÀ>gž9Hƒe`C–œè\Óà¨*rÓ4lýü.¨¹hq–T°ŽMÛ,¶ÎnÇØîXdÊ¨çš2•Ébžn9¹ñlÐ®ŽÆƒÚ Æ‡üIü,ìéF¦mùÏ™÷ïwó[…ygØ1ÕwG1ÆemíË˜¯µ"þ§ÝþéÚí·ìþ§ÞÎQo²Ú}ùçsê#]±©Æ…f#Š¼‹‚e
+˜D3¨^ âõ&­ñMõ¶^GP¿?lÛþØc‘ªúÀï?¨í6ùPÝ…}[NPw¹\¢Í˜»x¹õ”`ÑJÏÊÃÒûà±?, ÜòÃÀ/@m_Ýíaôuµ5ÙUwÑçGª;]®KzûÑ}Ê±H588~“ÚÓåCá^‡.ãþSJø”T8wpà)Å<·‘>Êý6.ç^›ã%äË]$%b/VŒM+LW±¢ šŽ¬{BÀRe'“qÃ°äÙïóûÌD(Ø/é”ó½×VÕêú<gÏçF=Wh3™ºkÕKN7‘~~yÖr#ÖïvÆÕB¾‹ˆ&ðVYf±ÜòÆÐì(ãBT¨ðP)_Ù`/^.·ìØP…šn bÈú]‹S!ÕMpY>`Q]7œËuÓüCsË‹¤çÝ':Þ¨Ô|éÜ¾ÞŽF­D½“OAÕ^ÜÎÉè¾‘Ó'Yê±’øÞ¹euÇÑ£ƒrMÄ#i´-Waèç
+ožn¥_OnqÊyÙWÝÀºM0Ü! Dm`jâ*RLlAf xÝ
+Œ? ûªÎoÙƒó¤5°*n¯OßšÕìkýå­FFwŠg£E&Aªo#ò-³¯0:iº›Xý\žgtGñ’ª(×4'¶XéŒ¦J‰ŽtKÉzwÌ@4Çšm:¶nPŠ/pcó>«N–M>#"VÅ1ÙÏ £ydöS‹Qme?eåÙÏ(¹¹éõ$--ê+e>—òc•ù<ÝŽSgðù)wÛšËE
+¥~hÔó¨”§‹i²_T_Që6ÈºÞn‡ª¯Î|êqZö·ˆ‰ƒbj/…¹7§#R˜ªªìXÄâÿÔr'ý,SöûO5²ÇzA’Ð<-¹»šõ¾Üwºx„+ÇqåàõÂ#ØJ4,eðg¢:A²ŸÜ]„1Ñ¬Í·íf'ÍËÅ„Ãëè u· …÷Îúƒ‰\[ay£¸îgqÊ
+b9ª¦Œf0@™M€a!G‡H¡_£änUn£)1Ê*ðéƒ‰…üéªéís™ @ÉT^Õt?íºÕ;v÷¥è&š=VùæYÍÔ ?t‹¸XØé'Æîö¹¨"‘7È._ãªÀohKù¬Ný¬°wâ7bHŸÑQ\d*–'F5‘
+°E4€LSq€ujrŽ,íš¤¦}È“ËµüÑlI¶-Æè€Ì§LFíƒˆzd ÂsyºFš­ÙÃë€<ÜÁ!.ÁinX|IÌ†ä5ˆíåÔÜÌ§ÃŠw¿{ìG¾7f^”­ƒ¼pôÖmÎF¿0aT·e€]¯á{m±	Ž*&Q#…+¿Óè±As™¿ßèwt²½ò›,/¼y.kßôÚ$ç·³À.ai²ãN³À´0©óUÀ	E6ˆÚPW™Ó0@ŒËc¾¶4S™ÌFðºñê«ÙDBñì¬£[Æd˜}˜uf98š·ú£÷I)=º(™4¯Ï]\ð*1YÇ/*²Ù=ñt¹x›ä‡ëEÜ®šÀ;À,Ÿ2–ƒ†Ã`ƒ›ÂXÂ• c‡ØŠ¤\î¶ã5¯h§K¿d,ø•ŒååáÂ«ØõÄƒ9»Uq«ßH1Ë,=<Î±°AJÑÉÂ^×Ë£Ä~—ã«ìŒ“Ùê3H,‡i‚|+Ö[WbÈ"jé¶m‹1fÕQ</ÏÕ˜ÇŽ¥¢™Öù·Y|Ä{èïm.f•a=º¶F2á—×Ö$µnãÉ.Ì‰•#^uíŒ†s½ÀÓNóýY]à‚“©Ó,ðú^§­Úš.X[³ñÎ‡>®†åhúPåxŒ½]œrU#z——ëT¤	ß·ä…ð²°æZVä©µlÔ¹ÂU°Âd…Ö€É!–©#Ò±T¬]îŠô@-ìûÓÌË}Ã˜¦ÊÉ§lY¸ØÙq£ÓŸ”T%õ¬æHË'í|]ß½‘ôëjÙ`Ü><X¨öÿ€1/¬ ]²]ÜÂÇ½˜þÝ±Íš¸A,¤R`S¤ä/ŽjÄdÐ4lÅ„ìø£Êþû Â,¦ºæ¾@>szOãI©“*8“{gJpƒXöBËF5“~â…Gr×wï+#»…A’v«¬ÓúÑtøñ§Ê„®Vv`¥ÇG[5!Â‰0ˆ*ò¦
+'ÄtÙxúšho?N:¹b°|×Œü]vŠ:Íúói½Ûó K‹Í©ÓàýÔkn÷æÐu5I,Àr\"|³Q­r\¹Ëu!ü•ãñåÖMv]£Üì`@,û‡ËQ¦YÖñÕQ'à»r™N÷®çùÙÁ,Ó©;F†Òáƒ^0`ÜlÃVfgéöÄoÿ¾0Úo¢·¢ÓÀ®¸ò‡ï7 ›þŒ¿UEã¶Í a&D´† –iF¡ø@7	×¯Ê´g:é½-<à!7óOCPêyh”îôÞËïÀTú¶+ÔÏå3Ó¤·#!¨aNnSñÚr¥ò}1êÙ-Y¾ÎfÇÖus3Á¢Ô‘ñ È…;J¨*7MSbîï†”?§ùÃ¤‘YÜ–ïÀtX¾·xJ§ÚsgÐ²î
+¯Ü›”mLm;ÆÝ#XÃV‚ñ›Õø·‚Ùc£X÷&¶;3¦\EŽÃB+6‘-KMYt§2¡‚-¦°o‹3Î$%Ð)Â²åX÷	ýí¥„­*IòŒõîÝ¾=*ÉÆëºÓê»¾=ÙÆyI±=.^½|àfuù«¼ô¨=Ž¿‘´>îånÆ±®Q,$4Au…jwµ+Š…9dú³}Úk¡þ´0ß_<µ[{{Túr"“yúk'~"6hÇÃùÛ-ÐP£€ð*ºãU?r½.¦>¹·?oøLÞ†u¼eéÂtVtÀ1V R‰Ü¦A„•ešÛB|óóù@+OE…S?^P,>vFùRqâfSÂ¸–˜ôr®ý–2ü”ïXf}Øœ/ôÆíËn®~ã§×TÛ“Þâ©jøÔ|j}wÊ~ÓÖ{¯þÇAäX¿‰Ø\SLdê ‚™MNU qZÒujßÂóZç°5YIx\¾h7Ç8…;Y”Í÷ÔÇDµK[}6¯¥oïª‰—9%»¾qŠÙÏn‚-ÔyòSÛß ëñ¬Œ,S!&D€Y†p˜lf b#„—¤0‚Ä§ôxV>M7ŸŽi¿”M7¸ûÖéž+žù4´S(Y¥wô° &æ)§‘u~¦õ´ç+­ègzÕÄàÍêÔé :^š¼
+sDm–hu<\ž+ïË†
+Û[_£©‡!™Õµšû1šp@£Ý¡ÛlFeÃÚvp"uõÆÿcïZ—G’õ«ókNÄT·î—™‰àblÀ€mŒÝøÄ†¢¤*@H `GôsœÚÛ*Ý@¸±ÁÝ½gûGƒ[Hª[fVfeæ—dÛÿ#ñ™¿
+ÇÌ¹[’ôÜmkQ6A×@KZÛ–)ÉZC¤¿Ù«"dˆg2c–)Oæ=k¹ØYz{Â%ö¢‡­r/K£ÑríÇá&¡•^ŠÎÆí|ä¿ör¿O°½Ètbù¤Ï¹6²³ïäøt5WóÎ	‹-Æ
+@vƒ•Úòós·?ta‹Ž’Ô¼]†V¼vé5ê9¦¥P²¡ÄÊiþÔ˜âa~%ýg?ÀóÜ=ÛÍwÏ±ô7p][‡ù)
+ÜÐË½3\ÄÈ;R k‚
+4?7%l:Ktæò„›ä}D÷¢žH«ý¢Ä+Ì$ÑJYUg!á#?)K¶¥[úþsî‚NCêf¹ÅLÊ+')oZÜåÃ’e‡ÕþCØO•ˆf·N«Û[íesíBû™­u/†§Wä£Sö‰
+hÂ+ÛéK‹ó•½dŽ2Ë±ªKG¦d\¬i´.¨¶ÈÇÝÉ”Ñ
+Õ
+ÕdÑÒBu”w\7È*è%§Q‡
+BRæÝ,ÈR¦ÙïÙ'¦h$W‡L0·þtnõ×ü£²Z/F]ÔžÐºƒæX_v†÷£îIS‰©WŠG¦I(ž»Ö²bq¾}LXQxxé{»nzþ3²GCQnžú½úÀ¼{fÁìIí¼\éâi…caú)ùŠ2|5ZâHõ‚'ö½¢B€Æ*\Š¬óÀ4e(qDÇ`ÓS÷÷›l>;–ÖŸÈúí^	î/ìyï¡¸êÒ¾™÷YézÕn	¦5‘Bá²yÛzYzbß¹W‡ƒ©1¼|œqã´ÛÂvÑ>œëfaSÛé\¹§//·AŸ1tS®Ì¢”þ‘Ææ¤|J{ÐŒúCß›¨7„ßçi™Ø®¹ñÞÉÆ½lÐ¦)à_¿ÒKû/&»&èµ—Ò¶^¸€öu²I¦ë_:ñæI›àJši~àn€¼ªF?L%zg¾‰^H³éuÚ_ÞD—, |u5ªb-C7È|ÞT¬ÆchÍ“z¢4&¾dú¥äñÊáEÈhUJ—*~ŸXÞß{B{S’Ç€ìÏFÔ§¯)T•Ž­¼ôg)3>ÛØ'Êžîæûør&Ç£7ÐéŒ]ÉáÂv!Ê¶‰=ž¦Œx_Žw…P·cÊdQm_7F/£ª«E×ƒèÕ~Â s¸ÑbÜ£l'‰á’6"šd¤Jo¹ƒLÁÚB[E‰º¥ó0g“–Ô¼xƒ°%A1KÓ^5€bò2àÌ!ÅP%Q:þœô=Â’ß–Ù >RVª’lM§òB²doílÙc”ÇÛ&®4ƒãGÕ	3QB°Öê_ºû²’¦´l;ù³IJùÛ’2a£xÖ§i5”Ù!­¿ÕÙM³gTzUß^‹Rdþüd	1…™//þû$±ðFI¯•“©5À'2äÊõ¬ªóÚwåÿh™]XÁÄ]Gú9Êú%ÉÏ!Éø9²”9’uÕˆ¬@ä:£ÒÈŽœ®p
+yéÄz¦Q–òG.¢0÷â ?©åNÓ¤µ¼®Ùìö$OñÒYZU•›*þ¢31±k-±áuwêÑí,¾”OJ¹*‹?÷ËÊ¤¿äh'4ª–{ïIåÑÙ¤'{åÑ“LîíEÐãU·Øœ"¬bìW;§.QÔ}Aö<õÐ±LÅË'@ž(K†Y€@—¨*Uh°"Ô?Â²<iR›2Ô÷?ºŸW;Óž×–ïî$f´X®ÚKívy×#¬”âxGy¸«/­Ç]´eü¨Øá2¶Ú‡)*å¯£!’öý+Y8Ú±ÜÅ~?îŠŸÜg!5á ¸ãy8g/gûHvQ9C’XbV°˜¡12 /@×ƒƒˆUø0m‹<;D#)$)¾áýR}æun²8cq{ß¬iv/TÜÓ&|h$€ìšoÈ«kÜ£Cá;ÅÄù·o6Çåpÿ?ÙdØ°É”¡É-2Ë‹u cA+" #(1†Î‰"Ë¨â‡r‹TÊ-;[Ì[æÔ¸cÿeÐ_ ÷ü®›Üox˜ÝÈÒÝ¤Ñ7“Þ0\¿Ü}ñj'(f+_¼Ç6Å­à,œ£d{ˆÿ±›HþÀ @	°š•ùéúÙÐ§soñôþŠù¯ðS?yXÚ¹#Ì½x‹`¨%>l+q¼‡±Å4U,}pž8'…ÍSIÌh1m?Bü%º4Œg8óAÇužçn˜ù2åÒ8~e© (îù¥CxàH	E#“€"BH&š§`tr³,V…EgJ%ÄàÊ{¤ÄÖ[ýŒÛ/“ª<XO„®6~ŠÍu‹öÍæf*zX_tõÕdzÞÅn^2'ìÈˆÂPJ•Î]Äˆ3	òw+ÿÂŸnŸåÒx– ŽUxÒßÿ¥žõ?ÆüÏÑ?AáÿóFÃ“‡³@“EjáŒ+cË¬LcòSõžžÀÐGÎxØwípgŽ¢-§üG*È¨“è‹-HTða{9áÈîÕvt”’¶}HÛ[–ÜôïÅÄ<Ý‹e3´ó¾h1+>‘¿”œ7õþ*œ6õHÃ	¤ôå¥“–4ûg?OprË7J€íåø}˜Ô£¸*ÇÚÜ‚ÎÉ2–Ãë<z
+äÖM I¼¡È"ƒãô$rvOèeIä[ «¡—¢F½"ó’tqaÁòiEv(=´‰Úù)~Á»àÜÐplj:Æ.¼±ž;®×\1KÖ4Ú‹Ç+-|º_bmã>´¡á•z=€U*óvàpÎgYÜçÞ·#ñòó…Ð¸(3/ GÍ*¶åŸè‘wo ­hòg¥:§ôÎÿ¨tñÆ2ÜJôîÊou¯0!ôG¥?±Ü,FS÷OŽe9vË²{Ñ¸‡x7‹¾‹µx¾hKéZe~þö£Òñ[l½¬„¥?'ª>‘ \ÑÀ>-.–”&¯—šSÒ>8ÔY%G†r¤ÀàLYWeEF0d€9DCPFUy^ùØ*ÑGœ:àrž#oèëI—&«Í¦1ÒW ãê÷f¯Uëé7#uÙ¿±SšÕzƒÅŽ”Èº˜ƒŸ9ßyCÈå×aÃ»Ù£1áH618j2¨ jBºŠ (!‘á°„xùØ$#kžÝe“ì‡ïí`\Ë;·WvJWc2šùÄuPƒ…c¦:X\>Ó^k§\
+—†é—týÐ‘õÞ]¥\ó- ˆÃê›âûv‡ª0#7ô*+Ë£qÏ¸B¶Ï¤Ÿ~
+ÛâæA©)Bk@$ƒò?c“”¤<SéÔÊìæ{¡Ô(!/SÄ"~Ó2ùnÃa»&õ0½f×üÔæÆ7‚`#R
+‰¾¤éQI»´høžPX§=cî«·µ»çŠžXW-Yo]Ü\_ZLm´|ZÝ G®OÌ9)ö[þñc­(ò‹D pÕ J‘ˆx€A5ƒÕuôÙsÛÀ‘²ü“Ë©âã;Ú56ª?	ïî_æ"Öíu¿-/;uµu„Ëî}£¹ãÄßÇ9«û>˜s@8àÏËM^nj¢ë´\Bôå@›t'ÄT&±i	šÒý¢¨¦±^Ä˜Š;ç¸1Óo×˜â§EâRK0ñÝŸ‰šOðÄóºÎ¨4¢ª„žV!ê>Ö¯«5%òOÿPzÞ¯r!ûë‘['"i2Rnûb¸ö„æðna›Î°>´75ÁBMåñò¡¾«¦ç#>Èež#æ¢sùçm»#	W’)#F‚©ª@€ Œ%@èU€º¡sœú¡„›Kó:™j/jCW^ö—Ðz‚·Ú]]õ¯GbËmt“/¬dù¡u5¨Öç;þì6æfå/Q{<™¾ÍÍ¡Š‘tB©oÚ!8I‘$l"ûˆÌë×EìûÑfAÝêfþ¸=µ†f¿>|nÜ®0rÄ»Àõ»ùEkÝ›¯FÓ]]K¨õläÍ+=oÈÉìRÏä)ïÅ;}gjf¾5¿ÝÊ+P¤I@D¨K‡¨2V¤@!V6ä‘½|Nö¦I½*‡½Ÿ¼³/­›ÎÓÈju»S››Îf&*w#SRŒ«ÁZì=ÝŒ´ví¹{q ›ùü¾Ïçq#K=ý¤µÐ³´‘ÜßÏ:f³3õÜ€2Û6Wi¾hüç34Î$ÌµÀ;ø™gäM6ÉóLzW†ÏNÛŠ?|ýÙ¸øþ@5X,³"U	åP±I´(,èÈZ á;*P'ÃÂ<.úšî+5_»qŽ/;œ§"Çe@m3[â…ºþUu'xÒÜž+òþ»¼JUêÜyì¼È:%3%šW<[ÇñøÏÛ¬Þ{@Ïs"Ï’hà1x „,P,	’Œ‘ |„þõ†Ýêý'îÒ<Ôš–Ý¸_Æƒþ=åzs|Õ´$6Àlygm‚+E½LJJt|Øaû¯ýê×~µÏÈZh}ód9MdÒDLZ›d¶âKÉ4¾-¸ƒuº–Ê<J£ÛMçå©:nß®åêX
+mÏ¿®gî¼ÉØ“•Þ:<‚Ê+ƒã·À9‡Ò6opç\(‹% ”’U¼`9%‰=°×É/}ÁuÃ%…R>ÇÄç¦}ûLñÓªOošBåºØ/ãõu NFwŽ¯É†Â$žCR{‚–_:¾°jL0¼”.NÂR¤‡#Qí ‚‚.ê@”%ˆ3ª›ÔM•1$ÃàN÷Â¾…•K]~¿QZT[ ®ÛK¼ô×õ—Çé–ý^îÛÒ‡A¼MPòZIÎVåê¾{rÌëxE˜9ÍÏ‰e6½–<–\/@%nˆƒ‰=we¡ÌãšB-•'›æë¹¥¸?{¡9•ì¶»Æ(k‡Éþ†•	Ñ]ÐTþÆsòážýÏ°L¾ô,}¸’\¡KO¾B»B¹ŽüåÚÒ7/Hÿo[äÙô# ˆ|L¸Š}óÉ·|‹É·/h“íÇ:äËš+¾gT ÅÆ[‰6¡
+¥gï €¶[¸@	;¾@öƒ±ÿiÀHlü#U's³¯ÅV[Ïcþ7Ç5]:ƒ[žXÊFwDï/YÝ½;NY^yqS'f†ð¢%Ã+éKÉ=§ôF9Ø›-ÞL<sI¹läk8bžß}JÕÃ=dS1yÚó¶Ä^÷ßZÖ·-ÐÂë}cKJ/F;›ä#î/°‚l²
+0‘Ì 9 eS/ˆª*#É@ŠT{¢àŸàõÍ¼6v,uj7:Zkz½nØ+ÿ^·œ˜ ›±ûë©àÖhWð«	,|©Ø/ÖÈ-âžÐ¶Ú×÷“‡9ñGÈ…W¸®(QÉòÆêV	Ó¼ó”ž•íŽÿEW–£Q½ø8‰€y™(‚¬D,È@ª
+À˜“x¨,/¡“%BV.çMÜÞkuj4[káÍ¤×b–Á×pîLy>è«·h#ßªÂ Ó~ÑKÕ¼:•œƒ­¨æm'jŸã÷õ¼X¿RŠ›1Oà¢„xÝwv­¯ÝµzeêçÎï§ô£¤ñZÊù6r¥enO
+wñº¸Œï8s?ÏËh&Ú³e‰®}äþË±&¦Qf$ HP:G¬/AexY5¡)¡Ókè¾Û:Ãi[¹·´§öÀž\våB›OÚ7@™ÏoïzÃšt×tM‰;³Çm"…bJ§ã€e%ÒHÏÂ”a^ñ?»yÅ
+êOj^½fù¤¹dÇ[>?’eÿÜébå[ça4P9	jÖ^ÛÉ8šûd¯á³¯ùw­e×2pjø¾U<4­›i—D5MóÂfU®I÷×kÇÒ†Æ“>Ç3ñRÐ9´¹m›êI[IµÅƒ“ëÞ|–I½õ
+ÓxóÂQ^ôËg?ÊÕú´ˆcÇ(Ü@ÄÃšåÄÖ§FHÄZÁÀZa?*à‡Ò„ïkD³›inDåIÞ7y3ðÜh^éËž¹À`àÕKèúu›k(áúùb$b¿©Œ/Öç˜¼¨T¥M²÷çO)Ù•^ÕEQ€*J:d²!é²¡ÅÀ!ÕMýGíJmÎaîÍ—ôñày3õ%o€Æ›ëé@¿¯Ž—ÏëÞFS%¡»»+EÉ
+Þ~ºŠ×ô‡Êï‚ÂüëÿÈÇÿüï<Ø4Éôny>ŠaFHæ!$º±ŽhÙ E¤èK¤;ÈätVâÄ¢Ì(Ü>êÙ,91 ú?ŠÂIˆpãa¶-å‘áÈXþ*¸kÒKÔµHÞË÷3‘Ùœ˜>áü8:cA¬*ž¦Ç	
+@°/"AUq§#	¼ÎFjoî<]Ý.9¦:<ß÷ªRÛY^»mà´'—`>l¢îžöCO:¢IØ#49†lç•ß9ŽPùxÒt„LQ½£EÂYPf(zo@r"™µC”vÜ³g¤42–]J‹/}¥eÕ[#6¨@UÇ¬I¤¡3Aâe ˆ&Å‘‰$ŽÅ§£¦½ØŒºE6Ò«ñõz*ºóK^´ýŽ!\Ï…nÍ#˜=¸ÁµÅÍ±íV±ÍÓÝµîÓ+¿³!9òñÉ±¹Æ©
+P$Ž¡Ðr*ÐÉ#À0tÉD†‘eõÉ÷ìI.®x_ ¹øÒYI.)Pñ-ç+=ÐN‹h1¸¿æc;9ÀzŸš0Xv¡÷Òšnê|SAO®Ú¼èoÌe£ÓÐ|ôÈºÑ¼`kUîå´z	I­¶×Ëb¡ AD“Ç’Zz“ñ¦aqýî—úÀø2ì_F­†
+“i_Xò’ã8°ûØÚÍÅòéå’=Ã°ò0%!/\™¤àE‰C4-Éä‰ E@†C@‡²"é
+æLæGmKUüÈ.cíßßVëÕÇËÉËª;sº£jÛ6žBfjOM<ä]ßÝ•„)ª[„bðo¡AÊEFlr§ÿ÷gjÑ»£Bá™€Os%©Êœ–Y­ØÖW¼öÿ¨DjsÅ#Ì }ìÓŒOZ,¢²pýÀÿ”t&¶D·yˆ4Ú™(óT§÷s(Jôzªèç¡˜èÖúoö®¼7q%Û^k¤™+M¥½/ýZw 	!ìDH¨\U³ØŽm£ÜïþªlKHzZšù'
+ÞÊuÎÏg©:Ë6Ú˜ZA°®’òøq÷£{¿mÁÓ‹ÐÓKàÓû&òˆZrˆ bPý"q25Ÿ© TÊ&ÏcY×ä^ ÞA½B=Š¡^¢^‚¢^jò½8ê¥Ô‹‘ÔKC©wK½L½oåY˜•îJµ.š–³£F°€Ü¼Ž„Gzí›P¹ž4…V6¬Ü5ÔKàÔ‹ðÔK\Í^²wÎè?–bÛüØœ¡¸ê¥TUzp-có¨ºB–0wqYCëŸ††èg ù{Ö ®Xfæÿ=ºób30T/FTï[ïÛš|iP½$lV½®zûÀê%jåÛ©Èò°y1…®KåínúÙÅrÑt•—C†(°z4¦t!àÎ”	É„ûŠ2}üÛ5`¿¬ßìªE”îÌmËù‚ã-…ŠûÀ¹•êÕLÉ­ŠœË>>VËcc0ï‡¨îPyí÷½ÝÞ[yµT+›ºÿb–lc-
+Çƒ?r)’ðër•˜íÛ`•--#‚¶Q¢EÏq	¶»ç7{Rç<®‚7\{íÚæ,=·¾ó¯DŒRè±i¥Ræ“×bõqé±8˜ŽòD[W’ïQ<÷Øl;OïÎ965„âýˆ¸öMáøû8Eý¾CŠÊw¾¯þâ}+¶(%éïg,~ˆSÛÜ6cë}³7·ÃY0ŒvÈý¤R@„ M¤%«¯ÂþsŒÜ´@JWez§4B˜pŠªˆ€çxê[i*uêÈ+<°ˆEr_Úëè„ú¹§ç¸\cÇ¸!¢ª“ü*0ºófTPÝüSaÆËûBàv¼ÁØsŽ¤p¥Í­#BèÝ…¬^•@Ù%J =ñ©’pßÿÊŸßSþlòPÏ;oÞ~@ìüõRñ½ƒb[¦Í‚W…—¨tëÛC	Û÷µX6	¹\|ûk0Hæ_0¨=·êvx´?P\¢ÅÌ’:»k:+,Ö|sñ6!Eˆû¬nóÆÍFv3ÛÞÁ.a;ýmåÒÝT›=2ƒúÛyk&{êä€uL—˜"6LÌñ *¼ $A%@Ã¢
+U‚'ˆ˜W¿¢\ûð~¤*ÚéŠDn—{"uˆ?_=…¦«–ì<Ú:X,½ÛK[UÜ§¹[¼Ë^N\«µöûêž½ªA:Ä¨­IpPƒ(ÿÕ ÿYä×ÿxÙÿI¢öE’ãÅ‘lÖC2×PˆÊñ¢‰d ‰Ñ–¤ÆCÐ±¤êP’¸ó«Û¾Ñ«ô•º´Ç¤ïÙY¯ŽŒg‹°ÉçZ¥¥<T‡³™Î}—h÷õQÝ·£ìÍ\·G»K
+ÚNJéÅ&©õˆ,>„º/•×9,•·:º5ŒZ¬“É/ª(’$\½ùœ”\Nßùi ßä\¾×–Ð“±$	"ŠkM	*à4q2ÒÎdx%¼ý¬ìÔV±5™ºÙ »•B¶ŸåæŽ% ©!WrõÅíÜºÎÊ¥v²66„zÃ<xGÇ@ÜÊÝñüˆÃGÈŸÄ3 wxkÇ2C¨8 þ xˆ¬B 
+Š ®PñMET¶¾<§Û–ºÌƒU±
+µ¾91!·jŽÁ´ÿ0¶Š•Òüê²
+”'¡¬ß÷wS›ùxØ„V»{ÊQKªt…9Ã}[s7|RYwb<2D¬ÿÙ,f|!nXAP5ëLÅì~
+"¢¬ì!B5xŽ©/‚‰&‰¬ð&À%BQqÃÿ¶âd,Â6|ìó³á˜Œ…Öã5!\-ëVk­ùÃã-Ä+‹ŒqXÊÊÙ}D¤hµ‹9¶gü}<¤„ËËMý=4ì<þ "ÎŸËøã›Ü›N/ÐÆ}ÇÛ6©W7|ŠI»qº~(Qjù&B‚I:äQë/Ýò>¹—L ÛGÌ¶06»˜SË¶¦³iáxxStÝ—Úý˜”1T„$êuÈGñ6r¶¡¤%¿Äè×úœý’’_ò:w‡ýP6­t)G6ÃRÍúßZÿaÙ‹*ðÅÊ§©+a’9‘¸Kg0ˆŒ–ÓB!†óûå-_¹%|…ëÇ…Ï=øæl8‡y«~Õ·]ÀD¹<jÏŠðÉœØ¯À$z×¨<íÐ¢r¡„ý½Ø`fQÏ'@³Ô¦¿þ¦ûqïà¸˜ý¯šŒÀÞö"!Ýþ,Ãj(œa˜Ð$&ÇLS¨m$PDh òï
+phË÷“â÷›æ=WŸö¯L†v•z%’Žî|TÈ.%íÆ|p*"Øêæ±TV~}æj‡~@¦±7·)rÕÚð‡ýøð;­RE4t	‘¤².¤ €5MÕ$ERÑ'Ô<Eœ»k*‹~‹\6ó×Neœ—ên­RÀµVh]•®shX¸¯º#+w PùaÊíòŒmÙÖâ+2‡‹€îíÒn5ÊëÃ|…r9ˆÎÉÇ€eÈKD3€(`H<ÅMDd]—eÎüÒlÜsÑjŽýAûq>¢vÞuÁ.üåìjUåž.KšÐÂùeµRñvºäñú–c)²í¡‚ÞÐ„QÑ!ñÊ ¿3û$i9Žr¢@4…ð@Ñ$pyÁøAQ¹µl¥Ù¯ù7jÕ‘4.¿lJJ^R®+ZðT;ÕÛ°¤¶Š—á®´¶<Û¥Ý2è[¶××œ 1ÞêË1’˜LHðA‘t‘Ç€ ( §¨R¿D×yÄ!ÄÉ©.9ËI}\r£<_žåàoBmV%¾PÉÍôB¾"-j¶oÚWÆøzùmŸd{ ˜æg¬CÇvñÒgMI‹£ÿ5@˜Â1u+Ã¢A54‘£æ©[*Q]¨¥!SUTˆyYRøÏëRöÙhð«† Ü4CÑ,ºñ¼Áuî”þ°ò4ê+˜÷æÆÜ¯\>áÎz×º•ØºíA‚¾B…^µ	S¯~'.Þè‚cfŸÉ¨SÃSÇ&ƒ‡CUÊ›Ø4 þ«×/N‡Ç$_Ñ§óëbv¦5š€Y®*5=5ìÊ÷5/_[> ¸e¬ì¬Õršk;”Û«óð ëëß‘·û5 q=gê|T—èÄÐLŠ`"ž­–cXÖÁ©ªBT,Aþ÷]ð¼ãùËÖ“U–pÙ¹“\Éé#®Yì„—Âìm›èP5]Mß]ðLvÓwh¶zY-¾bƒÀÉ˜ý?³^zn9>Ü/‚Æ)F¨Æ‰@’Mj„BMR¶¯"Š¦Cý¾fÆÄ¯G²G ÞwŠå\­Ø-v
+£N¿Vëî «LA {¨áì®|nxõgõC†Æñ~>î£ò¯kœ¦“ç*$X:4¨·*è
+«$%ˆø÷m½ä»þêv‰Šû8m@T€J˜7Œ!	+w C$³fxN©88\žüÞé‡0päÑ¿ ÔÛ9EUÈ&‘dUB,±E’jê@S0ëÊÀ«º)ˆ—ÎO?ø*Ü\ºÁÈ6gÕJàãr8OºK§: Õ\«Ô—“q8Ùö Ü®¡¹^òß¥Ú.X‹ò™:©|(ª(¦×¯ŽøËrŠÆ@¯`"› é<1Yî1§U D“tÓPá—®e…A±Þµš¾»(N¸IXm*‹~)WsçÅl-¬§üÝmaÑ©†ø>Ø]³HñëC‘¯òå ˆöê Æ}Ï™¬Ñxe…Z~@‡tg,}$Š¼ é
+……
+Ä«è¢AO]B¢¡Šgž_hìµ˜#1	“`óx9×>·[°¶‹Éá×é²‹Í—Å8I&›¾0ÃÁ¬Kv&N"&83Kí²îÑ™‚wø…Ž"$Î ÿñÍKô«	¾C’OPÜ¬.~Åˆ‰h
+ÏÊÑ3£CV.@(DG
+2tMP¾Ú=}>†îªe¶†]ž+ê êúSÍ¼2noCoØÔ½ríÞŸfiãä0ÙöÜúÚ—ì¢}ìüÃÿã½èyu¸_#a´™œ€Þ€ºÉA$H†ÊÖÀtðÚ,ŠŠ!ä~ß {îÝêFÁš¬.çSÁUu¯nòîeVÅ——íQsØlÊ]äÛûk`Gè¶gœÐ¹èª}Œd ŠÂo?€•×þ5`ñ"[ë\‘L}ÌLÖjLSy@=SÒ4ãüV¿J#%*Þ$Í.:dqcºÑK‘%{ºf¾Øo£œfö©ê	#«@1ˆFÕ“` ƒ1‘J ÆQÿRÿjïøtáÓ¬ùí®ßHÃ|(Èb³åäé‡ûá¢ÛMõ¶e«ã]¿hmþ Üž‚Ò˜ákœ­¢ÞòåN”Ô`­ä3	ëà V"8ê=bÒ—Ú„¥ÜýïÇy²RDìkiUóÂÉÕ Ð7Pub"¿ÛY˜×­Õ(/¡?n`sð_V;2¯¨ÒGü¡3Ùæ°É&Í¹£l†þz¶…ñª që°ðÏc-kÊÁé
+ÇÒXƒ“ÛœÍ÷µUéaµ¼*4;£°”ëÌnÂ!&+*}ØºîZ6']}aXVÍ‘âƒÑ¾2Õ™Þ6»æe0RTÓä¯¸ª¸åùAÃ0UY’PY96ÙõåÝluñjÆÂ¥¿—ÈÄ·ì±õâÃH#Ý >Õî†^Çx’êœ¾y¶•Ôõü(éïõöÌë
+ÅZ‹“ï:å¢n
+ÅNý©PZ¢6G+/Fn¨vçSHo™æLF¤·ã,¥u¾[ðµlâ÷'âŠ¬SÛŽOÐ/ÓšlÎœ@ ¾í)¼.;ýyEëËåÀÇv0Ò*°ª·/KÝ7¹S8±æwÎë‹“€I“#«‚°W¾ræNø²Ñz*GÚDm¢v“ÙG}t¦®ã%kéùïÁÔe>Ÿ:ÙŸÂe¬ºnÈÅ+Ü)Á¤rm=¿z0G†hd«×O¥ÛÕð–Ë/'Ý¡Ò—/åZèèö)BîH³Î5¢Ç™Œ­ ÑËüí„á™×)Á2¹„OÖ;®%5žÙüˆ¯ÎÌ<q‘}3ÞßNËw‚ôi3ºàcµ»è<F.ôŸf›Yª|Â´È]–ÌñÍM»5,‘gÏÇN7¬Ý6¼òCq9(5FÕÆ¼%d¯þÓJb†ÍŠ•ägš„~éódEåÇ·¡›T®.#{ä¯&ºP€Ë‘—«XO\˜G£¬‰ðRüªÅWu¼Tàyõl“©MÖ-\+Ú(qÐ„ˆÑ(¬šñÐíO£¢'0ïa¨³aš5ÁÀ»þc»V˜…×R_q«¶¦h«Û»ædUv>EyÒ÷dë›ÌAÜŸ³˜LoJ|?Y×é+þŸo$cù*ÔX1½I˜™Q#ØË¤v‘éPrèÌ&8cKïÌDQÑ“ð"ÓB{ÌêGmëHQ)g±ž¯™àb’+]Ëô
+ªZ¼Ê–\±®X–¶h£ÂìA»ÌëUoæ˜Öö)´$öì"ñÒßçÖJPC’ÊC`R³H’! ÍÄ:0!'	
+ú„Ú§E{Wú—Cwü|Ø®K‹{®8h÷ïðåÝÓxUÑTÿv9‚9\éS{±íÐààÂzj%#ÃØ/l'QËì–TQq:–B¾^se~u€Ó+"	%¶­Ï©,÷‚—Ì“}'ÈñH1 €–€dH@ÍÀ ›ºÊñ‘žü›8éC÷ÊòEçZë×­~gp}/ÌÛ¸®ä›¨ÄÝ‹f6lAœ½ÝñåÄ—ßã£ÄÇ7NþÚ­Ûg"‹¸I_È. ?Î°$ÿË¸f:Np(õÛ8EQE‚@eÖÂ³EÓ¤0/h‚lpÂù-Nc›z“Ž¼ÒWx Ëº¤VýS·Ü¬ÔÍ’>i6šU)ot
+j¶°ÓŽž%×F$Øå=QØœ8Ä.¶K‰v;®ZO1¯˜Æx§è‡dPÐ€IØ
+ € ‹¦4…`M%ª ñçï.œÆ©ºÐ€âÈt®ïÇœ)6GË›®Âa£^¸¿Ìîê!_¯Z`l;ÚKNI¬ðÂïKfn–±áÜ¼ö1÷=â˜ü‹¹ÅÌï‰W‡ØÅ6¶ÊÏ+H2'M—!Pu"ð¢Žež».s0¿çW«¼-Ýñ~Ê6ú¹Y±:Ò²…›yk©^–'}­ˆ–hOFØ[—ýñ­µ>~€I¢ž¨=vsÌ¡f“Jˆ1ÕlF˜Iú |ç\j®²¯ù …·.ƒ õ?ÓYánºÊ3áríJrëª#Èß.›Ç‰ãÄõD|?µÂ1XYI“¿"n›Ðú«9·]£¡&£1YO8zæôÆÔ ÄûÞ»øÇ¿~ËàÙµÏË|¦Ó¿Ïtüç‘ÿl!çÙ_˜ÏædþŒÖ³é…“g<™<“%y†¾ûÇß¾[ë•G²D“YT:5áøÞûNGˆj—Óç1-"È½ïß×¾Ëº‰ŒBáðóòÕ\ë¡v•a‡ÿü™ü%ÿù3*¶ó'`æÎ	2jŸàŸßãƒ?¿Ç—°j/ôrþÏÔô×ÏÿgïI›G’ý+
+¾ì--ßÌ‹ct›˜c`™PèÄjdÉH6`&:bÿÖîÏÙ_ò*³²J%YÌÎÆ¾ÙØ˜6:JU™YYyçôO™€æ8/‰çìd_Ûø	õíÁJµˆ=îÃãÛé³1ÀUÝ{Iå~˜²Áù°?àdá~[CØNcf…ï¥¦˜!‰µkTßdE°†«ä›'½Óízc¿ç÷woÎOªw}÷ññbüpg_·Î?D9MÒUÝH¨8Pä…¹äÏÂŽVAHfãe0„]Ÿ¥ÿˆ
+¡Rð˜{BR^å£”˜ÓðKûðð¶ÑšŽýÇym2:ónjýêåõ9=ë{Û°»w‡Ûï+ÉM°ÝîµÃ6šuÃÑk6žÜžZ®¡û~­Ùìzv£]·iûÈöS l,åÓ1]ï>;¥‚€çOÞ#oãÄ¢KÆ7V†“ÂŽôj]Ü„??ªÒ1º‹~ÿ@ÁGüøäEÓÙw¦L³ <Ú²r%Ïè¦jñ`SËÅWá‚:?„ ˜pÞM;Ã3Ç	ýÞþÉŽL¶Ãƒ›ÙU­ëÃ;w·õ4¨OÛ‹»±ébýø¶€‚F€Ù¤ó)&J†J˜·oY­?üæ%Ýqoûò2²û{çW»WƒÁAÍz:Ý½XÜtW·»Û_üž}ö!G\må&Œm«Äè#x†Ï1jMÞ $òI0ñ„'<^¼ƒÑ}äV&“Ä);à+ü\í"I°jñîW¢ª:/µy¤”ÓcrPÂ%ž†ðìÈ”8ð­Mg†Íy©]X³pŸ8$IÚ²MªXUVâ€Ç®-É«”±K§Æ;Ö´vÁ”¤wÖ8º·½ƒ­ãGk~|×»ùö:³{eôÒÖÓŽÕzº?û[ï3ãÈ2W/´´ø£©zyaU	s¦úu ²ßD±Ñ(ð’IjNÊÐbƒ¶”`,kû!¿N­‹Ó–³çÔfçÇÇÖé5û¼³oõïÎÌxq²˜´žNC£}XéÇ€§Pì•§…×4n§©wÛÒN­É¸nivµmµšÍªó{iá°ùœ4ÝóAíhºã}¹JGCÿX¿l^ãÑö×‹Ž~pà·æñ$-¶n`?O©2Xd¡×ÉšcËÒE«Æ{6À#`ÕºIâùTÝ@¶K™ŒÁÀËn²]˜2uœ=Åv¯w'lh"í‚9ÝK ¼ÉB©Ý¢sy¦½ÇÙ‹MU”º+é|2ŸSÖhïmÎ¦­[ïÁn·O¶†_ë¦õóÁQ:íL;íÛ©Öï'ýæÍÖþÓQØŸ¿ÏÐ?‹çIÿÂ[ªÏƒÂ"72.vp»ƒé°¾îÛP Šòu­–Íd ¿j[õªßh×A‚âI®) D\êk”>Ss\‹¸’7ôšpô/‹«‡ï¨ó¥Õœn;wñSäÝºmëiêuCóâ4z4†ÕkR,®7&r:ÎÏ 5ãk2^oœ³û´]ÎšQä–´´~Ÿm‹ÁàKÎŠ”Ñ]Sv¼0j]¨¡†H­À÷°ù"L:F<÷r·ìeÑ[BBM6fÁ”pS•ãqÀ™€w¨ã¥Òò3|…<f&ëÎÁ¶]	xûÀŠì4D;S¾š§Ðš wœpˆƒÉ<lS‘_ç¼‚úiðšœ.uZ=_j«¸ U®µ.˜ì6½«¤ÒÂ¨Ë«µ E=>Î'‹éÄ-ö5Þï ‚«e’£ôô“ÆÄºÊ'ìE‚t ±4ŒHªh=IÇŠ0ÀŒmöVÀtñ6ÂÃ8€n&‰§…jäc/ñÀ}%ÝÊ|Æš!@ÔsKalB°f³$°%m“…åë¡êË ¦Oèì0 *Ä-¡?t!p¸vU«^Y8R–•³ü— ª‹<âV§ÜÓdþg€"0Â Æ,—ÿ£)‡¤fE®†5‡ù-'Œ#ö~P`š›ÄSÝ"qÆ˜ãD÷L›qL‹q´´uÁ¡c'¿ŽÐógÙ¦}®Œe\1&–ÎCÞRµ¦Šn`/ß\å®…-`ëCÜš2@žWðNÇLÇ D¾•Äªh;¸…þ4¢ƒ¼	Pö‚g±}¦¨ï1…Âáâ“6OèÞ,ˆí!±e«hÃDýÄ.ªäm†ä„0šÆÙ7ã(dƒL=TË[¦èOÆÉð%°Îè°`…ˆ7½íe¶× ƒD	3,|¦Â€ëqËÿ)Õl‹MÔŸGÎŒ2k<GBxiÈ	­”3Îz£„§êL±Ðí¹sëÍ*‘%Ô„«5‰×¡&xr7{1GEà?ãÝà™M	Ÿ`C.–è%C$²^ÜÑ°áù wI)ŒžJÛ\°õ— ß^Wè÷ü*¸ÒƒkíRXx“ï’g_ ÙHÔmÀ„fHõ¼ã¨G»Cl]Ø.¸O`ƒËÜø±5ƒHœ²Ô<—6ì±ŒÚ`ûñ‚Óƒ}åGFÍ\¼{IíÁJñÖúø!€Žáõ­e|èPÈÖLx‡/¿³::3Ö_äº„ËOo °D\0á÷Á¥ðk¯¿æËts­ÀqÊRý!po<ÉcrHãd¶‚Å”>·öy5b/jý„#I`-C®ÃÁù“Ä<;&N æˆ‘=?$Ô½ Gl„¾d2‘Ú`ŠZ2ç‰|/2œÎÚ„k¼ xø¾ Ûæì^¤Ú—^Yò†€üj’í>G²ð}8:œå„Û]›pk¯€ß3d›ÛÕÔ;°\6^ñä: áïHy3:øk¼×ÒhxÐX€TùoN£¥*™Ðð?@BÅJß×y«Äk^¿ûÍmçS»ÉR
+†è±§tv@P¢»×Dñ
+º=fÑu
+°dóPüT*§àÃñfÎXÚŸ—­Íy©g=K…ÎÕæaüØ9‡ÉýUÑò"ŠgŠQ<ËþòÀµÜ$„u‰üd1ÌcªÊ¼2ñDæ€â$Åy1aòM¡ŸÆñÓÙ¾_}Šï÷Žë{ÕÖe7™ûOO~ ÷/þéi¸ãïíãÅÃ»Ì_˜Èæ‡q\”Ü"÷Æ<pMfØ¥`šÕJn’ó“]{"¦Š!l¹Õ¯&œ³§L³ZÒÙóoI?»ôž¼£Ú¨óíë¤{4ºôÛÑñ¡×ÙNGzÝvŒ‹ÑááÏ[Çï3x#œJ¢7DrÜW”\‰óDC‘lò 2l§ú7qS04øÐ/Ÿ®£ë¨'œþxñüOE $[=SY¼H›X.Ó\fÚßÀM‹uø©À QO˜RÅ¥°ã¿ÂöŒn'çÿª
+àÜpÂäAMÎîÄÓjÞLº›Z)²w&l¢Gµ¦Ž±•À—ùšø7u6ú/pñpxº³‰v~#ä±dŒõåfð˜Æ˜˜Ð0ž€k9•sñ§ÛZpÆÇSûÙaNìh²¡=aÈ@32À>N‘È¦äâPº®© Òfž5‘\›Z{ræz4­Üœf@.Á_×Ü¯ÌÛë¦)V
+g+ðf+è¢Q}5]à0xtˆ‘³èé7Ñ	4zfýH2`XÒ±é4;ˆ$9d­Cx!’ÅA)Œ&ßB´B†PøÉ~÷ Ê#^ƒQ 9Î¡QÑ3I1–’í«ˆæOo¦8O<†3“ç4\t.xr¢1@0I¼P”êåN·V*†«‰ÃôsÙ¸…#½Ð7¸xÌÉˆèŠ+êÿ­ä‚0B2!!&ŸTaŒEv˜û® c6q¡ûsp›sÛ.V
+ÐÞ$Jà(Äw6ÈÙg×¢À&P`/*àx5BËé®«Ò]›lo$1`”º’üÏñ®|Ž‡	$Ï–þ ²ÿp"k(G£ëÍ@:^±5U'tšT¶‚¸4,~q1®7†$éãÊÎÈe1ÑÜ41·Š6R”ƒ•ßòTÌ%žãUÁ‚#†aáVBUNlá)ÌíÑŸ–éæŽ@Ž¤´ÚÚÝ7£Mû³0	Ž¿p|¢“q%>ÍÌµŒÕV£©_Ä’ç0TÉv284ùþý÷.¸–¹ë±ŒÁýsgrËx†n/Ua­ä,æ$&>ñ_/±ý^Ü‘0  —l5ßA}‚©üEQˆÞlž°‚Úže’—¥
+`Øhü5%ß·	ÚŸé‹b­Íl­\ïZ¹Ønõ½‹XsµïA­ø$-÷¹  7ÅîL{õ“a|_7†;wó“ËÏûöc}4u·?Ïï»¡ù´7;¼ÆwnÿM~o7ø•W?zm¨¸ë¸ÍvÃÐ«:Ô¯nùºÕjµõN½Ó¶º¾×´ï¯~ÿ¶à¿á¤µ»3lß_]Üìó{ÿqæÞ^xÉ±qt|ÐH/ÎÜÖqý*ò‹–kò¸ê¹ôÇx¹ãšA–µTÄ€Òâj›S/™)YGß[GA^G‹I<mÔfÝjtº~ÇÓkõFMot,†8·ÓÐ»f·ÓêN½ù{Em~k>íÝ½­»~Õ>¸¹³qóÌ³o§ÉÞVçÆ4vþr7ö§{Oq!C­¹†%œAn«¸©­l“W@ZµiMµk7cN^šfõDG›E5ð.P„XzfI •—LžvDÁCMeÑ¡˜¼uå-`>àáåm™,£ÊˆhŽMñ²‰|]ÍÙÉÍ@ÊöJÌÊåÁŒ%Øvµ®7jnSo´Ù:mßÓ»ÕnÕpí¶cWß_©øm´åîU÷íÃÑ·æ]ëçó«Þçt~¾=Ý;
+»¼=|MÎ†ÃiÒ¹,c
+*,–*‹ª”YíÕDÖy™È òd‘Èl+œ×Ò¬j§³ÜlTMaoƒ©¸!Egaöe¶¸/N>HÝóRéöþ¨vµçªK•>r<¢«°…B¦U,¨Ô§Àù•„>÷¼‹@R+¦P¨FbyGRv¦o¨oåeCIÍÍ¢$%“ŒÍ¦E™3ÒÝ|Þ¤&—¬TþÔ´ñnYŒg'DÐÊ+œ¼Fo6ŽùNeé®vƒ“‡›©8ø:­FUdoÉ§?¥Ðt[ì¬IÍJ·ãáAupñóùÁÙÕöS»Ñ¸tj­á¸Þ¾_Ú½Îíçáx4Ù_ëKôQ?C²èµƒ‹˜e¹†¥·lU“r}3kzšipY"á§Êa2Ôl!’Ntž9'BëÌ»¹— ¿Í(Ñrïo.[8ŸdÓýxh®**¹Ê&r =Z²a»›Â‹m*6Ô._	Ìe¡lS²‹ÉÛˆz)áÛ²™æ%»dKøMlñÆwòÿ†Ö"5Ãàúƒà$ä–h@Z1ãlµ<¦Æ´¢…©v¹ŒC®	C?ïÆÍˆ÷Â]L¶U‰«Z°E/²Ü“?y{pÎ}ÿéÔ	e££Þ!Ñî¸F?¾ˆÐf–_? Õ,¿"~@»Y~Eü7ÅñcÜWð>ôïXÑ,¯/;½íú#«Au'†ÃS~R<yªýÕ;9ô÷wè/*d@vú§ƒá¡@UšêÛâÒÉè¯íÓÞ`DÈ6îæl.âÊÖþ°ÿõøŒMHÌÃÄLŸÏNÄÈŒÄL–æ3ÝÞ>Ù‚y°Ÿý!ŸKé“~ˆk÷VB¿Î{'“Öd*0Ù;8¢û·¶ˆ!øºµ-EÞÊÿž?ž5¡;ô–Ke„
+ûô+ˆDvÒàpDØ»£éß”þ½)náÄ:q»;ç¡×˜×ïú£“ýýÎNÔÛµj·ç¦ÙMÎí…7¾_v7ç‚˜ ² Û‰%‚f£¬…gù]è„Òµœ¶ÞhUÝª{]Ý·›®mÔ;ì¯4«+Ígª×±âiâUxŽ‰)SÆ±CeæY¼0l¡t¬±Ô0!9ûï¨${ò¥¶3~ìƒ“oÕÚQ÷ñò¾:6÷ýñø-«—wº·í{
+v—»øÔ‹"-lìŽ²eæ¥™pÀ	{a(„ºO¼F4WˆbgÖÜãYÕMØÕb"é’Ÿ7˜¹ÊÙ*ÐCîA¼LCF2ECé¾#¾"Ž¤¬ö™ü°Ä+íj¬Xí@q`	«=ÒY±Üåâqqpøò,¯QB¢ºMñUùãN)Ï‹*æTÑ#ü Ê†hŠšœxßTpŠˆª,XË„“•Ž+%$È…:rfJ	ÓÄC_‹Ü)U1>Ïˆ$K'\	(¬xˆ!Z\%%®”­¯Á5¡åuÉ&t·L/¢	È²'ÅÁs´§Œ“çû_žø¨Ä,ÑDâãe<óƒ´ày(žÉƒÅÁ6†ˆ¬Êì ÝŠûÑNþº©Ö¡9ájÇ˜!†ˆæÄø´BÌæâs&FÕæ”¸j¥N6 ˜µRGàïÃÆÎÀæžðœÉ
+‚ylD-¡:aý™*-#eÄ¾k„¸¸rÏ@%ÔxÆSx)UòcùJ3$”|!KÓÎß1s6¢ÜÓØ=Ù2˜Yá¹ Žîæ'­Vý¤ìß&–½¼ücùTê+†§rxÕ5`§úFBÙ™Å¯˜jE°!=ô]I[&DuHÜ&•—=ü¯¿ÿƒý_0v¬íK×ÿÉþ!¥¼0PœZ>Hj›@¢ÀFåMÎ^àêM’žK_&êå$¸3êÃÏ®(NnJÖ±«Ùã‘^é8Y„%Ÿ9óÂìlSÙÔxA0X®ËJxã”[J*9Ò«‰R2¹×¾óo+‚Üz¬ËE±-W|‘Dˆ’FDÈ”øÝR }çÑªVr3—ÚFM(sô”¹ð¬ÄÄ3¸W«\o«Rk"[ª*@9æ„PïÑñ¦¹°z<OL®ïISDùüùM‚~ýU“ ©,ONûþ·lM™=®R‡<znqÊJ&•ÇrRô8+E	4ZÂBr½ð–‰QUa@ìVQtBeßË”B ; NBö“G­0p‹ºtnÏà„DŠØz† ÜÚXoFv!!YšLmjáBqkmŠ*¾‹ÊIwµüÎ-9j€˜FÁ5ìÅªˆðÎÁ‚-ÊŽãÐ³¢·íIeªÅ2Q˜þT4’5Rxû7âv¸ÁÜ£<D›6Ä_ÿú×ýÞáç³Þç¬Ž4‡ãŒÄ2v7ãkûžÇhí\WVû³%|fU¢Š+[UŒƒJÛd—2±
+ñ4.ÐCM’j_­ŠK°?©ƒŠätÕŒ&Ã>-
+7/ó@”\äÚ&ûòÜñ2KW}WÅ²,)ÌnYíƒõ@ö8/³T3:Oé‘G 6ÊaQ1ÔÆˆJ
+®£²)DµÜm3SšKkrÍ¢	ÿE~@»lNràú!·M…µËDæ¼Â˜—šEm*œ7vQ«ë~ü`bŽ•Š“l4S¹Ÿy¡!™—O”lTú1á¶à2“¯nS,¸D7+ÍkAE$KZ4«¢˜¾bNT<zæ³P0VÏ³·4ÿ>-B>ýœµü»ðÛ0õ\ç®dèÈÖy/¯¡PBº)Ù–R1ž|¾”º”5¿`V¸–ÌdŠÌ«K)3¼Ù'†³t“žÉ›Û¢r.Áï¢`§N¾NF£¢Þ&ë¨Y+µnÈ{+¬Mjg'Å¶%ãF“!"WM5!T,›6DæØÛ-„ÂŽ$îí)0q½?¤âßG*Ý²Þ,øÖV›	þRî¬›ÖÀK8‰rk#aã‰Ã³”ÈRŸKlDÄ-”°‘úG±¥ÒaÞþÿïãËáç	÷¯ôèøV­S5º5Ýj4[z£å:z×q:z­æ7Ú×°ëÕ÷‡¥-7ó“ ãÜ¼?Ä73I/£àf¼QØÁ–¿8¶ìãÛpÎôæþN?ØM³Võ¶zèß.G¦ShíÇ¾þ<Åñ«…-zHå6MÚ+dyèž¾D.†}OxM2G7]Ós®óÜÄ_tá¨Åó…‡}¯SyßË|8K-ÛÃòK®˜7ûyÖõá|“££z	!ãÝ~Žð/}„é9ÕJÿÒ>šßÏGÓ|ƒæ0Â”y  Üÿúû?´#åšâˆ`OB„#wEüáïyÞßó’¡AU^
+¼Gàæcì%†k<žçv¡0Ç*Z”òúÏ‹(ìH	±h™–	ä€­âO…øÃ´¸‘ŠŒòp¡¬OÙ•ïÊŠÏªnÀ>ÍU’î(êPÎs ö<¾¿!0*nÔ•B$œ7µ–ÌÙLŠ1yØ)6²‰’d+Rrùÿ¹STñ–Y*.˜ßršEz(Ÿjõwè÷£Jè51œÞ¼M°Và#Ší­h‰+nƒz;§9*[ReF/ÉŒªIEâ7ò~äbûÛdÓ
+¨-ûÎ(Q¨VHM£%¼ƒxÉäMsmú5£ã-CôÄºeÇSÝ*OŠñC|®2”çd-ÐR²³gn¬`a¦Sö_áÖý?öÞ|ÉqãÚžˆùož‚Ó1¾v-$v´âÞ¸­ÖbÙRËV·d_'	 QE5‹,qéEþê‰æ¾ùï>ÙœÜ€ÌDY ‹Õ‚Ã’ŠØr;ùË³þÅYŽ7Äœ)ºëùÍìÝ5SìµêèbCPºÁU²¿F{Þ8""vÔ—ó÷úµÍ®l\Û‚„K¶ú,^¶V‰›¦‚ªó‘K6’yƒg´†;5ªˆ,óÛÍ|£h†n@¸Ð&™¹.Ë‹3cUô›Æb0Ã/LÙ­`Rë¥…iT¹Ü[Ê4®ß’™L_×:á‘ÒLCw5w®ÈU¶å×·ÇpRßcDÛx95h|¢ùÄjQkÔ(%o¿[Ó,+k³ª’01[ñ”ATò2}†T+Tëÿµi¦5fgâFM²~%ëUu5Ïò-W½!ë7° kŽ¿8u»²Žptu¹“.Etá§¯i(9Ñ¬f\‘¨éa9ìØ›¡Ë©Þ7úù-Õ­Zm
+²Øâ:ýVí±J/ë<9×,Óë<“bô‹ä^¦«m0j2«×<~ÌßÐü'‰‘¯ñí\]T)hšÖ—ò3Lf
+®›JÜþu¦y¸Ø8Ý—J>ÃáâÊÃEáHÇSe<UÆSåqŸ*©¤½Y™¼ú€ŠÉšVÈ®AÂvÔˆ“F[Só|1üŸ1-êó–cGéLû±£¥^Ã´®HTÇ>†\vúó‡ïfI_eóãÙ3ž=ãÙó8Îž{`ž4:Ò¸ëÍV„2Ç‘/Ý-™GEíâ²PâõV.7ÎŒ§êMOÛøUlT©Mëß¦ªÍt‡†¶VsÔi±¥Ön:Meïy¸ÿïµFGxDàÇ„À¡–nÍ­/07<Õâê=ÍÊd¹PTìF|Á£P±NõÂw
+Ï+ì®´eõÞíˆF%2Àm‰ˆùÐ`ŠpÜ¦é¿wÈ€ÞfÓi^™î£üC¢šrx¼ÌÆžMÓŒ¤O„Á=EÔ6Í¨¢§ÖU£MP¸|ÕhŸ¨£*Rà 4h‹Šù˜lhÐPÍJcVm=>#ÚTW0Ì¸WÚ3~»ÚA•¯ãOÒ#wx\,u\Ìøß—ë¥®Å6ëc:F©î«šÌÖòîé$7û£bìêYÎ­h'à|Å|xâ5Ë–LK—-WºSm]ÓôéÄÊ".ÑU»cUI´^0GË«Y5ù5ßÓoê„îýü¾É«–µÇ—l»½{áö
+ôæöO¯Ýw×‰f†.-²F˜™!{ÄxŸ©ñ¾88šñ„HQuoÉÞxãÂLú£ù=2ë)š?›éS8õv9M¨÷)#þoG¡@*Ü“å®òM5½²3IÇ}·ýðcó²–C*è•'q®SðYRÜÆa©ÇzÊ{Íj§‹Š¥¿:&êEfRÑò½ã^2DHŒHáAP:—ÇŽ£Ôq1JK7Î\/Ë÷âËÕbD!|ð«€™›Ìûìžñ/üâ»Ÿÿüúó¿‘Ýßn~ŠæÑOoüö¦¼ž¿úùå¯ßü]¿X}¿Þýã÷K#þ%¬ú%'´Á£3Ï{zGIb{Xð%ã‡&*Kª~öÉU–4‘.Á€‘.¡%M±çb:¡Ê%2bZÌÇ1--q$æ{uÉþ`ŠÍê†4Gé–ðjŸó~Ê•»Œ‰i6&]‡ñßWý`÷W}ŠØ”Î‘¢¦5Ô\@q¶&>Pe+¾¹ê¼ª•p7_.æK¢nQêA|TÿÕâð×ô= Â™È}lê‹[YBIFK‘ü%¢­*´-kŸ›×4.·Zý€-ð9aÇ5`U†ÚM»1S6—eâúuËpfPÞßÃÛäyÙnCÆbç*¹ÀF3Ýg—g¦“£˜éÄðG3Ýf:A÷Q˜é_eyíª5½Žwþê”ýÝ¾FˆûCÜè‰0Bœ	qª¸ã+.\3|%­ÊM7.xWÕ›é¹zþi`ÞâÅäšú&Kè ÅÕ'}õIÑN#Ù)U Ø½ ¸æÎû&žíi"Dd-ó¤=—ewÉ½™(¥×›iÈ<j¦ôì“ô¢fŒB*[÷Ü„‡¥äl=©é¦Ñ¡sÎ^Ð§O:ÃN&E$5Ï±×7Ïqïƒ¿~ÿtv+[åcówe^>v—WÙŒk™´ÙWs]«ÎŸçúÝ‡žãNîí˜é“C³eß·¨FU;-ê´Óê³ÿ¸ì´ûŒžº–ê˜^®ªiR³âè4Í¼ûMµƒšÿüÓ˜U†O4¹?aä±©(L4‰ªÏ›Ú~û®@µ ÑÕJØß WßÎ7@ÿò¥ëß‹^áÅBÉŠ`O?Ãã€?jÊdvHŠ¸4ð]?#§(RâE‚Ä-Ç+R7JP™+èå$)âÃØ½Ã•?~ñ2õ~ù.Ê_÷—Íßý¯ÓŸ®7?~½z~ø‘D³×Ÿÿ1Ë—ÿøã‡U£hOKF8¸ó¢¾sHÑžÀ’Žé¬e{6…µ˜¦LÂF;½ÒÌ„f6âùÏl¢"ÕYDWz!ëYrÉÔ:Q®³r·X4ç¨Ã<N2	÷±‰ËC´ÞÈ[ÿù&_ÉŸÔœ+“Þ·ðçä?ÿïcJæ%Yªa“y	O6\@ˆ‹7b#´]Uù_õoTÁP8¼(j®ö£+WÝl3E¼Õ~‹àj²%—`Šõê¶Þ¬Í+f€^=N=YûìÕÉ¸O–«îÔåæS\å/¸‹œ,//±}òv=_Q-Ÿ³ÅØ5mÜ¥Nê…ç–³N¬'—Grn˜vÁ]5õr{ª#þ¥öó¬9ãö³aá­Œ‚äœt×›ZiÕöâa†RÔf'½ë¶{=¬9©¡à²3a]%t& éyºLFí „ñª*—¼–×?Æ%9Ü²ÑÂŸÆ½ê˜´l=Vûô!‡š;±WéOÆ|l£„ôÇïññddó±]j>¶=§•îçÞyÊH™5N%€©>e„cÓ}ÌÈWmÇ@ªº¢æÝ¾Û^W¡ÝËÑe«Ö—‹Îo=f_{n'i]{þ²©C0VXSÇÝÇqÅXÆWªŽï£[Fe©t/›S˜V¸-’‰¼ä	Äo	3÷l»ÞIøË.[Ì7×BÖKÍ'K¼ØT´ñãò¶~zŸÏþ=ñêÊƒœ:Üv÷ÓSãå£r*>zŠºÈ|qÇÐ
+dÉ7gˆt»òÍµ)/YæF™f”iF™æð,sGgã%Ü¼Ê%(gÍàO|FÚ>a8òÂØþU¼&\“Û]ìXk×Û÷·ÁX6Ê™ÃXž'/VsÒ6ª?÷ iò,‰Æ)ß;VZÑF[:,mfNˆ…IˆeOq‡´mOeE÷vÅO6}fpïT<ŽWÌm}V—í­ôÑ¦ÈÐ›Àï¨ã¢åƒÁ¢ï7]áhÓp_9DÑ÷ËËwºñ‹JÇgÑÍ	ùÆ„|Ã'äëÈ¤w/Å¦iNaýØ²õ&blDP-¾÷F£&1«“üø°`ÜúÇnýÚV~ü’ÐØþFÀÂ`¼ýÑ°ô’˜ê-Íc[KsMÒ6æúñaÁÈJŒÕqð QÒþ$½zpO­pÚÈ©ãÌ)â8ë®X£+‘ˆ®ä¼»\Ù+’²%½jkò-i®5Ç®™q×úE8F|[VlÄÁi¹è´n®WïfâÃóå›JÐ\uÇ	¶Ž[1 ‹ùË/DêG—Àëû}#S÷åÜŸH°%¡-¿`ï0ÈøaŒVfìù³PP6‹ždäCÓ^l7Ïx\ØüY$6Ì ‰sÃöWÅæBõê<_­˜O%
+uzÚÈ‚&–ibÉS«ƒO;Ú·§’5²Ñ:,¢žVZö
+àLcØt^R;áâàŽRe~K¨ãÁ8z3u²ã}iíÉmÑã6:qòai}ËAÅNš‡¡Dnæà²·,ü4Î=/õ%yñ±ÊÛ/ò›_¿._]éþýOYùîO¿~x-þôúÇÿxý=˜ÿ´K’¸¸Z}U~qe$ñ*f -‡o „ä»¬Åô?‚å§ë²÷z2ÒÙ{3Dºm~\[åÛ6C%ZÚ|µ-m~#¬(z¾¡‹<Ûü² ê{·žkî+WÎ1÷> éJe¿8~)YX¹†ß3îSEnÃ;Ïoo¤<anË  (p{Ì«Ü3¯òÁSžn;kd³J}¯€‹Š¡Ûk)iwZ²¹(Y’,0}ÓË¶zÔèn2‡8„œF…w‘ž:Ÿ…±Ÿ¯ãÉ"§t/Uÿd^ªçK¸5zŽ†½‡áÃãÖP†mQSªaWeÀ{¤˜JZKd”æ€3FEõöJï<Dìéqm^ž(<‡›çC9BV‡M‡ýQˆÇ9Aî·wõ³5ö°Ž]˜¿ãhìQºSÙÏ{]˜3NÜ*ŸøÃþðíó—_ÿøüë/g¦¶î±µéóØ^ƒæos1ø­nñÑà{~¯™é€d
+r%ˆÑ|âáùÇ% >ú×‘ß¼‘a»Ípq`¹äî4Ü¿rÉ÷wéãbLè>!Ïß>‡’Ã	¼îë^g”#J³¯Ðãð†YÄ²Êê$¯ÈùÐ|Zª[R« #øNÔ¡0a¶díÌe—•ò¶•CÛƒ—¨ULÚþg{LÚ”ª}d¹×‘Ì½~Ñe¯ÏºVÃø€\O6=ÝÂÄC!vc'‰|äe;8wC'/C„<7õƒ\zœÊí€vw·ƒõ{ÿüïÎ7}ó§ðíüù‹¿þ°zûÃ›q|ùáÅ"Rÿëg_{þÒû«îvòN4’}„,ù5¿nºð^[™XÊ2š>Cìû‡zx¼™ÿF¡=¥ÂuÙÛÍÀ¿l7”˜‰Unlò;ò°Þ÷ö6Ø›'þ#t7 óÍ9ªöSKžxÃÝ ÚWóJé»]mñ‚½´±xªIÞc“Ëß¢SÜÖßÚd¡ß™iÎXßÐ{¸7‘.ŠþŒ7ªéáÔ~2Aî'þ² zdÛ_n°2Çù­¦OiTâL@|Ÿ8Oôù®åüŠÆE/z<‰ô¥P4l"ýDH@åÜ8^~IWWûÏ›y×Ïç?»³è×%Ïš¿Ú2ìSt_í*÷Añ·žó^è¥&J6æùr¥k~yÝ¤p_%J¿!Å|w£v›Sâvû¨ÄùI¶Ö«÷³èK¾ðdÿ²›5 ]àò[÷ÙYÓ½¸îé)ÞëóLSáYD-CW¿5zíðÅ¢iäy­ø|IÍÁÅyí<|^°#S®Úõ¾•ÖÂ®÷e4Þä9ü†¡YåüÙGÆ«g 8øÜK\¹…n†éfØq£›ác¬r3LòpbÙŒÎ„š3á°G…ãMáÏmç…Ôq^ÈWÏp^ÀD}÷Íw_Ž=.þÐ}ÓÇC£#þF$Ã –²@NƒüãMe’¥Òó”¯ž‡m~%ZpDÀ!JŽXÂÆIÀÜÔJ{}3fï¾s¤ËVaï€ò.#ðÀ7ßEß½
+µ—#‚;¯¡ÉÕZÖ»k¸±$Âì<,ô6«ÕÆ5yu“ù!Ð«¿yŽÊ34)ûíb…‹	w¡xDà%Yè‹:Ù
+›ñæŒ•¾º°V…Á†‹€l[¢«z€íY3o°	¼ÅmG´ÑvDÛKA[¥®¢êéäë¡x†‡g´®@ÚÝFø#«=Rßj©Ý[Öuenï7ý!–VöÜ ¼V±'W¤ƒ«š}™¢æS6#ŸþóŸâäînà€G ¾‡ƒ‚Ï`v«‘Ï7ó:Ì%e+$¯qªbîù\¤ †±É8eÍ–×?‘«#4 ®ë:Ù8íÆ¬Î1GgMØ.ý¯ÿÎPŽÿØ²o,…Í–»²žç¶´A2Sukf%¹lg1#GÀw¿xÿT…Šè%i:´—*ùJù¥JäTv•*1:Y©’1'	é““äˆ²E÷ð²ÃÁåú]"˜>IƒáÒ^+(!\#Œxp°SŒfî]IùìÂI\eÃ03‹·Z¦y9å±lÙ£yRÌôJÔÇÛ+÷.3’n™ë¡‹›Q©øåJ¤£:c•wÓÓß7Úmhh¥/ÐÕTÚ¹FÊªö¼R2°~–Õ2xd¯†&.:µß³Òà…Á¬É^‚ºÈ”z>×E¤¬‰^è·¾2Ò«’J«ª‘¥VÝ¥è`[92–°%“dnC’j¹Ê~6*¥õØìÔÑ¸u:»H­O2v·<¸>þ}ïö®5øÚ²Þ=¶¬×¾emk¡nW¯}»"5}Q½+;Ú‹»¬ÿS?5¨W÷’ù=5•­ºÄæ¬t“5«dÄä7”€ñŠÏRÏWƒ’J­«JÕ3"OLeÙ`ëuóö]w}˜ÌB¶BFcf¡Ï.0³®@¯‹ÓÞ§n«@G-B 3úf\tS£‰zR49Äžj{û<nÚ_ŠŠ9£ÛÊgš:ZMG«éE[M{Õ+‹ÜÀ–;åœ”5)+ SNÐþø¥ÆžÇÃ™ãÖ^<‚×^¼º¢›9Ž=ÓÖQ'îPÚkçÀ¨„¦b½šÓä½óåÕ¤n|„ªªF¨úX êì®µãTÊ¼k'U“#:è4¢ÓcA§sûÎJ}c›ï,¬N³‡ì”}Þ²Ze›&Þ4|FCwwiVe£J’Â¹´¤ôÃÛII‘AüÀ&Âr ¬8ªCºJ£È&mF–j’[u.¥Äýqd<DêÔO¨ë¥èôp=ùç?'Õ:<­Ã%<¤ŒLÜW'¨ƒÏ·X4‹U$õbW³GË’„–w7o Ú˜éIl®°Êñ®~—i}SQ"Ä€Èú€®51MK‚~ÖÈ<ï
+ËU•T^ºð¸¢†‚%¹0â{úý¬Êlix¦2:há÷HoÕÂ‡ÒÍ-lüòÃˆb^à­	£”9]´Q$Sç<_4iðŽc”üÌÌ¨ôÁ	)[§ÍõšÒÕŸQ!Ëà´DÞ©#ƒ ªD¬¿íB-û5}é•,Ñµüj
+à{´šP.-K¼DE9zi]lË¿¯iL..™¹-—}xÁÙ×9!4²­[7Ñþœë&Þ(öÅ–ÊH¿G4°£JP9ªôpAAŸ©.(ž8Ä›.(Ì9å.(Õ¡[Ã8)_Ñ³ça—xqê¤—N€ƒÂqûN¹IQº\‘ãkÑy"ý¯'®ðið]^@í©Ø+t3@'ÂŠý=]o6ÕøOn	æEì:ªÞñ
+œT½ûúeù>}ó2qÜÙŸ¯þê¼/ýòçâï/^üúwñMòÚýæ/_ý-yõ‰¯ôªw4Ñ‘\!±3TíÊWê=íì¬zo=Ëý”qâUeÖÛõêfµ%Åd»šl¯É„µÉ\:-‡ZË¬Vªè°¼E¼¨x¸
+utïŠ
+u•;ÚýKÓUžT~g¥à*Á.ÃéŽË”Î¨ãrµtÕê%N2B–‘$eòlŸ
+jÒ$þ>ÞÓÝhÝÇq»!Švm®ÞI³úð~m~ì3
+]°ê}W³Ú-ÝížîÎÙjùjÿùjýÀýfLÁÆì´÷¹£±	Ð(¾l¸öîõÑ×4-§WH·¯dÕê¿ö7²ÈW7„¢áÿÚ€øýŒÿÛ6‡õ›§,Üï<¿½]|¨géñ×m´©Ç”“gQ†Ö¾®-Q›ÆþX¨Ãá£ºø)B²V¢d²B‡DYÝYƒ¼ìÑdwf„›kì<u²›ÑqmWÅ5µ,’=âi˜ÕÓã»,Ôòu×Ãõ)µG²™A¾ÏžüëˆÞ^É¾.›ñì	²¡•žsóðªóê Í¨QYXÙ“çX©1¼'´ S{„¡>Ü|è9>5‘ÇT¯
+DýF ìªo?`4-×À'þð‡?|ûüå×?>ÿúË™²÷0ôylol®Û û¶ØÜvT¸w0î¾sdàèÛCÏ…1vˆ@ZE»s hÛ´Guêr·¼Wƒ8†dŒúèŠúÐôkÁ=clt¯7òÖþŸÉWò'u­Æéó-ü9ùÏÿ+Ï_vX¸[ÏŸ¥’€mûv-u½³žÉídQÃ¤|xLi'¬ÒÚ!êRc(í]Ò¼ÖW|°bà^Zi°7“¨½O¨…i¿øòÕ‹a¸Á“p:¼×læHz´¤%oÏsnûƒxÖÌ2Fû’6òáG^îx-"¡ØüO‡Ýy^§:Þc{n”ó53>Óq µ™©›wFÒˆzãõÈaµRÕOW!tUŸ-¹ú€š»†ŠÛ=øo¶dm’·ò¢¯+Y½œì&&j|ò01±D‰q»yÆs dƒrd>ÛftIHÑ'u}ÎÄBùnËLÓÌâ­þÐwCuw,^#lda¥'ÝfóôýÌè'¾¦)uví‡¾ÜŠ`ÛÅðmV7–ÓÎ;ŒáÛ·ï}6ªf3~·ŽÌŠ­;»ýp—jek<é¯ÑÒæ¹/Ç3¬Q×?tuî$od&±Ó·œpIÅê‘qäuŽ‚¶]ø—Î´#¶\"Øcq¿Z¬6¼þÐÓàžc\HFNîe±”né¤×Ga™{$I|Ü=ÛîRÚopGrQXöžpØÝ<¥)XžÞ`J3g±š;·/¾úþ§2ÛÎf?ãÕõWeùúÛåOøíuðýç/¢?ÿðåóe~=ÿauóWÝjN‘LÌ²àñÔ¬­_+·°™{¾f3ÿd’}˜,Èhó¬6rèX"[Ùo!oaNös5}x#‹Óe‘@–í’C‡s[eÙ„k	ñÏø½¢ÚºLƒÑÙß¹‡_;8É‹5ùµQA÷Ù°
+:[œˆéçàÿÉ…fŽ]ÿÿyî›F©¹¨Ü¼ —;C‹újgýÓ{=Àß¯eWÆ¼1oÁ{4!xë‡$þ¬¨ø`Ô9¯î¸&Ä£M°é¯ª`ý|·½nö²=»Ê©µ•ã7å}©’>ÞKy;BÞy#ä=ZÈãJ;äU€tw|éÇýü\ãe-J‡Ùqw·Ò¥£Ø1uß¨™x%Òû''¨úvB;Ùµ#ÔŽPûh¡vŸõ¹*ýh±»¢†<ŸBž¶'/Ð•“fê$OÍ¬w'N@áRžNJx>J÷ûDÙ‹m]k»+¢YÌoæ[E/ní(-JF\?úÚê]­ Þ®ñrC»+BÕòö(›H«Es¢t=²KÈ=ZV¨gj†*±õƒ¥-¸—Ä·/ºwÇ£{3ºwg‰îÝ¿#Û:-Õð4qØ•¬€ÕÌQßeWGiËÈ '804„úßŠ(¬ü©sŠFµ\¤ŒIŸÜ¦Z²%S€5Ýü|Õà zû®_ŠÓºéžeu,kž#Â~Ÿ{CG„} }¾îˆhc³æ°žãªK3ß|‚CØÔ¡íý|¨jÖA¹bTõÑÃ°äé5Æ1ŒqcÃÇPÅ1çv=lÑ—N!šVë~Uaèdâíf‚±µ+—VËAbÓ^æyõ`%ö4|2˜>E{î@OÉ{¹eÔ9ºÌèÐ-¾€[¹Ý®îJîB+9#¢Œ’/(˜*œÇ£L©-F¤ßÛRŸU8µ‹R~»K_§°Iv–öÄäÿ›ŒòïIäßÇ,âÚÜ´¡Ê¯6nq¬Í—×d=¯çªv”Ï¼#‹Ú„÷¹ïõM¶yÛÏµ`¨sM18N¥A]é0lJˆK
+•vmÎ§zåB³Ì!mWU,¤#…ž/QÚ¿_-W7@ºÐƒž¾ÛY’Y$NNÒÜ	J’8i„‡øA/S7³HÅ÷M–Vùn™Íoqæ¦vF1rïåßýõ‡ð/øÛ¢üêzûÕ«~ùÓûŸœ/>ýUø|•ÿùêåsïÅæÅË—_foß¹îßüº'l=Li™>ðZ<0‘h¾ÞÚX¬Bb |!2hÁgWË+Zjc»šàINÖ[Ø—“­ÚÄè¾×<yì^à£Ë÷èò=ædxl.ßªÖÛ’(À5YV->¿ì@9tæp¿75}BûÏl*SýrŽ_oFú£†?•ÏÀ\õÊð±ú·ºJPTo«±µe÷NkýÞe×8@­q`ÑzÎh•!¶ceˆ††ïA+CQ¢KÿÄÜ«x~˜ŸŒBJf%óVi¹iLrüœù°\`ª
+7´#[
+ßeÓqÑÝ^3=á¼_ÙÖfb#ÔŠ&nõš;Æ‰nuE3k«Ž³­,D¡så‘9sGcîhÌ¹2}³–¶Mî×še³÷+_=Èì©¡%×ç¡Û×·¯¶}ÇÝzÔnU­=‚ü\'NÑ§ù©qáÑ­áKçì¤ÿe…EíêÐ¶ä–ïzÿtQ×š‡=åÕ”‚šë¸êÿÂÊ¿›Ùsvƒ:c(%êìÃ-¬ñ¬fj[¬ÓDä””áï{ÝK¾Öi…âÇaâ‘ìr¥¾nØf{¯ÂS•çé4KQ»Õà¹ÓŽK¶7ãÚåy–M±ÐÒ/wú§t§ú??UfàèÜn0bWŠ¿™¤kê\T5­3$4¼4w¨M©lÝ¨o–Šd™)*ã-Àpá–¬€—ìé1yeD
+”;iQDN€pà¤I8^Fâ¸ôp‘ÅAC¦;Ôc@ú÷Õ¤Xü·çÇo^|þá›o¯¿üê—Ïÿœ’¯nÞÿñåOÙ—¿x¿úÎíÂÉßýíç/–¿~»Œâo{~,R=¨3fJ]Ðá¿T7Ì¼mU|xhC—V\ÿðZ…ÞÂ„‘ Õb/¯&ïæÛëÉ‡Õn=¡YC5æ·äÍ°Zów½ëž5\Û:3¬ê<ÚæßßžÏsŠdO=§ý˜°ÉlZÅQóÐe+t7ˆ[Áƒ%J?•õ>bu2¥/‡Å|/«Í~DæûƒK*„G›ï•³ãJŒÝIKI…c‚CÝA52}â$­‹zxj"×œŸÙnñF HÛÕÀ²ªénµTâ¨LÒk›Ý_ÿ¥œÆ
+ À“RŽPûMá±X¯nkø2¯ÜiA²­C¯ÝOYÄ[Æ×^ZoÙEMËi´í–vy%»­ÝÕ]cŸá€sªgí³Æ«=Ž.ë0qÂ½mmÝ„ Ë£MÕUK·&(¨Ü£¼ÉZ+Š^SíÛ¼†“ý2”÷‚×7TÙÏ´Ó'K¥O}m*Ù¼Æ¬Vª3fµ³Z]rV«†Ã”I:Òž!sê€¨åÇÅ‹›ÄFAìQƒ˜#­)’ï•<U½†é«Å1¬ðÃ5Ì0¼ªÚo¾ø>2à‹µz¦‰%§²¤ÉÊr%ø­™H«¼]ï¤Ìû<ßJ}@j>VâÅF¶þùb•¿~Î‡£®ˆ"ƒ
+óÒœñÝ5!Aºk®õ)‹…e|&>™Úþ…óT ùAöhÄãG<~,x¬e¸È°+Mg	7>™<±€7mŽá‘€£†ÖÜ’ ¿% ´—i¨<Ï *„kß1WóIÉgbÄ¶ÛFl{„ØÆ2ÊÈ23|µjc+éƒån»[«u8`®þù’½Å•áo¶{ÑÆ©×£%žDãßæ3UHl¤/iøµ­þ¿~ùLFæS·:Bï½#ôþæ —î”
+X'×d™W’°ÀôõúIÑÎy`XGáSPåØØ$}ãžóÆ[gb¿×qxÄá‡‹x	 Z-=K7Ä5Äü¸zZ nF¿a¹Z ÂcÓŒ~#²¸aF—¯žáÄ%ÖÐk#¬}|°&Ã?¬QÁw1ÏßpWLéC©g
+QyPOD×ÌêLîZç4çˆbÿ&];õ¾újFëÕ»À‹-žU	ëeh¿Ü,ŽÀ¯¯É[€I%-G$ï°0’QvMjQ­¤©ÂmUé¢X ïßÎÕ”3—\áz3•U$áòÕM&*+¡°¡:–7û¥‡Ðß8OÂ"‹ç[ofÄëN[#ÂDz¤­¡ÃƒCÙ<ÔhdÏK|C&«õ„ÐIŸ¨Ýºwb›fãÍ|/
+1œç¦ûä¹á©Ú`™?ÜÈ°-í/‰jÆ!wLŽÓ79Žæ5.C­,áG
+GWƒ€5·NµcÛÍæ0<6³y3Ýÿ#TÒÝUy[‚Š¶u, TŸ2nÂZ[´âÄzUåld81æÀ;8Ëˆé6¬ÌôRüÁ†
+Æ‡Bãå|uh Cù‹>ö{£­Í&)7g}Äƒlx tH33ý‹žøò‘ù7–ú²¿Ñ®»÷žOåŒµnwmNßN·nlÔsckþë‡losÒÇ&÷hö!ô™¥Ø¶æÛ{ÜQ#žåkªÛnßÏ¹¢†DWžÏc”†pTO\Gºnûc‡ãUÛw.ºÜK€®gë˜µ÷R¡Fòï×¶-Ó™ÿ—ýÜp»Æïì:ËêæQî®ÊÛg“@þ»±wÎú¬p’ò¦Ï8ú^4u¸ý.äqÃ¾gšîåî†¬y>µÎ`p£€’¦¥,’ß0E\¾»­ÞÒiªu×qºŸOë]ƒ_ü‹š<²ÊkÍ7õÃ‚W™åw&ÂÀìõ3*µ½û0ùÆ]1]²È ·î¾\Éü—ø-ž/èžÚV‰e½S‡!Š/SÈ¼a™+ÅÆëk3¼xÇR,×{ºº%ííÂÎþD¼*K6&Š¶ðÏôÖi_}«Š÷uÕ¡Úº¹^½ÉD©5£ÌŸæìƒ‚D‡§'g“•o6Mãº/í–¤jË‡q¨P`{ù…ølý(â¢P}ØÔËáÃ–ùºÎôÞËÇenîŸ˜9’YLeRåXìÔOùût1çyÛˆRUV’–ßS—ŠCoØ#QHéó·²!ßšu¨C1*1“uÑj©£¸ÓˆCú<3Ó¬*Ã‹Ú
+ek8ÞR›÷;>"JO4€ÖFÛ|2alÔ'lÈ
+‘6*W¤Ž3¿Ñû*Ž»tÈìÙï®W³ÍlIÞY³ŸÔY³§,mö”Ai¿‚ ŒK„\'Å~îA9IJøY–EbœÄhÊ7÷´J=å1cÊ©`*´2ÓJ]Go«	´§Jí©HB=­ ›OÊ”ÍßTò'SžF»~¥ì£DÚ¬7W³¤|õ·?þãûŸ¾É>ÿxþâëÍ«¿»éÛÝŸ®yóÃÍËïÍúÙ	²¿~3¹´§OÄ|ÐW38å”>åL[uÿo×«ßm&ò¾6m l÷MÕíÇ?Hûø
+vÂf‚'ã&«r‚	ý"_Ú¦œ¬–ìƒ¾bð6ÐÍ”³sÕTL+4U²kOzNŒ³ñ4»Q}]ÒŠ˜{~#yú¾n–ïÖ©’j[íK}ÈLSÆÚqecò•O0«¦çÝ®(Sž;S%õöÔ<y8!Å’yhA=
+Ú_Š°ÕÐ}\õKû†|¼z‚V¯M­1ƒ¯–†Ì5UÛ©J‚Lyì–O0RSòt[¿Ö¨™«{ZsuÓ*[÷´f…§2_÷TáP§zÆî)?Ä¦Oj«³vOU†„aƒš·»e\!§ÑynLß=ÕówWo²úÛÓ'‹ÔTÝõ(ãÎ¬Þîô,7ÿFªôYIä]uM¤òž
+vF>¬ä´¬±‘ŽROç]‘Âó-£_#¥wE˜4©·B^,­wÓš1Ö)ôª}ªg•f»(;;RNëÊ1¬g4´¾ª&éLQŸÝ¸©HQ;¥ù2[^ ­p§©°7*¿•è™7USËUÀ¡Üåýëƒ¡lÆþ‰zÊ+¢¦#«D½–ohÓP%™ªfN·Ó:¨+¯11¯"Lúråë®íNéÛ>­Ùà)ó¦Ö·¦æî­}@:|O×TqÒÖ>L×qªšÜ§ŠŸ±þ…ÚÓ¸¾Î7^-¾×3|µ_Í»T£›"ÆëKÂw0Ð›UÄhò•ÛL5î'ÊýÚYÜx(m<dû”å)ê4^Aç*¨nãúw<dyÌÒž§Íp¯Úåb}äâ*Žá5f±Ô
+'ÃãÕOX·wOžJÿä4öíÿ“w’±ÂüÛðÝcsk-hÈaÜ‰*à®¡'a¨ÉUUoÜ©ÐÃ×¤:ñ&FÐ1ÛFMÐGL¥ÖÕ»#mžÚÐªû÷™9å#gØÑÖéþ·ê3’(DFkJð7‚³¬>Á.â÷úEƒ¢èu”Æ®ã"ø¾÷ŠÎZ×¹>â‹i­õÕ©GZ]¦ªÙE#¡Ö£Æ*>Ôw=¾z3e¢j„×fOçÈj£DsÒ¥1Fû–´6h¥¡FÜ@y”›dêýÃðV³¿Ô0l^¾“§Lm˜ÑO™Ú4£Lñqs¸o>¤¡¦Â@º¼ÜTSïGf¬©^iLŒu
+¹X£Úd*ª}¾àcð<ó‘™òmÅn3U7SEhhâBÑ÷¡
+*nòÃõ‚Ó­!LSÕÎ£ÉyõÇB“ù•3`}Vòò‚ÿòÕ…éÆƒVZ­×²2)$FÍAS;ÿ9Èšê)µ–·íŠ^ V¡FÆ¶³©ÊE•ÙPÊ¤êµQnÒÆªš®êKŠæ¡ÖªÏ@H×NUá´ÒÊ«•²pÚ¡-œ*êBës•¾pZ•à“¬j§B8•ºÀ©RK© t!™qÔëj†¦{u*¡|Ødoô¯´jTš+ÜPªm¾]©¨Êv×„]vóy¥ó‚fx­2~³î¦ù^³gløÃôÔ¸Z	…½ücEè¿)j¹»{2˜öxµ‘Ó,»Ø¡@öP’¡‡N–D®d~à$n€œ(KS\ÄI’¥qEQ—¯@¾qßÞüÇÍõú×ï~ˆ^Í¾yáþ¸ø³ûbáü.¾|ûmâ|™½Ï²ü‹í?˜š
+dÖeu-.9Aóg&õ¾=XœÖêdª(fÚcº´©V¾YÁv[“(sña‚™K(ßwÜÔCŸaÚ&ËËÇï©OjçËV;3õP;³Õ¿]¯@¼&*s6*ŸµsuT>?{Êg$Ùç=Úçf›¦ö¹Ùp$OxY‘Ðà>«šƒQ)01SŸ‘™¹”N0ñ|QƒISe—Šq;U7Ù^5›½•ç£ò|TžÊóQy>*Ï{ìèÆtÓ&ÿí_«ï¥=§pP8—N7M ×Îî(ÐÓjjÍ¶;ì%%Õm}Ñ¢bÚ‘çœ}ž3ïìã5)¤€L"Jp°çj‚KZg§“krÍ4¡ü/¼€Y	è§õb÷SÑ7ÇbÓMÄt"½_1¶=5ö¢û2ÎSÛãò5ÖSQÝÏwécV÷›PjjûO¥Šø³ñMR×o]ÐZÇÁ^RÕSÕKŠº¿Zu^¥î%µ,zuÛ\tv˜P•AËB+/žÉ¨£³äÌ R)t¡9úìëk8&þÉwë5×¨ý;Wž1úö´eõ´qÝõ3—Hçéi#6FACUÙòè!óßþ³/ˆ*CsZ×Ç[ÖÇíµ4¬OúhïF3U?3“÷T÷Lê³5Yµ±U3kG­ÃLXœñi7DÙÛè´yLXÙ¼8)n¯ñÖ ÒÅêê
+¸ÇùRpŽ¿)ªmWä=ÉA˜ø—ßößþÛÿ€>-¹ÝÊù·ôÿËïãVê×Èþåwòô#›-å–hfO˜Éß}2©­_\ÆLXÕE¸</ÌKp‘·‰ÁxæxÁL`ìÎrµÀQ½`w_ÿðã—Õ ‡ÇãÔïì@Š¸Z’Âxç÷ü?¿ƒ¾ÎYÖ¦=])oéÇWÏ¿}5@Gª¦Úzð¯ók¼î3<é0ÍÃßé-Q³aŸ–¨^z>?´=ä%F{ÒÖxÊ6Õ&Ù¿~w»žÓ ÊÉòÁFvõƒ»åü—¡Ï5éÓNÙ‚AžÑ‰œÍ˜0n›f}&Z>7ë&Bõnc˜7¨‡NÎ©¾ä|>'»m™Üd‹fº×>VÄ¶tû>º”ý<L?Î·Ï½½ÔIÎJ§DÎF›ô”{X¨®ºBwÇHpp´vöˆ² v)›_P¹ŠGQzCêòúæòšib†ÝHÛùòÃQp­Òzýâ˜²÷¤7tÓL­3s€³®¡V­Ûf¦žPýÊI¿ã{Yù®—®ßõ9¶uî‘ý‘ÞýÁ}ØGp¿4pobÝÇƒòŽÊ!ŸAcpyâ¬¹…ŽÝ2]Ûâ”9ª.ZÎüØÕF#ëóQ³>'Ò
+¨@Øóe39Êò(ˆ‹<¹æddLc2æo0ç;à9/½hÏŒç&,úÀUùð8ñ`äöðäÈ@ÉâdûÔÂ›¯ççè¸næýÆÕ¹–‡ŒŽÒÉ•nIkdÝ¿žÜc}XNÃÔ•ÁÍ3£°BË«£›êƒD=O‘²7ßÍ°ö(N»ûdÒ¾K?[õ³}ºq<i¯Û6¢öCìÖOêŸ(EÕÏß·º•Åö7Û—ZÞ9ý¹c¼Ñ ä©z÷}º³*tŠf~ÃXÀ¾ŠãzýzqJN¡µ®	U4ëi‰ÂÚþbém²¯õ¤êÄ¶¢èë"fÕ_8³¶ù+U£¨ùrë~ÐÞVr2¹žo¶«õ‡> r<ÿwz©´i}?´mqƒÃâæö¡æfÿŽ©OW6‹û7†}®—¶ãHZ„¾æ£5©_N,víAô¾RÉ‰»ÑÆ¹ÕýÈ«ì0B4T%û©MYuvîI2ó%ñ[•F¨S5§{B ÖVÕ´˜›¾‰„xöœ§\Iò”6Ja’<Åæ·yÇa‡=C.J7I¡È	ü,r2œÅNà¥Q\¢ÄóWí
+{SÉïã»Ïžl>l¶äF´òtIíëü–Ìø…'ŸõÏ£Ì 2œ–.&NŽ	q‚,Nœ4IKá’Q\`ì¢ÎÄæ XŽƒ/s²`Z£óŒÃ÷}Ø1iä`?ÆN€âÜIý,sÊ4Èý,ö3·,ºÆ$Öqà¢`‘¤bOŸ'R@Œ=9ÈM)E…±“z¸t"’æQž¥‰ÅKY‡ÄcAÎ·2!R¹“åAêq™:IT`'òPœ–A–£ ìFhÝ"»åízu³ÚžiŸD>Lxî%N˜G@_qLœVÁ)’$N‚(ˆsÿÀÅi~f·»l1ß\Ÿg)É’2óa_ä(¼*“aêdnG$.ŒºñÊ·.ÆY—‡ÁÞÈß+`_ Xì—±“ÏÓ4Ý2:lr)Î»8áÀ€Ù/à¤pLB»1ràØ( ©œdy×BdÝÛkr³‚!<beE^yî;AX0ª$MyNà0‹’‡y÷&i¡®sî<€íSØèiQBÏIædY;1*‹Îö"BÝbjKÞRÅvž¿ùp¦‘ÄYâ»iá¸¸ t$ôhÏ§Œ£("„;Úë‘œu©
+{ŽçÑtŒØMg¥“¦(wóÜó¢›ª<ë8
+² ç‚¬<ƒÍNÂÒÉST8)]€,7ub$HË,ÆÝÕzžsk®ë"ßÅÁ.lo×+œ,"È‰’(÷\ì–uŽ¢ÁcIà=÷@rŒ³(ƒMxìqäp¶Ç'.	Ê´û´3‹»åIx«:¹äÀ}½ž¯YsTe–¥ež¹À/zÀ¢dÀm¥06‡”˜âÔ‹“¬sŸÞ3–©ÒÖ £·§,Œ8ë.s,ÛkrCžex½¿±u7P÷5ûÂSñoöÊþÆ1ýÿKå¬Ög·xóf#ã½Ôú$+(ŠÒñªi´þ¤åÁk²¸•åÓ¼ÐúÈ†PÅ€,HC+»Ù\½#¬ŒðüYDŸŠ­O	W	Öû¸ýcJ™¸¤}6²5ÁE¾ÞÝdì{i{³Ù/‹ùòªÊkè#ës¢î×Œ5„gQû¬ðÄì)Gl[ŒçËúslëƒÛÕj±91‘nÈ[²´Ðhª2jßØ3ž¯?˜ô‡Ä©Û|Eè^¬›X_hÐ«¹Dü¹ÆnatëÙ•”m#Zþ„J‘e¥ùS
+1Æ–Ç2h1±l89 VëóDëÌu$>p~e99.B8.pá$(Ç8ó“’$èÖ®é<e¿=.òÈ-âÅ d<sÒÐž<Mã,#eŒýN°áNÙqßÃ¾ â, aÂ/sîbÏÉËœWã|ÏùÜíOÚÿyžWN`”î²2ôœ"F(‰@®ðÝN•Ç^°?mçã!`²½"ñ:N	@Yì "ñ2” 0NÒÎÎwÃûI»Nb’‰ëÄ.°¥A”ùö@pˆS$¡$6¨ììúž£ø¤}/“ `Ü)ADˆ‹ÀI¨ÜF¼§°&~¸G«Ñç>å Tn'$°ŸaD‚˜V"óý(MÂ’2 ëùtÊD(vK/œ"É&pqàà Jœ"Ëq	BZšÝ0¿çL<ißIû8'F%L~ž'-‹Ò‰‰æIrÀ½^/^ú”#ˆQ‘{9¨¤"rÀ™)r\ü£ M2?î$Ÿ}œï)ûžx~èQ¢ŽÀƒ½¢dV¢ÜÁY”—núnÖ)?g“(ñ8%Ž€C 9ÞII:¥ç¡8/3\Ê®¼Û)»cßssœ91Un ÔäàÈ)PZà4AAVtCÎ!ìùI’âØõMH‹˜ §F¨~(g@R	ðErÄ™+ÍSv=sIåÀg8 æ8Ã¹“ Ô;Qä{1`Y††·ýrÞI{Ó‹‚0qÊ$ÔÉ\Ø¹~L"IZø^ÇY·qª¿´vÒa$	,vœÀø#Ì'#ØðoA'üïóOÙù<O†Jäx	°Ì5ˆd$n?.Ó¸Ä…øÝçîC( ¸ÆdAâ•Ä)yü	JçÒ8Þ¶´w|ZtM'í~ìa”Æ`&‡c«€‰Oc ”¥1É¼Ü-¢ƒ8}C¼?i×1ÉòÜËàÌ" ×u’ $¬8ý ôIIÊnÛFØIûO2ÀÀúŒŠ‰SKFN‰\·tC7÷ÃnÑ|¯Òg ÞËåœUÞ‘û~àg—ž“b@‰b'Í?ƒ¸~’ ·›Šäö•M=¥M=e…j††´1´ J£˜dä­€<œg9ˆd	Fyãè€Kõæ¬Þuñc˜Î/·À~³ª>vÝTPÂ6õ€Ó÷ ¤62ŽâÌq=XŽ2+P@ºg={"yJyZ×pþæ,½/‚œÄ>L}ú9lãÔÚéÑ+à(‹„=Soöþ–¬74ãù½§‰©Y×ñÖÚy7ÝØs}À Ìu‚È
+Ê2`€ÛO\Ï Jö©s£¡§›ëÕzÊÙ×{ä’ÈÏ‚Ä‰½ˆPcrR”`§Pˆü0ÃnkŸz£÷´œÀY:xaêc8i#äÃq²-[8È'AŽÃ(w“n~'²tž•Xú ,ó9FàÅÀ3” 5eÛ‚<Œ@Üˆ„ ‡usü­# Î1!/Ï¼Ø	AðØÌa#ê™d”çw‹´èV¶Åm#¸=ˆÔ²opkBÀyF ~‚ <w.‰Ò<Ê’4ë†ŸÖExGÈ ºoI’x¨(sÇBº×I#ƒ@ì¹°t%:ÉÈw»Èˆº¹Ÿc©rJÜsŽ=  øxcÁziŠsÒ=Š°k;/h’sí
+ ‘ –ÄpDêâAL’0ÃÝ•V’:×b?N‰G«ÈG9UÄy ìŒ0õB7-‰›ÇÝƒoÁ)æ»›³t?s`&`;'ÔX„®ƒA´qÊ8ñ€ã¹!éÖ#Úh©Ä‹ÅPLÌü×®B÷‹HRìÀ!@Õ@nê$qæƒxãÈ#¾‹ò½’0ÿ¼h…sÑ3J?'îzYHPîÀÔÕø)ðA¥;~@¼"ÉÓ(Œº§Ý7»^î‹áz.Š†ÀrÎDúRü0ÿy–2Ë0¤	"ŽçF~í—~ç‰@ÝÈó–¥\PýWDuœs|ì‡û%°pT1lŒ$¢†Ž0I?=ÔÍ8U>B¶ñ±¬ùì_02[§ô2ª‡ŒKºw@¢vA$B	°—3Òí·vL—OÙ¦zˆ1ïù˜”NS¦1,©¶Ò/œ¡ (Ò4ÎÃN}SçêÕ^0²dXBHìD)U€Çyîd)	Ãv¤_–nÞ¹zA¸odTÁ“/N6¸›U‹Wžë’E®ë€¸RPy%p2D5=))ã8£†ŠNL÷m#£­ñ¶&WóÍ@†uÑ-£Ó¹X'afÀ6Ê6G¥ë$~A¡?-ò0Æ8êö0KmðÔ‹µpyž%æ*¨“kî•öáHÊ¨Èü@2ëÔÌ™{L\pÜâü¬#ó"Ÿ Ú;QÐØØh˜ £gAzµ³vŸm¨ï²­7ƒ¨Oû,À¹"R8p\GÔ»šŠ9ì¸°Ä(HIxÝôØµd§„Å½#ã(Ì“(qÊ"Á4Œ‚FµÁ_(pÓ(óˆyÝ°˜tŒìôìÈÞñÅ^Xº%‚Í%#`·J8²4„…+2ù‚_ÏÍö##ØO¼ 9Q–€`žK™ºEáD!†zEd~çÈ‚¾›mKðæ¼ø_äòü0á„ê{²™fNI¢Ã¸èÜo&«¥í<¬ÖÞ1‹2öÕ*AzO#ãQ™8aÒŒnàvj·öƒ%Ã”Ó,^3R¢ˆøØÁ•WÂ¹†]`’Q™º¾ïÆIÞÁ‘ZFÅ˜6$îo0cÎ7&RF¡#‡`j„…!:8gnh®›E%°•ÁÞpÀŽ1y…P"¦›&Ž˜ŒpH¹€]ôKßËb`‡qw` oÃš]<ÛÑ>œ¸‹ )4 q€Ø¥ÆÁ,pröPZÄ4bå¸áÈS‹ª	Î6?Â%ˆZ¹Cv{Jhø,0ÂÈÌËˆÛ©åÜ>û‡×Ô<Û j4OáÔ%Ypžƒ–P÷;—ø.I¸Š;¡Î·A]Mrg] (õË</cÇ§i'Éàh"ÀÜ¦IvÓ[÷€±mJZÆI ìäØˆ  ®û\J<ôÝÔëv.i§5ýˆ=ëú”qäÇ>Uòc8…‚¢ˆìF4P-É
+—eÝÑµ­´ÆÖç¼cÉB@57tÊˆÆ¥"àó’4N`@iê•9©e7‹Ðº@[ü~µ\ÝÐD­Ô"?Ð xD¿kKÀã(.¡ÞçÁ ×cNÒ<H\”ï'{Ía¬Þ”Âæd«âÃY†#7Éœ˜P¿ NVàä'7Ï¼0DnÚíÏçY† 9íý:ö$õò(B	°fÄ¥'ML=B£ÜÃ3÷pÄÖ-Q×²Öœm9r¯$¥…Sd˜ºW†ØIIP8ØèÐõHTìÉšè£¨E:c{;Ï·»õ V±½Cžº –ãçyŒY€,rA^Mq˜âcÖ©Ç£»]Š)}K7¥³­Md^ÃaïúH¨EBy™Œ9îæIºÔ“bŸb²•Âxë´.îyÆ\&Ê’Ì	õ‚rSÊpz¾ãe‰šë<+}¹lBèÙ†„>)JÎS·Ì˜:EÁöq3¸Û‰¤ÝÎ¼æ`,3¿Tn0ôoQu¹mP¾ú~…4™õô0È5iB¢ ŠIÝŒ’ƒúŒ'€vÂ‚r3d‹IêD	ö‹Åyœv3Í®9ÎÀ<Ôòd™›‚pL
+4—ÃÀ’ŽQ?K1*#ø'ëN`ç´¸ÖgH0ˆ"˜½ £)v
+kbšw*J¢ˆ” 	Ýîy‘u…gz%@9"1
+0¥¾zÈ+à-©¿UyäR%w?fÀBlÃ‚tÑ$8*ãÂRêÁ@b9@bÎ€Móº·u°ŒæìV¸ØwQ:‰çÂžIs`—ÃÂwŠ<HAEYÖí WóšrÆ±3Ø€4ãb—+Ÿ‡à`‘¸ÄeþW‰«PÂ˜\p—Q·B—Ómå©p˜Y“Ív°LŠÁ\8z#@MºÜ>°Ëz@Xeæx~¦i\DyÑ-¿øæ0õAÙ? âÇY˜¡Ü	ISÊ)žCˆù8	uÇRæ n4ŽŠK9ÏJ\``ó‹£€†” #–•t¸LÝ<Ês¯Ûy¬1‚a=˜ØÉ
+X´(“ý4CèzFphÄÐÿ,ÎS89HQi–YçN@ñ³'¬§¬§šÿþGyæ(ŸŠí »NÐ)ü°Ò$A…×É4¢Dïøp{ûzŽœfë‘C§ƒÈFK×É“2,¨_Ú“]é=ß^ïn²%žB/4ÑN(Qû$÷¨½’rM!Uµ y‰f®×)Ÿ£:…mãépéZ»Œ<·È"êXˆ"’B*a¤ ‘SwOä§ ãNãŠõ.`×Úã 'y@R¥‡i”Wæ9IY¤N‰ÝÀ+°çåÝ,Jõ‹d'ís„]”G¦^§ÍÂà—d…S”iì"@Ï‡Ì2ËßxÒCÏ²{plš‹Ò£ibü2r’ˆ Ä^€:1Ezièîf)îZ£¶|”ƒhŸÓ1 –4Á,°0n–˜™4éÔô!8i¸†lÝ$pu÷ûaä”E,©£JæfYôpœDYB¼ÒíéXí³é‡èöº(g7øöv¾´³ºn£ £É­}êŠ€:R"/@JDA’ý	m §¢S8<Ç ù`ÿ%¹ã—yè¾ëÒ oŒnZqŠƒÀÝ1ªA×Ñ%DíE^ ‡ƒÄ„@ès‚$9=ƒc>BØ+üÂO÷ñWê(TÝÐ9ú_ú°ƒ.³A{¥[pâ{1ˆ~®ç(îVk#Kÿ‡Ú¼{;ŸD‰ÂIÏ±?‰ü¬ã&aî†Àrå{2#¯4XCt^ØŽoYq ›e$’ñaªB’ 5áô/ìè Æ8ÎapÝ)47/kƒ›t˜æm¸ûºOB€G`œ4¶#È±“F°‘A6M½8Çtié>O³?\÷iØf¾Û²ºÖC6‹Ü,a4	èô—iá$°“`b0uêÎrÒÝZ(@4“5¨·^eoW9Îv ³´øD…^À±ê$Íð”£…™¹1ŽÂÐíö¢à#ÛzZ·5xnW»FpÊzµÛ’ÍÓ?<eÌègâEjoeÁ&Ò/K‰SngÚi#¬%öþÆÙÍ´ë—ÕeNêiàHQ:eFó³Óã6Å M£¤t3ìÇwcN×ež#}Õ"ˆú¨»Lˆƒ|êp‘àÒÁE8i ¼d”x¹vËG mpŸ|há)^®–nV»A(»»ãA‘axŽÐ	?*i+ˆÑpBá´$!öæyT:>tÂøîÎèz–¹€‰TÄTŸ—ÄIÝXã,Î³=¬¥ÞùÝöšv §Å‡è<%?»4Mp™ÒR/)ÎÊ#×£q ›fa’fžŸÀÿöQ9£m¾™éA4;ÓÚe%ŠáÍê°'?œAÌE9Mq'I–îìTºüîz5ÛÌVËÅ|yâ~{Øe)LiJšfDêœøN¹	µ•v›?\­ßåzµÜÅ3¶v:ÊäP:ÍR[pô¨„ŸeY0’$îæ·\Ëd/É»“v:L<R'Í$òåR(‡ëÓU†d½ÔºÃ°¨*@iZnö¤Ž¼2"Ê”º’\'Aàx‰ãÒÃ  Ýò¾EÍ ÀÙ-YÝ#µv>)ÔÏãÈ)Š”Pû±¤‰WS7JPÙ^­Òù/µv9C„Ä4Ôº¤º" 8J£´tcáºÝ“½Èè2“ÿ7³5ÉOÞõ$)²0Hœœ¤°!KZƒð‰$ñò0u÷r¯J×5ùÿ¤ÏõJB"'÷he±Ò¥6@q×Ga™{$IºÓ8S¾DéøÕbµÙ Û}Ò>ÃÑX4pšÓœJ û€¤FŒeá§qîy©¿7
+¿IÚç “£Äõ@ªÁAHm¡`K"'BÀ·&…—ù‘‰fÒ=¤ã¢Ç æ7Æò¯>ÍvË¢ªE|ƒoÍþkmÙû¸yF³m1Ã2~æ‰ßT›øD¨©©pön¾½žmv77ŒL6Ïhv@Öö†¾Æ>CS¿ñ]êßww' €‹¶¡!¯JÄ5kc*†È3Y‡W_ÔZÊÓo¹²¦+ØØ¤ÿ“tj-v°öaUŠ>ý×Ý>Ìæ§SrØÇ‘tvÎ&ÒƒsA¸A¯IIÖd™7Žû“·|íVL¥ògWÓ'¥Ê—tQ½îw0iüb´B#y¿Í—›-†§
+s(¢`ŽXìÚT¢ì{×ùÅzw‹Ó€Öð/ŠâÓ/ÙKâÿñšŽÆ¥ý“ÑùÃá?»Bš¿òÙKºô!»Cë»ÏóYŽók˜Š¬²Á­Åjõfw;ƒBN‹pÛ…ù€cæÃü>yËRµa˜]‰ý0Í…,äM.pF²NGµ¼|ëv±cžyÑÄâÐè§w zÏYí ®3†6oÈúŠbàUÃî³ÞUƒƒ=S°Ê›bpHýp‹fÅ£Y õÛ|ìb-äØc:—b(Êõxô¿	]“·óëñúôä	§2åZBßZ^å s–Ÿtv…RsÖçzµ2ú"ñÉà×áMY†‰#(‹õêí¼àÄ^.Ewèâ.0ñá&+A‚üI}Ïë/rzX­ç°Œxñ‚¿ú²nëÓX×°Â:”ÞMƒ ¹ø>ÿÏsö,øv½Zü‘Gì^á-fûDû>y%_º«¨BÊ9ë›ùF®)¤ˆ¬'UæwÎ‘qRÏ®ÖxI¸ðu9¿Ê®®§t1_¾Ù(äó«”~€eb¥—ŸUÄ.ÐPû›UO½½*µ½-®
+²|)6½A«Ymi±iÑˆ'¶§Yš«÷Eÿªûê-þÅÆ¼[˜Í‹]’z¬O>ûžÅã«ëõj»ž/¯^‹¡µékå#ßá5` %T ØzÎ %…ù˜ðújÇä)e¶]N£·b!ùus6ðQº”Êfƒâ÷©Öx¡ÞÔEäNíÖscyùd\­W0(;àUfÍN1o´ÕV˜¿šG\r¿:>—|›M(µNÄé4jã'ûn>cÔÈú‚å™rs´Vñ>@^ ø[IFâ+Ø•Ág¢uµ§‰ùŒd¶4…Ÿñg|gÏèÓy¶QÍï\Ÿ_àEÁwJò–ç*Ó«¬Üiø[qºó1<-}P¶Ì‰¸ Q›QóÖtŽ$³Ñ ãŠé§2g:T&%ïd“¯ç·|y!/vÆÿ²›‹‚t±Ø2:âñ*]”XäqÍ–¡*%ç7tUä¨OÙn”6Uµ8Ev`y¢ûñD]ôÛäDø½…?2wÕWôsrS}°ß«Ÿ?˜]2˜k‹¦^ÕoÜ—Ýêâ•^Ž<ÑÅñDt±(=LmO4Ú9¤‘CÚÏ!ñüŒC²€äcd—Xyˆ×¶Tœ¼È*«Jæ¦_”´i_ª/yü( ©9K#X¡wd~u½•¬G}òqnHÓÑDM%ü	EÅl¾` ÿ0üIdçO.˜‘µcZõ¶©™©röHÅtTŸ;„Ñz?1¾Ï>Ü¦¡ÀÈ2wd»ùBtžÆÃ5¿ð<õyý}‘AÑÞ¿…§”iˆÔŠÚk.©rä@ØüÄWì6P^÷žÔ7¥Oñç¿`ñ·îN¯uŠ5­ëÌPJ'OZOø¸RÌM°÷)kôS€ãSÊZþô/¡ÓŸþ“ýºû´ž°”ç¨®¾A«õúŸ€‘É‚=6ë>ru#W×Cï×\³‘?R>®
+ïæçh‹¤û‚¿¬qrìôká×P½L>Eº•¥G1ø
+×U¦œšgÑ-›•Ö.Ï—åj?;ccOerLµŠoT1kák¬Ï™ªW?—å££óBiæ~'¶(Vìôòê—ýG#›6åJè·tYíkerBôxÞûAƒ1²±b½¾crfÒõ’‘†ê©û+›/ä5“Æü7|Êá’iØû-É¯‰‚¿§ñyAÒòfÍï‰×U¶Ïd,hÿŽSÞVF Ôã
+˜öRÃ–yÄIšSoþyÎYz(	.ïŸÚ@îäGV“rõö:xË=­°Üò8aËµò¢ìßNíƒv,+ÊÏÚfYH…“èÃ¢ËÖÀH^ì ÌnøÊOŒÄ6ùæÀ>’•æ/ê¨{M6ÛRS(¥$6µ0áè¤L8]uÚ-3.Zq’žš^5÷ ì7OÝ'˜Ïæn®ãÊžœOoÀËF;Àùr^ £sEM”/?»lþ]Ï1¥|Àæäç+<ó÷ê1l³‚}Q}ë	Wmñ¦8rÂÜ‘+Îèê„µ¸ÁÕqÇhl±»QÈŽ:csS.æd­0à>û¢8;wËÍüjIW “úÛÍüWÉ..iFŸ…p	Eôéù/;2‘²_ÖÃ‚¼'*éxŒ›"ðmíéz£4_áãžoÉ2%0
+¢Ì‡
+Ê»ñßßÐ×à—:›\‘”ÔûJýîš[Ý~+7,n¨IåÉ­<S–CÓ.nïIe+ÁR…TøH/à÷ºâ·vd¨¯mv¥zíN9õ¡Ä‚Nr¢„ÆAþÍG*)qá¬–‹•4jú5Úw
+'¯¯É$×ûÿôÈh–ˆ6ÑÒpûP„i[ký„"R¿”¾Ó\¾/Ê(BõC{ÿ–Hâõoòù\ô~A–W´Pì&9xýK-0Óh)Ö'qñî‘ŸöF¢PC"¹d±Õ £,™™SN³†mä¢ÔŠŸœ²ÀµeA­|9V 3?þø˜ Ä³@	ÁyÁDU‹'-ÞÈ¼\*fÄáÈ½Ü{…ùAÐúÿcïÏÛÜ8’<a°þ®O'ß™•ôŽ˜Œ@ª§f%Jêâ´®©ª©^ì‹' 2QÄ%$³´üîëæ÷7®LT·˜ˆ¿Ýügææfæ—$¹€êàf#Ú~\ ±¨úkŽ¢åo
+6´°=Õv×Ací”cž&¾ø~ùíQ_y4„Át-öþ;*é©Y5Ö
+hÖIÌ!yàÌAVõèÚi”Õ<Ì&“lÉ½Ùiƒ%³MîcãŠ¤4ÐiÐ2…ET@4ËSÖ,šÖßÇ@+°Î3„#Ö“¬ûã‚—n%Õ`ãE24-—mYôïh¬ØÃPÌd}NIØ˜ˆ×ßvVÓÎý"Ù:T%FEÈòÀ–=—µI|·¦~È…Í‹€ÈØ/‘àš(A¤mÂ­{8ŸXñyªâAñ:”NÊèÇ¡	È.DîRüò¨QP“ãÅÉ…ÀÙ	²˜¬,q˜uôÂpFì0šÂH÷|dÚØïu9ÄÔâ·„
+éÂ…±óÓ*ÆT¤QD :"2¦šŽˆ™WÓùþ!á£ËàCãsuŽ4+¡ûº3ÚÌ²©ÜVàÂ«=µ~¨‹U…=`ª‚-“Zuså<Ù”¯y|k&>C8}E›Ëí(y³ØXO
+ÑûßðRþž”Û,™ÁY}-™4èÃùê¾!ÐçCÈ¢Ü´±{Hôú“ép ³û'ªÂÒÛÖ ° %.	1ž•žŽ°¸‘ag‘m·õ7¸‡EÁ8"B´5hóØÉ>â›nÐw¼cC€mg¶D³-WoµŒ5u^Æ’o€°Š™ÙC
+v^V=ÐÐõLÁþ4á!	KRªÚ\å*J­Cn¡À2I´êì–|Ô%K~7[ ÒYç²"èCºíÌÓí®LÙ¤ÉZ·ª¶ZÅ u©Õ—	JÆh¯ºkXYW(Æ~m£\Ž&öáEwQ¨°Ù æ‰C-@:Ôg"X—m¥I ¿'ªKÎ9²æä0(¿[iMƒ,…Žl_e|ÐûPÂ9Ö…³¸˜ZB¥×¬6ìIÇ»3Á8’ \Ð—J“‹†{Ü–Ô3Z­æYºlKe"°JÒ˜À÷Ùòñ‰ÊBa\^¹¬ÊBÒØkØPS"Ø-Bâ¹»ù¹®¶•µšNÒ,4„?O§µÚu³X¢Q¥%ÚKô¶‹ôz9Á7Æl;3‚¨|	›*Aã¶BtÙÙ­ZÃ]ë)cu]|›ñbTm¸95§¯0}0Ý¿Âô3…i0°û–¬JØÎœãwNçé}gF04ü2Ò¢ÚGÿˆ=1{t, %â)ßdèÃö©õõÖL5Èu	?Ëa¯¦r,O14î	 s{ö?´øº%Ñ-)—¸qrÊ¿+Br›¯)(\÷9*Z¬&{.„¹Ìïv}Ê[1N7ˆ¡#Ìä(6Š A+‰
+‚Ý\ó'…´m¹">Û[ÅGë®‡<µŒpqÂÄà•Ñ±e‘?^L[^én¿•NìÑ;æìQ&^zp_/ð‚Qì½èÅpiõ8êOÇc4šL¥±”é0 2Ä?HÃÐ
+ÝL†ëtƒfÖsÂ†$À,;í
+§¡þÒížFTföÆÛ.ÿ6ü!œ|ìovÿõí¿q6šøùwÿ¿¿ê¿þîEôï?¾ýöû±ì6¼Û Á&,S‹l“ñh8dð¾æ˜w.iÅœq÷qözû˜ë
+l ¤Ikù‰.WLTH<ye:DâëÛÔJŒèËéÇ¯<fw/¤°:h47ïg¨9[Lidáz–ã™¤C-aBŠ·hYe<ð"Y2ŸuˆÍñüˆa¼5sè?,lwTêr% 	PipÖO×È×î÷e"_»ƒ—ÔŒÓäŠ-ô§é­¤U—;?VS¤ÙO±Í¤XJÕA•³ >"Qå¬R0¢Êy•€D±+œ’ŠÐbQZ£E¹"éei£Îÿ>–7’d”pE]¿\$!5Æ¥²¨ò%îÀ›¥‹gÒ±	8D©’¡Œmë19]RüóÓÙj`¦“‡	ºÆìüêØ‘Ø=-f§ À“ÞŸxòÐ-	‚°,‘9å+8m!:]îGÿ¤‡u¢tÚÌF±;»Êí–aPM IRÌnšHÌš(´ŠØ×£«V,,•ÐÒ¥ˆœ0ol×Ê4â$ØWnÖ7<©*®|Uâx:šü)¿SŠQ®µ¢0hgèçeµEê´…SO\…ØCª{Fr,Óê2¬32sÒŠª†ÄléfÆ‘”Ø— Ü/iû^þA8ã^Æ¶Äy1/Ck²é¨-­ÙQéd+!r"iKë±*UœjWÜÒÛãÈ(žAÊ.ÇË*·Ô-‰ ú&ÖÜóŽF	¼JRò"=eJ	/
+$M~½¥ÅŸð‡,~wî¡)™dZ:(åM
+­ü„ÀHz¨?`tI“VÛöüdÀÔæBâi@þN„™¤°þtÂ? ‡lÎ½"ôŠ—’²dÙ¸íè@D&àÓÿáêœhÀM ²À@60+ é-"¢b0±Ç#=³d£c¢Ú¨1€cˆ…A€Ë"` L|-*åó–õ<z HÃ‰2#AñáeÇ=8;UiÐÉŒ!áf@Pwp#^¦Õ—‘èöÍ÷$>”üž»Û:Úe¤„ñv@Wvs- ;à¨;+z@eÕ^; è;Pàw àï@`™ pn<ÄG«txp¨~À@á€,¼/·M:ÓÃÓHö]˜4ÌNœ$s‚  Dû-	ÖB€(ˆ€7Çà¼ÁlÉ¤Û…1L·J0Þ)âx?bh8ƒÏÀ2KÕRXLñúÓ‚;(³$ÞÅ*ÞñÉ5ÀŽCHÑrÈÌ‡0T.Í˜OÙ‰Á
+Z(/¥ºJápšGÇ)êUO6ÑcµV¬T£Õ°,§$`=)‹ÅÚ,	;}v”i2 Gò´ß;^@?È­¬¹È`†h,ul@Ë'È’É¹}cÒH°¼Áçö°¯tâ€-h/D&¨qóŠá±A/H4ÐSÃäý4àª€¸Ñ²ž =ôÑ$®a¨Œ‡–»J9ïØ÷qëüÈ9GE8åñôTÌt4PòˆT?@òå¯ï‡UÐ7èªèk%‡ è‹±“g!^2Kôü‡?Ó#A—º÷¤„÷'|Ü)¶›}«tµ¸° Rag{Nâ#VN@í¤SE\Ömîw/;T€WÄ´!fì1uZ>V&ÇÀJxóKºi®÷;øÅ]dkÒh¡è#®’Ä'íl²õü|"S–ä4ŠÀuÃýu_d»¢ã‹Ñ±Wi7ß6:BáK¶£:4EÏoèùñeA£Xad:áéÃÃlü@ð‘A¦ÀÉÆÐhÈµðRÇºú¨	I¨Y_{˜‰ÏîTòhë¥{Ç·Ð¼*ióœD_U9;yZêÉ ð« š¯!š¦,w0‚Ü8¡Xçz.Ã‰¾>Z95…º”k6¹î2(©»KIUæ„/)/}ï+¡a•% Ð¨ðÐlÓÚê!íU,{¢bYwO-–AÄ«‹eGÑîAs#ÑÇ.@(™P¦LcB	œÖH Ë9Ú	ÅÔC
+Ç²œQÑ¢ö–·é‘2ÞC/_róž³äÖOŽ/¹yíJnG4hÙOŠ^ýlñÌ8Æ% öÙ¶Kö”8&¯TÉ²²qŒ8êh€d‹t6oÉ “-²]«˜ âè¹ÀVV:’Åâ’,«ñé©js”]"”ÿoâyƒM¨›ór°ÁƒÜI'“M¶Ýujã†ÝFu«E¶&K-a–Í6³c‹@ì³ç)…I50‰T0aóe@Ià€ÈpŸ±š
+
+ü« î³Ç ¾ƒ`…v çˆC„4Å¢íî©ìÈª:"<18:Á–ÌáepæÚtSœîÏ¦<7L‘Nœ:ÉƒÛà ^WÒ8©…6A'Óö[(ÏŸ	âDa%s-Ý‹Sž‡³ÜOÁÈ¾’yæ0ÁŽ{´Š(hÈ÷\è²Z¿÷–Ñ‚zE‹fhWóÔÑBš‡óE©‘çQPˆòý†ç†ò8×D²OðÔí½´ !`˜B>›W"àT³åã3‚v«|=(‘gÈ®}·ìj‰-@ôŸ—MÖ”Éoš8”P­œNë7óäp˜LÙæ³í\èÀ—ü¹#4¶ùüºC‰Õ~'E&[|®I'†Ö•êr)ðÜåwàÐÕÊŸNÃõ¼îqPM‚lCÃEF¼E×Q\|"ÝÙwÖót|	j.?böTé|ýN²ñl‘ÎÁŠ}“¡Þ‘+ÑT«Ï¶¤{áê4Üá/;6m¶ÅP‰¯Tƒp0éÊ:$xS6éŒ;Xq0)`g;$ýb8¾g‘XõqÏ’ïüÑ¯´¿ù3ÆÀ¤Zä´600lX?”Ðq &â;#ò0fŠþL
+m¹[¹|v;ˆ(ÙLÚ«çnÃ¤Ú@eTpÅ©§€Sýj¡‡ž/NA‰,¢Î…œKÆL…(Z"Øjÿ`ƒ,P)¦“ÉI «,ˆ•Á«än`„ùoµ®Ä£ÀS\5ˆO@ƒØ?
+BÃ«oÍ;_/¢¡Äú—Ú6ê¡[_äËm§Ñ0º¼oã&ÁE¨zÙ­˜VâË®&±\x;7Þp$z€ÀEßjUˆå‘ÇI$ŽHâ¢ê¬	{“Á¸p)½ÌœÈeŸ‚“ 4bÿ$nÀ•	‡¶Aºw ]‚K*¶­’Üƒ;.ÂÅ¯í7ájb r./"‡My{ð}¸"tq#n‰™âk”j¶…ûõŸÈÍ¸4¸ÂÑÈë'éôE¯ß^Dc¿÷¢×ÍF/ÂQ?õ§	úo4UÆY¡á “0ùIj»!Wê'e—øŽ\!T`ô›˜·ä’é†’·þ±z5~>ü£÷Ÿ?Çû›èûß~]Ï§Ëß^ý6_ÿòM4›|ßûû¿ÿíÕBiJ“/Ý”+¦(–‰˜½<¬„¾ÕÛrÉðlâ¾\pþ$Ý˜;àWæR"”îÌÕÅš?I·æZ	˜ß›;/Î%C)nÎ•³ÆŒžÄÝ¹b¼¡M|AI×çª«“ÝœËW°É›ÞØðìoÍ…K¨/­4
+C’áz‡î!îÐµÝ¤TñÂ4Ë•^œÉ…W‡¹+×r9—T£yAn¹ôÒ­¸å2(†Eæ%eøÂ0)_‰ûoÑ67§âK»ô6ˆ”Koå¸›mÝ}‹©ÃreYZ®e7’±iåwY”T-Œ¶Ñ/$´]—Ë
+ÁCò’’«y!.Ðc~Þ\‚«Ý¦øLo¿mé–·ëÅ·Ïîâ[@?zñ­Œyåír—ŽÉnÇS|VLí–S<7Ùx¶ž²%²i/×óGx&çh(.x ] ö‹æì.a‚ád¶Á×ç^EÙ6DYA¡y¢,NU$ÊâDòÍè‘É|ÕEYUJKŒz¤
+*ÝÇÛÍ+I“%qÃ´$GyÅ|‡ÐÇ&—Î¤Þ©›'¢jÂñ±%SÜúÒ‰$SÜ I˜ô\C2Í)Ì.`vá”/ýú`zÁ/©G¯ uI°ÕÁ‘ô™‹¤‚`¯"éU$­#’Š5{Á")…ƒ©Ôqy=½3Y‘G±á€CØôÅ²hM‹©Œ ä(›<cƒŠD-»ÈVM ÓE-W”¶à¢h»´õ£ThCIË¬ƒ‚&­£¤N,,¦œŸöóù‘æ®6S¤5S¾¤ÍøJi—Ô|Sñ˜â#-†
+N'—z¸ñIöïå@â¼ÏŽ÷Ç‚÷ËðÙ?c¡T¿xh¾ß%#Çª;	Ã'ÐGùœªUAL•“üqeÏÀô' ¨‡ÙRºtpCŽ|sôOdv~Æ{Õ< ®w),©k xúËðè‚9Ø]ÊDJ¹aän	û˜—2&1mu»LÄ´»Iu©òù®åjv¸mÞP|´Xc×ŠÀšÆÁï!ÎGm­·€ìº.”µ!åï'9[,‰+aÉîÛUææIÜÈûö†7rX/;©pÁƒ*Š{;Òív5žA$2¬n8>^Ø)¨1hýÒ³ˆj(>çøLôÞb2½¢É‚8–ÃéŒ½éÂm÷jI‚œÍ¶¸OàCâH(ŠªÓì.
+«+.õcÞJq¶+Ý÷«…&mí¢‡ãù+Ë3»kâ ßòp!4ÿÖ‡*j<öí¥ç»HÃãÇ2ñ½–o‘º¤û?­b¸®Y8üÕŸ/jßý™¿TÕÅÕÒjIÚÚhûb˜tOÊX³I%Æ¶5+úm,\âsxÞ+ñG‰j¹ƒr+ÑŸ&VWbŠ¶Ù¶…è9g ŠÛ¬>l	fŠòÉX¯š"²d#5®eiš<—ä)­0)
+=d<hE¯ÖíAGQpóE~T‰Ó_Ãmœe¸£ln€^‘esî»éï,˜Æ
+o\:i=ÛÚ°£ôuÇ7l§ÙÅŒù 6E6¢¹¥N&-JF—•€îB/?^Û_•]Æ•à\ý(Nø:!×„#QŽª;Ò¹®ÜhvË\-\ÐWrcp8LŠIºËð‰Hº;¢sŸdByÒÐ(3‰wÃÜùºw7ët·Ë6×(Í]óÀýI{õ'ÕV;%l$kbá–§™"ž‘Á*Œäàù{QtC‹qáÕ¶}D“µŠ?X …\ß¼DoŽ(!µj2±yçu²¹ôú9ËD°ˆÝ£¨x%˜ª÷Sõ-âàÃW¨{uf*¬xÕ%>÷†#u¾Üd÷ØÄõ%Pó Á—„¤·ÜËN¢óOœöU×¿¤×°\ÉÐôá‹¼ò¥·î¤÷œmò!òàŽr—huÇûêÈ¦÷˜sƒÐM.ËÚÐrµyšÒbBøqºccB¸ÃjÃDF4mlGÇã“”¶ {Íýz¾J'§Et”ºrÖb¢4ÂVQù®û
+i‡¤áaD‰UäÂÀ”=£üç$Aµ~jGìiâ¦w ,À[þ‰ä®ÀU (  	õÇ'ÐržwpzÀú¤ƒÄªF‚Ô„$¤–
+•ã©D:@Õ,07$¢dÇW!
+å n#g¦rJîè5ÆÃK>w±Uˆ²²òÉáú¯ü½Æ·Rù%³‹áy7ÎPÜèsæôÝ‘éû*v\ÅŽb±#ô…Øaå…Ë ÀiŸ” RîË%Ð•´QEÒ"ó?êEr‹
+°¨äpü®w@6¶[Š¾¡Þ——?A³û½Oml¯'N¡,Q…²+²’Dæ•“È~”Ú{Ç®âØAÅ1ôŒx9E_e°«V"ìRÏ*ƒ]® ¶ËP‡û9¼÷óÕýåFet0^§`$³]À_Z\"X°t÷ŽÌ¼ÑkÏ¶¹³Æ‡zí“åàÆ@Êr‘XcÎ‰¸ ÅL¯òÎ·èÃûùßg»‡_é@ý@P…c‡áØv¢|óûþSh³(æ£½$òG	ûø,X~íå‰Ä¨Éž—ÜC7TV ]r _G)J~S¼ !<s[ É%n­K!þA¥0Ý‚eÅ®7ÑætpÆ/;¬sÛ[è—(¤<Ã€‘ÇKÜëìÉH%¥cC~Æ"T øY¶­ÄäEü,nÜCÅdô„F+»'üÒv»à©˜jðÕÓœÐêÀM’<ý¸ â)Þï—ÛÙýl‰FôC|5@–`	2ç—PËwP‹9Â-Ä.Ò”wÊýÓ2&)5³~«>"ÔEÄ2~Â=Äá"œCøJ‘ËåQ+1jK¸[ˆ¸í!ù„HÓ¡XõPKšÒƒŠg±n	ñàEúQÕÃˆ›mÄ»í~*¿c®!fW¨cÈÍ!°Mñëok2†þˆ4%1ºrB$”*Ü&aÛ"ÔäK’”ÍœD©ŒÞtáJÂ~«¦÷}º?¤&¶ž„RQQ¡CHÞ<2ÿlëÊ5ªã`.^~ºàµÆ¥w|§G£µ¬l¾BŠ^!¢å±+ä¢ê/¯ºËw¥¢Æ@¨ÖóX«Òºh¾Z}ó•Ýžë’LºW~ÛØd©>:ç²š-Š«æ«ZQ^5]Ñ´°=ÕºÔYÒ–àÅOs“hMåVqÿÎÚ²Œ¥nf±½®(TÒR³j¬&¸j…™Òˆ! ­ž¼§×·ùÒ(ÉV|Ÿ¬W¹H™m²‹ô™–).“dŸ±Neí¼whêB‚®znC$'9›B61Îàóö.ÇHœÑrÒø…cBa»{gŸ*/n³Ø­Š¸Í,fª‰Û]Vd#J„En[þåÃÑ\þM$ö;FÍÜeíÁ¼¬zE‡9&?Í„5E[i”«ðÄîy"h\¹”IÚ×/àº' Ø£™‡ùh{c‹¦¢{@I´R¢t¿Ù æñŒÎ‡tK»2¹­Ûÿl":[×n+¨J%C”“æ ÙbñÓ„*àÐgVqx“ Bæ¨ÄALÔx-$=£ºÕ4gsmª¯¬áŠ/õC.P](õKë·•+Û¦ÙÊŸý;9ÞÓílù	ùƒr^.]IÄ¤Ç9 w
+Ôƒ
+9ê±.œÜÅY8p‘tOÂ~÷°Ú°'ýÎ	ñL\jî€eñbáÔ‘ßrØõü;92l[úøIÏx%UU{…û'*#ì^©pX6	|ü5$bái+ŠÿýcIPˆ›^ºyX	
+Î7›Y6?vH-£ŒÀèûlÛy\í;éû¬³H'YÛXsÃÌÏô£(cqå«®va›Í‰qšßéñxMÍIì 7T„â%®™„a59»t¢WKºRÑ%éNBæûÔU'AÒ?’ê$ÚÒœ:Qc~JÏt¯Év&òE6;a=×m
+XdVÖ8‡º¦KR9ëªhÑ[	_Äu”ÓÉqù€½äfø)Ù@·£O3í¡[Ð§ÑˆÙmIbß+	ð}¶||¢dèG¥±RÕ²Ic¯%UÎ#•·o!õseÿqNËC“·m÷{Ékµë4lŽ¿%«²³œ%›ˆQQ_w¦óô¾ƒÖÌlœ±u>°˜ä³-Ü¨ÌcböèXL¤’Ü-.qh¤ê´ºŸ4ìÃ› _’ÎÔ))‡ü8$ÅÊ8$]½‘ž—7’›Žj:&›Îå\‹Næ¹ÍU}†®~BW?¡’~B¡•Ô/ÛG¨†PÿêtûÍ«{Ð³pr—suºº]]ƒÎÇ5¨ÂJ½º]Ìr¼º=_· 
++úêt®øø.A‡4¼ºÖõ§š¸}uû9ãu–?½ºý¸ýT‘m¯.?g@üI]õÐÕåçêòSÆå§
+"\Ý}®î>}¿, ]Ý}®î>gåîSê®®>çEAPZ¥wuõ¹ºú\]}ÚÑ•\Ý|Î“Þ‘T%W7Ÿ«›Ïstó)•5Ãö³×ûL¯÷™žþê,qŸ©L”lõü©ÍûLÁüzŸéØ¯?¡´¤ûL¾¯÷™^ïÒj|Ÿ©”—k”Ž{q½ÏTH®÷™^ï3=¡,Q…²ƒÝg
+Ùõ>Ó«8vÌûLæ®÷™^e°*2˜yŸ)ÇÅÀÈ˜’þQøÂ<†«Ý+†!º´*‚4m•Æt&‚˜¢Š4).þÊ¢ßÝ%_i&z³»îW6¥êìŽiÚµ³¦Ù]ŸÒ­òABÔ
+’B°BïÔþ‘Žœ•~ê!~ìK(Ì!Ét­IA¡8©ÁIØÒÁ'4¯D¡…ŸH«E*¾œìc´S*á*í\¨´ƒêüžãíUÒ¹J:%$ˆK:2ð]¬”Ãœ@ÚQöüå~VJ¤M¾ '_HäÝù%!/æ«ñ;IÐeeº™ Ã˜Oå‹üÓÿJµ“ bÐ17†f»‡árE® –¤ Ñ=ÛÅp+±¦ó”tøË3sN&êr©!îôrÄ*G4‘z4¡E¯Í¬F
+ÕT]t•~.Kú¶`‚èlÕèaW1è*ˆAa ‰A*0^¤84/:i»˜è!0 ƒÓb÷µyV.¤c©¸’9<ºQHÈˆ´Ô}¤Â¾jÜ5%~7ÏsW?A‰MvªåÊ#žzÈLmQ¦¾3ÓžHa½™ñ.%€
+¨Z·˜	ÝP.«ç•þö[šà²L|È€Ùp‘.ÑL)ði°ý¸þür™ý5ÀãáÙ{ŸR'Ž<!ëÓ+ì~2Á<ú¹{éÐŽ7)ÀÔÀHÀIÔcÀˆŠPu+°¹d¸OÆ ¯p4ÙBM
+?÷ÉwÂ.’kÆ€ùf$çŒñÎHîƒ^vHÊHp·Ú›4ÀŽkÂr4rÒ€»¯doì®1`zé-ZÅcc ã„GzfÉFÇDõÚP·Ç×—ïÆ@8oøBRÊç‘ ñ÷‰ü‰[ÃKÃ‰2ÃTñáeÊŸµ«®<èdÆ„Üˆ—éGõ%d$š3ó=	^%¿gÎ ¶Žv)a°P´Ô‡ÝLb8dÄrædL¦óúÛ…Í‚›8rÊDóÐ|D1¡JçŠên38LIGn›ô¤‡çÈ°ƒJX>£RÜ@ÒCr2 ÐC{,É9f	@D´O²–ÛÛ/©Äv‘“ªt‹wŠxDäØ—êg6PÍLì²T-EÀ¯?=!„û• .V!ŽO®oÌKm ¹©I“é™§Ú@Ú©4_5>e'Æ'hDË¼\pŠdp‚®ž,¨…O=<ÇDÐF±R!lZCœ²¬—’8õ\ä©n\	mú*Ú(Ód ŽDéd0ëfQ;”Pk/2˜'ê• ŽhcB29·o$Ðñ°ÜpVžžîBØ¯ä¥‡Ïcð8¸„2®Íå¡?2ÀiðTä ;­Ê`~"ZÁ• •Òò Iƒ7'ÛvrC;ñ(»µ	\ŽfI	õSÂ^–ú~¥ÝiÐUÁÔJ1Îc©Êö[º8 lªçÏTi/ˆP%¡¶¶“cí>#¡–š`Æ± ‰rZt(¬²:.æ	´j Ó±3¦ö0+9Ä€µ¹óì
+Î&Ê± °e·œOK¼ó£n%ùNƒ$iÊÊï'YˆXm?éÕÞOq ÀïÝŸ;äDPÍOR\,m5Yg¹ê¬Sôw¼Z¬WKhù	ä®©2”µå®Í¬=ž€üg@=¯ E* ±ù2Ð'ÈGÐø§W\AÕ¿ýúú0&fêsÔÜÎnÕ!öm>Ïfø"ÝùjœÎ;«Mg“-V»ì‹Fpƒû&RŠuˆ' ú·Íì7¼hôœ²¦˜Di«‘˜´˜]ˆ˜TNñõ¼¥¥€]k~zi©¾öý(Òn>üñõßuÄœ5 þPM}¶m?‘€DÁ£!Ñ£é'gÞb‚™{.ðSq³v ë1æ§1m8
+xõvñnŸ7l……-h¯²ß›-;£Ç]vªž¿:øE„ˆÊÓ.zV«y–.¢—¹ÞdôRN5[>>#¤ê…MJž!ûÎÞB\æ¢ úÏË&Ê\M§m%ñÏÓiýfž|¿Ëü[æçµ	;¼$À$ƒí—DºëÕíŠ:Ÿÿõo¾û¢“.'°“OAÍÖùüí¯¿}×p÷ÞÔ¨Ÿ”Øì¨Øî¬:ˆ+ð[Â1Ž’«sÚÅpQh7ÏÝ†?¤ƒFH-ÏCUûŽ£¾’yÞð1InÌB‹o±×f¾tUÖqe:}ÕÕÇâBÐ2ðB¯xÐb¿Hóp¾x 5òÌñ .ót»£÷ÂœäÑ¬
+Ÿnä´Ë6C°˜KwGy’RâvÐˆ'±”˜7ñÕ&ð ÿâ~`wƒ¶X[)Â?±í©Âˆôïfeegéf	©SæÃÞ²9JôcºF',mÖŸäÐ#Š÷2J#¹G£§ïE¹UÜ¤#‚úü¢‘¸ÍÝ¤“‰½R¹¶¯'“ïq>\D6™áúÃ(/Ïw(ËDîVa>»ªß4Î6±$ó·$ÉI˜ïö€”½ »yÿ€R#«ÑRÌªånž"º.f¿7ø=,´M‡¯áVœ´ê+“öbJç#FƒúWù’àÑKê©û’Píö%q§~ù‡BÌŸÌ¹L¼z%½äeI	·ù'¦Yœ4Vo³»Ž=—è8~óÕ±ƒåÅR”i™^`x˜Ù»Iì£Ä´Wzx1tŒúÝˆö²éãÉÄA5Ø$õ]b]4|m9äº˜&²‰uâœ„ÚkxxÃËl"ÓEšLk5b1KÔçê’ü\²\‡‡sžíô vÖŒßâ”,+ÄÞ›ï·š<gÍù=$Ì—#­‘YµÀ{ú¤ˆ|G
+¸G¢IânGY[2`DÍ’Èˆ)°¯ËnDéKÜ‚¤\|“hÿÓK>s†`Ö,’u„/Ï/Ë6QÐ%t\p<ë†øk–zLÛL_²¾
+¦WÁ´¬`ÊGüNZÝ(–¢IÚ?ÇûÁÌ›%è,Üò9H¦—|³ÜòŠhË­gÜ>¢QYXR) !IÃHíGV^³»$y–ŸJÇ+B²'ñ	I
+ˆš9õ]%„«„P,! HQ	õ…ŠC€“!U?•èÆ.¶Š²ÌmÜ±Tdc…é*v&Ý(¾1,cz¬Ö™V¿NR(;Œä2þ½—š6Œ‰Ù©æÍïsøO!žÂPÉq˜Ó­íù!”¯|I.ÉAR€±«èÄâ¯ýœ°žI«ÆªÛŠãŠ¥ÈÊ.ª³:L,çCŠ6ŒÙŒÓåj9nû\y‚@r?Þí7ÙK¨ô%Ø½üÃŸO/™jÑÐÕ/Ê¢+’tOeKc|b.<Ú•ëHyFE<&¹Cæó*ó²½Â·à`Úí@Ë.V ¼½>‚RÈJÃO&¶)–Ž‡ýY
+«IÈ`?ËG+˜Öˆ™©Å.—›åb  ü _k…ý)|ÿ‰YäJ¹ÌW2Ç½¡w€r÷ÐVbˆK¤¼†y)
+'EìnE¹/‰¿Ìmve“]ÙbW\¼%Ùë*æºªµ.–îŒ,¤ßª©.µÔµŒŸ°Òué
+]¾läry„kÐÒnËÌïÝYÜ?é Š{Í¸ïgÉAÅ3X¥ð"ý¨ê·Äù¶xG|=ù;flv…:Ýøúª^[“YôïDXX)*¬ª¯lW»Š;àŒµ,u:»‡ÙVp¾]ô,h_ÍÎõînJmNô‹õ¤]›E>t#mÄXPkºck
+AÒÖ¯üBUâcÐÖ“XrôjC	¡cQ·š½ütÁ(Å¢T—€©X)é"£X|)<†›šÇµjh52Æq158_Ü]7QÆà8ÔGGi)7ÂEOÔ_ha{ªð¨ƒ1ÆZ(1OSªaq¦KàE_Áy
+4ÌüÌb{\î¨¤¤fÕX*ÄTâHËC z y¦oÊ¤QBDCâG³ðÑ\ÓeÉlƒd-n4-S¸‘° ÑÆµ¶GÁ'*	\RãH ôÓÚ& %½h
+QØùE| …Aiè²Ë÷ÃÒÕ½3ã€•rð¶"ãh 'Ûl²ß÷³Øü@èè»„²Ž¿ª•C¢FkZœ]Ý’îòm¬eíï,æ¨¼üÑl1³x~Êjöj­æþE~äŸ»ÖÑ¬V1’Ð ]0Ä á ë¡ÁíŸ-±Ë46¥«":DºdŸÊÂ[¨Ã²$½éRèº"Ž½ˆu9/(!çñò†0~üF{£dÒWnžÂûÚ^åýFèj!±+Èž!ÈöýËÙCîa†¿•éö6D/Þ<¬>,;²eçaõ>ƒOøËA£l]d='õêì–Ë (%±ú`iÌrCÌìÓ„¤ü³ÌâæóÁÍ <©pz~êô>•MùÚ87Ðì‡’~
+ZyÛùz>Ç(¹%—p rnázž¤óùv?~è¤ÛÎÍnµšoo¾è¤›¬³N7;fg¨µá=P:y2%ÐpS
+z*Ö4?$v>-œ2ƒ¡ˆÅ¢žì73±€LL£v%5ÎKÊƒ^ÔûJQ¸kƒeù–V·@Uê‰±`¯ò¶ÈQQ„^½AŒ?Ïþ…vWØ\úG³Òí–½¯èçh¾ÑŸÌ¢ àf«yËŠ–o“ÁÚWGŸ“lÀNMÙ7p&šÝ…™\¬à"`¿[^\VÏPYk ÐõMÉŠÝº‡W]ˆhøº'†Qw~h`¿wX!˜ž7ÀM&S·¼X¯ÀX¬³[µ¨]PÅ_v¾SE.èÔJ6ÍêÎ>h*”JÚô\W¶Áös-˜žÑ ÒmË
+Ó3	ÀàûlùøD­ÌÂ ®™4ö6üAïXàî¶Ïîn~®»‡FeñHÝmcÇè®Õ®ÓH×¨¤ïøb<C0öAÆúº3§÷ ñEke†P9ëÌ„¸% ¹“v¦{$zÿöë³{ÄH$ð´ƒ@o·B8ð%Êó.ë<ìvë»—/;ŸûÿÙapôeÇCO`;	O_Eð1»Ggò6R®zÀ›+ƒÊç
+ÏçÏÉžÏž“ÂsŒæö5Å¼-(eñ{Š&¶³}Xíç8+7›\véxÓ¾$‰÷‚|<ÌžºOCØïÕ„³j^îa=†WÃ!wÏ¨çÏOdëdwß!k±“.VH#úPz8/´¡4À9~1ÉÖ»‡ÛÎkq€ÿ%—ò¨*õ•ÈÊý0C²Þ*‚«W¤D)Ú»PR!p\¯¶xr²Ig™¥
+£»Õú(b;m:Ü9—
+Xº`¹ì#KiAãã-%€ws]ÂMÖŽÛUXmŠî»·ð*¬ž£°zP‡„XÀ±–X•gÈ¡z¨A¯§bì'ˆ}hJÞ¸{ça6Ÿl²å—BàÆÌ$H·t½F|„÷ô¨Ú‚ƒ²i!Öc#Úòå>Õ´ÉlµàÓŸ¶M'ŽÐ»t!/PÓ•¹œ	s©½u¸2—g.8è]‹gÈR’˜«©áx\ÖÔhJŠ(°ÚvPr‚ÄGâ þÓæ /ü¦,D†ýæ
+©5Úk.[PH]Í”ÁQâ¨¼ïúÙ˜)RãBü/˜d;ëùþ¡TmWö›ÝQs¨×ß2Û+²ÒdKÜ/a³Åz÷Ø!¹‰q3U<íVëÎ<{ŸÍY)³lËâ15$´h.¹ŽYè¢$W^V=äÑý•™äú4¥W÷´Nå*Îí‡4@ƒ÷J´êì0 ¢ 7fŠË2 ð3!`ƒ-ºÃi¡‘ˆ!Ív³#{k„Òëvõ  ñËu^·«Gß®Ô¥âÉ’UÙÙ‰ÎEãß»Rû**$Ñ-ìlÛAÿÈ:1{Ô6¦Â{¦Ty_g“ÛÀ0Áº>T&äB H-º¬HàêMÀhŠ—< ˜¤üÃ,q½%ül9v¸ãJap<àMe1ªšD‡Ëî$Êú“+\úJxŒ¸”C„Ö†lJ’êþSÙ(à}ÊÌ¥(àzñPna¸ï ïÌ$ÂzÛ"\]3£ØZ¿1$1Ó»¢~ÃÊ†ú¶<x±tŸ‰RÛö[š@RO…th$£úÀ3³Ûï¹óÕ„8ü7¤V/¸“®Ôsý‰Œ9Ž¤;"vV»ÅÜ64]ü
+™áy)ë7äÙæB»HHciÒ½z<—ÄŠJÝp÷ÓW%‚‘ë‘üÿ$…!)oSÂC_B›^þÿº.ƒVÉÉ¤{áôhä ÷JRkø ßjùñLDù¸ÉÖ‚—Ø¶ ‹BWbòbÈž?½$ªZ!ÖVIŽ;†‹”]HþT.@yË&Þ<:uGkKU-øŸô€é‚æ…H'€Gƒˆòœ8b§“•Ia/ÿ¤‡S‡A”J?iõníXàl ezÑÓ[§	jFï¥ªÓT[ ÷ÖïÔ‘º­ÛRkPù…ÌDŒz Ôÿ7NÑÑGô‡<Z=pKº-S?°€î$²ù5nýŸqëIÔz*’sÀ¼Ô2žP×Þÿª(®½ˆ[jm¶!•ÜmïÚ÷ôBŒÀ÷ÊžL¨{¼Ç©Ý>`.ÄËkxûsV=‡ðö‡<¬;¶6MkúywjhHÄfÝ¢‘r^c¾?Í˜ïåÃÔœIÌ÷C.Äöc¾WYŠùÓóÖ"S¬]Yä¹®³¤®9ý•GŠ¸{¿Òz»·ÀTä–ïk­PEc}½ÅàŒV¦ïy¥—æõƒ3»ÆÀzÄXÎÌ#wkLÕEc’¬éB÷¹ÊBh#ª¬x”Žè.† Z9ÐzºÉ&_KUõFG@0½I²ºCúpñ‘Àüò’u Z¤Ú&Ü*eû|Ä\g¨àqˆ¦ž€mÑCºJZ©ÙÕþ–ÈX-ÈÆœúª-Ækÿ3_(É5Œ¿jÇƒ°¸Aì~Ëâ«j¤s8§’†ŸCáïöè­¨ËÎT&ÈÙè?sI ðzÇ—"røt! íáà:óõ~÷€Š™tF5QðÀ±Ec²6`ˆqhºBØ	mŠÛßÄ¦ÒËpð¨ØNJ‡¼$Ü¯Ãfèî‘Æ«ý|R~CM~ÍÝ ŽÃŸŒŒÑ†G¡üué	Õô2Då¯Æ«Åš™ý(µÄ®õ¨°?Wël“îVLÝöêçŸÞ~ýú§7´L­†.ñ­¢g+fVEUdm1É@±»‘¯NçÀ’«Ásu"@´öË~4ŸmÀ"_Ø!Ÿ_âÿºC	ÎîEu rÀ“`MºÔÌ«Š¯ß\°UŒÄ+â- à&Kwm¹j²²®®šÅgØ^ù[=5WM1ÊUøYü=SO#&þªþšÀU“Žê±`ápò*lDQ&,ÖµDVùMÐØ@©CwÑ¾×žÆBÅ’ võ??¨EQ]P«ç~à¨?çìösñ¬%×óCU:¡¬pTÑbµká|äºOlcÝwë®ûë>ñÂ÷‰ ßû…,Æ	\ƒ1Ý¬ |O}SŽ£l°TñK¿ó¨„tÐ”v‡-ÆïF«"®<ÌoñÈGFÈzZ¸ÙøÝã]Ï]£ ¼±×]Ÿº¾ÁkÇ[­áÐ|«j«â‹®¶Ág‚®I{è*depõ%¯ky7}U¿S“¤îNµžúí ÁÏ{’™¹¢¡9»]kÔµíZÇä˜·ÃF9T3"×Í#[æÞWnô«²ø]¸:H^­lž£•MÔ/Bbesè;8ÌAÎ5<lì	Ki‘3nv£aÞÙáœOÍn¾ºoá|n;9_Õ·iÖü¤‘¤]%»9üI
+@qXúü6!†3«L~V¶É4‚ã"ÃâÙÛ
+ªÃ
+Hht¾ÙÌ²éü±Cje/°º|Ûy\í;éû¬³H'Yëªý*Û=Én,Çç:ÎÔ\¨$£èÉ~Æ	c`1…cUmV¶&úê“-y¤Ã0Ué‚¾,Šy¦Ó)¾ççªJ;Ô»T<[UZ_Þ$‹:b‰ž!;€û,Å%¼ìæqv¶²dªtâËøBòLÃîGÃ%°´º$zT~®œøWH~¦|T^BL?v ò|Q¹|hò‚X£Õ„œ/‹)ÂU1 '4„ó+|bszÇ?ÔÖÔwü–”ÆIØpÃæßI4BwS5uC—(†pµóp»_,RX—PÇb5Ù‹hà,Ô#‰{««ÌxÝãt3ÀØ8ªðLŽln›iRÑ|5~'.‘Š!Ú9iÛrEâ»n•UûínµòàÚT9äB~.pCâ•Ñeá¼_[‡-b†Î-\Ñ;
+‚C÷ÒdÚxÝÑ´ß¥Iø"ífÉ‹éh¥£ñ(úSieú
+€¼ðÒ´Þ6“á:Ý Y4Gšðšá-y¡’èÊ%'€Ã‡tûÀ¶Üß}óÛªûûÏÿ=ýWúŸÃ__õ·?ü#~½úö?ÖoÂè}·û·×}óõ«Åßþ!‡µÜmÐ¨…©Ïxh{2d_K,Œ$iÅœñêqözûX‹•N	’Öò]†˜”°ñJŠã)¸>ûú6µ’ úòcúñk 
+|kÿ„Fsó~†1‘³Å”2Ö{9žIªzÔ¶0ß%zz¾¢f,ºYŸPS6¾ÀtÙü„Ò£RªŒÚ+£ªšgÕ@þfArÇ"ˆv‹EEØ1eÌZÍ(•–E3òXk?nŸM=z%»y‹Wf$ð©å*SHœUëÙÀt&"L³suê£N!øyÖîãx„’Wù\©<ºÈ¯*†½4N¿÷"žÉ‹h”¦/úÝ¬ÿ"é¥ádâwÇÝÓ¡â›wÿçõ/ÿñ_ÿ˜½þñÇÝò›Åtùñ]ÜûõÓÑõÆ}ó!þé¿~ùÇðóøãwWTt¢b(¡"Y]dI¬˜áh´p>17†ÕbÁîïl¥P^¢åJ+ã¢šYGF­h	A<ÙÐVîYcLe9Ê6/%Qcì÷&½(}ÑÉRÙäEoÜM_$AÒK’l:ãS¡Æ»Ý«eÚÿ¸øûûü×ëß¦?¿úíñÛÿ|ŸM–ñ¯»å›èÕ¯‹ï^øiñþÿ_Q£X–’ÉŸ‹SPˆ]‰ÆÞ,b…‘B]Â”VwõV®ÉŠ²Á"$˜¦8mÞ¥WËÕµ%“®³1äÅe"ˆ}²ÊHäý¬ëÇ/â~’½ˆü`ò¢ŸMÑ®,‹F“qâùQ?;ˆü}ýówÃÑ¶÷Ívø×Ëmwl†HÞ|ñq¹ò^|óñÝïÙ:~ñãö¯_o¯ RyCÖë£ÈáîN 7Vä^ªšŽ`“tWzR®ŠÃJI6æ„vD`íTùOæmržÞùjõn¿J‘Óùx‘•òI¯(û¸^mð)]yp1 ŠÝ.n ë½äì.$©²ùšZSQ û ÝçCB¿Àû5¼Dßt±Ñ˜8rn÷£Ål‡¡â¿xi‘!(œÐÁãmVè§µ«ôp€Å€]¥'M€ì°ÌGÉ¸yJDmlÑw½Ü;ôªÝ'Íª:Á¢`!•®ÆÇIz8£·Ã“P<ÿz¼ˆ.hqÿ\d¹§ŠvÝA'Ya`µ6h&ÿ"{I¶Ëá
+’ªwÏõÔÄüî9ÈAîŸÃDÉ˜q`^§__Çrk—Áu•{£¸,ˆðÛ?mÝWÂ‘^ã÷°6<L™ì¢ã,JqB/üÚ8vÒ \ò1±^âŠ_n;ïö›ì%®õå"]¢†ÓëØà•ëN98ø(]†táHñq/WI.€ûI0RéÊ7õìÁv÷ÛOB’ïZûé«ü+Ö~újëºIM*ÑÈa—=1g|!<-ò^V­—“‰¯‘<©ìB0…uÞÖE/'#ž6üT/‰sŸ_ˆ‡O«õ$wwa¢,¼›Ë¤ë¸›‹¶´§§1®Þ‚õFFüŽ¯í¢{¸háçtáÖf2.ÒõÕwT±±áôpµ‡—c>gDf¢ê«„m`¥VS!R’ˆø!kËåÇng~$ØžJLYÿ8c‘ø§Du©/Ä‰lBŸ€/”€‘ß¯“éRyU¤¾À”ú4Ù†ÖAþ¸D¿ƒŠG¥nÌ-€›£V„ç½±Ï@v€Ûf¾ý¾#ÓñUt¸Š%D>âw^ ð°Íàj‚!„9¶Î‰‡<9¨äX%¡fá'‰ë”^jò•æE}Å.ë½Ÿ	-“¹äN#=ôíÒƒ¬GÒ‚à±ž™",¦òpæ’ˆDÂI$a‰,Âˆ¤:!iE¿ÁO¿°Rj¡"½Q¼K±*zbw9š²GRdEª"N2ÔB°ÊIjÑdbQjI¦ßölß¡„’†Kyä´ëÅòd8¢#ù>\³lIÒl‰žµ Ñ%V•V—+‘Ê¼$u¾**)‰ô]Š­8ª\’¤ÞÂ‡D«W”ÈMÔï¼¬¸F³Dv²îw/$÷ë¸_½D­‹2/É+´u…Þ3—Å	 4Š…v•ÅŸ³,.-îK”Å¤8Þï
+q‰}Ë|‘*ÁœXÏÚåké¤ÿ@Çšòù¦!Èi$Ð*ë?ØCXdXn«›/eÚ¥Õj²§&eöDÛ¦–"GÆ¤©¸”)—[EÆŒseLV+¾Äi'ó¾“ø¡¤¨3Jd"›t>Z"µ|FZ"¹*öÍDŽ¤OšLˆÍ›T'©Xìaéé¤ì/É–´ØÝÚAû"|óûþSÖâ‘¨&È"½½$òço(1—é ^dÌeœ.WËÙ˜pÇ8Ô… ˆÓòî¬ÞLÓqö’MÇK(‰XôÑ%’&^Íò$ÁT˜´±¶gG­æR'íŠx„Šx³	Ÿ`Ë,§ìçVöËyÚžÌÏÅJL‚RÌÁ'öuùÙ÷s’÷"!ïIkï’>Õ¬RÊkˆ4`­ZðÇ„¼'œ¨ËnsB×).úØh³€ñ’Nú„½U\ô¥éÐ\ôê¢_nPñL,f²â›rU®PÈ‹wÛýT~Wú–è¶#ÔŽUg¿qP_wØ‚ªñùÒ®ÙÍÇ\ß˜1@Ø^Ë.ãÉ™mÎåûVÂiJ›»6°¤øz?è}Uöþl[ø^ÂPÄK3ºæå NØ/9±9lÊ¬Ñ0ëµÉ÷Ôëµ¹ÿ|¥v‡ÄÔ˜ß~»$¡—mA£O…!Òò­"Š¦)’ÐÂöªcp£HAeÐäiÊ"Ý¸42ôd§à\Bw£’~šUcY¨¡KÜ$§Çy—.’Ó.‡³d¶/W•°w eJq)hº‚Ùöš¬ˆ kdVô© I· ¨K¦Šæ‰/Æ·0xîáÃ}¿|ßÖÂ‡Û”„G<ôsªš³ââßd¿ïg±y= EïS (q*\³*Ž«ƒ›8k
+j	‹&ÜÖæ­ËÑÈÀ¡ ŽKïÚ.[òòãòQ©x£<%¶edLµmw¦?›Èâ¨1?IK ª~ÿ([0X£-â‚yå.8®œ¯aœ† ÒDË¾gÒ«Œègw‘g
+^kò)}8“ZzAšmj‰ü\4Û~ÿ8ºm÷°C·Q;þÎÍ®Ï¡(Ò¼NºX-ï9n;³%E È­$KjRìÕë)ºÉérŠnvL]ZXýf–»ß£—àüöëkÆ~ }Ÿ—'XyQï+E,t×æ³m>ª¢ü¢J=qL®¥9EØ°s3Kçh%O:øäúG³vÞ9ûŠ~Žæ«Ñ
+ìš<ø[VtîýXbôyp_é…}Ï´If¢Ñ%ïs¬¤¯sÀÈÚ\W@ò!‹Ýâçàé!·§¨7¿`ç3DÓn7ç«1¹o ¾æà¹^yBg·jQÀÌ$-—‰$Ð‰•”Šé±8$¥n-sîÀ~j(ø®7œ-õ®÷0_o*¸ÞTp.7«%ËßVË‡µ—éQ½•CŒAL\úÓÁœ•ƒgåÓ¸;¼:\.Æçì.ìP»ÿ©’7‡ÅÏBóæx“Uwè`2…äd`«IªBr,PAº¹Ù*ùç8i ¢Ü.ÇL¤’DH›ŒT–éPR2ƒì¢\.GŸÅ—eÊÐÌF=”w¯ä„Š?Š1v”[qI9‚ÿÙ„GRÿ„×…áëòà®²ÒJùôR1›W‡á*[­üßŽf-g¬NõìkG¡ˆÚ§óágêñÛÎ©òé>®.¿_]]@jŠ´J°õ§âøAä->¾` dŠŽj”ãyÐîE| w_K|—˜(b‚ç…6f©ØŒ½eeV‘»¦|h«Ê–=N#žcÈôWŠÀcËø†'´:¬úöÌŠ¯ª;
+³’Ç)‹z¤Þ-wLúîZ·ßÒD=§ìÎÙ‹(Š>Ãcér{K‚³R—Í·¸±\¨¬²2½!xà²v½ù‡Bñ.×],5åfÌ‘ã`H2A¾‰Gn_Z»ïWãtãô(ñÆ2Ž¹í2j4Ø³µ¤’”csö{P‰ÕÒ²Ç0,µ¦3q~KÕá8}ö$©PM| yõ&f¬‚JP–…|»z×{ ŽÄP¥XðôÛ<ÍW r’›[B6¯G¿Ï&ì>Áó•D«x$#zøC}d¹uõI¾ú$WÃGá:äVóƒiw{†ZòÆÇ<G@‹ÊÒº½º:%_’¯NÉç†‘„ÐòcáG¾'r9 ¹ú#Ÿ+(\ý‘¯þÈÕc«`Rœ’…FÅNÈå‰é¿¯ÈWäbìkÑÙ­½0?ä64©gá…Q_C1Ýªóáa6~ Àn¶í¤[²±>âÆí}ó)íê’|–tuI66egë’¬lÀ`Uµmm\è>RBÕÉQäQ]NUœ %¯äX—\Ë¸©”òwŽ«úªîL¹±t]„´ÐL3¤þŽF`8_•Ë@K}t#R&ý©»Þ}ÂÝ‚ÉJwÖ¹)”±¡]TJæ’ ôöòÅÀ~RZôVæù\öÀ0ßjî¥ç¥pLøuG*Ÿïià¸«eXÍÇP¶•ÆP\#Ð@ß¼ÊKA _+»æÃ«ÍQ¹.Ì^£I\ QéñG“8ä¡ÂyG“ º	–¬D‚¹àL‡÷·ËÎ&›S·èUgEÜíÐ—mm<®â$7£[¼ªU…¢4:­Ó¶µ9Ž>ð§¯ÎiÙ÷J#´¨³MÌ…iÀjƒð¦íY®yH‹Ð÷VYôµW¶:ƒÍì¤±Õ+„²¢"
+ñLrÃh¾µ­º¬Ù‚l°¬A`6^-H¼¬zR‡~RÄ¤Ž')J„^ycU”F¹Ê–êÀ¶F¯D«În‰Ã]\X15[ ÒÐZH·yºÝuÀ–»¾æ:GcUiY«‹¨¾Îæeäl×}Ø«¹î¯QF´U}2r2ÒF”‘%Où(#eÀùÀæð’ïÁ1CŽ`8õ¬û ¡Gb)1™(|„Ïˆù¸¾Dfw!á\³l
+,šGê6ùÓIÂ–È¥•p>U¶õÊÃ94Éqw«ê°js
+¥Ä«]4kb©HÔ ]—jD$±ø¼ŠÌî€$!m‡Äâ”*Šb^¡1Ì>O`scÅN¡"Û¯ÖêQYüfµÌš_©êB«ð¢Ük÷£ý´u;–’Oø=,)Ä$Êh!	SÂ¦“‰äÑã17_ÜwûM&BYð=zICÂØâŽøµsh‹gÙvImÕb9¹ ÷bþj¢à°vÁ¬,ºYPƒ¤Du‹eýWã£ 	8Ë;@L»Óý3ŒÒ—[­NÌgìÞzrR FbYò—'eµßQþ––~yy›Gïƒõ‹g~{ûßâCY¤®$Ž;"qe^¬&{’9$/HÅL
+ÇªŸõö:°©¤‰hÐ!YK_õ00’°‹Rð0¬¬*²49Ø²„d‘Á@%Pzn8–ê²¤.ÄëE¸WèóÄÑ–âß)*ÈV$gŒ§/†€ñ)#Ó«Øq;J„ÇH„Ø(çåy¹aØ]å%¼¨[
+¬fãÅ‚­AÛ,‡¯²¯n¾
+)Ø,üÆÊªÂWû¦ŽJ/Ê-«&Å(Ó3‰j
+#–h‰ç¨ŸWbü<¿¦³„R‹ÍLJ5è[Å\c‚‡Ýbnk»4¿Bæ_xÞOEš8}´QÖélžIj´qŠ@‹Të«i±
+*}…“°<˜|ï±j×©¹~¥ßrc¸u­­²…p³‹e¤ ù¬@S—(š:hÌ¶%5]DY˜ú‚Ãá¾üþýdÓ7K’Ó¼d1˜‰¥L…HÛ×ÒŠÙ4O¾Ð­³Õzžå)›ÈØ@¡CâÀ™.èaSÑrÀ5Ö­í9Zƒ¸ÛìrÁgG¾RÉ5XN5­O—è“‰•†´tˆ´›éÈ ‘¨áÐ€¡8jc3pë¡^ýˆ„ÒÌ1a@@'É@:~0#¢dE4 ùÉ?apÃËIÙÂ4Üš~ ‚|°…Ñ€°èµ¨p3£lg4ÌÒHz‹ÖÉ@±5Èâ‘žY²Ñ1QíÔàÈ1ÄÂèÈeu4fG¾È”òy<5ü}"â†GÒpâ‚L÷>¼Ìúh žUt2chznÄËô£ú2U§ùž85Èï™m­£]FJHIõa7ÁÔ‚¦§±œ9™ê¼þv@!u `ê@Õ„ª2AÁÜÏŸ(&TÉ¦á@}Àm“É=éÈm“žôðüñzpCÉË¨T¦H&7œôÐK‘YÐ‚Â­€·†í—Tb»È…IUñ>å"þ§9LÛ€úü§»,UKÁÚÄëOOáXø¶’«Ç'×À71` …ÈÜ<hÀ@Òx´°|ÊNŒOÐ2v¹àÉà„#½ž,¨…O=<ÇDÉÔF±R!æTCœ²¬—’8õ\ä)®$ÚôU´Q¦É@É‘ÃV|ï0ëþAŽ`Öd‘Á<Q'su„@%ˆ’É¹}c Þˆ¯ùà†³zØ'6(„ÑŸ¬§86¨¡jjä¸ã¢›†M5ÎïQ©=Ûl²Éð
+vv¾Ÿ³}´È´•ÑŽŽ¢¤c“…¿¼Z-Öóì#îIÞ4â6~=Ÿ¯>d“¿a-ŠHÞÃ2Q½‘ùô¤aÃÔÌ´ÞXGwwŸíhY¯¤ˆ_!‚†â?ÊøQ¿Æmf)©|Êõä ŽQæ¶*U˜i‚2GÉnWÉÏ¶µ½'´¶:›lœÍÞƒ×
+‚ƒÙ|ÛI—“pxŽ+H*?6´ºA±&Ê‘R Ñš^±ö²±6ê]±ö°X{”}vÐW°¯Í‹CÜ¤Wq¸²Ã_bPÔY£DÛF@‹gQqôc¯xú	ú›ìjø\§´‘´Ž– «¾Å,µ©ì
+4¶á0‹=ZVùÄ°¹×­„Í]›¥)+¯ed‘I5-£Ç4av-#™hl€DH€x!œ(Æ€ž„På ½ù‰ËJg‹; uÍcÆà“Ö¦"%q:P4:·“es(WIïÃ²™Ü*X\ZlQ&…?¬6íÊ\A0ï$9h¤úT&íÐ0xj!
+üEîðyÃZSXc“¤@[çó‡tûM¾h&Í¹7x´6«]6Þe 0B·Ô¨¦n­¬[ >h·`„3Zd»éBÐŠžB%^%„JT„Ós–'3Pþw¼‰ç(üXi{‚Rå-¡dä€ Ây˜èô#j.~bDÂ¾ü*d´Ÿ¾:p‰®{ÂñÎþµZ>‰}g<g‰‹E`?â¶xõ]gsÕ"3¬-¯ZŒ¢»²ªÅ·tI`UâÈ`õšX¦gç	…s-ín}«Tï”±«”ÒÒÝ¾Å½)<Óp}­Ky²¥³b_‹SÍ–ƒgcÒ†Q%1O3j–gÈÀE®_aAµ¢Ð›Ÿ—M”Éc,¨•0Ä?O§õ›yò8^Ø,›/ösÛJü;¹HMƒàžµ1ðÜÎjÓÍWãwÙä¸¢ôˆ‡¢¯ŠØ
+ÖÖÄkš›,Ýe-»¦ˆB› ¶il& û¹Àr·,ËóPuÿ}™Fö•ÔÈ3G¦ÒS£_c,è×t¸,»é®>¿»–¡€z…‚FPyÜÎäy¨
+Góõz%5òÌ¡ Ÿr üFÝqS×
+y„ëîñH‹öpÆÆÉ3‹õ)#EèWAŠ@
+¹iP™‰³Ä
+<‰?Àã¤xî€Éê0æ¢'Ù¤ƒÚÊ;‘Y£ˆ<uPÌê~¶¼‚Ê¹‚JRIü¸DPñ¨0J<wL	™E©SPG³ïÌ–—‚%2403 ÚiI®fG€—~XiwÓš™Áq ê~µ¦óNv!ö1³Ë$öéd²A<Ðe‚mÔg´?ˆ÷Ct&¢ý@µœÐ¡žu E‹¢Ëf5ÏZÜaêÖï»¬>X "abÿzq?¦N=ˆ]3Nòú[~=6ÎÚ¡Ñ‘øPTô5·½«8åh¡9JýT ƒ—xq5ËÏ@³C°R‡Ã"Ác©HÇ84.çE46&¦Q¥~)ª„°'†X(ÿWº›!«tÛè@\7zd/Œ(Bš{H›¹ýÔ“Ä6b<kù­'–·ïIyµ8P%•´IWË€ó´èEÎ…W–{/AÚ…ë_ÓØ¨‡î€)ðE¾®Q|©nià×‘]0^—+LôXÏðåR„#È:%øÅ1xÑpÚô¶‰XiéF—}«•/V…Þ7Kc¶Ä*óO<Èº½k6-Ál¡yõ“KZ,ßñÐÊpsRˆl‹™P±®÷£ùl,:Ãf„•I³Kµ~¢˜’R	ŽG{Œ1ÛÍ3óõ‡ÙKî?ÑZðeˆ‹Õ&Jâ¨A³¹4Î4:‰`<à¶®±ôIH–ÌØ•Ž¹.}ù,çŸÔàÇ|%Ð‘&Ö;¼²€f¡aô‡f»‡árEš´¨ö·Ê5òâ›…×Ú¶xáÒ9i<(I²Põ¯‰˜£5û!@	‘GQaÞÂ Ãq¿ð½~ü"š†“išú/ú½,‰’n6‰¢±BˆÊÂðº)ŒýÃl3®ÓZ–0T€ŽWÙô¸/*½êüžÝ@ÉÉ»ûæûÙüÛöÿºóóÛÝî«ïïÿúý|<‰¿}ñî÷_gwíõ¿{óðÛàF¦“ÝÍo¤[¤uâSIÍÂöŽ)(Ù`6Î^oÂq´$¦ëœÕÆ}0½¢eúŠGÖ=öýmªÆŒˆ¤o?¦¿¾Ï¤ýˆFyó~†š3Q²ÆŒ˜ÖpwÄr<“)ÚÄ!oÿØÕ®|‰²û¤‘¥$l9âæPÑ“ñ†ó¨êâ;hpõœ9Z¼I·èê.vÃ,¹º«w‡ý @»¼Bé‹àþ'»ÄK½H—ÿp_˜{×{±åœDZ¸‹ä×•ˆå/|åûrõâ¡\é.’ÜE m“E ¿ûRÝ€6V¾ÊÃ3°^‡æÝA¦\„ûi›w9Ä¨—.ÇPÖK{WdX.žbí¢Š—XQÂïZåô$_4«_£öÊ‚{ãÓìR/EQ]½()•^’åÞ¾µ%­_õú¼/Tã˜p‰÷h\/TûêÈªâW¾~/ðV5ˆcuî··V’ñúõ®g%\„ë°˜œ‡¯¾¾‡§˜B³€³»D~‹	ÞvI[a«½¯+&;ë3“]arG½WŒ‡3–#rÓ—CLŒéuk69Q\B†“0êþ+­Š ž,ûuµâ¡Ü“ÜæºÕ¯,ã#r½ãõìDN}YjBŠ¢¦2àWÁåy
+.ÒM°øVÄ³’YÔ›;o·¿Ïu{é¥qLr!ÉñJ7¶MD=Pòr¤ÆºœÍl‘náÀW•ò›$šuù™ÌRîpÈ‘²Ê#ïÎ‰¿}bÄ¡ ¸k‰š…bÂ¤:q¡èíÍÔZÇºJC-k©	í’»Ý­
+¬Â—Â÷æ‘êØÒ¼áP†’@ iO•Úìâûô–4Ÿ¼ž} ÊLaà,ºÌ°ù'6ô¿C/kz Võíh5y´,í€bè£ É5‘$ÛoÉž•Û¡-Ãö’JÜ†tKå[r4ÅÏê%‰—íÝ0ÉàF±½£eË;ùB¥›åj×ArÖ\ÉZ;ÆkÍ>ôP^°D"Å;<Ä4:¤MÝªóáa6~ ã›Õ‡b£«åýöKb úá![v°ö‡1ÖJaGÄl=wTRóúŒonŠ{&H_ëV‚züu‡Z¥8Oú(:`¿–W¨k¬3AÀ>UÉ2ŽœïÝñ«ü¤ëZõ–[ÚÒá§BÕl"7lÛIw;à¿èíŠó[Ð¨¨«4ŠUXØ:e…×¡fA©61‡´áf¤muºoÙžÍ6áEÅ„6f›!vkj¹_Œå™ÍùRX[/Pg/0:uRPÙ@„Ø€p›O©Áð“ÊÒJqevo]Häð’”ºÝ/€§´P.‹hEÊ%w6ÛŠ-¦½T/þ“•FÒ]´Òš	ò¡Ëšð"1õüp.‡K†Ps†.½µ/Ï\Ë2PJzå›CTàe²«ôÓl-ÃØCH”+ëº²®+ëº²®+ë:ëŠóX—eW-Ô8Zt9í›@Ãµ,ÒZP,‰r5»ÐžÌÛ×¤N%5 ¨ø£¯kZž»Â\Ä•™wÓi:dÃN03Ûúq«HƒBuGy˜40	Œ“yÎœÕ#¤£4-Wi{Ê†Õ§óÃ7ïÔ¾œ®Zª†cº²T—ËÉX4Žé-¶ËTÞºLbÇ©\Úv¡ºˆè[·M ë MªTmP}Ò>\³N@Ó\ü¦‘! MéUY¼m§	§œšvD¥¦ê“’Ök„AGjdT:rþzÊå1_Ý[Ö‘%kMp *¼ÍÐiÇHrA¦Ó)¾3§e¨úÒ°Ùêka³Úœ­•§œm|qpÍÙ‹"”Æx9¹Ï‰ªØw	bÃWCßìÑ(A%lPH¿†J«‡Cîu«jÍîU3¬¹ŽØ©´±Vwq[ºÃÚÎºc%ÃÛÚ,Õ=óqÌWhX‰Ñù‚ú\ÓÄ›SÞ î9Í	è<\rKEº%N¦xWö½Háâó“'›éihYtð¡YCqjgñŸ9ÈÀƒýri£\æ J3)Â³ËÖlÅIó‰¥3Í[Õ8•SÆÌÏlØuU1°T+ªb˜êË5×›áz6Ñ»±¥K.:Ÿ˜‘7Í¿Ü/†Kð$À‘ÞòO,ŸÒ6ËYYì}¨ÖH.a6Ù6Ÿ8L‰HH†ÝJ@ÎƒHj"­VÅ\» ŠMµýaWA•ãKv#°ƒ¢/ãü0§ãVÀu!€ÙQFFÝðWþ#´ê¸³D;ï0µ&»8_Z´r†<%Š,ÆÖ435Þ’‹2mÖz†ÍÃÕfíj³v6k>øLU4Zû’
+,4âûå{pã]¡ºeÿ<Ên‹n'%¿y×¯vo‡µ{“8ÁìßúZéWSëÃ4÷€‰|®4§b¢yÊUæqi±Qölu †à4”îÔc,Ã®%Ôq‰ÚyD]°qqL™¼Q¬°qql˜+Êç)W{ì!,a<YoxaÖ‰îâ©52³J¥§? ‘ O0´žT“îtL-hHcñœÄêÌ=^"q{ÃåÝIa›ŸÔh=¬Ùenm¬PzVæE™1æÑv×*9á!"eV¢rÇ¢"¯‚RŠÂC.Ö™£Ë1WtOÜ-ÕÝ¢þCy¶ñÈ]ÖÑ9h«+õ¼ÆêM¼³\¼ë¥6v¬õŒå5r¬Ö©Iugkb•3ûÑ?Q‘mžšÑ"«®½è,×9Rm“XØ!íD¯ã³¯<cçØ„NhÚŸ4qËJMûí?ìÚ$ÖzÓ‹rÕ•Ø­˜šªýL(kbˆŠ:"¡>c{}KÉƒ^äe™\ñ±) ‡J©bOnè$ætœÆÄ‡íø³ín¸ØÏÁbq¾º¯†TuöBòLw|-dYžQTìª jl·Ðw–tˆ}0É®†ç„êCg¶ŠfQUcöAPwƒ¼¯Å™îŒá‘ÂùvD	µäxäKÓû	ôå)éihôKÏ°Û›.Ÿ)¸JŽàMß”ØŽÒÆrlê”-laQ\dp‚ÒK£ÈÁ½Ö9¤2´éÂ8hÛ-ˆƒ¶¬……pQZåÒÀ¡Zm…ã×Ó´–?lkg^ÝÊSÎnÙXmÈvm=hKŠ;ËèÕg­eÁí¸ñÓÔQ£4ã]Gnk«ä²C%T_K0:‹l»µÛK´‚‚p!‡­>›¸P'œBKý[y³ šâîÝÜÃmÖ(IB/O¼PUÏ9¢TWÐ=çñ:%éçÙ½×’tøÖO#[Ù`¶‰§œÐ¼Ó³‡9gxš¹e¬ó9\«r°°#[³€¶Õ|[á•/KêZK9ÈaZ`o°ó í8ÓYR)^0¡'Tå–˜Â§ªÀ­£¼­7‘‡TAÖŸÀ‹U<ÖR:Vž´ÃkëOÝ…ëë+OfkÑSkOÙE¨kªkÎÉqÃ¨ÖŸ¹§£ÒjEU]Ž9¸þªsÙZ«f«‚-Æ%ª\<û6aìÆIÔŒ{¥ÔSe76Ïu„NEÕE¯U¼‹ÖòÔÒðT^ò'×îèªâ³ÐìLgó¬œ.‡Œ:Øå£,ÃEºLïyƒ|ÍHyHÔ“tŠ"ÚYú‘¢F,;gHƒ«¦/îËñ ØëÎ»eØ
+âi¸¦¿µH‡’5ýæ Lù¾2¿,yÚ9$ól1Ëñ'-?.=’J«»§õšÏ \‡ÛÊTCr¶#ÝÞÈõQ]}Oã™Âà:•Fær´Žá(p#.ÏœÛt vsìžÊ±E¾GŽÇ8>æ@æ	ÈåGñL½GuØK¹Žsì7³–Æ~3kŽþÖ€”.‚Žµ‘%P†^w8Û¡å“oó‚PÜÓlìÙr?œÏ–â¾
+'öˆfŒü¥¶züØšt…Äç“Ì{ßVÝ¥:'š³g.¸´ÞZ9©ˆz `ÒknÊ8uûN4›
+‹ZcvfaøËCÙh”µÆãÂüWË—ÓÚ*]¼ Ýi™qC{îÑ¼ýåF‹m¨N:8×)b¯íŽèëi¹?<»l³L±çê)÷Â‡'Ç²¢¢Lr»Á:“u‘&ƒeæ®Ðb°âÔ`°æ2»íY©CŸë‘¹Æ£öQ8ùPVKØTBQ	ýöëk¦‚|º*(OJð¢žºH}¤h¨$™ßvÓID/û@É;`ÖR¥ŽK*!¬pMx|bGÀnÿM¶™¥s´¼'<ó0&4+½êÃ>>¾)oä´ÅAÓ±eE×ñÛ1çŸê%”I¦xiÿ­’lŠÑ&Ê;TŒ´2”ŽÓä¼Ô¦6¨üúü…ÝuºAZ6ô†”úäv›l2ÛŽWï­Öf6TØ>}á"åV‡7*HÿTÈ)W­í’¦ÎU·—ê:ÊÙ(ºÍIøÍîZ@Rj¥m€W~p(¢]"Ñ·BXLðÐ Âr¡êö²À_¯OŠCtbá½çþx@Í8Y%<^„Uâ5/Íš—¢æ˜&³xºÜÜ»,{^³¥DÚSíÚÞe3Š2ã.õ}8Ý E ÝrÁ­ÒÖ›ÕbµË,Wû’jñ‹ÙøÝ#»™M¹Ùˆ ©‚^ÌWCËIúŒíšå‹teãCˆY/‹OŠ`*P”ôA*äÚ/5bš'M~¥ØšlKX• ‡$–s)û-­“‚H§‹®f×wãjÖ%¾ÇjìØïcíGE×ûXO/®÷±6ñŠ*×¨¨[ù:Öë]ª‡½Kõù w¨´Ôí~±ÀbvîWd0®w²–¹“Õ(%½~«ÄõyQÅ÷†£ÎþÊ–0ùì}veTWFueTWFueTÇfTq£²Üyü+ÔøWt9üëxû:·…ZÀŒŠ]š“ãxÕIµ—ñªËÝï_†Ek¦È<Î™bÚµ¡tÃsžäïÃÙíF†„Ó½J8W	ç*á\%œN$nÎU.Dê#Âý;¥sšMÖ&ë¤óùêª	Í%n™à»Ž×ùŸ±¾ìøèïx¾‚Æ|÷¢„óÇ/¾ìèýjV~ûòÃµú·K“¹BghÇÜQ‡‘H˜¥•¶C.Á9¢^ùMò•‹\¹È•‹\¹È•‹s‘SlwÆ\Ž¸)*ˆÄXyûZ#ºIùí«(\Ù¾ò£ôúÛ×3
+Êâ˜©².:¦ìÎ_uæâÂœÑsEÞ |2Ã,ÞŸ³+©²Aõ@Fçî ‡^æé¤¢n„Ièã¢}:ìŠN‰Ûðà(¿¨—FXî@– |¨‚íØ4ãÜ(ë5»Õƒ2%J(pÖ;ú]F$EÆý¢â@V¤©Å½å°nv4qh"\¨t9<n 	!Žî@£™$2¢ˆ¥'ÖV‡lzŠEÍcw™§¾‰QWmbÁs@%ÏgñV•@/†u¥PPYt@d–ÃrÂšÖP0%|†M°D“,¢šÍÚwBK°¨+bÑ6bù§60Å˜×´šöõ{,î`g3bœ/¹Ãá[Ä±ç»Ï€"7³Ñ~—YÞ„g#¹Ø·ÒœGm
+µÑ›¿¢æèåkÒdHîj8±toÒtß¢òmÿ0›à|ymCJ81#2þ³eg=û˜Í·­icOkã¶{.jdDIR¸•Š¥­kÛ+©Œd&áã7Lë&P†éÝà¤<–Šðé4P‘5¤’ôÞÅ3äM’þµADü•¼tŸÈ±/J°Ú IYbËìHêˆ›š)pq'¨Ž“âòðõ€ÄÌýbY¶p2éSÚH¬qL˜Ì(TŽå…G¼¸Ëª¯‚äU¼
+’WAò*H^É« y$í‚dœ/HZà›)ÞU	34$L6§W	óˆæ§›ã*Hwé½-ÜmÀÁ²zÒæZdõó-²D)×ãôëqúõ8ýzœ^ë8âû(Q/Ÿ LôiŒªfæ7º‚×:%Il˜e•ã ±_Þ2ëÊM®ÜäÊM®Üä™p“'åKÔœÉÏ$ÇØGCs‚X“ÕLÚghœ#¶Ã~_‡§Ú°ÉUsjÓÃ’Ô±œº¨žr_Z£‚•¤tæ q«‘üqšd£ý“6¨2í¡YÇ#bªûL9ºÔé¬2[mÅ‘ífåëŸ!+,!p—Ë´Huñ“ŒÈn¶ÈÐ–n±ne\zÒ¸ð’ÏÙ¢Z´v“.·óJ¦Ó)ª£²E¼+$z_K5m­§:«úh;Á”æÅµuXb±Ÿámp¡JC¹­®káÌ>Ñ*å|JPIä®B:Ÿ"ÇS7d›7‰oÉ™;’ÊRõ¦ºã‹ó¾Å]
+Ðx:6Ýz#Ž9³Å¹ á6O<-5âÈ êŠc]c*ÀºöÜ\dXm×d¡v»æJRlÍâÃ¶ÄÖêjƒ]ê“®Ê} cã­(ŒYüŒâx”h¹j¸‘žôâ]÷$ê”»x7žžAÿH~9") <ý¹ÊðžæÞ Çà¾o¨˜}8ížWS1{À&ÕSÌ¡Au³‡nÖˆxû°ÚìÆû*—;£–±\b§ZîJgU–·ê	•ïsö¤º.õg>=&Î”½è6gÌŸF`œ1r‹Y6"¶¨ýŽpdõù¹ÈË#sf©(LG¹¹:è™yå9º¨#æ¼¹É¹²Í•Q¹^)ð®†ÛQmòÏëFÈ¢æíÞfÎ·è8öB ¡—K;_¥Hh.Ö¡Üò¼#µ‡Eˆx*y¨ŽKÙ¹÷*Vçb©ýÍž<ÅG¹zåG×$Î)@r:ÿ¾Äê„˜\êe‰»ôãj¹Z<wÙfQáÖD0Qòª#”·ßaÑÒ7œH«ÅTÜu³ÂÊl»‰ë5V¼žnWgóMhJ«w·ÉŒÒ¥+ö$š"E‚z_âü‰èµâPV~É³ãÖ>QÂ'k³lñÈÇÞÂ~ùfdÙ›½uXž;æLÏ(S®º,H÷rs]”‰{Ët‘³aUî~<Âò4qÌ}e7øÈ[^nÁsº¢hÊjšjŽÆ…©›ŠG‹‹²uÊ”=Æ¤Ò‡­Ýçã1 UJ?Ðý;*`xwœd–
+CÃæóßãªŸj.¬‹ÒAMNÙÚzâG”ŸÄàÆ©7±µ•‹²ôÎ…‰ø.ÇF¡êâ`Œÿ Šôš«äm;ÁìåítÝÓw®›Þ0p,ší|‹FßnP°vÜ&.ï[5qi[[æ´÷¹V/ïE‚zè}Æãr*¡&_ëR®z9D‚e}³a‹_NÇ"ÜšSÏ°Äžz_É¤!¤5UU©ìkÙ3¸á.%í0ô!\h±uêpÓl®…t<Î¶6¾ç´Í™kÐR^¥ýºû²Ž?Š”¢lYÝÃÞuØ
+®q»E‡«ÏÎ‹]êÐÊ!nv‘‰¥ÄÍ.ÇºÒFHÕèæÂTBŽÁ™-gî#jAGgVeLîV5:ùâ*R´l÷È–=Õæá¢T*®YÝÏœªÉŠãfwÎð¾Hgó–°õJkkÚñ>QñžU(ïmÉ»£Žbžþ­:˜ÕÐ»%,œQ¡ŸÛñeV1Ýƒ¥]”¥…kT6Ù4Ûl²É0,fË¶…ØÇºªh”O6fm‹R=y´.~œ6«yæ^r>Û—âdyº¡0²Ä@†¼4€#.à°ÒÖÃkÀÊ3Xé3Så
++¿¤„¤F|¿|PåAi)Ð@ÈºÓ-Zš”üæ]¿½<ìÄ¨­‰ï²æ1þ¤ìc‘Çöý¨<Ï|¥Ž< Y]m°Ç8@¤¬!xji$à Ž–XQêƒóºsB
+”P±h~ôòt«6?GhÓ§ÄÒõl¼Ûol÷3Q}@åW9yÁ]u¼Ìeå²®Ô]/¨{6ÔL\ù†º„âë%w'¾ä.`8JQïün¹Kô^Ô5w=c|/èž;£ñçxÑ]_oäÝt÷d®L.€ž=?aÑ•vµ4¼Ó.·ô#\jç‡sÌSåíÊ¹¤‚k—|H×®êzµÝ÷k4R™>žÙÇÙdCúÙªà0½ÐãqÍ¡Täp“Óùx?‡ßãÕr:»ßoH4cºZ'Ù:C+m9že[îòÕ{ËìÃV)Š
+­h€1‘àþ\QbË2†ûõp²_ÏAÐÍ†$Ù’ÕoÏIÆš¸¥@mz3#²²ääQÌL à
+­Õ©^rCê¹–8›Çú’d:šÍa$Ù.eëBÎÝ•"çÌà<ø¬LØb€÷8Ì2db=k62[øp„¦áC
+ˆ·‘s÷isÍÜÛô=jì-áÅ­ãõfµÎ6»GÂE‚ˆJ¼DÒñNÉœN&¨oÛ-dÚd“")æÉ»[Y˜*\PL¢QŒß)Mf[Àµ!þ²Ec°{.fÛ-8ƒd„-?zB"Ðª5Ö ¨w¨rˆ¡QŒ
+¡M\¦-Ÿƒï÷”Ë o¶»G”U%‘òËôjÆ‚¯4Q`…€eÆ×$†¥<6—0€O;•âfôAªAqj	0i\/Þ^ÏçhélÍ¨1'XÛÖR-3‹Išå¨ç÷¼^7IÖƒüÁéò"ýÈAÁV§ä?É¹)ÞO_Ñ—(¿ô²!EmVH*ÞÜ®S´T6«ÕÎ–»Ïx â¦øˆœ ³eø°÷~µy”ôñøƒì}KHGº…Š¾áÐÙåøÀÁ‘pF†x`+LòqÐøBæu‡%<ø™­[z€€6‚;Ú`Ÿ¶x‹ö„[¾¶Æïð›è+)ä"zŽ±Lzóû~6~µã—	Í–Ì€ßtI¶ñfE­GD.4‹ã‡Ù2rûæþWôP
+Â‘²ÿm¼ß€¯õ_ðKŸŽjº#EBL·ë‡5~MÄ¡‰€®t¿[¡_ƒ´ŒSFd ¶zg¤y=¡aÜ
+¿KH²âÎ£aÐ%¯6ÛííÇž,Å”“5Æ9 JÚ·ˆ:öhÁlßmo	¡Ú"Pù‘çEEýÓ!ú•D˜¡o!¦<ø`‚ƒ_>&4øåaƒaébº‚_	&(øZ‚ñÙ$„xàŸ˜ü	½ÀÏ€
+dH B¨âú@¿|BØF	O;t‡Ì7ú)ÆŠ<…è—OfÇ?Âó…§OMBqº>kNìó|^(îP²^†Ž0¦#&tÐÂ.Ç°G9ì³qÇ¥·EK¸Ûæ`2°T_ì º{n(¤ï“!0¢ rÈqn†aöLuzlÝª	Ç)j2Hçíœ);x™X~)É>—§…e	ÖK4-ãÒJy3c´·é	eï3œ–ìJÃûD‹¥§Ñ‚!vJìû&[Ï9Ô†¾ø²Ì>0	b‹#:à(_B&ä´$‚+9(û‚GÜ\ó	Ã -pïVÕ^aè–ºŽw•†”™H•vƒú…¹‡uøJøÎ-Ý±|Ün9ÈC·ùWe÷K|ÕT!Á{ÔSÜ«|š–ˆŽ´ÁXÝs^ fWô;Žy&}öégàw·é?‘l€fø~“‘–3öw»›­·Ãt>çŒ
+ég0ë”AÞÂ>bž"éÏ <g¾à£htÒÉ±GÌ4 ]¸?·D^ïGh“ÆôZù¼™½O)kêQ’ÂR“².ûlwM>Ü$£cH&[ƒ
+†45ô)*Èß©&~(‰X7xj:¬ƒ"±‹P¾@<_´Ï!»_ŠXZð	å+äL±µtºÚä„lp¹ðq+oÃ.]Iâ39’à²VØ£)Ävø†À¸^Ûi¤>"fAd[6ÖëPyOGEQ ¦yÈæk#Mh)+I¤4‘¥=Mü•"êb®mÑÖ~O¨ED½ÛÈóñë®þ:Ä¯{úëè†ðg:ä5“öbì2ò÷²ÐG© AØ†}ìSÙ¦†%MDã€ý@
+ÙšNV–óUŠBŒ—4—[oÑk´'ÔSqïß¦¨uD¦dö¾ÿ†Ð1#o²¼Ð@ò®kGãEV7~@ßú”yÒoXdÅ+øöaGÄÅÄs&ùç–^â«™Œè¶é†ÈK¤èGJ:ŸO´o7ÓÝê]F*Ðø²]Kæ£‰Æ˜Õ¤:cNh¥Tb¾ÝîG=
+ÏeÒ¥È†¹Î&»GðCxJÒûJ‚_ÅjO¶A}2üø5±êFŒÝS^lìúlG@K µ.câ5š‡Þ-tC:âÛXôˆ$ÑWÂÚ‚¶K|dË‹0Q8ŸËPÕMäÌˆ-e;©a]¹½ø#~Ý“ÛKòp†àÁ-¦dL4ÓñT¼r{ž=üCS`ˆ¢{m*¥rw*©¬vï{0Æ¯#Ú™“(BH/¦Ø%§Ð©—XJQè²×US°YêéYR¨eôÕ–È3ÉÒô½¼¥"UØPÞ—ðsø.3¯¥B †ä¶·_/¾ˆÿ#|ñí.GóÿóÛ_ß|ükðÍ«^ÿõßÞÏ~ùmýÍÛï~ÿöÿóÛÿœÜÿ­ûÏßÿÙÛ÷ñß‰{ãùæý÷Á›ÙC’<~ÝTy$·D¤C*8„m‡ÿÜßgÐûmÐöÈ2LhÅ­f½Q?i©‡‹Õd?ÏK²l¾Â˜˜~(M¹z+Ûb»*˜³ñj“½$¥l_’ï/áû–¿Ô2êÏ·³åtuû¸˜Ó£uìÑ¼ÞØ‰8>Ý)ò:û‰V'éˆ^§³ŒœOJKpC¸ép¬UJ>Ñ?J>ŸgŽöów¼ÝIÏ^i·žÃx¡Öáó:xñ%‡…g’«…#4HïÑNã>Åš7r¡6–~ª…Är!‚`ŒA%i-U3ëÏ*ÑøFeCª®BôâÕ¬’akö6h ª[÷â°ÏˆšQV*êÓzøœ¥ke›óÚ	âÕÏC"án‘Ìª›’D{T
+„ r)±4ïk… ÷ðŸAo£t;ƒ÷`¥7ñYúi)DM>8¥†_ä‘~³;êAŸ–QV*BKc”MEûÑ ðb2|’™}\¯¶hÄÉ¾~Këb™øfPî4€ðØ&¢X€À þyÉ“ˆ_ê
+p1–F0:,hªýµÑÿÙýp=£Ö»íÐü‡ÚÂHdGÛq¬(‘ñ±¯Ï/N›1GÎ*±„R+8©èË´¨jµ>£qCö jÙð…ük¶LÖ:bb0ÆXN¡>©¥õ´Òxg{ÝÜ"µEX^™Ól$‘Ð>¿GEÕSÌw}0˜0=©ž§câ¡‹	Òwù·	]ø›¼ô-“jk¼4f&1&rÁbŒºÖV:‹WÆÄ10+«¡HqÀü:‘É2zq¼Ù/F‚†ŒEhí³äµ¾4ÐÒð‘Ö…WM¢x;ƒ`_¤Q.Û	yŒÕg“LP×Þ­WÌùÆ þYúiâ8ÿ4$FMj·–áxmtƒØ`TcÔ"ôÓ˜‡ñx\QkõgQÕ)‘ŽFÅ>ò³¼‘±.ó2´fÊu¦€¶}´E:aà/ä_s2à­zHV­<‹ôS)X6
+ Ž—Z¡øûk <³EÉëÝ#1Dj¶¦·Ñ^„óƒ:0hcžs+V*3+è©ÜèéøY\Eó•A¶bCx¸¶+…¡÷ü‡:#]‘sHÌeÛƒF‘OJl)ÌÒ`{	yßÌµÃÒŽÓÍŽZŒ›uØØHÅÃ“Z Ü5„*ãwX7Kƒ»Pšð¥‘ÕØXñ«>a$nÎ’qª—j&ƒ§óÏëô‘-1 g©4ÝK=£}ÝI	¼ž‚ÎáhQ,½QûàŸõfFè2w|pª—j¦œñÙ lããCÒ½Ô3º['‹Å­Å©^ª™ì0Ÿw a&FœÎQš—r÷êà¨Õ-¿2ÕµhÊÞžT¾ÆeµÊV£ðYËKCÊ†D•U]R&ù·Ú£P)«2†pØH–ª¡:*ªH.ÀõÞBTKÄÓå½ª!::ê•óiº*“p[U™äý£*rxÆ¡P)Çótû0äÖ•´Í¾gˆ0¤\Òè2Å”J¤6Ð³5Poš¡1.hYA›Ü­ñykdëÝñP•wûeÊU@Ñw‹AÒ¿Ç–9N
+³¶Aä±¼rÕ4ƒ“é]µš¤<–W®)gÁ±«M¹#ÁgÓT’OÁHŸÃ¢¾ùÈkÏéü`/šp—ÝSçç&Ú^µšÑõÞEç+p<f{=ú®»
+(ú®6(zŸm6³IfßÓÝÚ$W…	,ÜRÍÀEòTrY_º– u¡ª´¥<–W–¬Ìµ¹µT!—7\˜c2ïãÒÃ¥ä²¾t—dµ…ûbîóôd–W®¥)›„	:´ÏˆR…Áìm¥¹ÞÛæk™‰ù*+BñLòos§O-û­;}üýµM9¶Îd®E½,R
+.Èh¡‘ÝúÒ"v“D9»û¼
+•Š\k‘ÌÝÝUÃw÷ú+k•Ñ½e›\zÖ’Y^©3Õ·®uÍ÷-ÌN¯Èì¦³Ìü¯jç¥öi«9±¸–ÎöÎÆæõ4Ò‚¶‘«^‹½ï¶%mý`ƒ¬	å)±­ÇzíÒ&ÅþÙ¢]>=µø,ý4µº°{ú}Ÿís´ºv S3êÏúÑ 
+@(·	cYÄ/cëÖ‚[6i<#~Kÿ˜è„_ù1_Ü5rª$©ò`r$é#óÂäœ”«@ë½½D×{W79½w“¡ôàê&ñ¼ÕÖCq7IÖnê%ºÞ›¸LÒ}˜ý+Ýˆ1ïÆF[¬ÕJÙ,¯‹Ò­´TJi1”lê“®EEX[?ØGþÃÐw°Ã\ù€§]Çh5‰öhë1ùìxy£Œ>‹Œê“~¶2a¿ËÙ
+þBþ54‘ø­FƒÆé+)@k™–Ñxa´íÌÉ
+ø%ù×Ðzã·ÃÉ~±Î6ÊÀ©™µfé™Ì7ŽŠ¨¾¢ZER&óIW8Å}¶¤v÷êÉ€4<öhœ”ªŸeex¿[P²­;zAŽ×ŽÄnì²U¡-·@Jf¾1Ø3I!ïâŠgEšë.n2Û®çéãð}º™¥²eH)–mËm}©ŠC0L›ý:i$‹9€NHJI'ˆ¾¯ïVí-)S^¹TG˜<.ÓÅlŒý"ˆöÎ*©›É,¯h&:},5Qpâzo(ˆ²t3ep¬cQ6 Dhƒ¹qñ<”TôÝXÕ$½MŒïétä—t®/f{~Çk]”Ìt>@üm&ÜãP,U}"­æ.cûHbJ]aËMFÚ½}˜­ÅÒŽçÌ•M—\ŠË.‘Ä0ñeY6ûÉðA¶âé•£#[vû[ƒ‘ë=ÇS`L –ÈxaXº»”	n%†ÞýÉ5‚"i­T³ÛßÖT’Ý^)HÎ)$ï›¿ìôDÕ“öJ	Êf^Ë+µû±¨‘FÒÕº ¬¤s4À(ÊýÅDU+§”Å1— &ÜÈø#0Þ"LœaÿÔ²'ªŽ\ïIN—}D©ðjªBa"«ùÆµªp
+ŒÄuO•V•šÝþÖEÈ8ZötR‰¥¼–WÊÁ:¬Ñ10
+’›ÞlVàÉ»y?“!¨\£¼–W†˜K’pj/%ˆŠ<ÒO•‹Âºþˆæf&.H¤ÇT–óHS7j¯³¸´2iÝ¥-	Ké¹\%8?èT¬²n ñò¯A*46“N¯u9™¡¶ØÌjyePŠª3¬!ÝIX·ÁâÓPØbtuõl~ù4§ùÆW¤nÅCAe„­ê/qš&x˜m –ÃFâ*†+@N…ZvÇk]EãoÌ¬š(ö‘ÿ0Gìƒ[qÄË°5šfTŸt³x®Êbð?–Éƒ˜ê*584ÎNZ¥§7^èznüï$Ì>«%‹"MÂŽ¥ÂrLß¥"åW*Í"›åË²o"Ÿèƒ_Ñ .²ŠÃ–›÷—%–[`‰£pâê¶µlšÇòÊ˜©ÕfQñD‚g¿,^mö;Ãò¯I–ð¶SpF‹”ŒÆ•«ÞÝÜW ÙV¢WðŸžò!•Î'¥f ÷ðŸ>œÜág·zÂñ_úBë=ëB†øC#‰Ã–¬åcmC3«Ã¥æÒÍÍÅfÝðfq•.
+6Ê”ãçYÎóé7ö×@ñ.Û,%­b¹£:-£þ¬“0/d%aü…ük0aƒIƒVƒ	“Ôæ9Í7†,ART“:Eé§±Å§œ¥èî†´õÔÍ–slCw$l„jöl¦°¼26‰f!‘vs×zd/ÇõÞÕ?œ Ëù[«&ÖLfy¥2-
+6âF%8:Xp!Á¢rœ-¦óùêøQ?¤›t¡†É.µ…lTO³Ü: ½ËY€kbùñËÈÐüÁ—Öî+ÙÔ'ÅßQß¹Ð8‚/ø]È”-Ñ!“œYÌ€/±ÌzÑ04lUy™¤—¹ä5„už:›gÅ"Ø0uµBÉéxmL,OæDCWuj-¶)…pVVÆð?ÆŽµGÏÝ”€RmËm}ipGœ¨@VÆ­¶T(¶ö¬ËÊäÔÂ*+ÓòÇ•Ék÷žÃz"e’BÒ·!^q«5öÚ ÊI·$(¿q TT£­¤¢ï†þNNÏÎo2«þ®°9<»ý­!à0¸x:ÇÂ+?Ö#•ùÆn#ÅÜá@«d¸u43+¢]Í/¬è»Î#pòj»žEüÒÅVüê¬#ˆ¶ñô¯‘uvÏlÌ¬äûk8ÈÐ÷Ãñø¬_¢—nH§.,'9BÖ;\¢ØR‰Œ]‰Z-&89µ–©&+Ÿé˜D¬§2ß6,…æ½ÒÓe~6Gö!”ýX,ï”æi„½G"¹·±Ïh¬¥:¨I‡ölhbµïÃtò²M˜Z³L%<“óƒa*êJw@ì×ÿ“¶j'…|6PXOÎ[Ö+9,F…öf˜µcY§Â7gÍfËF’^æÓ£¬Â†ØÆ2€p÷a3Ûå¥@E-ÇñÚ°Ö”Ë^AÁÄÀƒs¬7Ù:ÝdˆC|½©¶°õ"œŒ4K¸ý=ÇW+¿ò‡ÙýÃðCºÓ±˜iÈÀ,7Ž"sü¨MªüdH¯tŸ¸ >lEéÕ–ÛúR­—›†ñëc°hƒ/×£ iºWå5ÀZLîGÃ„%/1Ú¨ÎÈ“§ë­6‹ÔT"‰Ú~Þ‹»ù³ëvãOóû˜«Œª»¬â•Û´Ø¾ 8…‹ i”LóJ«FÖbr?ºVæ&û}?Ûd5W¦’ÛúÒØ¸åU'×bŽy/¾XPWeçõe³%«íÉi`ÝÐ8î§‘¾)†ŠQþ¨íºû¾£@­ýö\ïuÍ‰™oÑLÀüÁ˜$c]·gW[ªç3^"¡ž ƒÿp´æøR0‹±¨To~î‚Ï†|c$ÇÁy¬[ð}'¹¯Ë,#™¬ï3Œ#ÊTÏUYÎ/ú†'ä«W_X®:Å<[eþE68(KJR>ã…"Aöbë2ó§*YmïŒ=šHãÖ¤åVG²ölì•WÓé8]¾O¥Å¨äj¿Ûgp­.5¯ö¨k V¸›[«‚~cÓJúžq&#ü…Ž>¬<ÒÜœÜyßÌfi9—«V©Ç,¸§,Í¶¾UpOçÚ|eìMÐ\ŽVûå ÁªUâNëºT—²ÌUˆóƒqp(H
+3£§‚âÄO£ÕµÀ(D2øw¹(…¨Gt‰N£†ÿ€ùÁuG«©jŸ'òH?hBÛÀtæ®g‘ª0N;U™mït¶WîYÙ>|Àÿèø/éãÝ/Ù6šEü2–äúa½_Îrb±lgäF­î.çTÌ©›§÷ kÜeÉƒH|‘~¢«H®œè*ÇŽsÅŠÃä+¾aeËrB4måäq[nëK}:¥«ÉU³J]ü«øeðþÅ-ˆbÔV«Yuƒ™ÍdŠG×d¡÷ðŸá¡€ÞaôŸÏÆØ±	‡·ëtœ‘h:&B1¤9îŒ9ŸŒåIñP«õvõ1UëÕrØÞ¤Bü‡†ä>¥Ê[7[nëKãœ†&ÂaVsøÍnÌÛØR‹¢ ¤¢ïß¥[N|ªë»·}Ž¶èy-¯rkÔ˜5vyƒÈÉh/7äE†_žÈxa(&ôT„Ë³ëLŒ:ôÞ¹Ìý¨ó¦Tƒ7mÈˆ™fðÎB“wðâ—!¾ó/9â{^ÑT¤Óž¦¯F«Ýv÷‘ôX:ßàÄ/ƒ1‘kIÝr¿
+E¦!¹ßŒå¤·úY=»ÏÌrVO>Ñ?ß%¯‡éz¦ó]ñEúih£Å§ád„Z‹0_¡ôê“±W¾'Ù4ÝÏ©ÿO\·^ŒãµAbR2N½öÚÉjéõg¬´ït»~ù*´>ÒW‡Ð“°ƒ,Éb@¶˜+¬UË_ôÝ	Ìô»¸)§W­),kÎ'ã¤PO
+n›BªÔsÙßÖ—W¯ç²¿-¬QÀd•	JZßz0)hÂ¯ŠvÎªeÝªyÝ_m-M‰£À’;°RfòozhT±×Q€ë½!ÒtÙb”M&Ù„Ûºš`NíJnëKÃ|‚%‚îÉí'¦·b^¥<«ùÆÕMPEŽeµc¥n*¹­/]x©M­)ÜåÔj™U×„'ùÁbùGßõ¨n¶Ê“¥ý6×]ÃÍæ¹kqÕ-ðÑ%@<ábçÙDV^”E¬Ùíoƒ?zq<"£*’ªoh€.±-)wðWXVq
+C±±Õ.÷1îVËm‰R©Q~OÜ(‹‡Ã˜`ú‘ÿ0E3®U±jÞ$¥‹øiŠ/ü“ 5£—.õ–Y6ú»K—“tƒU#›TD!øRÀ—ì+ÿav¢ow³ñÖÞaþYúi’;ÿ¤q<ýEyZ·mEØßrøã–x2äpü‰þ±äC„æÊ4HïYÔUÍ4`÷ÜeBu^Î%×U‚óƒêCÃï:Î–R¸¨wÈŽ6­­ó£R*‘ê…×È¢"W·D—z•ÃŒ2å•K¥`o+=ˆ/˜€ÚM/*¾V&uú¥:ÆûT¡õ¢Ë¦s­ÆÚ†hÛûMUyW	Î¦€A’æVÓ~™y-¯×š!ý?³±¤•4Uún/'ÿ«¡v¡©9g/'ëˆLòoÏÉ;ƒ¯ó-‹u‡ò$¿‚YUV¢¥yJFõÉØ)0·»ýÈMˆEÕ©E¸ÞJw)Ì‡Bqõœ[ÞéÊº]6ÏÖø¢yË¡	ÿ*~¤£)Y]¥æb$«P]S8‹ÁßT/ÞR«BÍ§=êzYu­zYø€ÿ1$ÄÝC¶È´†•âÌZFýÙØ ’ïp£½¼ñ)ÅƒŒ¬æC{HRl÷÷÷è«bR`ÄgË©SÏïxmÈ²$‡Ÿ
+*Õb/yõ.[V-™ç‘~ê¶#`%<J7LRÉ‡|c“
+ú~8™mS`–pGüP*ÐMÅKÔê.'÷£±·c‰ù@@Û :VâÁXi«ýÆ¾ÒÐüLèoŽ.ƒd#ˆÂŠ_Æ\mÒñ»Ì1Wäûkô½ËF?X1êø™-¯T×¸}`¤"•´} ÿc»É2¦&É³ÿcéÏ~.«­ìÜSJà1óZ^™œíÜa§öŠZÎÄ’ÙöÎ8cÄi$;æò§IzNã…½.!a¥d	—QÈ*!™ò^*ÒxQÔˆQû/Lî¨–T;jMÐžu ¹·Ìª  ’?õÓÏ¶ãÍl½«Hýf^Ë+C>Ò®l3DkëÅ¨òemÎ;ÚB¥ð¡‡G»JOH6õ)·
+¿^¾ú”[EP¯Š@}Ê­"¬WE¨>0'…-'µç.s–Ì¶wÆZNÃ"J<Ð;¡Ëm¡]%8?¢£œpØ€XœåDG{~Çk×ŠÆÉH,ÐÊ+ZÊky•;Ñf»‡a÷c½‰¦™mïŒýÐ~3'.÷Cj>íQ—$@D´Jiðÿc°,U¹NàìZ»´|ÆÃu'#icµ®Öà§„ÍB%¡8qUì,¦à³9-\1Ò5€ÅÕ5G}4˜*þŒÈÝsïªDdÓŸíÕ¨Rnéj$ùV{Ö…[^¶BŠd·xti.ã:]”·Ý"bä4ß8jÃ}È‰é®MÊi¾1Æ]J€àºìcã¬òéÏÆ´ôh-Ý±ÃàŠ•ñÌÖ—ZJ‰dcUP+W#YÞéG’Ä ’}ä?Y}p¯6^†­¹,@¥òdˆ…²=ëÃ“I{7IJ ÿÖ%áð…a$+‚¼¥ÈÇÅ‚¿/RZOÚeŠ/ÒOc}ˆO)q[Â‚bhZóÁÒ¥Ùò~¶$æÇ²™½šØòÊPøšI$.R4 ¼"uúeºÞKmúôÙ—þâ‹?¿ø¡µý<ÝlÒÇÏÿÜé|&nÀý¬ó?ÿÒùŽU3”}‚}}I;×›Ù{#Þe$.&ÁLù_áÏÛåwÿýë?úÁü÷ÇaúCüõf¢?¯7ÿØýã‡×o§»~ÿ?þÙKÿ¾ðâŸŒâç?¼úú·¿þ×·ß÷&³ÿü÷~ÿû/Û½ß"¶Òd¼Ã»¸Ò[|“"ä`ƒ›-ÄÜ|õ
+“ÁÍ·8ÈÂ`ð
+-ÉÁà;¦ÞÜI/¾û#zýd›ÁØå…ã€àÅ {‚@Ûð‹0@oðrÇ‰À‚UOþåsÆ³Â¢äY}ŸµöVTÐ…wûÔ1 ê6Z?-z@–òàfµ™!òaŒ´ƒQÜoÑãìÎ§ß¡-èE
+èNûÈ[}|ÃÏé>ÂƒÁ\:Õï >ìþ(z5ÉÈ&.æ\!zûö!ëP[ÐN:YÌ–3‰HqÄ:d¾:½Î‡t‹Rog÷ËlÒA·3žgé²ý¶_vˆ½Dß_†Óå¤³M—Û`µ3E%-wÝª“-Öévö/ÜàŽÕ€“b‹¾Nºë@,€[>?HØí€"@y8"Ÿòí…&*­Â5I¾å3¼NÇï+âÃýŠM|¤§ |ø{·Á­gÎsˆ?}èàf>mÒÍ,ÛâYöïþ˜Ýy„™S*{y?_Òù‹íîv‡(Ù'Œ RÖ,4./© fNCWÕlŒÊÙ¥#^iÎx+½èã|‹õj‰¤'ñ: ‚^Ì¶ã—JA·$ïµùÓ§OX\¦ÕþÛÝîg9uÉTJ_EðQe†0u~²Úˆ’ØZJ&¿õêß¨þv2Kç«ûê=Ž’’-!#òö’7Î‹6tzx’OxË%O.ñ…SKJ†No¤ÕF#P<Á¹ør¤AÊòû¼,=UþlM!½•Ó}Â‚Æà†ŸH$.7¡ÇËÐñŽYð1Û>dhÒ´–ôÈ´¿ä3-ùsÑ¹ûD29A#ùû0à0·8Ûpäü«xÄÈ¹Þp«nñò—MöBy‰axƒ²Ž7ûÅH¼ûF{™!Îý·Ë&âå_µ—nÙ|ÍþÊºxfDÝ]Wâ™pD8—\­ù‹_Ð‹{AúIF«’à¤~A2ù%$8ËÂÁÐt¶ÙîÄëïá±C?JTCyø0›L0KÑÂd3n+°D­Ù³»ÀÞÒOdšˆ(&Øã‡Ù½`êb¶Š»1«Æiš¾Ÿ1’>ŒVÏJT©°ƒ;Þ¯gc(	v#:Ã¡ÑW|	J)ÞÿCË‹òÞO”2?Î¸ó°ÚåŠ-<ÕízyÏÙÌúaÍ¹Q|ßöùÓnc$ý‹ºa?Œƒ¤Ï¤ÙI]CŠÈ ‹ŠZ}XÒ…&Zã¸ýnGÿÜJó‘U3}4§O(Ë2zÄÍ@òÏ'2sôi]ÀV(oÃoYTR›Î¥­Ñ<ËÉÀ@_áëvµ!¤ø"è±f’»<q‡ÕöðÜäñú(‰^ðøJjŒê<es±Š°”×ùÏöE‡¼uÁÅ¡CPü¤]qÝ$œ¼W–×#¶HèŸ"‰=à-ÎÙCIdW'«®ÌŽ¹®$RÈÚmy]ùš‹ãB¦ïì!èko½[ï³mZÚY¤›wû5–j_½ys8i³Iç#<¹bjˆåJ(Ž\€L¥rÃ2Ü«‰ŽXV/•@9;C\öÑ’„È¸sThbÒ¥,GkðXjMÂšÝl
+¯HK‚›û9M¹¥7íPéû¦ŽSF&]LSÐZèK³PÑBóïW××ûÕ¨@<
+Q©Q`:ÂB¾Þw®‚ä•p$ëgììgafÜ§ÐËëSÂÔTÚ[’mÙAÍQ¢&K—àZ‚¤x3	¡{"<‘HpâÊO>NÆ—:#òsg™l³I™Iw!ˆ;ú£ªÕ¡P4Ó^žèQNÒÂì„€#Ö§»}:Wº‚ß¼€Ø=%C§dˆå¦á¢n©é(§åÄHâLýIª€s­Y™€ÍMòêÐ{fq°{Øjé"?·P3ê¤h¨©A^uèÌ‘¼e–ƒ¼sÝü‘P’Êw(L±±Y­G{´-«Á™ðØb¥“(Eú)š)¦WìNKÚxTÝ˜2Ò¨N[½ ,Ñ;ïéØji®F’8¿¾‚xkhUf!
+ñKÚhƒØsMþÄ¯‹sð'ó^9“?%TºMšçñ}“êñêP—5JßÌddhàtT4ŽEëðnOTÈ‹Íé*_m‰H“<G“NÑ?©-”J4ƒkÑ…Í omŒE„Ä‰üÒD¢!áh|3–É.aT¹hH§‡†Mä=µs=™WèØ‰™^¾ÁšF®0)jXøÈÅ˜4¤^—bŽTÇ®– íb7LàÄ`‹Õ¶acÃ¢dR”~£…ƒpLÚ2øÓ<Äéãj¿³ÐŽU«Ct$}´¤ ­·âvW”gj®{¹“ÊEkÔ$¸9}Ö˜™ãF`Œ:ë½'7ÅÁDKLÚ€®XâÐÕ†Y¿Å1….)\i’phÔ É¶FgR¾z¤È{)84’åf„ÎcÐùeÏ¥g7P“GÐšçkß]	ùq’U`ëm×Yœ«¯ø°K`½åoj 2[¾RH×¦Ê@Á\nÄ‚˜¢‚²Z«ð¡Z(Tü@.ýgúñÅz³ºßdÛ­ÞÈˆ7’Ô[6ŸÐ~Hæ³û¥‘°ç®À–>J,ïw+x„‘{î$`Ï­åãpK=%²‡–j±¼a@×F#Ý•åd
+Ì*`Û—Î–Ùæ¹ÑÈÓwVT”UÚ¾‰<ó,ÝLgj|w5Ž,’n„§d¨Es“Æ<géŽ¡e¨ˆÜHé G†Ø,LÌ^ÌgææSf–îÌc;ÿ§ÙÃØY²%±e8–«›Ô ±œá°gˆ,T²^mg ï¿à$f,67½g¶¦žr*re±J—í^¤ë5¢e¸Ó©Â2+Êj›”gö/3en%y¤”æÝãb8QÌsóÙÖ>M›lR)sÖ„3³8û­Z-¾Á‡ó¹È¦<|»2ÝD+AM8›85)÷D#hí²%ÐeÅ¦¨”r+d"¼Ú 3©!¼LfÓiu‘ÊW×Ç-”bê×ÔÆHi„TËã<P9=7Ð—ðÉÖÆa¡>žÕÃ¼Æþ…·ˆj‰õ…à©ßíé;_+Û±Ñ‹Ö’uµR¬2|ì(Ë%Á{æàaÕEÙkÇÇ§*ÂäÜ¶Š”©Ì5°«AñØ‹ßµC~þ–:,êõG©:ûÕÁ'¶Æä"\›WÕYØL*t:Øó‰5n›«=-'ìGç'áiçÐdèi¤É˜šÑS3hm¦úŠ“%w›.‡êMrA4’	–";‘‘¬—l}ÉÅ˜nVe÷"Í]b¥ð’û,9´º¦s“2LvÀìÙwè+\U8ð“§’ÎyÇ,ÓHýé³/s¨éö¹>îË Fô‡l*ÛŸÒã	–x›¡FP[(äW0®U’ÒCÖ›Ù"Ý<) o!o;â-nnšÞ¿aïEz|µZí¤š¿m·j$\ÊøùÓÛær³|ÍD±Šq®iÖIÌ^u£Ýžßóz×eäa1§Ø°6Ó¾}âŽnÑ‹@‰±ÌÑìMÄšÝê®ù„Ü9s)ïÀæ|ÔŸgé|ün¶•
+Â€TP•¼¥ìõav³we»éÓåón½š-wRØ”*ÝÃ6W5Æ˜6¶v‚n>Ôœ&Ó`ªFA–åÀ³ì"˜²c¥b9æ5h-•¹¯g&‹¯lvŸe¯`N§ò`Å¾’kø€Ðsy B{ÏWô† á‡‡Ùøa8ÛBä0üºì\$jñ¹È…eKé:KžO%úê¹ŠafÇ$î‘fá²r¸"i[²ô¨W®tFØq¬dÙ¡6K8.Õv‡§‰J¥ŠêU‰‚"¯DÛý¨Ò†þÊñPà©RžV@Å`‡ˆaQ©jl/Å{xÈÆïF«Yf#SiQß	oéâô6Ÿ"S(-Ç¶»Trg)âÑtOöÍìþô­ß$/ãRÜ™ò¿!Á:E­éü¿:Ÿý¸BÓóÙ_ÈGc¦_¾/F½yì’~þ†Ös»x%ýò
+¾5æóHz~ñ–gÂ^È$ýžz'ãlI¶#žõb ‹ø&•Ô^)¥½©;¸Ú·¢­<”*çÞð¤³,EG›8'¥MÂu’ÜØÑš¦"Ž)²IW¥'³zQ‹¾ç³C7g)½…ÇÒ—x $ÿ“­Ò%þoß#ü‹˜°{I_ø¹R=ÎJ_"ÜŸüÜ;¦Ã—r1ƒ¥i¤ÂxšŽ”¦˜ÅÒD¶‚^H‰êsYJËÖ
+$Ç ú¬¶t%ù-Ý
+¾E_;ìk‡|íp$©Êé¡¢³ÐŽš¶
+;gtå,ZƒG¦ª¨ßðg’S‹‘ÇéW9·òÕÁ{é‡ßÐ‡Î[­±Å,—&ú$"uŠD:®[¸.ý"eWÝùN<~£>º\9UN­†ë0Ý<ã;æØùœ Ö¼H»6ì“¾¬:%ö#ìŠÙcòCmWLR?ýSÆ“¦,çŠ©}mWÌ®UN’¦ò ñSzèëÎtž}„û¾DËKx–%è_¤ËGÊ¿Hô‘´#nžü²³XÐ¾ÀŠÍ±<MLŸOžÕ³8ÛŒP‘Rh„qôŒlžákD©
+˜L] üN„yOJ/ig	&ÉØŽëy*PúÙ,€@óü‚E4›å¹¡a.â€ZÞVu°¥uÂ¸íT;áUã·ßÓ·¢þ’a-Š4éya$Þ×éµKIÉ¥÷˜êxÈ HµàÏ¼kä³T[XrË¥–ìEµïf›‰»vñ™ÌÖíëÇDãßÑ†‹¦ÕO7hbùµT²VM,½•Jž®ö¬Y3¤×J›§ò[Þfòö©ÆêÐÏ(r6Öáw“žEŒÐ[ÑûŸyàá¼QUÿÍe«ä4‘Cb†Žš¢¥¸—j¦[>x@’˜ËMÏÉ‡$)Z‰IÂ_T‘ƒCô¿–ä`ì‹üÉ•ƒ*yµ¹¨-óö¬Ä)mPª†ñ»1–h¥¸#$~Œ'µ,0É«7o°:k‹ö_)\ÐzÛù!K7ËÎÃêøC8Ú!íè¤(…\à‡éëü[Úy@(ñ?‘À²Û­·w/_~øðEK[mîÉ¨¿¸ß#Vÿ²7¸ùèŠ"Pý;|ú·—é_ŽòÄ\IlB%Ôk‚‚2'¥%¤óÙ¿d5±5Ž “k´dÖI¿–óÒ¦Ù»"»’†Ùâ(…(‘ö¤X^z¼"?^³éô+ßdHµ2ëj-s,2K)ŠìK\;=	;¯&(W”K9é¸P‘S‘¢Ž*rò=¡†,Ö’Q•êÙYÈE”·P*®}¯”Rÿ _.¦ýƒ|¹ô¶òÇš \t2«ˆ­ÆžÄ7„õ[ŒÈ±Åè7Ýbì”³ö1Üõ€ìdùg¹§Ö-¨IÕÚÔ¾É¤„ÏÉ’qm2ˆ×u¶ÒºûtÓ^x||!¼Ñ?·Â?¶ä†=ùpœ´ËCúÊA”;ZòÚÞ©×ñ°Zm}¼,6Ë”^uQº¹e•H¢^fæµIýàL=n2°‚xŸ±W¿*¤ZSB«¤­0¼J›o‰¦Z[WMJ(³|L—C$J´××ïås6ÌZDÎ'ûUÁfóÉð½Â£[zTx6íQ¿¶­Ò¾T-dwÁÐRðò¯qõÅ*
+/KýÂ–NmŸ%·íq¿x®I!ÐIàSR»òŽ^ÆH”WpþWãÚ0Ýf“Œ1.U›e´Ä2Bˆ4¬"žc`xJmnl%Øß]×Ç¬]'q0Õ®‹Œ|§e¼0î½qÈg¸óú-Gô+ÒGF×{ƒ*síÔUšc`„ÕT&!·Èü¯Æ=Š.‹7;”ñÄjƒ\…8?Ø¡ŒÜTƒ2žM{4¯ú–¹»RYO¿ã¬P`Ð*5^Û¹†‘¬„ªqk9ŸÌûÕå¤P'íÊ@xþÆ¼YNAÔ$õ$4’×öÎ¸bŒ`1–I±„Zzl©w’ôÛ¼m˜šv1û-<xå+æî
+L$:JäËÒO•¥ûwuL4É:­(Ú”-¼Nž<©LÛðÖ‘Ê´"r>©éº‚7Ã¸%¥Wš½Œ¼oêL{Ž¶äî¹ÉDW£µ²e×È¢îmz¥z¤lñÉBéN…’+gPû¢ÎN®‰,Ù¤Uœ“ÜK'4.Ó´Y¸Ze{åzoÚ<[fëËœ;ZÝ‚tG+«OÍ¥?K7Ç /]ý
+sùêNZeNyß>£[äâë×ç×oTj©)MpšÒ«Åàef¡_Hç„ßUh[AEßÕ†u‹ $£WDmwqåR[7«a:^xúÀ-<!¹Zßê÷¬
+9*dä'¤~Ëu3Lo êO«ÞÀr©$­Š¨WmUÙÍ©i6¢Þ´e³[ŸÜ´tí(™Cª›qé*rPu¨¸‰=µ‰æv§/SáÎ–¡BV"ËÈ´7 4lVŠdFÇ¹?~ÏÞ˜JÀ¿ÃÍjè>Ù†ºO«Ð«Ù!8Çp­Öˆ8ñI«Ïöä
+l»E4q8
+­‹ÍBÊ	×Óœj’qº\-!z=ÛÌR»¹V”WŽÆîÅcßˆæÆÌèIëT“¨ÍöQ§0JYÙ}Þ·Æ5qàJ0V4Ý JáÕí4Ë&´C>Ë`ù¨f’FÁÌ¤‘:®Rmô¶ð[{‚
+ÔLæ`‹ˆv‘ê„Fˆ ÑNµÏBÒ=Ïó*s^]x6-—#êAµ„Un.¬†ÍªãzÀÃŽÓ×¸Ð)º
+lÏâ˜™ÀóÚš¢<tg–»t|è©çñ‘[080ø9p-pÑÈ«xD¿gã!FÚ1h_[Ÿce2¬ñÛ¢hÂ‰ðºÉÞ|qdèÃC(»ååÐ™˜ÈÝ#‡­¬#\Ú™­6Ži÷Û£f|MÊaû÷¶|9Tã”8Ú¯îÐ+LV¿êWÄó°]9 ÷ÃK4üŠŒÃvf3™¶‚m–nÆæxµ[½aãÀµìR0…7™d»µàNúj‘ÙVó°½YöÀ5(È‡®dàˆÊéðb%(…œì¾5ðÂ:­Ãc$‹*[45ÙÇ¡Cöù_ýùÏÿñî%©áÅ_H±Ÿñâ/c´µßeoAÕûùgï²Ç!.m˜}\Ï6hZ:¢…X‚ÝâzøK³áÒ'ôüíh“ÓÍ0ÝŽg¤Ý8Árµë,÷ó9Nôö×ß¾ã_æÙòñœÙz"u»#_èë/È1D§m†˜W;ÐþpT¦z¸€‚æ Û|Q£¼j˜Æ¦t-ÄhØÑËÀºQ/L¢®ÜüÏgÔéªƒH(Däy™gË	"U“¶RÚXµ{<³½p12%‡ËLMZµxÜþ>¹¤ca€ŽÃ~7í-F^eúÊš-Ðì,K	Ö#YBöU/–¸´¨ñOÞ¾rÈ!#ª´oËvã‡á4ÍÁÑË ŽŸ¾Rê"äŽ5ý}ßÖMÏ£Ö›Õ?Qâ!zHõÜH†óÄT€Ó'VžBs6Scsø¯™¸ójC08Èâ¬¤+¶agÏ!4i»ñáXv/‚°‡–µí‡QAÂÕ‚¸y_}²¿&®3³åx¾ŸP? j)­VµÛ¹†~`Í1ú†?awLE­,\'_í·£CJÌœ‰RXu.”Þa§YªÓå/^ýÇwâqþ›KO¯øSW8òçWÒsÂÝs„7ðÇt‰&Xu,MÇªc){öé]ìT)æò×ù^õM:ÂT‰üÅ·òè»Ó˜–„¾§Øßö‡ÕýýŒ:'’›ežpÂy½$î oI¢võ|ÅaÇ1¢4ôßÇ]Gf>üé{þÔ»wóøsç·×|qP§dòðýLrlá—ïRŸXñèöt…~Qþ«ô-Äªþôz!/UPFð‡ØöE5”â¥ãQ
+i*y&Ú}xÆI¤ÞÓKOÉÃOìRÒ>þYzÆ$¥M)ŽýÈ§T›ÊèŽÄ]à¿°å¦MQøÂ+<Ñø¬a´±å¿ýö{áËƒ÷£ÂI<â›‹Ä“äÅùÎR‘_<b-q™yñV~Iò‡·ì\ÙÂnÝ!Ïo¥gœmBDNö€Ã`Æ"0â“—=¼¦± ÈÃoì¨
+Òüéoü‰ß¼!¯	2Sóée,Ç•P¢'à6±$<x	€!ûFÔØ,ÒÅmp<Ý"ý'[æJ@4;vHZ¯¦Óø-ðbw³ ”F‘àíUVÇèGAûôRf{83æ\ÖÞD¼U›lž!ÔîQaiR(Éàâç±Q˜‹MGœþwé½åfu4£}D•³¥” 0 K$ˆdç92ádõ®÷£ùlû Ç£#1äceÇü%Å—Z¿&«K08’
+•'rº[Ë…b³ Vô––ýy»K7·÷ÿâ„!V È†~˜t{¢¿‹ÉCº%oßz½4í÷»½QìÝ,H¦7™öÃQôãi2–˜Ï_´Ç_øûqß“X×<Û
+º,‘ ÎÿÔ)×dã!þ•S‡®Ééæä›ý}g:û˜‰ûX¨‡<;&ÙÄF>MÇûÍl÷Ø!¤8ô—"á0—„C'	‡‡'áð$¶OÂa	wûaDaßIÂI/œLÆaèu»£‘?íŽÇÝ~œxÝ‰ïG~ey$ìý¤ç”„IU•9%“°¯m‹ça’´»ÅcÓaì3ù6®i×†×
+™	þ¿‡½”-˜d©»²¤ØÆŽfÅ\aî½“Ñ&L–e!6ª“'}3gÙË‰=›´“Ó_b³?¶SvqÚ&ÎÝ¹˜š”Ñßß°ß`ï«lÞèU¶n”ò¥{óò,é¦>²-­oØèïWì76aÄ›3úôJ<%Ì]ÀZÌºMã¥àM/…?AKÅÍŽ¾=£Mf›3úø­ôˆZ7f¬}[†ßCÆ¦75*gKF»+†—¤ím ÞpÑßß³ß½;¾£lFIhþüžþLîèŒ>|ÏP"Ø|ÑŸ¥?QëéÆ‹>ýU<¡¶àMýýz!@1ýùý	¶…Æf‹}0¶Z´6ºÑ¢Ot›E†Mýùý‰ÒÐ}úY<9¨S~i–­-6Vôç/ô'JÏ7U¬H±¥",6TôÚNÑQ&›)úð†? c)úøFzL˜­(ËÇzÂD’>¾•±åÇýù–þ3w²Q¢OoÅä@û$–ƒþL˜µ9Ãu»DSÃf‰þüþ¤Vš[úûoìwïŽo’è#Û"±’²A¢¥2×Dhº9"{£OŸªÈ:|j˜¾Ogs8Ý2qÃ0¤Â`oSHü’Çü}‰?3=ÌSSò½™²u¥@Ñéz¦lŸä |~W•Mí‚æûûõµ†%ÙÚ„CªÙ·bÝ¸Ú„À&[FYàÙÞÁÚ÷ˆI÷ºI¼nÏe“¨nÅ®{½ë^ïÄ{=A/AY‚r	2p¤…œÚ&Èà´OA!Aö|/‰£ÀMá$é÷Ñ.³›¤IßKzÙt%é(òâ>"Ô( ûž×ú%È\hôËR¢ŸK‰¾“ýÃS¢
+JôÛ§D¿$[çAc:‰Ó‘ßOúÝ,ó¦ÝI·‡rDã,M»“É4Ió(±×õ½8:%ze)ÑË¥DÏI‰Þá)Ñ;%zíS¢WH‰q’xI%Æow'Át’„ao’xiœ…¾ŸŽÇ~¯7Šr1±—tá‚%ÒŒé§ìCG
+³Œi´ÏHèÅfLywlÒi¢Ñ)MlÒª^œJ¯æ×#Ð¬’ û¸Û¤¼]¬uÉ:©IÖj÷MÒNüZ¤Å’wõ¢0î9É;K²î¤?%I:éio2é†^6õ²¨v»²½†hÃ îž+yûUÈÛ.èÅ¹ÉûÂA	òn&?4 ï\¢>yËaÐ‹½ž½Çh[5§Þ$O»Q0íw»}$¦v§“8I§aî«Gý8<'òÆ“Áe»4tRxO§p–Ü¤qK™*™[œŽÒ±E!oG]ZïÕ¥um,ÔÖ£v\p!½èHfqÒû(ë÷34F;6/îuGñxùQÚOG}´Xâ$—ÞÑ18ˆÜÜ½»+½ÛEK™¹ô~jÁ…Ñ{3Ñ¥½ç/è½X|ñÑ^®—#÷»axãþÈKºá8ËºA4Ê¦Y¿›H¡b—‹Þƒ$
+ÏßÝŒ•Þí2Œ¥Ì\z?µ$Ãè½™,ÓˆÞó¥™ô^,ÏxA˜»ãi6é‡ÝÞ¸›ÑÑ4
+¼°ßŸÆHŒÐ:È£÷nì‡ÉYíFLyþ­ïV™„2¥Ó”&‘+©ä­}jBØ–¥!úè7S›„uˆVí™EoÒ«N¯Pf‰e·×Ï!Õq"pöÓnêuãé´ï…ñÈ÷ãiù]/ÍUœ$±E!Õ
+§>¾±©„&Ï§W;Ù5yì«©Éc_F“ ßˆ$kiò”~µ£ÉCE–Øv“ÐM²îØóül<šÄã ›Å½°;îw³È›¦ã|Y!‰z²ƒ_ÿ¶W–{¹”ØsR¢ÐZ¦ÄÞ)(±×>%öÊpqpYuR"á(ô{qßKƒ`L¦ÝÔï§]o2õ’I®	BFAp©µ%vËRb7—»NJìž»§ Änû”Ø-¢Ä¤×‹ã<õ¯ßÏú±×íg±7™„c¿Á¨ïgSw½0W_x~’'gÒIY‚Lr	2qdrx‚LNAIû™dqŽÔ8§“I0íIÒ{ã`ÜM§cQ$ÚídÉÄÏ#È¸÷z'3Aðoã²”çRbì¤Äøð”Ÿ‚ãö)1.¤Än¯åmµ‡öÒ°ëûŠã8Œú/c‘pŽò)1‰ÂŠ‹%-Vý\‹Ußi±ê·`±ZH‰'°XõÛ·Xõ‹-V°ËÊSröÆ^w„ùt:ñ‚"¿l„h·I:šF“\¥ÂÄnxX;Á\J,i±êçZ¬úN‹U¿‹ÕBJ<Åªß¾Åª_l±š$^àG=ÏI‰Ó Ë¦QàƒÔK|„Aì÷§=ôÚëG£nîÆ%Žƒ^÷°˜XF\,i±êçZ¬úN‹U¿‹ÕB‚<Åªß¾Åª_l±
+j—(Ì;ÿñ§“éh‚²‡ørùÓ MüÑ4é#Bî{^>A†QŸKZ¬ú¹«¾ÓbÕoÁbµO`±ê·o±ê[¬&Aˆ /ÏN0èOÃI7@’ß8A›cð%ée^šxÝÞ¨—æZšÄˆÄ“Š‹%-Vý\‹Ußi±ê·`±ZH‰'°XõÛ·Xõ‹-VÑ&Äïù}7“N“Ñ4‡I2JûY#D›ê íyYÐE;—|L<?8%63éó«˜ôù…&}~®IŸß’I_Iš=7“>£ûí˜ôùåLúâ~¿›ä‡ÝIæ‚^Ö÷ã¬—Äiöâžß§½ ñÂ<òF¥£Ö9‘7µ¾ð«™8ùeLœü"'¿5§f”~B'Ë´còá—5qŠ{I¿ß‹ÜpŽÈ<I}o:
+&ÙlVG“^o2{¾ç…þ(W°ˆ‚­3¦÷’&N~'¿ÈÄÉoÍÄ©z?‰“eÚ¥÷b|OúÝ¸›s$NÆá(ãhGY{]Ï‹ƒÔïÆ£~Ü¤yâ’Š’Ø?È	@]z'°Wö”ÊË=¥òœ§T^§Tš=ù)•×þ)•W|J…dÏËsOìÇÁØ&Q2õF^0‚þ$‹ÇaõÇ>ºóh´‹¤”ø°Ç¦9›=¯ì)•—{Jå9O©¼N©
+)ñ§T^û§T^ñ)BK?Ê;ûašôGÞ´ßŸt½l<J"?žt»Ó¨ÆÝi.%v½¾2S¯ì)•—{Jå9O©¼N©
+)ñ§T^û§T^ñ)Uœ„‘ßÜ”Øýd2‰Æ~Q xÓž7õÐÿÂ8ëw½q>&F‰ß=µ)‰Wö°ÊË=¬òœ‡U^‡U…Ùè°*ê»	R"–ðÍùb¹Ú±™j“Oªâ(êõ‹vSã$žÆA·—öºÞ¨7Ò ?ž¤Ñ”“ÄÏ;3EÔ|:\,yDååQyÎ#*¯…#ªB2l´—/I†Á¡É°xó =Gž|"ÉpÜÆÉÄO“I€äÊqè|:BÛš|P¼¨w÷êrdXò|ÊË=ŸòœçS^çS…dx‚ó)¯ýó)¯ø|*B[ß$OPŒ‚p<Ž&Am¡“dâõûý^’Ž½^M“t”gÎä£-{Ò?ÙI©Wö|ÊË=ŸòœçS^çS…”x‚ó)¯ýó)¯ø|*êö#?O¡ÙÆY?£iÚ’QÜóÂ ²obÒþ4ÏÄQbÐkp>åÝý!Î”<| A7!EgJ"±ëLINaž)É_@g¹gJÍö,µÎ”Œî·s¦D‹-&ÉÈóH2Ó¨öú½~â.â½Iu'AEáxä™ÁûI¯Ûo Ž’tÇu°¤}+¢ç&É#lIJd3»$™Ë¡6In`¢$	Ã ‡_O²É$é¡­KØ÷¼`’ ­K¥Þ8özqwóŽ9ý‘p\ß}ÒB’%cE‰Äù$éŠ%=5Iž V”Ñý6I²p3ƒ6ÕI/ïä=I¦0ë©Æ^ä{)Ú%OÃ´7ždq:
+ót^ñmÿ°½VR¦«’æ#"q>»ÌGä¯§&â˜Ýo“ˆ‹÷Aà^”k§×ëEþÔA¦½xì{1’F{½,N¼8‹²8W£~Ï÷NYç!C€ÏX'!÷uBæé-Çæ–RµsskŠÓÑ4Ì§Ôºd£]Ê'k},”Õ£lRr!q‡]$7äÉ±MFaOz~&~2õ½ 	½nôâ4ÿ\2
+Ã“lòu"‹+·ý˜ÒVj>qáØ²q7;ÜlFÜ¹gœˆ»ð¨mÑØšCÜÝ ›u=/KGÝ8ìÇ	D«Ç“Ñ$ðlœOÜìîët’qëì¤jWØJÍ'ÕS«8©6Ó$4#Õ|eBR-Ô'„½¸æy1§ã¬7š¦~7êõ¦é´ç àõxÚŸŽz^ç…¯ö¢~ˆ »mRuëì¤jW+ØJÍ'ÕS«8©6Ó04#Õ|%CR-Ô3„=¿å‘ªŸõº—$ãq2š‚§i€Ïù½^O§~”§õ¢ž{õÍí¤êÖ5ØIÕam)5ŸTO­và¤ÚLóÐŒTó•MHµPÿ¢-˜÷rÎô»8ìØ$zá¨ëý(Ò´;b/Ë²¼#,DàŸ4ÖÒê$ãÖ(ØIÕa¿l)5ŸTO­\à¤ÚL¿ÐŒTóUMHµPËÝ¸õ|'©BÜ‰¥S?MúÁÄ‹û½Iš]?ŒÒ(òr ”1	êŸû;HÕ«Hªö£T[©ù¤z´£Õ"Rmv ÛŒTsÏa‘jáqlè…vÇMªc´yê’(èvQ²^ÚŸL»~ Ê®!kî^ÐO’nsÀWH¦ï¤ÔžRí±-eZ}BÔ§#SæÒ,\c-ŸË´ãÂ.¢Ñ €9Š›F}¯ïƒku0îvûS°ŸïMÁ(Å‹’~<ÊòâNxÂÛàT%—n5µÇÂ³”™K£Í#ãµC£ÍÂç5¢ÑÜ zMh´0”^õºq˜C££nèù^o:šLÂp:Íb$˜ö£¬M‚~˜¹üô€&ú	\IÑ\;¥R‹ûÀJ¢Ž3³Ì\=õ	#ÑfH4ÿ| ‰A„öûž[ƒ:
+¢®—…YŽ¢iš¤“qæAt0A¿£‘Ã(“hœ½^}›h;‰ºõ§Vu¨OÍ2sIôÔÊSF¢Ít§H4_uÚ€D5§>""Ä¼Ý$š$ãi¯ßÏ¢8M‚î¨;öGY:MüÉxÅB¢qÜšoñUjqëM­$êP›šeæ’è©•¦ŒD›éL‘h¾Ê´‰jLý¸Ûï†9$Úëg£(Çýn6ê{\,v{aŠ~MCW|L¢Q­“hÉ˜ròBuÆŒPœžDO3Â2í’h¡¦ÔÃ~ä'nY4öCoEÙ${£pšv=D³È4ëN²iè0$$ÚóX•S¸âidV2>„œ¼¶ñ!Ô§§íÄ‡°A»´]¨Zõ æ¸dÓ,»ãn4Ê&½Àë¡Õ0ûišu“,vY!bÚï°×~CN-é|ýc±x:‘Š2µ•«ª=ÉéHú ·¤&±&^]b5†ÁB®q=r¥E¬ï‡}´;rlgi0AøÛí&ˆp½0ôã¬ïu»Á¤Ÿi$Á"¡Á•M.‚uî»\ëØyÙÊ- ØSï¾Á6Ú5%ØüX#‚-Üƒy]DVyÛŸtýt:™xã,†ˆªÓi<Nƒéh4N=o2íæ¬ßzakjÚ#·[¾*HÉÝB€’È&(	ªj-:<Å&ËìcK\ž\Hƒî+r’éÈƒxÚ»£^×›Ž¦é(˜öã ™L’ÌwœJaô—šsy•Ü>ùVÌßd)‰rh°Î&«žbeö±],ÜEy~Ðóhp:™zøê‡nœu»hÃ?š„qšøY’“žËU Fµ×í£²OaL­Û…ßJµùÛ'%QÕÖÙ>Õ¢ÚSìÌ>¶KµEû£°ß¢~CµáÈO»Q6¢`äGñ¸›&ÓÔ›fI/\fÒ˜j(¾µã|Ú#·ó¾•v'f™¹4XÇê¤6³*iDƒùF%h°È¦$DlíaâÄIƒ£ß$Jº£,uÑv}œ„ãÞÔó‚n²Àzvô½~Ü <£AO&÷=ž]	:JŒ5´|?ý%Œþš™‹t_¾µHP›úŠŒEÂ~ J/vßx§Óú?º;í…Ñ¨ßŸDŸa¯€øâ {Ø;îÈ¸
+¹/ü´‘¬ýÖO³Ä<’­sh’mvh’Í½´É]ö½°ú9$ûp÷g/DÛl°VB{Ÿnw:‚£PhÉ¢”a·þnç!ž²rßj#d‡¡”Qb!×1“ªCÈÍÌ šr¾T}B.2‚
+{Ý°(ÕMÈ šöÆÚ2õ#?ùÓ$œÆ£)qLüå|·ÖI÷ ÎÕí²;‚³æTF‰y„\Ç˜ª!73–jBÈù¶Rõ	¹ÈT*ìÅ~†9„œLGI6ê‡½ ÷§Ýx<£iLÑþô&¹„1[Öãîýâq‡y¶‘«ãDÊ(1\ëœEÕ!×fþÑMÈ5ÿ˜©>¹1…pÛ£—G®Ñ(ûi’Žz½4é±çià…àõ¦QîözaÒoyÃåŽìl#>Çé’QbñÕ9WªC|Í¬öš_þ‘Q}â+:/BèõÑ~?Ç/Î)»éØG¬ÈCLQ_˜N¦8ÀU6qDO#Äç¡mÙa/(±±wÂøK ¨ûèÉFÈŽ“'£Ä<B>ð¹'äfÇNM9ÿÔ©>!:ž‡˜¾[u:îö’¶_=˜2Í¦ñd2é¦ý(™Œ§žëzSLÈI„þÿ L¿BvŸ_ÙÙq|e”˜GÈ>¼â„Üììª	!ç]Õ'ä¢“«öûqâFdÏŸÆq¯¨v‚$Ýqw’Äc/ò¦QÒ‰+ú9&äÐï'.ŒVb†·_L²÷NÒSÂ®‰Ä®°kr
+™îböµÅ©¶%ðU#ª±êQMî·‹ÚüêÔF‹-:&íùÝ~7ÉqËÆ~ûÓq˜aäE£q¤(W:E¼?ìåF–úåÆÎy„<‚*ÔR[KmAÔfAÈ3 ¶à0Ô”£¶nÑ3ß°'Eádê!æœM²Q/IÂx<"VÅI½ÌÕôúq¯ÁÅ
+µùU¨Í/¤6?—Úü¨Ír,Ôæ†Úü’Ô†ö-½°Ÿ³µAPæ'Ó îÇÓI’x‘M¦I˜„ýi˜9l7	µ%qäõ[Â6¯
+µy…ÔæåR›×µÆ&=	µy‡¡6¯µ^+7Ã¥ñ¸ŸŽ½Q4õ'}/ÍâxLÃ^}r(ém!ýÀ?§«>ÙdžnwÃiFäz”I=¯‡`ø«O7_þ¹Óù,û¸žm²Ï:ÿó/Ïð×~xÁg_þù‹/þüâ/ÙÇl¼ßeŸñÕŸÿüßÆ«å<"¦ÙŽ²Eúù/þ2Þ Š³·éhž}þÙ"[îñdQâ]¶Ü}öe'ÝlÒÇÏ¡®é,›O¶¸.þ½žMôWè%ôŸ´j›mféü³/Ù—åj×Yîçsüõí¯¿}Ç¿Àœ<h-,ä<ûåvv¿Ì&Zž/ÈŸÏFûådžå¶â}º?¤›aºÏfe3Ï–÷»’9>S+Üï:Ý¨:Äjµúæéò~¼š°‹¾ÒEüÏgëÍl‘n;ï²GÛ¤‹„ûåì÷}éLê0HjˆÉh8„1ß§ó½­[x„-·¿Ï‡ÐËtŒVßp›íHó÷»io1Š0Ý×¥õ!Bœ´‚ŸÁ²yJÔ~lêƒrg»r]tÔôý×?¼±WÄ±V×$ÛŽ7³5Ë‘jÄ¤âGã­R+¦õá~3;L/½È@-\á1§’Ô¸Âsi¬[¥ÎÑ|5*U¡X¦£Ù½V’É²Í2×„WE»ÙòQ«i“MfÛñ
+	ƒ‡¯ëC6»Øµ\‚qbüÖér’Õ…Ó
+}Ê– úG¨hn@l:¹£b–÷­÷Ê:U“lšîç»a)^P™êYZþ¹“È8CD…„ì²Èd½oÃ¼^òŠmƒ"æM}£ ¿MÊÁfåAñ/ÅËÐãO_^jÚm²¬Œ ÔŸ+VÄtúÈÏO¿M9äžÁ‡òHÔ´Æ‚¡ß¬Ðôøâ©BºZä@,Õš¡µv!d¿É—?òûÖ|z‹å»VºYVJo¥²ñ<ÝæOÝÉ~mðÕ£ÉªëÍêýlR ?6„ØsÌöq»Ë­Jd@Þ¢ž;ZáëEêc¶ÁÓ¡™ ÜB	û%ÙbnL¦Xñrððn‘4›O_<Ý€O²5]0'©~íŸ`®‹E£upžÍ
+Ï³YÑy6+>Ïf%çÙ¬îy6«wžÍêŸe³¦¨˜a±´ØÒþ¢X-‚·¹"iÞÁŒu7j;tÉÕ¦]¦­÷bóÏ»¶ö¥ßÒÆÁ¬øI¿¥-ZÅâwWúÝ“~÷múÒÄ!‘µˆP®¹\:ão‚½Õ4tãý¥xã‹¶¡6lñ!˜eõ’¥´Tº¤ùÂÕ&}3\Ü¸ª£Ùr›mv²®Î¢‰Žès¡4RG\.#By õ®[;dn¾É"ØuNwªø§¼›Ä/ÈÆ?Ù–Œ.6ºmÂOlÓBÊòQ&&X“®1?DDeBRŸOÿôoHÿFôoLÿ&ôo—þíÑ¿d	ÈÀDm‘YÇÏh:YÌ–ÒTH›&†t'w+%•´LŸ3åÈcÓÌ|æ˜AÒ4lÎ#fSÊ ´Ÿý|õîn¾Åf%ƒW«M6x³ÛÌ–÷o7ér;OaRì7LãéæÝ~}s‚ñFÿîæOÿ÷Ÿ¶8¶ûˆîn¾†&ÏÐ;œ—ZÓ@²ts¿_ ì1K#l­_(íp$“ÚÈ˜ ¯77_É¤‡ßËÿMþç‡ÙòÝ·”=)jŒ²Ç—·ÝÊn›Mª¶f¯•=)e…ò6ñ³¾FÔF3Œ¯‘ï}ØºùLP½\+¿ùc¤>Æêc¢>vÕÇžúØW56nÎÃ÷(>ð®Ñâ
+Ü‹KØßè‹ÌµœìN-ç^÷îæis›®Õ&¾GRQ­“Î"]¦÷Y‡ŽómƒF_¼ð½6 ÈE‚àY A˜ƒˆîöc0lŒZI—€èùkõÙâAY!ÛtFóÕøÝöK	Ø= ?Ùnü¬@¢wxŒŸFDVŒØ=d‹l‹–ê}|0J¹l€uòõz¡–,Çç‹*êM6G›c,/ T˜ÎîœuÈ ?+0HªƒW¢g±«É~ŽÖñ1¢h`s	pÜÝ|÷1ÜÉÙ"A€œ@¶dYuèPwv«N†ßÙÎvYgº_b]Z:ŸíŸB‡GˆøY D’¯\˜Òãñ†º^Ì% „bÝf¿­«ôÚ•<eG±Ív;ôåYÉ
+GÐ-$Ïº…@0\d“Yš–Åž‹
+r™—€hÿ#´øªåoW»VYÝ§¹{Ö>ÆCò{È ¾Ô4—–±Ýe_ÂZô}Ð¯#é˜ôàl¹tÒòÞÎwæ«1.£³švökpÏ&ìLŽ…þ‡ÕHöØAÜIÇãl»Í&W¦^Qº@Jï‰@Jß
+)³EzŸw«ÕüÝl×:¨ä•~°‚Äÿ×Ð‡íÃÙK7BÀò°Zm³Î‡‡Ùø¡3“›Ê‚=ú4›vWûÎCúý^nwé-Óio:g©ŸÕ¦!89ÀôŸÀ0é/oÛ°Í6ïgˆ‰µ¼sP‹½dA«ëïÙ¨ÃZ~ÝD´¹‰¯´…`tûÔö¾Ýo³Ý!˜Û¶"··­1cUº
+¿ˆ%‰Xè¯oÞth4,i¡ž·÷ýXßGàC ©Ö/ñÛå~1Ê6°·@ŸÛÎ=Àü|‰72”ˆ¼Ùv¶«ý|Ò¡ò`„·/w–j³}9ÝÏç/À{ñ9ÉÇtbë÷ò¨ÀjÐe’½Ïæ«õ¢Ð€±²l`”|Xä£¢DÃÏˆÂDÆ!ÀØfHCŽ÷ÏjCq
+-([aON„±[9¯.ÒË!ÏpÁâ¦J140 $§Š‹À´.­£ó5wJP£Þ¦ï$9f5ÎgË¬ƒ¨®³_CXO¢]aqEš–Î.Ý¾»ÂË¡%^Ø²¼||±[H")Úƒ×}µMRYxq×pè‚¤“_DÎX"e—4NÇ°©Ã@2Bÿ|˜MvXù¹˜ý—ü¬päŠOG¢§‚#vãÊùêþQÜ0Ä^úEà*êÒzbÙ¸Ù¬6­ª@Û•O|]Ù‚Ýzž>‚^·½³È¶ÛôžJ)°šFÑ›ÎÐ³‚¶N	+ñS•b‹Ìá&»Ç‡w-kMÔb/T´J¥­ÆËjîÑ¢<[\‰û2®°ç¦›_bÛ9•MˆÆv'êyV¨RTšªTTžŒJÅnÜÉ¨¯¢¬bƒ	óPÈ^ö%€Šß•@…5ÿl%
+mÖes¢˜EÛœì_«eö,MÃO²ÛÑ„­¼Ë‡Í:Ñøšnˆu»Ûñj>'±}ÚÀ‘\˜€„ò-ê_ŽÒ™3”H°EºXèÀ›¥ÒÝÐó²K}Q#¦MÛ€òTLS}»mªf~ñZÞåÈ…^‚øÜ·™’¡´w¶ø‘(øvÈÉÛNö5äm'[ÞÃ±Ï³ÕÉžâè¸¯‚ÊSÙç0/S¤ylS¤B/S)çí4)z’Qº–0MIŠEÁ-“ñæ™ÁFÍMCØ`U>9Ø°ÍbsÙ’Èëh®«ÚÎ˜`78q×p	HÒÉ7æê<[\é‚3¾‹4æäËN¶HgóN:AKe‹ e;_Ý§Ë/;4ÚsgŠÀe×°G_Š³+ü|U¨xÿ£c[«—:vYàcí¥ÔK ØIlÎ8þFäÅì™îw+ qŠƒÏÚ\í`"x*0‘ó“À~Öòv†x	<¿m³MÜfšž³iZ¤Õ¤Rèð÷ØÑKýxNQË„¤év&T1ãÉlgì®Ê
+ÿ°Ú¼›ÎWZµØK€TÒßi£Ï7 4(3 4XÀ`6ØÏ	'Z14«†ÑE	»ùª²œKÝ.P$.î®_\6 rþÃJvè?;´PBXÓŽYßòn<'ð8‰?QøÈ3SÝdëÕfW ¾(J9—€Ør·ùlá!D›¿Í²:¸_2g;Iµù¬´­`BÁí$Ï#„h`73ÝîÒÝ¾H—iYêæq‰TÐ% D{ƒÛL[‹ pƒ[:`M%mµ4ÖÒÚoî@´w€E(ñß3$åt¶r»;é)„Û`õægÛÎj‘àÈ·Ú«Ò­Ò¯Ô1þåÓÍEâE+ÊÍ|BÇ‹à‰F<4£RÐQ<À·‰6ØxØ‹ºÔHÀÏvµžŸ¯3Pô˜Xi™ŽÇ«ýò<£B°™8…Fï‰â€fJm¿¥5<%Uhh·ÈKrki— ×ãk²¾Îß¾Â÷ÿ{fA!ƒ„dÂ5[Žçû	(%Èµ¿_b8v•*zø}?Ûd¸wt{‚5˜çí3B›D ÑÑ&x*AKCÏ7eXŠ¡æ½UÎ_ö€ðô,D<r¬æL‰ö&‹Ùv{>µ7(z*B<=!!4‹P¼ í—'æl?.ïžÄÙ‚º¸ØÄgÍwµkÌCm]=›eX–Õ|u–@Ù…uÐõ¤jU2†Î~™ïïgK2ˆ?¬ÐÏpïØPžE† ƒ§NÐV9R³Í›Îæ;¾Ç„¹y?ËÊYØØÎÄEå9å^cuÑÛì#;ƒ&žÄÙd¶;çøO]çu¼ÐÚú/ùu=ì˜}¶íÙÊp¤íåyûI“¦¶1'Ø«jÇìáF«ÄQ“Œ‰¬³›­·Ãtn‰ •!j¶K X1¯V‹5\r­¿8¹Ô¹Æ¼3Xc:ÔEöLØ¸f	G•8ËÕ$î×YùÀ&ˆl÷ãâöEXXðE,ÈPÃA'Î˜…CÇMÆ‚¯,ˆÖˆ)šÖ(g‘™^‡ Æ‡Ý”­Ÿ#ï^òØägÇ¹óÏ´BTÂË7³3nÍ@æÁÄdXEdÉtá“ìéò¹8ž}ÆkKçØ‰º¸ž	ÇÖÍ(crKÇ;|¼Û6ÓÎ-û"Ö$åÛ¨„÷-ßßËm?G†Lx¦¸Q'_¾½ÙtµâÛ.	84ƒ3:g$GÆìÈx	@Ðå8pq|ù¼—˜Îš{ê{&¬Y3åÍWãw”ÓÒ}V3~ì,ðÖ¬¶o ÔlÔ¨s7ïÂ+aÍõá!Ýuðp…wº^géfÛ™-óð-Z´#x/np"á^·gk/Žûu¦ÐR{?Ñè~‘f¶5^-€td{¬¼c6÷ùš¥ K “ÖŒSÌ8SY®;øa¶Ýñ3?‡Ž8*üÀ_ œ E™Î;¿ï³ýYFÀ -½H T ˆž¨iÖ[|gî :ýÜ²/Lˆz€,ÂóVëG	· ò’5ø[¡Â_M9È\Qä â[mOE4cµuº{¨eÛc5;½Ìðïn~ûõ‡N:Ÿ¥Û3FpyÇÇûínµè &o;»U'ûˆð=I8K”€†µu.Vjhž£žJx¾H3$Kþvû¸—‡Â‹/)z7qå‚ö?lVKáÿ|±¢{wózAœÞaËòÿdÆ ¢Cç²?ôÙÉnwŒ.ÐœÏŽš9Ý>@Ö¶·$Ö2/<ÀÃµý|å	)ò–ÞË²ÜwæˆTÎR’À´ÉÂºž6TÛo<Ñ€|‘Ýq—~\-W‹ÇáûÕ8íçéæ±m¤(SÅ% *é-íÊÙbGÒ±<S|Sô—qºËîWåÒWL~³élLÄ§Õôì=	Œ¹|£D;ÆhF‰“Ñ|u[R‘¢ËVÒ%`Ü_òk6µ'ê ,q¶øÑ=qø>´o„”É>¤ïá.ièÅü±3Ê²%¾†þ<Ž0¥@«á%ô¸\Ñ½/:êÚ`Ìœ†ËØ@î—“æ`a+ï0qÛˆ ‹^½]­a7GéŽÐšMíŽbà&èÆG/:ŸG^´ýâl­6„&Ç8ŒÕÁäò.í`Ò³I:#V;œdËYÖ–XŠ»$(I”~th?.
+IbŽ$ÖN „W 9<Ñ(‘fZŠ=ù†ûÙ-=ý.¸ÛN]…HN‘±™A›ƒo©3#´ü|·1‰%Û•r¸^>}ŸÎæPŠá‹‰µ#gëÂè,€¤j´Q]	òDíHcÍŽ”jAÉŸ!¨/ð²ÏÕ²…¡d-,þ" Æ£Ú‡óF—@	¤6ïy£¯¨ÑòÑmjÄO6ìV¥t]ã66ÜÅ_
+lÀø_lLy£¯°qdØx*÷<Ç6ÈÜ!"Û€”y•>×ÍÕˆT©ábÐ:Ó™Ï¶­:­¶k9†^üLÏ¿à¼–šé¬–t>ïI!¦õW,9°$ÖÌÇžŒZ±„˜c7ôòRÂ8½Dñ„r„>tÖg}¶û²Rd+5+=è|Ó˜­Ó&ž#šÈTu†á˜Ù®ÇOÅ5ÖlQÉIŠ<uMNdL`9s” ë±Õš/»‡Íyû´„\³ÝuÖ«5˜íi?GdxòÅå› ZcÖÅúÐ˜œní¶aöÅod¹„µŸ0áâ"â8­w‹JˆÃ¨ëyÄ‰5“Ë‡l¾¾]¤E+ì«KË|	k+º»ù+jõÙ2R(ê×lŠ–ÈrLN÷`ú¥êîEŒ²«É~~ž|(£}ÞÚoòïŠŸÇÝÈ±=dålÊ¹íîq^}ë¾È&³4wçžWú%`¬±×Ð‡îÃùJãÝž²sÇ%¦ÙãtÙá»Ê°ÕBg“mgÿÂ»÷M'üsO<ÐñDa]!=:GˆÁ<Sù½ÒŽ^3´dKóò1¦gÅ˜íÚ«÷»á6ÛU¦véóÊ¾ˆAÏohÎ^ÀXPd6}ì°‡ˆ7g)°>ÀB1zO1ì/Ãî½m'Sk™—€1Q´/:„ºÙÂì_9+¥a°ÎÖehb{©‡ŽšCüD­%ÍZ’ÍÙ-=®ñ•‡ÛÈ=1È/ó@Â§êøm‡6ý|Ñ¢§š)Ðö’ÊŒ+àù¸ÆOØÊº`ÄªH	04;Éí|º™ÜN7ˆUŠ²ÿo8Ë_.@Ù¹Z´z{úqŽèéºÒma=ƒ„D¿<y4»ES·Û7â¾–‚.a­ù]´)ænB¤çËv{¨Qÿží:i‡Œs‡LI'¡ñ”Üh?„ÛâÍ;Ä“3~úÀbf/Îó ‚t } yŸ‚EŸ¿!aö1£ùù_ýùÏÿíõ–dýâ/Û1¢‘ôó/^üeŒ/Szsñ9½Û¬#°‡Ø©âÚùKôzIqFz‹ùqÍú7³”\$KÒ¯vå~N–þÛ_ûŽÙ¢ý(É³„ ¥<ûåvv¿¤“.ò|Aþ i/¿	33Ó¬ÿû¯xÓBxU®¼‡Ó÷t3L·ãÙ¬ÌXÌ³å='Åà3µºý¾ ÃªóƒžVß<]ÞX§\å.f‹tóØa|E':‘r¿œý¾Ï ¡…<áUb´<„q1SµtªÚqœyh'¯÷jjÒls™å·†ý‹p8ÛÝi”½xÜþ>Â§cÄPA“N‘t7í-F^è÷p8ZMË,ñÑ~9™tö{"Ë„ò!ˆù˜ds$KÔ]ì°ÙÍ–Žê=­~êdUnÚ»Mö~¶E³{êv8òÓåó§XJNdÍØe+¶cDõjUm÷ Çº•¹øž£6>Ò]ãyVk•': 6_¥€X‰4(¡j1P;¡Ž~¨²å¯UUþz.À¯˜¸2‚+#¸2‚†cÁ.ø¡Z’ƒ6ÅM¢O@„D>§ÖKW0¼‚áŽ…´¢Š7¼GoQ:/%ÒVfc_WØ(ãÀÕÜm×ë{A”Sñ‡Ù„¦<™žLnÎƒÐÙž¦=OšGVX|ötGã·»ô~{e·Wv{e·-Á+,¨sà¶Ï_GÛšìðèJbë¶q€w˜mê9¬l¿äÊž¦óù(¿;â0ù¥‡éþL§Qä|q¸¹ã‚É»ß¤Ë§ytŽ]bòpã¨)Ä¹6 ò¹5¯ü!1]$
+]º™J-$ž-·Ùf§B/]È•¸X›ÔšÂà'ÖZ©­2KÏ²2Y.2öÌ¬DÙÏ´ÆHHÄa†eËû3”Üh£’U'rV†A^øCmkº¡À6?çÀ÷fµÒNýG6Z9¶IG¶(¬§j)Á|¸IÎ‰'óÇFóÓ¼æÙU^Ó¢—£Ô´Þ¬«ò71E³ñ»üû6ªá–0?¦Ó)ÐÚÃéR·Yª§¬|Xj¹7îo%! Â’(¨ÀZLïÏ0¯g¢2ÛH(QßÔ°6c©k›”i`Ã¸¼üÛ8šÝìKN^çBg_l£„>°‹ˆ™-hA?Âb]^‰_–h$=Ç:˜¥^²4Ì
+9¨eb¾ä(Ryà<ìKñÂï‹½á_ºrÉíè0/f)Ë!Udb]E±âú/P6*mËuŽZ<ÒjG:ªTU3ñ¨‚äÐH>ªPÏU@R°÷ý…	H5%–ñº§ÄåŽà©sF'–ûl‘!N°X5y­õy_K6¼%pma^Kš›‹—›2àb_.™š¢B}•ÀyÒòÁE™Þã¡ÌÕeÇàrzõWk‰«µD¹±¸ºìœØeÇ4­¸,sòââêÎseÍÚqeOÀç¢Áõà yuõ¹å(¯®>WWŸ‚JŸ­«ÏEóÏ
+ëñTÞ?:/¾º]Yñ•_Ý€t¢º\ì=CÏ ß÷Ù¾Ô†g¶ËETs„ãB{ô +º´	"éjÆh¾5VÛf×³MËæ åUc÷æ¶ (U¯s œ«DLW¼Ivó?çtÐ]¨8xî¦”QÁy,‘uZ°áhli_Ü 4bË!¸ùlÙd×Õ¼-ÓYÝÍNËÓÎááj¹_Œ•¯SˆÝjo·æQTÐÙÖßl¡çÃ…F<®NéV¶:Í})>Y­tÕ1k@˜çE»Ó²LÙ/£í˜pñBCø§Öf‡[™Å?Þo ¸ø_¤
+ñ‡—æcÁ‰ØJb®d‚¶?{uúw7oÓÕòqðjµX¯–(ãàW”d¶¼Ç³›»^×»û#½ëC¬íèîÚƒƒa{w7¢2’ÿaµÝÁOH{×»»¡´'ÇÊîn6Ùï{Äxm
+ïÞÝÙîa5¡yÿý»·ÿ¿_~~óöæ«Oø«^GþöQcÔìÙ/ŽìŒ¯Ý@orpg¥?¯hzÜ”rH¢¬Ogs±EwÌî<zÓiý|óÕìÎ‡KÂºP/¾ë‡8<dé5a‘î3Úàæú	/;[>¤Ë1-Ýg¥ÃØ«ßoIxTò{”õD:Žy\&a—µLmqˆÇŒ5õŽ^·x2Ûábå	¢ˆÆü¾êÜ6rtÐ&”"Â°áû”$7ç×'D2\o²éì£VàN´Éî³,Èüÿõÿ¼°dƒ¿ü·ÿ‹™gåíVï²¥<ˆRÏQ+àäŸu]¯ð\ŒÖZP-kÈO´FüNÔH÷é{µ4hh•ñªÉ•ù3Y˜ö@C€á ’õÓ'0Þ`xñâ†|…‡„y`ÑFôÑ’°aêt)dÀ”++|•û=ˆ0Ä ¾Â4ðC|Kh(‰ž	”ÐF’ñBL2¿S‹	ÐÜÈ_oé+ý¤"Qr4Á'ÁØÓppÑ§‡ÚÃöÁe¹Bu¼;ºÐÅ-w´‡"q(‚ª.WCÒÁŸç+°\å	Ë2»ÂÊV®°r…•ö`e4_!‚ W²¥“‰/øËK~ŸòKœ½¼üƒ\Ó9œM>½ü_þõ)ŒÜýw§B¯.Pù1=REˆªõ¤®Ý
+j¬ÇÝ.’Æ0’$pp-¨Åìûàxñõd"^ÝÝÄ»éì5nÓ¢=ãöºRö}>úÆÓwp	ù{@ÜÐu¶YÌ¶[ºJA•€‡e¶E3F
+Ùžy¡ÕCz1 žË§¿¡¿ò$œ''ÝÀŠÀ¼ †lÑ°Öbµ£t»
+íøÝ% î^»Ÿÿ¯_þ·ä/ÿŸÿçåÿ÷ü/>ÿ_wøn{ùÅÿr³±ˆu°‡;=ƒ32•Ìî²I±ð"T;©”¤í'HåfOEcjc\&±MæzNîôrñù¿[8_’Ëù’Šœo’-V%Y$­Ïïpî^ä%6†ÆÎ•Û_ŠË.r9™ÅAµŒmÑ¨4cüS€Oénˆ€v9î³ÝOiŽ^“0ßP /%[eqq<­‘åy¢‘=çÑÙ¡-½<Ž£±qD>p…Ü¯›»$íì/örØ^É›s3¹ }&çdKEµñ%ÇP‹õó!ÓÆ„â\&WeB³ízž>–ãC•YÆsºµYŽßµjƒ‚À5~¸Lq™ËœfŽžé×ê†	5gè AF}¹î–Î‰s\òn)ìEÕôUùkÅdA×Íè¶òšq$W×Ç¹c¤q˜Äa= &eÉm NýmÎÝâ¶ ì[õ`9Û¹ý—ØOs+pá€~Ý
+ÔÙ
+ÀZ¨±À«÷â¶¤³µ @}ð­À|6Ú@ Ÿ²¼§nÂ~Hm*¦ì'1¡[Ó§õ¢ê3!\›Î‡¾á<@eE¨Š_æé¸è åÊ‰®œè˜œ(
+›q¢Ð+ZŽfæ2#²Ï“•éòù±¤Ð¹à}@®4NwÙýjó8L÷»*½ùGåN8í–ö¥5­…'fü¨¾Ò*±+­€åÔ_Š	ù.3€<&ôŠV÷µT›ÌŒÔVœBSu5÷¾\Täõ+j¤J,“  6@ˆÛž±‰zª°MGRR…îB‰aÓ 9È…ä ,$éê@†	ŽýhGcbß¤äÀë)w“à6ÍJê[fõ|ë~Àgèli£@iÌÊ¶V£÷
+O&ÌËqlÝõùr¬\ú}¶ûšTð–l3NòÉA÷0àf;ÍD7ç™wP ?£å…F„ì¸³e` ‰°|G§-Ú	nòíz³úø8\mf÷³e:n³ÍûÙ8#€ç¹c:w Ê•ofCãwó74.ÚÉq§,°0‹ÁÃ¸E™YÅ1ö0ÎÎåïhô^æî^ò°Mž™8y& EqWKÇ9
+Ä7x9yd)vØÞn$žâ
+¹Öç{^3¾gjÀÐbWñ~»[-®öÆWÜo×Q¾ªÇG	d™MFö¦nò{Ô‡Ùÿo30Q—w¡{"’ù%dÞÁl‚Ä¾¤>GÝª.#Ž&UÀk *sNéÌL¾|kƒâ#ñ%ï.x_pF|#¨Ä7h}fRÒÉ'ÊX¢žÝ‘ÅÉXê­{Ë	IsBÂfzQ8Tv‰‹%n6Vo´[w¡W/Ãw‡c-á—žq2k†6ìoûÖ0S’½œVs)Æezà_¸ l¥ÐÔ‹Ö%o/¾†Æ¨û
+ôâ´£-bhŠYfª3´¾ÂÐÆRc¯û‰g¾Ÿh`‘kY=¹ZŽv,rfœ“E®eŒZWá( <L×Hp{O#S¢óK#yY˜ÖrŠàqmÀb«¶}ä·¡&r0þ¶$…dˆâ`\ÃÛ}…ò+”·$Ávk['”—\W–ÓìÄé<kp/Õ°cE‰0_rü4¼rñ>ª‚÷· gøƒþøôROiÁx–é¿«‰9¬×GõØïYÅpØÑ8›ZÐÑ
+üZP î·`8•ãe§©´b©ÂƒA:F.&~Ø[	1…–ˆäúWmREó·›)!Z:$RÌ'I¨ Ö4ù§av%•Ü>S1•RÅ”Ô]ø´h¡oâJ˜Ë>{ìkŒ†uêÓ»Úg ‡så@4¨ûPZ_&&Oê	Ppðžæ=8àšþþZ _0ü(ÁÄÅ}°á=[…c”°eHN$”îæ‡'Qú{.­a›ÌÎÍë|©‚Gt;³Ì>°‹s·C|?ÄÝºØÝöå&[Â*.Êçf~åŠháX;¬6^‘'¹¨-¥¤Ëà¶Tå‚¤1?e˜¦ë'Ô’HCªna"i
+ÂUÙÖÕàö‚w)qÅìª‹Âb¸Ë,£¨Œ&G•šzò£ñª#ÛúÁ9Gzrùà¡ÇxçÞÎ@²O¨ëùc¹Œ”´…}LØ·FÕÚÆFwùj*Ðdø —ëìAAÛoßÏà€„B.V“ý<N²5Çr<ËßYâj”Ÿç·á³ì?øîŽµÿùl>üÂÍÇ™òG¸[_Âã%§ÿ:›‹ÐØ\@ydguƒ}è;(04ÚUˆN¶µ¥P†íHû‰DÙOpÀ<ØnBe:oÁ__þ!iu>±'ôƒ\
+	e¢‡õl’ë¢ùßáÿ4D¯‰®Ãƒú¡õV”XÍŠ})¯i³±©^ÕÄ}¶ûÈüEŒP½`;‹„Ž´PA­!ðæOù[À:bu+ñµÄ¯¾Õ¡Íûšr.-aLËjëåq–¦L¾·]Ý?ò¸ !¢så‚}ÏîúÁ¹‰¡ŸæüGèJd{a‹ÍaNéHcç¤¾—(¬”€0T©eÌUDz¯¼Óã¯Eã¼hÅqcO>cëcMywíò¤Éüoš4M'—OpH•câm!›xq zlS6	"§px;Å|Ü" ´aRÈz;™M§n“”âå${ŸÍWë9g$ñìS@”—ÛÇåø%ðòíj¿gŒ¿Ó+¬ñS)²õè"ÔwxMBëù`·+Ÿ®¶0 ¥ggEÐºU)ÞÈB4†’ÔˆBÆT—‚	7ôïa³ZÎþ•u”ž_í>®Õžg?udü•–Çq4ú×~uè
+4cÀ²«X¾ÔãöÑ‹ãÜa`]Sñ@Ÿ¢‚½}ÍIÉ½ä 
+™´ja¸]`c¿°1ê^.£îUcÔTÌãÛžól©,0ƒa¿?‹—Ëõ[tqP›±÷b«ÂÜ÷êLjaºrü+ÇŠ¿ß·k B>ð”ËÖˆŒäÀåå€Äk¶j"Aä×	d8 6@ìQÑ ´'4D—#44RRÈF5ÎÆa“GZ$âVÕqà”R vRS¾kYú¹"K¿¼È’}\¯6»ádõa9_¥.ÏôÂ¦O÷óùKRÖ£¬ú’ˆ»Ø6¼ÖÃ°oBªÐ®­Í÷«Š´Òïp*\áƒœõ*J\E	=D{¯š9VÇrûlRE
+Êð‚Øm5ïÓéÄÛ˜—Cé¶)ÿj[à=í²œ9Ý¨·Š
+CjWù½+\dÁQÂÄà,p’My
+áÖ“wôpå.§:GÑZR2µO“ùx=¬%Kà‘º<§§©ÝÓ3˜c`¾²E¤5w]?U¼!Ã¹ikAµ™Ù}jMé*×ÕçéÖÔ^=kÙQ(Å—"ÓÓÑØ\GGÐ…Ì¹¢ s‘¬*ÿ"—Ú)(_jníë•Ÿ]ùYÍ“Ø à2xƒd…NK!Z÷k®g‡êÕ¯Ä •™UêŒ®_•:$ô«‡?–UÇ±«2_Ç²f¨ðh¶,ÝKhBŒ‡:›-ÚÙh’rÚÚhÊ¥ÓF“´ëÍ×‹¼æëEí&iò•1_ó™m4ÅZje£IŠ;æF“uà7šbìµÑ¤|¥•fk¼ÅR^+Ü%Š­Ü¥:¿¯Ê_\FQNÕ£Ì‡®ÜæÊmŽÅm*Þ)ÖhmYøM¯Æ¾®9Ç©ß‰3à9MfàP\LEj2›æì¥Å¨ž‰Õ4,oÂ\s‹âå24¸ÆæÄÇâ–—Õ™ÆÕróÊ9Ç±_SìáYmYbãDxE“žUz¡=«ëB|.wéx‡i½Ôe24CÕ«cŒlm ~Ø³Ê±Ýh/5 <ÊÛ®…Ð¡…áwÖaøÝ\$agZkgi!˜EYÛªÐ[buDl1 ^3†SNz½æz3cJµ®H.XèÎØ;9ùšÞœÛ¤Óóœ2Ãv0F³!z¶ÞüHSä‡¼‘’RÇYï pU¥x…5<ô+Q€-<´-§ÔL³áÕ«•¿zƒÆ…ú7·ºIÒ™yña6É4®u>QiZf4Ï îÚr0ˆ«qmµZìX°5œ¦¸+5Ç0®õ[Cl?±ý’ˆ:¿Gr	ÙiEl’â¥–ÂÝ–Ä-9öúÖƒŸRk)@wùÓD]µIÉ­ÉO°Y}U9T£ãr;<6ê5|ñ3Á¤¢¿Œ›Ü-we	DTR7¹×QýÉƒ»Ç¥õ0Ã“Ñ|uK	m’-g™KŸ²É@§¿}IÒ¾ÐÒ:õ)9ÙÜ×Þ`p •”Yö|5–|ùî OÜ€î7yíhà‰0¸‘p|Hó€ŠÌ¤x~»Zw>£ðG»×É6›Õf; ”9Ay@ÍP=Íx²4=øvôÃJqtÜ­ÖèÍ¨$JoyË§TdÜ(Í0 (H>¡| cù€J£Y¾îÐ‘(0,ç£ÄÐ|@á|Àð| ×ÑÒåaÀà¢M0ÃõÝ=ýÈ@R4Ìè ?PQ Áþ ÷øòtèaÿ€ÿ@Cÿÿþ00Y ë¦6 !™ª`ƒ1m}2„˜+qƒeƒÇœ),a`(H˜)®0ÙB…uë{,+FcAP\S¢æXnÄ3ÄÒ”¸ÆÀÅ6˜o$Iaû>ÑAå\d °‘ÄGœ‘dN2YÉ@ð’ÌLÀMpÃºl¨ü¤Â€B"Æ]"ÂðMƒÃ„½`mçfQÀXpÚ—zÚBÆbÉÖÊÉld5$•QÖÔ;Ž¤Û	/À§±ßÂÏWó,Ý^ XGA4¦ßöÏ3ŒÚcÔ­* ³ <£úm$ª¦…q‚ëaíõ°ö€zqçº*Ð‹[óµ£w4é¬ôâÎak]/N@={ŸI˜çA:NùòügX!Þ_¾zmÇ=	»ŽÁÔ;Pá4Öà$Ò±^û©×ùm¶Kgó­ûp
+ût…ö«§­°'vìæ}BÅ²¥àrÇÃ˜:—’ÌãÀ	ædâHè´bæ6çÆ÷ ±ËœÚOâ.çdÎ½cÄÐVÕL^uîA×Â=â\î—æ«÷`‘}(Ã@*ò‹"åRi6á'öËy=û¨5ã
+^®ÀFÏ4âAÔðëUò¿²‡jù»/)Ì[/=ìâMDygŽ$ÂwÝœ3:­_øD°LY†ËXì—Eê~Hü%~¡&.„b[¾ÖþIàPø÷M=—ÚÆÿ.ÓøC¹Tn‡tð$*Òy¹WÿUçr¿zÕyI¹¥kUú'6¥?d ;ú—ÐXï_¦ç¥ø/7ªÓüo³t3~(`1Z¢BÖ"§oAÌwXT¾Á˜IÅ¥ä|ç¥€I9_e ¦´*^DÚÕY?lÒ-¿…–Y¢¬ÝŽM nkÞ¶R×ÝÂu·Pi·Ðó*îò–e»X¶$C“ý‚»§ß0äPë;†ÑÁjsK®žÛ#dJ—[8·Ê&C0ÙIúr7¬ÎÓåýß	þ(3 }²¢óZþgÿ§
+Ô¾‘%ð=ëoÞnmôªÛpFE—ˆIcßá?2·¸Ïv¿É3ôStèçÛrÎ–/Öótœu F4Tˆ=P¨Àñ;øÆýÍ`h?ßþúÛw§a ×ëaÎ‘‚R‰z·ÆZN6·*Ùœ'ó½Ø)nç
+OÔ*†ät–,W:\‡,]ŽLvÞèÄ™¢WãfñkÖXå¥ÜÚâ“™¤y0Cs„F3T¦¡»b´mÝB«^h5jšN¬ŸàLÇ-	É4f}Ž½
+Z=sßZã‹~YÃ"`5gÂ,€øáÇíÖ%R‰ pàßÀæÓ]yIÊ¬‹Lõ/§íN,Àª‹ÝH’ã[9Å!RßÿÙ~EÂa>å·Ú(¾Ýo³s’güPk`\£¥}–®…ÆeörÏOôˆƒCä8ÚKÒ.5Àõ©Bh0
+¤ÚŽaƒaëb¾%†«¯¹Ž‘l5Â–{GïYÓÆoZÛÐÏp8™¥²}…ÆqÈ×—8)Úíâ—e˜’Ï¸=jÀoìöÒÝÚäò†Jˆ¬®Ác°Q6a4¯¡†oqm¦Z±šßÖpqP7¤ÿä&SufŒ'a³1XG”áˆÉpš#[t_#òìwªòþH4‘cbY£¤ì[•57«øý1¸Ü¯û?gsùŽ6p­ZGn†8ÓÆršÛ‹SðrRÖ`88[›ü¦×uº å4¸&»IòØÍ¨·é‘°]Ð„+£¹2šg4öåo
+ƒdeXùLhá3x-Ÿ+›qvï¹ŒoÇÉ1LØ·£ù
+Q9ñÄØZçx¹H—xË€Ÿ>½$T‰©óß•„ª­~Ø¯8¶º,¤T¥Gåy“5Ž$z'°uçó-ñ?ÅéªÛw•ø‘¸Êv$‡Ó°ò¤€ó$šæ)ò)’±¶¾Ýlž÷IP–cÕ/Xêv÷­¡#Œ n‡_ðC=²¾KÜG–wnÄ@¢éÙœ42ùWŒ•¢\>©NA«Ê?wL´ÐÚÒÊMsþ$óMlÌQ›kÖg—í¹öF}«1§äÚ›ß‡†2'79dL#5Ü£”b’ö]çÄûõ$ÝUÞ·]YäSg‘—¶ó+r:>{j°ÇCîf—«q<[f—ãqú…ÌÎÂåš;Ë\nH×ðí8]®–³qjÞ‡IZô‡’<—½‘:«mŒê‡ýÈªzÅ­µqÌ)l|«G‰H¶£VÆzpµ$Á 8wdßn¾&ÿã4üËÅÜZós-.Œ®>QõäsbSQ×~‹µbH M¼_%l%ÛùRHŽÀÈZçˆú´dÚäBl
+›½ù¼HêL¡™…etÚd>n›¾ÇNiJÕÎcÀm¬\;–¿¥Âÿ¾ Ù«ï¨,ÙÛˆ†õí÷”%Nv®4¤wŠs"XÓ¥	ö [Þ¸¿¡'¸W@6úC 4™›ŠI€åWûínµ {®Î|6Ú¤›GÊw°élâdR@¡“Ùv=Oi²ä;^}<àË`‰¶«”µÐ0ØÀZìÔ¯¦5˜!j]Ü°Ç:‘nî÷Ð8Ä1Öb‰ÎMíäz¾Gû2: <Ø‰#¥hUO›Ò_pú@sØe‡—°µM†¨p¹E`²EÄ¼Å\ÝËãöV6+Tgd¿Ø‚Ú“ƒh‹<1²óD÷ÅlPÃrh—·cÃÿXMîd+ÝÆÓ¬2ž=wã\/ïüÍº})qàFY·ýd­gsyô];­VNÒÌm’ãD-ajílÆD-×ÍØu3vá›±8´û–·¾‹üÂÍØIOÌÊlßòÎÍÎhûæærpr¢1CkÁ@ÞÆÐÜcWUáUUxåNWîtU^U…ÍT…4ÆÊŒÄC0ý€KìðTc†¡¼´?½ÔŠ­§R6)rqBÅÔß‰uû‘uÝG†Uû^ŠóE5d"ù³©’ƒw}ïˆiÇ³­rê=Óø)ª1¢Åq«;¢@‘™p¤ÏSK¢ÂF{¦ïÄ½©¨a„‰Ñ5Œ¬Þ$ƒ£véÖ¬‹4š€…}Ævö9d	fWÒ·J\8¾v±Yô…ýìVÍs¹
+È®ã²ÁKDeg·àPpìL¹×-­¥4ÌL”Vr“L²n0ùšnh’éÑüfå¡Ír¦µUÕkàÞ•‚ýP¾i+º¹bE·¦XÇ¤á1äK(£±ä ",=\„Þ³Æk‹ÊNnN=-.ðsë^˜óž’‡§ðŽxrQ6¯Þ%6£IÅ ýÕ—‘EmÚ+Ïq1Îëª¶÷Xwüºíþ«ðQ¬"	¿¨î@W~/V×·ÎÁO­çö¡öÛÁZÙ‡¶rvÛ¸NýÄ7ƒÂªÎ^{ÛÉgÁ3/Lyû<¶”gååwÝRÖÞR:OC¹¥¬ê+XšI¶%èÎ÷õX“Èjýš¸ïKw¶Ùal k…ÅÔ´ÈîÏÏÅð"ØúsÞ"_»O1¾OÊî½–ÙýAÃtº™wÞaðe2ïÄ}pÅy·…i·æÓ ~ŽŸ#Mñòú#—÷²Äí™.E5 'Žàj4­Â¦9fà!êô|”Ë‰D
+èI•Ïo_‘Wò¹-MõK¶Y¤àgð–Üæ×+½Ž$gÓÌ.„íòWõ¦×MnŸ%B ?þ¾“zqöPÏ<XuGù,Tžv;Û”–½ÃÒ‰°DÀîèïÃZ9)MÏçhJr¹•>Ç±l‚j’Ò¸‰ÁRž*Ù ùÊaÞøÖ=A<{xéØÆ*kr]JYûÆŽB¯4€µ¸ƒ¥”+¸ª\Ï’Ä~Á¬ÒÍe gäÄ¡±œ<èy°œÇ®ÌrŽàºÁ Ï­¡4áÒ–ã:"e<'ì[ÏA¯çhdMŽƒ²|Gs[ùM,s
+º¬ÃQ´†W†se8gÇp¼øð'Îg8°¢°›˜FX¾2ÅKPëc°šª¾¬…ìdˆ>×öÔÐÊsxg4ˆ?t­w½Å6n™Î•bcçéŠ¡²³Æ>°¿”Œ:iÑ‡ö¾¨hF#ÔŒÎ“6@•OžÈãêqqp‹$,`&ÁØ¨5¤ŠvÆšØmK5è‘øí9;S˜ƒ•Ï„KZþQ™u~Žñ:òŠ™FŽŸDÛçcÄÈ!LÊY³°†b³\ôuR‡Ok™Ûð‡ˆ|{ˆ6›‘ŠÑŒ
+‡k¶Ýc¢RÓ--Qå°	¹¨ˆ18Av< àFk³ä&Ògoz¦ŒôYìO/Ño#´_ˆäŽ­Vz¹[6«ö«"ŒÜMÂª•lÞéÝ3Êä¡Ü2D­àÀGóÕ`K3êÖæE~ÏzC3¦õ8÷Ä3pÕ²¿{¥r‹²ž«Þ3Äò°_1NfÑr1<ÈEð¸ß”#¡u×	ÖE#u`õ_uŸ¹|Yu9c÷ÔöýsI`Eôú¿V.¢ëkŽC8¿åTrÝf\·OåìâuyçåÅvÕå9¹ÑÑtyå]ÓrYUÜÞvql=y‹lA¿s»Óåv5nÈŽVíf&-°ÛSº]Ùí•ÝÈê¤Û;5»õ›°Ûƒz‘Ù˜gžµý%0Ï¼ÛðJìžl6ú-ª—»tLxe®›NüD¤/ð#9ZsÝûÿ·÷î=näXžèÿû)„Æ5Ù´oÉôÜêzÌnUwm¹ª¸0 (Sa[]ÊT®vy¼þî—x‡¯ ã¡Lb±=åƒd0Èßï¼x˜´ˆ”„æ§Ïw…e¤@+î¦ÜçÍè“€½éEZò7½ÈŸø›^äO¯wçœÖ´éÀŽ$W_‹¹í5‰ Jzê	*9mzñ”Ïý‚×vE5 ”ý¬² Éú„µýPË"h’žjÊDu¿Ã1÷.:÷¾Š—Ò`œæ2zû«Àf€YÞþb™ÅÄyEž3S½˜Gw^UûØÖyÅã!à¼"f¸ç×™w^yçÕ@Î+	ìWä÷Î+	XOÁyU­TÎ+¢ÍœW”@j+#uwr^qýí¼R¿œçUkíûp^ƒL&‰“[Á'nz†Ö4Mç•Z)X’X,0t^q0"Òa¦è¼jh=œWüª¬™;¯@6ê×yÅ µ‰óJBU6ìÐy•‚÷›Î+Éë¸p^5¹­feÔ{Å©GNÈw‚=ùzòÆ•Õ'ùŠ\YZä;)â5P©¹+‹ç•!\Yè|œÐ`ndËô¾.7²b„óÙp¹¼JíÕßÈ¦ÙK¸ï_tgY/‚¬¦å#È›(qû¢xWyE{ºšñ¯h{Í¢´>5c¬6‘·ßœÕ^D
+Ms´4¨Íf?Çßœw÷ÆhÅ£u]¡î©¾Â(ïg×Õ„“°t/¢é1ëØ"Z¬²|‹~Ÿm¶3<ÜŒ6ìàe\q|yÚ¡NéK]Ž›Õ¼«Ñ»å&¡a­:Ý#$Œ4?û†<lsáYknù qÞ,Ý5l },ú¸Ð«}‘Â)Îèª4¦_}×¤v÷We˜DÝ«Ï-@‹)¦\¼¼¥uÉQ‰Ès‰›Q×å·ž•ÄÓÁ’*p2†Ô&»êØ²RÇ<ìÍ¨ÞŒú*]e
+M­¹Å`Œ3cˆ€Yqk±bn°&ÇLs¢.ÎÖZ*ÊËuYT¹^}M§áŸI$¤ù$5§‰t)¥ÿe7úW9@»ñŸKÖo›M-JËUÌÓÀ’î-y>åiv—¦…»Ô1ÇOÐYê9Þs¼ÇÇ‹iq|–¹äø^=© cKkÊ]c#2v¼êÀØ U;+ËPÅz»;=î7ò°eç…ãñ7ÅÎÊÇ·;uQD>\$°ˆ|ØÕmÖA‹çaýØÚÊ}O˜ïWµC5ž13À[—tpØæk¼e
+ú®jI]·Í
+¶æŽÛ0e\ëzµ„Ë¾0vin¼Æ»åË¯¢Œ-ëJæv8Ç´š#øÄÓw>Gn¥ Jˆ–Þi<NPªúªNÊˆ^ê,\M®ðî*v\x— ö›±-!,èomî•šE®²p/"t±ediÆÌ/Z4<žÀUä^E®ùgžâBÌµW²2"é~+Ðç¾‚nÜ9]ƒ`ºžÅ2/ry‘Ë‹\^äªD®å
+Ul¼«¾eSÕëQB8Äß•4Fóï£6jÅöF-håv-Xø{þ¢¾…?ËíæÖa&¾×BÂLŸN3HD¸ã‹xÚ¢ëhqk% •XÙ,®@¬"ø^ÿ
+^Õ}Ñk7©ÙÔ§Óì¸\Ý"vVÎÊ±9¹¬œW-Þy1n:b\šŒ¶;KìJðMØ(öÜ’xkä’VÚ»œÝù‰5ú–.}¾·²kIW	ˆêœ 5\,ÁH¡Ì8øõZ®¼dã%/Ù<uÉfÂ©C1Wšš¦:Ë<Á"t'ô<oÛ$cÉ¬Ne¬ÎûÆ­ëQœ•7†\
+Ábh‡c#÷}Išy¢³}©y¹ûÄ%°/é¾èµÛ—œdÛÐÇVòä#ú§˜‚ãªÅ/ï7œ¾X¦ipê1¡ˆÐà¤™Pdê§g”^D#ÿãØ§F:1Ã“® `ix’¬–[ÃÓji`xêüòS6<y‘Ç‹<^äyv"¦%ŠÝëŽ,QjaHl‰ê yKTSøê`‰R_÷ÍÈ–(©¤1´%ê-¶ù	cd}A?jÙÄuØ—Ýi)Hí
+…­k½áµ›œÐ¸—¹Â%'sáaÆ´VôMÅn½ZŒaÚy	ËKXW)a¥,aUÓçÏ,C…=žÅE9i
+P b¹¨ÿ,Iõ’[‘4NjCjœ¡ìGJ&×zDd}“‘‡[Y‹$kãÖVÙ3HbîöÖS6y1Å‹)^Ly‚bJ¶‚+Ý„0š:
+0«Ì‰ ó¬?-yIføé(/uÚ%ƒ™| 7ŽT\ÚàsÞüqx8Ü#¦ÍISMËOñT%`TÝ|8Ümn/ûÍñÓ—ùáFðücw{Pc˜².«s‚h$b9@wœÅ"\»Éc·szqØñY¸ñFu×­˜—¯?µBŸð2›—Ù®SfTñJ¢C"ðÔ…j€Èi°§®	ÎXæS	mL»0?…øàoÑ$\\E`“Ö*Ë#›dßÕ­X¥•hÛXXWÀ20[u—.ìŒYzËØÎ$wÎÓËÌ$¥Âp¹.S6wyË‹X^ÄzÆ"Ö’^I–ÄG‰‰q˜Tgá+ÀsèMúºÛ™BØ³‹ ’{Ò@ªÎÂžísš>*go³ŠjË/€ Økò¨n…bøü1?<îó9‚¦Ãñ¹¡ùL»“Jt‹ºS%(¹Å­‚w²é\»5ýÜ–€VýÝ©ww9ˆlJ‚.W!
+y±ç
+Äž85,PjŽ5m9&J•B½h†”EKMç;PùÒHd¼Â^M¤¼š8àU•]EcÞ¬&:½6í$içøŸ U7æ»¼æ” žY=³zfujÛ¾¶ÅÀçrÎu8·“9ÀA‰4ss€ŠW~§ÑÀ’–Øˆ] µº—h`¼/7Û­¬˜im(¦wƒŸ¢3FM¶óÏ<å9J]:äûTò~i¾ Ù+—"ùãOÐ7h=ÚZ_o·”LØƒ™:,K€®óãýît*Ë5¯Gú:zù4ª—¦í%É9Éù¾ˆhž3?±:¦xÑ9>f÷ØDk™ªš]€ ,0ëC•0N­(ºxÓÄLÏüÌ†¢çÖzÈéÙha”Ü}Œ¡¸ºù!â¥A‰ùî°ßçwøDt f;nFƒv.3„pùð(ÑZõnT»ßÑæ0¯4iuú}I±§Q96é5S¯'«I’UÁ77„¶Zƒ£iábE YXgµg8Y6U4XÌîÇRÜ-p›ïó¢–w¬ŒéjöûeN;¶ÔÏ*—0Û›‹ŠÔA‚÷RÈCÝá½-Õ¶PÛêŽyJAÿú–ü¤­¼ÅõˆŒiU>¦Wß¼ú¦dDlûæ±zt’l˜Òz¨ÕÜlJ«rÀ„¹Œµõ7&N«9Ã*H‹ž^‹xôy*<³‡×RQXÙpQåºŸðkVUYSýkÐ ôO ûÝ‹Žä ‡¦ÚLã™š}¡ö‹Z 0ì™Eƒ|‡~èô/Û'}OúO”ô#•½v`ÒÏà¼I¿WË­ˆÂ5]«×BázÎU-ÂÀ†‹#¥«(®t°vv IßÏíbÄ_Ê6!ui‘`QZ€Îê}¸à,ÝÐfìøöZL¯Í}@!ÙaX,òl§l Ü›µâµ¯ªÕÓ`®ª…œ±šo¬[j‚âÚ€$‘T’ôÀ wÔØ}¡>Æ?áï¨M+¤¬:$£¦Pd˜ü]øã©Àê± ¦›7M\ÆP{–µáÃ: 6»»ý/ZS…ñÃtqå¢“äÃfÿ0{£Z2À"£ªƒÛ— 5ÿÌó¸‘¹DgýÚ—ÿ“E÷ËÿiÉVK(HÃÕ‚h	[:1ï6Â–¤¼ å)/H‘Ëþ™"¦èˆÔ7±›º["VÀÅâìe,ÒŒ“¡®ü·ÖOnˆjŠtvwüÅ"ìŠ¿‘Îr‹9½ìŸ”A•€°E»è	+€¸çú¦?'Õ…ÊørÕˆ?³e”;YÇZåQY-ÀÐH°ˆŠÖë]±ù+«
+_÷!®áŒ¸VŒÔ» &dìØâßŠ
+vlS/´B›Î¦#œ¥‚0×F¹WvOÂ_áÚf,<ÂW
+§Yj +-GWOc²¬öru*ÈË¯›FAÞæª ŠzúRÛT¯.¾RXÑ·Jiñ¹•J´6n«©Ä°OOãci¾òD­L^^ñòŠ—Wž°¼²\Ä:•uÙ=mjFê,É¬R’Ìs5A‚S‡bºjÁ©óV¬²
+dúËC{üîøêò¦ ®ðç²,t45ê»7Á±QSÆë]±)ÛÅŸ¾^Ü±¸ÇrâµÊn+d*¶©—©¼ãî*e-MÛ»×$*¾î½‘mˆƒZ*QÕÓ˜¶mˆ[®N¶!~Ý4lCÍ/4®m&íámC¼cb#Ò zK¼FnmDpl’ÀFÔå•'j#ò‚Œd¼ óœM£»×Ô"ŽÐhd$â<k£QC¢ê`4RKT·ÊÈF#‘ 1´ÑèæHÑ,ÁËVþ\U>îd$jT$vn"Z¦`âòXUñz¯+¶Å´Bu/^·ˆ¤ð0#IO|n@rªe¦›¼Øt•bSª*„ËŸX0
+U@(°üÄpñ5A±ÌS?U£OcäÅ’š{Úd S˜v¦Þ¡=DòÐ·î¨8ÚÊ°¯ˆ[³ÎÎÖ–6}×‰Zt¼ðá…/|<-á#S•ˆåÏƒ©½¦£X²‚óôê‹%ÏÔPÓ’‚dFšŽRP§1˜y2<‰Ä¡3\mt}+Yµú.¶q½[Q¤ÈBpJµýaÝ^ýŠÍ;øö>·Kzñ˜ñ·÷¹ñÆò—‰ªDK…ð	/‰yIì*%±t¥J)¬â»Ê´Š·CÒ×ö•5Ñ‹XÀ|*Q¬‰Ë¦¢ ç}nã¼u¤pECZK+’}L·ÒR)˜jfVKãÊM6¦NâƒåI¹xíÄGqÚ=ñQ–÷[B5#­ÆDmS^rò’“—œž§ä´LaZ¨$[ãð£Î2U€ª¡êz]bÎ.6I"ÃIC”:Ëp¶ÛÊiº£8KwP¨’Ž€Èw½&;º  V˜ÃîàºÑÚÆ.ç+‰,ê¦”DàM¶(SUÀ¾~Ûú#þ-¹«ú»S!î²o‘õ@®BÂñÒÌH3qK3âŠ˜&àÔÄdK4Ë;°)Š©?ÉÊbF’0“m0e"eÊÄSª ò)w0o(:tYk+.‚¾ÜD­ž+=Wz®t:»PøLôU{;å®P+@ª‹Êî V–¹ÊnIÚÊ¯0P‰,&jVEe ¡÷5KÊn¶Û.u-‰²Žž­j=ÄbQÒ²êÒ%—G o""d5_P‹ÍÅ¥,<ï”ß ÍähW}½ÝÎp+B–h9Öùñ~w: ò—’‹×#}
+}zje,8×)cÉ4Ÿ	?±2–DŠc©—Ýc-e¨b qXÀÇPt"Œ0#g¡NË
+k˜–ÅÌ†"åÖz(HÙda”´}Œ¡*WBÑ"^”˜ïû}~‡ODj¶cáf¤eç‚“Aƒùõ#¨B{Ý¨v¿£Ía^iÒ,êô%ÅžFåØ¤×²ž¬&IV± ï–ØÐªt 3+|¥ #+«î²±âÊ{‹ÙÀýXŠû±îoó}ŽOiG¬¬jöûeN;¶ÔÏêLo.jY_f„ÂÈ:¼·¥Új[Ý1O)è_ß’Ÿ´•·¸‘7 JÆôê›Wß”ŒˆÍÜ#VN’ÓU¦PÝÀÍ3e×‘&Ì%œš Òß˜Ø©æë‹äôZÄ c[h	ÖçðZ*ªï.ª\÷~ÍÁJïjªÚ‚^‚Ï	äcGŸ{qÀ‘àÐT›€QK©Ùj¿¨%ñ 	]¯ß¡z ýËãvãIß“þ%ýHe¯˜ô³Ì%é÷j¹Q¸Ìv{….3àÆfÞ§—†%PLzÉ— ¥?™èö¦5âÉ§ùgv]”~i-ÚbúŸ,:-‡AF]­ÌJ›/–x‰ÄµÜW¯;_ã¦Ø
+¿R^ƒáL†½	&¨½HI%@ôx,ä
+š“›oêo~ÿe)Ðôóµ
+UY¦åEÈ[{P Í¸©rWÖ°¨r_ *nÅ¾†¶#ÔÎÑ^l¹Nß°ºÀÕ}pÁ>ø‚]ÍôÃËïˆuØŒ.Å7$å7P¿7‘A n%èV:}ÛŒ™Å¹×L,ºp1˜{	…Ú9Y-ÉMVo‚rŸ·4êà’!Ôª³¾Ûì÷·›»ßKKa)•Töæ{ÔÙ›ïñ¿¾!`ûþÛ«Wïòó¯¬ehLI°4yIÐK‚^t~ïvYMS„Ãû“{½þÉu2ÃWC®³»ñ/–ëdþŸ–\‡Ä¡\ÖMÕ’I ÎÙÍ‰@w:Žh"C‹tób\÷&:®c76º¼M±2üÔæ‹cg¤Ãí¶üÆM‘¯7­1Jî²Õ£Ü ³
+¼¤ÆIjøÖôÁIf‰­ùˆ—ÜÆÜÄæöbÇ»"éŸ‚aíxÅÑ±0äáèÍ
+Ä½%ïÚ%>©%ò+‰*ƒ™òRÜwóÊO2ÕqiOn}°QT~×0îv.ÐïšA‘ñÝ_~`/+áN2·ku¯Š„Y©ßúc(,Y|So`{†âØi‰¢L{“›	a‚z°,¤	¯,x5àÖí­çç½¥kü²ŸX!]i}S¿º»ÊmÚLq\:XRV%f8ãÅ'}ƒYùÁ‰Ôä²ä^¸Ò¾¥Öáu¯Ü§9€ÜÕ³3ÓË]^îz^rW¶Š&*w­àlåŽÄ®§ëš„„(iò+¢¤uø ƒ”PH ¤'gwú@éÉÜáØÅþÒÁ½(–3a—¢•ù)oýgPÔ˜Åëâ@´’†€\3	ç9,ºîÛgø$¢«ö>/iš~Âe¢Š÷Ï8çôqeœò.@ožjw-ŒÌSb÷^_ö©‡óæî¼FqÂÈÝÅÍGz`DÚ#~Ø¥›¥W7_†n	Ü|]_~`76k5¾õµúûdâT½úJqŠmêíK>üjÂv'M»£ˆT,¶™úû8\¤"U=?ïïë(P±Ÿ¸›@ÅSJwWìï“‹#ËS&v+cÂ‰åÒï×ÔøýŒ_÷Êý~C
+bãÜfô‚˜Äž¨ ¦é A[‰€Nä°'î lHU€W!Uup 
+¤…€¼8ÕÅhn¡éä	 =8S8vv~ýQnÄ#à.aÔðrCŒt›pš’ÒU{ ½ätõžÁQÌX"Ï 3–÷zC–®gP!GfÉzÀµ?ÍÝ>O•¸A:q{á G?`°ÊPÌ‚>[§·ØˆþøP×õz"n¿})qU]‘šiçÍL^Xš°™i©JµÀïz3!)„ü',~	L	(!qÀ‡åŸj^ÞÇg<8ÿYb‘Æw”
+Eú{h0Ï^¦bÖñüzŒ4¤o{2“
+Aî¼xÁj–#M¡fïyå¼¾Å¨Qœv^ŒòbÔ“£²l191j¹ìIŒz².º–P$sÏ]§P$uÌ)Í#¸åÈ™ûâ­$Üp"i±'Ü¶AÆÊnï=Šÿ­»tÜÂ9ŸîwGÛÔ¤ïa»zig¢¶hzÏ*íËpä½jÞtTJIPp±BÌvtÞüqx8Ü#žEÑÅ¥V<_IU‡w›ÛË~süôe~ø€Á=ÿèÎÑÖöEkÓ-^EÝó¦£}ˆU+(<ÍáºìŠÃùÒ¹]ñ´œrxÀ· Å›ZôŸð&&/tMØÄ´
+T7óDGÁ0²Iÿ¡M\¢¹	žXÊ&Z	[M}¢î<|šïê æI´T¡OZŸ]ûÔeºÛ4 ÛPÕ–; 	®Ÿ$èg`ör §8ÜZ†°Ô¢5xÝo	¥Kp±Wî>NôçöŸý¼è÷,D?u4ûø¢œœ¡/ÑoR.H¡ gw_P"ÈI¯>A		bANÇ>È!#Ùà:¸.]Øšº845„aØ¹ie…KÀà¯üåpeFqyºÈ”Å¹Fºnx¢™w^½¨6M×è*˜¾¸&ˆëËRwíþSo«ÒV—‚húâÉ`Æº‚rm/+}fþ˜÷ùÁÖá‚ˆÝÒ‡*ïTà5ÂîWÓôš&µW¼Ã{ìEÄ_®%|UŸ¼7”	Z²XP®Ø-P^„™¨µ)MRP|©§¬+Ÿ¤z˜ Ë(›fJŽ)„Ñ¤„úëQ½âs¹*—„K%šÄ ñ´õYÎ·Ê8cBiÖœÝ ë´ûÅº4Ë¸$A'®¾roØ¤ß¯Ì“¾'ý¾H?Y-§@úijMúb¶‡w]…§âka‘®j¹XR)u§6Ô­ëY1ÒGµý&*aö”XiÞKXó^uÓ¼G¾úeÁÅÊë_¸ž\|-~ÏÍö)¤Éj
+üœÅöJ¹Ò ÔÊÇõ\§KÕrÍ—Õëå
+¹;ì÷ù>=b?æ‡c5S5eCí+fÎ:órE¼ÂZËæÖbÜ°É¸ûm.f²·©&]^¢*Ïè£JE”·²£Gfä¢ÛŸ¨elM!¯˜ý|÷ëÿýùï¯7éµæ)HOµ£+*¡¹ø¹âÞ
+ÝòÖ ¤TÏ™|«rZhÜê«9e¬h	_¦sƒ.ýÊL›ŠBVUäSK ¢É$ 4/^Æ%jgBÌ–.Pš#)4G&ÐŒø7ç—ÛÝ	«\Ó*NÕœ>Sg£àºú2oö¥RµÝ¾à;r£jep]¡E“4Í^µòWºV€÷ð5ÚÐöØ·ô·ÞÜ3Ú^Á ‰S:¨	¤ý„›Q0jLT­ŒjÅµŒNõÄHËÒÊ94a¥)\q'`¿JcëèêX0Nt¬¤­c	p†êXÌŒjÏ'=¥–JVuÖ­•,`éLµ,ÑÊµ,ø›§f©X¬_5‹rM»©ÅY³¸C¯g’7soÀèÍìHZ¶—]æ÷Y¿'~½êÃùˆ•áã›ïÉ_ê?Çç›Û|ß‰ÜÍÉ•LÏížÛŸ·/ÂIp{šÙs{¯N§Í<œSåi#§ˆ¦útqîîiÝ¹Oû\mü,æyèd3'OÞ'5ì ŠGkº»† ¯2jqp{væQ¼;˜ul«Æè™ðï³r4S»(_ÝmÇõåÍ¢Þ,ª`¢8„£k…fQÝ3Ó&›hÙ&æÙ7ÅÃÖR½¹d8Äj˜î6=–"{ÜÙµ/Š´§Xi(LÆWEÄÝöq[$y mH5{Y{¬ýEZTþñm}‰c$ŽèUµjr%#º¬««zµÊZa6MªUs›	x®Ç&ÄÝˆèŽÕ¯˜iMôÎHkíVS“E”+dÐWÌlÚÒÇÔ¬Õ§á”eM³©&¡¹ m‡¦ÓÅ4FéÚ’§Sž§KËi+Ì_™1ÛÔSµ§jOÕ.ö88U§+TÝ«! ^©ôzˆWb[7%´3”)ôíþrzïP_&ý9Q—™žåVHõnx½ª%	g<	W]r,œ¼úÓ÷ôÏ¿ž=ÿŠTe•r(U1ê *,°Ð”±ë°À¯(wS”3E¹Âî¾ôd÷——›íV/Ñ%nþ¸5IRÉ?ãÂUÁIÅC(©x9º¥.1Ñ…j)úíëív†—s)ÆÎ²ã»c¾A ZöÄt„)1h5%€9ƒŠ9ËY{Êì…2S0h§Ø?SeÍhk­â‹$ª£¸JáôÕåC6Jä“ß7ª\­¾œ¢Y ™ünÀ¥¦ƒÿñ¥T„Ø&’4èL$I
+Þd$Õ‹Ð
+Fÿ»*´ô©–{¤ËZ`Cúú‘ Eÿˆš¶-«QÍE³=iÑ™‚ŒÂ?7)OO“¦§Àˆžž*û$™ââ}µsd•‹dŽ?ÌGI,æ#F)Ãÿ®´1)O)u±˜Lsk¯‰Õë!×ÀÔ#U»¸ewj-ÏF+ ü…€3ÙE	g*cCùÉ™Ò£»‹ñ1˜ÚŸ¹ÆÊÜM«*#?§išÄŒgé‰/h0¦É.
+•ð´VY®ÏÊgsñ½} ßùÜ\|oNbJßÛÔ×Åwµ&µ“™Þ¼2Ï&`<¦Š¶®Ê'/|KRPX¿Q—øwv©a¤åláÕŒÉªþêšBY*2sö£€À¥|¥
+È¤"'Ÿ²’)ÕaH¤[MD¿¨Y›M:³bƒ£Ew:ÜRZD¹°ãÁUÁQ×Á‰í²“Ùòp“"¶oNï¸çMÏ›¦¼cð¦Ä‘$àÍ>ÃY”…/N•£…˜¡"QQ ô—Hé/1£?Î™ñònópxØ!ìÖãÂÝ9¿§DÂuóeŽ	Á˜Io/˜g]h‹éth%"m\þNvt‰½”í5/m+‘qq)@Ów%HCcNÎ5 MJÌQeË×äÍ0(Æ«™‘Å|Ï†×Ã†i¨Êo"7¦2€™1›-)p”¼ÈÍ R.1„X¨–X¤§(di(X(…š©X1yˆ¡øÛ¥rBå˜›ÌÓ·ºÙÄ~CÓ¬:Zi‹7wm£M¸ÌƒüˆßË’wAÙnSÎvë˜x§gÍõÄë‰WI¼‘êz|ïÄ×zÖ%ÞIYuŸ'ù
+í‘K¿†¦_¯îzu×³®g]¯îzu÷
+wlu÷á°Í%eüóü3þ_©•4kúK»g‡‰P3Å¸ÈÎÈ€ùÚ·pæŸ’po¬³óoèßÿØåY‡çôo‰û4^™uw–úN£âÍqO¢`öfû¯%·uE›¾,'9|è¨Ð›J_AêM-ßÒ”&ŸÀU…+c»XÅvÕ‡ù-)0Ìd!½‹@N8&-üAûÞ¥ã²<I•×²˜®ÜkYÏ[å¬ßÞ%ƒˆ©d%$BNÈPÊ¡!KÈì *kX9é„aƒf÷ûÕqæÃG˜ŸÚ„¿$³(-EIÒÓâMPÞI-ZróOb}xÌÜyCCi.Ï„¼¶¤à¥"/˜àEùcTÓ¢˜qdzÍØŒ#¾ÆÿÊ#8À<Î.GÈ› Y\WøŠ9¶<‹œKÐ”dÎÑ6Ô’0Îj-ä¤¢àÚÎ²'O*×F*êøK¥d%"•±,gOŽPÂšPæ.·tB«Z_vëF=o‘_‰”¢®Bò	Tá?}Ñ®.èê\ ÜÆ³„` #&Ëµö[i±U,JÂÕ–£«ÍW—Cû†Ä¾ÿ¸;YÃ¾e^©ízB[é'2ÙS¬¹r¼PTÝm¼†º¸½<liäÌY%_l¦¹»Ù¸ßjü~øP@kÿ¯)—Ü–rÜ¶.ÿÞÛÔñºü¶Jªi³¾{=4;FeiûËî%ÿÌ@WÅ+Ìtè‰
+9ù$p@A9„X¤ø "ÐÅALIždü:³£¢Žº–fVHKTc…ž'õRI™¶ý9†ò9)Ùà…¸Ü»[ÇÚxØe«uÅ7ÿú2ÿŒÿÏúÿm·U{¥Ê^^´üSEù‚L8G¥$£5w+ÿŽ‘9œ~¦c¸°Ø€š=Ê½X4[×¢TïŠU`uRôöü
+MÉy…_‰Èº­6mÆÅIäŒË÷ðT|[8´ˆ£IöÈOU™Õf¯—¾õÅw•èÃžnÃMŒ0ê²V;K0©´øCE¢øvlõ…¿ŠV»‡k´ß×6 ¤µ²
+–bÜŽŸÎmfe±ö›59ãèËs–“œB<Ô	ÊëÅ-ËF§‚ÆÊ™s¤-6µÖ¼`©DlR`®ä¬õ
+v¬ K–'Ëa_¿?H83ïòg$°É/âGUÒÌ¹•(Ö€Y;›pì„‘Ÿý5³Proªü—pN±°e ¬1¸±ŸºXYÓDde­OpEåŸ*þÃ›WÌu‰Ž%¶";
+VCÁaøryõŽ¤yäÄw¶~j§q.b­5dÜŽM^èÒÙý{WGýúýît>?é±¦	Aº‚I@‡dŠˆQŸ9s,ú’¿°]@™š³Ùß?`•ˆÅ)™wpzæÌ)¨>à(6F[Y#…`±gíÑÌ ®êÛ­IŽIÊfbò5v^ºKÚ«p!”"”Œl ­Y›ys;à\ü†¢×¬Kz­ðÆœŸðŽïÌ'söÉœ•ÉœcÃdÎÒƒ²À‰6É6éœ%Ó?Ÿ³túGc“Ô!Âxó¬!gžóäÎKðz–Y”‰“(ü”õî¡ø²L•‚¦rEyrQ!Ïšv®,pò:#F&•&ÄGŒ—ºÆaý” "úéÎ¦î’BÇ+Ø‡¥½‡
+ï1ËnÒ›Cè=ž(ŸQ^¡~–$ŠôZ=’e§øP“eŸŸ[Ô'Mû<iê“%V¢1¬áÌûtÊ7Ç;´ƒÐ@jÓ…š9}fŽŸÑ0ï	rQò:X& ¯NÚogçÃ›€Yµ¶©=óšü>+F3d<lÜeŽåM|žBÔž|QMlâSžá%háS6¦>Åt&PbZ¹`}EÕ±@­¶ú“«„{¦'}ÛŸ¤Cý/»Ãz‚°ŽkÉv{AK3à’ƒü~Â1¦¢á´ˆPr–•’Ó H¯æx{à«4†cÿê÷in1˜¶˜¤vb˜Wröbµf&Ó4¶—KnÔ\7yJCè¹eÓ/SÞSƒ :Î¤tœu¤ãÝ	2k*ntÓ‘‹Ù^Üq“qÒŒéäØ¸ú½¨yŒvÎÆýQÍ‹üCb;æñ¿—¡qDŒÃ¤Ypk5§œ½jpvýzž´¯…´ŸyÆÅ4†ï£ÈÉÙÂ’“é±³ eì~ªqÀ³²!+ë¼@MMCÑ²Ê‰§ËZv„ÜŒŠ±¸ŽrçeÆ<lÓ\gòwÁ³ÈŒ¯qwÝ¿6´è	æü÷„ìµhË2êŠ¨š´èÐŠ±ûôBì+s^û¦âëÝ‘–ùÅÍpdðàBnôÒMf;qd•ãiºX¥éÜ¦£“à”Îj°'Ý«'Ýg¯_½ešž_KËt^îÇ2]ÿ*ð)?¯.±¥dÔÕM³«n¼Üê©W—ñÊœœ™	j1t `hö~ºC£q¿>}[ìyØóðóãáDqG} ktbÇÃè¿)áÃæÆ;&‰<'›r²–eôEï{#æ÷‡ãùîr–TÃã&{A0v³C0r|»¹Ëçåãs\K1VñO}ó´´?‡vêÎ]š´¶“æ:°V—+/*;Óª³ò¤0ÒM˜þkÆ]ÖýÓ¿uÍÓ'sh8©i˜y_höéš•WK9õr;¦Ý¶$;ã=8mó/îå*é·œ¿rÃ²éZHy´µöY—ã–mSÎ"½š™k×Ö$Ó hùôd¡b°ÍûZòjÂñªM‘Bbåú<±zb½"bM“tÄšEÖÄ:jø³œŠešìõP±LM3."
+ºÄgÍX+¯Òz•Ö3¯g^¯Òz•Ö«´â¡Ö…^»{ tçP³½itéDÁå:u¢çf0í_Ú2ãwz{+WnT€SvÏùr‹¿±Þ\:xùËhj?ó0rl¬Ó‰žŽoéù(Þð×_~ûÎóõùÚ‘s7TÒqúYãg¼U¦ÊÕi¶šW/ôÝ´ä7ðØ8ãJ]®PÌkÍfZó²“ÖÌFßÊóú”Ÿµs/	&oKíî22…1¨*Gº$ÞM5®’3…õ>ÃëÚR‹ÑV*)ùdž‹pÁgfª;òÉ™|r&Ur¦6“3™6‘Åæ^‹œM³?}“Ñ’ö–É‰ÃýËé|¸ßý·;³
+be:þ2¯z¶Vûª@©F—n”¾ ä‹´·ÛñííL­aƒO^rýòyÿP×?"b˜a9BÅ-âtì`àmñ+ ·­Zz[IÅÏ"„×[ešÞJ¡éµ7™@ÝÓ¶äÉâ}—@¼¯Pácc™VÁ¿<ØÖºbpÆEÙãÆr*?ãu•Ç ƒŸs0ý¯•±QŸæÓþ¬#š`t×Ô_žÇlƒäoúÍÀ÷¶t²6ÉXã„ÛÑ §JœU›Ü’ÿ'˜Òó¿ç[þ_N‹ÿ\ùZé!Ÿ7ñkç™6’…wË )ûœ‘½Ã¼U‚ü‘v¾%»gª-“XñÜžÑ *÷Ìî5{ÏìOÙ#¸þÀHÌÝäíÊì½¦¬‚xZ‡um<-Ç2ÖÏûÈ:oþ8<î?­Ñè÷/7Û­f¸â±Šªª~>î6·—ýæøézjkT®Ñé‹ºEVS¸:ã/ïð~¬äËHj+`£¬~-þÆFY¡1¿/8£n4ä×ÛíF9ac|.	ûî˜#Vfx'Wã¶Ä+ðÍ'Åã+fÊõ!:ë’tàÏ„Õ]§ÜÀË
+v±»&ËÝ‰"VZ¸±Þk°26#ÚTnm`fj`>•*ŽÁB§»u „—M‘}Ckýä¼.ûb£Vv…˜m8Zçß¨&†Û1,‡ÿ)U­ù[Êswy
+’t„]DÒÉjq* bœ8¥€Œ»üã©šÖ?Ð¿~F_Œe`„”Û}Û.^ŒˆzÂ]¬wäûbüææY"ÀvwzÜo>ÍRü¦ïòuP¾ëšôQ6BáÇ‚<
+_{A‚Ô™¹Xç&OB]GŠ7ª÷Å%ú—µj ½²	`Y®Ìæøî‚g†øî±šZô÷õB°ð_h¿´ûâóâ3Äô3”¢Ø²žö²±g~&ŠO½ù¹èÏà£¦xíl<œVÐ99ia!Ú/?‹¶ðSîHÓsPh©å)É&öqs%8¼§¨jP€Û:HÀ4Œ‚à8jà!”“(ð_QþW“kÿÐ;Êå xõœJ B ïì&=TI©>êJõ2Çº”?5|ç—xÇ£î—Ž#°Þ‰aÔ™»eäÛ¢±i„ð r€KµmÉ…cÙX È0æ]&‘æ:e.òfñQ¯!§ŠÊîîém¥EoKéS¡LIž"‘±ô% €œóÐ*ö:ËI?gB‡u{'dÂd˜(É°ôìZPaÐ¦'8éÆªð»#ÂÚQì‰Ðáµa¢ŠürN„™>b ° AŒDk<	JI0 H°éa(ðí.ßo×—ÝšüÇÉ‘{÷ðûÀòóF¯\½`gLÌuw&Í–ˆI³Eg¿oc®Zd‹ª…5ÿ”Ÿ‰5Ö~ÿöñ*âËV¬ÍßF/ÚVPÑ¶ü‰ÌVOïÍ‚~	ÊKìÓ¨³ÛKiã&ochÆß…¹6ÌPM©EÒÙ³w£Ž×å¨¤#Ç±l'V'PH§þ’æzÍ´éJ‘Èr01wg«»‹¸\6w¶°•³…ƒÞw¬Â-Njq% G8‹ß–¤C”X×@°vü—E¢Ž8 ï^…+Ùš›…x	®U	x„'í˜p5·^§0.É >lëZÃ¶†Ï9r•q]±À·*L;¢ mJÆ'@FÉÒp,e–IŸ]Dkåz×pfR&•jO³/58)ëLIÁ¦¤D²®Ýè¨Ê¥IG¨¿_«¥÷€ˆ ¨þ™²Oeà×—4*¨\bôV ¹Rä¶AmùdBìLØªÅê=H…kuS»œnú™nµXÜ:É˜ñ!èl}tì’‚4 yÉª]ýDàïSŽëõ¯Ÿ<Mg`šªJ½vá$ubMœVî‡g`:”\;‰uøD{ãþæ	ƒîª¼†hEðf÷IÁ$îÊì–”ž‰¨µ
+ÝÜÁldz_¤@~k¤ƒ,0ÁT^ð²€[Y XLDHW.d^/ŒH˜]vmäš˜=Z™=Òáè†I"¥ôÄŽÒK¤Kõ½ìÓM ‘C>…ËôDÖDúŒ™»dz¼#štsB¼ù{Ñí¯ùñþ$#ü°ÝÁ |Ã|_.„gûçÄöx•Méþ~z\Ÿ©.{¦÷/FYhþ+&zÈëþ¶º¿½àHgHíÿ˜Ÿr—êÿœth'$0]8I-•Y+Rp.É;Z˜o«®9?jüK®ÎöØ›·×3úµ3ússU§i<^wL€Á‚ÔqHp.žÑí]/¸Bò¾èg¦|I!I¶ù1?<îó9:Å‡âíÄÌàsN*ó…`f&jžAG­œ¹ÈC’®~M»{Ÿñ¬N`ÖFŒ¿E;œj™44f`ôoZýù¸«!ÕÓ+¤2›˜YñRÄÌÂº‰™MjR1³â•ë+f–àùÞÎ{Ðqƒùgü¿_æ´ÆIë\Ã
+·»ÃvûUñ‰æ§Ö­ëßJ¼¬P«yMšY7y–ƒ˜¶ýÓ¿±™
+)òË~ÇŒ}2KiP½)?¨ô¦r|þ‚«7]ÆKEÈRµ#`šHŠ#+`ƒ€°9ÓX7ÁÿA3Ð£fYTW›ìõÊúM¥Ê·^.GL8$[‡Ô Ã8ô-‘Ro–Áo5±4¥{A–(Œ~ìŒº™ÛJ“êª€ó·—ý^â{‹ë´¡DK`ün¿¡³>7ü»ÜÛfÊ9å»¸ÜÜ¨žX<±`b	‰q¬ˆ%ŒÄâ0LEL²˜”±iB\–$«X ‡PJ¡)=¨néQHm@bÛÕÝi‚h·h¢v¯Ñµx"é1Õ8úÇÏÕL	Ç3ºu
+©¾ž°“¤ãÓL0ÓžÙ	à–¾ÓƒÓc0õìß‹bÁ„Ù¿‡Oó<ÒqG1\
+Dhþ!¡ÍCoAZ˜·€A2g‰–€Ñ3y<œ7w‚xÎ<DêØ¯Ø–X1\äçz„fØÑ‚…NÅ7uPf1¦ºT1«m³tS´úçÃÃfOÑK¦z„Kæ´æ±xz}ÞÜ¯öë/¿}÷§h*^éIqŽÝM£ùÅ'«l¬ÁövV¬PhÅ¢ëcaÆÂµ„*”xîv¬„±cÕÀ×«!K|qÅqU¢èbÒ@~hŽ‰ÀkåAÖàûdÐøo…ŸBu‘lTÛVåOóþ˜÷§x³—ÔŸ¢¨lgöZ‰˜h™žŸ …5	28»% ½ÄÍp vZfÇkëZ÷ ép	š×¢V=dx"Z,6Í,Ë‹q¹•¹l`UÃ–UMœVÙ	±ùÌÄÓ²XÅ1L$B‹•É)ª
+Ê¸-eJa¥}KŠC™½$U^–³¯k¹ÄÌP*×u¨Ìqc>h·v‘ê0†–UÃ€H‡í¦²”I77Yœnã‹.tÓ0[uëOã˜±®<Âö¹]‰²ÐÐÉ >B—w»¹ÃA4ÑóJ–¦Oqœ¢­:o!;§êš_Õ~žB¨÷
+“Dæ8×Xü>–f¦”mÒ›ÛÍ³ˆÆ™Ê]Ež» ÃPÊ†*Žó×½}éUºPx:øÝ%¸Û‘Ê>L?éB@?ìÝÃjäifl¬ÜF¥Z$©åªýºWÉ1}ˆü€5öª²*X§#}ºËÿ—,`{ÖR—7-	3ã‰L^ Ó]N/5Ÿ§KO—é2‰™yú¢Ë$êB—}&Ùk‘Ÿ,ŠyÂä'I¤Ê¹×zÖclGÈ´îD€ìóMþb‹
+Õ`˜[”5—Y0}úc¯ÙãJïÜ5{’ù‡ü\ƒ|¯ó»ÝÛÝxïÞÓ¢§EŸ®&ÅHq5G‹[ŠFÃ\pbØæD9&N‰ò‘ƒXÌˆR¨†ÑY&|âåí1ßü¾Þî~×KG.WÿÆÿûeNz¸Á=˜äƒcúyÑêÂ‰I5Y*Lªz/e©!&ôj³Îm‹*êó¯øçý¹r£TÓž
+ÆtvŠ;æ¯ç¿g¯®àë@läY‘¸&¿LzÌÔ ÌáÆ &@ü•õ”¸7äÄÙTrÆ$Èž][;j½:
+ªj™TÑõ73-›€Lú´¡¸5¨uI¦hLC?@Ciåê##ÛET;£øñÚ»aàGãk5EòáC>ä!K8C¨8­šôH Q™˜4l©I¦1zì‡|ú
+ÿ kR±²-Ö›W§ä¨ÅyØ|ƒ,$&zKý$(4u´GMõ†ÊI{¯˜xÅäZŸôª˜$p±H™b2©°Ž§«Ž0AèRÎè]ÙîNøstáÄÆ“Æ¤È>ï¤’\®9
+ÐëÐ"pUiQ¡qU‰è0¿ýÀ^QÚüsóÇß‘8¼)Q&Ä,V]5'Ù=[{†%{ÖïEg|:¾¥;¹xÕ2Ãƒ'×É’«£t¡’;LÎšÙ"Ðž™.±ªóœº'V‰ò&"Vz-3JÔˆà©UD­ò×ÌÓ?·^÷»»…ÚYvÐdùÜ8ÈÀŒ¬q¬G³å„,õÏ¸¤7¶¿VšðoË_»k¡à@ž+'Ë•^UyÈÆPDáJÅR¾,Ï›;}˜ƒëISHš+%i²ø×+m’0Ë2ÙfGæÄ}Ì?×IS5".ï¤~²ÑQW`àe¢§£¶ÞÊJ[McmµLœÒÌHû7ûîôB0ZŠÌs~ÿx:£ÎJn3£ÚÄ”jË2=‚u›ðÊø3‹à{za¾kbŠCV]†Æ¬Šð¿üû+òC=«òç?ÿ»˜lcë ÌÖJ¨ó­W™«BW´¹¦m“ï>™+T1a¬LÊãYïÆß]ÙÚÝÁ8Éª¥¥Ó×¢åÀ5-{
+öü,(8	G0ùÆÆ*lŸXJ“Þm˜¦&*»ê§ÒDÞrv×òÖCGhãAcMóÁ­?4Y±›šQBt6Óq‡’[o½¡%ÑÕoå¡WjàõÎÐë2¢ÇÐ2Ê¨‚oÕíeTãa¯&]´ÃðÿíjÍ-wcÐ-:sÇ³œL&Ñ»1½›¥o´ý)ºî`°íç"…×G¢LáCÇ®ßÃ®›jqÔ¯Ä´‹#™*pòÖ]×ñMî;7ðVéØË·¿?lÕºrÑø76ºÍ<èàVcˆ#È¸Ýåf`§/kŽ;}B4zÏ*Ã¯É_X]˜¶ùÏç§üáòW|5µ¬JÙ*gð-æ¬˜¦!»ãÄ»oùÎžùuÉ	Ò¼øM [\Å5´ŽP‘Ö%Ë¢¬ôQ›Bóýš¤Þâ9¿.YA;£OxGqkñsüìœ}Ìë=¸(b	’~Bgx.VðŸ-åul¾#«^àøOh\–ððß~EØõ:/’´ˆ §ÉûæýápÊgø‚ß3ú5gTóñ¼àyÁ%/$†·äà†ƒu#ž ª>l˜Âd¦¨jc¶°ÎhMò æ¾ŽäAÔ+òà{—<Ê¹ŒGxFäðäáÉãúÈƒ=l]É£ì£_ò¨gzäÁ.läAÿí7ïò5õFcYß’L“ÅaSÒ	iMÿ÷¦x¦ÊáÏõDŽí—¢à~½òŸ&Ä#ë… ãŠÂ¤;!-£"¤%Ýa»ZÔ·Ò= g‘”Ï¤dçkú•¿ÞnEižÑO³j|¸<'ÆfîŠ~êBd²æéÄ_€a.n qµÎ¬G÷V°l¼çšRr;,g³-<[Ð=‰L¤Ðhä2E4õ9<É:¤™ i*Øs09Ç‘ðÀ½Z‚Ító¦	`ØÝÕžeå«¡ìÅ2›ë„ØóÒÆFÛøá:ËÃQŒ\ž"ûØ.¥DyB1$…nÁñ+ ,¥ÒÉÒ‰t‚Nß½Ž\R´«¸·ø·)¤Ñ³RòÂ¨{¼K zÏRh?š½ñtåÂGdêNLÒŒ€QtÝ·h!âbÈVï,60oÂßth1Ã‹c‹iªÈ¼ÝÞO-Ò`x…‡¾¡Ñ€ ,/°Ó¸*I¡½„rAk-årøÕœ¹#¡D@žP%×õø"‘Î›»ó»úIC ín¤Ïc¨°•¸žû•à\´iÀä§+àº¯íÆî5Änˆ‘,aý®tb ÛÔ[¼x`$°›ÇH<`ÅP<à0‰Šõ4®O<à–°“xÀ¯¥†xÐüj#‹
+òI<xÐ	”ÅðS×Æ80pö*¤˜0YßIûU§+ ?ây»1	„÷ã~Ç!ü})±Î_×ŸdÚy¦÷L_0}œ(‹P2GpoòH³ˆ!àøäxj0ÃWã_½7ÖMqYU½€ªÂ–4©ÇJ²˜¥Ÿ7÷ˆr{­eëŠóªÇ?î6·—ýæøéËüð£cþÑŽñC½Pu[‡$ÄÝ¯Õ,ƒ’ Ii–‹1]™ G$pû¢ˆn€‘ì+æ=ëo†$Ôø„—¼ìPÄ$¨2;	wÀX y”Ð#ˆD€/"5aÀ|*± 0{ùŸ'4ZÛ„‹¬0'h­¶Üž û¾Nãbñý«T‡°$”:R.D.Bh«²R8:÷‡"œ"†QGurî…¾ª×™M4§4]‰!¦5ä[rBõw;KîC,"8ÉÉáYöªX6^†f÷ÝN)ŠMX¬ìII”Ê0ü.ó(?•(ÀVÛyþ&t:ó—8Ú‡wG´‡[ä‚›ÌË_çŸÏ?IÓ2ñÍ›ÉzÓîéX¤zAÌ0­)j10;/wkŸ³—°¾Gÿþ¯Ýö]~þ-{«œ€ñ*¼C(€Ì˜ w“›S±Ðßå†Tçš˜y -Ò~ð‚ð †åˆ^‹â
+ÖlPßC$³­ÞBž5z©2Á®ŽSìB7ÞËM˜ÀÙE®|Ì^RùªTDäÂ<Å›ÍY#ì¹Ú[˜t‡í t2–kxZøÝÊŽ·ßÑæùŽxõÖ´¿–ÔŽï­þŠöÝ¬o¶yØÎpŠõÃ±€/9a¼BÏg~ýÕg¤ÓIº™‰éZ'€ÿ¸-•7´Á5&5È$BÜÖZ¹ˆÇRõAœ!É“ OI/C‚êY¹bÈ£H±¨†Y T§YÌ_]òùÑj‡9× .ÇqŒ4åPwÇWðdr‰C2•4¨Àä Ì¢òÇ´^äY¤ž}R0Çx±¹&K@!œUœ A÷Ä$´T’mN½ÉM ƒî*ö‡Òy÷ÚzÐosüÛü3*›Oõ˜;‹O,@ÕaIÕ/ÑDÈ°üÄœåuÛ°ý ¿°6ÚæW46!!,$/wÊggÒ@ªUÄ`I‹õ]NÆœÜèQQãÔdS!ð—qˆä¹bZ(Bý€= 0U…üÉ…I_y§†ªê„c37Â+èµ¶«ÖûÉÝàðºdÄŠ(Ú«	°Þì÷2ÂÑ$˜¦Fca™së@›ôúè$«¨˜—šGž8¦Ex98â(¶àT™#Šs¿éŠx‚°Pô0»Ý@ÍÀ*4€9”s¨ÌïóýãËûÍîA`ŽÂ¿«Ou+€à%ã ¾¿†‡³Âã˜qìâÎX4þOôo‹ñï?mvíšhôÿ$1ô„U‘±Yé, %ðf›w>[¦÷cÄ„}ÁbÄl 0Ù0WÜÌ/›Ž—í%è-ÅùðïóÏ¸½FÉ2ÒØa`LË±KnYŠÙŠž`ž=û2e§pÈ#[žŸ¡}BL£¨¦ô®!êv ’ÐÅ(L:0¯Ë@ö‡ˆ‡§~Ìïw8„þÓËwùyŽ÷™ÜÏ_ƒa4EÓ9nJZÑÙC°…ö÷ys/7Oè=ëBD^‚AÄ™ š„ô‹""ÓŒ~:‡þôO, iüÍâ4‰_™9øÐHè¾I8ŸŒÜ7©s„¾IÕÃ¶¾IõäF¨µÑ½˜]À5L¥RN‹¤ù2Çu€ùÓ²‚áîAQ{&ÌÂ13´B^Ö„¬‡¼xÈ¿‘Œ%°ÄÇ"#ÀË²´d\'?A»âÍö_§dC®&ä/	¸ü%ÏÔ`|ežÆxÇBrrjµ±Ûè¿¬Ÿ ãCãË$!AûúÏä¤ZÜ×Å…Àéa7¼™[ž«ZÀ§¯(¿†Ë½«R¸¯Í%ƒˆ#-q,^{{ïw÷Hõ™¿}›ß‘ÐJYéù"Êæ>ßî6sòàÍéüiÏd§"\“?~ÁÑ7å_hÿ†å/H·MÓO˜,ºgã€?YØŒ.êþÞú&#öNmÄ(¤;z¡öüŸß‘ŽE÷i18â@NòÔŒNÂÜZÄ'Ù¤}Ñ÷6e°^#9ÑÌ™å™lY1×ÒGqš_÷}’JÒRpƒ þ.ÍMV{>Ùƒ.L¯Ñ
+›b	Ìº\½vox„Y™™n•e#Sý³Úäæ ì}{ä¶·˜¬×öOÖEï[îþ»VA2õ—‚d†n[Æmå…Pªˆ3}R+˜:ì“tpRÇ6ß#Hw#sÐ.Oþ7†°?Ê^pÖñ¢ûýUçkÅ9;YnBI¼P	%ß’Þa¹í]ú³M¼hâEÑd9qÑ$X¬œÈ&%V‰ä“µÄbJ¢2/`î+¡ÏE
+ñ–D£26¯X	!N¥šøiK5ˆW…R“6»ÎJ*à¬L|'Þ¡]fu·ÂKûJ
+:\³Vö»÷ïhcYªÄ™ïÐÇƒ…„'øG/ÊxQÆ‹2:¢L˜N]”ò®õ ÊLÊÔÒL¼¹Å¹%	:	&=š\È˜êÀ4M²hÈw’H#]6‘ŽHaŸK#ávš4“Cç^2ð’Ïá$Œ[ˆS­šœuà‚´&Ñ[fÒÐžã’i¬§ó|,7=w6€;àô	Áà=IxšóáõÂÏtOK5a¨—muwÙ™š’Œk#Eèõ_Á*Ü—‡çuZ&Øh¶¯ñhß>>ì›-÷¶Í÷»’TÚWr1Ú%%=ƒ·k»¦ð?•2–o"Ò Iô)pJaI©S:Õ"ÍÿNA­FÖº û¾¶ön@±“–Õ®d-®ñáœªoK!%âü¦"ÂèŸ/·ûÝ]›wg4â|Z“¡¸³6'¦Ý-ÀIƒÕ.É1}!;j*€ñÌè™ñé1ã¾ícÏŒ™ô¬Â™Ñ|é’#îyRµ®£ËTlì$E²å”°¦}ýÁ\uÍãwâjU˜ÄOÌqóùgò0yòqy·{ø2çz:¡Î^0ÏÖ´ÙÝÊ™Âé‚ÁbÞÊWêèM+Ø)–™úGBÿø!vŽÆ…s?6Ã³1¿·špöOÜÑ¤ìž)Fz~©A>ÛµÙ_R32}V>‹çóò…¦¡*#$¸mäœÊA ¼&`ÝÆG07'P{8Ñ2X^ô¢ dÍ·ð2)HW±^ò”“Âã”gµÒ‹Y¨¦=æ§Ü’jù.¹–yØÙfÑ$ÛÀ”lÉ¼:²m&gÛ_p×0Ý¢nÈ¯|™ñ-ÁÞ»Ëé|¸gtÛ$­éS>×W¯ðl~8‘?œéÁö,îY¼dñP‹ÅëÞ¹&t_N—äam|8’‡‹3k’<A2–OÉun‚†žæÍi>VÐ|E4½ñ<zãFÅë¶‹€ó£iN“=ç¢pZ÷©˜"Fð¬LÌÉªÍŒŒ•óc#ÇÓÏdÔ¿—„7¼šìù==Ó¦(šøT(Š¢Áº)Š&šÔ¤Š¢‰WÎyQ4’c
+äÄ?Ð$é>;R/`ÕÞaÙ™˜†;ŒÀéé«KPJÕ¨†(Ü%‹¶8‡‹¶e@XR*Oë»Í~»¹#Tõ„s³þJ50)fc"ïŠÓ«0…iRšUæUc!L;sÜ¤Š™ÃáIÛ€pXw*]­©ŽT(–¸³;ti©¹zÜm10Þ–ˆÇ*UL†©uùwSGãSfž Á<å±Ÿ,ïdŠ²ü®¹hÅà„€v¨fSI™‡Št;DÙÆkÈïXðï#Õ;ÚË3P2Y›ûI%[îÝ5˜¼\‡«L Í~Í¨GN¼I. W ˜œ«yeÆ”Ómâ:áà¶75ÁxŸ‚G¦Õ,ÕhÄZ[(j$4ÏkóÕ§s%›…ŠRH«@os{Ùí·T¸Þ'?æ4
+ÒF6çËi^<¤¶ÇÈžsbY©
+ÙÃ3Ð·ÇpÞ”UµÝ	²÷Ä/´ÇŸ+ýýô}ežö•®Ìuð\í3âS¢°ÏÀº±Ïˆ&5)ûŒxåú±ÏÜ#tÚ=îó"Ç™·‹ÓFÅ eüÄNÁ‹¶Œg¾#\7/¯i¶°ŸŠe47Ž§œq÷ëÁÙƒ³œ!8+€Ìµù”,+¦3LV.X?€|Ì?ìðÎS2™LU€>s*LÖå¿uÒJ’~^0]ÒF†aÂðvMœ”º‰ækt‹YbóAÖ°MËÖÐþ%ù 14ù óÍq¿C]ÎJ¾D,
+¨p/SÁ½‘]õ…çgšRÈ@ÂìƒIRD(’U¯X ¨0ìò¼M%å±Dôdµ%¥Y{¡<Þ•-¼üÓDS(+"èÁËQ¿§qEq•YîÄú{H¯âè}n§7WÅ±C„]…Ô°«ýÝUž]ÑäÇ³%»ÒNÙ•}È»f–ìJgÔ»þBz‡Ù5ÅAÁøçÙùà˜`/Û'XO°ž`9‚¥gÝ’`KÀð{u[cý0{>nN{
+w.Èvþy¿yxw‡ÛvâÝVYv¿‘³„³F¤†ÌË¼S7Æw€tHø×úc€|ŒÕÄ|<;¼mfÌõí	zÊ½Lb #}Ä¦´†/Oh7Î^.í9›4(§¡ K­Èø·–Ç5¤»½ T KÒH±© é,Øï1—‚BŠ…¥LPè)#‚yâD¿u¤:n¨™ÞWø_c”¦
+_#0¼>£ƒ©|#&ÚNä›rQ|³:,Ó$Z$æ¼l_ÆÞÈ>/Ã6º¡K°:ñÚ>‹o9ÞsËâká7n…ßxÊßœÎ¤ü¦‚sî7Åoû’BeÞøÒjîÞÏñÏF	ãÁç\dŠªCxú¼ÂÑÅŠ²Åf¿Ûœ
+¹µ"›0©áCÕÈª„¯)§„§\Ž{:ªoññ-½ŠÏ‹"ø~ÐMð¡hRãçU×Z9çÆB³%ñ€	áÖóÏ»­~=±Öã­{¤Ým€QzßÚÉêáwèˆâxoäu0Ž§Ž×™ð<{ 
+È“H‘Fuƒ‚È¬-TçÆõ$ã:9Ø †Æâ2fõ–r3šÎëJ/g²«éôZ¦Ø€„Ã¢UxÛ‹‰¡|‡ûÃ.ÿ¨M#]¸Ã!I$ó'’•ÔbŠ¼äùÛ/?²ˆ¥„‰ŒÁ\òüý›¿ä‰&ø÷bÁ‹Yýž:áæ™e²—<¯:¢Uf¨¨Î ÿ/¤<a#ûË'3Cjµú´Ó”€]œ}ñ¿ÑÞDôgub¹	aÑ_Ê‡%Bt¾±ß+˜{üöøíÎ†#È -®˜§yr Ïäâ>}Ö¦PžÖÔÆ7æè.a?öœÆm#%˜ÓöÖœ¢—öœ¬«°ë½G·®p	™l$“0Ö“
+ÇnoÕÌªÃæy]«Ž¥dWR±l#úâ$NÐ²£õÊ“³íÄ°×u¡ØÝïØzôÍjs÷þžËØ[RKÕjµ¨Dò@Éº0ÖÂ#k±…0‘/s÷¦êýÍÿÆÿ…ýœœÏiÊ>Ív7ûÍ]>Ã#¡7¥ŠØ	Uxq~sÌŽ¦›c¤»¾í!âÁ'l1’iŒžžK¾FÎ“uÕ Z„²6Úòz=Újþ¹hM2À–ÿ’Jì­.Úå:ƒîBzƒI_ð]DÝÉ[o¼Ò^:Ük´ÌòÛæ¸K¦ŒH¬söFeäËú‚ÅTŠ{VÑ™Pì&®dYÄnrŸ¬ˆZê)~óz¹Äª,	›xzT“ÆEB™=RNˆÙ_0%€0åÇZp‚Ufh® (ýû@A«7uP”[KÕLx•e@ÕßË©ãCrã!€h.þiïô¨)÷í.ßo‰ÅGÂ¸øgeÍ?Ópß_˜;ƒóÏÄ“rÞ†´Æ8/Êÿ× æUçÄúa W)ËøMcÿ–vü½Ôæo2iØTGúÆžÇÔ«9T×?ð¨Å+N­B·'ñ‘H<JMZÒ|±m¦IêÁb	ûƒ}– †7fàuEŒÜô¸²¨!’:ÁBA€ÍxœT@L_& ªçÎý¹y·“ü‘þ—>%³”/š×Híî†6>½aþ…eriTKŽ’Ý7$E}>\Ša+q=‡°ýþµ@ˆb™TËŒD1ƒ¤o$‚X«‰Tœâ[»°$/…9`X;i(Ó–†êñ¼ÙÛ;Øµw„6dÉ~ÈqƒœËæÖcáF7K–Æ¹Ý˜zýHe¼ë5#<ÞÑ;ŸóÏô/ER•Ž*ïËa¨G²UÕX|JüBúQà-D…e—høžqsó!ÿ8£mI%9“œ6Å`wÇ|ƒ ‡1Ü¨¦8ÜkÑëæÔ€«þËJÓl¼„¿ìßËeÿf
+ n[M•p’ÕB]àºyš;\Fz'ËÊ.™–˜‚•½æD†ˆ_,@ç{Jïd©4–}ü[KÕô×RPéû|ÿH³Ñ?´(µ˜ÉÌƒË(n[qdÖ=2)’¸ šƒjQ`$
+e©3í—ZMþÂê!´Í£¶bäé³÷õïŒ§'(rÈÐ>f]ØÇZéá/Ë;PPe¸Üâl…½«°âês«ªðéõªYõ$E¾ÓbªW¨…¥†‘<Âóè`Ô@Úll£Áƒ¤ebýK´(Î«’²”qA2«‚2p]Êh´†2ªA¯ˆ2˜u÷”á)ÃS†epç]EUcG”Á>)Êà¥/Ê8æ»‡mþ‡ºª_K*žìf¨ãvrÕVeG|=™†¾mŽ«öÇÀeÁ/E}VÒé7tEA.ùfÚÏŠ±%x‹0×²JÆñ7²ü,ùeÛÈ0ašþÙ®Û®­âi›·šÓ›À•[í…t~é¶@y0óMCGª Í¨üî½³#×”g%í§‘´Ì·mïÎô—ŸQ”Cê´ú½‰ÈËû^ÞoÈû¡aždþ˜‘s¬oÁì8CåÐB?ÿÒx¤ð˜Á»®«@ÓKà,L)
+Àt	øk³ãYA?ŽO2€þo=Ø{°÷`¯ö±©q8Þ ägMW€I§5äøXÀ*ôyE8@Óö¯iö’ðxç oà÷à9 ”Ç[Å¸# CNŠÊUpÏïÇóÝåüú»ºÄ	žÇÍ”ãÛÍ]>/ŸžßoÐ‰.ÿ€ÐîüG:Ýà~µ-ýŠî_4zdò=tO˜œ… Å¤­¬lÝÞ]ßC ù¡™ª)e÷;ãÓnnÁ¬nKãKçÔ9°ÃO9“Wü+›ÒM¯A¾a=M<9uV5ëpMŸI˜¯ó;#WÅ›®àJÛu8ik+Á¤·lõrÀ€Im™´Ý¸Ÿ7ä!á½Ì«Kž
+ÞÒH!"Fzc¡Ä2ë„íÅ”g„0_Uyl0ø1Ý&‡§ÅNZi±µ	 ûK‹-ò_ï5÷ Ü4ºv&
+p»‘–àýÈÌôëÉWBK0Ý«Ì—•D.x7Eƒò—ÑD~(æÑA#]ñÇˆÉE'{:¾¥'§xË.‰&¼|ð$ä]Å–D§°?ãM4U©!C/3!©a¤®µ—ÞHe!=)#>TÀç¥)"m]/2åÊ~…	´ Ý	x¦¨k1ëÇE˜`œÅà^m¡ ˜‘= ºÍ›6ˆWV¶»l8«¶h·»¼­ÝîyüšxÜ_çÕ‹rÌ`JZ©;} í|hÀÝ„›QW–îÓ?²ÓZ»‰d)îôqwœ¥$öþ3þß/Õ¤¤YãÉ/šm+Êê®ÆÆ)4IÒBƒ³Ô§&.˜}ÙVEI4ûk²@Œ*Ú"*´!^×ƒK£Ù1âÜ]NçÃ=ÃL	 ÃC¿zEèëêQËúy©{øOèÞlÿUÂvU[€ä*ñ«²»+ð{ßÒ@éŽš*#%E%”j?À•æ¢®A¬âÿ¨tÀ
+lt?œÈ[­¯~[¹²W¿¶T‰ãÏ%‰57rG«‰÷ S9¸£õétÎï_Æ‹ ÍC~š³?AÁ<Vby)xÑ
+¯33œ•¿”MžO»d­¢ÿy>?ÆüÁXDÅˆ­úW¿=l.èàwÿoåÔ”Ucaëô‰çJÝaÑ€èâ³O££N$Žmiow ´%¥¡-U3›È–æ€ã¶´—À}\K	€‘ #- Œ œ¾€[Žhp ŒÚ ˆ¾"•gÛüaçÐ#`oé!`ä£É!`Ô/ÆbŒµ0vˆ€+5Æƒ#`ÜF@|\6ïòÙÃá<{{¸<xôØÆz;ƒÀxr÷	Äê»#•~FgWØƒ ÃŒK»¶è¥Kè½&áV‘¿|Çý)¸üu¸û¼ÈŽ¿Ý×EÊãæ\_“ôìU\ÇlÃõDrcŸ\þŸº½yf†ŸÜ©3¨]j ÉŒ2úupîÝßg€r?àæîLî`	ƒ8H“ùg\ÜC+ã:iïLŽÓtmŒ—¡¸&qíeÒÀÖbäNÑÃ÷ÅNôoßz õ ê>vPÖÙAw¡@›Ö8àbHËù÷WÄtÏ”—úó¿÷™V¼~y&qè­T.¡z•ƒÁ•ïËT<Ž ÆçéÆß¹«I”Á¶Ñ¨÷¡…äÂ´®¡™˜|ø€£¾èktÀÉ-‰MÄàÛk
+ZRI:¿w/>{ôïËü —4› SˆÑËVdš	¢=èøFh!z5C@±.¶»<HºÙHÍµwo;X{NÌfž¨##Œ'8+œú¸2œÇaÃŽqxih–$ ™uÚŽ.°ÀeÉ$FOj-] !„äõ6ÿï÷J¬†ªðºõŒÌáŒIa+€š|¢¸£{ÙIzÄöˆí±ÉÄˆ­:F@œí¢ÚÌC6È-ŸÌøè­Z¬Aü>ßîÚÅ˜¹iñMT¨Í´v!cÃ÷
+ƒV¥P2ì4‘}çŸèì<D{ˆžBYgøäË:·›Û–u†&0: K–f(Fo‡¶Äf/GãV+ ó¸¡â›sàÈÓ„e¬=ýRÌp¶yØÎö›‡weagÓ§»?“|ÊO ÕYªË'l„hÉ4Flù‚Ù‚œÐ@QÃz^­Ô 
+êHO«15u"1R£ƒ¼ÙnÎ^¢öHÝƒDmjôœ$ §–Ö¥YÄS£%«3B“Ô4'F7Z©Qš} Gob‹ãÊ‘'ŠÔh¾ÿ•ßÎêYzˆö=9aš=DzÂtù„Saš9%£µt†jò7Póm”0Í4wÒpî[€äÈ¸Ó„h\¥˜žÇfÍÓŸ«³£)>“önÅçò|ŒŽÊ’Õ“/;“L¥“º3MG0>+ª•L§ñŽøÍsÆÌÓ¶lÇ—c†‰=uç¸y<m\9§ñ‘\cÙAô‡ãïo÷‡vÝrnr­V*Dçpb	õ"åÈÓDqÔïUôðíá{r¶öüèÙBÊ'œÚBêiŒÕÒ5ê¥åW_´ï¼ —],JÍ
+r±4õo¹$êb³øfá©šÆ?Ð¿0¼²ŒúvßÜú>Kñ/RÁ—^L¬±¦ÜìÛÝéq¿ùTüžâ7{—¯IÖ=šº&—NïìÃ·Oû"PD ^LY‰vVß¤la6š£Ð^–¯²9¾»à)"|}¬žÿªûË;ôštYbº,dö© e=«eãþLÿ(žzSr¥î"S8æçËñá„Žÿ	íÓS^ýfDJ5Þ?-î©`Ï!½$¦ñ…   ·'W<­X^Ó†ÿþ$¸ý^ Ü=ló?äÁÿ&¤¦™‹«ë!L5Å’ñ¬„÷X*¼!%Žj@ŸÌÉËëƒßFïRí»qP„Õ¾™v¶Õ¾¹!Ç‡R`úÒcþx8žEa#Í_…`Ê5t§1˜Û‰¡šbÄiZC2s]ÌÏ\ëò³ÓîœÏ˜÷ô úÌAÕBJe¶‘BJ-Zº‘R«aÇ‡Vp-úW$]î*'Ê ×þ]°¦. NŸTIë1§	²8Xºž¡—a=Ü:†ÛÔ4¡³àè Öf6…^ÕÖrÁ¡Ç]ÁŠô»·xg“œ¥/ßŸïÛWÉï2°e8H÷.À|vxQÈ@V¸*Ïc÷WÜ?«dÀGƒ¤ÒõÝf¿¿ÝÜýNºÌºuù+…dGÊÜø¸tÛ¦2©£g
+¿nªËŠàÿýá°¾Ý½[?î°±VW¼9:9ô¹ÆlF´z‡SCïkËÅß%—tu$…¹¤IË\ÒÅ(“È%]½q_¹¤<þçéÐN¿?0/Và•n3<œã±ÜÄ|b«ÇG|¼; ˆÿ8ÿü{þIšSŸ´zÑ€Æ°»5 eª'd,¢” ‰zfAñxQy£Võ9¤}¬ñì lñþ8 Qò§¤´YÖèZOÓâ(§¿GÝ =,Ê~Ÿ] °Ó¬›ä$à<÷¨£2Í}ŸIî«)ËsÜ×s—f¶gÀ%ˆ†BÍJôxÑ§ÖGXŸò3ÞªÐ´Ö‡»z—ë˜gjI4±¸bâm;[3º¾¹ )„ÃÒÒÉ£î÷è½ßM8³*á›c—¨ ì¸*L©ù‘:¯îø¬÷“NŸT¡ûk4¹®åRåyÑKÅÉ<ä4'7™¡DZqéyåj5:–"tl€Ð§ã[òí*¤9ÙsþW¨i»¡‹Z¤	h ÎBnD;Ó@*3|ƒçW<+	ß•”ã°Ô<àKŽ>u5¾S@@k_¸–¶aÇ÷MkÑ—ŒºÝàƒAÍ\›íV/ùå?usÞÝçsúèiÎ>«›SÖM…¡iwá’öqÜdù„¼aX¨C3Ù?Ub.vi1‹ü²è}Mpìëv†ÛÍJãéØb®ß9Âñr&úŸÎŸY”ê½ðùüôH×ÍŽ.å+®e	U>ÏE :U[2™—ÇÃŸÖ‡ãîÝ}Î2ùÅÜê™—tYŠïDÖŒûk—ÉÃvSú’OT*3Ã`Þ.'¿MB	 ¨sý¼iudÁQæsˆÁR1…uYçÁ¥R‚Kîv}yÄ£¶¨þùåãûÇùçÃ£Ô¨]7uæóÕÄöýÆÌôeü#xÑ|÷ðö gŒ£5yl³5óŠw[_Žû5{!ôŸTGû€gOJf•wŸ‚¼6åýÛêËLŠ¸Ê_ýJtg
+Äÿ€Ûôû½cA›½ÁíÊâ®‡ÇaJ»–ï (ìÚ|©í›Y—aü‡ÀZ÷¥[”Öå|À[jŸ \´A[!?æèÀp­çŸÏ›ã»œÈ/óÏ§|Ÿßáýº¦—ÜßJKûZå¢”ùÿ¿Ì/;Ã|ƒ¯–¸ØA_ïneÊ ohmúŽLùkfží+áì¯ÞJä­D"ÎX	îâU‘8xw2‡ Â5ü*ÍÓPEß„ìì±‘¶»Ë¢ÀU”g‘ŸbÌOÌ;”DEþÞz	Á¯ì[¨½»±=ÏÉÖ’_ç¾ïnnÓms«|Á“´ÎG‡x»×½éR X
+€(UR¡À>ý.D”à…Ó‡üˆÈ •”ÈÙœ¹^Â Nbˆ¯À‚34°wçÓ–uþíáãÃþ°Ù²äº-þVXéàY>w6žm=ÛJ4´¥"‰ÙS--jœ ˜ãúh˜†¥¢FûFYc_G¡°µßKª²5jÀbðÍÅï+ ´éÅ/‘Rmdb7†)ÂOºˆe
+#°ö~X1‡nMÌId#š0 Óë¤`\Þ,¸É¬Êzìã›Æ÷¥<¯ø¦84tØkž!¡Oðè›ëlâZ3?äIsûÀw÷8ÏÞùpØÿ¾;a<yò¦xÒågà|ºRðÞWÎ¢#Ò' Òÿ€{þ•vc=ši4«†÷hïÑ~ð	†	´O€÷+Þ“‡ß”OÛ ¾Þì&€ùºËØêïïÞ¡ý ‰÷ÛüC¾?<bHšOjã½ðY7xÖjk//0‹Žx¿ ñþGÚ'õ¨ÏâwR43?xÇx¼÷x?¸toXcBû$x¿lã=ð°S¸'7E¸¬b_p¿¹{æ²Æ?¬ÏÇÍÃiàãÅB±MçpS òUO¹È†DmÈoð‰‡·ò€'AËþéoh Ö$ßÓÚñ®á3‘{cüóÉâ/L+G¨·< ÇÔ/~ÌæZ™jB£_¥ÐX²¾bŸîÛË>?­÷HnˆÙEµLÍ5t©™ør7¢Œ’t0Í
+—ßýpa[ÁK‘Ò£ÅTQDÒõíÎïgwå,É`œÌƒ2÷Otj?¢uý¾ÙLPwÉ	ÔÌ›z)ÚKÑ=e¹ev™"ËmÑÒM–ÛjØÑ‘^‹!À—Ö];ŠêMç¸é¼ÙT…ÈÀSnü– >6ßÍ²*”ý†v9°7çõág'è»-ñtv9g·ù,Àû­‡iÓCÉÕI¹Z~¬„rµø1[¹Z6¡ñMkÖ›QƒÅöü´!wL6û@Ã>ßõ.œPÀ
+4qÇéºs“éÆ	ÃÂðÁwÌ2nÀrlÛÃ=x*óRšø~°áñ‚S/¼á:±¹l4×ñ)ÃtmûæËÃîá„Æj'cç'Ùn§ä‡Æ#.Š1²²µ´ªzìŽŽÎ•þ+;=ú[=ºyòÃ¤f34Ë¨d0ÐÔÏØHúÒ©Œ_‡Y±R}…Ÿ· ZS´¯Ú›rº‰V­9Q(^\K“NûJ„á2Ù_c+~Ÿ]<¦{L:`ÅÐ†£{˜ñèÂgmÂU´¦6¾|®»„}ÉåhW’Œ@ø2ªy|"ót§ÅÖóN?…ïe²¸ f&ExØoúsÝ¯ðÒÏìØ>PÑãþÐ¸›â¾ÉQ^UÕéÀ†ô'90YÑÞ¸ Ì³Ö‚þ¢DêÑÒùrš³U5 [Ï8I—C<“Ðº=º¬ƒ[‘èLvzËô‡‡·6J‘&¡zªh¾	Í}£UV|øX(²â·r“šÌøP¬\­Þà·9æëÒS$‹1¶˜YfæŸ‹ÈÛm¥)]]5³E‹îÙ¡—°‹u)Ñƒ/ÔÝÕú’Ôéòöšq­eyTJMãŽ}¾z…§%/˜êí<^ÞwJ É2•ç¤Á¯ÌŸ5a·@yla‚ÁÙÃ% âÄãì5üD†(³¾¾<™Ö:HÓÛˆÖÜi h9ôÖ”˜ öK¤ì—˜°É¥µ&IpÊ¤[Š\eøÿàµ³•µˆ,µ(æG‹Æ­|eÕ,­4.Ë„B®,ñ® #ó~õ§—ÿZr‡OWölÓ•eŠ„ÒÜ¶àë%,ÃÉ<	ËÞ—Ýÿå¥S”/68Exþ-Üæ)k­ÓìÿB Ç’iëút—•4U!‚Vsíª5ü“nþá„­A­9ttÀAÿ¿½]ÂeƒY=ü“µ+y­a²ÔÂ™,’•ç`†TRé¥|Ôi®2`bã¢4×¯/sÔíÍ·y¾=éÖÒ¥UŸNsôàÍãåv¿;½7É]#}Þ_ÌiÐv½fâôO§ïñâÂ †ùåõë;¶G|øƒû…a;‘_Xr” ¿p”âe:xÃôàÔ1,œåHÀdI{£‚ËÃš«‘.õ£Ö7zÕ¥º|0©|´¹xÊ)Ø™jÂv-Ô'k£Aãü´y¸löûOr3MWh§Ó:ß®ÙzÅ]l9N
+RâyXßmÀU˜?!.pdö	µÀ¾.YÁ5Ák²L^éÒ;a
+Ñ¿ýä›Ëšì:óš èk­^_heËâB‘lÉ…üOmOøéæi}ù_ö¼2È`sO›aá™t”ÿ— üÿuþCÝ7¬ -ô×ÍiwG1Þ[¼.pÕº€øXiêuoØÜê¢YN€L–´Wv¸ßìðA#·îÛvbKa(+ód§­çeÁLº1VÌðSÝ÷Ohyav@ÿbÚáø}ÀSÃÕ_hœ+óëL½]à&9Ef¬hoÌ@T-‘©iÈaF°.p.}d‡.´£B•·êa[L^“Ÿft‚é§jºf(–†%J¤Hé 6ïØ\)Obüd²ê+8ý4ÔæøI?Ùn œl´uy±A[D[ƒZpœµÃòMË¼®ð^«&#]9ùœ#'£Ô0±¼p»°ÉÕv­Ûd+†?a±hQúÊY|&›=üNdÄØ<>æhÿj,šm]d‡óØµÄ_ª–¼p‰~ÍuÒQ˜e•.ìÏh]Í/6eœ¨z.Î¹OŸ½xÚ	c¡S"ÄØfc[Œm>Œ…¥WŒ]Ëo±Ö3™k'~=ãÀN.àÌ	°ts“ÔÂ˜‘VH]ÅÈ‚«*5˜(tDˆ¬îÂE<î>³ØheèT"E:‚öCnÒ@“ß~ Z¬Þl´¡Ì”ô/ör‚Û 'ÛÄ£wì ŒØGÀúuÑµ0®£–·»Çux9Ù;ìºÕê0µò* ÙÙîï¨¦3>h+×kÔ^“êc÷ü3y@#Sôpón}w†ñ(S8Æ²u-g? œÒÀ`c?ýD¶XR—ŸqõRíÚ‡IíÂ¹ÁªwJŠ*º¼ßêã•êÉµ~2êÙ[˜7”_ìïB#‚utæ‹ye)Å?èÂ¿³èŽŠYÖŒªi¥ÙP‡M¸g\(‰!§r1u2£c"ŠÙæ4+ÎÎ¥2¨/eõ–É­ü·´×_ë}çM?Þôsý¦æØé›~Š‡œ›~87óM?Ìbõ«D¨òN2s2(Ö$~ÊØ‡ptäð0,Ù$LÜºÞ/quQß¾‡³ºS5’¢f+ô˜›š­ð„Æqõ’õã»ûü¿P
+ƒ ‹ßçŸ7··ÇüÃŽ„™>¼}‹¤Mô»Óz»ù´ß½{^Ÿ6ÐZã‡tÒ-òƒ;ˆƒIW„íiÊu~!-
+ˆEÐ¶±PLŠ¥wù¹üs‰™ìŒ™) ·£“Ç;ã&(@Hðxû E £ýRP–5ªV½µéŒ¸=ª¶  8¦0]AÊ;ÿåß_3;ÁÒšTþFgÙü«`¦e³?ÿ;þbŠ­Ròå¢6ªÎ3çnb“ö¸õý¿à$NàG…(·‡=6P¬”`ß:Ï‚|>ö·›ãËÓåö|Ìó¶Ã½h0/Ì?¿ßœä™[8Ì~œ‰uHöcÁLíÔ,ÆXVôÏ‘,ýg/+FÿúŸ›?îŒów—ÓùpÏÐ#›Ò_oDÂ¯/·¿¢a¿®úñÜÚ[±Ó†W£Èç™*µÆª„úxß£3 dÇ86mŠúZZg3bKý6ŠÌÉðkIý*ÜJ”9yV?Ù“/ÛÍ9yG;Òô:’»´ùüˆN¢ôª–¨u²hía;úÞƒÜhoÔ÷þùï_ÊŽù ª'FF¿ÌÎ‡}È<“oT;Þž?nŽyÑ9@aXý3ÄôÅŽÞÒ6´cÞÄ‡×‘kRœ¼âãUD?MB‰2Ãêê’ã\uˆ‹ÛÜæ²ƒh£[à$KÓ¼ß“ÔŽk­„ÖÌÉ.ÕÏ‹ <æ$Î*åú:ð œ@G9þ44f¹³ª7@`%ò‚%œrçl!¡Y®%Ùæ“cïƒQù`V†>£¨x{ÎÆ£œÒørt–ÍyèTI¤ –â\YuKÛ“>àBà_Â…­Ú…êMüçíìg™ÌÿÓ~¨Gà‰õ^ü6{È?µ½üïåÿ'"ÿ/M=óÒÓ	¨ P~Ñ?^2Ñùõ¦Pð§ÿR•ðå©ëô2í] 
+_žZëVÚ[:{VÀÿ[5 ‡ûèå/ê=Ô?¨ïžr­})×øÜ¤\kNb|œ—-P_0O•
+…ŒßÔ<´e}éƒ.ì>Q ×Æj"hLaá?«dÏžžÄ|oÏ¤À
+p2…Uw¥Oº­¯ÒšÖøÆ ½ÅëËTP…T#hNKW3=ç„'KPEX	Ô«
+ž$<I8"‰ÈPUÐ9– GÄŽ°WÔ“Ÿ!´V®/‚P$]jNH?ó’üI'þãÖ#ÚY°›sèÈQ‹!(êK0a¤ Íf‰øâZ×N×œµÃ¦´ºì<iÖWl>ê¦´ºxbãÃ»æúõðAÆ¨î®VŠ (­>„Cþi÷èž¶ç¯?lv{Ó\îÚ§ÝsÍØmãªÎÂUÛxÂ«¶5ñMøÒ5êË†¯“§š´Ñ7ÜÍ]8j3PÊk³7î: sî”³È[b®J>–˜(3M|$9š ä³Fz®½à§0>ÜKV§_°—áé\tMïíÖNn_!9ÌvXoe÷Øî±}Ä»WÍÃ¨¸{Å6ws÷ŠŸÀèÀ.Y÷¸~B»˜žÉ»c.FõÇüð¸Ïç6BXš;	µ„ƒìk"äÆ5°¬`dB#îÎŸ*€Ç°CV}l‚¶-G=}½ÝÎp#óTÕ)ä¸“)(§N@™6xù¹6Ou£ïU¼><bËÃF×êmRB	‚Ëb™Â è´úëKú=]×Na»iõzOÒZc!¸·N¤BpçÚ»ÜSße«Ó'Àï¶ù|/
+ Óù¨ñhî¤Î8œ§^/n\+Ëy*M$Ý®ÌHÛ|gñSþpùëþp÷;­ÓØî.¦gj9¯®`ÎJj óNvaLONf÷vs+$nsíÝ qc
+SBâÖêô‰ÄõFù3b€ª„îÖ3N¼šª‚ íÁ;ÚU˜¼ xÅ
+«
+ú¯Ÿë®áaF^fxSø9‘¼ñ&Ïy}0JŸIýá££Hêß~ÈMRh2ãã´j±úë;¼m÷ë"ïX©q›ùgü¿_æ´é¼h:ÿŒÓ^žÎ›ûÇ/4‘c¾E38¤™'I/]5£ƒÎ¾\€yþô:½Š¾Çí‚/¨Å7´ï:ä‡ËÃyF‡Ü7RÃð‘.QƒØ8ôo.§$íþÒkaŸ¨ÞïE¹Më×©^Aj‘k;Qô÷DöË6ßç•Ù©´àyoÿu
+Ã¶óƒV"Mö§Ç=Ë ¦‰´§_“N¤yBè4À¬•XÔŠªLpjMüA›ÿÏL)“LW³hfŸffÂfœ3\bž³½ –9¦ùU.ÒLxaùEªIëÎ š*Ýha˜Æ!˜â‘ë/*MAÝu9M-Å_AèÈŸ€tJ¥ƒTW:ØÞí`¡€ÿIDõL+¥‚4žáÕf†ë¨”"¥ìGÜ)¨Ž¡ g»…"†Æ^ã>×»ÓMñÚ>tšhßýãë‘|Õ+<âf‡		ï§ŠîŸ5+5Ô›¾ÈÑ8U>ŒbÃäÀJ,¤5¹‘f6¾çæ€iX’”ýí%h f(EÍÐ5_¾?Ÿ'X%§t
+Sñ¯äêË×—ó{,eÞˆUfÊ"SK´1þMYªóŸ'(Ÿ=–ƒ%Ú¯äø‘hQL–k\ `Ã‰©î”Môî1óybf±eTÐÙÌŸ,EP®±N{¿äªÚüxš&VxZÞ€’¡ª´ð—–ÒŽÇÑ‘k†MùÓ9x¦p‘01x
+à“Z´¶RÁðã#ªp]zVô…hÊþ&ÁÑª™]$`ª˜ d5µÂÎ8Õ7¥—ÃuSá;F›ûŠNO@7¼à	íp@ Ì80Díl`°5äø ¬BŸÐ'—&GÀ¿ ƒ¯î¸Ä¿ta!;ÊÐ06BCP„4)Šá5uWõ1tpÖA™Œ!Ôx»“†Ý{N»Ç}¾VÄ–ðáá¤­þ­¦¹‹Ø¿,Ö¼uSÅ[˜{˜âfxGåaú©X1ÍñMíÕkÿÑãÝÇñaÿfåqºÆ°?7cªS£y3†´w{3¦˜Âøq~’Õé'Ä,#ŠQ	¾Í¸<LÅFÚt¾ä/õ5}ü;x¡ûŸ>•±zÞàM†iš€Ud,*YÔåaO}äÕ‚ûº¤ èƒÜ©}Ï„ˆ»ø—‡ãV©æó{tÅ¥$^ŽØMždÁ¡q¤è¾C²Âõ‘Oùyöép9Îê9È@Oê(òQKÃÊ–¾¢ÁÁ11Í› &WµÊ^¶´QÚaÇWÛÁµèGq/³@À8ÚúU„£|C8†pìRµ4lú
+MA²S6,ú}Cî±“ÜuZâ"¾KPå*ÂRcc²ãé3¹91|ö‹cëÏþäPšÝÑr”.[:Ai~E'‚ÒìZô…ÒHvA4úiþù²Û~ißiSßË£¿Àÿ¯ÝaÜ¼“ôvá|ã:“¶³("RYÛ ™ÆÏŠò¨—ó€²²›ÄGrYïÏÃúnƒ€èIå¼¸2ù8aãAÄÌÙ½¤˜^K]i«£8É.‡q:XœÆg’ÜoÛmËëið}¶ê2[ù1¶ÇÖ7Øê÷ìãæZçÞÊTÜfS‡÷ŸAzÍð«»$º03]Æã6a€ì)Ù%FdG4c%ãéÒ[ƒÚR‹dÛ°Z’ÌfEc‰A0Û»üüKÉd°ùÇÍÜ_^óÔö-äqÇM¸³`°(T0˜˜šBkjb8 °å pQ\|*Æ÷¨ïýù%)¶K®Ë5ÍktMWêâUgHáÚÈq¨§Ú˜ÞV†˜¡éÐQp~,‡õ¼àyal^È2¸¾ñÐÊOæFùQ]LTæ-l)/ÿYê8¬²d¥Þ´”%“”2¢”%í¸e)^	É4l’iÍB ­:ÊÙð¡ÞvÛâT.è·:ÍÙfªËÆNŠFÇpØeÔ‘ªÆ¶ôðdÔ¹±ÆýÕf!8ç9n3b‚Å>3Ÿ¯˜e =)çè)Úµ½=)úP[2—ÇÃŸÖ‡ãííÍ~žú°»Ë_6|A4i™]¯ÓŸ|¶ôkŒ	]®cBåG]¶ÃB«Gl"Ce¿þ¨bœ×ý°Ë?¾¼Å‰¾×Åy!á¢ë@À§óñrw¾ó9yˆþïMñ¨šJ4wÁ+I^Ÿ“ÆD´H&ùœ²êáÅ=U“ûú>eu2„Û*•“?ùÍåt>ÜÏÈÄfûÝíqsüTpîw½Û–ê:÷ùÊÓ´Ý÷›OE³/þ¬*”…5é£ltzøXÀ/úd¿Ú’éõ¾n™•1ë¡©» ½eù†›ã»ž9BþÇú(âSÆ¯Àãþ‚u¥])`<QÂØ—¶¬gµl|ïŸIƒâÅSoÊ¨cÝµ§ôtÌÑ}8!Ð9¡~"´HxoBté3Ö¿ŠcÃÐ	 jSc2Ô>ÿ¦ìÀ¦`·öÇgM“õì‡BµÈS›&aBì@Ã÷/HÔ
+7âèÌ—‘ÄÉåTx®«AÊÉ-Œõ»
+fÅ\f‡X×É?zªëBuOu×DuÝ¢[#ŒäZÚF	6†F”`k-œG	BB»>?iÑÑœ4Õ&%¶¹ƒ›×q¦ªwÈ;:AaçV9žž¼Š_ÆÑÀ°ª '2OM^{FÔdW7ŒÇuÝ°º½³ºaì¦tO½µ:ÎãAš”êPÖürBmçŸº¬Òð?ñÃÍhÀhÑ=$kÏD-Ò‡f?:¯á]…‰mF¦Õ•ÝBÏn…‹­ù²ÅÚÿíYÏ³ž[Ö+®×ˆã*¹Í±`*Ã'PÖ8TÃa1dÔ!"/™7”Ç^ª^UŠÉ¯£S…q!&á¥”<ú	¼§d|Dãa$zù6Ï·€y<^þq/ÍØÅ5qF&‚k'ã5*†F‹yîD ZN!ÒeîÓ?7M—¦Ä¹š†VˆWÊ%?~_ôgÏžÇÓþBCí¯€E2&$‡Ú¼Á,´<n¨Ñsñ4^Üy:ž}L‡m.ãŽúwÄ‘‚q†8+çŠY£ÿ¨Ž§Â×ª<kŒÂ]ò¶•!ÌÛ†Xæm£cŒÎìëöCçÍ‡‡Ãý§5ù^¤k”æ¸Qi2›ãÆ2
+áŸzÁ´¯)¥{LE·ñ”ÌwšTƒá…û^KéÍºçµÏCm+^—¦Ó¶â‘Ðv–;;ÈTËZG JÌ`‘ƒÑ}n{‡³íI«K0’=/G€`ÈK Á:ŠLä	V „eÀ­Îrj$‚pPÄª×N¨^{âî2O¨£„ägŠt#®5Êtuî¯	Q¤$ÿHÚfH€…œÛ­ôDÓëvòˆIÚF÷Æ´Ãð}Ðï4ï
+ŽÎ…è?W3i0byõš]mg¬hÇï¢Ž’ôüWGŒQlZÇBÀôÙ¾¯m¾ßtüè}h!z	Þ?½ÜüsóG‹ƒÈOsî'€š­\ìà‚½X,©‡ÓbQ½Ê„©FÑˆÉd…èk4Ë@xÄà?ò;IÅëëó”pwe‰u£¶ª‰±®½£¤K	ÒÕÍlp®9àø(×^‚~0n}Ù½g)ª¯ñsÑIT$|ÈI®"¿ºz\¯…‰ÂtEK*A¿,:‚’}PB ©?Qt|GjWðˆØ%‚ºÏÜDÕ”¤õ'ÊYûŒDƒT°àöÏTá>^†€”g°÷`ò…ê)›Ë@ŠéŒŸgA½`½ø0(W\Î¼)ö.¤QÓÖœm=?oÞ©ÉCùp-HwD $ÍÜ’LÃJÀNÃ†€Ö´)cŸ~û±™ñÅÃÛÙXÈ¨¦Lóäê{Ä«82ºÒ? ^³WU$OÛdÊÑœÞP²½8œK!{¹TBp·8=éšÚÛÅæ`~ùüÏÓL27ÅcóÏøï_æŸkÛ1Î±N£ÆMÐfç/¸žÁHQØôWpöTL¦/kE
+q
+©"ŠÍ-o‚ñŸt¤®Ä÷U}J€¢¨K]£V2ðÀÔÛò¸%â#B­Wúç©ßÿ<ýßR×œ SÏùýãéŒ:+éÃL3IL5“òƒLOqÍa8÷ nL•¿VYòWåÁ-vw5º%¨û¶éîªRuÓ­$PTBTLTA"ÑR°wúŸ§¿TçîÏjÞTXƒÆ¹çõ”ù„èhÒjwê¢îS±>–ñdÍå·M^}]Ué'ú+D¯ÒŸëŽÌ%¼Øg_0?KÔJÉæDWÛØiAª(
+5±ðý ^„›¥T¸Yš7Ô?ý·HI…¹ž>ñ|'i¦è®-ÇA÷Ø¼åLp‘$
+9FünvÂKÓeÔ^è°^rñ’‹—\Š#¼ŒÅVL ß¨²ŠÌ$•L4…B,.E	Ûr-•(!‹t')!è2c‘K²r,¦RDç-åÔ”ˆÁœÁ C&2c¡X¡xÄ±¤ìÕ¹$%‡T,¹i¾dŸÄ·t4/@xÂ¥é#…#j¦dúX	%Æx«GV,ªãzƒ‡3ƒG´”H.…`ìÈ²¬·ùy³ÛŸLüÜMñœ+³×§cÛM³×’`r	Fõ–vòK&•_¾CcK‡ö2Œ—a¼SAØ}3¦de$³`TySÁÊ36…+,ÆzƒHwƒHHÄŠ&µ`é¢—˜î([pN¤–h§qWÑ"\$°h‘ÉEÍwµ“0VR	ã;íCD¼Œáe^Æ‚‘Ä®‰y‰tàN 	B³€ÛXòÙ$³–MÊu²I*[Œ•í•L©¬$“W°Ñ€>IœII©C)©—óáR‚BL/– ÄÖ€– P+© µê*@­Ñç8n:ˆQ7äÁ…©b€Dª%xÍ"‹´D*½÷¶¬’X_°úÏÆKW^ºòÒU%]­®KºŠàŠÍ
+éêMD^Èº!‹¤ØâhÄËZ=ÉZ²ðP¾Pâz‡0ù±‹ÄEìSâ¢¸—¸øb«®Ä¥õÞZWè@âú<Fâ¢Ûš|áÓ™PóR˜—Â¼ö<¤0
+N^
+»N)Œ|=/…(…q2Ç RØ1ÇmÞÝÀªrR]÷ë<¨:†¯•Çr‘KçEíœ†‰TÒú¥ß›´¼0å…©*°¾™5¥Àj3ñ©ÆZÝÇ…rìkªÖØGW»»N.sâ5Ø|€øêjÄk;É47ôYWqÖ­~ÇZÇ -I[°‘¼­Ó.Ðl¾'Ã{ñÆ‹7^¼)c®âÍˆ1×ÁÂìæy/oJ|yÎ×+}Ü”çÄ_w¾'Qùv€ ìc~8b|+ÖÄèzWñìMù¬;Ñ£ÑïDDõÛö+zñ‹ëþº—=¼èñ¤Dr¼ßÔøâEp½èÑ›èÑæÛ~Ecþx@O" Ì÷[‘ÌQ4šÓFt¶7'„R…òaåBÂ¬ÙÇd`–LÃ.Òº´%ÏôN§ò}56Wi“Òo§|;Û=”9ÜR…OïÁ›%‚‡HtÁ+NPùœÍ=ý¦xÜM&xéüÆ¯ä¡¿’ýUô(‘žV©TA=W³­äÇ*xÏº£{ ¢{¸l­*7¾®ã\#pýçzð°“‡fÕô<°{`wR‰ieX‰Iãà µ=b Ò,/´)Ç¤œÓ@0ž	Q\gÙz)œMðû”ŸñÇ?¡ƒ÷ooÝZ~åsóÖsÚ†@ANJ4-SÚ%náÖdôa©^Uµ¿ªÐDm|E¿¯‹Ê¨tÍ1L”gÖË‰y\wë]ªða[Y£éÛÊ.ûô`?MmBØ7=T€T/Ë[ÐêÃ‚Ì¦:~©'Ó¥í¯àSE·›ÓîÎ#ºSƒCSN¸M9â|I5ðv!‚H˜uç¯x¥,€7ƒþ#€hX}Uóü bªù6V‰MÀ„£·~Ýì7ùùú¬ÿòçûÿã¢Mòßá]ró²ë6ÿòç›¿ÐbÀ¿bË¿|uÊ7Ç»÷ëíæ¼Aƒõ¿f5%–uÜõGôçÓnÛüú+>—t*»‡3™%ùóÃá<{¸ì÷ä§_ùí»ê—Óî¿‹ÐÙÚìëg
+Œ¥?.ê¿_N»wù¶Ñ×Ÿéÿùj¿yxwwØæÒÉ}Ào»9®7§»ÝNgšûüá]IyA(˜äWüLªáz™EqÙ·;épøŒ˜}’ÛÝ»Æ Ç|÷°Íÿ˜Þ—ÿ34Ž»ûÍñÓì÷ü¸a›{„ýRu/÷ŸNÿg¿ÆŸfs‡íŸ2—Ëùíòþ–2³ƒEWMãX}<åçªØ4¦Û%YèmZ¬'v¬Owˆ´¥ã½Ý6¢òý×?¾V~ÍD¶&³MôÙù9ÈkÁRÖ·»gàfÞÃ¡=Îx¦hï—‡ó´öHå~óø/Ré±½Ò0Iô>Ñ¯'0üÇŠè‰êÝA¾ŠD«Fÿ®ùfÅ=ãÄÿ¹äH1<élIõ^8åÇK•]èÕNFªWØb±vèEÎìê`„®
+cj*Ç‚Qõj}tWjˆÆ­õu.}Ë=
+ùF%wYŠ6ËÆ±ÁJk¿Y©’§v÷ùé¼¹Aî¬VŸîén÷‡[C5ÈRò‘ã£tÅªßø7„÷÷¥’´úBHDØgthuŽ âôŽøÁb¶Õ+÷r2¢°ùmTàãøð¨Kiî{nÛ_vˆ8p;@k(¿ÙCë5^ºõZD­p5’FßìnX¯Ï›ã;ôÁ/Åí7ç©"Ñò Z¼^{õ«³
+LµÅ+} }‘Jè¬;&¾K²Û ˆnonóM|G›ôf³V7oo³·wËxû6¸S ÏåÊ©„†SÉ7áÝ&Û.n6·Éò&Î‚Û›Mz·½¹Û®V›0‰ï–ËD>cÙ‚ß,Äøfq½Kã ÜÐ€Cxð¼×O‹Òa¥«ëc¾{÷^¾žâ«¯}ãyì~G wÜõóf‹¸EdÀ!“ŽXø"{Èj±p­µEçy÷ð©Î†/MæZc6l¾ÒZör¬©­µõ'ãÿÒ‚gŒ	t*ÙóÜ?¸ãñ¿ê?FµíÏýp3Ë†4Í-lZä?L¡¸×âÎ$ó‡òÈ?ŸÒùìÉaíW_o·³ÂGÏ½ùñ&\4_¨<Vùña³5@}Ï7ÛmûEqÃ¿ýöãÀ“>¨ëUðò¼ÁRêP¯Á~/Yƒ`¥Xêæ:èi!:Ë<øx_Ð˜†e¥£G	¿D¿&HÇ£¤¦„‹–Q@ò:ÕO½ªúçÍ‡‡Ãý'}_çÃDwÆy¢óÂÉ«/r™ÈíÔ‚&5Ÿww¿·6¨¥ ËÈH¢¥©ü\d¿ñqtµøvÖ3ååÇûõƒ@îde³âÛ3ÿ&Ÿ¢úw¹4Ãq2m]Wuœ0ì}èÓÀæíyà'¯[Êzü–êÁªð÷/ÓO>ôm‡¦åê@õmEö4`<ÒMj[;¶ùéî¸#ò»xÃk…ð™˜<˜1qDóÆÞ8˜¹LgWâÂ{œt«ëY12ÌMÍŒtîdGâAÉÜ˜t¶²&HÅ¦á‡ÑnÈ¿ƒUPýóÏ²QÖçc†š°oÂØbÜŽiH€5ìºØ7k½ßåGŒŸ&AZ•ªÇÍ1WÏM4 ™9ãÅK¨O¸ðm™zÛ=—ã~½Ùï6Zf£Çñµ†Óár¼ëYhîŽ&Òås	¼V‡G-…›,hÍfà.kâm±g¥€Û¦5fJÍ-e8~±í'ÐÃ‘FÇp½>öz1·\RfÝX±«·ù>wnI2°di;GVäŽù‡Ž{{ýcŒ–)žîÅ-ªÞ¿	>KRÛ„óàqM€­÷lãqkg®uA¡øÁdÏ²¿š®k³…à,Å,R‚Nbæm¹•m¬{ë>äú+ /û?™@¦ÉÏÁ¯l•Nãæ')ÿ{Jë#Vö
+}š¯Ê+ìÇÍùpüª£Ç’.:ùßÇ¹aëYÊ³”g)ëµ`”&Y:¥Í^Ë¦ilÍLZ¶b~%z”aóf(7òÇÝ¶hÚ“¥Óð¼ï=&R1¡§.ÏhŸ@AÃÞÕÂi©öì³wÕòÑE2W-ÙHZkñY 8W7î<T7Ì£äÙÛÛ$6·7á]ºº‰—ñÝÍí"‹oî¢(¸MÓ4ÉÞ6©Å[Å`As°åÛ(ÜæÛÛ›,ŽnoâÕ6¹YÞÆoo«<o“·‹ä6”ÖE">i{š§»wØ^ú”Ðu/ÞOä
+¥Úqì$VžšÜQ×.U•ÄšíkH*wûÕ¬.Ür\oŠÑ&=ßfñ$c“ð8Y~<æ[=½]„dtšoŒ9ôã’6›“Ë$²ä~³Û÷4TSùÂ÷¬ÿûðÐ²×Š²ŠüÕ@ÝálGˆÍ¡‰x§ýáÝNžCÀÑívý˜7Úû|jM*¹R}…Ûp!5`€’\: LÕo-µt>…†¾¦'™´ú_õ¿%¡JlçbX ÂÎÏ
+O_ñCj¢ò>¤'ÂBAãïº&¿V[‡2}‡rkž ÿb¢ø¹¥«àüƒY™SŠ½·+îƒißîkª¹°GF ¿âJu­NÍ¬×¢Ú£Õ_8ýŠ[#vÚìþû*ˆ—Ár±ÌÒ”_:ðGf÷UkP¡tù—
+N«y™Þ ljøÃ¬3iÕXì¯þçëÿù]ôý%ùí‡ŸþßÕëÅËÓ_óß¶»4øÿÎÿû¿ÂþþëÏáü×/?,¶é÷/ÿúÏßþ-Úü¸ÿîÝWüújó°=æ»ÿgs>?Ý]^–›œÿdß]Ž‡Ç|þŸùþ´{ø}×þ‚Á°_P<oÇw!?â¤ÓÛÃ;­ô€}‡²U¸;QsÍ@)3›ljhmÞÉ'â"GnY·²söí‘Nù´uÎ]oäuw«?9¾™Üu¥ÍRbî6gUî.óÏ
+ŽEð9?ò^>C[S0”æÕ»m)Á!$½´¼p’XýÔUÂýÿ’Œ§Bz 
\ No newline at end of file
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php
new file mode 100644
index 0000000000..0c537f5345
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-data-revision-metadata-fields-2248983.php
@@ -0,0 +1,162 @@
+<?php
+
+/**
+ * @file
+ * Contains database additions to
+ * drupal-8.2.1.bare.standard_with_entity_test_enabled.php.gz for testing the
+ * upgrade path of https://www.drupal.org/node/2248983.
+ */
+
+use Drupal\Core\Database\Database;
+
+$connection = Database::getConnection();
+
+// Data for entity type "entity_test_revlog"
+$connection->insert('entity_test_revlog')
+  ->fields([
+    'id',
+    'revision_id',
+    'type',
+    'uuid',
+    'langcode',
+    'revision_created',
+    'revision_user',
+    'revision_log_message',
+    'name',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'type' => 'entity_test_revlog',
+    'uuid' => 'f0b962b1-391b-441b-a664-2468ad520d96',
+    'langcode' => 'en',
+    'revision_created' => '1476268518',
+    'revision_user' => '1',
+    'revision_log_message' => 'second revision',
+    'name' => 'entity 1',
+  ])
+  ->execute();
+
+$connection->insert('entity_test_revlog_revision')
+  ->fields([
+    'id',
+    'revision_id',
+    'langcode',
+    'revision_created',
+    'revision_user',
+    'revision_log_message',
+    'name',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '1',
+    'langcode' => 'en',
+    'revision_created' => '1476268517',
+    'revision_user' => '1',
+    'revision_log_message' => 'first revision',
+    'name' => 'entity 1',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'langcode' => 'en',
+    'revision_created' => '1476268518',
+    'revision_user' => '1',
+    'revision_log_message' => 'second revision',
+    'name' => 'entity 1',
+  ])
+  ->execute();
+
+// Data for entity type "entity_test_mul_revlog"
+$connection->insert('entity_test_mul_revlog')
+  ->fields([
+    'id',
+    'revision_id',
+    'type',
+    'uuid',
+    'langcode',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'type' => 'entity_test_mul_revlog',
+    'uuid' => '6f04027a-1cbd-46e3-a67e-72636b493d4f',
+    'langcode' => 'en',
+  ])
+  ->execute();
+
+$connection->insert('entity_test_mul_revlog_field_data')
+  ->fields([
+    'id',
+    'revision_id',
+    'type',
+    'langcode',
+    'revision_created',
+    'revision_user',
+    'revision_log_message',
+    'name',
+    'default_langcode',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'type' => 'entity_test_mul_revlog',
+    'langcode' => 'en',
+    'revision_created' => '1476268518',
+    'revision_user' => '1',
+    'revision_log_message' => 'second revision',
+    'name' => 'entity 1',
+    'default_langcode' => '1',
+  ])
+  ->execute();
+
+$connection->insert('entity_test_mul_revlog_field_revision')
+  ->fields([
+    'id',
+    'revision_id',
+    'langcode',
+    'revision_created',
+    'revision_user',
+    'revision_log_message',
+    'name',
+    'default_langcode',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '1',
+    'langcode' => 'en',
+    'revision_created' => '1476268517',
+    'revision_user' => '1',
+    'revision_log_message' => 'first revision',
+    'name' => 'entity 1',
+    'default_langcode' => '1',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'langcode' => 'en',
+    'revision_created' => '1476268518',
+    'revision_user' => '1',
+    'revision_log_message' => 'second revision',
+    'name' => 'entity 1',
+    'default_langcode' => '1',
+  ])
+  ->execute();
+
+$connection->insert('entity_test_mul_revlog_revision')
+  ->fields([
+    'id',
+    'revision_id',
+    'langcode',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '1',
+    'langcode' => 'en',
+  ])
+  ->values([
+    'id' => '1',
+    'revision_id' => '2',
+    'langcode' => 'en',
+  ])
+  ->execute();
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php
new file mode 100644
index 0000000000..3a5bc181bc
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/drupal-8.entity-test-schema-converter-enabled.php
@@ -0,0 +1,36 @@
+<?php
+// @codingStandardsIgnoreFile
+
+use Drupal\Core\Database\Database;
+
+$connection = Database::getConnection();
+
+// Set the schema version.
+$connection->merge('key_value')
+  ->fields([
+    'value' => 'i:8000;',
+    'name' => 'entity_test_schema_converter',
+    'collection' => 'system.schema',
+  ])
+  ->condition('collection', 'system.schema')
+  ->condition('name', 'entity_test_schema_converter')
+  ->execute();
+
+// Update core.extension.
+$extensions = $connection->select('config')
+  ->fields('config', ['data'])
+  ->condition('collection', '')
+  ->condition('name', 'core.extension')
+  ->execute()
+  ->fetchField();
+$extensions = unserialize($extensions);
+$extensions['module']['entity_test_schema_converter'] = 8000;
+$connection->update('config')
+  ->fields([
+    'data' => serialize($extensions),
+    'collection' => '',
+    'name' => 'core.extension',
+  ])
+  ->condition('collection', '')
+  ->condition('name', 'core.extension')
+  ->execute();
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php
new file mode 100644
index 0000000000..4cc5227774
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/drupal-8.views-revision-metadata-fields-2248983.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains database additions to
+ * drupal-8.2.1.bare.standard_with_entity_test_enabled.php.gz for testing the
+ * upgrade path of https://www.drupal.org/node/2248983.
+ */
+
+use Drupal\Core\Database\Database;
+use Drupal\Core\Serialization\Yaml;
+
+$connection = Database::getConnection();
+
+// View for the entity type "entity_test_revlog".
+$views_configs[] = Yaml::decode(file_get_contents(__DIR__ . '/views.view.entity_test_revlog_for_2248983.yml'));
+
+// View for the entity type "entity_test_mul_revlog".
+$views_configs[] = Yaml::decode(file_get_contents(__DIR__ . '/views.view.entity_test_mul_revlog_for_2248983.yml'));
+
+
+foreach ($views_configs as $views_config) {
+  $connection->insert('config')
+    ->fields([
+      'collection',
+      'name',
+      'data',
+    ])
+    ->values([
+      'collection' => '',
+      'name' => 'views.view.' . $views_config['id'],
+      'data' => serialize($views_config),
+    ])
+    ->execute();
+}
diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml
new file mode 100644
index 0000000000..d9eba9a39b
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_mul_revlog_for_2248983.yml
@@ -0,0 +1,435 @@
+uuid: 25b89168-a8e5-4ae1-8fb5-c8efb91f0938
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_test_revlog
+id: entity_test_mul_revlog_for_2248983
+label: entity_test_mul_revlog
+module: views
+description: ''
+tag: ''
+base_table: entity_test_mul_revlog_property_data
+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: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            name: name
+          info:
+            name:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        name:
+          table: entity_test_mul_revlog_property_data
+          field: name
+          id: name
+          entity_type: entity_test_mul_revlog
+          entity_field: name
+          plugin_id: 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: true
+          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: {  }
+          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
+        revision_created:
+          id: revision_created
+          table: entity_test_mul_revlog_property_data
+          field: revision_created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision create time'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: medium
+            custom_date_format: ''
+            timezone: ''
+          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_mul_revlog
+          entity_field: revision_created
+          plugin_id: field
+        revision_id:
+          id: revision_id
+          table: entity_test_mul_revlog_property_data
+          field: revision_id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision ID'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: number_integer
+          settings:
+            thousand_separator: ''
+            prefix_suffix: true
+          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_mul_revlog
+          entity_field: revision_id
+          plugin_id: field
+        revision_log_message:
+          id: revision_log_message
+          table: entity_test_mul_revlog_property_data
+          field: revision_log_message
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision log message'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: basic_string
+          settings: {  }
+          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_mul_revlog
+          entity_field: revision_log_message
+          plugin_id: field
+        revision_user:
+          id: revision_user
+          table: entity_test_mul_revlog_property_data
+          field: revision_user
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision user'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: true
+          group_column: target_id
+          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_mul_revlog
+          entity_field: revision_user
+          plugin_id: field
+      filters: {  }
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: 0
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
diff --git a/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml
new file mode 100644
index 0000000000..412972c45c
--- /dev/null
+++ b/core/modules/system/tests/fixtures/update/views.view.entity_test_revlog_for_2248983.yml
@@ -0,0 +1,436 @@
+uuid: 5a8b00d2-67ce-415b-9e7d-6c013bf7f6b8
+langcode: en
+status: true
+dependencies:
+  module:
+    - entity_test_revlog
+id: entity_test_revlog_for_2248983
+label: entity_test_revlog
+module: views
+description: ''
+tag: ''
+base_table: entity_test_revlog
+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: table
+        options:
+          grouping: {  }
+          row_class: ''
+          default_row_class: true
+          override: true
+          sticky: false
+          caption: ''
+          summary: ''
+          description: ''
+          columns:
+            name: name
+          info:
+            name:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+          default: '-1'
+          empty_table: false
+      row:
+        type: fields
+        options:
+          inline: {  }
+          separator: ''
+          hide_empty: false
+          default_field_elements: true
+      fields:
+        name:
+          id: name
+          table: entity_test_revlog
+          field: name
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Name
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          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_revlog
+          entity_field: name
+          plugin_id: field
+        revision_created:
+          id: revision_created
+          table: entity_test_revlog
+          field: revision_created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision create time'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: medium
+            custom_date_format: ''
+            timezone: ''
+          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_revlog
+          entity_field: revision_created
+          plugin_id: field
+        revision_id:
+          id: revision_id
+          table: entity_test_revlog
+          field: revision_id
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision ID'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: number_integer
+          settings:
+            thousand_separator: ''
+            prefix_suffix: true
+          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_revlog
+          entity_field: revision_id
+          plugin_id: field
+        revision_log_message:
+          id: revision_log_message
+          table: entity_test_revlog
+          field: revision_log_message
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision log message'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: basic_string
+          settings: {  }
+          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_revlog
+          entity_field: revision_log_message
+          plugin_id: field
+        revision_user:
+          id: revision_user
+          table: entity_test_revlog
+          field: revision_user
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Revision user'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: true
+          group_column: target_id
+          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_revlog
+          entity_field: revision_user
+          plugin_id: field
+      filters: {  }
+      sorts: {  }
+      header: {  }
+      footer: {  }
+      empty: {  }
+      relationships: {  }
+      arguments: {  }
+      display_extenders: {  }
+    cache_metadata:
+      max-age: 0
+      contexts:
+        - 'languages:language_content'
+        - 'languages:language_interface'
+        - url.query_args
+      tags: {  }
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
index f3ada1f6df..9f8c5b0521 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTest.php
@@ -48,6 +48,9 @@
  *   },
  *   field_ui_base_route = "entity.entity_test.admin_form",
  * )
+ *
+ * Note that this entity type annotation intentionally omits the "create" link
+ * template. See https://www.drupal.org/node/2293697.
  */
 class EntityTest extends ContentEntityBase implements EntityOwnerInterface {
 
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
index c668bd3ee8..e6cb5428b9 100644
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
+++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithBundle.php
@@ -41,6 +41,7 @@
  *     "add-form" = "/entity_test_with_bundle/add/{entity_test_bundle}",
  *     "edit-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/edit",
  *     "delete-form" = "/entity_test_with_bundle/{entity_test_with_bundle}/delete",
+ *     "create" = "/entity_test_with_bundle",
  *   },
  * )
  */
diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php
deleted file mode 100644
index 4f4f4f1f25..0000000000
--- a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestWithRevisionLog.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Drupal\entity_test\Entity;
-
-use Drupal\Core\Entity\RevisionableContentEntityBase;
-
-/**
- * Defines the test entity class.
- *
- * @ContentEntityType(
- *   id = "entity_test_revlog",
- *   label = @Translation("Test entity - revisions log"),
- *   handlers = {
- *     "access" = "Drupal\entity_test\EntityTestAccessControlHandler",
- *     "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
- *     "form" = {
- *       "default" = "Drupal\entity_test\EntityTestForm",
- *       "delete" = "Drupal\entity_test\EntityTestDeleteForm"
- *     },
- *     "view_builder" = "Drupal\entity_test\EntityTestViewBuilder",
- *     "translation" = "Drupal\content_translation\ContentTranslationHandler",
- *     "views_data" = "Drupal\views\EntityViewsData",
- *     "route_provider" = {
- *       "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
- *     },
- *   },
- *   base_table = "entity_test_revlog",
- *   revision_table = "entity_test_revlog_revision",
- *   admin_permission = "administer entity_test content",
- *   entity_keys = {
- *     "id" = "id",
- *     "uuid" = "uuid",
- *     "revision" = "revision_id",
- *     "bundle" = "type",
- *     "label" = "name",
- *     "langcode" = "langcode",
- *   },
- *   links = {
- *     "canonical" = "/entity_test_revlog/manage/{entity_test_revlog}",
- *     "delete-form" = "/entity_test/delete/entity_test_revlog/{entity_test_revlog}",
- *     "edit-form" = "/entity_test_revlog/manage/{entity_test_revlog}/edit",
- *     "revision" = "/entity_test_revlog/{entity_test_revlog}/revision/{entity_test_revlog_revision}/view",
- *   }
- * )
- */
-class EntityTestWithRevisionLog extends RevisionableContentEntityBase {
-
-}
diff --git a/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml b/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml
new file mode 100644
index 0000000000..4afba6215f
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_revlog/entity_test_revlog.info.yml
@@ -0,0 +1,6 @@
+name: 'Entity test revision log'
+type: module
+description: 'Provides two entity types with revision logging capabilities.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php
new file mode 100644
index 0000000000..5a17b858dc
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestMulWithRevisionLog.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\entity_test_revlog\Entity;
+
+/**
+ * Defines the test entity class.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_mul_revlog",
+ *   label = @Translation("Test entity - data table, revisions log"),
+ *   base_table = "entity_test_mul_revlog",
+ *   data_table = "entity_test_mul_revlog_field_data",
+ *   revision_table = "entity_test_mul_revlog_revision",
+ *   revision_data_table = "entity_test_mul_revlog_field_revision",
+ *   translatable = TRUE,
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid",
+ *     "revision" = "revision_id",
+ *     "bundle" = "type",
+ *     "label" = "name",
+ *     "langcode" = "langcode",
+ *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log_message"
+ *   },
+ * )
+ */
+class EntityTestMulWithRevisionLog extends EntityTestWithRevisionLog {
+
+}
diff --git a/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestWithRevisionLog.php b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestWithRevisionLog.php
new file mode 100644
index 0000000000..b03415ff58
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_revlog/src/Entity/EntityTestWithRevisionLog.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\entity_test_revlog\Entity;
+
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Entity\RevisionableContentEntityBase;
+use Drupal\Core\Field\BaseFieldDefinition;
+
+/**
+ * Defines the test entity class.
+ *
+ * @ContentEntityType(
+ *   id = "entity_test_revlog",
+ *   label = @Translation("Test entity - revisions log"),
+ *   base_table = "entity_test_revlog",
+ *   revision_table = "entity_test_revlog_revision",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "uuid" = "uuid",
+ *     "revision" = "revision_id",
+ *     "bundle" = "type",
+ *     "label" = "name",
+ *     "langcode" = "langcode",
+ *   },
+ *   revision_metadata_keys = {
+ *     "revision_user" = "revision_user",
+ *     "revision_created" = "revision_created",
+ *     "revision_log_message" = "revision_log_message"
+ *   },
+ * )
+ */
+class EntityTestWithRevisionLog extends RevisionableContentEntityBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    $fields['name'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Name'))
+      ->setDescription(t('The name of the test entity.'))
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
+      ->setSetting('max_length', 32)
+      ->setDisplayOptions('view', [
+        'label' => 'hidden',
+        'type' => 'string',
+        'weight' => -5,
+      ])
+      ->setDisplayOptions('form', [
+        'type' => 'string_textfield',
+        'weight' => -5,
+      ]);
+
+    return $fields;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml
new file mode 100644
index 0000000000..b77990a6c1
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.info.yml
@@ -0,0 +1,8 @@
+name: 'Entity Schema Converter Test'
+type: module
+description: 'Provides testing for the entity schema converter.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - entity_test_update
\ No newline at end of file
diff --git a/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php
new file mode 100644
index 0000000000..1de5790071
--- /dev/null
+++ b/core/modules/system/tests/modules/entity_test_schema_converter/entity_test_schema_converter.post_update.php
@@ -0,0 +1,41 @@
+<?php
+
+/**
+ * @file
+ * Post update functions for entity_test_schema_converter.
+ */
+
+use \Drupal\Core\Entity\Sql\SqlContentEntityStorageSchemaConverter;
+
+/**
+ * @addtogroup updates-8.4.x
+ * @{
+ */
+
+/**
+ * Update entity_test_update to be revisionable.
+ */
+function entity_test_schema_converter_post_update_make_revisionable(&$sandbox) {
+  $revisionableSchemaConverter = new SqlContentEntityStorageSchemaConverter(
+    'entity_test_update',
+    \Drupal::entityTypeManager(),
+    \Drupal::entityDefinitionUpdateManager(),
+    \Drupal::service('entity.last_installed_schema.repository'),
+    \Drupal::keyValue('entity.storage_schema.sql'),
+    \Drupal::database()
+  );
+
+  $revisionableSchemaConverter->convertToRevisionable(
+    $sandbox,
+    [
+      'test_single_property',
+      'test_multiple_properties',
+      'test_single_property_multiple_values',
+      'test_multiple_properties_multiple_values',
+      'test_entity_base_field_info',
+    ]);
+}
+
+/**
+ * @} End of "addtogroup updates-8.4.x".
+ */
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
index f9ae073422..9187012977 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStorageForm.php
@@ -86,7 +86,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     //   that issue.
     if ($this->getRequest()->get('immutable')) {
       $form_state->addBuildInfo('immutable', TRUE);
-      if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodSafe()) {
+      if ($this->getRequest()->get('cache') && $this->getRequest()->isMethodCacheable()) {
         $form_state->setRequestMethod('FAKE');
         $form_state->setCached();
       }
diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml
new file mode 100644
index 0000000000..9441db0658
--- /dev/null
+++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Array rendering for non-HTML requests subscriber test'
+type: module
+description: 'Support module for RenderArrayNonHtmlSubscriberTest.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml
new file mode 100644
index 0000000000..e81ae77fa8
--- /dev/null
+++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/render_array_non_html_subscriber_test.routing.yml
@@ -0,0 +1,13 @@
+render_array_non_html_subscriber_test.raw_string:
+  path: '/render_array_non_html_subscriber_test/raw_string'
+  defaults:
+    _controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::rawString'
+  requirements:
+    _access: 'TRUE'
+
+render_array_non_html_subscriber_test.render_array:
+  path: '/render_array_non_html_subscriber_test/render_array'
+  defaults:
+    _controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::renderArray'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php
new file mode 100644
index 0000000000..73a4622b2d
--- /dev/null
+++ b/core/modules/system/tests/modules/render_array_non_html_subscriber_test/src/RenderArrayNonHtmlSubscriberTestController.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\render_array_non_html_subscriber_test;
+
+use Drupal\Core\Controller\ControllerBase;
+use Symfony\Component\HttpFoundation\Response;
+
+class RenderArrayNonHtmlSubscriberTestController extends ControllerBase {
+
+  /**
+   * @return string
+   */
+  public function rawString() {
+    return new Response($this->t('Raw controller response.'));
+  }
+
+  /**
+   * @return array
+   */
+  public function renderArray() {
+    return [
+      '#type' => 'html_tag',
+      '#tag' => 'p',
+      '#value' => $this->t('Controller response successfully rendered.'),
+    ];
+  }
+
+}
diff --git a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
index 8ac86f1a94..99fe192308 100644
--- a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
+++ b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
@@ -17,7 +17,8 @@ class ThemeTestSubscriber implements EventSubscriberInterface {
   /**
    * The used container.
    *
-   * @var \Symfony\Component\DependencyInjection\IntrospectableContainerInterface
+   * @todo This variable is never initialzed, so we don't know what it is.
+   *   See https://www.drupal.org/node/2721315
    */
   protected $container;
 
diff --git a/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php b/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php
index ca11ad0f5a..2f233be5d1 100644
--- a/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php
+++ b/core/modules/system/tests/src/Functional/FileTransfer/TestFileTransfer.php
@@ -46,7 +46,7 @@ public function createDirectoryJailed($directory) {
 
   public function removeFileJailed($destination) {
     if (!ftp_delete($this->connection, $item)) {
-      throw new FileTransferException('Unable to remove to file @file.', NULL, ['@file' => $item]);
+      throw new FileTransferException('Unable to remove the file @file.', NULL, ['@file' => $item]);
     }
   }
 
diff --git a/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php b/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php
new file mode 100644
index 0000000000..08380dec02
--- /dev/null
+++ b/core/modules/system/tests/src/Functional/Render/RenderArrayNonHtmlSubscriberTest.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\Tests\system\Functional\Render;
+
+use Drupal\Core\Url;
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Functional test verifying that render array throws 406 for non-HTML requests.
+ *
+ * @group Render
+ */
+class RenderArrayNonHtmlSubscriberTest extends BrowserTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['render_array_non_html_subscriber_test'];
+
+  /**
+   * Tests handling of responses by events subscriber.
+   */
+  public function testResponses() {
+    // Test that event subscriber does not interfere with normal requests.
+    $url = Url::fromRoute('render_array_non_html_subscriber_test.render_array');
+
+    $this->drupalGet($url);
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertRaw(t('Controller response successfully rendered.'));
+
+    // Test that correct response code is returned for any non-HTML format.
+    foreach (['json', 'hal+json', 'xml', 'foo'] as $format) {
+      $url = Url::fromRoute('render_array_non_html_subscriber_test.render_array', [
+        '_format' => $format,
+      ]);
+
+      $this->drupalGet($url);
+      $this->assertSession()->statusCodeEquals(406);
+      $this->assertNoRaw(t('Controller response successfully rendered.'));
+    }
+
+    // Test that event subscriber does not interfere with raw string responses.
+    $url = Url::fromRoute('render_array_non_html_subscriber_test.raw_string', [
+      '_format' => 'foo',
+    ]);
+
+    $this->drupalGet($url);
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertRaw(t('Raw controller response.'));
+  }
+
+}
diff --git a/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
index ee41968a5a..534f614980 100644
--- a/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
+++ b/core/modules/system/tests/src/Functional/Theme/ThemeInfoTest.php
@@ -90,13 +90,13 @@ public function testChanges() {
     $active_theme = $this->themeManager->getActiveTheme();
     // Make sure we are not testing the wrong theme.
     $this->assertEqual('test_theme', $active_theme->getName());
-    $this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling'], $active_theme->getLibraries());
+    $this->assertEqual(['classy/base', 'classy/messages', 'core/normalize', 'test_theme/global-styling'], $active_theme->getLibraries());
 
     // @see theme_test_system_info_alter()
     $this->state->set('theme_test.modify_info_files', TRUE);
     drupal_flush_all_caches();
     $active_theme = $this->themeManager->getActiveTheme();
-    $this->assertEqual(['classy/base', 'core/normalize', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries());
+    $this->assertEqual(['classy/base', 'classy/messages', 'core/normalize', 'test_theme/global-styling', 'core/backbone'], $active_theme->getLibraries());
   }
 
 }
diff --git a/core/modules/taxonomy/src/Entity/Term.php b/core/modules/taxonomy/src/Entity/Term.php
index 43e62c612b..03491ab962 100644
--- a/core/modules/taxonomy/src/Entity/Term.php
+++ b/core/modules/taxonomy/src/Entity/Term.php
@@ -46,6 +46,7 @@
  *     "canonical" = "/taxonomy/term/{taxonomy_term}",
  *     "delete-form" = "/taxonomy/term/{taxonomy_term}/delete",
  *     "edit-form" = "/taxonomy/term/{taxonomy_term}/edit",
+ *     "create" = "/taxonomy/term",
  *   },
  *   permission_granularity = "bundle"
  * )
@@ -229,7 +230,8 @@ public function setWeight($weight) {
    * {@inheritdoc}
    */
   public function getVocabularyId() {
-    return $this->get('vid')->target_id;
+    @trigger_error('The ' . __METHOD__ . ' method is deprecated since version 8.4.0 and will be removed before 9.0.0. Use ' . __CLASS__ . '::bundle() instead to get the vocabulary ID.', E_USER_DEPRECATED);
+    return $this->bundle();
   }
 
   /**
diff --git a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
index 6933e74561..37abdd565e 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument/IndexTidDepth.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\taxonomy\Plugin\views\argument;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -106,7 +107,7 @@ public function query($group_by = FALSE) {
     // Now build the subqueries.
     $subquery = db_select('taxonomy_index', 'tn');
     $subquery->addField('tn', 'nid');
-    $where = db_or()->condition('tn.tid', $tids, $operator);
+    $where = (new Condition('OR'))->condition('tn.tid', $tids, $operator);
     $last = "tn";
 
     if ($this->options['depth'] > 0) {
diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
index 95e5b1ef80..fa1865474a 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
@@ -194,7 +194,7 @@ public function getArgument() {
             $taxonomy_terms = $node->{$field->getName()}->referencedEntities();
             /** @var \Drupal\taxonomy\TermInterface $taxonomy_term */
             foreach ($taxonomy_terms as $taxonomy_term) {
-              $taxonomy[$taxonomy_term->id()] = $taxonomy_term->getVocabularyId();
+              $taxonomy[$taxonomy_term->id()] = $taxonomy_term->bundle();
             }
           }
         }
diff --git a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
index e0b9a32212..367565c387 100644
--- a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
@@ -145,8 +145,8 @@ public function preRender(&$values) {
         foreach ($data as $tid => $term) {
           $this->items[$node_nid][$tid]['name'] = \Drupal::entityManager()->getTranslationFromContext($term)->label();
           $this->items[$node_nid][$tid]['tid'] = $tid;
-          $this->items[$node_nid][$tid]['vocabulary_vid'] = $term->getVocabularyId();
-          $this->items[$node_nid][$tid]['vocabulary'] = $vocabularies[$term->getVocabularyId()]->label();
+          $this->items[$node_nid][$tid]['vocabulary_vid'] = $term->bundle();
+          $this->items[$node_nid][$tid]['vocabulary'] = $vocabularies[$term->bundle()]->label();
 
           if (!empty($this->options['link_to_taxonomy'])) {
             $this->items[$node_nid][$tid]['make_link'] = TRUE;
diff --git a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php
index 732f5b1501..93115584c8 100644
--- a/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php
+++ b/core/modules/taxonomy/src/Plugin/views/filter/TaxonomyIndexTidDepth.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\taxonomy\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
@@ -72,7 +73,7 @@ public function query() {
     // Now build the subqueries.
     $subquery = db_select('taxonomy_index', 'tn');
     $subquery->addField('tn', 'nid');
-    $where = db_or()->condition('tn.tid', $this->value, $operator);
+    $where = (new Condition('OR'))->condition('tn.tid', $this->value, $operator);
     $last = "tn";
 
     if ($this->options['depth'] > 0) {
diff --git a/core/modules/taxonomy/src/TermForm.php b/core/modules/taxonomy/src/TermForm.php
index 6e307ca35a..1eae95a0d4 100644
--- a/core/modules/taxonomy/src/TermForm.php
+++ b/core/modules/taxonomy/src/TermForm.php
@@ -85,7 +85,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#value' => $term->id(),
     ];
 
-    return parent::form($form, $form_state, $term);
+    return parent::form($form, $form_state);
   }
 
   /**
diff --git a/core/modules/taxonomy/src/TermInterface.php b/core/modules/taxonomy/src/TermInterface.php
index 0a582d3d60..3087a56ecb 100644
--- a/core/modules/taxonomy/src/TermInterface.php
+++ b/core/modules/taxonomy/src/TermInterface.php
@@ -87,6 +87,9 @@ public function setWeight($weight);
    *
    * @return string
    *   The id of the vocabulary.
+   *
+   * @deprecated Scheduled for removal before Drupal 9.0.0. Use
+   *   TermInterface::bundle() instead.
    */
   public function getVocabularyId();
 
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
index 41780412c3..a75f16ae93 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
@@ -57,7 +57,7 @@ public function testViewsHandlerAllTermsWithTokens() {
     $this->assertText('The taxonomy term name for the term: ' . $this->term1->getName());
 
     // The machine name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary_vid }}
-    $this->assertText('The machine name for the vocabulary the term belongs to: ' . $this->term1->getVocabularyId());
+    $this->assertText('The machine name for the vocabulary the term belongs to: ' . $this->term1->bundle());
 
     // The name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary }}
     $vocabulary = Vocabulary::load($this->term1->bundle());
diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php
index fceaf0bdbc..207b528589 100644
--- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php
+++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d7/MigrateTaxonomyTermTest.php
@@ -77,7 +77,7 @@ protected function assertEntity($id, $expected_label, $expected_vid, $expected_d
     $entity = Term::load($id);
     $this->assertTrue($entity instanceof TermInterface);
     $this->assertIdentical($expected_label, $entity->label());
-    $this->assertIdentical($expected_vid, $entity->getVocabularyId());
+    $this->assertIdentical($expected_vid, $entity->bundle());
     $this->assertEqual($expected_description, $entity->getDescription());
     $this->assertEquals($expected_format, $entity->getFormat());
     $this->assertEqual($expected_weight, $entity->getWeight());
diff --git a/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php b/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php
index 6d433eaf2d..7f703b799b 100644
--- a/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php
+++ b/core/modules/text/tests/src/Unit/Migrate/TextFieldTest.php
@@ -11,6 +11,7 @@
 /**
  * @coversDefaultClass \Drupal\text\Plugin\migrate\cckfield\TextField
  * @group text
+ * @group legacy
  */
 class TextFieldTest extends UnitTestCase {
 
diff --git a/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php
similarity index 96%
rename from core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php
rename to core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php
index dd4b5c43cf..9585c86eb4 100644
--- a/core/modules/toolbar/src/Tests/ToolbarAdminMenuTest.php
+++ b/core/modules/toolbar/tests/src/Functional/ToolbarAdminMenuTest.php
@@ -1,11 +1,12 @@
 <?php
 
-namespace Drupal\toolbar\Tests;
+namespace Drupal\Tests\toolbar\Functional;
 
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 use Drupal\user\RoleInterface;
 
 /**
@@ -25,7 +26,7 @@
  *
  * @group toolbar
  */
-class ToolbarAdminMenuTest extends WebTestBase {
+class ToolbarAdminMenuTest extends BrowserTestBase {
 
   /**
    * A user with permission to access the administrative toolbar.
@@ -297,7 +298,7 @@ public function testLocaleTranslationSubtreesHashCacheClear() {
     // Assume this is the only result.
     // Translate the string to a random string.
     $textarea = current($this->xpath('//textarea'));
-    $lid = (string) $textarea[0]['name'];
+    $lid = (string) $textarea->getAttribute('name');
     $edit = [
       $lid => $translation,
     ];
@@ -330,8 +331,8 @@ public function testSubtreesJsonRequest() {
     // Request a new page to refresh the drupalSettings object.
     $subtrees_hash = $this->getSubtreesHash();
 
-    $ajax_result = $this->drupalGetAjax('toolbar/subtrees/' . $subtrees_hash);
-    $this->assertResponse('200');
+    $this->drupalGet('toolbar/subtrees/' . $subtrees_hash, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']], ['X-Requested-With: XMLHttpRequest']);
+    $ajax_result = json_decode($this->getSession()->getPage()->getContent(), TRUE);
     $this->assertEqual($ajax_result[0]['command'], 'setToolbarSubtrees', 'Subtrees response uses the correct command.');
     $this->assertEqual(array_keys($ajax_result[0]['subtrees']), ['system-admin_content', 'system-admin_structure', 'system-themes_page', 'system-modules_list', 'system-admin_config', 'entity-user-collection', 'front'], 'Correct subtrees returned.');
   }
diff --git a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php
similarity index 97%
rename from core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php
rename to core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php
index 6995d5985c..2f6f92da81 100644
--- a/core/modules/toolbar/src/Tests/ToolbarCacheContextsTest.php
+++ b/core/modules/toolbar/tests/src/Functional/ToolbarCacheContextsTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\toolbar\Tests;
+namespace Drupal\Tests\toolbar\Functional;
 
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
-use Drupal\simpletest\WebTestBase;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\BrowserTestBase;
 
 
 /**
@@ -13,7 +13,7 @@
  *
  * @group toolbar
  */
-class ToolbarCacheContextsTest extends WebTestBase {
+class ToolbarCacheContextsTest extends BrowserTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
diff --git a/core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php b/core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php
similarity index 94%
rename from core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php
rename to core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php
index f4d6a11418..995d49ee38 100644
--- a/core/modules/toolbar/src/Tests/ToolbarMenuTranslationTest.php
+++ b/core/modules/toolbar/tests/src/Functional/ToolbarMenuTranslationTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\toolbar\Tests;
+namespace Drupal\Tests\toolbar\Functional;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests that the toolbar icon class remains for translated menu items.
  *
  * @group toolbar
  */
-class ToolbarMenuTranslationTest extends WebTestBase {
+class ToolbarMenuTranslationTest extends BrowserTestBase {
 
   /**
    * A user with permission to access the administrative toolbar.
@@ -66,7 +66,7 @@ public function testToolbarClasses() {
     // Translate the menu item.
     $menu_item_translated = $this->randomMachineName();
     $textarea = current($this->xpath('//textarea'));
-    $lid = (string) $textarea[0]['name'];
+    $lid = (string) $textarea->getAttribute('name');
     $edit = [
       $lid => $menu_item_translated,
     ];
diff --git a/core/modules/tour/tour.module b/core/modules/tour/tour.module
index 1de83992bb..ce9f309247 100644
--- a/core/modules/tour/tour.module
+++ b/core/modules/tour/tour.module
@@ -54,6 +54,7 @@ function tour_toolbar() {
       '#attributes' => [
         'class' => ['toolbar-icon', 'toolbar-icon-help'],
         'aria-pressed' => 'false',
+        'type' => 'button',
       ],
     ],
     '#wrapper_attributes' => [
diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index ed0e2eaf1a..a9341f9b7f 100644
--- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -6,7 +6,6 @@
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\RedirectDestinationTrait;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Routing\UrlGeneratorTrait;
 use Drupal\Core\Url;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Block\BlockBase;
@@ -23,7 +22,6 @@
  */
 class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
 
-  use UrlGeneratorTrait;
   use RedirectDestinationTrait;
 
   /**
@@ -94,7 +92,24 @@ public function build() {
     unset($form['pass']['#attributes']['aria-describedby']);
     $form['name']['#size'] = 15;
     $form['pass']['#size'] = 15;
-    $form['#action'] = $this->url('<current>', [], ['query' => $this->getDestinationArray(), 'external' => FALSE]);
+
+    // Instead of setting an actual action URL, we set the placeholder, which
+    // will be replaced at the very last moment. This ensures forms with
+    // dynamically generated action URLs don't have poor cacheability.
+    // Use the proper API to generate the placeholder, when we have one. See
+    // https://www.drupal.org/node/2562341. The placholder uses a fixed string
+    // that is
+    // Crypt::hashBase64('\Drupal\user\Plugin\Block\UserLoginBlock::build');
+    // This is based on the implementation in
+    // \Drupal\Core\Form\FormBuilder::prepareForm(), but the user login block
+    // requires different behavior for the destination query argument.
+    $placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE';
+
+    $form['#attached']['placeholders'][$placeholder] = [
+      '#lazy_builder' => ['\Drupal\user\Plugin\Block\UserLoginBlock::renderPlaceholderFormAction', []],
+    ];
+    $form['#action'] = $placeholder;
+
     // Build action links.
     $items = [];
     if (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
@@ -128,4 +143,20 @@ public function build() {
     ];
   }
 
+  /**
+   * #lazy_builder callback; renders a form action URL including destination.
+   *
+   * @return array
+   *   A renderable array representing the form action.
+   *
+   * @see \Drupal\Core\Form\FormBuilder::renderPlaceholderFormAction()
+   */
+  public static function renderPlaceholderFormAction() {
+    return [
+      '#type' => 'markup',
+      '#markup' => Url::fromRoute('<current>', [], ['query' => \Drupal::destination()->getAsArray(), 'external' => FALSE])->toString(),
+      '#cache' => ['contexts' => ['url.path', 'url.query_args']],
+    ];
+  }
+
 }
diff --git a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
index 6f44aa5091..feec81b468 100644
--- a/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
+++ b/core/modules/user/src/Plugin/EntityReferenceSelection/UserSelection.php
@@ -3,6 +3,7 @@
 namespace Drupal\user\Plugin\EntityReferenceSelection;
 
 use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\Plugin\EntityReferenceSelection\DefaultSelection;
@@ -228,17 +229,17 @@ public function entityQueryAlter(SelectInterface $query) {
           // Re-add the condition and a condition on uid = 0 so that we end up
           // with a query in the form:
           // WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
-          $or = db_or();
+          $or = new Condition('OR');
           $or->condition($condition['field'], $condition['value'], $condition['operator']);
           // Sadly, the Database layer doesn't allow us to build a condition
           // in the form ':placeholder = :placeholder2', because the 'field'
           // part of a condition is always escaped.
           // As a (cheap) workaround, we separately build a condition with no
           // field, and concatenate the field and the condition separately.
-          $value_part = db_and();
+          $value_part = new Condition('AND');
           $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
           $value_part->compile($this->connection, $query);
-          $or->condition(db_and()
+          $or->condition((new Condition('AND'))
             ->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + [':anonymous_name' => \Drupal::config('user.settings')->get('anonymous')])
             ->condition('base_table.uid', 0)
           );
diff --git a/core/modules/user/src/Plugin/views/filter/Current.php b/core/modules/user/src/Plugin/views/filter/Current.php
index e712673639..aa42529f5a 100644
--- a/core/modules/user/src/Plugin/views/filter/Current.php
+++ b/core/modules/user/src/Plugin/views/filter/Current.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\filter\BooleanOperator;
@@ -28,7 +29,7 @@ public function query() {
     $this->ensureMyTable();
 
     $field = $this->tableAlias . '.' . $this->realField . ' ';
-    $or = db_or();
+    $or = new Condition('OR');
 
     if (empty($this->value)) {
       $or->condition($field, '***CURRENT_USER***', '<>');
diff --git a/core/modules/user/src/Tests/UserBlocksTest.php b/core/modules/user/src/Tests/UserBlocksTest.php
index 1495b20b08..0a4c619da6 100644
--- a/core/modules/user/src/Tests/UserBlocksTest.php
+++ b/core/modules/user/src/Tests/UserBlocksTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\user\Tests;
 
+use Drupal\dynamic_page_cache\EventSubscriber\DynamicPageCacheSubscriber;
 use Drupal\simpletest\WebTestBase;
 
 /**
@@ -77,9 +78,29 @@ public function testUserLoginBlock() {
 
     // Now, log out and repeat with a non-403 page.
     $this->drupalLogout();
-    $this->drupalPostForm('filter/tips', $edit, t('Log in'));
+    $this->drupalGet('filter/tips');
+    $this->assertEqual('MISS', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
+    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->assertNoText(t('User login'), 'Logged in.');
+    $this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
+
+    // Log out again and repeat with a non-403 page including query arguments.
+    $this->drupalLogout();
+    $this->drupalGet('filter/tips', ['query' => ['foo' => 'bar']]);
+    $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
+    $this->drupalPostForm(NULL, $edit, t('Log in'));
+    $this->assertNoText(t('User login'), 'Logged in.');
+    $this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
+    $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=bar') !== FALSE, 'Correct query arguments are displayed after login');
+
+    // Repeat with different query arguments.
+    $this->drupalLogout();
+    $this->drupalGet('filter/tips', ['query' => ['foo' => 'baz']]);
+    $this->assertEqual('HIT', $this->drupalGetHeader(DynamicPageCacheSubscriber::HEADER));
+    $this->drupalPostForm(NULL, $edit, t('Log in'));
     $this->assertNoText(t('User login'), 'Logged in.');
     $this->assertPattern('!<title.*?' . t('Compose tips') . '.*?</title>!', 'Still on the same page after login for allowed page');
+    $this->assertTrue(strpos($this->getUrl(), '/filter/tips?foo=baz') !== FALSE, 'Correct query arguments are displayed after login');
 
     // Check that the user login block is not vulnerable to information
     // disclosure to third party sites.
diff --git a/core/modules/user/src/Tests/Views/AccessRoleTest.php b/core/modules/user/src/Tests/Views/AccessRoleTest.php
index 4d5db4d029..57055572d2 100644
--- a/core/modules/user/src/Tests/Views/AccessRoleTest.php
+++ b/core/modules/user/src/Tests/Views/AccessRoleTest.php
@@ -126,7 +126,7 @@ public function testRenderCaching() {
     $account_switcher->switchTo($this->webUser);
     $result = $renderer->renderPlain($build);
     // @todo Fix this in https://www.drupal.org/node/2551037,
-    // DisplayPluginBase::applyDisplayCachablityMetadata() is not invoked when
+    // DisplayPluginBase::applyDisplayCacheabilityMetadata() is not invoked when
     // using buildBasicRenderable() and a Views access plugin returns FALSE.
     //$this->assertTrue(in_array('user.roles', $build['#cache']['contexts']));
     //$this->assertEqual([], $build['#cache']['tags']);
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index b865e958d9..61faa3b4f0 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1003,7 +1003,7 @@ function user_user_role_insert(RoleInterface $role) {
     $action = Action::create([
       'id' => $add_id,
       'type' => 'user',
-      'label' => t('Add the @label role to the selected users', ['@label' => $role->label()]),
+      'label' => t('Add the @label role to the selected user(s)', ['@label' => $role->label()]),
       'configuration' => [
         'rid' => $role->id(),
       ],
@@ -1016,7 +1016,7 @@ function user_user_role_insert(RoleInterface $role) {
     $action = Action::create([
       'id' => $remove_id,
       'type' => 'user',
-      'label' => t('Remove the @label role from the selected users', ['@label' => $role->label()]),
+      'label' => t('Remove the @label role from the selected user(s)', ['@label' => $role->label()]),
       'configuration' => [
         'rid' => $role->id(),
       ],
diff --git a/core/modules/views/config/schema/views.display.schema.yml b/core/modules/views/config/schema/views.display.schema.yml
index d17c48cf52..3e696143f1 100644
--- a/core/modules/views/config/schema/views.display.schema.yml
+++ b/core/modules/views/config/schema/views.display.schema.yml
@@ -49,9 +49,6 @@ views.display.page:
         context:
           type: string
           label: 'Context'
-        expanded:
-          type: boolean
-          label: 'Expanded'
     tab_options:
       type: mapping
       label: 'Tab options'
diff --git a/core/modules/views/config/schema/views.filter.schema.yml b/core/modules/views/config/schema/views.filter.schema.yml
index 0dc8d35a47..00eb11a976 100644
--- a/core/modules/views/config/schema/views.filter.schema.yml
+++ b/core/modules/views/config/schema/views.filter.schema.yml
@@ -31,14 +31,6 @@ views.filter.combine:
         type: string
         label: 'Field'
 
-views.filter_value.date:
-  type: views.filter_value.numeric
-  label: 'Date'
-  mapping:
-    type:
-      type: string
-      label: 'Type'
-
 views.filter_value.groupby_numeric:
   type: views.filter_value.numeric
   label: 'Group by numeric'
diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index 298c20b3b5..da1a04bcd0 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -5,8 +5,11 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\views\Plugin\DependentWithRemovalPluginInterface;
 use Drupal\views\Views;
 use Drupal\views\ViewEntityInterface;
 
@@ -290,10 +293,13 @@ public function calculateDependencies() {
   public function preSave(EntityStorageInterface $storage) {
     parent::preSave($storage);
 
+    $displays = $this->get('display');
+
+    $this->fixTableNames($displays);
+
     // Sort the displays.
-    $display = $this->get('display');
-    ksort($display);
-    $this->set('display', ['default' => $display['default']] + $display);
+    ksort($displays);
+    $this->set('display', ['default' => $displays['default']] + $displays);
 
     // @todo Check whether isSyncing is needed.
     if (!$this->isSyncing()) {
@@ -302,6 +308,45 @@ public function preSave(EntityStorageInterface $storage) {
   }
 
   /**
+   * Fixes table names for revision metadata fields of revisionable entities.
+   *
+   * Views for revisionable entity types using revision metadata fields might
+   * be using the wrong table to retrieve the fields after system_update_8300
+   * has moved them correctly to the revision table. This method updates the
+   * views to use the correct tables.
+   *
+   * @param array &$displays
+   *   An array containing display handlers of a view.
+   *
+   * @deprecated in Drupal 8.3.0, will be removed in Drupal 9.0.0.
+   */
+  private function fixTableNames(array &$displays) {
+    // Fix wrong table names for entity revision metadata fields.
+    foreach ($displays as $display => $display_data) {
+      if (isset($display_data['display_options']['fields'])) {
+        foreach ($display_data['display_options']['fields'] as $property_name => $property_data) {
+          if (isset($property_data['entity_type']) && isset($property_data['field']) && isset($property_data['table'])) {
+            $entity_type = $this->entityTypeManager()->getDefinition($property_data['entity_type']);
+            // We need to update the table name only for revisionable entity
+            // types, otherwise the view is already using the correct table.
+            if (($entity_type instanceof ContentEntityTypeInterface) && is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) {
+              $revision_metadata_fields = $entity_type->getRevisionMetadataKeys();
+              // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout()
+              $revision_table = $entity_type->getRevisionTable() ?: $entity_type->id() . '_revision';
+
+              // Check if this is a revision metadata field and if it uses the
+              // wrong table.
+              if (in_array($property_data['field'], $revision_metadata_fields) && $property_data['table'] != $revision_table) {
+                $displays[$display]['display_options']['fields'][$property_name]['table'] = $revision_table;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
    * Fills in the cache metadata of this view.
    *
    * Cache metadata is set per view and per display, and ends up being stored in
@@ -468,4 +513,61 @@ public function invalidateCaches() {
     \Drupal::service('cache_tags.invalidator')->invalidateTags($tags);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function onDependencyRemoval(array $dependencies) {
+    $changed = FALSE;
+
+    // Don't intervene if the views module is removed.
+    if (isset($dependencies['module']) && in_array('views', $dependencies['module'])) {
+      return FALSE;
+    }
+
+    // If the base table for the View is provided by a module being removed, we
+    // delete the View because this is not something that can be fixed manually.
+    $views_data = Views::viewsData();
+    $base_table = $this->get('base_table');
+    $base_table_data = $views_data->get($base_table);
+    if (!empty($base_table_data['table']['provider']) && in_array($base_table_data['table']['provider'], $dependencies['module'])) {
+      return FALSE;
+    }
+
+    $current_display = $this->getExecutable()->current_display;
+    $handler_types = Views::getHandlerTypes();
+
+    // Find all the handlers and check whether they want to do something on
+    // dependency removal.
+    foreach ($this->display as $display_id => $display_plugin_base) {
+      $this->getExecutable()->setDisplay($display_id);
+      $display = $this->getExecutable()->getDisplay();
+
+      foreach (array_keys($handler_types) as $handler_type) {
+        $handlers = $display->getHandlers($handler_type);
+        foreach ($handlers as $handler_id => $handler) {
+          if ($handler instanceof DependentWithRemovalPluginInterface) {
+            if ($handler->onDependencyRemoval($dependencies)) {
+              // Remove the handler and indicate we made changes.
+              unset($this->display[$display_id]['display_options'][$handler_types[$handler_type]['plural']][$handler_id]);
+              $changed = TRUE;
+            }
+          }
+        }
+      }
+    }
+
+    // Disable the View if we made changes.
+    // @todo https://www.drupal.org/node/2832558 Give better feedback for
+    // disabled config.
+    if ($changed) {
+      // Force a recalculation of the dependencies if we made changes.
+      $this->getExecutable()->current_display = NULL;
+      $this->calculateDependencies();
+      $this->disable();
+    }
+
+    $this->getExecutable()->setDisplay($current_display);
+    return $changed;
+  }
+
 }
diff --git a/core/modules/views/src/ManyToOneHelper.php b/core/modules/views/src/ManyToOneHelper.php
index d772db1a63..cb2e5754a8 100644
--- a/core/modules/views/src/ManyToOneHelper.php
+++ b/core/modules/views/src/ManyToOneHelper.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\views;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\HandlerBase;
 
@@ -268,8 +269,8 @@ public function addFilter() {
       $options['group'] = 0;
     }
 
-    // add_condition determines whether a single expression is enough(FALSE) or the
-    // conditions should be added via an db_or()/db_and() (TRUE).
+    // If $add_condition is set to FALSE, a single expression is enough. If it
+    // is set to TRUE, conditions will be added.
     $add_condition = TRUE;
     if ($operator == 'not') {
       $value = NULL;
@@ -326,7 +327,7 @@ public function addFilter() {
 
     if ($add_condition) {
       $field = $this->handler->realField;
-      $clause = $operator == 'or' ? db_or() : db_and();
+      $clause = $operator == 'or' ? new Condition('OR') : new Condition('AND');
       foreach ($this->handler->tableAliases as $value => $alias) {
         $clause->condition("$alias.$field", $value);
       }
diff --git a/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php b/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php
index 2dd4652a97..ec066ab64e 100644
--- a/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php
+++ b/core/modules/views/src/Plugin/Block/ViewsExposedFilterBlock.php
@@ -24,9 +24,23 @@ public function getCacheContexts() {
 
   /**
    * {@inheritdoc}
+   *
+   * @return array
+   *   A renderable array representing the content of the block with additional
+   *   context of current view and display ID.
    */
   public function build() {
     $output = $this->view->display_handler->viewExposedFormBlocks();
+    // Provide the context for block build and block view alter hooks.
+    // \Drupal\views\Plugin\Block\ViewsBlock::build() adds the same context in
+    // \Drupal\views\ViewExecutable::buildRenderable() using
+    // \Drupal\views\Plugin\views\display\DisplayPluginBase::buildRenderable().
+    if (is_array($output) && !empty($output)) {
+      $output += [
+        '#view' => $this->view,
+        '#display_id' => $this->displayID,
+      ];
+    }
 
     // Before returning the block output, convert it to a renderable array with
     // contextual links.
diff --git a/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php b/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php
new file mode 100644
index 0000000000..59cb42d49c
--- /dev/null
+++ b/core/modules/views/src/Plugin/DependentWithRemovalPluginInterface.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Drupal\views\Plugin;
+
+/**
+ * Provides an interface for a plugin that has dependencies that can be removed.
+ *
+ * @ingroup views_plugins
+ */
+interface DependentWithRemovalPluginInterface {
+
+  /**
+   * Allows a plugin to define whether it should be removed.
+   *
+   * If this method returns TRUE then the plugin should be removed.
+   *
+   * @param array $dependencies
+   *   An array of dependencies that will be deleted keyed by dependency type.
+   *   Dependency types are, for example, entity, module and theme.
+   *
+   * @return bool
+   *   TRUE if the plugin instance should be removed.
+   *
+   * @see \Drupal\Core\Config\Entity\ConfigDependencyManager
+   * @see \Drupal\Core\Config\ConfigEntityBase::preDelete()
+   * @see \Drupal\Core\Config\ConfigManager::uninstall()
+   * @see \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval()
+   */
+  public function onDependencyRemoval(array $dependencies);
+
+}
diff --git a/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php b/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php
index 00233f7cca..bd7d59ceec 100644
--- a/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php
+++ b/core/modules/views/src/Plugin/views/BrokenHandlerTrait.php
@@ -59,7 +59,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
       }
     }
 
-    $description_bottom = t('Enabling the appropriate module will may solve this issue. Otherwise, check to see if there is a module update available.');
+    $description_bottom = t('Enabling the appropriate module may solve this issue. Otherwise, check to see if there is a module update available.');
 
     $form['description'] = [
       '#type' => 'container',
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index e31b5a295f..3744fea2bf 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2115,7 +2115,7 @@ public function render() {
       '#cache' => &$this->view->element['#cache'],
     ];
 
-    $this->applyDisplayCachablityMetadata($this->view->element);
+    $this->applyDisplayCacheabilityMetadata($this->view->element);
 
     return $element;
   }
@@ -2126,7 +2126,7 @@ public function render() {
    * @param array $element
    *   The render array with updated cacheability metadata.
    */
-  protected function applyDisplayCachablityMetadata(array &$element) {
+  protected function applyDisplayCacheabilityMetadata(array &$element) {
     /** @var \Drupal\views\Plugin\views\cache\CachePluginBase $cache */
     $cache = $this->getPlugin('cache');
 
@@ -2139,6 +2139,22 @@ protected function applyDisplayCachablityMetadata(array &$element) {
   }
 
   /**
+   * Applies the cacheability of the current display to the given render array.
+   *
+   * @param array $element
+   *   The render array with updated cacheability metadata.
+   *
+   * @deprecated in Drupal 8.4.0, will be removed before Drupal 9.0. Use
+   *   DisplayPluginBase::applyDisplayCacheabilityMetadata instead.
+   *
+   * @see \Drupal\views\Plugin\views\display\DisplayPluginBase::applyDisplayCacheabilityMetadata()
+   */
+  protected function applyDisplayCachablityMetadata(array &$element) {
+    @trigger_error('The DisplayPluginBase::applyDisplayCachablityMetadata method is deprecated since version 8.4 and will be removed in 9.0. Use DisplayPluginBase::applyDisplayCacheabilityMetadata instead.', E_USER_DEPRECATED);
+    $this->applyDisplayCacheabilityMetadata($element);
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function elementPreRender(array $element) {
@@ -2330,7 +2346,7 @@ public function buildRenderable(array $args = [], $cache = TRUE) {
     // of cacheability metadata (e.g.: cache contexts), so they can bubble up.
     // Thus, we add the cacheability metadata first, then modify / remove the
     // cache keys depending on the $cache argument.
-    $this->applyDisplayCachablityMetadata($this->view->element);
+    $this->applyDisplayCacheabilityMetadata($this->view->element);
     if ($cache) {
       $this->view->element['#cache'] += ['keys' => []];
       // Places like \Drupal\views\ViewExecutable::setCurrentPage() set up an
diff --git a/core/modules/views/src/Plugin/views/display/EntityReference.php b/core/modules/views/src/Plugin/views/display/EntityReference.php
index 73b137ce03..4dedd51a83 100644
--- a/core/modules/views/src/Plugin/views/display/EntityReference.php
+++ b/core/modules/views/src/Plugin/views/display/EntityReference.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\views\Plugin\views\display;
 
+use Drupal\Core\Database\Query\Condition;
+
 /**
  * The plugin that handles an EntityReference display.
  *
@@ -131,7 +133,7 @@ public function query() {
       }
 
       // Multiple search fields are OR'd together.
-      $conditions = db_or();
+      $conditions = new Condition('OR');
 
       // Build the condition using the selected search fields.
       foreach ($style_options['options']['search_fields'] as $field_id) {
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index b9a2990ce4..c664c053e2 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -106,7 +106,7 @@ public function preview() {
   public function render() {
     $build = $this->view->style_plugin->render($this->view->result);
 
-    $this->applyDisplayCachablityMetadata($build);
+    $this->applyDisplayCacheabilityMetadata($build);
 
     return $build;
   }
diff --git a/core/modules/views/src/Plugin/views/field/EntityField.php b/core/modules/views/src/Plugin/views/field/EntityField.php
index 5ee05a24d5..25b0a556a5 100644
--- a/core/modules/views/src/Plugin/views/field/EntityField.php
+++ b/core/modules/views/src/Plugin/views/field/EntityField.php
@@ -23,6 +23,7 @@
 use Drupal\views\FieldAPIHandlerTrait;
 use Drupal\views\Entity\Render\EntityFieldRenderer;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
+use Drupal\views\Plugin\DependentWithRemovalPluginInterface;
 use Drupal\views\ResultRow;
 use Drupal\views\ViewExecutable;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -34,7 +35,7 @@
  *
  * @ViewsField("field")
  */
-class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface {
+class EntityField extends FieldPluginBase implements CacheableDependencyInterface, MultiItemsFieldHandlerInterface, DependentWithRemovalPluginInterface {
 
   use FieldAPIHandlerTrait;
   use PluginDependencyTrait;
@@ -1077,4 +1078,29 @@ public function getValue(ResultRow $values, $field = NULL) {
     }
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function onDependencyRemoval(array $dependencies) {
+    // See if this handler is responsible for any of the dependencies being
+    // removed. If this is the case, indicate that this handler needs to be
+    // removed from the View.
+    $remove = FALSE;
+    // Get all the current dependencies for this handler.
+    $current_dependencies = $this->calculateDependencies();
+    foreach ($current_dependencies as $group => $dependency_list) {
+      // Check if any of the handler dependencies match the dependencies being
+      // removed.
+      foreach ($dependency_list as $config_key) {
+        if (isset($dependencies[$group]) && array_key_exists($config_key, $dependencies[$group])) {
+          // This handlers dependency matches a dependency being removed,
+          // indicate that this handler needs to be removed.
+          $remove = TRUE;
+          break 2;
+        }
+      }
+    }
+    return $remove;
+  }
+
 }
diff --git a/core/modules/views/src/Plugin/views/filter/StringFilter.php b/core/modules/views/src/Plugin/views/filter/StringFilter.php
index 4cae120b17..a9ab5a1861 100644
--- a/core/modules/views/src/Plugin/views/filter/StringFilter.php
+++ b/core/modules/views/src/Plugin/views/filter/StringFilter.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\views\Plugin\views\filter;
 
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Form\FormStateInterface;
 
 /**
@@ -265,7 +266,7 @@ protected function opContains($field) {
   }
 
   protected function opContainsWord($field) {
-    $where = $this->operator == 'word' ? db_or() : db_and();
+    $where = $this->operator == 'word' ? new Condition('OR') : new Condition('AND');
 
     // Don't filter on empty strings.
     if (empty($this->value)) {
diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php
index 1210c1c72d..ab056f59a7 100644
--- a/core/modules/views/src/Plugin/views/query/Sql.php
+++ b/core/modules/views/src/Plugin/views/query/Sql.php
@@ -5,6 +5,7 @@
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
@@ -830,7 +831,7 @@ public function clearFields() {
    * @code
    * $this->query->addWhere(
    *   $this->options['group'],
-   *   db_or()
+   *   (new Condition('OR'))
    *     ->condition($field, $value, 'NOT IN')
    *     ->condition($field, $value, 'IS NULL')
    * );
@@ -1056,13 +1057,13 @@ protected function buildCondition($where = 'where') {
     $has_arguments = FALSE;
     $has_filter = FALSE;
 
-    $main_group = db_and();
-    $filter_group = $this->groupOperator == 'OR' ? db_or() : db_and();
+    $main_group = new Condition('AND');
+    $filter_group = $this->groupOperator == 'OR' ? new Condition('OR') : new Condition('AND');
 
     foreach ($this->$where as $group => $info) {
 
       if (!empty($info['conditions'])) {
-        $sub_group = $info['type'] == 'OR' ? db_or() : db_and();
+        $sub_group = $info['type'] == 'OR' ? new Condition('OR') : new Condition('AND');
         foreach ($info['conditions'] as $clause) {
           if ($clause['operator'] == 'formula') {
             $has_condition = TRUE;
diff --git a/core/modules/views/src/Tests/Handler/HandlerTestBase.php b/core/modules/views/src/Tests/Handler/HandlerTestBase.php
index 5345f47b05..1603329bdb 100644
--- a/core/modules/views/src/Tests/Handler/HandlerTestBase.php
+++ b/core/modules/views/src/Tests/Handler/HandlerTestBase.php
@@ -1,11 +1,13 @@
 <?php
 
 namespace Drupal\views\Tests\Handler;
+@trigger_error('\Drupal\views\Tests\Handler\HandlerTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
- * @todo.
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\ViewTestBase.
  */
 abstract class HandlerTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/src/Tests/Plugin/PluginTestBase.php b/core/modules/views/src/Tests/Plugin/PluginTestBase.php
index 3b03dcd84f..c386181103 100644
--- a/core/modules/views/src/Tests/Plugin/PluginTestBase.php
+++ b/core/modules/views/src/Tests/Plugin/PluginTestBase.php
@@ -1,11 +1,13 @@
 <?php
 
 namespace Drupal\views\Tests\Plugin;
+@trigger_error('\Drupal\views\Tests\Plugin\PluginTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
- * @todo.
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\ViewTestBase.
  */
 abstract class PluginTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/src/Tests/ViewTestBase.php b/core/modules/views/src/Tests/ViewTestBase.php
index 720d528cd3..121b21bfa5 100644
--- a/core/modules/views/src/Tests/ViewTestBase.php
+++ b/core/modules/views/src/Tests/ViewTestBase.php
@@ -1,6 +1,7 @@
 <?php
 
 namespace Drupal\views\Tests;
+@trigger_error('\Drupal\views\Tests\ViewTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\ViewTestBase', E_USER_DEPRECATED);
 
 use Drupal\Core\Database\Query\SelectInterface;
 use Drupal\simpletest\WebTestBase;
@@ -13,6 +14,9 @@
  * When possible, ViewsKernelTestBase should be used instead. Both base classes
  * include the same methods.
  *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\ViewTestBase.
+ *
  * @see \Drupal\Tests\views\Kernel\ViewsKernelTestBase
  * @see \Drupal\simpletest\WebTestBase
  */
diff --git a/core/modules/views/src/Tests/Wizard/WizardTestBase.php b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
index 835b9f4edb..f5f7cc0514 100644
--- a/core/modules/views/src/Tests/Wizard/WizardTestBase.php
+++ b/core/modules/views/src/Tests/Wizard/WizardTestBase.php
@@ -1,11 +1,15 @@
 <?php
 
 namespace Drupal\views\Tests\Wizard;
+@trigger_error('\Drupal\views\Tests\Wizard\WizardTestBase is deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use \Drupal\Tests\views\Functional\Wizard\WizardTestBase', E_USER_DEPRECATED);
 
 use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Views UI wizard tests.
+ *
+ * @deprecated in Drupal 8.4.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal\Tests\views\Functional\Wizard\WizardTestBase.
  */
 abstract class WizardTestBase extends ViewTestBase {
 
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml
index dc893efdd0..08e2d3a06a 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_tag_cache.yml
@@ -59,7 +59,6 @@ display:
           type: string
           settings:
             link_to_entity: true
-          plugin_id: field
       filters:
         type:
           id: type
diff --git a/core/modules/views/src/Tests/DefaultViewsTest.php b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
similarity index 97%
rename from core/modules/views/src/Tests/DefaultViewsTest.php
rename to core/modules/views/tests/src/Functional/DefaultViewsTest.php
index 48e3caeb3a..0e5c893442 100644
--- a/core/modules/views/src/Tests/DefaultViewsTest.php
+++ b/core/modules/views/tests/src/Functional/DefaultViewsTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\comment\CommentInterface;
 use Drupal\comment\Tests\CommentTestTrait;
@@ -42,8 +42,8 @@ class DefaultViewsTest extends ViewTestBase {
     'glossary' => ['all'],
   ];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
 
diff --git a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php
rename to core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
index 698a43e79f..19aa191e14 100644
--- a/core/modules/views/src/Tests/Entity/BaseFieldAccessTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/BaseFieldAccessTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\entity_test\Entity\EntityTest;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 
 /**
@@ -32,8 +32,8 @@ class BaseFieldAccessTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
     /** @var \Drupal\Core\Entity\EntityDefinitionUpdateManager $update_manager */
     $update_manager = $this->container->get('entity.definition_update_manager');
     \Drupal::entityManager()->clearCachedDefinitions();
diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Entity/FieldEntityTest.php
rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
index 89f71edf0c..a46e54c9e5 100644
--- a/core/modules/views/src/Tests/Entity/FieldEntityTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\comment\Tests\CommentTestTrait;
 use Drupal\node\Entity\Node;
 use Drupal\user\Entity\User;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 use Drupal\comment\Entity\Comment;
diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php
rename to core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
index bd4e2ed1f7..2a227c5433 100644
--- a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FieldEntityTranslationTest.php
@@ -1,12 +1,12 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\Core\Language\Language;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Symfony\Component\CssSelector\CssSelectorConverter;
 
 /**
@@ -164,8 +164,8 @@ protected function assertRows($expected = []) {
     $rows = $this->cssSelect('div.views-row');
     foreach ($rows as $row) {
       $actual[] = [
-        'title' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))[0],
-        'sticky' => (string) $row->xpath((new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))[0],
+        'title' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-title span.field-content a'))->getText(),
+        'sticky' => $row->find('xpath', (new CssSelectorConverter())->toXPath('.views-field-sticky span.field-content'))->getText(),
       ];
     }
     $this->assertEqual($actual, $expected);
diff --git a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php
rename to core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
index f099569b80..993293cebf 100644
--- a/core/modules/views/src/Tests/Entity/FilterEntityBundleTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/FilterEntityBundleTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\node\Entity\Node;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
@@ -42,7 +42,7 @@ class FilterEntityBundleTest extends ViewTestBase {
    */
   protected $entities = [];
 
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp(FALSE);
 
     $this->drupalCreateContentType(['type' => 'test_bundle']);
diff --git a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
similarity index 87%
rename from core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php
rename to core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
index 82c683995c..911cd61e66 100644
--- a/core/modules/views/src/Tests/Entity/ViewNonTranslatableEntityTest.php
+++ b/core/modules/views/tests/src/Functional/Entity/ViewNonTranslatableEntityTest.php
@@ -1,17 +1,17 @@
 <?php
 
-namespace Drupal\views\Tests\Entity;
+namespace Drupal\Tests\views\Functional\Entity;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\language_test\Entity\NoLanguageEntityTest;
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\BrowserTestBase;
 
 /**
  * Tests the view creation of non-translatable entities.
  *
  * @group views
  */
-class ViewNonTranslatableEntityTest extends WebTestBase {
+class ViewNonTranslatableEntityTest extends BrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/views/src/Tests/GlossaryTest.php b/core/modules/views/tests/src/Functional/GlossaryTest.php
similarity index 89%
rename from core/modules/views/src/Tests/GlossaryTest.php
rename to core/modules/views/tests/src/Functional/GlossaryTest.php
index b1657687df..d67f70dfd7 100644
--- a/core/modules/views/src/Tests/GlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/GlossaryTest.php
@@ -1,10 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\Component\Utility\Unicode;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
+use Drupal\views\Tests\AssertViewsCacheTagsTrait;
 use Drupal\views\Views;
 
 /**
@@ -97,8 +98,8 @@ public function testGlossaryView() {
         'user_list',
         'http_response',
         'rendered',
-        // FinishResponseSubscriber adds this cache tag to responses that have the
-        // 'user.permissions' cache context for anonymous users.
+        // FinishResponseSubscriber adds this cache tag to responses that have
+        // the 'user.permissions' cache context for anonymous users.
         'config:user.role.anonymous',
       ]
     );
@@ -113,8 +114,9 @@ public function testGlossaryView() {
       // to ensure that both of them are correct.
       $result = $this->xpath('//a[contains(@href, :href) and normalize-space(text())=:label]/..', [':href' => $href, ':label' => $label]);
       $this->assertTrue(count($result));
-      // The rendered output looks like "| (count)" so let's figure out the int.
-      $result_count = trim(str_replace(['|', '(', ')'], '', (string) $result[0]));
+      // The rendered output looks like "<a href=''>X</a> | (count)" so let's
+      // figure out the int.
+      $result_count = explode(' ', trim(str_replace(['|', '(', ')'], '', $result[0]->getText())))[1];
       $this->assertEqual($result_count, $count, 'The expected number got rendered.');
     }
   }
diff --git a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
similarity index 86%
rename from core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
index 2656adc4dc..dc914ce219 100644
--- a/core/modules/views/src/Tests/Handler/AreaHTTPStatusCodeTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaHTTPStatusCodeTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -10,7 +11,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\area\HTTPStatusCode
  */
-class AreaHTTPStatusCodeTest extends HandlerTestBase {
+class AreaHTTPStatusCodeTest extends ViewTestBase {
 
   /**
    * Views used by this test.
diff --git a/core/modules/views/src/Tests/Handler/AreaTest.php b/core/modules/views/tests/src/Functional/Handler/AreaTest.php
similarity index 81%
rename from core/modules/views/src/Tests/Handler/AreaTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaTest.php
index ca9fc422dc..d631373d23 100644
--- a/core/modules/views/src/Tests/Handler/AreaTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Component\Utility\Xss;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -12,7 +13,7 @@
  * @see \Drupal\views\Plugin\views\area\AreaPluginBase
  * @see \Drupal\views_test\Plugin\views\area\TestExample
  */
-class AreaTest extends HandlerTestBase {
+class AreaTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -28,8 +29,8 @@ class AreaTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'views_ui'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -111,41 +112,6 @@ public function testRenderArea() {
   }
 
   /**
-   * Tests that the header and footer areas are not rendered if empty.
-   */
-  public function testRenderEmptyHeaderFooter() {
-    $view = Views::getView('test_example_area');
-    $view->initHandlers();
-
-    // Set example empty text.
-    $view->empty['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-
-    $xpath = '//div[contains(@class, :class)]';
-
-    // Verify that the empty header and footer sections have not been rendered.
-    $output = $view->preview();
-    $html = $this->container->get('renderer')->renderRoot($output);
-    $this->setRawContent($html);
-    $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-header'])));
-    $this->assertEqual(0, count($this->xpath($xpath, [':class' => 'view-footer'])));
-
-    // Set example header text.
-    $view->header['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-    $view->header['test_example']->options['empty'] = TRUE;
-
-    // Set example footer text.
-    $view->footer['test_example']->options['string'] = '<p>' . $this->randomMachineName() . '</p>';
-    $view->footer['test_example']->options['empty'] = TRUE;
-
-    // Verify that the header and footer sections have been rendered.
-    $output = $view->preview();
-    $html = $this->container->get('renderer')->renderRoot($output);
-    $this->setRawContent($html);
-    $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-header'])));
-    $this->assertEqual(1, count($this->xpath($xpath, [':class' => 'view-footer'])));
-  }
-
-  /**
    * Tests the access for an area.
    */
   public function testAreaAccess() {
diff --git a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Handler/AreaTitleWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
index afae1eb8ec..9e1fcfad23 100644
--- a/core/modules/views/src/Tests/Handler/AreaTitleWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/AreaTitleWebTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Entity\View;
-use Drupal\views\Tests\ViewTestBase;
 
 /**
  * Tests the title area handler with a web test.
@@ -23,8 +23,8 @@ class AreaTitleWebTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Handler/ArgumentStringTest.php
rename to core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
index 0682892e89..17ece944c5 100644
--- a/core/modules/views/src/Tests/Handler/ArgumentStringTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/ArgumentStringTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -9,7 +10,7 @@
  *
  * @group views
  */
-class ArgumentStringTest extends HandlerTestBase {
+class ArgumentStringTest extends ViewTestBase {
 
   /**
    * Views used by this test.
diff --git a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
similarity index 85%
rename from core/modules/views/src/Tests/Handler/FieldDropButtonTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
index 9d5c67fa75..e0e380b0f8 100644
--- a/core/modules/views/src/Tests/Handler/FieldDropButtonTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldDropButtonTest.php
@@ -1,6 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the dropbutton field handler.
@@ -8,7 +10,7 @@
  * @group views
  * @see \Drupal\system\Plugin\views\field\Dropbutton
  */
-class FieldDropButtonTest extends HandlerTestBase {
+class FieldDropButtonTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -27,8 +29,8 @@ class FieldDropButtonTest extends HandlerTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $admin_user = $this->drupalCreateUser(['access content overview', 'administer nodes', 'bypass node access']);
     $this->drupalLogin($admin_user);
@@ -48,7 +50,7 @@ public function testDropbutton() {
     foreach ($nodes as $node) {
       $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => $node->label()]);
       $this->assertEqual(count($result), 1, 'Just one node title link was found.');
-      $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => t('Custom Text')]);
+      $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', [':path' => '/node/' . $node->id(), ':title' => 'Custom Text']);
       $this->assertEqual(count($result), 1, 'Just one custom link was found.');
     }
 
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
similarity index 92%
rename from core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
index 7efd1d7414..653ce11527 100644
--- a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldEntityOperationsTest.php
@@ -1,17 +1,18 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Url;
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Entity\Node;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the core Drupal\views\Plugin\views\field\EntityOperations handler.
  *
  * @group views
  */
-class FieldEntityOperationsTest extends HandlerTestBase {
+class FieldEntityOperationsTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -27,8 +28,8 @@ class FieldEntityOperationsTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'language', 'views_ui'];
 
-  public function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create Article content type.
     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
@@ -72,7 +73,7 @@ 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' => $operation['title']]);
+          $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']]);
           $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/src/Tests/Handler/FieldGroupRowsTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
similarity index 92%
rename from core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
index 2521e6329e..d38ba41792 100644
--- a/core/modules/views/src/Tests/Handler/FieldGroupRowsTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsTest.php
@@ -1,10 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Render\RenderContext;
 use Drupal\field\Entity\FieldConfig;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\field\Entity\FieldStorageConfig;
 
@@ -15,7 +16,7 @@
  *
  * @group views
  */
-class FieldGroupRowsTest extends HandlerTestBase {
+class FieldGroupRowsTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -38,8 +39,8 @@ class FieldGroupRowsTest extends HandlerTestBase {
    */
   private $fieldName = 'field_group_rows';
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create content type with unlimited text field.
     $node_type = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
diff --git a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
index 646cb12242..275960cb0d 100644
--- a/core/modules/views/src/Tests/Handler/FieldGroupRowsWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldGroupRowsWebTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the "Display all values in the same row" setting.
@@ -59,8 +59,8 @@ class FieldGroupRowsWebTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create content type with unlimited text field.
     $this->nodeType = $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
@@ -98,7 +98,7 @@ public function testGroupRows() {
 
     $rendered_value = [];
     foreach ($result as $row) {
-      $rendered_value[] = (string) $row[0];
+      $rendered_value[] = $row->getText();
     }
     $this->assertEqual(['a, b, c'], $rendered_value);
   }
@@ -111,7 +111,7 @@ public function testUngroupedRows() {
     $result = $this->cssSelect('div.views-field-field-views-testing-group- div');
     $rendered_value = [];
     foreach ($result as $row) {
-      $rendered_value[] = (string) $row[0];
+      $rendered_value[] = $row->getText();
     }
     $this->assertEqual(['a', 'b', 'c'], $rendered_value);
   }
diff --git a/core/modules/views/src/Tests/Handler/FieldWebTest.php b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
similarity index 99%
rename from core/modules/views/src/Tests/Handler/FieldWebTest.php
rename to core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
index 31de7be7e6..318be3f902 100644
--- a/core/modules/views/src/Tests/Handler/FieldWebTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FieldWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\Unicode;
@@ -8,6 +8,7 @@
 use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Url;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -16,7 +17,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\field\FieldPluginBase
  */
-class FieldWebTest extends HandlerTestBase {
+class FieldWebTest extends ViewTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -41,8 +42,8 @@ class FieldWebTest extends HandlerTestBase {
     'views_test_data_name' => 'name',
   ];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -99,7 +100,7 @@ protected function clickSortLoadIdsFromOutput() {
     $fields = $this->xpath("//td[contains(@class, 'views-field-id')]");
     $ids = [];
     foreach ($fields as $field) {
-      $ids[] = (int) $field[0];
+      $ids[] = (int) $field->getText();
     }
     return $ids;
   }
diff --git a/core/modules/views/src/Tests/Handler/FilterDateTest.php b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Handler/FilterDateTest.php
rename to core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
index f81e753d60..ec3b52385f 100644
--- a/core/modules/views/src/Tests/Handler/FilterDateTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/FilterDateTest.php
@@ -1,11 +1,12 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\config\Tests\SchemaCheckTestTrait;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\node\Entity\NodeType;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -13,7 +14,7 @@
  *
  * @group views
  */
-class FilterDateTest extends HandlerTestBase {
+class FilterDateTest extends ViewTestBase {
   use SchemaCheckTestTrait;
 
   /**
@@ -30,8 +31,8 @@ class FilterDateTest extends HandlerTestBase {
    */
   public static $modules = ['node', 'views_ui', 'datetime'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Add a date field so we can test datetime handling.
     NodeType::create([
@@ -213,7 +214,7 @@ protected function _testFilterDateUI() {
       $this->assertFieldByName($name, $value);
       if (strpos($name, '[value][type]')) {
         $radio = $this->cssSelect('input[name="' . $name . '"][checked="checked"][type="radio"]');
-        $this->assertEqual((string) $radio[0]['value'], $value);
+        $this->assertEqual($radio[0]->getAttribute('value'), $value);
       }
     }
 
@@ -221,22 +222,27 @@ protected function _testFilterDateUI() {
     $this->assertConfigSchemaByName('views.view.test_filter_date_between');
 
     // Test that the exposed filter works as expected.
-    $this->drupalGet('admin/structure/views/view/test_filter_date_between/edit');
-    $this->drupalPostForm(NULL, [], t('Update preview'));
+    $path = 'test_filter_date_between-path';
+    $this->drupalPostForm('admin/structure/views/view/test_filter_date_between/edit', [], 'Add Page');
+    $this->drupalPostForm('admin/structure/views/nojs/display/test_filter_date_between/page_1/path', ['path' => $path], 'Apply');
+    $this->drupalPostForm(NULL, [], t('Save'));
+
+    $this->drupalGet($path);
+    $this->drupalPostForm(NULL, [], 'Apply');
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 4);
-    $this->drupalPostForm(NULL, ['created' => '1'], t('Update preview'));
+    $this->drupalPostForm(NULL, ['created' => '1'], 'Apply');
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => '2'], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => '2'], 'Apply');
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => '3'], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => '3'], 'Apply');
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[1]->id());
+    $this->assertEqual($results[0]->getText(), $this->nodes[1]->id());
 
     // Change the filter to a single filter to test the schema when the operator
     // is not exposed.
@@ -250,15 +256,15 @@ protected function _testFilterDateUI() {
     $this->assertConfigSchemaByName('views.view.test_filter_date_between');
 
     // Test that the filter works as expected.
-    $this->drupalPostForm(NULL, [], t('Update preview'));
+    $this->drupalGet($path);
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 1);
-    $this->assertEqual((string) $results[0], $this->nodes[3]->id());
-    $this->drupalPostForm(NULL, ['created' => format_date(250000, 'custom', 'Y-m-d H:i:s')], t('Update preview'));
+    $this->assertEqual($results[0]->getText(), $this->nodes[3]->id());
+    $this->drupalPostForm(NULL, ['created' => format_date(250000, 'custom', 'Y-m-d H:i:s')], 'Apply');
     $results = $this->cssSelect('.view-content .field-content');
     $this->assertEqual(count($results), 2);
-    $this->assertEqual((string) $results[0], $this->nodes[2]->id());
-    $this->assertEqual((string) $results[1], $this->nodes[3]->id());
+    $this->assertEqual($results[0]->getText(), $this->nodes[2]->id());
+    $this->assertEqual($results[1]->getText(), $this->nodes[3]->id());
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Handler/HandlerAllTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Handler/HandlerAllTest.php
rename to core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
index 565437657e..1a37ce8307 100644
--- a/core/modules/views/src/Tests/Handler/HandlerAllTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerAllTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\comment\Tests\CommentTestTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Plugin\views\HandlerBase;
 use Drupal\views\Plugin\views\filter\InOperator;
@@ -13,7 +14,7 @@
  *
  * @group views
  */
-class HandlerAllTest extends HandlerTestBase {
+class HandlerAllTest extends ViewTestBase {
 
   use CommentTestTrait;
 
diff --git a/core/modules/views/src/Tests/Handler/HandlerTest.php b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Handler/HandlerTest.php
rename to core/modules/views/tests/src/Functional/Handler/HandlerTest.php
index e07beb3834..cffe6d1402 100644
--- a/core/modules/views/src/Tests/Handler/HandlerTest.php
+++ b/core/modules/views/tests/src/Functional/Handler/HandlerTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Handler;
+namespace Drupal\Tests\views\Functional\Handler;
 
 use Drupal\comment\Tests\CommentTestTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Entity\View;
 use Drupal\views\ViewExecutable;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\views\Plugin\views\HandlerBase;
 use Drupal\views\Views;
 
@@ -32,8 +32,8 @@ class HandlerTest extends ViewTestBase {
    */
   public static $modules = ['views_ui', 'comment', 'node'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
     $this->drupalCreateContentType(['type' => 'page']);
     $this->addDefaultCommentField('node', 'page');
     $this->enableViewsTestModule();
@@ -260,13 +260,12 @@ public function testRelationshipUI() {
     $this->assertFieldByName($relationship_name);
 
     // Check for available options.
-    $xpath = $this->constructFieldXpath('name', $relationship_name);
-    $fields = $this->xpath($xpath);
+    $fields = $this->getSession()->getPage()->findAll('named_exact', ['field', $relationship_name]);
     $options = [];
     foreach ($fields as $field) {
-      $items = $this->getAllOptions($field);
+      $items = $field->findAll('css', 'option');
       foreach ($items as $item) {
-        $options[] = $item->attributes()->value;
+        $options[] = $item->getAttribute('value');
       }
     }
     $expected_options = ['none', 'nid'];
diff --git a/core/modules/views/src/Tests/Plugin/AccessTest.php b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Plugin/AccessTest.php
rename to core/modules/views/tests/src/Functional/Plugin/AccessTest.php
index 7a4eb1a5b3..41aa6ec53a 100644
--- a/core/modules/views/src/Tests/Plugin/AccessTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/AccessTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
@@ -12,7 +13,7 @@
  * @todo It probably make sense to split the test up by one for role/perm/none
  *   and the two generic ones.
  */
-class AccessTest extends PluginTestBase {
+class AccessTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -42,8 +43,8 @@ class AccessTest extends PluginTestBase {
    */
   protected $normalUser;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
similarity index 93%
rename from core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
index a4e82172e0..b3956de8ea 100644
--- a/core/modules/views/src/Tests/Plugin/ArgumentDefaultTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ArgumentDefaultTest.php
@@ -1,10 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Url;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\views_test_data\Plugin\views\argument_default\ArgumentDefaultTest as ArgumentDefaultTestPlugin;
 use Symfony\Component\HttpFoundation\Request;
@@ -15,7 +16,7 @@
  *
  * @group views
  */
-class ArgumentDefaultTest extends PluginTestBase {
+class ArgumentDefaultTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -37,8 +38,8 @@ class ArgumentDefaultTest extends PluginTestBase {
    */
   public static $modules = ['node', 'views_ui', 'block'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -161,9 +162,9 @@ public function testArgumentDefaultNode() {
     $this->drupalPlaceBlock("views_block:test_argument_default_node-block_1", ['id' => $id]);
     $xpath = '//*[@id="block-' . $id . '"]';
     $this->drupalGet('node/' . $node1->id());
-    $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node1->getTitle()));
+    $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node1->getTitle()));
     $this->drupalGet('node/' . $node2->id());
-    $this->assertTrue(strpos($this->xpath($xpath)[0]->asXml(), $node2->getTitle()));
+    $this->assertTrue(strpos($this->xpath($xpath)[0]->getText(), $node2->getTitle()));
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/CacheTagTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Plugin/CacheTagTest.php
rename to core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
index 72d94f3cf3..1d78204db9 100644
--- a/core/modules/views/src/Tests/Plugin/CacheTagTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/CacheTagTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Cache\Cache;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Views;
 
@@ -12,7 +13,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\cache\Tag
  */
-class CacheTagTest extends PluginTestBase {
+class CacheTagTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -70,8 +71,8 @@ class CacheTagTest extends PluginTestBase {
    */
   protected $user;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page', 'name' => 'Basic page']);
     $this->drupalCreateContentType(['type' => 'article', 'name' => 'Article']);
diff --git a/core/modules/views/src/Tests/Plugin/CacheWebTest.php b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Plugin/CacheWebTest.php
rename to core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
index 7786606376..40bf60189c 100644
--- a/core/modules/views/src/Tests/Plugin/CacheWebTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/CacheWebTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Views;
 
@@ -12,7 +13,7 @@
  * @group views
  * @see views_plugin_cache
  */
-class CacheWebTest extends PluginTestBase {
+class CacheWebTest extends ViewTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -33,8 +34,8 @@ class CacheWebTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
index 7fb70580a2..567e1c930a 100644
--- a/core/modules/views/src/Tests/Plugin/ContextualFiltersBlockContextTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ContextualFiltersBlockContextTest.php
@@ -1,10 +1,10 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Core\Plugin\Context\ContextDefinitionInterface;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Tests\ViewTestData;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
 
 /**
@@ -47,8 +47,8 @@ class ContextualFiltersBlockContextTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     ViewTestData::createTestViews(get_class($this), ['block_test_views']);
     $this->enableViewsTestModule();
diff --git a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
similarity index 86%
rename from core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
index cb43946913..708ac55030 100644
--- a/core/modules/views/src/Tests/Plugin/DisabledDisplayTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisabledDisplayTest.php
@@ -1,6 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the ability to disable and enable view displays.
@@ -8,7 +10,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\display\Feed
  */
-class DisabledDisplayTest extends PluginTestBase {
+class DisabledDisplayTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -24,8 +26,8 @@ class DisabledDisplayTest extends PluginTestBase {
    */
   public static $modules = ['block', 'node', 'views'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
@@ -56,7 +58,7 @@ public function testDisabledDisplays() {
     // Enabled page display should return content.
     $this->drupalGet('test-disabled-display');
     $result = $this->xpath('//h1[@class="page-title"]');
-    $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_1 display is accessible.');
+    $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_1 display is accessible.');
 
     // Disabled page view should 404.
     $this->drupalGet('test-disabled-display-2');
@@ -75,7 +77,7 @@ public function testDisabledDisplays() {
     // Check that the originally disabled page_2 display is now enabled.
     $this->drupalGet('test-disabled-display-2');
     $result = $this->xpath('//h1[@class="page-title"]');
-    $this->assertEqual($result[0], 'test_disabled_display', 'The enabled page_2 display is accessible.');
+    $this->assertEqual($result[0]->getText(), 'test_disabled_display', 'The enabled page_2 display is accessible.');
 
     // Disable each disabled display and save the view.
     foreach ($display_ids as $display_id) {
diff --git a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
similarity index 93%
rename from core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
index 16c0680b36..8c326baa05 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayAttachmentTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayAttachmentTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -10,7 +11,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\display\Attachment
  */
-class DisplayAttachmentTest extends PluginTestBase {
+class DisplayAttachmentTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -26,8 +27,8 @@ class DisplayAttachmentTest extends PluginTestBase {
    */
   public static $modules = ['node', 'views'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
index ac7209c284..a081ad7d97 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayEntityReferenceTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayEntityReferenceTest.php
@@ -1,11 +1,12 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -15,7 +16,7 @@
  *
  * @see \Drupal\views\Plugin\views\display\EntityReference
  */
-class DisplayEntityReferenceTest extends PluginTestBase {
+class DisplayEntityReferenceTest extends ViewTestBase {
 
   use EntityReferenceTestTrait;
 
@@ -64,8 +65,8 @@ class DisplayEntityReferenceTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalLogin($this->drupalCreateUser(['administer views']));
 
diff --git a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
similarity index 84%
rename from core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
index b5c853faec..3d2aca6639 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayPageWebTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayPageWebTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -10,7 +11,7 @@
  *
  * @group views
  */
-class DisplayPageWebTest extends PluginTestBase {
+class DisplayPageWebTest extends ViewTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
@@ -31,8 +32,8 @@ class DisplayPageWebTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
     $this->drupalPlaceBlock('local_tasks_block');
@@ -55,13 +56,13 @@ public function testArguments() {
     $this->assertCacheContexts(['languages:language_interface', 'route', 'theme', 'url']);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_suffix/1/suffix');
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_suffix_and_argument/1/suffix/2');
     $this->assertResponse(200);
@@ -72,13 +73,13 @@ public function testArguments() {
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
 
     $this->drupalGet('test_route_with_long_argument/1');
     $this->assertResponse(200);
     $result = $this->xpath('//span[@class="field-content"]');
     $this->assertEqual(count($result), 1, 'Ensure that just the filtered entry was returned.');
-    $this->assertEqual((string) $result[0], 1, 'The passed ID was returned.');
+    $this->assertEqual($result[0]->getText(), 1, 'The passed ID was returned.');
   }
 
   /**
@@ -88,11 +89,11 @@ public function testPageDisplayMenu() {
     // Check local tasks.
     $this->drupalGet('test_page_display_menu');
     $this->assertResponse(200);
-    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', [
+    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [
       ':ul_class' => 'tabs primary',
       ':a_class' => 'is-active',
     ]);
-    $this->assertEqual((string) $element[0], t('Test default tab'));
+    $this->assertEqual($element[0]->getText(), t('Test default tab'));
     $this->assertTitle(t('Test default page | Drupal'));
 
     $this->drupalGet('test_page_display_menu/default');
@@ -100,11 +101,11 @@ public function testPageDisplayMenu() {
 
     $this->drupalGet('test_page_display_menu/local');
     $this->assertResponse(200);
-    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]', [
+    $element = $this->xpath('//ul[contains(@class, :ul_class)]//a[contains(@class, :a_class)]/child::text()', [
       ':ul_class' => 'tabs primary',
       ':a_class' => 'is-active',
     ]);
-    $this->assertEqual((string) $element[0], t('Test local tab'));
+    $this->assertEqual($element[0]->getText(), t('Test local tab'));
     $this->assertTitle(t('Test local page | Drupal'));
 
     // Check an ordinary menu link.
@@ -114,7 +115,7 @@ public function testPageDisplayMenu() {
     $this->drupalGet('<front>');
 
     $menu_link = $this->cssSelect('nav.block-menu ul.menu a');
-    $this->assertEqual((string) $menu_link[0], 'Test menu link');
+    $this->assertEqual($menu_link[0]->getText(), 'Test menu link');
 
     // Update the menu link.
     $this->drupalPostForm("admin/structure/menu/link/views_view:views.test_page_display_menu.page_3/edit", [
@@ -123,7 +124,7 @@ public function testPageDisplayMenu() {
 
     $this->drupalGet('<front>');
     $menu_link = $this->cssSelect('nav.block-menu ul.menu a');
-    $this->assertEqual((string) $menu_link[0], 'New title');
+    $this->assertEqual($menu_link[0]->getText(), 'New title');
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/DisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
similarity index 80%
rename from core/modules/views/src/Tests/Plugin/DisplayTest.php
rename to core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
index 42a389cb91..6748152987 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\views\Entity\View;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\views_test_data\Plugin\views\display\DisplayTest as DisplayTestPlugin;
 
@@ -12,7 +12,7 @@
  *
  * @group views
  */
-class DisplayTest extends PluginTestBase {
+class DisplayTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -28,7 +28,7 @@ class DisplayTest extends PluginTestBase {
    */
   public static $modules = ['views_ui', 'node', 'block'];
 
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp();
 
     $this->enableViewsTestModule();
@@ -94,6 +94,13 @@ public function testDisplayPlugin() {
     // Check the test option.
     $this->assertIdentical($view->display_handler->getOption('test_option'), '');
 
+    $style = $view->display_handler->getOption('style');
+    $style['type'] = 'test_style';
+    $view->display_handler->setOption('style', $style);
+    $view->initDisplay();
+    $view->initStyle();
+    $view->style_plugin->setUsesRowPlugin(FALSE);
+
     $output = $view->preview();
     $output = $renderer->renderRoot($output);
 
@@ -113,9 +120,9 @@ public function testDisplayPlugin() {
     $this->drupalGet('admin/structure/views/view/test_view/edit/display_test_1');
     $this->assertText('Display test settings');
     // Ensure that the order is as expected.
-    $result = $this->xpath('//ul[@id="views-display-menu-tabs"]/li');
-    $this->assertEqual((string) $result[0]->a, 'Display test 2');
-    $this->assertEqual((string) $result[1]->a, 'Display test');
+    $result = $this->xpath('//ul[@id="views-display-menu-tabs"]/li/a/child::text()');
+    $this->assertEqual($result[0]->getText(), 'Display test 2');
+    $this->assertEqual($result[1]->getText(), 'Display test');
 
     $this->clickLink('Test option title');
 
@@ -161,76 +168,6 @@ public function testGetAttachedDisplays() {
   }
 
   /**
-   * Tests the readmore functionality.
-   */
-  public function testReadMore() {
-    /** @var \Drupal\Core\Render\RendererInterface $renderer */
-    $renderer = $this->container->get('renderer');
-
-    if (!isset($this->options['validate']['type'])) {
-      return;
-    }
-    $expected_more_text = 'custom more text';
-
-    $view = Views::getView('test_display_more');
-    $this->executeView($view);
-
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
-    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
-
-    // Test the renderMoreLink method directly. This could be directly unit
-    // tested.
-    $more_link = $view->display_handler->renderMoreLink();
-    $more_link = $renderer->renderRoot($more_link);
-    $this->setRawContent($more_link);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
-    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
-
-    // Test the useMoreText method directly. This could be directly unit
-    // tested.
-    $more_text = $view->display_handler->useMoreText();
-    $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.');
-
-    $view = Views::getView('test_display_more');
-    $view->setDisplay();
-    $view->display_handler->setOption('use_more', 0);
-    $this->executeView($view);
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertTrue(empty($result), 'The more link is not shown.');
-
-    $view = Views::getView('test_display_more');
-    $view->setDisplay();
-    $view->display_handler->setOption('use_more', 0);
-    $view->display_handler->setOption('use_more_always', 0);
-    $view->display_handler->setOption('pager', [
-      'type' => 'some',
-      'options' => [
-        'items_per_page' => 1,
-        'offset' => 0,
-      ],
-    ]);
-    $this->executeView($view);
-    $output = $view->preview();
-    $output = $renderer->renderRoot($output);
-    $this->setRawContent($output);
-    $result = $this->xpath('//a[@class=:class]', [':class' => 'more-link']);
-    $this->assertTrue(empty($result), 'The more link is not shown when view has more records.');
-
-    // Test the default value of use_more_always.
-    $view = View::create()->getExecutable();
-    $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.');
-  }
-
-  /**
    * Tests the readmore validation.
    */
   public function testReadMoreNoDisplay() {
@@ -290,7 +227,8 @@ public function testInvalidDisplayPlugins() {
 
     $this->drupalGet('<front>');
     $this->assertResponse(200);
-    $this->assertBlockAppears($block);
+    $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]);
+    $this->assertEquals(1, count($result));
 
     // Change the block plugin ID to an invalid one.
     $config = $this->config('views.view.test_display_invalid');
@@ -302,7 +240,8 @@ public function testInvalidDisplayPlugins() {
     $this->drupalGet('<front>');
     $this->assertResponse(200);
     $this->assertText('The &quot;invalid&quot; plugin does not exist.');
-    $this->assertNoBlockAppears($block);
+    $result = $this->xpath('//div[@id = :id]', [':id' => 'block-' . $block->id()]);
+    $this->assertEquals(0, count($result));
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
similarity index 91%
rename from core/modules/views/src/Tests/Plugin/ExposedFormTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
index cfb3c0a071..38b7327b4d 100644
--- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ExposedFormTest.php
@@ -1,11 +1,11 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Component\Utility\Html;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\ViewExecutable;
 use Drupal\views\Views;
 use Drupal\views\Entity\View;
@@ -33,8 +33,8 @@ class ExposedFormTest extends ViewTestBase {
    */
   public static $modules = ['node', 'views_ui', 'block', 'entity_test'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
@@ -192,26 +192,6 @@ public function testResetButton() {
   }
 
   /**
-   * Tests the exposed form markup.
-   */
-  public function testExposedFormRender() {
-    $view = Views::getView('test_exposed_form_buttons');
-    $this->executeView($view);
-    $exposed_form = $view->display_handler->getPlugin('exposed_form');
-    $output = $exposed_form->renderExposedForm();
-    $this->setRawContent(\Drupal::service('renderer')->renderRoot($output));
-
-    $this->assertFieldByXpath('//form/@id', $this->getExpectedExposedFormId($view), 'Expected form ID found.');
-
-    $view->setDisplay('page_1');
-    $expected_action = $view->display_handler->getUrlInfo()->toString();
-    $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
-    // Make sure the description is shown.
-    $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', [':id' => 'edit-type--description', ':description' => t('Exposed description')]);
-    $this->assertEqual(count($result), 1, 'Filter description was found.');
-  }
-
-  /**
    * Tests overriding the default render option with checkboxes.
    */
   public function testExposedFormRenderCheckboxes() {
@@ -265,7 +245,8 @@ public function testExposedBlock() {
 
     // Test there is an exposed form in a block.
     $xpath = $this->buildXPathQuery('//div[@id=:id]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]);
-    $this->assertFieldByXpath($xpath, $this->getExpectedExposedFormId($view), 'Expected form found in views block.');
+    $result = $this->xpath($xpath);
+    $this->assertEquals(1, count($result));
 
     // Test there is not an exposed form in the view page content area.
     $xpath = $this->buildXPathQuery('//div[@class="view-content"]/form/@id', [':id' => Html::getUniqueId('block-' . $block->id())]);
@@ -381,7 +362,7 @@ protected function assertIds(array $ids) {
     $elements = $this->cssSelect('div.view-test-exposed-form-sort-items-per-page div.views-row span.field-content');
     $actual_ids = [];
     foreach ($elements as $element) {
-      $actual_ids[] = (int) $element;
+      $actual_ids[] = (int) $element->getText();
     }
 
     return $this->assertIdentical($ids, $actual_ids);
diff --git a/core/modules/views/src/Tests/Plugin/FilterTest.php b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php
similarity index 96%
rename from core/modules/views/src/Tests/Plugin/FilterTest.php
rename to core/modules/views/tests/src/Functional/Plugin/FilterTest.php
index 081835f404..60424108f5 100644
--- a/core/modules/views/src/Tests/Plugin/FilterTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/FilterTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\views_test_data\Plugin\views\filter\FilterTest as FilterPlugin;
 
@@ -11,7 +12,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\filter\FilterPluginBase
  */
-class FilterTest extends PluginTestBase {
+class FilterTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -27,8 +28,8 @@ class FilterTest extends PluginTestBase {
    */
   public static $modules = ['views_ui', 'node'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
similarity index 93%
rename from core/modules/views/src/Tests/Plugin/MenuLinkTest.php
rename to core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
index 06e661f28b..8afbb57b8c 100644
--- a/core/modules/views/src/Tests/Plugin/MenuLinkTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/MenuLinkTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\menu_link_content\Entity\MenuLinkContent;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the menu links created in views.
@@ -36,8 +36,8 @@ class MenuLinkTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Plugin/MiniPagerTest.php
rename to core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
index 7e9f57a305..492d22f987 100644
--- a/core/modules/views/src/Tests/Plugin/MiniPagerTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/MiniPagerTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 
 /**
@@ -10,7 +11,7 @@
  * @group views
  * @see \Drupal\views\Plugin\views\pager\Mini
  */
-class MiniPagerTest extends PluginTestBase {
+class MiniPagerTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -33,8 +34,8 @@ class MiniPagerTest extends PluginTestBase {
    */
   protected $nodes;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page']);
     // Create a bunch of test nodes.
diff --git a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php
rename to core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
index d463336c41..08f2504c54 100644
--- a/core/modules/views/src/Tests/Plugin/NumericFormatPluralTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/NumericFormatPluralTest.php
@@ -1,10 +1,10 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\Component\Gettext\PoHeader;
 use Drupal\file\Entity\File;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the creation of numeric fields.
@@ -27,8 +27,8 @@ class NumericFormatPluralTest extends ViewTestBase {
    */
   public static $testViews = ['numeric_test'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $web_user = $this->drupalCreateUser(['administer views', 'administer languages']);
     $this->drupalLogin($web_user);
diff --git a/core/modules/views/src/Tests/Plugin/PagerTest.php b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php
similarity index 99%
rename from core/modules/views/src/Tests/Plugin/PagerTest.php
rename to core/modules/views/tests/src/Functional/Plugin/PagerTest.php
index 6ba4c069b4..eda88916d6 100644
--- a/core/modules/views/src/Tests/Plugin/PagerTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/PagerTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\system\Tests\Cache\AssertPageCacheContextsAndTagsTrait;
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\language\Entity\ConfigurableLanguage;
 
@@ -11,7 +12,7 @@
  *
  * @group views
  */
-class PagerTest extends PluginTestBase {
+class PagerTest extends ViewTestBase {
 
   use AssertPageCacheContextsAndTagsTrait;
 
diff --git a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Plugin/StyleSummaryTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
index cbd569ca08..252a3091ca 100644
--- a/core/modules/views/src/Tests/Plugin/StyleSummaryTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleSummaryTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
 use Drupal\entity_test\Entity\EntityTest;
-use Drupal\views\Tests\ViewTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests the summary style plugin.
@@ -58,13 +58,13 @@ public function testSummaryView() {
     $this->assertEqual(4, count($summary_list));
 
     foreach ($summary_list as $summary_list_item) {
-      $this->assertEqual('(5)', trim((string) $summary_list_item));
+      $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1]));
     }
 
     $summary_links = $this->cssSelect('ul.views-summary a');
     $this->assertEqual(4, count($summary_links));
     foreach ($summary_links as $index => $summary_link) {
-      $this->assertEqual('type' . $index, trim((string) $summary_link));
+      $this->assertEqual('type' . $index, trim($summary_link->getText()));
     }
 
     $this->clickLink('type1');
@@ -100,13 +100,13 @@ public function testSummaryView() {
     $this->assertEqual(3, count($summary_list));
 
     foreach ($summary_list as $summary_list_item) {
-      $this->assertEqual('(5)', trim((string) $summary_list_item));
+      $this->assertEqual('(5)', trim(explode(' ', $summary_list_item->getText())[1]));
     }
 
     $summary_links = $this->cssSelect('.views-summary-unformatted a');
     $this->assertEqual(3, count($summary_links));
     foreach ($summary_links as $index => $summary_link) {
-      $this->assertEqual('type' . $index, trim((string) $summary_link));
+      $this->assertEqual('type' . $index, trim($summary_link->getText()));
     }
 
     $this->clickLink('type1');
diff --git a/core/modules/views/src/Tests/Plugin/StyleTableTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
similarity index 89%
rename from core/modules/views/src/Tests/Plugin/StyleTableTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
index 537839f7bf..3bbe6bf97c 100644
--- a/core/modules/views/src/Tests/Plugin/StyleTableTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleTableTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Entity\View;
 
 /**
@@ -9,7 +10,7 @@
  *
  * @group views
  */
-class StyleTableTest extends PluginTestBase {
+class StyleTableTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -21,8 +22,8 @@ class StyleTableTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -33,17 +34,17 @@ protected function setUp() {
   public function testAccessibilitySettings() {
     $this->drupalGet('test-table');
 
-    $result = $this->xpath('//caption');
+    $result = $this->xpath('//caption/child::text()');
     $this->assertTrue(count($result), 'The caption appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'caption-text');
+    $this->assertEqual(trim($result[0]->getText()), 'caption-text');
 
-    $result = $this->xpath('//summary');
+    $result = $this->xpath('//summary/child::text()');
     $this->assertTrue(count($result), 'The summary appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'summary-text');
+    $this->assertEqual(trim($result[0]->getText()), 'summary-text');
 
-    $result = $this->xpath('//caption/details');
+    $result = $this->xpath('//caption/details/child::text()');
     $this->assertTrue(count($result), 'The table description appears on the table.');
-    $this->assertEqual(trim((string) $result[0]), 'description-text');
+    $this->assertEqual(trim($result[0]->getText()), 'description-text');
 
     // Remove the caption and ensure the caption is not displayed anymore.
     $view = View::load('test_table');
@@ -52,8 +53,8 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//caption');
-    $this->assertFalse(trim((string) $result[0]), 'Ensure that the caption disappears.');
+    $result = $this->xpath('//caption/child::text()');
+    $this->assertFalse(trim($result[0]->getText()), 'Ensure that the caption disappears.');
 
     // Remove the table summary.
     $display = &$view->getDisplay('default');
@@ -61,7 +62,7 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//summary');
+    $result = $this->xpath('//summary/child::text()');
     $this->assertFalse(count($result), 'Ensure that the summary disappears.');
 
     // Remove the table description.
@@ -70,7 +71,7 @@ public function testAccessibilitySettings() {
     $view->save();
 
     $this->drupalGet('test-table');
-    $result = $this->xpath('//caption/details');
+    $result = $this->xpath('//caption/details/child::text()');
     $this->assertFalse(count($result), 'Ensure that the description disappears.');
   }
 
diff --git a/core/modules/views/src/Tests/Plugin/StyleTest.php b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Plugin/StyleTest.php
rename to core/modules/views/tests/src/Functional/Plugin/StyleTest.php
index e059275617..fbb5bcfff1 100644
--- a/core/modules/views/src/Tests/Plugin/StyleTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/StyleTest.php
@@ -1,9 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
-use Drupal\views\Tests\ViewTestBase;
 use Drupal\views_test_data\Plugin\views\row\RowTest;
 use Drupal\views\Plugin\views\row\Fields;
 use Drupal\views\ResultRow;
@@ -31,8 +31,8 @@ class StyleTest extends ViewTestBase {
    */
   protected $elements;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Plugin/ViewsBulkTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
similarity index 90%
rename from core/modules/views/src/Tests/Plugin/ViewsBulkTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
index 269f5b05b5..0ca6f8775e 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsBulkTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsBulkTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests views bulk operation selection.
  *
  * @group views
  */
-class ViewsBulkTest extends WebTestBase {
+class ViewsBulkTest extends ViewTestBase {
 
   /**
    * An admin user
@@ -25,8 +25,8 @@ class ViewsBulkTest extends WebTestBase {
    */
   public static $modules = ['node', 'views'];
 
-  public function setUp() {
-    parent::setUp();
+  public function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalCreateContentType(['type' => 'page']);
     $this->admin_user = $this->createUser(['bypass node access', 'administer nodes', 'access content overview']);
diff --git a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
similarity index 83%
rename from core/modules/views/src/Tests/Plugin/ViewsFormTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
index a730189317..3f6e1eca5f 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsFormTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsFormTest.php
@@ -1,15 +1,15 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
-use Drupal\simpletest\WebTestBase;
+use Drupal\Tests\views\Functional\ViewTestBase;
 
 /**
  * Tests Views forms functionality.
  *
  * @group views
  */
-class ViewsFormTest extends WebTestBase {
+class ViewsFormTest extends ViewTestBase {
 
   /**
    * Modules to enable.
diff --git a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php b/core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
similarity index 85%
rename from core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
rename to core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
index d3c93de447..40405ae03d 100644
--- a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
+++ b/core/modules/views/tests/src/Functional/Plugin/ViewsSqlExceptionTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Functional\Plugin;
 
+use Drupal\Tests\views\Functional\ViewTestBase;
 use Drupal\views\Views;
 use Drupal\Core\Database\DatabaseExceptionWrapper;
 
@@ -10,7 +11,7 @@
  *
  * @group views
  */
-class ViewsSqlExceptionTest extends PluginTestBase {
+class ViewsSqlExceptionTest extends ViewTestBase {
 
   /**
    * Views used by this test.
@@ -22,8 +23,8 @@ class ViewsSqlExceptionTest extends PluginTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/RenderCacheWebTest.php b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php
similarity index 83%
rename from core/modules/views/src/Tests/RenderCacheWebTest.php
rename to core/modules/views/tests/src/Functional/RenderCacheWebTest.php
index fcd38b7304..f8dfdd810d 100644
--- a/core/modules/views/src/Tests/RenderCacheWebTest.php
+++ b/core/modules/views/tests/src/Functional/RenderCacheWebTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\node\Entity\Node;
 
@@ -60,15 +60,15 @@ public function testEmptyView() {
     $this->assertEqual([], $this->cssSelect('div.region-header div.views-field-title'));
 
     $this->drupalGet($this->nodes[0]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 1', $result);
 
     $this->drupalGet($this->nodes[1]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 2', $result);
 
     $this->drupalGet($this->nodes[0]->toUrl());
-    $result = (string) $this->cssSelect('div.region-header div.views-field-title')[0]->span;
+    $result = $this->cssSelect('div.region-header div.views-field-title')[0]->getText();
     $this->assertEqual('test title 1', $result);
   }
 
diff --git a/core/modules/views/src/Tests/SearchIntegrationTest.php b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php
similarity index 89%
rename from core/modules/views/src/Tests/SearchIntegrationTest.php
rename to core/modules/views/tests/src/Functional/SearchIntegrationTest.php
index 1b6ab89159..f4daac774e 100644
--- a/core/modules/views/src/Tests/SearchIntegrationTest.php
+++ b/core/modules/views/tests/src/Functional/SearchIntegrationTest.php
@@ -1,8 +1,9 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Tests\Traits\Core\CronRunTrait;
 
 /**
  * Tests search integration filters.
@@ -11,6 +12,8 @@
  */
 class SearchIntegrationTest extends ViewTestBase {
 
+  use CronRunTrait;
+
   /**
    * Modules to enable.
    *
@@ -108,10 +111,10 @@ public function testSearchIntegration() {
     $this->cronRun();
     $this->drupalGet('test-arg/rocks');
     $xpath = '//div[@class="views-row"]//a';
-    /** @var \SimpleXMLElement[] $results */
+    /** @var \Behat\Mink\Element\NodeElement[] $results */
     $results = $this->xpath($xpath);
-    $this->assertEqual((string) $results[0], "Drupal's search rocks <em>really</em> rocks!");
-    $this->assertEqual((string) $results[1], "Drupal's search rocks.");
+    $this->assertEqual($results[0]->getText(), "Drupal's search rocks <em>really</em> rocks!");
+    $this->assertEqual($results[1]->getText(), "Drupal's search rocks.");
     $this->assertEscaped("Drupal's search rocks <em>really</em> rocks!");
 
     // Test sorting with another set of titles.
@@ -127,8 +130,8 @@ public function testSearchIntegration() {
     $xpath = '//div[@class="views-row"]//a';
     /** @var \SimpleXMLElement[] $results */
     $results = $this->xpath($xpath);
-    $this->assertEqual((string) $results[0], "Testing one one one");
-    $this->assertEqual((string) $results[1], "Testing one two two two");
+    $this->assertEqual($results[0]->getText(), "Testing one one one");
+    $this->assertEqual($results[1]->getText(), "Testing one two two two");
   }
 
   /**
diff --git a/core/modules/views/src/Tests/SearchMultilingualTest.php b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php
similarity index 96%
rename from core/modules/views/src/Tests/SearchMultilingualTest.php
rename to core/modules/views/tests/src/Functional/SearchMultilingualTest.php
index f53421917b..d6a72bf8cd 100644
--- a/core/modules/views/src/Tests/SearchMultilingualTest.php
+++ b/core/modules/views/tests/src/Functional/SearchMultilingualTest.php
@@ -1,9 +1,10 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\NodeInterface;
+use Drupal\Tests\Traits\Core\CronRunTrait;
 
 /**
  * Tests search integration filters with multilingual nodes.
@@ -12,6 +13,8 @@
  */
 class SearchMultilingualTest extends ViewTestBase {
 
+  use CronRunTrait;
+
   /**
    * Modules to enable.
    *
diff --git a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
similarity index 89%
rename from core/modules/views/src/Tests/TaxonomyGlossaryTest.php
rename to core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
index ccda8877d2..c34e6f2a02 100644
--- a/core/modules/views/src/Tests/TaxonomyGlossaryTest.php
+++ b/core/modules/views/tests/src/Functional/TaxonomyGlossaryTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\taxonomy\Tests\TaxonomyTestTrait;
 
@@ -34,8 +34,8 @@ class TaxonomyGlossaryTest extends ViewTestBase {
    */
   protected $taxonomyTerms;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
 
diff --git a/core/modules/views/src/Tests/ViewRenderTest.php b/core/modules/views/tests/src/Functional/ViewRenderTest.php
similarity index 84%
rename from core/modules/views/src/Tests/ViewRenderTest.php
rename to core/modules/views/tests/src/Functional/ViewRenderTest.php
index 0b3f0ee257..aaf894cd23 100644
--- a/core/modules/views/src/Tests/ViewRenderTest.php
+++ b/core/modules/views/tests/src/Functional/ViewRenderTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 use Drupal\views\Views;
 
@@ -18,8 +18,8 @@ class ViewRenderTest extends ViewTestBase {
    */
   public static $testViews = ['test_view_render'];
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/tests/src/Functional/ViewTestBase.php b/core/modules/views/tests/src/Functional/ViewTestBase.php
new file mode 100644
index 0000000000..0465f966c3
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/ViewTestBase.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Drupal\Tests\views\Functional;
+
+use Behat\Mink\Exception\ElementNotFoundException;
+use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Tests\BrowserTestBase;
+use Drupal\views\Tests\ViewResultAssertionTrait;
+use Drupal\views\Tests\ViewTestData;
+use Drupal\views\ViewExecutable;
+
+/**
+ * Defines a base class for Views testing in the full web test environment.
+ *
+ * Use this base test class if you need to emulate a full Drupal installation.
+ * When possible, ViewsKernelTestBase should be used instead. Both base classes
+ * include the same methods.
+ *
+ * @see \Drupal\Tests\views\Kernel\ViewsKernelTestBase
+ * @see \Drupal\simpletest\WebTestBase
+ */
+abstract class ViewTestBase extends BrowserTestBase {
+
+  use ViewResultAssertionTrait;
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['views', 'views_test_config'];
+
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    if ($import_test_views) {
+      ViewTestData::createTestViews(get_class($this), ['views_test_config']);
+    }
+  }
+
+  /**
+   * Sets up the views_test_data.module.
+   *
+   * Because the schema of views_test_data.module is dependent on the test
+   * using it, it cannot be enabled normally.
+   */
+  protected function enableViewsTestModule() {
+    // Define the schema and views data variable before enabling the test module.
+    \Drupal::state()->set('views_test_data_schema', $this->schemaDefinition());
+    \Drupal::state()->set('views_test_data_views_data', $this->viewsData());
+
+    \Drupal::service('module_installer')->install(['views_test_data']);
+    $this->resetAll();
+    $this->rebuildContainer();
+    $this->container->get('module_handler')->reload();
+
+    // Load the test dataset.
+    $data_set = $this->dataSet();
+    $query = db_insert('views_test_data')
+      ->fields(array_keys($data_set[0]));
+    foreach ($data_set as $record) {
+      $query->values($record);
+    }
+    $query->execute();
+  }
+
+  /**
+   * Orders a nested array containing a result set based on a given column.
+   *
+   * @param array $result_set
+   *   An array of rows from a result set, with each row as an associative
+   *   array keyed by column name.
+   * @param string $column
+   *   The column name by which to sort the result set.
+   * @param bool $reverse
+   *   (optional) Boolean indicating whether to sort the result set in reverse
+   *   order. Defaults to FALSE.
+   *
+   * @return array
+   *   The sorted result set.
+   */
+  protected function orderResultSet($result_set, $column, $reverse = FALSE) {
+    $order = $reverse ? -1 : 1;
+    usort($result_set, function ($a, $b) use ($column, $order) {
+      if ($a[$column] == $b[$column]) {
+        return 0;
+      }
+      return $order * (($a[$column] < $b[$column]) ? -1 : 1);
+    });
+    return $result_set;
+  }
+
+  /**
+   * Asserts the existence of a button with a certain ID and label.
+   *
+   * @param string $id
+   *   The HTML ID of the button
+   * @param string $expected_label
+   *   The expected label for the button.
+   * @param string $message
+   *   (optional) A custom message to display with the assertion. If no custom
+   *   message is provided, the message will indicate the button label.
+   *
+   * @throws \Behat\Mink\Exception\ElementNotFoundException
+   */
+  protected function helperButtonHasLabel($id, $expected_label, $message = 'Label has the expected value: %label.') {
+    $xpath = $this->assertSession()->buildXPathQuery('//button[@id=:value]|//input[@id=:value]', [':value' => $id]);
+    $field = $this->getSession()->getPage()->find('xpath', $xpath);
+
+    if (empty($field)) {
+      throw new ElementNotFoundException($this->getSession()->getDriver(), 'form field', 'id', $field);
+    }
+
+    $this->assertEquals($expected_label, $field->getValue());
+  }
+
+  /**
+   * Executes a view with debugging.
+   *
+   * @param \Drupal\views\ViewExecutable $view
+   *   The view object.
+   * @param array $args
+   *   (optional) An array of the view arguments to use for the view.
+   */
+  protected function executeView(ViewExecutable $view, $args = []) {
+    // A view does not really work outside of a request scope, due to many
+    // dependencies like the current user.
+    $view->setDisplay();
+    $view->preExecute($args);
+    $view->execute();
+    $verbose_message = '<pre>Executed view: ' . ((string) $view->build_info['query']) . '</pre>';
+    if ($view->build_info['query'] instanceof SelectInterface) {
+      $verbose_message .= '<pre>Arguments: ' . print_r($view->build_info['query']->getArguments(), TRUE) . '</pre>';
+    }
+    $this->verbose($verbose_message);
+  }
+
+  /**
+   * Returns the schema definition.
+   */
+  protected function schemaDefinition() {
+    return ViewTestData::schemaDefinition();
+  }
+
+  /**
+   * Returns the views data definition.
+   */
+  protected function viewsData() {
+    return ViewTestData::viewsData();
+  }
+
+  /**
+   * Returns a very simple test dataset.
+   */
+  protected function dataSet() {
+    return ViewTestData::dataSet();
+  }
+
+}
diff --git a/core/modules/views/src/Tests/ViewsEscapingTest.php b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php
similarity index 94%
rename from core/modules/views/src/Tests/ViewsEscapingTest.php
rename to core/modules/views/tests/src/Functional/ViewsEscapingTest.php
index 1ec3a9f3d0..80a8398722 100644
--- a/core/modules/views/src/Tests/ViewsEscapingTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsEscapingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests output of Views.
@@ -30,8 +30,8 @@ class ViewsEscapingTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp(TRUE);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/ViewsFormMultipleTest.php b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
similarity index 81%
rename from core/modules/views/src/Tests/ViewsFormMultipleTest.php
rename to core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
index 844a1b10c9..03d5bcee8c 100644
--- a/core/modules/views/src/Tests/ViewsFormMultipleTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsFormMultipleTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests a page with multiple Views forms.
@@ -19,8 +19,8 @@ class ViewsFormMultipleTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
@@ -51,9 +51,9 @@ public function testViewsFormMultiple() {
     // Submit the forms, validate argument returned in message set by handler.
     // @note There is not a way to specify a specific index for a submit button. So
     // the row index returned is always the last occurrence.
-    $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg2');
+    $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4--2');
     $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg2 was submitted.');
-    $this->drupalPostForm(NULL, [], t('Test Button'), [], [], 'views-form-test-form-multiple-default-arg1');
+    $this->getSession()->getPage()->pressButton('edit-field-form-button-test-4');
     $this->assertText('The test button at row 4 for test_form_multiple (default) View with args: arg1 was submitted.');
   }
 
diff --git a/core/modules/views/src/Tests/ViewsTemplateTest.php b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php
similarity index 88%
rename from core/modules/views/src/Tests/ViewsTemplateTest.php
rename to core/modules/views/tests/src/Functional/ViewsTemplateTest.php
index 4a06908296..8f7de40184 100644
--- a/core/modules/views/src/Tests/ViewsTemplateTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsTemplateTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
+use Drupal\views\Tests\ViewTestData;
 use Drupal\views\Views;
 
 /**
@@ -22,7 +23,7 @@ class ViewsTemplateTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
+  protected function setUp($import_test_views = TRUE) {
     parent::setUp(FALSE);
 
     $this->enableViewsTestModule();
diff --git a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
similarity index 95%
rename from core/modules/views/src/Tests/ViewsThemeIntegrationTest.php
rename to core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
index 1fe836a82e..9bdb405b86 100644
--- a/core/modules/views/src/Tests/ViewsThemeIntegrationTest.php
+++ b/core/modules/views/tests/src/Functional/ViewsThemeIntegrationTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests;
+namespace Drupal\Tests\views\Functional;
 
 /**
  * Tests the Views theme integration.
@@ -33,8 +33,8 @@ class ViewsThemeIntegrationTest extends ViewTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->enableViewsTestModule();
   }
diff --git a/core/modules/views/src/Tests/Wizard/BasicTest.php b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php
similarity index 94%
rename from core/modules/views/src/Tests/Wizard/BasicTest.php
rename to core/modules/views/tests/src/Functional/Wizard/BasicTest.php
index 7394991d23..eb2ddbbb67 100644
--- a/core/modules/views/src/Tests/Wizard/BasicTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/BasicTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Component\Serialization\Json;
 use Drupal\Component\Utility\SafeMarkup;
@@ -14,8 +14,8 @@
  */
 class BasicTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
@@ -80,7 +80,9 @@ public function testViewsWizardAndListing() {
     $elements = $this->cssSelect('link[href="' . Url::fromRoute('view.' . $view2['id'] . '.feed_1', [], ['absolute' => TRUE])->toString() . '"]');
     $this->assertEqual(count($elements), 1, 'Feed found.');
     $this->drupalGet($view2['page[feed_properties][path]']);
-    $this->assertTrue(!empty($this->cssSelect('rss[version="2.0"]')));
+    // Because the response is XML we can't use the page which depends on an
+    // HTML tag being present.
+    $this->assertEquals('2.0', $this->getSession()->getDriver()->getAttribute('//rss', 'version'));
     // The feed should have the same title and nodes as the page.
     $this->assertText($view2['page[title]']);
     $this->assertRaw($node1->url('canonical', ['absolute' => TRUE]));
@@ -134,7 +136,7 @@ public function testViewsWizardAndListing() {
 
     // Confirm that the block is available in the block administration UI.
     $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
-    $this->clickLinkPartialName('Place block');
+    $this->clickLink('Place block');
     $this->assertText($view3['label']);
 
     // Place the block.
@@ -164,7 +166,7 @@ public function testViewsWizardAndListing() {
     // Check that the REST export path works.
     $this->drupalGet($view4['rest_export[path]']);
     $this->assertResponse(200);
-    $data = Json::decode($this->content);
+    $data = Json::decode($this->getSession()->getPage()->getContent());
     $this->assertEqual(count($data), 1, 'Only the node of type page is exported.');
     $node = reset($data);
     $this->assertEqual($node['nid'][0]['value'], $node1->id(), 'The node of type page is exported.');
diff --git a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php
rename to core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
index 58f22a8424..c480ba94c7 100644
--- a/core/modules/views/src/Tests/Wizard/ItemsPerPageTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/ItemsPerPageTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to specify the number of items per
@@ -10,8 +10,8 @@
  */
 class ItemsPerPageTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
@@ -72,7 +72,7 @@ public function testItemsPerPage() {
 
     // Confirm that the block is listed in the block administration UI.
     $this->drupalGet('admin/structure/block/list/' . $this->config('system.theme')->get('default'));
-    $this->clickLinkPartialName('Place block');
+    $this->clickLink('Place block');
     $this->assertText($view['label']);
 
     // Place the block, visit a page that displays the block, and check that the
diff --git a/core/modules/views/src/Tests/Wizard/MenuTest.php b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/MenuTest.php
rename to core/modules/views/tests/src/Functional/Wizard/MenuTest.php
index 0805de6168..853c0692d0 100644
--- a/core/modules/views/src/Tests/Wizard/MenuTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/MenuTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Url;
diff --git a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/NodeWizardTest.php
rename to core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
index dd63efe373..41870b6db9 100644
--- a/core/modules/views/src/Tests/Wizard/NodeWizardTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/NodeWizardTest.php
@@ -1,7 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
-
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests node wizard and generic entity integration.
diff --git a/core/modules/views/src/Tests/Wizard/PagerTest.php b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php
similarity index 97%
rename from core/modules/views/src/Tests/Wizard/PagerTest.php
rename to core/modules/views/tests/src/Functional/Wizard/PagerTest.php
index 2ec6d55511..c8c697c081 100644
--- a/core/modules/views/src/Tests/Wizard/PagerTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/PagerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to create views without a pager.
diff --git a/core/modules/views/src/Tests/Wizard/SortingTest.php b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php
similarity index 95%
rename from core/modules/views/src/Tests/Wizard/SortingTest.php
rename to core/modules/views/tests/src/Functional/Wizard/SortingTest.php
index 58926aabca..07268e3f75 100644
--- a/core/modules/views/src/Tests/Wizard/SortingTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/SortingTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 /**
  * Tests the ability of the views wizard to create views with sorts.
@@ -9,8 +9,8 @@
  */
 class SortingTest extends WizardTestBase {
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     $this->drupalPlaceBlock('page_title_block');
   }
diff --git a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
similarity index 98%
rename from core/modules/views/src/Tests/Wizard/TaggedWithTest.php
rename to core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
index f723950419..680d64496e 100644
--- a/core/modules/views/src/Tests/Wizard/TaggedWithTest.php
+++ b/core/modules/views/tests/src/Functional/Wizard/TaggedWithTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\views\Tests\Wizard;
+namespace Drupal\Tests\views\Functional\Wizard;
 
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\field\Entity\FieldConfig;
@@ -65,8 +65,8 @@ class TaggedWithTest extends WizardTestBase {
    */
   protected $tagField;
 
-  protected function setUp() {
-    parent::setUp();
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
 
     // Create two content types. One will have an autocomplete tagging field,
     // and one won't.
diff --git a/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php
new file mode 100644
index 0000000000..0178c08c25
--- /dev/null
+++ b/core/modules/views/tests/src/Functional/Wizard/WizardTestBase.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\Tests\views\Functional\Wizard;
+
+use Drupal\Tests\views\Functional\ViewTestBase;
+
+/**
+ * Views UI wizard tests.
+ */
+abstract class WizardTestBase extends ViewTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['node', 'views_ui', 'block', 'rest'];
+
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    // Create and log in a user with administer views permission.
+    $views_admin = $this->drupalCreateUser(['administer views', 'administer blocks', 'bypass node access', 'access user profiles', 'view all revisions']);
+    $this->drupalLogin($views_admin);
+    $this->drupalPlaceBlock('local_actions_block');
+  }
+
+}
diff --git a/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php
new file mode 100644
index 0000000000..0f209cac2e
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Handler/AreaEmptyTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Handler;
+
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Tests the generic entity area handler.
+ *
+ * @group views
+ * @see \Drupal\views\Plugin\views\area\Entity
+ */
+class AreaEmptyTest extends ViewsKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    $this->installEntitySchema('node');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function viewsData() {
+    $data = parent::viewsData();
+    $data['views']['test_example'] = [
+      'title' => 'Test Example area',
+      'help' => 'A area handler which just exists for tests.',
+      'area' => [
+        'id' => 'test_example'
+      ]
+    ];
+
+    return $data;
+  }
+
+  /**
+   * Views used by this test.
+   *
+   * @var array
+   */
+  public static $testViews = ['test_example_area'];
+
+  /**
+   * Tests that the header and footer areas are not rendered if empty.
+   */
+  public function testRenderEmptyHeaderFooter() {
+    $view = Views::getView('test_example_area');
+    $view->initHandlers();
+
+    // Set example empty text.
+    $empty_text = $this->randomMachineName();
+    $empty_header = $this->randomMachineName();
+    $empty_footer = $this->randomMachineName();
+
+    // Set empty text.
+    $view->empty['test_example']->options['string'] = '<p>' . $empty_text . '</p>';
+    // Set example header text.
+    $view->header['test_example']->options['string'] = '<p>' . $empty_header . '</p>';
+    // Set example footer text.
+    $view->footer['test_example']->options['string'] = '<p>' . $empty_footer . '</p>';
+
+    // Verify that the empty header and footer sections have not been rendered.
+    $view->setDisplay('default');
+    $this->executeView($view);
+    $output = $view->render();
+    $output = \Drupal::service('renderer')->renderRoot($output);
+    $this->setRawContent($output);
+    $this->assertText($empty_text);
+    $this->assertNoText($empty_header);
+    $this->assertNoText($empty_footer);
+
+    // Enable displaying the header and footer when the View is empty.
+    $view->header['test_example']->options['empty'] = TRUE;
+    $view->footer['test_example']->options['empty'] = TRUE;
+
+    // Verify that the header and footer sections have been rendered.
+    $this->executeView($view);
+    $output = $view->render();
+    $output = \Drupal::service('renderer')->renderRoot($output);
+    $this->setRawContent($output);
+    $this->assertText($empty_header);
+    $this->assertText($empty_footer);
+  }
+
+}
diff --git a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
similarity index 88%
rename from core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php
rename to core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
index 896b1348dd..6f7154d10c 100644
--- a/core/modules/views/src/Tests/Plugin/DisplayExtenderTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayExtenderTest.php
@@ -1,7 +1,8 @@
 <?php
 
-namespace Drupal\views\Tests\Plugin;
+namespace Drupal\Tests\views\Kernel\Plugin;
 
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
 use Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest as DisplayExtenderTestData;
 use Drupal\views\Views;
 
@@ -11,7 +12,7 @@
  * @group views
  * @see \Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest
  */
-class DisplayExtenderTest extends PluginTestBase {
+class DisplayExtenderTest extends ViewsKernelTestBase {
 
   /**
    * Views used by this test.
@@ -20,12 +21,6 @@ class DisplayExtenderTest extends PluginTestBase {
    */
   public static $testViews = ['test_view'];
 
-  protected function setUp() {
-    parent::setUp();
-
-    $this->enableViewsTestModule();
-  }
-
   /**
    * Test display extenders.
    */
diff --git a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
index 8aaaa2dd5d..3232ecb815 100644
--- a/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
+++ b/core/modules/views/tests/src/Kernel/Plugin/DisplayPageTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Menu\MenuTreeParameters;
 use Drupal\Core\Session\AnonymousUserSession;
+use Drupal\views\Entity\View;
 use Drupal\views\Views;
 use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
 use Symfony\Component\HttpFoundation\Request;
@@ -22,7 +23,7 @@ class DisplayPageTest extends ViewsKernelTestBase {
    *
    * @var array
    */
-  public static $testViews = ['test_page_display', 'test_page_display_route', 'test_page_display_menu'];
+  public static $testViews = ['test_page_display', 'test_page_display_route', 'test_page_display_menu', 'test_display_more'];
 
   /**
    * Modules to enable.
@@ -149,4 +150,71 @@ public function testDependencies() {
     $this->assertIdentical($expected, $view->getDependencies());
   }
 
+  /**
+   * Tests the readmore functionality.
+   */
+  public function testReadMore() {
+    /** @var \Drupal\Core\Render\RendererInterface $renderer */
+    $renderer = $this->container->get('renderer');
+
+    $expected_more_text = 'custom more text';
+
+    $view = Views::getView('test_display_more');
+    $this->executeView($view);
+
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+
+    $this->setRawContent($output);
+    $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']);
+    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
+    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
+
+    // Test the renderMoreLink method directly. This could be directly unit
+    // tested.
+    $more_link = $view->display_handler->renderMoreLink();
+    $more_link = $renderer->renderRoot($more_link);
+    $this->setRawContent($more_link);
+    $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']);
+    $this->assertEqual($result[0]->attributes()->href, \Drupal::url('view.test_display_more.page_1'), 'The right more link is shown.');
+    $this->assertEqual(trim($result[0][0]), $expected_more_text, 'The right link text is shown.');
+
+    // Test the useMoreText method directly. This could be directly unit
+    // tested.
+    $more_text = $view->display_handler->useMoreText();
+    $this->assertEqual($more_text, $expected_more_text, 'The right more text is chosen.');
+
+    $view = Views::getView('test_display_more');
+    $view->setDisplay();
+    $view->display_handler->setOption('use_more', 0);
+    $this->executeView($view);
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+    $this->setRawContent($output);
+    $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']);
+    $this->assertTrue(empty($result), 'The more link is not shown.');
+
+    $view = Views::getView('test_display_more');
+    $view->setDisplay();
+    $view->display_handler->setOption('use_more', 0);
+    $view->display_handler->setOption('use_more_always', 0);
+    $view->display_handler->setOption('pager', [
+      'type' => 'some',
+      'options' => [
+        'items_per_page' => 1,
+        'offset' => 0,
+      ],
+    ]);
+    $this->executeView($view);
+    $output = $view->preview();
+    $output = $renderer->renderRoot($output);
+    $this->setRawContent($output);
+    $result = $this->xpath('//div[@class=:class]/a', [':class' => 'more-link']);
+    $this->assertTrue(empty($result), 'The more link is not shown when view has more records.');
+
+    // Test the default value of use_more_always.
+    $view = View::create()->getExecutable();
+    $this->assertTrue($view->getDisplay()->getOption('use_more_always'), 'Always display the more link by default.');
+  }
+
 }
diff --git a/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
new file mode 100644
index 0000000000..6767fffe3c
--- /dev/null
+++ b/core/modules/views/tests/src/Kernel/Plugin/ExposedFormRenderTest.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\Tests\views\Kernel\Plugin;
+
+use Drupal\Component\Utility\Html;
+use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
+use Drupal\views\Views;
+
+/**
+ * Tests the exposed form markup.
+ *
+ * @group views
+ * @see \Drupal\views_test_data\Plugin\views\display_extender\DisplayExtenderTest
+ */
+class ExposedFormRenderTest extends ViewsKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $testViews = ['test_exposed_form_buttons'];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['node'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp();
+    $this->installEntitySchema('node');
+  }
+
+  /**
+   * Tests the exposed form markup.
+   */
+  public function testExposedFormRender() {
+    $view = Views::getView('test_exposed_form_buttons');
+    $this->executeView($view);
+    $exposed_form = $view->display_handler->getPlugin('exposed_form');
+    $output = $exposed_form->renderExposedForm();
+    $this->setRawContent(\Drupal::service('renderer')->renderRoot($output));
+
+    $this->assertFieldByXpath('//form/@id', Html::cleanCssIdentifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display), 'Expected form ID found.');
+
+    $view->setDisplay('page_1');
+    $expected_action = $view->display_handler->getUrlInfo()->toString();
+    $this->assertFieldByXPath('//form/@action', $expected_action, 'The expected value for the action attribute was found.');
+    // Make sure the description is shown.
+    $result = $this->xpath('//form//div[contains(@id, :id) and normalize-space(text())=:description]', [':id' => 'edit-type--description', ':description' => t('Exposed description')]);
+    $this->assertEqual(count($result), 1, 'Filter description was found.');
+  }
+
+}
diff --git a/core/modules/views/tests/src/Kernel/TestViewsTest.php b/core/modules/views/tests/src/Kernel/TestViewsTest.php
index f9aa673421..dcd1859be3 100644
--- a/core/modules/views/tests/src/Kernel/TestViewsTest.php
+++ b/core/modules/views/tests/src/Kernel/TestViewsTest.php
@@ -34,7 +34,8 @@ public function testDefaultConfig() {
       \Drupal::service('config.storage'),
       new TestInstallStorage(InstallStorage::CONFIG_SCHEMA_DIRECTORY),
       \Drupal::service('cache.discovery'),
-      \Drupal::service('module_handler')
+      \Drupal::service('module_handler'),
+      \Drupal::service('class_resolver')
     );
 
     // Create a configuration storage with access to default configuration in
diff --git a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
index f5a2e39aa0..294bb0f44c 100644
--- a/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
+++ b/core/modules/views/tests/src/Kernel/ViewsConfigDependenciesIntegrationTest.php
@@ -5,6 +5,7 @@
 use Drupal\field\Entity\FieldConfig;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\image\Entity\ImageStyle;
+use Drupal\user\Entity\Role;
 use Drupal\views\Entity\View;
 
 /**
@@ -17,7 +18,7 @@ class ViewsConfigDependenciesIntegrationTest extends ViewsKernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['field', 'file', 'image', 'entity_test'];
+  public static $modules = ['field', 'file', 'image', 'entity_test', 'user', 'text'];
 
   /**
    * {@inheritdoc}
@@ -25,6 +26,16 @@ class ViewsConfigDependenciesIntegrationTest extends ViewsKernelTestBase {
   public static $testViews = ['entity_test_fields'];
 
   /**
+   * {@inheritdoc}
+   */
+  protected function setUp($import_test_views = TRUE) {
+    parent::setUp($import_test_views);
+
+    $this->installEntitySchema('user');
+    $this->installSchema('user', ['users_data']);
+  }
+
+  /**
    * Tests integration with image module.
    */
   public function testImage() {
@@ -69,7 +80,81 @@ public function testImage() {
     // Delete the 'foo' image style.
     $style->delete();
 
+    $view = View::load('entity_test_fields');
+
+    // Checks that the view has not been deleted too.
+    $this->assertNotNull(View::load('entity_test_fields'));
+
+    // Checks that the image field was removed from the View.
+    $display = $view->getDisplay('default');
+    $this->assertFalse(isset($display['display_options']['fields']['bar']));
+
+    // Checks that the view has been disabled.
+    $this->assertFalse($view->status());
+
+    $dependencies = $view->getDependencies() + ['config' => []];
+    // Checks that the dependency on style 'foo' has been removed.
+    $this->assertFalse(in_array('image.style.foo', $dependencies['config']));
+  }
+
+  /**
+   * Tests removing a config dependency that deletes the View.
+   */
+  public function testConfigRemovalRole() {
+    // Create a role we can add to the View and delete.
+    $role = Role::create([
+      'id' => 'dummy',
+      'label' => 'dummy',
+    ]);
+
+    $role->save();
+
+    /** @var \Drupal\views\ViewEntityInterface $view */
+    $view = View::load('entity_test_fields');
+    $display = &$view->getDisplay('default');
+
+    // Set the access to be restricted by the dummy role.
+    $display['display_options']['access'] = [
+      'type' => 'role',
+      'options' => [
+        'role' => [
+          $role->id() => $role->id(),
+        ],
+      ],
+    ];
+    $view->save();
+
+    // Check that the View now has a dependency on the Role.
+    $dependencies = $view->getDependencies() + ['config' => []];
+    $this->assertTrue(in_array('user.role.dummy', $dependencies['config']));
+
+    // Delete the role.
+    $role->delete();
+
+    $view = View::load('entity_test_fields');
+
     // Checks that the view has been deleted too.
+    $this->assertNull($view);
+  }
+
+  /**
+   * Tests uninstalling a module that provides a base table for a View.
+   */
+  public function testConfigRemovalBaseTable() {
+    // Find all the entity types provided by the entity_test module and install
+    // the schema for them so we can uninstall them.
+    $entities = \Drupal::entityTypeManager()->getDefinitions();
+    foreach ($entities as $entity_type_id => $definition) {
+      if ($definition->getProvider() == 'entity_test') {
+        $this->installEntitySchema($entity_type_id);
+      };
+    }
+
+    // Check that removing the module that provides the base table for a View,
+    // deletes the View.
+    $this->assertNotNull(View::load('entity_test_fields'));
+    $this->container->get('module_installer')->uninstall(['entity_test']);
+    // Check that the View has been deleted.
     $this->assertNull(View::load('entity_test_fields'));
   }
 
diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
index 195e3d4e9f..74bcc083e1 100644
--- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
+++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Config\Entity\ConfigEntityType;
 use Drupal\Core\Entity\ContentEntityType;
-use Drupal\Core\Entity\EntityType;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\Sql\DefaultTableMapping;
 use Drupal\Core\Field\BaseFieldDefinition;
@@ -1087,7 +1086,7 @@ public function setEntityType(EntityTypeInterface $entity_type) {
 
 }
 
-class TestEntityType extends EntityType {
+class TestEntityType extends ContentEntityType {
 
   /**
    * Sets a specific entity key.
diff --git a/core/modules/views/views.post_update.php b/core/modules/views/views.post_update.php
index a278034c8a..e09159e7e0 100644
--- a/core/modules/views/views.post_update.php
+++ b/core/modules/views/views.post_update.php
@@ -201,3 +201,15 @@ function views_post_update_boolean_filter_values() {
 function views_post_update_grouped_filters() {
   // Empty update to cause a cache rebuild so that the schema changes are read.
 }
+
+/**
+ * Fix table names for revision metadata fields.
+ */
+function views_post_update_revision_metadata_fields() {
+  // The table names are fixed automatically in
+  // \Drupal\views\Entity\View::preSave(), so we just need to re-save all views.
+  $views = View::loadMultiple();
+  array_walk($views, function(View $view) {
+    $view->save();
+  });
+}
diff --git a/core/modules/workflows/src/Form/WorkflowEditForm.php b/core/modules/workflows/src/Form/WorkflowEditForm.php
index 6b01920ada..764c0c9bc5 100644
--- a/core/modules/workflows/src/Form/WorkflowEditForm.php
+++ b/core/modules/workflows/src/Form/WorkflowEditForm.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\workflows\Form;
 
+use Drupal\Core\Form\SubformState;
+use Drupal\workflows\WorkflowTypeFormInterface;
 use Drupal\workflows\Entity\Workflow;
 use Drupal\workflows\State;
 use Drupal\Core\Entity\EntityForm;
@@ -180,18 +182,42 @@ public function form(array $form, FormStateInterface $form_state) {
       '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
     ];
 
+    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+      $form['type_settings'] = [
+        '#tree' => TRUE,
+      ];
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $form['type_settings'] += $workflow->getTypePlugin()->buildConfigurationForm($form['type_settings'], $subform_state, $workflow);
+    }
+
     return $form;
   }
 
   /**
    * {@inheritdoc}
    */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+    /* @var \Drupal\workflows\WorkflowInterface $workflow */
+    $workflow = $this->entity;
+    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $workflow->getTypePlugin()->validateConfigurationForm($form['type_settings'], $subform_state);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function save(array $form, FormStateInterface $form_state) {
     /* @var \Drupal\workflows\WorkflowInterface $workflow */
     $workflow = $this->entity;
+    if ($workflow->getTypePlugin() instanceof WorkflowTypeFormInterface) {
+      $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
+      $workflow->getTypePlugin()->submitConfigurationForm($form['type_settings'], $subform_state);
+    }
     $workflow->save();
+
     drupal_set_message($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
-    $form_state->setRedirectUrl($workflow->toUrl('collection'));
   }
 
   /**
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
index e87e4d7945..34af735e3d 100644
--- a/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeBase.php
@@ -56,28 +56,28 @@ public function checkWorkflowAccess(WorkflowInterface $entity, $operation, Accou
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function decorateState(StateInterface $state) {
     return $state;
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function deleteState($state_id) {
     unset($this->configuration['states'][$state_id]);
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function decorateTransition(TransitionInterface $transition) {
     return $transition;
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function deleteTransition($transition_id) {
     unset($this->configuration['transitions'][$transition_id]);
@@ -98,14 +98,14 @@ public function buildTransitionConfigurationForm(FormStateInterface $form_state,
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function getConfiguration() {
     return $this->configuration;
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function setConfiguration(array $configuration) {
     $this->configuration = NestedArray::mergeDeep(
@@ -122,7 +122,7 @@ public function getRequiredStates() {
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function defaultConfiguration() {
     return [
@@ -132,7 +132,7 @@ public function defaultConfiguration() {
   }
 
   /**
-   * {@inheritDoc}
+   * {@inheritdoc}
    */
   public function calculateDependencies() {
     return [];
diff --git a/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php b/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php
new file mode 100644
index 0000000000..942c2d6ef4
--- /dev/null
+++ b/core/modules/workflows/src/Plugin/WorkflowTypeFormBase.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Drupal\workflows\Plugin;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\workflows\WorkflowTypeFormInterface;
+
+/**
+ * Provides a base class for configurable workflow types.
+ *
+ * @see \Drupal\workflows\WorkflowTypeFormInterface
+ * @see \Drupal\workflows\WorkflowTypeInterface
+ * @see \Drupal\workflows\Plugin\WorkflowTypeBase
+ * @see plugin_api
+ */
+abstract class WorkflowTypeFormBase extends WorkflowTypeBase implements WorkflowTypeFormInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+  }
+
+}
diff --git a/core/modules/workflows/src/WorkflowInterface.php b/core/modules/workflows/src/WorkflowInterface.php
index d156918a6f..4f241c34f8 100644
--- a/core/modules/workflows/src/WorkflowInterface.php
+++ b/core/modules/workflows/src/WorkflowInterface.php
@@ -273,7 +273,7 @@ public function deleteTransition($transition_id);
   /**
    * Gets the workflow type plugin.
    *
-   * @return \Drupal\workflows\WorkflowTypeInterface
+   * @return \Drupal\workflows\WorkflowTypeInterface|\Drupal\workflows\WorkflowTypeFormInterface
    *   The workflow type plugin.
    */
   public function getTypePlugin();
diff --git a/core/modules/workflows/src/WorkflowTypeFormInterface.php b/core/modules/workflows/src/WorkflowTypeFormInterface.php
new file mode 100644
index 0000000000..7da4bd9fb3
--- /dev/null
+++ b/core/modules/workflows/src/WorkflowTypeFormInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Drupal\workflows;
+
+use Drupal\Core\Plugin\PluginFormInterface;
+
+/**
+ * Defines the interface for configurable workflow types.
+ *
+ * @see \Drupal\workflows\Plugin\WorkflowTypeFormBase
+ * @see \Drupal\workflows\WorkflowTypeInterface
+ * @see \Drupal\Core\Plugin\PluginFormInterface
+ * @see plugin_api
+ */
+interface WorkflowTypeFormInterface extends PluginFormInterface, WorkflowTypeInterface {
+}
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml b/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml
index 84e7a4169e..1502edc04e 100644
--- a/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml
+++ b/core/modules/workflows/tests/modules/workflow_type_test/config/schema/workflow_type_test.schema.yml
@@ -20,6 +20,9 @@ workflow.type_settings.workflow_type_complex_test:
   type: mapping
   label: 'Workflow complex test type settings'
   mapping:
+    example_setting:
+      type: string
+      label: 'Example setting'
     states:
       type: sequence
       label: 'Additional state configuration'
diff --git a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
index a254a4f31f..2cc25afcd6 100644
--- a/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
+++ b/core/modules/workflows/tests/modules/workflow_type_test/src/Plugin/WorkflowType/ComplexTestType.php
@@ -4,7 +4,7 @@
 
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\workflows\Plugin\WorkflowTypeBase;
+use Drupal\workflows\Plugin\WorkflowTypeFormBase;
 use Drupal\workflows\StateInterface;
 use Drupal\workflows\TransitionInterface;
 use Drupal\workflows\WorkflowInterface;
@@ -19,7 +19,7 @@
  *   label = @Translation("Workflow Type Complex Test"),
  * )
  */
-class ComplexTestType extends WorkflowTypeBase {
+class ComplexTestType extends WorkflowTypeFormBase {
 
   use StringTranslationTrait;
 
@@ -88,4 +88,33 @@ public function onDependencyRemoval(array $dependencies) {
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return parent::defaultConfiguration() + [
+      'example_setting' => '',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form['example_setting'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Example global workflow setting'),
+      '#description' => $this->t('Extra information added to the workflow'),
+      '#default_value' => $this->configuration['example_setting'],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $this->configuration['example_setting'] = $form_state->getValue('example_setting');
+  }
+
 }
diff --git a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
index 077501cd6e..0411915716 100644
--- a/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
+++ b/core/modules/workflows/tests/src/Functional/WorkflowUiTest.php
@@ -176,9 +176,8 @@ public function testWorkflowCreation() {
     $workflow = $workflow_storage->loadUnchanged('test');
     $this->assertEquals('draft', $workflow->getTypePlugin()->getInitialState($workflow)->id());
 
-    // This will take us to the list of workflows, so we need to edit the
-    // workflow again.
-    $this->clickLink('Edit');
+    // Verify that we are still on the workflow edit page.
+    $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test');
 
     // Ensure that weight changes the transition ordering.
     $this->assertEquals(['publish', 'create_new_draft'], array_keys($workflow->getTransitions()));
@@ -187,9 +186,8 @@ public function testWorkflowCreation() {
     $workflow = $workflow_storage->loadUnchanged('test');
     $this->assertEquals(['create_new_draft', 'publish'], array_keys($workflow->getTransitions()));
 
-    // This will take us to the list of workflows, so we need to edit the
-    // workflow again.
-    $this->clickLink('Edit');
+    // Verify that we are still on the workflow edit page.
+    $this->assertSession()->addressEquals('admin/config/workflow/workflows/manage/test');
 
     // Ensure that a delete link for the published state exists before deleting
     // the draft state.
@@ -253,6 +251,28 @@ public function testWorkflowCreation() {
   }
 
   /**
+   * Test the workflow configuration form.
+   */
+  public function testWorkflowConfigurationForm() {
+    $workflow = Workflow::create(['id' => 'test', 'type' => 'workflow_type_complex_test', 'label' => 'Test']);
+    $workflow
+      ->addState('published', 'Published')
+      ->addTransition('publish', 'Publish', ['published'], 'published')
+      ->save();
+
+    $this->drupalLogin($this->createUser(['administer workflows']));
+
+    // Add additional information to the workflow via the configuration form.
+    $this->drupalGet('admin/config/workflow/workflows/manage/test');
+    $this->assertSession()->pageTextContains('Example global workflow setting');
+    $this->submitForm(['type_settings[example_setting]' => 'Extra global settings'], 'Save');
+
+    $workflow_storage = $this->container->get('entity_type.manager')->getStorage('workflow');
+    $workflow = $workflow_storage->loadUnchanged('test');
+    $this->assertEquals('Extra global settings', $workflow->getTypePlugin()->getConfiguration()['example_setting']);
+  }
+
+  /**
    * Tests that workflow types can add form fields to states and transitions.
    */
   public function testWorkflowDecoration() {
diff --git a/core/modules/workflows/tests/src/Unit/StateTest.php b/core/modules/workflows/tests/src/Unit/StateTest.php
index 82feca3462..ae9fc46202 100644
--- a/core/modules/workflows/tests/src/Unit/StateTest.php
+++ b/core/modules/workflows/tests/src/Unit/StateTest.php
@@ -27,6 +27,9 @@ protected function setUp() {
     // mocked.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_type->deleteState(Argument::any())->willReturn(NULL);
diff --git a/core/modules/workflows/tests/src/Unit/TransitionTest.php b/core/modules/workflows/tests/src/Unit/TransitionTest.php
index 3202e8a466..c343fed927 100644
--- a/core/modules/workflows/tests/src/Unit/TransitionTest.php
+++ b/core/modules/workflows/tests/src/Unit/TransitionTest.php
@@ -27,6 +27,9 @@ protected function setUp() {
     // mocked.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
diff --git a/core/modules/workflows/tests/src/Unit/WorkflowTest.php b/core/modules/workflows/tests/src/Unit/WorkflowTest.php
index e2f2db7be3..51cb912070 100644
--- a/core/modules/workflows/tests/src/Unit/WorkflowTest.php
+++ b/core/modules/workflows/tests/src/Unit/WorkflowTest.php
@@ -27,6 +27,9 @@ protected function setUp() {
     // mocked.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_manager = $this->prophesize(WorkflowTypeManager::class);
@@ -215,6 +218,9 @@ public function testDeleteState() {
     // correctly.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_type->deleteState('draft')->shouldBeCalled();
@@ -617,6 +623,9 @@ public function testDeleteTransition() {
     // correctly.
     $container = new ContainerBuilder();
     $workflow_type = $this->prophesize(WorkflowTypeInterface::class);
+    $workflow_type->setConfiguration(Argument::any())->will(function ($arguments) {
+      $this->getConfiguration()->willReturn($arguments[0]);
+    });
     $workflow_type->decorateState(Argument::any())->willReturnArgument(0);
     $workflow_type->decorateTransition(Argument::any())->willReturnArgument(0);
     $workflow_type->deleteTransition('publish')->shouldBeCalled();
diff --git a/core/package.json b/core/package.json
index b168cb374d..0ea5c8a247 100644
--- a/core/package.json
+++ b/core/package.json
@@ -5,19 +5,39 @@
   "private": true,
   "scripts": {
     "build:js": "node ./scripts/js/babel-es6-build.js",
-    "watch:js": "node ./scripts/js/babel-es6-watch.js",
-    "lint:js": "eslint . || exit 0"
+    "watch:js": "cross-env NODE_ENV=development node ./scripts/js/babel-es6-watch.js",
+    "lint:core-js": "node ./node_modules/eslint/bin/eslint.js --ext=.es6.js . --fix || exit 0"
   },
   "devDependencies": {
-    "babel-core": "6.17.0",
-    "babel-preset-es2015": "6.16.0",
-    "chokidar": "1.6.0",
-    "eslint": "3.8.1",
-    "glob": "^7.1.1"
+    "babel-core": "6.24.1",
+    "babel-preset-env": "1.4.0",
+    "chokidar": "1.6.1",
+    "cross-env": "^4.0.0",
+    "eslint": "3.19.0",
+    "eslint-config-airbnb": "14.1.0",
+    "eslint-plugin-import": "2.2.0",
+    "eslint-plugin-jsx-a11y": "4.0.0",
+    "eslint-plugin-react": "6.10.3",
+    "glob": "7.1.1"
   },
   "babel": {
     "presets": [
-      "es2015"
+      [
+        "env",
+        {
+          "modules": false,
+          "targets": {
+            "browsers": [
+              "ie >= 9",
+              "edge >= 13",
+              "firefox >= 5",
+              "opera >= 12",
+              "safari >= 5",
+              "chrome >= 56"
+            ]
+          }
+        }
+      ]
     ]
   }
 }
diff --git a/core/phpunit.xml.dist b/core/phpunit.xml.dist
index ef1ae3b6fa..c85258d77f 100644
--- a/core/phpunit.xml.dist
+++ b/core/phpunit.xml.dist
@@ -45,6 +45,8 @@
     </testsuite>
   </testsuites>
   <listeners>
+    <listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
+    </listener>
     <listener class="\Drupal\Tests\Listeners\DrupalStandardsListener">
     </listener>
   </listeners>
diff --git a/core/scripts/js/babel-es6-build.js b/core/scripts/js/babel-es6-build.js
index e073f6a431..0178d44ec5 100644
--- a/core/scripts/js/babel-es6-build.js
+++ b/core/scripts/js/babel-es6-build.js
@@ -11,44 +11,32 @@
 
 const fs = require('fs');
 const path = require('path');
-const babel = require('babel-core');
 const glob = require('glob');
 
-// Logging human-readable timestamp.
-const log = function (message) {
-  // eslint-disable-next-line no-console
-  console.log(`[${new Date().toTimeString().slice(0, 8)}] ${message}`);
-};
-
-function addSourceMappingUrl(code, loc) {
-  return code + '\n\n//# sourceMappingURL=' + path.basename(loc);
-}
-
-const changedOrAdded = (filePath) => {
-  babel.transformFile(filePath, {
-    sourceMaps: true,
-    comments: false
-  }, function (err, result) {
-    const fileName = filePath.slice(0, -7);
-    // we've requested for a sourcemap to be written to disk
-    let mapLoc = `${fileName}.js.map`;
-
-    fs.writeFile(mapLoc, JSON.stringify(result.map));
-    fs.writeFile(`${fileName}.js`, addSourceMappingUrl(result.code, mapLoc));
-
-    log(`'${filePath}' is being processed.`);
-  });
-};
+const changeOrAdded = require('./changeOrAdded');
+const log = require('./log');
 
+// Match only on .es6.js files.
 const fileMatch = './**/*.es6.js';
+// Ignore everything in node_modules
 const globOptions = {
-  ignore: 'node_modules/**'
+  ignore: './node_modules/**'
 };
 const processFiles = (error, filePaths) => {
   if (error) {
     process.exitCode = 1;
   }
-  filePaths.forEach(changedOrAdded);
+  // Process all the found files.
+  filePaths.forEach(changeOrAdded);
 };
-glob(fileMatch, globOptions, processFiles);
+
+// Run build:js with some special arguments to only parse specific files.
+// npm run build:js -- --files misc/drupal.es6.js misc/drupal.init.es6.js
+// Only misc/drupal.es6.js misc/drupal.init.es6.js will be processed.
+if (process.argv.length > 2 && process.argv[2] === '--files') {
+  processFiles(null, process.argv.splice(3, process.argv.length));
+}
+else {
+  glob(fileMatch, globOptions, processFiles);
+}
 process.exitCode = 0;
diff --git a/core/scripts/js/babel-es6-watch.js b/core/scripts/js/babel-es6-watch.js
index d614774f29..9b49482236 100644
--- a/core/scripts/js/babel-es6-watch.js
+++ b/core/scripts/js/babel-es6-watch.js
@@ -11,50 +11,29 @@
 
 const fs = require('fs');
 const path = require('path');
-const babel = require('babel-core');
 const chokidar = require('chokidar');
 
-// Logging human-readable timestamp.
-const log = function log(message) {
-  // eslint-disable-next-line no-console
-  console.log(`[${new Date().toTimeString().slice(0, 8)}] ${message}`);
-};
-
-function addSourceMappingUrl(code, loc) {
-  return `${code}\n\n//# sourceMappingURL=${path.basename(loc)}`;
-}
+const changeOrAdded = require('./changeOrAdded');
+const log = require('./log');
 
+// Match only on .es6.js files.
 const fileMatch = './**/*.es6.js';
+// Ignore everything in node_modules
 const watcher = chokidar.watch(fileMatch, {
   ignoreInitial: true,
-  ignored: 'node_modules/**'
+  ignored: './node_modules/**'
 });
 
-const changedOrAdded = (filePath) => {
-  babel.transformFile(filePath, {
-    sourceMaps: true,
-    comments: false
-  }, (err, result) => {
-    const fileName = filePath.slice(0, -7);
-    // we've requested for a sourcemap to be written to disk
-    const mapLoc = `${fileName}.js.map`;
-
-    fs.writeFileSync(mapLoc, JSON.stringify(result.map));
-    fs.writeFileSync(`${fileName}.js`, addSourceMappingUrl(result.code, mapLoc));
-
-    log(`'${filePath}' has been changed.`);
-  });
-};
-
 const unlinkHandler = (err) => {
   if (err) {
     log(err);
   }
 };
 
+// Watch for filesystem changes.
 watcher
-  .on('add', filePath => changedOrAdded(filePath))
-  .on('change', filePath => changedOrAdded(filePath))
+  .on('add', changeOrAdded)
+  .on('change', changeOrAdded)
   .on('unlink', (filePath) => {
     const fileName = filePath.slice(0, -7);
     fs.stat(`${fileName}.js`, () => {
diff --git a/core/scripts/js/changeOrAdded.js b/core/scripts/js/changeOrAdded.js
new file mode 100644
index 0000000000..1f8b1ee128
--- /dev/null
+++ b/core/scripts/js/changeOrAdded.js
@@ -0,0 +1,28 @@
+const fs = require('fs');
+const babel = require('babel-core');
+
+const log = require('./log');
+
+module.exports = (filePath) => {
+  const moduleName = filePath.slice(0, -7);
+  log(`'${filePath}' is being processed.`);
+  // Transform the file.
+  // Check process.env.NODE_ENV to see if we should create sourcemaps.
+  babel.transformFile(
+    filePath,
+    {
+      sourceMaps: process.env.NODE_ENV === 'development' ? 'inline' : false,
+      comments: false
+    },
+    (err, result) => {
+      if (err) {
+        throw new Error(err);
+      }
+      const fileName = filePath.slice(0, -7);
+      // Write the result to the filesystem.
+      fs.writeFile(`${fileName}.js`, result.code, () => {
+        log(`'${filePath}' is finished.`);
+      });
+    }
+  );
+}
diff --git a/core/scripts/js/log.js b/core/scripts/js/log.js
new file mode 100644
index 0000000000..08349b3ae3
--- /dev/null
+++ b/core/scripts/js/log.js
@@ -0,0 +1,4 @@
+module.exports = (message) => {
+  // Logging human-readable timestamp.
+  console.log(`[${new Date().toTimeString().slice(0, 8)}] ${message}`);
+}
diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh
index 4eea3cb6b7..09a7aad57c 100755
--- a/core/scripts/run-tests.sh
+++ b/core/scripts/run-tests.sh
@@ -17,6 +17,7 @@
 use Drupal\simpletest\Form\SimpletestResultsForm;
 use Drupal\simpletest\TestBase;
 use Drupal\simpletest\TestDiscovery;
+use PHPUnit\Framework\TestCase;
 use Symfony\Component\HttpFoundation\Request;
 
 $autoloader = require_once __DIR__ . '/../../autoload.php';
@@ -36,7 +37,7 @@
 const SIMPLETEST_SCRIPT_EXIT_FAILURE = 1;
 const SIMPLETEST_SCRIPT_EXIT_EXCEPTION = 2;
 
-if (!class_exists('\PHPUnit_Framework_TestCase')) {
+if (!class_exists(TestCase::class)) {
   echo "\nrun-tests.sh requires the PHPUnit testing framework. Please use 'composer install --dev' to ensure that it is present.\n\n";
   exit(SIMPLETEST_SCRIPT_EXIT_FAILURE);
 }
@@ -783,7 +784,7 @@ function simpletest_script_run_one_test($test_id, $test_class) {
       $methods = array();
     }
     $test = new $class_name($test_id);
-    if (is_subclass_of($test_class, '\PHPUnit_Framework_TestCase')) {
+    if (is_subclass_of($test_class, TestCase::class)) {
       $status = simpletest_script_run_phpunit($test_id, $test_class);
     }
     else {
@@ -865,7 +866,7 @@ function simpletest_script_command($test_id, $test_class) {
  * @see simpletest_script_run_one_test()
  */
 function simpletest_script_cleanup($test_id, $test_class, $exitcode) {
-  if (is_subclass_of($test_class, '\PHPUnit_Framework_TestCase')) {
+  if (is_subclass_of($test_class, TestCase::class)) {
     // PHPUnit test, move on.
     return;
   }
@@ -1020,7 +1021,7 @@ function simpletest_script_get_test_list() {
         else {
           foreach ($matches[1] as $class_name) {
             $namespace_class = $namespace . '\\' . $class_name;
-            if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, '\PHPUnit_Framework_TestCase')) {
+            if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, TestCase::class)) {
               $test_list[] = $namespace_class;
             }
           }
@@ -1074,7 +1075,7 @@ function simpletest_script_get_test_list() {
         else {
           foreach ($matches[1] as $class_name) {
             $namespace_class = $namespace . '\\' . $class_name;
-            if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, '\PHPUnit_Framework_TestCase')) {
+            if (is_subclass_of($namespace_class, '\Drupal\simpletest\TestBase') || is_subclass_of($namespace_class, TestCase::class)) {
               $test_list[] = $namespace_class;
             }
           }
diff --git a/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php b/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php
index c29324a013..c8748342fb 100644
--- a/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php
+++ b/core/tests/Drupal/FunctionalTests/HttpKernel/CorsIntegrationTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\FunctionalTests\HttpKernel;
 
+use Drupal\Core\Url;
 use Drupal\Tests\BrowserTestBase;
 
 /**
@@ -72,6 +73,19 @@ public function testCrossSiteRequest() {
     $this->drupalGet('/test-page', [], ['Origin' => 'http://example.com']);
     $this->assertSession()->statusCodeEquals(200);
     $this->assertSession()->responseHeaderEquals('Access-Control-Allow-Origin', 'http://example.com');
+
+    // Verify POST still functions with 'Origin' header set to site's domain.
+    $origin = \Drupal::request()->getSchemeAndHttpHost();
+
+    /** @var \GuzzleHttp\ClientInterface $httpClient */
+    $httpClient = $this->getSession()->getDriver()->getClient()->getClient();
+    $url = Url::fromUri('base:/test-page');
+    $response = $httpClient->request('POST', $url->setAbsolute()->toString(), [
+      'headers' => [
+        'Origin' => $origin,
+      ]
+    ]);
+    $this->assertEquals(200, $response->getStatusCode());
   }
 
 }
diff --git a/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php b/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php
new file mode 100644
index 0000000000..8ef9db4229
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Theme/BartikTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\FunctionalTests\Theme;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the Bartik theme.
+ *
+ * @group bartik
+ */
+class BartikTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->assertTrue($this->container->get('theme_installer')->install(['bartik']));
+    $this->container->get('config.factory')
+      ->getEditable('system.theme')
+      ->set('default', 'bartik')
+      ->save();
+  }
+
+  /**
+   * Tests that the Bartik theme always adds its message CSS and Classy's.
+   *
+   * @see bartik.libraries.yml
+   * @see classy.info.yml
+   */
+  public function testRegressionMissingMessagesCss() {
+    $this->drupalGet('');
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->responseContains('bartik/css/components/messages.css');
+    $this->assertSession()->responseContains('classy/css/components/messages.css');
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php b/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php
new file mode 100644
index 0000000000..dca624e4e6
--- /dev/null
+++ b/core/tests/Drupal/FunctionalTests/Theme/ClassyTest.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\FunctionalTests\Theme;
+
+use Drupal\Tests\BrowserTestBase;
+
+/**
+ * Tests the classy theme.
+ *
+ * @group classy
+ */
+class ClassyTest extends BrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->assertTrue($this->container->get('theme_installer')->install(['classy']));
+    $this->container->get('config.factory')
+      ->getEditable('system.theme')
+      ->set('default', 'classy')
+      ->save();
+  }
+
+  /**
+   * Tests that the Classy theme always adds its message CSS.
+   *
+   * @see classy.info.yml
+   */
+  public function testRegressionMissingMessagesCss() {
+    $this->drupalGet('');
+    $this->assertSession()->statusCodeEquals(200);
+    $this->assertSession()->responseContains('classy/css/components/messages.css');
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/AssertLegacyTrait.php b/core/tests/Drupal/KernelTests/AssertLegacyTrait.php
index 1d1816aa9c..f63c4bf0b6 100644
--- a/core/tests/Drupal/KernelTests/AssertLegacyTrait.php
+++ b/core/tests/Drupal/KernelTests/AssertLegacyTrait.php
@@ -6,7 +6,7 @@
  * Translates Simpletest assertion methods to PHPUnit.
  *
  * Protected methods are custom. Public static methods override methods of
- * \PHPUnit_Framework_Assert.
+ * \PHPUnit\Framework\Assert.
  *
  * @deprecated Scheduled for removal in Drupal 9.0.0. Use PHPUnit's native
  *   assert methods instead.
diff --git a/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php
new file mode 100644
index 0000000000..06881f2564
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Config/TypedConfigTest.php
@@ -0,0 +1,165 @@
+<?php
+
+namespace Drupal\KernelTests\Config;
+
+use Drupal\Core\Config\Schema\SequenceDataDefinition;
+use Drupal\Core\Config\Schema\TypedConfigInterface;
+use Drupal\Core\TypedData\ComplexDataDefinitionInterface;
+use Drupal\Core\TypedData\ComplexDataInterface;
+use Drupal\Core\TypedData\Type\IntegerInterface;
+use Drupal\Core\TypedData\Type\StringInterface;
+use Drupal\KernelTests\KernelTestBase;
+use Symfony\Component\Validator\ConstraintViolationListInterface;
+
+/**
+ * Tests config validation mechanism.
+ *
+ * @group Config
+ */
+class TypedConfigTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['config_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig('config_test');
+  }
+
+  /**
+   * Verifies that the Typed Data API is implemented correctly.
+   */
+  public function testTypedDataAPI() {
+    /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
+    $typed_config_manager = \Drupal::service('config.typed');
+    /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
+    $typed_config = $typed_config_manager->get('config_test.validation');
+
+    // Test a primitive.
+    $string_data = $typed_config->get('llama');
+    $this->assertInstanceOf(StringInterface::class, $string_data);
+    $this->assertEquals('llama', $string_data->getValue());
+
+    // Test complex data.
+    $mapping = $typed_config->get('cat');
+    /** @var \Drupal\Core\TypedData\ComplexDataInterface $mapping */
+    $this->assertInstanceOf(ComplexDataInterface::class, $mapping);
+    $this->assertInstanceOf(StringInterface::class, $mapping->get('type'));
+    $this->assertEquals('kitten', $mapping->get('type')->getValue());
+    $this->assertInstanceOf(IntegerInterface::class, $mapping->get('count'));
+    $this->assertEquals(2, $mapping->get('count')->getValue());
+    // Verify the item metadata is available.
+    $this->assertInstanceOf(ComplexDataDefinitionInterface::class, $mapping->getDataDefinition());
+    $this->assertArrayHasKey('type', $mapping->getProperties());
+    $this->assertArrayHasKey('count', $mapping->getProperties());
+
+    // Test accessing sequences.
+    $sequence = $typed_config->get('giraffe');
+    /** @var \Drupal\Core\TypedData\ListInterface $sequence */
+    $this->assertInstanceOf(ComplexDataInterface::class, $sequence);
+    $this->assertInstanceOf(StringInterface::class, $sequence->get('hum1'));
+    $this->assertEquals('hum1', $sequence->get('hum1')->getValue());
+    $this->assertEquals('hum2', $sequence->get('hum2')->getValue());
+    $this->assertEquals(2, count($sequence->getIterator()));
+    // Verify the item metadata is available.
+    $this->assertInstanceOf(SequenceDataDefinition::class, $sequence->getDataDefinition());
+
+    // Test accessing typed config objects for simple config and config
+    // entities.
+    $typed_config_manager = \Drupal::service('config.typed');
+    $typed_config = $typed_config_manager->createFromNameAndData('config_test.validation', \Drupal::configFactory()->get('config_test.validation')->get());
+    $this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
+    $this->assertEquals(['llama', 'cat', 'giraffe', 'uuid', '_core'], array_keys($typed_config->getElements()));
+
+    $config_test_entity = \Drupal::entityTypeManager()->getStorage('config_test')->create([
+      'id' => 'asterix',
+      'label' => 'Asterix',
+      'weight' => 11,
+      'style' => 'test_style',
+    ]);
+
+    $typed_config = $typed_config_manager->createFromNameAndData($config_test_entity->getConfigDependencyName(), $config_test_entity->toArray());
+    $this->assertInstanceOf(TypedConfigInterface::class, $typed_config);
+    $this->assertEquals(['uuid', 'langcode', 'status', 'dependencies', 'id', 'label', 'weight', 'style', 'size', 'size_value', 'protected_property'], array_keys($typed_config->getElements()));
+  }
+
+  /**
+   * Tests config validation via the Typed Data API.
+   */
+  public function testSimpleConfigValidation() {
+    $config = \Drupal::configFactory()->getEditable('config_test.validation');
+    /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager */
+    $typed_config_manager = \Drupal::service('config.typed');
+    /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
+    $typed_config = $typed_config_manager->get('config_test.validation');
+
+    $result = $typed_config->validate();
+    $this->assertInstanceOf(ConstraintViolationListInterface::class, $result);
+    $this->assertEmpty($result);
+
+    // Test constraints on primitive types.
+    $config->set('llama', 'elephant');
+    $config->save();
+
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $result = $typed_config->validate();
+    // Its not a valid llama anymore.
+    $this->assertCount(1, $result);
+    $this->assertEquals('no valid llama', $result->get(0)->getMessage());
+
+    // Test constraints on mapping.
+    $config->set('llama', 'llama');
+    $config->set('cat.type', 'nyans');
+    $config->save();
+
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $result = $typed_config->validate();
+    $this->assertEmpty($result);
+
+    // Test constrains on nested mapping.
+    $config->set('cat.type', 'miaus');
+    $config->save();
+
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $result = $typed_config->validate();
+    $this->assertCount(1, $result);
+    $this->assertEquals('no valid cat', $result->get(0)->getMessage());
+
+    // Test constrains on sequences elements.
+    $config->set('cat.type', 'nyans');
+    $config->set('giraffe', ['muh', 'hum2']);
+    $config->save();
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $result = $typed_config->validate();
+    $this->assertCount(1, $result);
+    $this->assertEquals('Giraffes just hum', $result->get(0)->getMessage());
+
+    // Test constrains on the sequence itself.
+    $config->set('giraffe', ['hum', 'hum2', 'invalid-key' => 'hum']);
+    $config->save();
+
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $result = $typed_config->validate();
+    $this->assertCount(1, $result);
+    $this->assertEquals('giraffe', $result->get(0)->getPropertyPath());
+    $this->assertEquals('Invalid giraffe key.', $result->get(0)->getMessage());
+
+    // Validates mapping.
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $value = $typed_config->getValue();
+    unset($value['giraffe']);
+    $value['elephant'] = 'foo';
+    $typed_config->setValue($value);
+    $result = $typed_config->validate();
+    $this->assertCount(1, $result);
+    $this->assertEquals('', $result->get(0)->getPropertyPath());
+    $this->assertEquals('Missing giraffe.', $result->get(0)->getMessage());
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
index 1cd141436e..e2e02e1dc8 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigSchemaTest.php
@@ -47,6 +47,7 @@ public function testSchemaMapping() {
     $expected['class'] = Undefined::class;
     $expected['type'] = 'undefined';
     $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for nonexistent configuration.');
 
     // Configuration file without schema will return Undefined as well.
@@ -67,6 +68,7 @@ public function testSchemaMapping() {
     $expected['mapping']['testlist'] = ['label' => 'Test list'];
     $expected['type'] = 'config_schema_test.someschema';
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for configuration with only some schema.');
 
     // Check type detection on elements with undefined types.
@@ -77,6 +79,7 @@ public function testSchemaMapping() {
     $expected['class'] = Undefined::class;
     $expected['type'] = 'undefined';
     $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Automatic type detected for a scalar is undefined.');
     $definition = $config->get('testlist')->getDataDefinition()->toArray();
     $expected = [];
@@ -84,6 +87,7 @@ public function testSchemaMapping() {
     $expected['class'] = Undefined::class;
     $expected['type'] = 'undefined';
     $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Automatic type detected for a list is undefined.');
     $definition = $config->get('testnoschema')->getDataDefinition()->toArray();
     $expected = [];
@@ -91,6 +95,7 @@ public function testSchemaMapping() {
     $expected['class'] = Undefined::class;
     $expected['type'] = 'undefined';
     $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Automatic type detected for an undefined integer is undefined.');
 
     // Simple case, straight metadata.
@@ -109,6 +114,7 @@ public function testSchemaMapping() {
     $expected['mapping']['_core']['type'] = '_core_config_info';
     $expected['type'] = 'system.maintenance';
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for system.maintenance');
 
     // Mixed schema with ignore elements.
@@ -139,6 +145,7 @@ public function testSchemaMapping() {
       'type' => 'integer',
     ];
     $expected['type'] = 'config_schema_test.ignore';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
 
     $this->assertEqual($definition, $expected);
 
@@ -149,6 +156,7 @@ public function testSchemaMapping() {
     $expected['label'] = 'Irrelevant';
     $expected['class'] = Ignore::class;
     $expected['definition_class'] = '\Drupal\Core\TypedData\DataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $this->assertEqual($definition, $expected);
     $definition = \Drupal::service('config.typed')->get('config_schema_test.ignore')->get('indescribable')->getDataDefinition()->toArray();
     $expected['label'] = 'Indescribable';
@@ -160,8 +168,9 @@ public function testSchemaMapping() {
     $expected['label'] = 'Image style';
     $expected['class'] = Mapping::class;
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $expected['mapping']['name']['type'] = 'string';
-    $expected['mapping']['uuid']['type'] = 'string';
+    $expected['mapping']['uuid']['type'] = 'uuid';
     $expected['mapping']['uuid']['label'] = 'UUID';
     $expected['mapping']['langcode']['type'] = 'string';
     $expected['mapping']['langcode']['label'] = 'Language code';
@@ -177,7 +186,7 @@ public function testSchemaMapping() {
     $expected['mapping']['effects']['sequence']['mapping']['id']['type'] = 'string';
     $expected['mapping']['effects']['sequence']['mapping']['data']['type'] = 'image.effect.[%parent.id]';
     $expected['mapping']['effects']['sequence']['mapping']['weight']['type'] = 'integer';
-    $expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'string';
+    $expected['mapping']['effects']['sequence']['mapping']['uuid']['type'] = 'uuid';
     $expected['mapping']['third_party_settings']['type'] = 'sequence';
     $expected['mapping']['third_party_settings']['label'] = 'Third party settings';
     $expected['mapping']['third_party_settings']['sequence']['type'] = '[%parent.%parent.%type].third_party.[%key]';
@@ -193,6 +202,7 @@ public function testSchemaMapping() {
     $expected['label'] = 'Image scale';
     $expected['class'] = Mapping::class;
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $expected['mapping']['width']['type'] = 'integer';
     $expected['mapping']['width']['label'] = 'Width';
     $expected['mapping']['height']['type'] = 'integer';
@@ -220,6 +230,7 @@ public function testSchemaMapping() {
     $expected['label'] = 'Mapping';
     $expected['class'] = Mapping::class;
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $expected['mapping'] = [
       'integer' => ['type' => 'integer'],
       'string' => ['type' => 'string'],
@@ -241,6 +252,7 @@ public function testSchemaMapping() {
     $expected['mapping']['testdescription']['label'] = 'Description';
     $expected['type'] = 'config_schema_test.someschema.somemodule.*.*';
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
 
     $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_schema_test.someschema.somemodule.section_one.subsection');
 
@@ -263,6 +275,7 @@ public function testSchemaMappingWithParents() {
       'label' => 'Test item nested one level',
       'class' => StringData::class,
       'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
+      'unwrap_for_canonical_representation' => TRUE,
     ];
     $this->assertEqual($definition, $expected);
 
@@ -274,6 +287,7 @@ public function testSchemaMappingWithParents() {
       'label' => 'Test item nested two levels',
       'class' => StringData::class,
       'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
+      'unwrap_for_canonical_representation' => TRUE,
     ];
     $this->assertEqual($definition, $expected);
 
@@ -285,6 +299,7 @@ public function testSchemaMappingWithParents() {
       'label' => 'Test item nested three levels',
       'class' => StringData::class,
       'definition_class' => '\Drupal\Core\TypedData\DataDefinition',
+      'unwrap_for_canonical_representation' => TRUE,
     ];
     $this->assertEqual($definition, $expected);
   }
@@ -396,6 +411,76 @@ public function testConfigSaveWithSchema() {
   }
 
   /**
+   * Tests configuration sequence sorting using schemas.
+   */
+  public function testConfigSaveWithSequenceSorting() {
+    $data = [
+      'keyed_sort' => [
+        'b' => '1',
+        'a' => '2',
+      ],
+      'no_sort' => [
+        'b' => '2',
+        'a' => '1',
+      ],
+    ];
+    // Save config which has a schema that enforces sorting.
+    $this->config('config_schema_test.schema_sequence_sort')
+      ->setData($data)
+      ->save();
+    $this->assertSame(['a' => '2', 'b' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('keyed_sort'));
+    $this->assertSame(['b' => '2', 'a' => '1'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
+
+    $data = [
+      'value_sort' => ['b', 'a'],
+      'no_sort' => ['b', 'a'],
+    ];
+    // Save config which has a schema that enforces sorting.
+    $this->config('config_schema_test.schema_sequence_sort')
+      ->setData($data)
+      ->save();
+
+    $this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
+    $this->assertSame(['b', 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
+
+    // Value sort does not preserve keys - this is intentional.
+    $data = [
+      'value_sort' => [1 => 'b', 2 => 'a'],
+      'no_sort' => [1 => 'b', 2 => 'a'],
+    ];
+    // Save config which has a schema that enforces sorting.
+    $this->config('config_schema_test.schema_sequence_sort')
+      ->setData($data)
+      ->save();
+
+    $this->assertSame(['a', 'b'], $this->config('config_schema_test.schema_sequence_sort')->get('value_sort'));
+    $this->assertSame([1 => 'b', 2 => 'a'], $this->config('config_schema_test.schema_sequence_sort')->get('no_sort'));
+
+    // Test sorts do not destroy complex values.
+    $data = [
+      'complex_sort_value' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
+      'complex_sort_key' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
+    ];
+    $this->config('config_schema_test.schema_sequence_sort')
+      ->setData($data)
+      ->save();
+    $this->assertSame([['foo' => 'a', 'bar' => 'a'], ['foo' => 'b', 'bar' => 'b']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
+    $this->assertSame(['a' => ['foo' => '2', 'bar' => '2'], 'b' => ['foo' => '1', 'bar' => '1']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
+
+    // Swap the previous test scenario around.
+    $data = [
+      'complex_sort_value' => ['b' => ['foo' => '1', 'bar' => '1'] , 'a' => ['foo' => '2', 'bar' => '2']],
+      'complex_sort_key' => [['foo' => 'b', 'bar' => 'b'] , ['foo' => 'a', 'bar' => 'a']],
+    ];
+    $this->config('config_schema_test.schema_sequence_sort')
+      ->setData($data)
+      ->save();
+    $this->assertSame([['foo' => '1', 'bar' => '1'], ['foo' => '2', 'bar' => '2']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_value'));
+    $this->assertSame([['foo' => 'b', 'bar' => 'b'], ['foo' => 'a', 'bar' => 'a']], $this->config('config_schema_test.schema_sequence_sort')->get('complex_sort_key'));
+
+  }
+
+  /**
    * Tests fallback to a greedy wildcard.
    */
   public function testSchemaFallback() {
@@ -405,6 +490,7 @@ public function testSchemaFallback() {
     $expected['label'] = 'Schema wildcard fallback test';
     $expected['class'] = Mapping::class;
     $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition';
+    $expected['unwrap_for_canonical_representation'] = TRUE;
     $expected['mapping']['langcode']['type'] = 'string';
     $expected['mapping']['langcode']['label'] = 'Language code';
     $expected['mapping']['_core']['type'] = '_core_config_info';
diff --git a/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php b/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php
index 7b08b40475..d1ab27ef68 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/InvalidDataTest.php
@@ -66,4 +66,81 @@ public function testInsertDuplicateData() {
     }
   }
 
+  /**
+   * Tests inserting with invalid data from a select query.
+   */
+  public function testInsertDuplicateDataFromSelect() {
+    // Insert multiple records in 'test_people' where one has bad data
+    // (duplicate key). A 'Meredith' record has already been inserted
+    // in ::setUp.
+    db_insert('test_people')
+      ->fields(['name', 'age', 'job'])
+      ->values([
+        'name' => 'Elvis',
+        'age' => 63,
+        'job' => 'Singer',
+      ])->values([
+        // Duplicate value on unique field 'name' for later INSERT in 'test'
+        // table.
+        'name' => 'John',
+        'age' => 17,
+        'job' => 'Consultant',
+      ])
+      ->values([
+        'name' => 'Frank',
+        'age' => 75,
+        'job' => 'Bass',
+      ])
+      ->execute();
+
+    try {
+      // Define the subselect query. Add ORDER BY to ensure we have consistent
+      // order in results. Will return:
+      // 0 => [name] => Elvis, [age] => 63, [job] => Singer
+      // 1 => [name] => Frank, [age] => 75, [job] => Bass
+      // 2 => [name] => John, [age] => 17, [job] => Consultant
+      // 3 => [name] => Meredith, [age] => 30, [job] => Speaker
+      // Records 0 and 1 should pass, record 2 should lead to integrity
+      // constraint violation.
+      $query = db_select('test_people', 'tp')
+        ->fields('tp', ['name', 'age', 'job'])
+        ->orderBy('name');
+
+      // Try inserting from the subselect.
+      db_insert('test')
+        ->from($query)
+        ->execute();
+
+      $this->fail('Insert succeeded when it should not have.');
+    }
+    catch (IntegrityConstraintViolationException $e) {
+      // Check if the second record was inserted.
+      $name = db_query('SELECT name FROM {test} WHERE age = :age', [':age' => 75])->fetchField();
+
+      if ($name == 'Frank') {
+        if (!Database::getConnection()->supportsTransactions()) {
+          // This is an expected fail.
+          // Database engines that don't support transactions can leave partial
+          // inserts in place when an error occurs. This is the case for MySQL
+          // when running on a MyISAM table.
+          $this->pass("The whole transaction has not been rolled-back when a duplicate key insert occurs, this is expected because the database doesn't support transactions");
+        }
+        else {
+          $this->fail('The whole transaction is rolled back when a duplicate key insert occurs.');
+        }
+      }
+      else {
+        $this->pass('The whole transaction is rolled back when a duplicate key insert occurs.');
+      }
+
+      // Ensure the values for records 2 and 3 were not inserted.
+      $record = db_select('test')
+        ->fields('test', ['name', 'age'])
+        ->condition('age', [17, 30], 'IN')
+        ->execute()->fetchObject();
+
+      $this->assertFalse($record, 'The rest of the insert aborted as expected.');
+    }
+  }
+
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
index 34ca74c693..cd3ec4a163 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/SelectComplexTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\KernelTests\Core\Database;
 
 use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Query\Condition;
 use Drupal\Core\Database\RowCountException;
 use Drupal\user\Entity\User;
 
@@ -312,7 +313,7 @@ public function testNestedConditions() {
     $query = db_select('test');
     $query->addField('test', 'job');
     $query->condition('name', 'Paul');
-    $query->condition(db_or()->condition('age', 26)->condition('age', 27));
+    $query->condition((new Condition('OR'))->condition('age', 26)->condition('age', 27));
 
     $job = $query->execute()->fetchField();
     $this->assertEqual($job, 'Songwriter', 'Correct data retrieved.');
@@ -395,7 +396,7 @@ public function testSelectWithRowCount() {
   public function testJoinConditionObject() {
     // Same test as testDefaultJoin, but with a Condition object.
     $query = db_select('test_task', 't');
-    $join_cond = db_and()->where('t.pid = p.id');
+    $join_cond = (new Condition('AND'))->where('t.pid = p.id');
     $people_alias = $query->join('test', 'p', $join_cond);
     $name_field = $query->addField($people_alias, 'name', 'name');
     $query->addField('t', 'task', 'task');
@@ -418,7 +419,7 @@ public function testJoinConditionObject() {
     // Test a condition object that creates placeholders.
     $t1_name = 'John';
     $t2_name = 'George';
-    $join_cond = db_and()
+    $join_cond = (new Condition('AND'))
       ->condition('t1.name', $t1_name)
       ->condition('t2.name', $t2_name);
     $query = db_select('test', 't1');
diff --git a/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php b/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php
index 3920826de9..69d5d5d388 100644
--- a/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Database/UpdateComplexTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\KernelTests\Core\Database;
 
+use Drupal\Core\Database\Query\Condition;
+
 /**
  * Tests the Update query builder, complex queries.
  *
@@ -15,7 +17,7 @@ class UpdateComplexTest extends DatabaseTestBase {
   public function testOrConditionUpdate() {
     $update = db_update('test')
       ->fields(['job' => 'Musician'])
-      ->condition(db_or()
+      ->condition((new Condition('OR'))
         ->condition('name', 'John')
         ->condition('name', 'Paul')
       );
diff --git a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
index 7370491816..722bdd2451 100644
--- a/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
+++ b/core/tests/Drupal/KernelTests/Core/DrupalKernel/DrupalKernelTest.php
@@ -184,6 +184,11 @@ public function testPreventChangeOfSitePath() {
       $pass = TRUE;
     }
     $this->assertTrue($pass, 'Throws LogicException if DrupalKernel::setSitePath() is called after boot');
+
+    // Ensure no LogicException if DrupalKernel::setSitePath() is called with
+    // identical path after boot.
+    $path = $kernel->getSitePath();
+    $kernel->setSitePath($path);
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php
index 9d5095d149..5e755d9584 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityTypedDataDefinitionTest.php
@@ -101,8 +101,8 @@ public function testEntities() {
 
     // Test that the definition factory creates the right definitions for all
     // entity data types variants.
-    $this->assertEqual($this->typedDataManager->createDataDefinition('entity'), EntityDataDefinition::create());
-    $this->assertEqual($this->typedDataManager->createDataDefinition('entity:node'), EntityDataDefinition::create('node'));
+    $this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity')), serialize(EntityDataDefinition::create()));
+    $this->assertEqual(serialize($this->typedDataManager->createDataDefinition('entity:node')), serialize(EntityDataDefinition::create('node')));
 
     // Config entities don't support typed data.
     $entity_definition = EntityDataDefinition::create('node_type');
@@ -123,7 +123,7 @@ public function testEntityReferences() {
     // Test that the definition factory creates the right definition object.
     $reference_definition2 = $this->typedDataManager->createDataDefinition('entity_reference');
     $this->assertTrue($reference_definition2 instanceof DataReferenceDefinitionInterface);
-    $this->assertEqual($reference_definition2, $reference_definition);
+    $this->assertEqual(serialize($reference_definition2), serialize($reference_definition));
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
index 1fd873cd86..73b3254630 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/RevisionableContentEntityBaseTest.php
@@ -2,9 +2,12 @@
 
 namespace Drupal\KernelTests\Core\Entity;
 
-use Drupal\entity_test\Entity\EntityTestWithRevisionLog;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\entity_test_revlog\Entity\EntityTestMulWithRevisionLog;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\user\Entity\User;
+use Drupal\user\UserInterface;
 
 /**
  * @coversDefaultClass \Drupal\Core\Entity\RevisionableContentEntityBase
@@ -15,7 +18,7 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['entity_test', 'system', 'user'];
+  public static $modules = ['entity_test_revlog', 'system', 'user'];
 
   /**
    * {@inheritdoc}
@@ -23,34 +26,102 @@ class RevisionableContentEntityBaseTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $this->installEntitySchema('entity_test_revlog');
+    $this->installEntitySchema('entity_test_mul_revlog');
     $this->installEntitySchema('user');
     $this->installSchema('system', 'sequences');
   }
 
+  /**
+   * Tests the correct functionality CRUD operations of entity revisions.
+   */
   public function testRevisionableContentEntity() {
+    $entity_type = 'entity_test_mul_revlog';
+    $definition = \Drupal::entityManager()->getDefinition($entity_type);
     $user = User::create(['name' => 'test name']);
     $user->save();
-    /** @var \Drupal\entity_test\Entity\EntityTestWithRevisionLog $entity */
-    $entity = EntityTestWithRevisionLog::create([
-      'type' => 'entity_test_revlog',
+    /** @var \Drupal\entity_test_mul_revlog\Entity\EntityTestMulWithRevisionLog $entity */
+    $entity = EntityTestMulWithRevisionLog::create([
+      'type' => $entity_type,
     ]);
+
+    // Save the entity, this creates the first revision.
     $entity->save();
+    $revision_ids[] = $entity->getRevisionId();
+    $this->assertItemsTableCount(1, $definition);
 
+    // Create the second revision.
     $entity->setNewRevision(TRUE);
     $random_timestamp = rand(1e8, 2e8);
-    $entity->setRevisionCreationTime($random_timestamp);
-    $entity->setRevisionUserId($user->id());
-    $entity->setRevisionLogMessage('This is my log message');
-    $entity->save();
+    $this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
 
     $revision_id = $entity->getRevisionId();
+    $revision_ids[] = $revision_id;
 
-    $entity = \Drupal::entityTypeManager()->getStorage('entity_test_revlog')->loadRevision($revision_id);
+    $storage = \Drupal::entityTypeManager()->getStorage('entity_test_mul_revlog');
+    $entity = $storage->loadRevision($revision_id);
     $this->assertEquals($random_timestamp, $entity->getRevisionCreationTime());
     $this->assertEquals($user->id(), $entity->getRevisionUserId());
     $this->assertEquals($user->id(), $entity->getRevisionUser()->id());
     $this->assertEquals('This is my log message', $entity->getRevisionLogMessage());
+
+    // Create the third revision.
+    $random_timestamp = rand(1e8, 2e8);
+    $this->createRevision($entity, $user, $random_timestamp, 'This is my log message');
+    $this->assertItemsTableCount(3, $definition);
+    $revision_ids[] = $entity->getRevisionId();
+
+    // Create another 3 revisions.
+    foreach (range(1, 3) as $count) {
+      $timestamp = rand(1e8, 2e8);
+      $this->createRevision($entity, $user, $timestamp, 'This is my log message number: ' . $count);
+      $revision_ids[] = $entity->getRevisionId();
+    }
+    $this->assertItemsTableCount(6, $definition);
+
+    $this->assertEqual(6, count($revision_ids));
+
+    // Delete the first 3 revisions.
+    foreach (range(0, 2) as $key) {
+      $storage->deleteRevision($revision_ids[$key]);
+    }
+
+    // We should have only data for three revisions.
+    $this->assertItemsTableCount(3, $definition);
+  }
+
+  /**
+   * Asserts the ammount of items on entity related tables.
+   *
+   * @param int $count
+   *   The number of items expected to be in revisions related tables.
+   * @param \Drupal\Core\Entity\EntityTypeInterface $definition
+   *   The definition and metada of the entity being tested.
+   */
+  protected function assertItemsTableCount($count, EntityTypeInterface $definition) {
+    $this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getBaseTable() . '}')->fetchField());
+    $this->assertEqual(1, db_query('SELECT COUNT(*) FROM {' . $definition->getDataTable() . '}')->fetchField());
+    $this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionTable() . '}')->fetchField());
+    $this->assertEqual($count, db_query('SELECT COUNT(*) FROM {' . $definition->getRevisionDataTable() . '}')->fetchField());
+  }
+
+  /**
+   * Creates a new revision in the entity of this test class.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity where revision will be created.
+   * @param \Drupal\user\UserInterface $user
+   *   The author of the new revision.
+   * @param int $timestamp
+   *   The timestamp of the new revision.
+   * @param string $log_message
+   *   The log message of the new revision.
+   */
+  protected function createRevision(EntityInterface $entity, UserInterface $user, $timestamp, $log_message) {
+    $entity->setNewRevision(TRUE);
+    $entity->setRevisionCreationTime($timestamp);
+    $entity->setRevisionUserId($user->id());
+    $entity->setRevisionLogMessage($log_message);
+    $entity->save();
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php
new file mode 100644
index 0000000000..1d20340819
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Form/FormValidationMessageOrderTest.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Form;
+
+use Drupal\Core\Form\FormInterface;
+use Drupal\Core\Form\FormState;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests form validation mesages are displayed in the same order as the fields.
+ *
+ * @group Form
+ */
+class FormValidationMessageOrderTest extends KernelTestBase implements FormInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'form_validation_error_message_order_test';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    // Prepare fields with weights specified.
+    $form['one'] = [
+      '#type' => 'textfield',
+      '#title' => 'One',
+      '#required' => TRUE,
+      '#weight' => 40,
+    ];
+    $form['two'] = [
+      '#type' => 'textfield',
+      '#title' => 'Two',
+      '#required' => TRUE,
+      '#weight' => 30,
+    ];
+    $form['three'] = [
+      '#type' => 'textfield',
+      '#title' => 'Three',
+      '#required' => TRUE,
+      '#weight' => 10,
+    ];
+    $form['four'] = [
+      '#type' => 'textfield',
+      '#title' => 'Four',
+      '#required' => TRUE,
+      '#weight' => 20,
+    ];
+    $form['actions'] = [
+      '#type' => 'actions',
+      'submit' => [
+        '#type' => 'submit',
+        '#value' => 'Submit',
+      ],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+  }
+
+  /**
+   * Tests that fields validation messages are sorted in the fields order.
+   */
+  public function testLimitValidationErrors() {
+    $form_state = new FormState();
+    $form_builder = $this->container->get('form_builder');
+    $form_builder->submitForm($this, $form_state);
+
+    $messages = drupal_get_messages();
+    $this->assertTrue(isset($messages['error']));
+    $error_messages = $messages['error'];
+    $this->assertEqual($error_messages[0], 'Three field is required.');
+    $this->assertEqual($error_messages[1], 'Four field is required.');
+    $this->assertEqual($error_messages[2], 'Two field is required.');
+    $this->assertEqual($error_messages[3], 'One field is required.');
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php b/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php
index 0bd761fed2..8e1a50d5d0 100644
--- a/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Lock/LockTest.php
@@ -47,6 +47,21 @@ public function testBackendLockRelease() {
     $this->assertTrue($success, 'Could acquire second lock a second time within the same request.');
 
     $this->lock->release('lock_b');
+
+    // Test acquiring an releasing a lock with a long key (over 255 chars).
+    $long_key = 'long_key:BZoMiSf9IIPULsJ98po18TxJ6T4usd3MZrLE0d3qMgG6iAgDlOi1G3oMap7zI5df84l7LtJBg4bOj6XvpO6vDRmP5h5QbA0Bj9rVFiPIPAIQZ9qFvJqTALiK1OR3GpOkWQ4vgEA4LkY0UfznrWBeuK7IWZfv1um6DLosnVXd1z1cJjvbEUqYGJj92rwHfhYihLm8IO9t3P2gAvEkH5Mhc8GBoiTsIDnP01Te1kxGFHO3RuvJIxPnHmZtSdBggmuVN7x9';
+
+    $success = $this->lock->acquire($long_key);
+    $this->assertTrue($success, 'Could acquire long key lock.');
+
+    // This function is not part of the backend, but the default database
+    // backend implement it, we can here use it safely.
+    $is_free = $this->lock->lockMayBeAvailable($long_key);
+    $this->assertFalse($is_free, 'Long key lock is unavailable.');
+
+    $this->lock->release($long_key);
+    $is_free = $this->lock->lockMayBeAvailable($long_key);
+    $this->assertTrue($is_free, 'Long key lock has been released.');
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php b/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php
index 85649484bb..a791454f72 100644
--- a/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Routing/ExceptionHandlingTest.php
@@ -155,7 +155,7 @@ public function testBacktraceEscaping() {
     $kernel = \Drupal::getContainer()->get('http_kernel');
     $response = $kernel->handle($request)->prepare($request);
     $this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
-    $this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
+    $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
 
     // Test both that the backtrace is properly escaped, and that the unescaped
     // string is not output at all.
@@ -178,7 +178,7 @@ public function testExceptionEscaping() {
     $kernel = \Drupal::getContainer()->get('http_kernel');
     $response = $kernel->handle($request)->prepare($request);
     $this->assertEqual($response->getStatusCode(), Response::HTTP_INTERNAL_SERVER_ERROR);
-    $this->assertEqual($response->headers->get('Content-type'), 'text/html; charset=UTF-8');
+    $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
 
     // Test message is properly escaped, and that the unescaped string is not
     // output at all.
@@ -192,10 +192,11 @@ public function testExceptionEscaping() {
     $kernel = \Drupal::getContainer()->get('http_kernel');
     $response = $kernel->handle($request)->prepare($request);
     // As the Content-type is text/plain the fact that the raw string is
-    // contained in the output does not matter.
+    // contained in the output would not matter, but because it is output by the
+    // final exception subscriber, it is printed as partial HTML, and hence
+    // escaped.
     $this->assertEqual($response->headers->get('Content-type'), 'text/plain; charset=UTF-8');
-    $this->setRawContent($response->getContent());
-    $this->assertRaw($string);
+    $this->assertStringStartsWith('The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException</em>: Not acceptable format: json&lt;script&gt;alert(123);&lt;/script&gt; in <em class="placeholder">', $response->getContent());
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
index f0bbb82a86..7af10f5946 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/TwigWhiteListTest.php
@@ -42,6 +42,7 @@ class TwigWhiteListTest extends KernelTestBase {
    */
   protected function setUp() {
     parent::setUp();
+    \Drupal::service('theme_handler')->install(['test_theme']);
     $this->installSchema('system', ['sequences']);
     $this->installEntitySchema('node');
     $this->installEntitySchema('user');
diff --git a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php
index 8aeab575e9..ad266c2852 100644
--- a/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php
+++ b/core/tests/Drupal/KernelTests/Core/TypedData/TypedDataDefinitionTest.php
@@ -77,7 +77,7 @@ public function testMaps() {
     $map_definition2->setPropertyDefinition('one', DataDefinition::create('string'))
       ->setPropertyDefinition('two', DataDefinition::create('string'))
       ->setPropertyDefinition('three', DataDefinition::create('string'));
-    $this->assertEqual($map_definition, $map_definition2);
+    $this->assertEqual(serialize($map_definition), serialize($map_definition2));
   }
 
   /**
@@ -93,7 +93,7 @@ public function testDataReferences() {
     // Test using the definition factory.
     $language_reference_definition2 = $this->typedDataManager->createDataDefinition('language_reference');
     $this->assertTrue($language_reference_definition2 instanceof DataReferenceDefinitionInterface);
-    $this->assertEqual($language_reference_definition, $language_reference_definition2);
+    $this->assertEqual(serialize($language_reference_definition), serialize($language_reference_definition2));
   }
 
 }
diff --git a/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php
new file mode 100644
index 0000000000..8e17422ff6
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/Validation/ConstraintsTest.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\KernelTests\Core\Validation;
+
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests various low level constrains provided by core.
+ *
+ * @group Validation
+ */
+class ConstraintsTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['config_test'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig('config_test');
+  }
+
+  /**
+   * @see \Drupal\Core\Validation\Plugin\Validation\Constraint\UuidConstraint
+   */
+  public function testUuid() {
+    $typed_config_manager = \Drupal::service('config.typed');
+    /** @var \Drupal\Core\Config\Schema\TypedConfigInterface $typed_config */
+    $typed_config = $typed_config_manager->get('config_test.validation');
+    $typed_config->get('uuid')
+      ->setValue(\Drupal::service('uuid')->generate());
+
+    $this->assertCount(0, $typed_config->validate());
+
+    $typed_config->get('uuid')
+      ->setValue(\Drupal::service('uuid')->generate() . '-invalid');
+    $this->assertCount(1, $typed_config->validate());
+  }
+
+}
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index 04926e03d0..7bbb774016 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -22,6 +22,7 @@
 use Drupal\Tests\ConfigTestTrait;
 use Drupal\Tests\RandomGeneratorTrait;
 use Drupal\simpletest\TestServiceProvider;
+use PHPUnit\Framework\TestCase;
 use Symfony\Component\DependencyInjection\Reference;
 use Symfony\Component\HttpFoundation\Request;
 use org\bovigo\vfs\vfsStream;
@@ -49,7 +50,7 @@
  * @todo Extend ::setRequirementsFromAnnotation() and ::checkRequirements() to
  *   account for '@requires module'.
  */
-abstract class KernelTestBase extends \PHPUnit_Framework_TestCase implements ServiceProviderInterface {
+abstract class KernelTestBase extends TestCase implements ServiceProviderInterface {
 
   use AssertLegacyTrait;
   use AssertContentTrait;
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 754f9d9838..5751368f61 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -27,6 +27,7 @@
 use Drupal\simpletest\BlockCreationTrait;
 use Drupal\simpletest\NodeCreationTrait;
 use Drupal\simpletest\UserCreationTrait;
+use PHPUnit\Framework\TestCase;
 use Symfony\Component\CssSelector\CssSelectorConverter;
 use Symfony\Component\HttpFoundation\Request;
 use Psr\Http\Message\RequestInterface;
@@ -41,7 +42,7 @@
  *
  * @ingroup testing
  */
-abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
+abstract class BrowserTestBase extends TestCase {
 
   use FunctionalTestSetupTrait;
   use TestSetupTrait;
diff --git a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php
index 1299cd6421..208440be74 100644
--- a/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php
+++ b/core/tests/Drupal/Tests/Component/Assertion/InspectorTest.php
@@ -7,14 +7,14 @@
 
 namespace Drupal\Tests\Component\Assertion;
 
-use PHPUnit_Framework_TestCase;
+use PHPUnit\Framework\TestCase;
 use Drupal\Component\Assertion\Inspector;
 
 /**
  * @coversDefaultClass \Drupal\Component\Assertion\Inspector
  * @group Assertion
  */
-class InspectorTest extends PHPUnit_Framework_TestCase {
+class InspectorTest extends TestCase {
 
   /**
    * Tests asserting argument is an array or traversable object.
diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php
index 6cd5575964..f78304bb03 100644
--- a/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php
+++ b/core/tests/Drupal/Tests/Component/DependencyInjection/ContainerTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\Component\DependencyInjection;
 
 use Drupal\Component\Utility\Crypt;
+use PHPUnit\Framework\TestCase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
 use Symfony\Component\DependencyInjection\Exception\LogicException;
@@ -21,7 +22,7 @@
  * @coversDefaultClass \Drupal\Component\DependencyInjection\Container
  * @group DependencyInjection
  */
-class ContainerTest extends \PHPUnit_Framework_TestCase {
+class ContainerTest extends TestCase {
 
   /**
    * The tested container.
@@ -654,46 +655,6 @@ public function testInitializedForAliases() {
   }
 
   /**
-   * Tests that unsupported methods throw an Exception.
-   *
-   * @covers ::enterScope
-   * @covers ::leaveScope
-   * @covers ::addScope
-   * @covers ::hasScope
-   * @covers ::isScopeActive
-   *
-   * @dataProvider scopeExceptionTestProvider
-   */
-  public function testScopeFunctionsWithException($method, $argument) {
-    $callable = [
-      $this->container,
-      $method,
-    ];
-
-    $this->setExpectedException(\BadMethodCallException::class);
-    $callable($argument);
-  }
-
-  /**
-   * Data provider for scopeExceptionTestProvider().
-   *
-   * @return array[]
-   *   Returns per data set an array with:
-   *     - method name to call
-   *     - argument to pass
-   */
-  public function scopeExceptionTestProvider() {
-    $scope = $this->prophesize('\Symfony\Component\DependencyInjection\ScopeInterface')->reveal();
-    return [
-      ['enterScope', 'test_scope'],
-      ['leaveScope', 'test_scope'],
-      ['hasScope', 'test_scope'],
-      ['isScopeActive', 'test_scope'],
-      ['addScope', $scope],
-    ];
-  }
-
-  /**
    * Tests that Container::getServiceIds() works properly.
    *
    * @covers ::getServiceIds
diff --git a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php
index 9da4c27bc1..038e018ea0 100644
--- a/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php
+++ b/core/tests/Drupal/Tests/Component/DependencyInjection/Dumper/OptimizedPhpArrayDumperTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\Tests\Component\DependencyInjection\Dumper {
 
   use Drupal\Component\Utility\Crypt;
+  use PHPUnit\Framework\TestCase;
   use Symfony\Component\DependencyInjection\Definition;
   use Symfony\Component\DependencyInjection\Reference;
   use Symfony\Component\DependencyInjection\Parameter;
@@ -21,7 +22,7 @@
    * @coversDefaultClass \Drupal\Component\DependencyInjection\Dumper\OptimizedPhpArrayDumper
    * @group DependencyInjection
    */
-  class OptimizedPhpArrayDumperTest extends \PHPUnit_Framework_TestCase {
+  class OptimizedPhpArrayDumperTest extends TestCase {
 
     /**
      * The container builder instance.
@@ -211,6 +212,8 @@ public function getParametersDataProvider() {
      * @covers ::getParameterCall
      *
      * @dataProvider getDefinitionsDataProvider
+     *
+     * @group legacy
      */
     public function testGetServiceDefinitions($services, $definition_services) {
       $this->containerDefinition['services'] = $definition_services;
@@ -248,7 +251,6 @@ public function getDefinitionsDataProvider() {
         'arguments_count' => 0,
         'properties' => [],
         'calls' => [],
-        'scope' => ContainerInterface::SCOPE_CONTAINER,
         'shared' => TRUE,
         'factory' => FALSE,
         'configurator' => FALSE,
@@ -361,11 +363,6 @@ public function getDefinitionsDataProvider() {
       ] + $base_service_definition;
 
       $service_definitions[] = [
-        'scope' => ContainerInterface::SCOPE_PROTOTYPE,
-        'shared' => FALSE,
-      ] + $base_service_definition;
-
-      $service_definitions[] = [
           'shared' => FALSE,
         ] + $base_service_definition;
 
@@ -407,7 +404,6 @@ public function getDefinitionsDataProvider() {
         $definition->getArguments()->willReturn($service_definition['arguments']);
         $definition->getProperties()->willReturn($service_definition['properties']);
         $definition->getMethodCalls()->willReturn($service_definition['calls']);
-        $definition->getScope()->willReturn($service_definition['scope']);
         $definition->isShared()->willReturn($service_definition['shared']);
         $definition->getDecoratedService()->willReturn(NULL);
         $definition->getFactory()->willReturn($service_definition['factory']);
@@ -440,9 +436,6 @@ public function getDefinitionsDataProvider() {
           }
         }
 
-        // Remove any remaining scope.
-        unset($filtered_service_definition['scope']);
-
         if (isset($filtered_service_definition['public']) && $filtered_service_definition['public'] === FALSE) {
           $services_provided[] = [
             ['foo_service' => $definition->reveal()],
@@ -481,26 +474,13 @@ protected function getServiceCall($id, $invalid_behavior = ContainerInterface::E
     }
 
     /**
-     * Tests that the correct InvalidArgumentException is thrown for getScope().
-     *
-     * @covers ::getServiceDefinition
-     */
-    public function testGetServiceDefinitionWithInvalidScope() {
-      $bar_definition = new Definition('\stdClass');
-      $bar_definition->setScope('foo_scope');
-      $services['bar'] = $bar_definition;
-
-      $this->containerBuilder->getDefinitions()->willReturn($services);
-      $this->setExpectedException(InvalidArgumentException::class);
-      $this->dumper->getArray();
-    }
-
-    /**
      * Tests that references to aliases work correctly.
      *
      * @covers ::getReferenceCall
      *
      * @dataProvider publicPrivateDataProvider
+     *
+     * @group legacy
      */
     public function testGetServiceDefinitionWithReferenceToAlias($public) {
       $bar_definition = new Definition('\stdClass');
@@ -556,6 +536,8 @@ public function publicPrivateDataProvider() {
      * getDecoratedService().
      *
      * @covers ::getServiceDefinition
+     *
+     * @group legacy
      */
     public function testGetServiceDefinitionForDecoratedService() {
       $bar_definition = new Definition('\stdClass');
diff --git a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
index 70fb0dcf15..c5fab90921 100644
--- a/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/DiffFormatterTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Component\Diff\Diff;
 use Drupal\Component\Diff\DiffFormatter;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Test DiffFormatter classes.
@@ -12,7 +13,7 @@
  *
  * @group Diff
  */
-class DiffFormatterTest extends \PHPUnit_Framework_TestCase {
+class DiffFormatterTest extends TestCase {
 
   /**
    * @return array
diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php
index ade152751e..69f92daec9 100644
--- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffEngineTest.php
@@ -7,6 +7,7 @@
 use Drupal\Component\Diff\Engine\DiffOpCopy;
 use Drupal\Component\Diff\Engine\DiffOpChange;
 use Drupal\Component\Diff\Engine\DiffOpDelete;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Test DiffEngine class.
@@ -15,7 +16,7 @@
  *
  * @group Diff
  */
-class DiffEngineTest extends \PHPUnit_Framework_TestCase {
+class DiffEngineTest extends TestCase {
 
   /**
    * @return array
diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php
index 4275bb7abf..1a649ae510 100644
--- a/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/Engine/DiffOpTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Component\Diff\Engine;
 
 use Drupal\Component\Diff\Engine\DiffOp;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Test DiffOp base class.
@@ -15,7 +16,7 @@
  *
  * @group Diff
  */
-class DiffOpTest extends \PHPUnit_Framework_TestCase {
+class DiffOpTest extends TestCase {
 
   /**
    * DiffOp::reverse() always throws an error.
diff --git a/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php b/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php
index ccf468d348..194f37f50e 100644
--- a/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php
+++ b/core/tests/Drupal/Tests/Component/Diff/Engine/HWLDFWordAccumulatorTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Component\Diff\Engine;
 
 use Drupal\Component\Diff\Engine\HWLDFWordAccumulator;
+use PHPUnit\Framework\TestCase;
 
 /**
  * Test HWLDFWordAccumulator.
@@ -11,7 +12,7 @@
  *
  * @group Diff
  */
-class HWLDFWordAccumulatorTest extends \PHPUnit_Framework_TestCase {
+class HWLDFWordAccumulatorTest extends TestCase {
 
   /**
    * Verify that we only get back a NBSP from an empty accumulator.
diff --git a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
index 7bc2382b1f..ea0685a717 100644
--- a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
+++ b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php
@@ -6,9 +6,10 @@
 use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
 use Symfony\Component\DependencyInjection\Container;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\Tests\CallableClass;
-use Symfony\Component\EventDispatcher\Tests\TestEventListener;
 use Symfony\Component\EventDispatcher\Tests\ContainerAwareEventDispatcherTest as SymfonyContainerAwareEventDispatcherTest;
+use Symfony\Component\EventDispatcher\Tests\TestEventListener;
 
 /**
  * Unit tests for the ContainerAwareEventDispatcher.
@@ -37,7 +38,7 @@ public function testGetListenersWithCallables()
         // When passing in callables exclusively as listeners into the event
         // dispatcher constructor, the event dispatcher must not attempt to
         // resolve any services.
-        $container = $this->getMock('Symfony\Component\DependencyInjection\IntrospectableContainerInterface');
+        $container = $this->getMock(ContainerInterface::class);
         $container->expects($this->never())->method($this->anything());
 
         $firstListener = new CallableClass();
@@ -72,7 +73,7 @@ public function testDispatchWithCallables()
         // When passing in callables exclusively as listeners into the event
         // dispatcher constructor, the event dispatcher must not attempt to
         // resolve any services.
-        $container = $this->getMock('Symfony\Component\DependencyInjection\IntrospectableContainerInterface');
+        $container = $this->getMock(ContainerInterface::class);
         $container->expects($this->never())->method($this->anything());
 
         $firstListener = new CallableClass();
diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php b/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php
index 7f992bdef4..841ac05ff4 100644
--- a/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php
+++ b/core/tests/Drupal/Tests/Component/Serialization/YamlTest.php
@@ -66,6 +66,7 @@ public function testGetFileExtension() {
    * @dataProvider providerYamlFilesInCore
    */
   public function testYamlFiles($file) {
+    file_put_contents('/tmp/dup.txt', $file . "\n", FILE_APPEND);
     $data = file_get_contents($file);
     try {
       $this->assertEquals(YamlSymfony::decode($data), YamlPecl::decode($data), $file);
diff --git a/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php b/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php
index d2b504ecae..2f8f23e5b3 100644
--- a/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php
+++ b/core/tests/Drupal/Tests/Component/Serialization/YamlTestBase.php
@@ -2,10 +2,12 @@
 
 namespace Drupal\Tests\Component\Serialization;
 
+use PHPUnit\Framework\TestCase;
+
 /**
  * Provides standard data to validate different YAML implementations.
  */
-abstract class YamlTestBase extends \PHPUnit_Framework_TestCase {
+abstract class YamlTestBase extends TestCase {
 
   /**
    * Some data that should be able to be serialized.
diff --git a/core/tests/Drupal/Tests/Core/Assert/AssertLegacyTraitTest.php b/core/tests/Drupal/Tests/Core/Assert/AssertLegacyTraitTest.php
index d2d7b855b5..edd7b13de1 100644
--- a/core/tests/Drupal/Tests/Core/Assert/AssertLegacyTraitTest.php
+++ b/core/tests/Drupal/Tests/Core/Assert/AssertLegacyTraitTest.php
@@ -14,6 +14,7 @@
 /**
  * @coversDefaultClass \Drupal\FunctionalTests\AssertLegacyTrait
  * @group Assert
+ * @group legacy
  */
 class AssertLegacyTraitTest extends UnitTestCase {
 
diff --git a/core/tests/Drupal/Tests/Core/Cache/Context/SessionCacheContextTest.php b/core/tests/Drupal/Tests/Core/Cache/Context/SessionCacheContextTest.php
index b621b2daca..9538bd2511 100644
--- a/core/tests/Drupal/Tests/Core/Cache/Context/SessionCacheContextTest.php
+++ b/core/tests/Drupal/Tests/Core/Cache/Context/SessionCacheContextTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Core\Cache\Context;
 
 use Drupal\Core\Cache\Context\SessionCacheContext;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
 
@@ -10,7 +11,7 @@
  * @coversDefaultClass \Drupal\Core\Cache\Context\SessionCacheContext
  * @group Cache
  */
-class SessionCacheContextTest extends \PHPUnit_Framework_TestCase {
+class SessionCacheContextTest extends UnitTestCase {
 
   /**
    * The request stack.
diff --git a/core/tests/Drupal/Tests/Core/Config/ConfigFactoryOverrideBaseTest.php b/core/tests/Drupal/Tests/Core/Config/ConfigFactoryOverrideBaseTest.php
index 7386ac900b..f81352f712 100644
--- a/core/tests/Drupal/Tests/Core/Config/ConfigFactoryOverrideBaseTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/ConfigFactoryOverrideBaseTest.php
@@ -6,12 +6,13 @@
 use Drupal\Core\Config\ConfigCrudEvent;
 use Drupal\Core\Config\ConfigFactoryOverrideBase;
 use Drupal\Core\Config\ConfigRenameEvent;
+use Drupal\Tests\UnitTestCase;
 
 /**
  * @coversDefaultClass \Drupal\Core\Config\ConfigFactoryOverrideBase
  * @group config
  */
-class ConfigFactoryOverrideBaseTest extends \PHPUnit_Framework_TestCase {
+class ConfigFactoryOverrideBaseTest extends UnitTestCase {
 
   /**
    * @dataProvider providerTestFilterNestedArray
diff --git a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
index 28040a603f..0b7aa25146 100644
--- a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
+++ b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
@@ -70,6 +70,8 @@ protected function setUp() {
    *
    * @see \Drupal\Core\Controller\ControllerResolver::getArguments()
    * @see \Drupal\Core\Controller\ControllerResolver::doGetArguments()
+   *
+   * @group legacy
    */
   public function testGetArguments() {
     $controller = function(EntityInterface $entity, $user, RouteMatchInterface $route_match, ServerRequestInterface $psr_7) {
@@ -220,6 +222,8 @@ protected function assertCallableController($controller, $class, $output) {
    *
    * @covers ::getArguments
    * @covers ::doGetArguments
+   *
+   * @group legacy
    */
   public function testGetArgumentsWithRouteMatchAndRequest() {
     $request = Request::create('/test');
@@ -233,6 +237,8 @@ public function testGetArgumentsWithRouteMatchAndRequest() {
    *
    * @covers ::getArguments
    * @covers ::doGetArguments
+   *
+   * @group legacy
    */
   public function testGetArgumentsWithRouteMatchAndPsr7Request() {
     $request = Request::create('/test');
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/AuthenticationProviderPassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/AuthenticationProviderPassTest.php
index 6f99d09854..9fe058a790 100644
--- a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/AuthenticationProviderPassTest.php
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/AuthenticationProviderPassTest.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\DependencyInjection\Compiler\AuthenticationProviderPass;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\Serializer\Serializer;
 
@@ -11,7 +12,7 @@
  * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\AuthenticationProviderPass
  * @group DependencyInjection
  */
-class AuthenticationProviderPassTest extends \PHPUnit_Framework_TestCase {
+class AuthenticationProviderPassTest extends UnitTestCase {
 
   /**
    * @covers ::process
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php
index 1a9dc667f7..97b2c942d2 100644
--- a/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/YamlFileLoaderTest.php
@@ -5,13 +5,14 @@
 use Drupal\Component\FileCache\FileCacheFactory;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\YamlFileLoader;
+use Drupal\Tests\UnitTestCase;
 use org\bovigo\vfs\vfsStream;
 
 /**
  * @coversDefaultClass \Drupal\Core\DependencyInjection\YamlFileLoader
  * @group DependencyInjection
  */
-class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase {
+class YamlFileLoaderTest extends UnitTestCase {
 
   /**
    * {@inheritdoc}
diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
index 8ab7950f02..541ec88e2a 100644
--- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityBaseUnitTest.php
@@ -10,6 +10,7 @@
 use Drupal\Core\TypedData\TypedDataManagerInterface;
 use Drupal\Tests\UnitTestCase;
 use Drupal\Core\Language\Language;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
 
 /**
  * @coversDefaultClass \Drupal\Core\Entity\ContentEntityBase
@@ -327,7 +328,7 @@ public function testPreSaveRevision() {
    * @covers ::validate
    */
   public function testValidate() {
-    $validator = $this->getMock('\Symfony\Component\Validator\ValidatorInterface');
+    $validator = $this->getMock(ValidatorInterface::class);
     /** @var \Symfony\Component\Validator\ConstraintViolationList|\PHPUnit_Framework_MockObject_MockObject $empty_violation_list */
     $empty_violation_list = $this->getMockBuilder('\Symfony\Component\Validator\ConstraintViolationList')
       ->setMethods(NULL)
@@ -360,7 +361,7 @@ public function testValidate() {
    * @covers ::preSave
    */
   public function testRequiredValidation() {
-    $validator = $this->getMock('\Symfony\Component\Validator\ValidatorInterface');
+    $validator = $this->getMock(ValidatorInterface::class);
     /** @var \Symfony\Component\Validator\ConstraintViolationList|\PHPUnit_Framework_MockObject_MockObject $empty_violation_list */
     $empty_violation_list = $this->getMockBuilder('\Symfony\Component\Validator\ConstraintViolationList')
       ->setMethods(NULL)
diff --git a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
index 27d5154252..b3e339b897 100644
--- a/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/Sql/SqlContentEntityStorageTest.php
@@ -534,6 +534,9 @@ public function testGetTableMappingRevisionable(array $entity_keys) {
         ['bundle', $entity_keys['bundle']],
         ['revision', $entity_keys['revision']],
       ]));
+    $this->entityType->expects($this->any())
+      ->method('getRevisionMetadataKeys')
+      ->will($this->returnValue([]));
 
     $this->setUpEntityStorage();
 
@@ -574,13 +577,13 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
     // PHPUnit does not allow for multiple data providers.
     $test_cases = [
       [],
-      ['revision_timestamp'],
-      ['revision_uid'],
-      ['revision_log'],
-      ['revision_timestamp', 'revision_uid'],
-      ['revision_timestamp', 'revision_log'],
-      ['revision_uid', 'revision_log'],
-      ['revision_timestamp', 'revision_uid', 'revision_log'],
+      ['revision_created' => 'revision_timestamp'],
+      ['revision_user' => 'revision_uid'],
+      ['revision_log_message' => 'revision_log'],
+      ['revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid'],
+      ['revision_created' => 'revision_timestamp', 'revision_log_message' => 'revision_log'],
+      ['revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'],
+      ['revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'],
     ];
     foreach ($test_cases as $revision_metadata_field_names) {
       $this->setUp();
@@ -591,7 +594,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
 
       $revisionable_field_names = ['description', 'owner'];
       $field_names = array_merge($field_names, $revisionable_field_names);
-      $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, $revision_metadata_field_names), ['isRevisionable' => TRUE]);
+      $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, array_values($revision_metadata_field_names)), ['isRevisionable' => TRUE]);
 
       $this->entityType->expects($this->exactly(2))
         ->method('isRevisionable')
@@ -605,6 +608,10 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
           ['revision', $entity_keys['revision']],
         ]));
 
+      $this->entityType->expects($this->any())
+        ->method('getRevisionMetadataKeys')
+        ->will($this->returnValue($revision_metadata_field_names));
+
       $this->setUpEntityStorage();
 
       $mapping = $this->entityStorage->getTableMapping();
@@ -616,7 +623,7 @@ public function testGetTableMappingRevisionableWithFields(array $entity_keys) {
       $expected = array_merge(
         [$entity_keys['id'], $entity_keys['revision']],
         $revisionable_field_names,
-        $revision_metadata_field_names
+        array_values($revision_metadata_field_names)
       );
       $this->assertEquals($expected, $mapping->getFieldNames('entity_test_revision'));
 
@@ -761,6 +768,11 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
       'uuid' => $entity_keys['uuid'],
       'langcode' => 'langcode',
     ];
+    $revision_metadata_keys = [
+      'revision_created' => 'revision_timestamp',
+      'revision_user' => 'revision_uid',
+      'revision_log_message' => 'revision_log'
+    ];
 
     $this->entityType->expects($this->atLeastOnce())
       ->method('isRevisionable')
@@ -780,6 +792,9 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
         ['revision', $entity_keys['revision']],
         ['langcode', $entity_keys['langcode']],
       ]));
+    $this->entityType->expects($this->any())
+      ->method('getRevisionMetadataKeys')
+      ->will($this->returnValue($revision_metadata_keys));
 
     $this->setUpEntityStorage();
 
@@ -810,6 +825,7 @@ public function testGetTableMappingRevisionableTranslatable(array $entity_keys)
       $entity_keys['revision'],
       $entity_keys['langcode'],
     ]));
+    $expected = array_merge($expected, array_values($revision_metadata_keys));
     $actual = $mapping->getFieldNames('entity_test_revision');
     $this->assertEquals($expected, $actual);
     // The UUID is not stored on the data table.
@@ -865,13 +881,13 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
     // PHPUnit does not allow for multiple data providers.
     $test_cases = [
       [],
-      ['revision_timestamp'],
-      ['revision_uid'],
-      ['revision_log'],
-      ['revision_timestamp', 'revision_uid'],
-      ['revision_timestamp', 'revision_log'],
-      ['revision_uid', 'revision_log'],
-      ['revision_timestamp', 'revision_uid', 'revision_log'],
+      ['revision_created' => 'revision_timestamp'],
+      ['revision_user' => 'revision_uid'],
+      ['revision_log_message' => 'revision_log'],
+      ['revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid'],
+      ['revision_created' => 'revision_timestamp', 'revision_log_message' => 'revision_log'],
+      ['revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'],
+      ['revision_created' => 'revision_timestamp', 'revision_user' => 'revision_uid', 'revision_log_message' => 'revision_log'],
     ];
     foreach ($test_cases as $revision_metadata_field_names) {
       $this->setUp();
@@ -881,7 +897,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
       $this->fieldDefinitions = $this->mockFieldDefinitions($field_names);
 
       $revisionable_field_names = ['description', 'owner'];
-      $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, $revision_metadata_field_names), ['isRevisionable' => TRUE]);
+      $this->fieldDefinitions += $this->mockFieldDefinitions(array_merge($revisionable_field_names, array_values($revision_metadata_field_names)), ['isRevisionable' => TRUE]);
 
       $this->entityType->expects($this->atLeastOnce())
         ->method('isRevisionable')
@@ -901,6 +917,9 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
           ['revision', $entity_keys['revision']],
           ['langcode', $entity_keys['langcode']],
         ]));
+      $this->entityType->expects($this->any())
+        ->method('getRevisionMetadataKeys')
+        ->will($this->returnValue($revision_metadata_field_names));
 
       $this->setUpEntityStorage();
 
@@ -938,7 +957,7 @@ public function testGetTableMappingRevisionableTranslatableWithFields(array $ent
         $entity_keys['id'],
         $entity_keys['revision'],
         $entity_keys['langcode'],
-      ]), $revision_metadata_field_names);
+      ]), array_values($revision_metadata_field_names));
       $actual = $mapping->getFieldNames('entity_test_revision');
       $this->assertEquals($expected, $actual);
       // The UUID is not stored on the data table.
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/DefaultExceptionSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/FinalExceptionSubscriberTest.php
similarity index 52%
rename from core/tests/Drupal/Tests/Core/EventSubscriber/DefaultExceptionSubscriberTest.php
rename to core/tests/Drupal/Tests/Core/EventSubscriber/FinalExceptionSubscriberTest.php
index 6582500ee6..fbde643ed4 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/DefaultExceptionSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/FinalExceptionSubscriberTest.php
@@ -2,7 +2,7 @@
 
 namespace Drupal\Tests\Core\EventSubscriber;
 
-use Drupal\Core\EventSubscriber\DefaultExceptionSubscriber;
+use Drupal\Core\EventSubscriber\FinalExceptionSubscriber;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Response;
@@ -11,28 +11,31 @@
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 
 /**
- * @coversDefaultClass \Drupal\Core\EventSubscriber\DefaultExceptionSubscriber
+ * @coversDefaultClass \Drupal\Core\EventSubscriber\FinalExceptionSubscriber
  * @group EventSubscriber
  */
-class DefaultExceptionSubscriberTest extends UnitTestCase {
+class FinalExceptionSubscriberTest extends UnitTestCase {
 
   /**
    * @covers ::onException
-   * @covers ::onFormatUnknown
    */
   public function testOnExceptionWithUnknownFormat() {
     $config_factory = $this->getConfigFactoryStub();
 
     $kernel = $this->prophesize(HttpKernelInterface::class);
-    $request = Request::create('/test?_format=bananas');
+    $request = Request::create('/test');
+    // \Drupal\Core\StackMiddleware\NegotiationMiddleware normally takes care
+    // of this so we'll hard code it here.
+    $request->setRequestFormat('bananas');
     $e = new MethodNotAllowedHttpException(['POST', 'PUT'], 'test message');
     $event = new GetResponseForExceptionEvent($kernel->reveal(), $request, 'GET', $e);
-    $subscriber = new DefaultExceptionSubscriber($config_factory);
+    $subscriber = new TestDefaultExceptionSubscriber($config_factory);
+    $subscriber->setStringTranslation($this->getStringTranslationStub());
     $subscriber->onException($event);
     $response = $event->getResponse();
 
     $this->assertInstanceOf(Response::class, $response);
-    $this->assertEquals('test message', $response->getContent());
+    $this->stringStartsWith('The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException</em>: test message in ', $response->getContent());
     $this->assertEquals(405, $response->getStatusCode());
     $this->assertEquals('POST, PUT', $response->headers->get('Allow'));
     // Also check that that text/plain content type was added.
@@ -40,3 +43,19 @@ public function testOnExceptionWithUnknownFormat() {
   }
 
 }
+
+class TestDefaultExceptionSubscriber extends FinalExceptionSubscriber {
+
+  protected function isErrorDisplayable($error) {
+    return TRUE;
+  }
+
+  protected function simplifyFileInError($error) {
+    return $error;
+  }
+
+  protected function isErrorLevelVerbose() {
+    return TRUE;
+  }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/OptionsRequestSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/OptionsRequestSubscriberTest.php
index 46a331736b..e995616632 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/OptionsRequestSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/OptionsRequestSubscriberTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Core\EventSubscriber;
 
 use Drupal\Core\EventSubscriber\OptionsRequestSubscriber;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Cmf\Component\Routing\RouteProviderInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -14,7 +15,7 @@
  * @coversDefaultClass \Drupal\Core\EventSubscriber\OptionsRequestSubscriber
  * @group EventSubscriber
  */
-class OptionsRequestSubscriberTest extends \PHPUnit_Framework_TestCase {
+class OptionsRequestSubscriberTest extends UnitTestCase {
 
   /**
    * @covers ::onRequest
diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php
index f3b156e136..3d3d501523 100644
--- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskManagerTest.php
@@ -413,7 +413,7 @@ public function testGetTasksBuildWithCacheabilityMetadata() {
       ->method('getDefinitions')
       ->will($this->returnValue($definitions));
 
-    // Set up some cacheablity metadata and ensure its merged together.
+    // Set up some cacheability metadata and ensure its merged together.
     $definitions['menu_local_task_test_tasks_settings']['cache_tags'] = ['tag.example1'];
     $definitions['menu_local_task_test_tasks_settings']['cache_contexts'] = ['context.example1'];
     $definitions['menu_local_task_test_tasks_edit']['cache_tags'] = ['tag.example2'];
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php
index 22f3a880e4..21bbde83d8 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultSingleLazyPluginCollectionTest.php
@@ -58,6 +58,17 @@ public function testAddInstanceId() {
     $this->assertEquals(['id' => 'banana', 'key' => 'other_value'], $this->defaultPluginCollection->get('banana')->getConfiguration());
   }
 
+  /**
+   * @covers ::getInstanceIds
+   */
+  public function testGetInstanceIds() {
+    $this->setupPluginCollection($this->any());
+    $this->assertEquals(['apple' => 'apple'], $this->defaultPluginCollection->getInstanceIds());
+
+    $this->defaultPluginCollection->addInstanceId('banana', ['id' => 'banana', 'key' => 'other_value']);
+    $this->assertEquals(['banana' => 'banana'], $this->defaultPluginCollection->getInstanceIds());
+  }
+
 }
 
 class ConfigurablePlugin extends PluginBase implements ConfigurablePluginInterface {
diff --git a/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php b/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
index 9dac5dd623..7188a51d13 100644
--- a/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/BubbleableMetadataTest.php
@@ -671,7 +671,7 @@ public function testAddCacheableDependency(BubbleableMetadata $a, $b, Bubbleable
    *
    * @return array
    */
-  public function providerTestAddCachableDependency() {
+  public function providerTestAddCacheableDependency() {
     return [
       // Merge in a cacheable metadata.
       'merge-cacheable-metadata' => [
diff --git a/core/tests/Drupal/Tests/Core/Render/RendererTest.php b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
index 962ba1e22a..7ac4a90164 100644
--- a/core/tests/Drupal/Tests/Core/Render/RendererTest.php
+++ b/core/tests/Drupal/Tests/Core/Render/RendererTest.php
@@ -511,7 +511,7 @@ public function testRenderWithAccessControllerResolved($access) {
    * @covers ::render
    * @covers ::doRender
    */
-  public function testRenderAccessCacheablityDependencyInheritance() {
+  public function testRenderAccessCacheabilityDependencyInheritance() {
     $build = [
       '#access' => AccessResult::allowed()->addCacheContexts(['user']),
     ];
diff --git a/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php b/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php
index 1b72b75303..8a7554dec9 100644
--- a/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/MethodFilterTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\Core\Routing;
 
 use Drupal\Core\Routing\MethodFilter;
+use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
 use Symfony\Component\Routing\Route;
@@ -12,7 +13,7 @@
  * @coversDefaultClass \Drupal\Core\Routing\MethodFilter
  * @group Routing
  */
-class MethodFilterTest extends \PHPUnit_Framework_TestCase {
+class MethodFilterTest extends UnitTestCase {
 
   /**
    * @covers ::applies
diff --git a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
index b9dc671faa..c9bccceec9 100644
--- a/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/AttributeTest.php
@@ -261,6 +261,8 @@ public function testChainAddRemoveClasses() {
    *
    * @covers ::removeClass
    * @covers ::addClass
+   *
+   * @group legacy
    */
   public function testTwigAddRemoveClasses($template, $expected, $seed_attributes = []) {
     $loader = new \Twig_Loader_String();
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
index c4805bc382..a872e305d4 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -15,6 +15,7 @@
  * Tests the twig extension.
  *
  * @group Template
+ * @group legacy
  *
  * @coversDefaultClass \Drupal\Core\Template\TwigExtension
  */
@@ -73,6 +74,8 @@ public function setUp() {
    * Tests the escaping
    *
    * @dataProvider providerTestEscaping
+   *
+   * @group legacy
    */
   public function testEscaping($template, $expected) {
     $twig = new \Twig_Environment(NULL, [
@@ -123,6 +126,8 @@ public function providerTestEscaping() {
 
   /**
    * Tests the active_theme function.
+   *
+   * @group legacy
    */
   public function testActiveTheme() {
     $active_theme = $this->getMockBuilder('\Drupal\Core\Theme\ActiveTheme')
@@ -183,6 +188,8 @@ public function testActiveThemePath() {
    * Tests the escaping of objects implementing MarkupInterface.
    *
    * @covers ::escapeFilter
+   *
+   * @group legacy
    */
   public function testSafeStringEscaping() {
     $twig = new \Twig_Environment(NULL, [
@@ -267,6 +274,8 @@ public function providerTestRenderVar() {
   /**
    * @covers ::escapeFilter
    * @covers ::bubbleArgMetadata
+   *
+   * @group legacy
    */
   public function testEscapeWithGeneratedLink() {
     $twig = new \Twig_Environment(NULL, [
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php b/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php
index e599463485..1bbb9f4dd1 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php
@@ -16,6 +16,7 @@
  * Tests the twig sandbox policy.
  *
  * @group Template
+ * @group legacy
  *
  * @coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy
  */
diff --git a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php
index 7f8396fe07..fa2541886e 100644
--- a/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php
+++ b/core/tests/Drupal/Tests/Listeners/DrupalStandardsListener.php
@@ -2,23 +2,26 @@
 
 namespace Drupal\Tests\Listeners;
 
+use PHPUnit\Framework\BaseTestListener;
+use PHPUnit\Framework\TestCase;
+
 /**
  * Listens for PHPUnit tests and fails those with invalid coverage annotations.
  *
  * Enforces various coding standards within test runs.
  */
-class DrupalStandardsListener extends \PHPUnit_Framework_BaseTestListener {
+class DrupalStandardsListener extends BaseTestListener {
 
   /**
    * Signals a coding standards failure to the user.
    *
-   * @param \PHPUnit_Framework_TestCase $test
+   * @param \PHPUnit\Framework\TestCase $test
    *   The test where we should insert our test failure.
    * @param string $message
    *   The message to add to the failure notice. The test class name and test
    *   name will be appended to this message automatically.
    */
-  protected function fail(\PHPUnit_Framework_TestCase $test, $message) {
+  protected function fail(TestCase $test, $message) {
     // Add the report to the test's results.
     $message .= ': ' . get_class($test) . '::' . $test->getName();
     $fail = new \PHPUnit_Framework_AssertionFailedError($message);
@@ -44,10 +47,10 @@ protected function classExists($class) {
    *
    * This method is called from $this::endTest().
    *
-   * @param \PHPUnit_Framework_TestCase $test
+   * @param \PHPUnit\Framework\TestCase $test
    *   The test to examine.
    */
-  public function checkValidCoversForTest(\PHPUnit_Framework_TestCase $test) {
+  public function checkValidCoversForTest(TestCase $test) {
     // If we're generating a coverage report already, don't do anything here.
     if ($test->getTestResultObject() && $test->getTestResultObject()->getCollectCodeCoverageInformation()) {
       return;
@@ -144,7 +147,7 @@ public function endTest(\PHPUnit_Framework_Test $test, $time) {
     // \PHPUnit_Framework_Test does not have any useful methods of its own for
     // our purpose, so we have to distinguish between the different known
     // subclasses.
-    if ($test instanceof \PHPUnit_Framework_TestCase) {
+    if ($test instanceof TestCase) {
       $this->checkValidCoversForTest($test);
     }
     elseif ($test instanceof \PHPUnit_Framework_TestSuite) {
diff --git a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php
index 0ba8143427..5b1d546b51 100644
--- a/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php
+++ b/core/tests/Drupal/Tests/TestSuites/TestSuiteBaseTest.php
@@ -3,6 +3,7 @@
 namespace Drupal\Tests\TestSuites;
 
 use org\bovigo\vfs\vfsStream;
+use PHPUnit\Framework\TestCase;
 
 // The test suite class is not part of the autoloader, we need to include it
 // manually.
@@ -13,7 +14,7 @@
  *
  * @group TestSuite
  */
-class TestSuiteBaseTest extends \PHPUnit_Framework_TestCase {
+class TestSuiteBaseTest extends TestCase {
 
   /**
    * Helper method to set up the file system.
diff --git a/core/tests/Drupal/Tests/UnitTestCase.php b/core/tests/Drupal/Tests/UnitTestCase.php
index f96b5109e8..8aaeb85743 100644
--- a/core/tests/Drupal/Tests/UnitTestCase.php
+++ b/core/tests/Drupal/Tests/UnitTestCase.php
@@ -8,6 +8,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
+use PHPUnit\Framework\TestCase;
 
 
 /**
@@ -15,7 +16,7 @@
  *
  * @ingroup testing
  */
-abstract class UnitTestCase extends \PHPUnit_Framework_TestCase {
+abstract class UnitTestCase extends TestCase {
 
   /**
    * The random generator.
diff --git a/core/themes/classy/classy.info.yml b/core/themes/classy/classy.info.yml
index 05ef0d7981..4685c3faf5 100644
--- a/core/themes/classy/classy.info.yml
+++ b/core/themes/classy/classy.info.yml
@@ -8,6 +8,7 @@ hidden: true
 
 libraries:
   - classy/base
+  - classy/messages
   - core/normalize
 
 libraries-extend:
diff --git a/core/themes/classy/templates/misc/status-messages.html.twig b/core/themes/classy/templates/misc/status-messages.html.twig
index bc8fd106c2..282df38ef2 100644
--- a/core/themes/classy/templates/misc/status-messages.html.twig
+++ b/core/themes/classy/templates/misc/status-messages.html.twig
@@ -21,7 +21,6 @@
  *   - class: HTML classes.
  */
 #}
-{{ attach_library('classy/messages') }}
 {% block messages %}
 {% for type, messages in message_list %}
   {%
diff --git a/core/themes/seven/css/components/dropbutton.component.css b/core/themes/seven/css/components/dropbutton.component.css
index 229f1bdd02..bc3e87319f 100644
--- a/core/themes/seven/css/components/dropbutton.component.css
+++ b/core/themes/seven/css/components/dropbutton.component.css
@@ -203,6 +203,9 @@
   -webkit-transition: none;
   transition: none;
 }
+.dropbutton-single .dropbutton-action a.use-ajax{
+  float: left;
+}
 
 /**
  * The dropdown trigger.
diff --git a/core/themes/seven/css/components/jquery.ui/theme.css b/core/themes/seven/css/components/jquery.ui/theme.css
index 02dc83d168..dd81ec26a5 100644
--- a/core/themes/seven/css/components/jquery.ui/theme.css
+++ b/core/themes/seven/css/components/jquery.ui/theme.css
@@ -33,8 +33,6 @@
 .ui-state-active,
 .ui-widget-content .ui-state-active {
   color: #840;
-  background: #fe6;
-  border: solid 1px #ed5;
 }
 .ui-state-error,
 .ui-widget-content .ui-state-error {
diff --git a/core/themes/seven/css/components/tables.css b/core/themes/seven/css/components/tables.css
index 816df9e909..5464456edd 100644
--- a/core/themes/seven/css/components/tables.css
+++ b/core/themes/seven/css/components/tables.css
@@ -48,6 +48,10 @@ tbody tr.color-error:focus {
   background: #fcf4f2;
 }
 
+table.no-highlight tr.selected td {
+  background: transparent;
+}
+
 td,
 th {
   vertical-align: middle;
diff --git a/core/yarn.lock b/core/yarn.lock
new file mode 100644
index 0000000000..0bea444cee
--- /dev/null
+++ b/core/yarn.lock
@@ -0,0 +1,2361 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+abbrev@1:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f"
+
+acorn-jsx@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
+  dependencies:
+    acorn "^3.0.4"
+
+acorn@^3.0.4:
+  version "3.3.0"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
+
+acorn@^5.0.1:
+  version "5.0.3"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
+
+ajv-keywords@^1.0.0:
+  version "1.5.1"
+  resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
+
+ajv@^4.7.0, ajv@^4.9.1:
+  version "4.11.8"
+  resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
+  dependencies:
+    co "^4.6.0"
+    json-stable-stringify "^1.0.1"
+
+ansi-escapes@^1.1.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
+
+ansi-regex@^2.0.0:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
+
+ansi-styles@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
+
+anymatch@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
+  dependencies:
+    arrify "^1.0.0"
+    micromatch "^2.1.5"
+
+aproba@^1.0.3:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab"
+
+are-we-there-yet@~1.1.2:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d"
+  dependencies:
+    delegates "^1.0.0"
+    readable-stream "^2.0.6"
+
+argparse@^1.0.7:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
+  dependencies:
+    sprintf-js "~1.0.2"
+
+aria-query@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-0.3.0.tgz#cb8a9984e2862711c83c80ade5b8f5ca0de2b467"
+  dependencies:
+    ast-types-flow "0.0.7"
+
+arr-diff@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf"
+  dependencies:
+    arr-flatten "^1.0.1"
+
+arr-flatten@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1"
+
+array-union@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
+  dependencies:
+    array-uniq "^1.0.1"
+
+array-uniq@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
+
+array-unique@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
+
+array.prototype.find@^2.0.1:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90"
+  dependencies:
+    define-properties "^1.1.2"
+    es-abstract "^1.7.0"
+
+arrify@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
+
+asn1@~0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
+
+assert-plus@1.0.0, assert-plus@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
+
+assert-plus@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
+
+ast-types-flow@0.0.7:
+  version "0.0.7"
+  resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
+
+async-each@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
+
+asynckit@^0.4.0:
+  version "0.4.0"
+  resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
+
+aws-sign2@~0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
+
+aws4@^1.2.1:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
+
+babel-code-frame@^6.16.0, babel-code-frame@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
+  dependencies:
+    chalk "^1.1.0"
+    esutils "^2.0.2"
+    js-tokens "^3.0.0"
+
+babel-core@6.24.1, babel-core@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.1.tgz#8c428564dce1e1f41fb337ec34f4c3b022b5ad83"
+  dependencies:
+    babel-code-frame "^6.22.0"
+    babel-generator "^6.24.1"
+    babel-helpers "^6.24.1"
+    babel-messages "^6.23.0"
+    babel-register "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+    babylon "^6.11.0"
+    convert-source-map "^1.1.0"
+    debug "^2.1.1"
+    json5 "^0.5.0"
+    lodash "^4.2.0"
+    minimatch "^3.0.2"
+    path-is-absolute "^1.0.0"
+    private "^0.1.6"
+    slash "^1.0.0"
+    source-map "^0.5.0"
+
+babel-generator@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.1.tgz#e715f486c58ded25649d888944d52aa07c5d9497"
+  dependencies:
+    babel-messages "^6.23.0"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+    detect-indent "^4.0.0"
+    jsesc "^1.3.0"
+    lodash "^4.2.0"
+    source-map "^0.5.0"
+    trim-right "^1.0.1"
+
+babel-helper-builder-binary-assignment-operator-visitor@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664"
+  dependencies:
+    babel-helper-explode-assignable-expression "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-helper-call-delegate@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d"
+  dependencies:
+    babel-helper-hoist-variables "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-helper-define-map@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080"
+  dependencies:
+    babel-helper-function-name "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+    lodash "^4.2.0"
+
+babel-helper-explode-assignable-expression@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-helper-function-name@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9"
+  dependencies:
+    babel-helper-get-function-arity "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-helper-get-function-arity@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-helper-hoist-variables@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-helper-optimise-call-expression@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-helper-regex@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+    lodash "^4.2.0"
+
+babel-helper-remap-async-to-generator@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b"
+  dependencies:
+    babel-helper-function-name "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-helper-replace-supers@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a"
+  dependencies:
+    babel-helper-optimise-call-expression "^6.24.1"
+    babel-messages "^6.23.0"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-helpers@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-messages@^6.23.0:
+  version "6.23.0"
+  resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-check-es2015-constants@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-syntax-async-functions@^6.8.0:
+  version "6.13.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95"
+
+babel-plugin-syntax-exponentiation-operator@^6.8.0:
+  version "6.13.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de"
+
+babel-plugin-syntax-trailing-function-commas@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3"
+
+babel-plugin-transform-async-to-generator@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761"
+  dependencies:
+    babel-helper-remap-async-to-generator "^6.24.1"
+    babel-plugin-syntax-async-functions "^6.8.0"
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-arrow-functions@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-block-scoped-functions@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-block-scoping@^6.23.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+    lodash "^4.2.0"
+
+babel-plugin-transform-es2015-classes@^6.23.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db"
+  dependencies:
+    babel-helper-define-map "^6.24.1"
+    babel-helper-function-name "^6.24.1"
+    babel-helper-optimise-call-expression "^6.24.1"
+    babel-helper-replace-supers "^6.24.1"
+    babel-messages "^6.23.0"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-computed-properties@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-destructuring@^6.23.0:
+  version "6.23.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-duplicate-keys@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-for-of@^6.23.0:
+  version "6.23.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-function-name@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b"
+  dependencies:
+    babel-helper-function-name "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-literals@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154"
+  dependencies:
+    babel-plugin-transform-es2015-modules-commonjs "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe"
+  dependencies:
+    babel-plugin-transform-strict-mode "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-modules-systemjs@^6.23.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23"
+  dependencies:
+    babel-helper-hoist-variables "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-modules-umd@^6.23.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468"
+  dependencies:
+    babel-plugin-transform-es2015-modules-amd "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+
+babel-plugin-transform-es2015-object-super@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d"
+  dependencies:
+    babel-helper-replace-supers "^6.24.1"
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-parameters@^6.23.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b"
+  dependencies:
+    babel-helper-call-delegate "^6.24.1"
+    babel-helper-get-function-arity "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-template "^6.24.1"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-shorthand-properties@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-spread@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-sticky-regex@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc"
+  dependencies:
+    babel-helper-regex "^6.24.1"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-plugin-transform-es2015-template-literals@^6.22.0:
+  version "6.22.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-typeof-symbol@^6.23.0:
+  version "6.23.0"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372"
+  dependencies:
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-es2015-unicode-regex@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9"
+  dependencies:
+    babel-helper-regex "^6.24.1"
+    babel-runtime "^6.22.0"
+    regexpu-core "^2.0.0"
+
+babel-plugin-transform-exponentiation-operator@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e"
+  dependencies:
+    babel-helper-builder-binary-assignment-operator-visitor "^6.24.1"
+    babel-plugin-syntax-exponentiation-operator "^6.8.0"
+    babel-runtime "^6.22.0"
+
+babel-plugin-transform-regenerator@^6.22.0:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418"
+  dependencies:
+    regenerator-transform "0.9.11"
+
+babel-plugin-transform-strict-mode@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+
+babel-preset-env@1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.4.0.tgz#c8e02a3bcc7792f23cded68e0355b9d4c28f0f7a"
+  dependencies:
+    babel-plugin-check-es2015-constants "^6.22.0"
+    babel-plugin-syntax-trailing-function-commas "^6.22.0"
+    babel-plugin-transform-async-to-generator "^6.22.0"
+    babel-plugin-transform-es2015-arrow-functions "^6.22.0"
+    babel-plugin-transform-es2015-block-scoped-functions "^6.22.0"
+    babel-plugin-transform-es2015-block-scoping "^6.23.0"
+    babel-plugin-transform-es2015-classes "^6.23.0"
+    babel-plugin-transform-es2015-computed-properties "^6.22.0"
+    babel-plugin-transform-es2015-destructuring "^6.23.0"
+    babel-plugin-transform-es2015-duplicate-keys "^6.22.0"
+    babel-plugin-transform-es2015-for-of "^6.23.0"
+    babel-plugin-transform-es2015-function-name "^6.22.0"
+    babel-plugin-transform-es2015-literals "^6.22.0"
+    babel-plugin-transform-es2015-modules-amd "^6.22.0"
+    babel-plugin-transform-es2015-modules-commonjs "^6.23.0"
+    babel-plugin-transform-es2015-modules-systemjs "^6.23.0"
+    babel-plugin-transform-es2015-modules-umd "^6.23.0"
+    babel-plugin-transform-es2015-object-super "^6.22.0"
+    babel-plugin-transform-es2015-parameters "^6.23.0"
+    babel-plugin-transform-es2015-shorthand-properties "^6.22.0"
+    babel-plugin-transform-es2015-spread "^6.22.0"
+    babel-plugin-transform-es2015-sticky-regex "^6.22.0"
+    babel-plugin-transform-es2015-template-literals "^6.22.0"
+    babel-plugin-transform-es2015-typeof-symbol "^6.23.0"
+    babel-plugin-transform-es2015-unicode-regex "^6.22.0"
+    babel-plugin-transform-exponentiation-operator "^6.22.0"
+    babel-plugin-transform-regenerator "^6.22.0"
+    browserslist "^1.4.0"
+    invariant "^2.2.2"
+
+babel-register@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f"
+  dependencies:
+    babel-core "^6.24.1"
+    babel-runtime "^6.22.0"
+    core-js "^2.4.0"
+    home-or-tmp "^2.0.0"
+    lodash "^4.2.0"
+    mkdirp "^0.5.1"
+    source-map-support "^0.4.2"
+
+babel-runtime@^6.18.0, babel-runtime@^6.22.0:
+  version "6.23.0"
+  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
+  dependencies:
+    core-js "^2.4.0"
+    regenerator-runtime "^0.10.0"
+
+babel-template@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.24.1.tgz#04ae514f1f93b3a2537f2a0f60a5a45fb8308333"
+  dependencies:
+    babel-runtime "^6.22.0"
+    babel-traverse "^6.24.1"
+    babel-types "^6.24.1"
+    babylon "^6.11.0"
+    lodash "^4.2.0"
+
+babel-traverse@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.24.1.tgz#ab36673fd356f9a0948659e7b338d5feadb31695"
+  dependencies:
+    babel-code-frame "^6.22.0"
+    babel-messages "^6.23.0"
+    babel-runtime "^6.22.0"
+    babel-types "^6.24.1"
+    babylon "^6.15.0"
+    debug "^2.2.0"
+    globals "^9.0.0"
+    invariant "^2.2.0"
+    lodash "^4.2.0"
+
+babel-types@^6.19.0, babel-types@^6.24.1:
+  version "6.24.1"
+  resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.24.1.tgz#a136879dc15b3606bda0d90c1fc74304c2ff0975"
+  dependencies:
+    babel-runtime "^6.22.0"
+    esutils "^2.0.2"
+    lodash "^4.2.0"
+    to-fast-properties "^1.0.1"
+
+babylon@^6.11.0, babylon@^6.15.0:
+  version "6.17.0"
+  resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.0.tgz#37da948878488b9c4e3c4038893fa3314b3fc932"
+
+balanced-match@^0.4.1:
+  version "0.4.2"
+  resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
+
+bcrypt-pbkdf@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
+  dependencies:
+    tweetnacl "^0.14.3"
+
+binary-extensions@^1.0.0:
+  version "1.8.0"
+  resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774"
+
+block-stream@*:
+  version "0.0.9"
+  resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
+  dependencies:
+    inherits "~2.0.0"
+
+boom@2.x.x:
+  version "2.10.1"
+  resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
+  dependencies:
+    hoek "2.x.x"
+
+brace-expansion@^1.0.0:
+  version "1.1.7"
+  resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.7.tgz#3effc3c50e000531fb720eaff80f0ae8ef23cf59"
+  dependencies:
+    balanced-match "^0.4.1"
+    concat-map "0.0.1"
+
+braces@^1.8.2:
+  version "1.8.5"
+  resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7"
+  dependencies:
+    expand-range "^1.8.1"
+    preserve "^0.2.0"
+    repeat-element "^1.1.2"
+
+browserslist@^1.4.0:
+  version "1.7.7"
+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9"
+  dependencies:
+    caniuse-db "^1.0.30000639"
+    electron-to-chromium "^1.2.7"
+
+buffer-shims@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51"
+
+builtin-modules@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
+
+caller-path@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
+  dependencies:
+    callsites "^0.2.0"
+
+callsites@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
+
+caniuse-db@^1.0.30000639:
+  version "1.0.30000664"
+  resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000664.tgz#e16316e5fdabb9c7209b2bf0744ffc8a14201f22"
+
+caseless@~0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
+
+chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
+  dependencies:
+    ansi-styles "^2.2.1"
+    escape-string-regexp "^1.0.2"
+    has-ansi "^2.0.0"
+    strip-ansi "^3.0.0"
+    supports-color "^2.0.0"
+
+chokidar@1.6.1:
+  version "1.6.1"
+  resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2"
+  dependencies:
+    anymatch "^1.3.0"
+    async-each "^1.0.0"
+    glob-parent "^2.0.0"
+    inherits "^2.0.1"
+    is-binary-path "^1.0.0"
+    is-glob "^2.0.0"
+    path-is-absolute "^1.0.0"
+    readdirp "^2.0.0"
+  optionalDependencies:
+    fsevents "^1.0.0"
+
+circular-json@^0.3.1:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
+
+cli-cursor@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
+  dependencies:
+    restore-cursor "^1.0.1"
+
+cli-width@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
+
+co@^4.6.0:
+  version "4.6.0"
+  resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
+
+code-point-at@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+
+combined-stream@^1.0.5, combined-stream@~1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
+  dependencies:
+    delayed-stream "~1.0.0"
+
+concat-map@0.0.1:
+  version "0.0.1"
+  resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+
+concat-stream@^1.5.2:
+  version "1.6.0"
+  resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
+  dependencies:
+    inherits "^2.0.3"
+    readable-stream "^2.2.2"
+    typedarray "^0.0.6"
+
+console-control-strings@^1.0.0, console-control-strings@~1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
+
+contains-path@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a"
+
+convert-source-map@^1.1.0:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
+
+core-js@^2.4.0:
+  version "2.4.1"
+  resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
+
+core-util-is@~1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
+
+cross-env@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-4.0.0.tgz#16083862d08275a4628b0b243b121bedaa55dd80"
+  dependencies:
+    cross-spawn "^5.1.0"
+    is-windows "^1.0.0"
+
+cross-spawn@^5.1.0:
+  version "5.1.0"
+  resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449"
+  dependencies:
+    lru-cache "^4.0.1"
+    shebang-command "^1.2.0"
+    which "^1.2.9"
+
+cryptiles@2.x.x:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
+  dependencies:
+    boom "2.x.x"
+
+d@1:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
+  dependencies:
+    es5-ext "^0.10.9"
+
+damerau-levenshtein@^1.0.0:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514"
+
+dashdash@^1.12.0:
+  version "1.14.1"
+  resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
+  dependencies:
+    assert-plus "^1.0.0"
+
+debug@2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da"
+  dependencies:
+    ms "0.7.1"
+
+debug@^2.1.1, debug@^2.2.0:
+  version "2.6.6"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.6.tgz#a9fa6fbe9ca43cf1e79f73b75c0189cbb7d6db5a"
+  dependencies:
+    ms "0.7.3"
+
+deep-extend@~0.4.0:
+  version "0.4.1"
+  resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253"
+
+deep-is@~0.1.3:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
+
+define-properties@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
+  dependencies:
+    foreach "^2.0.5"
+    object-keys "^1.0.8"
+
+del@^2.0.2:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
+  dependencies:
+    globby "^5.0.0"
+    is-path-cwd "^1.0.0"
+    is-path-in-cwd "^1.0.0"
+    object-assign "^4.0.1"
+    pify "^2.0.0"
+    pinkie-promise "^2.0.0"
+    rimraf "^2.2.8"
+
+delayed-stream@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
+
+delegates@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
+
+detect-indent@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
+  dependencies:
+    repeating "^2.0.0"
+
+doctrine@1.5.0, doctrine@^1.2.2:
+  version "1.5.0"
+  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
+  dependencies:
+    esutils "^2.0.2"
+    isarray "^1.0.0"
+
+doctrine@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
+  dependencies:
+    esutils "^2.0.2"
+    isarray "^1.0.0"
+
+ecc-jsbn@~0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
+  dependencies:
+    jsbn "~0.1.0"
+
+electron-to-chromium@^1.2.7:
+  version "1.3.8"
+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.8.tgz#b2c8a2c79bb89fbbfd3724d9555e15095b5f5fb6"
+
+emoji-regex@^6.1.0:
+  version "6.4.2"
+  resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.4.2.tgz#a30b6fee353d406d96cfb9fa765bdc82897eff6e"
+
+es-abstract@^1.7.0:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c"
+  dependencies:
+    es-to-primitive "^1.1.1"
+    function-bind "^1.1.0"
+    is-callable "^1.1.3"
+    is-regex "^1.0.3"
+
+es-to-primitive@^1.1.1:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
+  dependencies:
+    is-callable "^1.1.1"
+    is-date-object "^1.0.1"
+    is-symbol "^1.0.1"
+
+es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
+  version "0.10.15"
+  resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6"
+  dependencies:
+    es6-iterator "2"
+    es6-symbol "~3.1"
+
+es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
+  dependencies:
+    d "1"
+    es5-ext "^0.10.14"
+    es6-symbol "^3.1"
+
+es6-map@^0.1.3:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+    es6-iterator "~2.0.1"
+    es6-set "~0.1.5"
+    es6-symbol "~3.1.1"
+    event-emitter "~0.3.5"
+
+es6-set@~0.1.5:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+    es6-iterator "~2.0.1"
+    es6-symbol "3.1.1"
+    event-emitter "~0.3.5"
+
+es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1:
+  version "3.1.1"
+  resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+
+es6-weak-map@^2.0.1:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
+  dependencies:
+    d "1"
+    es5-ext "^0.10.14"
+    es6-iterator "^2.0.1"
+    es6-symbol "^3.1.1"
+
+escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
+
+escope@^3.6.0:
+  version "3.6.0"
+  resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
+  dependencies:
+    es6-map "^0.1.3"
+    es6-weak-map "^2.0.1"
+    esrecurse "^4.1.0"
+    estraverse "^4.1.1"
+
+eslint-config-airbnb-base@^11.1.0:
+  version "11.1.3"
+  resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.3.tgz#0e8db71514fa36b977fbcf977c01edcf863e0cf0"
+
+eslint-config-airbnb@14.1.0:
+  version "14.1.0"
+  resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-14.1.0.tgz#355d290040bbf8e00bf8b4b19f4b70cbe7c2317f"
+  dependencies:
+    eslint-config-airbnb-base "^11.1.0"
+
+eslint-import-resolver-node@^0.2.0:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c"
+  dependencies:
+    debug "^2.2.0"
+    object-assign "^4.0.1"
+    resolve "^1.1.6"
+
+eslint-module-utils@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce"
+  dependencies:
+    debug "2.2.0"
+    pkg-dir "^1.0.0"
+
+eslint-plugin-import@2.2.0:
+  version "2.2.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e"
+  dependencies:
+    builtin-modules "^1.1.1"
+    contains-path "^0.1.0"
+    debug "^2.2.0"
+    doctrine "1.5.0"
+    eslint-import-resolver-node "^0.2.0"
+    eslint-module-utils "^2.0.0"
+    has "^1.0.1"
+    lodash.cond "^4.3.0"
+    minimatch "^3.0.3"
+    pkg-up "^1.0.0"
+
+eslint-plugin-jsx-a11y@4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-4.0.0.tgz#779bb0fe7b08da564a422624911de10061e048ee"
+  dependencies:
+    aria-query "^0.3.0"
+    ast-types-flow "0.0.7"
+    damerau-levenshtein "^1.0.0"
+    emoji-regex "^6.1.0"
+    jsx-ast-utils "^1.0.0"
+    object-assign "^4.0.1"
+
+eslint-plugin-react@6.10.3:
+  version "6.10.3"
+  resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz#c5435beb06774e12c7db2f6abaddcbf900cd3f78"
+  dependencies:
+    array.prototype.find "^2.0.1"
+    doctrine "^1.2.2"
+    has "^1.0.1"
+    jsx-ast-utils "^1.3.4"
+    object.assign "^4.0.4"
+
+eslint@3.19.0:
+  version "3.19.0"
+  resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
+  dependencies:
+    babel-code-frame "^6.16.0"
+    chalk "^1.1.3"
+    concat-stream "^1.5.2"
+    debug "^2.1.1"
+    doctrine "^2.0.0"
+    escope "^3.6.0"
+    espree "^3.4.0"
+    esquery "^1.0.0"
+    estraverse "^4.2.0"
+    esutils "^2.0.2"
+    file-entry-cache "^2.0.0"
+    glob "^7.0.3"
+    globals "^9.14.0"
+    ignore "^3.2.0"
+    imurmurhash "^0.1.4"
+    inquirer "^0.12.0"
+    is-my-json-valid "^2.10.0"
+    is-resolvable "^1.0.0"
+    js-yaml "^3.5.1"
+    json-stable-stringify "^1.0.0"
+    levn "^0.3.0"
+    lodash "^4.0.0"
+    mkdirp "^0.5.0"
+    natural-compare "^1.4.0"
+    optionator "^0.8.2"
+    path-is-inside "^1.0.1"
+    pluralize "^1.2.1"
+    progress "^1.1.8"
+    require-uncached "^1.0.2"
+    shelljs "^0.7.5"
+    strip-bom "^3.0.0"
+    strip-json-comments "~2.0.1"
+    table "^3.7.8"
+    text-table "~0.2.0"
+    user-home "^2.0.0"
+
+espree@^3.4.0:
+  version "3.4.2"
+  resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.2.tgz#38dbdedbedc95b8961a1fbf04734a8f6a9c8c592"
+  dependencies:
+    acorn "^5.0.1"
+    acorn-jsx "^3.0.0"
+
+esprima@^3.1.1:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+
+esquery@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
+  dependencies:
+    estraverse "^4.0.0"
+
+esrecurse@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220"
+  dependencies:
+    estraverse "~4.1.0"
+    object-assign "^4.0.1"
+
+estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0:
+  version "4.2.0"
+  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
+
+estraverse@~4.1.0:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2"
+
+esutils@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
+
+event-emitter@~0.3.5:
+  version "0.3.5"
+  resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
+  dependencies:
+    d "1"
+    es5-ext "~0.10.14"
+
+exit-hook@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
+
+expand-brackets@^0.1.4:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b"
+  dependencies:
+    is-posix-bracket "^0.1.0"
+
+expand-range@^1.8.1:
+  version "1.8.2"
+  resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337"
+  dependencies:
+    fill-range "^2.1.0"
+
+extend@~3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
+
+extglob@^0.3.1:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1"
+  dependencies:
+    is-extglob "^1.0.0"
+
+extsprintf@1.0.2:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
+
+fast-levenshtein@~2.0.4:
+  version "2.0.6"
+  resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
+
+figures@^1.3.5:
+  version "1.7.0"
+  resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
+  dependencies:
+    escape-string-regexp "^1.0.5"
+    object-assign "^4.1.0"
+
+file-entry-cache@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
+  dependencies:
+    flat-cache "^1.2.1"
+    object-assign "^4.0.1"
+
+filename-regex@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26"
+
+fill-range@^2.1.0:
+  version "2.2.3"
+  resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723"
+  dependencies:
+    is-number "^2.1.0"
+    isobject "^2.0.0"
+    randomatic "^1.1.3"
+    repeat-element "^1.1.2"
+    repeat-string "^1.5.2"
+
+find-up@^1.0.0:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
+  dependencies:
+    path-exists "^2.0.0"
+    pinkie-promise "^2.0.0"
+
+flat-cache@^1.2.1:
+  version "1.2.2"
+  resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
+  dependencies:
+    circular-json "^0.3.1"
+    del "^2.0.2"
+    graceful-fs "^4.1.2"
+    write "^0.2.1"
+
+for-in@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
+
+for-own@^0.1.4:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce"
+  dependencies:
+    for-in "^1.0.1"
+
+foreach@^2.0.5:
+  version "2.0.5"
+  resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
+
+forever-agent@~0.6.1:
+  version "0.6.1"
+  resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
+
+form-data@~2.1.1:
+  version "2.1.4"
+  resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
+  dependencies:
+    asynckit "^0.4.0"
+    combined-stream "^1.0.5"
+    mime-types "^2.1.12"
+
+fs.realpath@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+
+fsevents@^1.0.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff"
+  dependencies:
+    nan "^2.3.0"
+    node-pre-gyp "^0.6.29"
+
+fstream-ignore@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105"
+  dependencies:
+    fstream "^1.0.0"
+    inherits "2"
+    minimatch "^3.0.0"
+
+fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2:
+  version "1.0.11"
+  resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171"
+  dependencies:
+    graceful-fs "^4.1.2"
+    inherits "~2.0.0"
+    mkdirp ">=0.5 0"
+    rimraf "2"
+
+function-bind@^1.0.2, function-bind@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
+
+gauge@~2.7.1:
+  version "2.7.4"
+  resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
+  dependencies:
+    aproba "^1.0.3"
+    console-control-strings "^1.0.0"
+    has-unicode "^2.0.0"
+    object-assign "^4.1.0"
+    signal-exit "^3.0.0"
+    string-width "^1.0.1"
+    strip-ansi "^3.0.1"
+    wide-align "^1.1.0"
+
+generate-function@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
+
+generate-object-property@^1.1.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
+  dependencies:
+    is-property "^1.0.0"
+
+getpass@^0.1.1:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
+  dependencies:
+    assert-plus "^1.0.0"
+
+glob-base@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
+  dependencies:
+    glob-parent "^2.0.0"
+    is-glob "^2.0.0"
+
+glob-parent@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28"
+  dependencies:
+    is-glob "^2.0.0"
+
+glob@7.1.1, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+  dependencies:
+    fs.realpath "^1.0.0"
+    inflight "^1.0.4"
+    inherits "2"
+    minimatch "^3.0.2"
+    once "^1.3.0"
+    path-is-absolute "^1.0.0"
+
+globals@^9.0.0, globals@^9.14.0:
+  version "9.17.0"
+  resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286"
+
+globby@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
+  dependencies:
+    array-union "^1.0.1"
+    arrify "^1.0.0"
+    glob "^7.0.3"
+    object-assign "^4.0.1"
+    pify "^2.0.0"
+    pinkie-promise "^2.0.0"
+
+graceful-fs@^4.1.2:
+  version "4.1.11"
+  resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
+
+har-schema@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
+
+har-validator@~4.2.1:
+  version "4.2.1"
+  resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
+  dependencies:
+    ajv "^4.9.1"
+    har-schema "^1.0.5"
+
+has-ansi@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
+  dependencies:
+    ansi-regex "^2.0.0"
+
+has-unicode@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
+
+has@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28"
+  dependencies:
+    function-bind "^1.0.2"
+
+hawk@~3.1.3:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
+  dependencies:
+    boom "2.x.x"
+    cryptiles "2.x.x"
+    hoek "2.x.x"
+    sntp "1.x.x"
+
+hoek@2.x.x:
+  version "2.16.3"
+  resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
+
+home-or-tmp@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
+  dependencies:
+    os-homedir "^1.0.0"
+    os-tmpdir "^1.0.1"
+
+http-signature@~1.1.0:
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
+  dependencies:
+    assert-plus "^0.2.0"
+    jsprim "^1.2.2"
+    sshpk "^1.7.0"
+
+ignore@^3.2.0:
+  version "3.2.7"
+  resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.7.tgz#4810ca5f1d8eca5595213a34b94f2eb4ed926bbd"
+
+imurmurhash@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
+
+inflight@^1.0.4:
+  version "1.0.6"
+  resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+  dependencies:
+    once "^1.3.0"
+    wrappy "1"
+
+inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+
+ini@~1.3.0:
+  version "1.3.4"
+  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e"
+
+inquirer@^0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
+  dependencies:
+    ansi-escapes "^1.1.0"
+    ansi-regex "^2.0.0"
+    chalk "^1.0.0"
+    cli-cursor "^1.0.1"
+    cli-width "^2.0.0"
+    figures "^1.3.5"
+    lodash "^4.3.0"
+    readline2 "^1.0.1"
+    run-async "^0.1.0"
+    rx-lite "^3.1.2"
+    string-width "^1.0.1"
+    strip-ansi "^3.0.0"
+    through "^2.3.6"
+
+interpret@^1.0.0:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
+
+invariant@^2.2.0, invariant@^2.2.2:
+  version "2.2.2"
+  resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
+  dependencies:
+    loose-envify "^1.0.0"
+
+is-binary-path@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898"
+  dependencies:
+    binary-extensions "^1.0.0"
+
+is-buffer@^1.1.5:
+  version "1.1.5"
+  resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc"
+
+is-callable@^1.1.1, is-callable@^1.1.3:
+  version "1.1.3"
+  resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
+
+is-date-object@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
+
+is-dotfile@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d"
+
+is-equal-shallow@^0.1.3:
+  version "0.1.3"
+  resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534"
+  dependencies:
+    is-primitive "^2.0.0"
+
+is-extendable@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
+
+is-extglob@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
+
+is-finite@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
+  dependencies:
+    number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
+  dependencies:
+    number-is-nan "^1.0.0"
+
+is-fullwidth-code-point@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
+
+is-glob@^2.0.0, is-glob@^2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
+  dependencies:
+    is-extglob "^1.0.0"
+
+is-my-json-valid@^2.10.0:
+  version "2.16.0"
+  resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693"
+  dependencies:
+    generate-function "^2.0.0"
+    generate-object-property "^1.1.0"
+    jsonpointer "^4.0.0"
+    xtend "^4.0.0"
+
+is-number@^2.0.2, is-number@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f"
+  dependencies:
+    kind-of "^3.0.2"
+
+is-path-cwd@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
+
+is-path-in-cwd@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
+  dependencies:
+    is-path-inside "^1.0.0"
+
+is-path-inside@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
+  dependencies:
+    path-is-inside "^1.0.1"
+
+is-posix-bracket@^0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
+
+is-primitive@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
+
+is-property@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
+
+is-regex@^1.0.3:
+  version "1.0.4"
+  resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
+  dependencies:
+    has "^1.0.1"
+
+is-resolvable@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
+  dependencies:
+    tryit "^1.0.1"
+
+is-symbol@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
+
+is-typedarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
+
+is-windows@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
+
+isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+
+isexe@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+
+isobject@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
+  dependencies:
+    isarray "1.0.0"
+
+isstream@~0.1.2:
+  version "0.1.2"
+  resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
+
+jodid25519@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967"
+  dependencies:
+    jsbn "~0.1.0"
+
+js-tokens@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
+
+js-yaml@^3.5.1:
+  version "3.8.3"
+  resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.3.tgz#33a05ec481c850c8875929166fe1beb61c728766"
+  dependencies:
+    argparse "^1.0.7"
+    esprima "^3.1.1"
+
+jsbn@~0.1.0:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
+
+jsesc@^1.3.0:
+  version "1.3.0"
+  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
+
+jsesc@~0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
+
+json-schema@0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
+
+json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
+  dependencies:
+    jsonify "~0.0.0"
+
+json-stringify-safe@~5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
+
+json5@^0.5.0:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
+
+jsonify@~0.0.0:
+  version "0.0.0"
+  resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
+
+jsonpointer@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
+
+jsprim@^1.2.2:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
+  dependencies:
+    assert-plus "1.0.0"
+    extsprintf "1.0.2"
+    json-schema "0.2.3"
+    verror "1.3.6"
+
+jsx-ast-utils@^1.0.0, jsx-ast-utils@^1.3.4:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz#3867213e8dd79bf1e8f2300c0cfc1efb182c0df1"
+
+kind-of@^3.0.2:
+  version "3.2.0"
+  resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.0.tgz#b58abe4d5c044ad33726a8c1525b48cf891bff07"
+  dependencies:
+    is-buffer "^1.1.5"
+
+levn@^0.3.0, levn@~0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
+  dependencies:
+    prelude-ls "~1.1.2"
+    type-check "~0.3.2"
+
+lodash.cond@^4.3.0:
+  version "4.5.2"
+  resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5"
+
+lodash@^4.0.0, lodash@^4.2.0, lodash@^4.3.0:
+  version "4.17.4"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
+
+loose-envify@^1.0.0:
+  version "1.3.1"
+  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
+  dependencies:
+    js-tokens "^3.0.0"
+
+lru-cache@^4.0.1:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e"
+  dependencies:
+    pseudomap "^1.0.1"
+    yallist "^2.0.0"
+
+micromatch@^2.1.5:
+  version "2.3.11"
+  resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565"
+  dependencies:
+    arr-diff "^2.0.0"
+    array-unique "^0.2.1"
+    braces "^1.8.2"
+    expand-brackets "^0.1.4"
+    extglob "^0.3.1"
+    filename-regex "^2.0.0"
+    is-extglob "^1.0.0"
+    is-glob "^2.0.1"
+    kind-of "^3.0.2"
+    normalize-path "^2.0.1"
+    object.omit "^2.0.0"
+    parse-glob "^3.0.4"
+    regex-cache "^0.4.2"
+
+mime-db@~1.27.0:
+  version "1.27.0"
+  resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
+
+mime-types@^2.1.12, mime-types@~2.1.7:
+  version "2.1.15"
+  resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
+  dependencies:
+    mime-db "~1.27.0"
+
+minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3:
+  version "3.0.3"
+  resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774"
+  dependencies:
+    brace-expansion "^1.0.0"
+
+minimist@0.0.8:
+  version "0.0.8"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
+
+minimist@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
+
+"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1:
+  version "0.5.1"
+  resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
+  dependencies:
+    minimist "0.0.8"
+
+ms@0.7.1:
+  version "0.7.1"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
+
+ms@0.7.3:
+  version "0.7.3"
+  resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff"
+
+mute-stream@0.0.5:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
+
+nan@^2.3.0:
+  version "2.6.2"
+  resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45"
+
+natural-compare@^1.4.0:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
+
+node-pre-gyp@^0.6.29:
+  version "0.6.34"
+  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7"
+  dependencies:
+    mkdirp "^0.5.1"
+    nopt "^4.0.1"
+    npmlog "^4.0.2"
+    rc "^1.1.7"
+    request "^2.81.0"
+    rimraf "^2.6.1"
+    semver "^5.3.0"
+    tar "^2.2.1"
+    tar-pack "^3.4.0"
+
+nopt@^4.0.1:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
+  dependencies:
+    abbrev "1"
+    osenv "^0.1.4"
+
+normalize-path@^2.0.1:
+  version "2.1.1"
+  resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9"
+  dependencies:
+    remove-trailing-separator "^1.0.1"
+
+npmlog@^4.0.2:
+  version "4.0.2"
+  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f"
+  dependencies:
+    are-we-there-yet "~1.1.2"
+    console-control-strings "~1.1.0"
+    gauge "~2.7.1"
+    set-blocking "~2.0.0"
+
+number-is-nan@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
+
+oauth-sign@~0.8.1:
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
+
+object-assign@^4.0.1, object-assign@^4.1.0:
+  version "4.1.1"
+  resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+
+object-keys@^1.0.10, object-keys@^1.0.8:
+  version "1.0.11"
+  resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
+
+object.assign@^4.0.4:
+  version "4.0.4"
+  resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.0.4.tgz#b1c9cc044ef1b9fe63606fc141abbb32e14730cc"
+  dependencies:
+    define-properties "^1.1.2"
+    function-bind "^1.1.0"
+    object-keys "^1.0.10"
+
+object.omit@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa"
+  dependencies:
+    for-own "^0.1.4"
+    is-extendable "^0.1.1"
+
+once@^1.3.0, once@^1.3.3:
+  version "1.4.0"
+  resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+  dependencies:
+    wrappy "1"
+
+onetime@^1.0.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
+
+optionator@^0.8.2:
+  version "0.8.2"
+  resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
+  dependencies:
+    deep-is "~0.1.3"
+    fast-levenshtein "~2.0.4"
+    levn "~0.3.0"
+    prelude-ls "~1.1.2"
+    type-check "~0.3.2"
+    wordwrap "~1.0.0"
+
+os-homedir@^1.0.0:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
+
+os-tmpdir@^1.0.0, os-tmpdir@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
+
+osenv@^0.1.4:
+  version "0.1.4"
+  resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644"
+  dependencies:
+    os-homedir "^1.0.0"
+    os-tmpdir "^1.0.0"
+
+parse-glob@^3.0.4:
+  version "3.0.4"
+  resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
+  dependencies:
+    glob-base "^0.3.0"
+    is-dotfile "^1.0.0"
+    is-extglob "^1.0.0"
+    is-glob "^2.0.0"
+
+path-exists@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
+  dependencies:
+    pinkie-promise "^2.0.0"
+
+path-is-absolute@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
+
+path-is-inside@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
+
+path-parse@^1.0.5:
+  version "1.0.5"
+  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
+
+performance-now@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
+
+pify@^2.0.0:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+
+pinkie-promise@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
+  dependencies:
+    pinkie "^2.0.0"
+
+pinkie@^2.0.0:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
+
+pkg-dir@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4"
+  dependencies:
+    find-up "^1.0.0"
+
+pkg-up@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
+  dependencies:
+    find-up "^1.0.0"
+
+pluralize@^1.2.1:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
+
+prelude-ls@~1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
+
+preserve@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
+
+private@^0.1.6:
+  version "0.1.7"
+  resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
+
+process-nextick-args@~1.0.6:
+  version "1.0.7"
+  resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
+
+progress@^1.1.8:
+  version "1.1.8"
+  resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
+
+pseudomap@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
+
+punycode@^1.4.1:
+  version "1.4.1"
+  resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
+
+qs@~6.4.0:
+  version "6.4.0"
+  resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
+
+randomatic@^1.1.3:
+  version "1.1.6"
+  resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb"
+  dependencies:
+    is-number "^2.0.2"
+    kind-of "^3.0.2"
+
+rc@^1.1.7:
+  version "1.2.1"
+  resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95"
+  dependencies:
+    deep-extend "~0.4.0"
+    ini "~1.3.0"
+    minimist "^1.2.0"
+    strip-json-comments "~2.0.1"
+
+readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2:
+  version "2.2.9"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.9.tgz#cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8"
+  dependencies:
+    buffer-shims "~1.0.0"
+    core-util-is "~1.0.0"
+    inherits "~2.0.1"
+    isarray "~1.0.0"
+    process-nextick-args "~1.0.6"
+    string_decoder "~1.0.0"
+    util-deprecate "~1.0.1"
+
+readdirp@^2.0.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
+  dependencies:
+    graceful-fs "^4.1.2"
+    minimatch "^3.0.2"
+    readable-stream "^2.0.2"
+    set-immediate-shim "^1.0.1"
+
+readline2@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
+  dependencies:
+    code-point-at "^1.0.0"
+    is-fullwidth-code-point "^1.0.0"
+    mute-stream "0.0.5"
+
+rechoir@^0.6.2:
+  version "0.6.2"
+  resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
+  dependencies:
+    resolve "^1.1.6"
+
+regenerate@^1.2.1:
+  version "1.3.2"
+  resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260"
+
+regenerator-runtime@^0.10.0:
+  version "0.10.5"
+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
+
+regenerator-transform@0.9.11:
+  version "0.9.11"
+  resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283"
+  dependencies:
+    babel-runtime "^6.18.0"
+    babel-types "^6.19.0"
+    private "^0.1.6"
+
+regex-cache@^0.4.2:
+  version "0.4.3"
+  resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145"
+  dependencies:
+    is-equal-shallow "^0.1.3"
+    is-primitive "^2.0.0"
+
+regexpu-core@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240"
+  dependencies:
+    regenerate "^1.2.1"
+    regjsgen "^0.2.0"
+    regjsparser "^0.1.4"
+
+regjsgen@^0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
+
+regjsparser@^0.1.4:
+  version "0.1.5"
+  resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
+  dependencies:
+    jsesc "~0.5.0"
+
+remove-trailing-separator@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4"
+
+repeat-element@^1.1.2:
+  version "1.1.2"
+  resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a"
+
+repeat-string@^1.5.2:
+  version "1.6.1"
+  resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+
+repeating@^2.0.0:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
+  dependencies:
+    is-finite "^1.0.0"
+
+request@^2.81.0:
+  version "2.81.0"
+  resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
+  dependencies:
+    aws-sign2 "~0.6.0"
+    aws4 "^1.2.1"
+    caseless "~0.12.0"
+    combined-stream "~1.0.5"
+    extend "~3.0.0"
+    forever-agent "~0.6.1"
+    form-data "~2.1.1"
+    har-validator "~4.2.1"
+    hawk "~3.1.3"
+    http-signature "~1.1.0"
+    is-typedarray "~1.0.0"
+    isstream "~0.1.2"
+    json-stringify-safe "~5.0.1"
+    mime-types "~2.1.7"
+    oauth-sign "~0.8.1"
+    performance-now "^0.2.0"
+    qs "~6.4.0"
+    safe-buffer "^5.0.1"
+    stringstream "~0.0.4"
+    tough-cookie "~2.3.0"
+    tunnel-agent "^0.6.0"
+    uuid "^3.0.0"
+
+require-uncached@^1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
+  dependencies:
+    caller-path "^0.1.0"
+    resolve-from "^1.0.0"
+
+resolve-from@^1.0.0:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
+
+resolve@^1.1.6:
+  version "1.3.3"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
+  dependencies:
+    path-parse "^1.0.5"
+
+restore-cursor@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
+  dependencies:
+    exit-hook "^1.0.0"
+    onetime "^1.0.0"
+
+rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
+  version "2.6.1"
+  resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
+  dependencies:
+    glob "^7.0.5"
+
+run-async@^0.1.0:
+  version "0.1.0"
+  resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
+  dependencies:
+    once "^1.3.0"
+
+rx-lite@^3.1.2:
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
+
+safe-buffer@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7"
+
+semver@^5.3.0:
+  version "5.3.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
+
+set-blocking@~2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
+
+set-immediate-shim@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
+
+shebang-command@^1.2.0:
+  version "1.2.0"
+  resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
+  dependencies:
+    shebang-regex "^1.0.0"
+
+shebang-regex@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
+
+shelljs@^0.7.5:
+  version "0.7.7"
+  resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1"
+  dependencies:
+    glob "^7.0.0"
+    interpret "^1.0.0"
+    rechoir "^0.6.2"
+
+signal-exit@^3.0.0:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
+
+slash@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
+
+slice-ansi@0.0.4:
+  version "0.0.4"
+  resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
+
+sntp@1.x.x:
+  version "1.0.9"
+  resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
+  dependencies:
+    hoek "2.x.x"
+
+source-map-support@^0.4.2:
+  version "0.4.15"
+  resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
+  dependencies:
+    source-map "^0.5.6"
+
+source-map@^0.5.0, source-map@^0.5.6:
+  version "0.5.6"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
+
+sprintf-js@~1.0.2:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
+
+sshpk@^1.7.0:
+  version "1.13.0"
+  resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c"
+  dependencies:
+    asn1 "~0.2.3"
+    assert-plus "^1.0.0"
+    dashdash "^1.12.0"
+    getpass "^0.1.1"
+  optionalDependencies:
+    bcrypt-pbkdf "^1.0.0"
+    ecc-jsbn "~0.1.1"
+    jodid25519 "^1.0.0"
+    jsbn "~0.1.0"
+    tweetnacl "~0.14.0"
+
+string-width@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
+  dependencies:
+    code-point-at "^1.0.0"
+    is-fullwidth-code-point "^1.0.0"
+    strip-ansi "^3.0.0"
+
+string-width@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
+  dependencies:
+    is-fullwidth-code-point "^2.0.0"
+    strip-ansi "^3.0.0"
+
+string_decoder@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.0.tgz#f06f41157b664d86069f84bdbdc9b0d8ab281667"
+  dependencies:
+    buffer-shims "~1.0.0"
+
+stringstream@~0.0.4:
+  version "0.0.5"
+  resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
+
+strip-ansi@^3.0.0, strip-ansi@^3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
+  dependencies:
+    ansi-regex "^2.0.0"
+
+strip-bom@^3.0.0:
+  version "3.0.0"
+  resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
+
+strip-json-comments@~2.0.1:
+  version "2.0.1"
+  resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
+
+supports-color@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
+
+table@^3.7.8:
+  version "3.8.3"
+  resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
+  dependencies:
+    ajv "^4.7.0"
+    ajv-keywords "^1.0.0"
+    chalk "^1.1.1"
+    lodash "^4.0.0"
+    slice-ansi "0.0.4"
+    string-width "^2.0.0"
+
+tar-pack@^3.4.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984"
+  dependencies:
+    debug "^2.2.0"
+    fstream "^1.0.10"
+    fstream-ignore "^1.0.5"
+    once "^1.3.3"
+    readable-stream "^2.1.4"
+    rimraf "^2.5.1"
+    tar "^2.2.1"
+    uid-number "^0.0.6"
+
+tar@^2.2.1:
+  version "2.2.1"
+  resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1"
+  dependencies:
+    block-stream "*"
+    fstream "^1.0.2"
+    inherits "2"
+
+text-table@~0.2.0:
+  version "0.2.0"
+  resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
+
+through@^2.3.6:
+  version "2.3.8"
+  resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+
+to-fast-properties@^1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320"
+
+tough-cookie@~2.3.0:
+  version "2.3.2"
+  resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
+  dependencies:
+    punycode "^1.4.1"
+
+trim-right@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
+
+tryit@^1.0.1:
+  version "1.0.3"
+  resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
+
+tunnel-agent@^0.6.0:
+  version "0.6.0"
+  resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
+  dependencies:
+    safe-buffer "^5.0.1"
+
+tweetnacl@^0.14.3, tweetnacl@~0.14.0:
+  version "0.14.5"
+  resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
+
+type-check@~0.3.2:
+  version "0.3.2"
+  resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
+  dependencies:
+    prelude-ls "~1.1.2"
+
+typedarray@^0.0.6:
+  version "0.0.6"
+  resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+
+uid-number@^0.0.6:
+  version "0.0.6"
+  resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
+
+user-home@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
+  dependencies:
+    os-homedir "^1.0.0"
+
+util-deprecate@~1.0.1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+
+uuid@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1"
+
+verror@1.3.6:
+  version "1.3.6"
+  resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
+  dependencies:
+    extsprintf "1.0.2"
+
+which@^1.2.9:
+  version "1.2.14"
+  resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5"
+  dependencies:
+    isexe "^2.0.0"
+
+wide-align@^1.1.0:
+  version "1.1.0"
+  resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad"
+  dependencies:
+    string-width "^1.0.1"
+
+wordwrap@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+
+wrappy@1:
+  version "1.0.2"
+  resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+
+write@^0.2.1:
+  version "0.2.1"
+  resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
+  dependencies:
+    mkdirp "^0.5.1"
+
+xtend@^4.0.0:
+  version "4.0.1"
+  resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+
+yallist@^2.0.0:
+  version "2.1.2"
+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
diff --git a/example.gitignore b/example.gitignore
index c292c2e927..d1e35ac003 100644
--- a/example.gitignore
+++ b/example.gitignore
@@ -37,7 +37,3 @@ sites/simpletest
 
 # Ignore SimpleTest multi-site environment.
 # simpletest
-
-# Ignore core phpcs.xml and phpunit.xml.
-core/phpcs.xml
-core/phpunit.xml
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 25d498e6f1..1720d11e43 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -86,7 +86,7 @@
  * );
  * @endcode
  */
- $databases = array();
+$databases = array();
 
 /**
  * Customizing database settings.
@@ -643,6 +643,7 @@
  * configuration values in settings.php will not fire any of the configuration
  * change events.
  */
+# $config['system.file']['path']['temporary'] = '/tmp';
 # $config['system.site']['name'] = 'My Drupal site';
 # $config['system.theme']['default'] = 'stark';
 # $config['user.settings']['anonymous'] = 'Visitor';
@@ -750,6 +751,16 @@
 ];
 
 /**
+ * The default number of entities to update in a batch process.
+ *
+ * This is used by update and post-update functions that need to go through and
+ * change all the entities on a site, so it is useful to increase this number
+ * if your hosting configuration (i.e. RAM allocation, CPU speed) allows for a
+ * larger number of entities to be processed in a single batch run.
+ */
+$settings['entity_update_batch_size'] = 50;
+
+/**
  * Load local development override configuration, if available.
  *
  * Use settings.local.php to override variables on secondary (staging,
