diff --git a/core/includes/common.inc b/core/includes/common.inc
index 19beefa..4b83cc5 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -271,7 +271,7 @@ function valid_email_address($mail) {
  * @param $uri
  *   A plain-text URI that might contain dangerous protocols.
  *
- * @return string
+ * @return
  *   A URI stripped of dangerous protocols and encoded for output to an HTML
  *   attribute value. Because it is already encoded, it should not be set as a
  *   value within a $attributes array passed to Drupal\Core\Template\Attribute,
@@ -281,20 +281,10 @@ function valid_email_address($mail) {
  *   \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() instead.
  *
  * @see \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
- * @see \Drupal\Component\Utility\UrlHelper::filterBadProtocol()
- *
- * @deprecated in Drupal 8.0.x-dev, will be removed before Drupal 9.0.0.
- *   Use UrlHelper::stripDangerousProtocols() or UrlHelper::filterBadProtocol()
- *   instead. UrlHelper::stripDangerousProtocols() can be used in conjunction
- *   with \Drupal\Component\Utility\SafeMarkup::format() and an @variable
- *   placeholder which will perform the necessary escaping.
- *   UrlHelper::filterBadProtocol() is functionality equivalent to check_url()
- *   apart from the fact it is protected from double escaping bugs. Note that
- *   this method no longer marks its output as safe.
- *
+ * @see \Drupal\Component\Utility\SafeMarkup::checkPlain()
  */
 function check_url($uri) {
-  return Html::escape(UrlHelper::stripDangerousProtocols($uri));
+  return SafeMarkup::checkPlain(UrlHelper::stripDangerousProtocols($uri));
 }
 
 /**
diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index 52ae51e..9936362 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -443,20 +443,20 @@ function entity_view_multiple(array $entities, $view_mode, $langcode = NULL, $re
  *
  * @deprecated as of Drupal 8.0.x, will be removed before Drupal 9.0.0.
  *   If the display is available in configuration use:
- *   @code
+ * @code
  *   \Drupal::entityManager()->getStorage('entity_view_display')->load($entity_type . '.' . $bundle . '.' . $view_mode);
- *   @endcode
+ * @endcode
  *   When the display is not available in configuration, you can create a new
  *   EntityViewDisplay object using:
- *   @code
- *   $values = array(
- *     'targetEntityType' => $entity_type,
- *     'bundle' => $bundle,
- *     'mode' => $view_mode,
- *     'status' => TRUE,
- *   ));
- *   \Drupal::entityManager()->getStorage('entity_view_display')->create($values);
- *   @endcode
+ * @code
+ * $values = ('entity_view_display', array(
+ *  'targetEntityType' => $entity_type,
+ *  'bundle' => $bundle,
+ *  'mode' => $view_mode,
+ *  'status' => TRUE,
+ * ));
+ * \Drupal::entityManager()->getStorage('entity_view_display')->create($values);
+ * @endcode
  *
  * @see \Drupal\Core\Entity\EntityStorageInterface::create()
  * @see \Drupal\Core\Entity\EntityStorageInterface::load()
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 36612ecf..7bf9eab 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2052,7 +2052,7 @@ function install_check_translations($langcode, $server_pattern) {
         'title'       => t('Translation'),
         'value'       => t('The %language translation is not available.', array('%language' => $language)),
         'severity'    => REQUIREMENT_ERROR,
-        'description' => t('The %language translation file is not available at the translation server. <a href="@url">Choose a different language</a> or select English and translate your website later.', array('%language' => $language, '@url' => UrlHelper::stripDangerousProtocols($_SERVER['SCRIPT_NAME']))),
+        'description' => t('The %language translation file is not available at the translation server. <a href="!url">Choose a different language</a> or select English and translate your website later.', array('%language' => $language, '!url' => check_url($_SERVER['SCRIPT_NAME']))),
       );
     }
     else {
@@ -2071,7 +2071,7 @@ function install_check_translations($langcode, $server_pattern) {
         'title'       => t('Translation'),
         'value'       => t('The %language translation could not be downloaded.', array('%language' => $language)),
         'severity'    => REQUIREMENT_ERROR,
-        'description' => t('The %language translation file could not be downloaded. <a href="@url">Choose a different language</a> or select English and translate your website later.', array('%language' => $language, '@url' => UrlHelper::stripDangerousProtocols($_SERVER['SCRIPT_NAME']))),
+        'description' => t('The %language translation file could not be downloaded. <a href="!url">Choose a different language</a> or select English and translate your website later.', array('%language' => $language, '!url' => check_url($_SERVER['SCRIPT_NAME']))),
       );
     }
   }
@@ -2281,11 +2281,11 @@ function install_display_requirements($install_state, $requirements) {
       $build['report']['#requirements'] = $requirements;
       if ($severity == REQUIREMENT_WARNING) {
         $build['#title'] = t('Requirements review');
-        $build['#suffix'] = t('Check the messages and <a href="@retry">retry</a>, or you may choose to <a href="@cont">continue anyway</a>.', array('@retry' => UrlHelper::stripDangerousProtocols(drupal_requirements_url(REQUIREMENT_ERROR)), '@cont' => UrlHelper::stripDangerousProtocols(drupal_requirements_url($severity))));
+        $build['#suffix'] = t('Check the messages and <a href="!retry">retry</a>, or you may choose to <a href="!cont">continue anyway</a>.', array('!retry' => check_url(drupal_requirements_url(REQUIREMENT_ERROR)), '!cont' => check_url(drupal_requirements_url($severity))));
       }
       else {
         $build['#title'] = t('Requirements problem');
-        $build['#suffix'] = t('Check the messages and <a href="@url">try again</a>.', array('@url' => UrlHelper::stripDangerousProtocols(drupal_requirements_url($severity))));
+        $build['#suffix'] = t('Check the messages and <a href="!url">try again</a>.', array('!url' => check_url(drupal_requirements_url($severity))));
       }
       return $build;
     }
diff --git a/core/includes/install.inc b/core/includes/install.inc
index c885553..f021373 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -864,11 +864,9 @@ function install_goto($path) {
  * @return
  *   The URL of the current script, with query parameters modified by the
  *   passed-in $query. The URL is not sanitized, so it still needs to be run
- *   through \Drupal\Component\Utility\UrlHelper::filterBadProtocol() if it will be
- *   used as an HTML attribute value.
+ *   through check_url() if it will be used as an HTML attribute value.
  *
  * @see drupal_requirements_url()
- * @see Drupal\Component\Utility\UrlHelper::filterBadProtocol()
  */
 function drupal_current_script_url($query = array()) {
   $uri = $_SERVER['SCRIPT_NAME'];
@@ -892,12 +890,10 @@ function drupal_current_script_url($query = array()) {
  *
  * @return
  *   A URL for attempting to proceed to the next step of the script. The URL is
- *   not sanitized, so it still needs to be run through
- *   \Drupal\Component\Utility\UrlHelper::filterBadProtocol() if it will be used
- *   as an HTML attribute value.
+ *   not sanitized, so it still needs to be run through check_url() if it will
+ *   be used as an HTML attribute value.
  *
  * @see drupal_current_script_url()
- * @see \Drupal\Component\Utility\UrlHelper::filterBadProtocol()
  */
 function drupal_requirements_url($severity) {
   $query = array();
diff --git a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
index 8be8e8c..a67e8ca 100644
--- a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
+++ b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php
@@ -8,6 +8,7 @@
 namespace Drupal\Component\Diff\Engine;
 
 use Drupal\Component\Utility\Unicode;
+use Drupal\Component\Utility\SafeMarkup;
 
 /**
  *  Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
@@ -37,10 +38,10 @@ class HWLDFWordAccumulator {
   protected function _flushGroup($new_tag) {
     if ($this->group !== '') {
       if ($this->tag == 'mark') {
-        $this->line = $this->line . '<span class="diffchange">' . $this->group . '</span>';
+        $this->line = SafeMarkup::format('@original_line<span class="diffchange">@group</span>', ['@original_line' => $this->line, '@group' => $this->group]);
       }
       else {
-        $this->line = $this->line . $this->group;
+        $this->line = SafeMarkup::format('@original_line@group', ['@original_line' => $this->line, '@group' => $this->group]);
       }
     }
     $this->group = '';
diff --git a/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
new file mode 100644
index 0000000..60e6066
--- /dev/null
+++ b/core/lib/Drupal/Component/Plugin/Definition/PluginDefinitionInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Component\Plugin\PluginDefinitionInterface.
+ */
+
+namespace Drupal\Component\Plugin\Definition;
+
+/**
+ * Defines a plugin definition.
+ *
+ * Object-based plugin definitions MUST implement this interface.
+ *
+ * @ingroup Plugin
+ */
+interface PluginDefinitionInterface {
+
+  /**
+   * Sets the class.
+   *
+   * @param string $class
+   *   A fully qualified class name.
+   *
+   * @return $this
+   *
+   * @throws \InvalidArgumentException
+   *   If the class is invalid.
+   */
+  public function setClass($class);
+
+  /**
+   * Gets the class.
+   *
+   * @return string
+   *   A fully qualified class name.
+   */
+  public function getClass();
+
+}
diff --git a/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php b/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php
index 1902b56..46c200d 100644
--- a/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php
+++ b/core/lib/Drupal/Component/Plugin/Factory/DefaultFactory.php
@@ -6,6 +6,7 @@
 
 namespace Drupal\Component\Plugin\Factory;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
 use Drupal\Component\Plugin\Exception\PluginException;
 
@@ -63,7 +64,7 @@ public function createInstance($plugin_id, array $configuration = array()) {
    *
    * @param string $plugin_id
    *   The id of a plugin.
-   * @param mixed $plugin_definition
+   * @param \Drupal\Component\Plugin\Definition\PluginDefinitionInterface|mixed[] $plugin_definition
    *   The plugin definition associated with the plugin ID.
    * @param string $required_interface
    *   (optional) THe required plugin interface.
@@ -77,18 +78,32 @@ public function createInstance($plugin_id, array $configuration = array()) {
    *
    */
   public static function getPluginClass($plugin_id, $plugin_definition = NULL, $required_interface = NULL) {
-    if (empty($plugin_definition['class'])) {
-      throw new PluginException(sprintf('The plugin (%s) did not specify an instance class.', $plugin_id));
+    $missing_class_message = sprintf('The plugin (%s) did not specify an instance class.', $plugin_id);
+    if (is_array($plugin_definition)) {
+      if (empty($plugin_definition['class'])) {
+        throw new PluginException($missing_class_message);
+      }
+
+      $class = $plugin_definition['class'];
     }
+    elseif ($plugin_definition instanceof PluginDefinitionInterface) {
+      if (!$plugin_definition->getClass()) {
+        throw new PluginException($missing_class_message);
+      }
 
-    $class = $plugin_definition['class'];
+      $class = $plugin_definition->getClass();
+    }
+    else {
+      $plugin_definition_type = is_object($plugin_definition) ? get_class($plugin_definition) : gettype($plugin_definition);
+      throw new PluginException(sprintf('% can only handle plugin definitions that are arrays or that implement %s, but %s given.', __CLASS__, PluginDefinitionInterface::class, $plugin_definition_type));
+    }
 
     if (!class_exists($class)) {
       throw new PluginException(sprintf('Plugin (%s) instance class "%s" does not exist.', $plugin_id, $class));
     }
 
-    if ($required_interface && !is_subclass_of($plugin_definition['class'], $required_interface)) {
-      throw new PluginException(sprintf('Plugin "%s" (%s) must implement interface %s.', $plugin_id, $plugin_definition['class'], $required_interface));
+    if ($required_interface && !is_subclass_of($class, $required_interface)) {
+      throw new PluginException(sprintf('Plugin "%s" (%s) must implement interface %s.', $plugin_id, $class, $required_interface));
     }
 
     return $class;
diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index d20ad6b..b4e0989 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -128,6 +128,20 @@ public static function setMultiple(array $safe_strings) {
   }
 
   /**
+   * Encodes special characters in a plain-text string for display as HTML.
+   *
+   * @param string $string
+   *   A string.
+   *
+   * @return string
+   *   The escaped string. If $string was already set as safe with
+   *   self::set(), it won't be escaped again.
+   */
+  public static function escape($string) {
+    return static::isSafe($string) ? $string : static::checkPlain($string);
+  }
+
+  /**
   * Gets all strings currently marked as safe.
   *
   * This is useful for the batch and form APIs, where it is important to
@@ -155,13 +169,6 @@ public static function getAll() {
    *
    * @ingroup sanitization
    *
-   * @deprecated Will be removed before Drupal 8.0.0. Rely on Twig's
-   *   auto-escaping feature, or use the @link theme_render #plain_text @endlink
-   *   key when constructing a render array that contains plain text in order to
-   *   use the renderer's auto-escaping feature. If neither of these are
-   *   possible, \Drupal\Component\Utility\Html::escape() can be used in places
-   *   where explicit escaping is needed.
-   *
    * @see drupal_validate_utf8()
    */
   public static function checkPlain($text) {
@@ -222,18 +229,13 @@ public static function format($string, array $args) {
       switch ($key[0]) {
         case '@':
           // Escaped only.
-          if (!SafeMarkup::isSafe($value)) {
-            $args[$key] = Html::escape($value);
-          }
+          $args[$key] = static::escape($value);
           break;
 
         case '%':
         default:
           // Escaped and placeholder.
-          if (!SafeMarkup::isSafe($value)) {
-            $value = Html::escape($value);
-          }
-          $args[$key] = '<em class="placeholder">' . $value . '</em>';
+          $args[$key] = '<em class="placeholder">' . static::escape($value) . '</em>';
           break;
 
         case '!':
diff --git a/core/lib/Drupal/Component/Utility/SafeStringInterface.php b/core/lib/Drupal/Component/Utility/SafeStringInterface.php
index 45d536d..136dd37 100644
--- a/core/lib/Drupal/Component/Utility/SafeStringInterface.php
+++ b/core/lib/Drupal/Component/Utility/SafeStringInterface.php
@@ -33,7 +33,7 @@
  * @see \Drupal\Component\Utility\SafeMarkup::isSafe()
  * @see \Drupal\Core\Template\TwigExtension::escapeFilter()
  */
-interface SafeStringInterface extends \JsonSerializable {
+interface SafeStringInterface {
 
   /**
    * Returns a safe string.
diff --git a/core/lib/Drupal/Component/Utility/SafeStringTrait.php b/core/lib/Drupal/Component/Utility/SafeStringTrait.php
index bd1ee75..a91e44b 100644
--- a/core/lib/Drupal/Component/Utility/SafeStringTrait.php
+++ b/core/lib/Drupal/Component/Utility/SafeStringTrait.php
@@ -67,14 +67,4 @@ public function count() {
     return Unicode::strlen($this->string);
   }
 
-  /**
-   * Returns a representation of the object for use in JSON serialization.
-   *
-   * @return string
-   *   The safe string content.
-   */
-  public function jsonSerialize() {
-    return $this->__toString();
-  }
-
 }
diff --git a/core/lib/Drupal/Component/Utility/UrlHelper.php b/core/lib/Drupal/Component/Utility/UrlHelper.php
index b442c57..608a5da 100644
--- a/core/lib/Drupal/Component/Utility/UrlHelper.php
+++ b/core/lib/Drupal/Component/Utility/UrlHelper.php
@@ -300,11 +300,10 @@ public static function setAllowedProtocols(array $protocols = array()) {
    *
    * This function must be called for all URIs within user-entered input prior
    * to being output to an HTML attribute value. It is often called as part of
-   * \Drupal\Component\Utility\UrlHelper::filterBadProtocol() or
-   * \Drupal\Component\Utility\Xss::filter(), but those functions return an
-   * HTML-encoded string, so this function can be called independently when the
-   * output needs to be a plain-text string for passing to functions that will
-   * call \Drupal\Component\Utility\SafeMarkup::checkPlain() separately.
+   * check_url() or Drupal\Component\Utility\Xss::filter(), but those functions
+   * return an HTML-encoded string, so this function can be called independently
+   * when the output needs to be a plain-text string for passing to functions
+   * that will call \Drupal\Component\Utility\SafeMarkup::checkPlain() separately.
    *
    * @param string $uri
    *   A plain-text URI that might contain dangerous protocols.
diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
index 7d36b51..bffe666 100644
--- a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
+++ b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php
@@ -164,15 +164,15 @@ protected function buildAttachmentsCommands(AjaxResponse $response, Request $req
     $resource_commands = array();
     if ($css_assets) {
       $css_render_array = $this->cssCollectionRenderer->render($css_assets);
-      $resource_commands[] = new AddCssCommand($this->renderer->renderPlain($css_render_array));
+      $resource_commands[] = new AddCssCommand((string) $this->renderer->renderPlain($css_render_array));
     }
     if ($js_assets_header) {
       $js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header);
-      $resource_commands[] = new PrependCommand('head', $this->renderer->renderPlain($js_header_render_array));
+      $resource_commands[] = new PrependCommand('head', (string) $this->renderer->renderPlain($js_header_render_array));
     }
     if ($js_assets_footer) {
       $js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer);
-      $resource_commands[] = new AppendCommand('body', $this->renderer->renderPlain($js_footer_render_array));
+      $resource_commands[] = new AppendCommand('body', (string) $this->renderer->renderPlain($js_footer_render_array));
     }
     foreach (array_reverse($resource_commands) as $resource_command) {
       $response->addCommand($resource_command, TRUE);
diff --git a/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php b/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php
index e48d060..d83db57 100644
--- a/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php
+++ b/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php
@@ -29,7 +29,7 @@
    * If content is a render array, it may contain attached assets to be
    * processed.
    *
-   * @return string|\Drupal\Component\Utility\SafeStringInterface
+   * @return string
    *   HTML rendered content.
    */
   protected function getRenderedContent() {
@@ -37,10 +37,10 @@ protected function getRenderedContent() {
     if (is_array($this->content)) {
       $html = \Drupal::service('renderer')->renderRoot($this->content);
       $this->attachedAssets = AttachedAssets::createFromRenderArray($this->content);
-      return $html;
+      return (string) $html;
     }
     else {
-      return $this->content;
+      return (string) $this->content;
     }
   }
 
diff --git a/core/lib/Drupal/Core/Block/BlockBase.php b/core/lib/Drupal/Core/Block/BlockBase.php
index 8c97809..ef127e9 100644
--- a/core/lib/Drupal/Core/Block/BlockBase.php
+++ b/core/lib/Drupal/Core/Block/BlockBase.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Block;
 
 use Drupal\block\BlockInterface;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Cache\CacheableDependencyInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -165,7 +166,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $form['admin_label'] = array(
       '#type' => 'item',
       '#title' => $this->t('Block description'),
-      '#plain_text' => $definition['admin_label'],
+      '#markup' => SafeMarkup::checkPlain($definition['admin_label']),
     );
     $form['label'] = array(
       '#type' => 'textfield',
diff --git a/core/lib/Drupal/Core/Cache/Context/OriginalRequestCacheContext.php b/core/lib/Drupal/Core/Cache/Context/OriginalRequestCacheContext.php
deleted file mode 100644
index e69de29..0000000
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
index 5dec0a8..ff38a22 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php
@@ -118,16 +118,7 @@ public static function open(array &$connection_options = array()) {
       // Convert numeric values to strings when fetching.
       \PDO::ATTR_STRINGIFY_FETCHES => TRUE,
     );
-
-    try {
-      $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
-    }
-    catch (\Exception $e) {
-      if ($e->getCode() == static::DATABASE_NOT_FOUND) {
-        throw new DatabaseNotFoundException($e->getMessage(), $e->getCode(), $e);
-      }
-      throw new $e;
-    }
+    $pdo = new \PDO($dsn, $connection_options['username'], $connection_options['password'], $connection_options['pdo']);
 
     return $pdo;
   }
diff --git a/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php
index 4f18f6a..32f460c 100644
--- a/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php
+++ b/core/lib/Drupal/Core/Database/Driver/pgsql/Install/Tasks.php
@@ -194,6 +194,15 @@ function initializeDatabase() {
     // avoid trying to create them again in that case.
 
     try {
+      // Create functions.
+      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric) RETURNS numeric AS
+        \'SELECT CASE WHEN (($1 > $2) OR ($2 IS NULL)) THEN $1 ELSE $2 END;\'
+        LANGUAGE \'sql\''
+      );
+      db_query('CREATE OR REPLACE FUNCTION "greatest"(numeric, numeric, numeric) RETURNS numeric AS
+        \'SELECT greatest($1, greatest($2, $3));\'
+        LANGUAGE \'sql\''
+      );
       // Don't use {} around pg_proc table.
       if (!db_query("SELECT COUNT(*) FROM pg_proc WHERE proname = 'rand'")->fetchField()) {
         db_query('CREATE OR REPLACE FUNCTION "rand"() RETURNS float AS
@@ -207,6 +216,28 @@ function initializeDatabase() {
         LANGUAGE \'sql\''
       );
 
+      // Using || to concatenate in Drupal is not recommended because there are
+      // database drivers for Drupal that do not support the syntax, however
+      // they do support CONCAT(item1, item2) which we can replicate in
+      // PostgreSQL. PostgreSQL requires the function to be defined for each
+      // different argument variation the function can handle.
+      db_query('CREATE OR REPLACE FUNCTION "concat"(anynonarray, anynonarray) RETURNS text AS
+        \'SELECT CAST($1 AS text) || CAST($2 AS text);\'
+        LANGUAGE \'sql\'
+      ');
+      db_query('CREATE OR REPLACE FUNCTION "concat"(text, anynonarray) RETURNS text AS
+        \'SELECT $1 || CAST($2 AS text);\'
+        LANGUAGE \'sql\'
+      ');
+      db_query('CREATE OR REPLACE FUNCTION "concat"(anynonarray, text) RETURNS text AS
+        \'SELECT CAST($1 AS text) || $2;\'
+        LANGUAGE \'sql\'
+      ');
+      db_query('CREATE OR REPLACE FUNCTION "concat"(text, text) RETURNS text AS
+        \'SELECT $1 || $2;\'
+        LANGUAGE \'sql\'
+      ');
+
       $this->pass(t('PostgreSQL has initialized itself.'));
     }
     catch (\Exception $e) {
diff --git a/core/lib/Drupal/Core/DependencyInjection/Container.php b/core/lib/Drupal/Core/DependencyInjection/Container.php
index c86aace..b4cac53 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Container.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Container.php
@@ -31,7 +31,7 @@ public function set($id, $service, $scope = ContainerInterface::SCOPE_CONTAINER)
    * {@inheritdoc}
    */
   public function __sleep() {
-    assert(FALSE, 'The container was serialized.');
+    trigger_error('The container was serialized.', E_USER_ERROR);
     return array_keys(get_object_vars($this));
   }
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
index e00426f..ce692b5 100644
--- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
+++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php
@@ -118,7 +118,7 @@ protected function callMethod($service, $call) {
    * {@inheritdoc}
    */
   public function __sleep() {
-    assert(FALSE, 'The container was serialized.');
+    trigger_error('The container was serialized.', E_USER_ERROR);
     return array_keys(get_object_vars($this));
   }
 
diff --git a/core/lib/Drupal/Core/Diff/DiffFormatter.php b/core/lib/Drupal/Core/Diff/DiffFormatter.php
index 2758351..cfd6bb8 100644
--- a/core/lib/Drupal/Core/Diff/DiffFormatter.php
+++ b/core/lib/Drupal/Core/Diff/DiffFormatter.php
@@ -9,7 +9,7 @@
 
 use Drupal\Component\Diff\DiffFormatter as DiffFormatterBase;
 use Drupal\Component\Diff\WordLevelDiff;
-use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\ConfigFactoryInterface;
 
 /**
@@ -107,7 +107,7 @@ protected function addedLine($line) {
         'class' => 'diff-marker',
       ),
       array(
-        'data' => ['#markup' => $line],
+        'data' => $line,
         'class' => 'diff-context diff-addedline',
       )
     );
@@ -129,7 +129,7 @@ protected function deletedLine($line) {
         'class' => 'diff-marker',
       ),
       array(
-        'data' => ['#markup' => $line],
+        'data' => $line,
         'class' => 'diff-context diff-deletedline',
       )
     );
@@ -148,7 +148,7 @@ protected function contextLine($line) {
     return array(
       ' ',
       array(
-        'data' => ['#markup' => $line],
+        'data' => $line,
         'class' => 'diff-context',
       )
     );
@@ -172,7 +172,7 @@ protected function emptyLine() {
    */
   protected function _added($lines) {
     foreach ($lines as $line) {
-      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(Html::escape($line)));
+      $this->rows[] = array_merge($this->emptyLine(), $this->addedLine(SafeMarkup::checkPlain($line)));
     }
   }
 
@@ -181,7 +181,7 @@ protected function _added($lines) {
    */
   protected function _deleted($lines) {
     foreach ($lines as $line) {
-      $this->rows[] = array_merge($this->deletedLine(Html::escape($line)), $this->emptyLine());
+      $this->rows[] = array_merge($this->deletedLine(SafeMarkup::checkPlain($line)), $this->emptyLine());
     }
   }
 
@@ -190,7 +190,7 @@ protected function _deleted($lines) {
    */
   protected function _context($lines) {
     foreach ($lines as $line) {
-      $this->rows[] = array_merge($this->contextLine(Html::escape($line)), $this->contextLine(Html::escape($line)));
+      $this->rows[] = array_merge($this->contextLine(SafeMarkup::checkPlain($line)), $this->contextLine(SafeMarkup::checkPlain($line)));
     }
   }
 
@@ -198,8 +198,6 @@ protected function _context($lines) {
    * {@inheritdoc}
    */
   protected function _changed($orig, $closing) {
-    $orig = array_map('\Drupal\Component\Utility\Html::escape', $orig);
-    $closing = array_map('\Drupal\Component\Utility\Html::escape', $closing);
     $diff = new WordLevelDiff($orig, $closing);
     $del = $diff->orig();
     $add = $diff->closing();
diff --git a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
index 1a3805e..59808a8 100644
--- a/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityTypeInterface.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\Entity;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
+
 /**
  * Provides an interface for an entity type and its metadata.
  *
@@ -15,7 +17,7 @@
  * implemented to alter existing data and fill-in defaults. Module-specific
  * properties should be documented in the hook implementations defining them.
  */
-interface EntityTypeInterface {
+interface EntityTypeInterface extends PluginDefinitionInterface {
 
   /**
    * The maximum length of ID, in characters.
@@ -67,14 +69,6 @@ public function id();
   public function getProvider();
 
   /**
-   * Gets the name of the entity type class.
-   *
-   * @return string
-   *   The name of the entity type class.
-   */
-  public function getClass();
-
-  /**
    * Gets the name of the original entity type class.
    *
    * In case the class name was changed with setClass(), this will return
@@ -171,16 +165,6 @@ public function isRenderCacheable();
   public function isPersistentlyCacheable();
 
   /**
-   * Sets the name of the entity type class.
-   *
-   * @param string $class
-   *   The name of the entity type class.
-   *
-   * @return $this
-   */
-  public function setClass($class);
-
-  /**
    * Determines if there is a handler for a given type.
    *
    * @param string $handler_type
diff --git a/core/lib/Drupal/Core/Extension/Extension.php b/core/lib/Drupal/Core/Extension/Extension.php
index 17d8b09..3c765fe 100644
--- a/core/lib/Drupal/Core/Extension/Extension.php
+++ b/core/lib/Drupal/Core/Extension/Extension.php
@@ -166,9 +166,8 @@ public function __call($method, array $args) {
    * Serializes the Extension object in the most optimized way.
    */
   public function serialize() {
-    // Don't serialize the app root, since this could change if the install is
-    // moved.
     $data = array(
+      'root' => $this->root,
       'type' => $this->type,
       'pathname' => $this->pathname,
       'filename' => $this->filename,
@@ -189,8 +188,7 @@ public function serialize() {
    */
   public function unserialize($data) {
     $data = unserialize($data);
-    // Get the app root from the container.
-    $this->root = DRUPAL_ROOT;
+    $this->root = $data['root'];
     $this->type = $data['type'];
     $this->pathname = $data['pathname'];
     $this->filename = $data['filename'];
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php
index 3f73939..69b5b9f 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceIdFormatter.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
 use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Component\Utility\SafeMarkup;
 
 /**
  * Plugin implementation of the 'entity reference ID' formatter.
@@ -32,7 +33,7 @@ public function viewElements(FieldItemListInterface $items) {
     foreach ($this->getEntitiesToView($items) as $delta => $entity) {
       if ($entity->id()) {
         $elements[$delta] = array(
-          '#plain_text' => $entity->id(),
+          '#markup' => SafeMarkup::checkPlain($entity->id()),
           // Create a cache tag entry for the referenced entity. In the case
           // that the referenced entity is deleted, the cache for referring
           // entities must be cleared.
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php
index 68d28ad..c362a80 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceLabelFormatter.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\Exception\UndefinedLinkTemplateException;
 use Drupal\Core\Field\FieldItemListInterface;
 use Drupal\Core\Form\FormStateInterface;
@@ -97,7 +98,7 @@ public function viewElements(FieldItemListInterface $items) {
         }
       }
       else {
-        $elements[$delta] = array('#plain_text' => $label);
+        $elements[$delta] = array('#markup' => SafeMarkup::checkPlain($label));
       }
       $elements[$delta]['#cache']['tags'] = $entity->getCacheTags();
     }
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php
index 6443669..90dfadc 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php
@@ -40,10 +40,10 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu
   protected $dateFormatter;
 
   /**
-   * The current Request object.
-   *
-   * @var \Symfony\Component\HttpFoundation\Request
-   */
+    * The current Request object.
+    *
+    * @var \Symfony\Component\HttpFoundation\Request
+    */
   protected $request;
 
   /**
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index a9ae1bd..725faaa 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -21,7 +21,6 @@
 use Drupal\Core\Render\ElementInfoManagerInterface;
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-use Symfony\Component\HttpFoundation\FileBag;
 use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\HttpFoundation\Response;
 
@@ -106,45 +105,6 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
   protected $formCache;
 
   /**
-   * Defines element value callables which are safe to run even when the form
-   * state has an invalid CSRF token.
-   *
-   * Excluded from this list on purpose:
-   *  - Drupal\file\Element\ManagedFile::valueCallback
-   *  - Drupal\Core\Datetime\Element\Datelist::valueCallback
-   *  - Drupal\Core\Datetime\Element\Datetime::valueCallback
-   *  - Drupal\Core\Render\Element\ImageButton::valueCallback
-   *  - Drupal\file\Plugin\Field\FieldWidget\FileWidget::value
-   *  - color_palette_color_value
-   *
-   * @var array
-   */
-  protected $safeCoreValueCallables = [
-    'Drupal\Core\Render\Element\Checkbox::valueCallback',
-    'Drupal\Core\Render\Element\Checkboxes::valueCallback',
-    'Drupal\Core\Render\Element\Email::valueCallback',
-    'Drupal\Core\Render\Element\FormElement::valueCallback',
-    'Drupal\Core\Render\Element\MachineName::valueCallback',
-    'Drupal\Core\Render\Element\Number::valueCallback',
-    'Drupal\Core\Render\Element\PathElement::valueCallback',
-    'Drupal\Core\Render\Element\Password::valueCallback',
-    'Drupal\Core\Render\Element\PasswordConfirm::valueCallback',
-    'Drupal\Core\Render\Element\Radio::valueCallback',
-    'Drupal\Core\Render\Element\Radios::valueCallback',
-    'Drupal\Core\Render\Element\Range::valueCallback',
-    'Drupal\Core\Render\Element\Search::valueCallback',
-    'Drupal\Core\Render\Element\Select::valueCallback',
-    'Drupal\Core\Render\Element\Tableselect::valueCallback',
-    'Drupal\Core\Render\Element\Table::valueCallback',
-    'Drupal\Core\Render\Element\Tel::valueCallback',
-    'Drupal\Core\Render\Element\Textarea::valueCallback',
-    'Drupal\Core\Render\Element\Textfield::valueCallback',
-    'Drupal\Core\Render\Element\Token::valueCallback',
-    'Drupal\Core\Render\Element\Url::valueCallback',
-    'Drupal\Core\Render\Element\Weight::valueCallback',
-  ];
-
-  /**
    * Constructs a new FormBuilder.
    *
    * @param \Drupal\Core\Form\FormValidatorInterface $form_validator
@@ -561,6 +521,11 @@ public function processForm($form_id, &$form, FormStateInterface &$form_state) {
 
     // Only process the input if we have a correct form submission.
     if ($form_state->isProcessingInput()) {
+      // Form constructors may explicitly set #token to FALSE when cross site
+      // request forgery is irrelevant to the form, such as search forms.
+      if (isset($form['#token']) && $form['#token'] === FALSE) {
+        unset($form['#token']);
+      }
       // Form values for programmed form submissions typically do not include a
       // value for the submit button. But without a triggering element, a
       // potentially existing #limit_validation_errors property on the primary
@@ -683,23 +648,25 @@ public function prepareForm($form_id, &$form, FormStateInterface &$form_state) {
     // since tokens are session-bound and forms displayed to anonymous users are
     // very likely cached, we cannot assign a token for them.
     // During installation, there is no $user yet.
-    // Form constructors may explicitly set #token to FALSE when cross site
-    // request forgery is irrelevant to the form, such as search forms.
-    if ($form_state->isProgrammed() || (isset($form['#token']) && $form['#token'] === FALSE)) {
-      unset($form['#token']);
-    }
-    elseif ($user && $user->isAuthenticated()) {
-      // Generate a public token based on the form id.
-      $form['#token'] = $form_id;
-      $form['form_token'] = array(
-        '#id' => Html::getUniqueId('edit-' . $form_id . '-form-token'),
-        '#type' => 'token',
-        '#default_value' => $this->csrfToken->get($form['#token']),
-        // Form processing and validation requires this value, so ensure the
-        // submitted form value appears literally, regardless of custom #tree
-        // and #parents being set elsewhere.
-        '#parents' => array('form_token'),
-      );
+    if ($user && $user->isAuthenticated() && !$form_state->isProgrammed()) {
+      // Form constructors may explicitly set #token to FALSE when cross site
+      // request forgery is irrelevant to the form, such as search forms.
+      if (isset($form['#token']) && $form['#token'] === FALSE) {
+        unset($form['#token']);
+      }
+      // Otherwise, generate a public token based on the form id.
+      else {
+        $form['#token'] = $form_id;
+        $form['form_token'] = array(
+          '#id' => Html::getUniqueId('edit-' . $form_id . '-form-token'),
+          '#type' => 'token',
+          '#default_value' => $this->csrfToken->get($form['#token']),
+          // Form processing and validation requires this value, so ensure the
+          // submitted form value appears literally, regardless of custom #tree
+          // and #parents being set elsewhere.
+          '#parents' => array('form_token'),
+        );
+      }
     }
 
     if (isset($form_id)) {
@@ -776,13 +743,6 @@ protected function buildFormAction() {
   /**
    * {@inheritdoc}
    */
-  public function setInvalidTokenError(FormStateInterface $form_state) {
-    $this->formValidator->setInvalidTokenError($form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public function validateForm($form_id, &$form, FormStateInterface &$form_state) {
     $this->formValidator->validateForm($form_id, $form, $form_state);
   }
@@ -857,20 +817,6 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state
       $input = $form_state->getUserInput();
       if ($form_state->isProgrammed() || (!empty($input) && (isset($input['form_id']) && ($input['form_id'] == $form_id)))) {
         $form_state->setProcessInput();
-        if (isset($element['#token'])) {
-          $input = $form_state->getUserInput();
-          if (empty($input['form_token']) || !$this->csrfToken->validate($input['form_token'], $element['#token'])) {
-            // Set an early form error to block certain input processing since
-            // that opens the door for CSRF vulnerabilities.
-            $this->setInvalidTokenError($form_state);
-
-            // This value is checked in self::handleInputElement().
-            $form_state->setInvalidToken(TRUE);
-
-            // Make sure file uploads do not get processed.
-            $this->requestStack->getCurrentRequest()->files = new FileBag();
-          }
-        }
       }
       else {
         $form_state->setProcessInput(FALSE);
@@ -1048,31 +994,6 @@ public function doBuildForm($form_id, &$element, FormStateInterface &$form_state
   }
 
   /**
-   * Helper function to normalize the different callable formats.
-   *
-   * @param callable $value_callable
-   *   The callable to be checked.
-   *
-   * @return bool
-   *   TRUE if the callable is safe even if the CSRF token is invalid, FALSE
-   *   otherwise.
-   */
-  protected function valueCallableIsSafe(callable $value_callable) {
-    // The same static class method callable may be formatted in two array and
-    // two string forms:
-    // ['\Classname', 'methodname']
-    // ['Classname', 'methodname']
-    // '\Classname::methodname'
-    // 'Classname::methodname'
-    if (is_callable($value_callable, FALSE, $callable_name)) {
-      // The third parameter of is_callable() is set to a string form, but we
-      // still have to normalize further by stripping a leading '\'.
-      return in_array(ltrim($callable_name, '\\'), $this->safeCoreValueCallables);
-    }
-    return FALSE;
-  }
-
-  /**
    * Adds the #name and #value properties of an input element before rendering.
    */
   protected function handleInputElement($form_id, &$element, FormStateInterface &$form_state) {
@@ -1161,14 +1082,7 @@ protected function handleInputElement($form_id, &$element, FormStateInterface &$
         // If we have input for the current element, assign it to the #value
         // property, optionally filtered through $value_callback.
         if ($input_exists) {
-          // Skip all value callbacks except safe ones like text if the CSRF
-          // token was invalid.
-          if (!$form_state->hasInvalidToken() || $this->valueCallableIsSafe($value_callable)) {
-            $element['#value'] = call_user_func_array($value_callable, array(&$element, $input, &$form_state));
-          }
-          else {
-            $input = NULL;
-          }
+          $element['#value'] = call_user_func_array($value_callable, array(&$element, $input, &$form_state));
 
           if (!isset($element['#value']) && isset($input)) {
             $element['#value'] = $input;
diff --git a/core/lib/Drupal/Core/Form/FormState.php b/core/lib/Drupal/Core/Form/FormState.php
index bd47f1e..9cb0b0d 100644
--- a/core/lib/Drupal/Core/Form/FormState.php
+++ b/core/lib/Drupal/Core/Form/FormState.php
@@ -105,19 +105,6 @@ class FormState implements FormStateInterface {
   protected $rebuild = FALSE;
 
   /**
-   * If set to TRUE the form will skip calling form element value callbacks,
-   * except for a select list of callbacks provided by Drupal core that are
-   * known to be safe.
-   *
-   * This property is uncacheable.
-   *
-   * @see self::setInvalidToken()
-   *
-   * @var bool
-   */
-  protected $invalidToken = FALSE;
-
-  /**
    * Used when a form needs to return some kind of a
    * \Symfony\Component\HttpFoundation\Response object, e.g., a
    * \Symfony\Component\HttpFoundation\BinaryFileResponse when triggering a
@@ -1297,21 +1284,6 @@ public function cleanValues() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function setInvalidToken($invalid_token) {
-    $this->invalidToken = (bool) $invalid_token;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasInvalidToken() {
-    return $this->invalidToken;
-  }
-
-  /**
    * Wraps ModuleHandler::loadInclude().
    */
   protected function moduleLoadInclude($module, $type, $name = NULL) {
diff --git a/core/lib/Drupal/Core/Form/FormStateInterface.php b/core/lib/Drupal/Core/Form/FormStateInterface.php
index 11b089b..fd46f70 100644
--- a/core/lib/Drupal/Core/Form/FormStateInterface.php
+++ b/core/lib/Drupal/Core/Form/FormStateInterface.php
@@ -562,24 +562,6 @@ public function setRebuild($rebuild = TRUE);
   public function isRebuilding();
 
   /**
-   * Flags the form state as having or not an invalid token.
-   *
-   * @param bool $invalid_token
-   *   Whether the form has an invalid token.
-   *
-   * @return $this
-   */
-  public function setInvalidToken($invalid_token);
-
-  /**
-   * Determines if the form has an invalid token.
-   *
-   * @return bool
-   *   TRUE if the form has an invalid token, FALSE otherwise.
-   */
-  public function hasInvalidToken();
-
-  /**
    * Converts support notations for a form callback to a valid callable.
    *
    * Specifically, supports methods on the form/callback object as strings when
diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index 10678e3..96f2320 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -105,12 +105,13 @@ public function validateForm($form_id, &$form, FormStateInterface &$form_state)
     }
 
     // If the session token was set by self::prepareForm(), ensure that it
-    // matches the current user's session. This is duplicate to code in
-    // FormBuilder::doBuildForm() but left to protect any custom form handling
-    // code.
+    // matches the current user's session.
     if (isset($form['#token'])) {
-      if (!$this->csrfToken->validate($form_state->getValue('form_token'), $form['#token']) || $form_state->hasInvalidToken()) {
-        $this->setInvalidTokenError($form_state);
+      if (!$this->csrfToken->validate($form_state->getValue('form_token'), $form['#token'])) {
+        $url = $this->requestStack->getCurrentRequest()->getRequestUri();
+
+        // Setting this error will cause the form to fail validation.
+        $form_state->setErrorByName('form_token', $this->t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
 
         // Stop here and don't run any further validation handlers, because they
         // could invoke non-safe operations which opens the door for CSRF
@@ -127,16 +128,6 @@ public function validateForm($form_id, &$form, FormStateInterface &$form_state)
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function setInvalidTokenError(FormStateInterface $form_state) {
-    $url = $this->requestStack->getCurrentRequest()->getRequestUri();
-
-    // Setting this error will cause the form to fail validation.
-    $form_state->setErrorByName('form_token', $this->t('The form has become outdated. Copy any unsaved work in the form below and then <a href="@link">reload this page</a>.', array('@link' => $url)));
-  }
-
-  /**
    * Handles validation errors for forms with limited validation.
    *
    * If validation errors are limited then remove any non validated form values,
diff --git a/core/lib/Drupal/Core/Form/FormValidatorInterface.php b/core/lib/Drupal/Core/Form/FormValidatorInterface.php
index d2c8945..6f1cc52 100644
--- a/core/lib/Drupal/Core/Form/FormValidatorInterface.php
+++ b/core/lib/Drupal/Core/Form/FormValidatorInterface.php
@@ -54,14 +54,4 @@ public function executeValidateHandlers(&$form, FormStateInterface &$form_state)
    */
   public function validateForm($form_id, &$form, FormStateInterface &$form_state);
 
-  /**
-   * Sets a form_token error on the given form state.
-   *
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @return $this
-   */
-  public function setInvalidTokenError(FormStateInterface $form_state);
-
 }
diff --git a/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
index 8ca889b..9fb3d81 100644
--- a/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
+++ b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
@@ -18,7 +18,8 @@
    * Processes the inbound path.
    *
    * @param string $path
-   *   The path to process, with a leading slash.
+   *   The path to process, with a starting slash.
+   *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The HttpRequest object representing the current request.
    *
diff --git a/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php b/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
index b350112..8826a93 100644
--- a/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
+++ b/core/lib/Drupal/Core/PathProcessor/OutboundPathProcessorInterface.php
@@ -19,7 +19,7 @@
    * Processes the outbound path.
    *
    * @param string $path
-   *   The path to process, with a leading slash.
+   *   The path to process.
    * @param array $options
    *   An array of options such as would be passed to the generator's
    *   generateFromPath() method.
@@ -28,7 +28,7 @@
    * @param \Drupal\Core\Render\BubbleableMetadata $bubbleable_metadata
    *   (optional) Object to collect path processors' bubbleable metadata.
    *
-   * @return string
+   * @return
    *   The processed path.
    */
   public function processOutbound($path, &$options = array(), Request $request = NULL, BubbleableMetadata $bubbleable_metadata = NULL);
diff --git a/core/lib/Drupal/Core/Render/Element/MachineName.php b/core/lib/Drupal/Core/Render/Element/MachineName.php
index 66c85c7..f351ddc 100644
--- a/core/lib/Drupal/Core/Render/Element/MachineName.php
+++ b/core/lib/Drupal/Core/Render/Element/MachineName.php
@@ -104,11 +104,6 @@ public function getInfo() {
    * {@inheritdoc}
    */
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input !== FALSE && $input !== NULL) {
-      // This should be a string, but allow other scalars since they might be
-      // valid input in programmatic form submissions.
-      return is_scalar($input) ? (string) $input : '';
-    }
     return NULL;
   }
 
diff --git a/core/lib/Drupal/Core/Render/Element/Password.php b/core/lib/Drupal/Core/Render/Element/Password.php
index bd54c98..308d53b 100644
--- a/core/lib/Drupal/Core/Render/Element/Password.php
+++ b/core/lib/Drupal/Core/Render/Element/Password.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Render\Element;
 
-use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 
 /**
@@ -69,16 +68,4 @@ public static function preRenderPassword($element) {
     return $element;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input !== FALSE && $input !== NULL) {
-      // This should be a string, but allow other scalars since they might be
-      // valid input in programmatic form submissions.
-      return is_scalar($input) ? (string) $input : '';
-    }
-    return NULL;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
index 026cb9a..7f3efa3 100644
--- a/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
+++ b/core/lib/Drupal/Core/Render/Element/PasswordConfirm.php
@@ -50,20 +50,9 @@ public function getInfo() {
    */
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
     if ($input === FALSE) {
-      $element += ['#default_value' => []];
-      return $element['#default_value'] + ['pass1' => '', 'pass2' => ''];
+      $element += array('#default_value' => array());
+      return $element['#default_value'] + array('pass1' => '', 'pass2' => '');
     }
-    $value = ['pass1' => '', 'pass2' => ''];
-    // Throw out all invalid array keys; we only allow pass1 and pass2.
-    foreach ($value as $allowed_key => $default) {
-      // These should be strings, but allow other scalars since they might be
-      // valid input in programmatic form submissions. Any nested array values
-      // are ignored.
-      if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
-        $value[$allowed_key] = (string) $input[$allowed_key];
-      }
-    }
-    return $value;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Render/Element/Textarea.php b/core/lib/Drupal/Core/Render/Element/Textarea.php
index efeebcd..60fc5cc 100644
--- a/core/lib/Drupal/Core/Render/Element/Textarea.php
+++ b/core/lib/Drupal/Core/Render/Element/Textarea.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Render\Element;
 
-use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 
 /**
@@ -56,15 +55,4 @@ public function getInfo() {
     );
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input !== FALSE && $input !== NULL) {
-      // This should be a string, but allow other scalars since they might be
-      // valid input in programmatic form submissions.
-      return is_scalar($input) ? (string) $input : '';
-    }
-    return NULL;
-  }
 }
diff --git a/core/lib/Drupal/Core/Render/Element/Textfield.php b/core/lib/Drupal/Core/Render/Element/Textfield.php
index 7348b4f..213ca07 100644
--- a/core/lib/Drupal/Core/Render/Element/Textfield.php
+++ b/core/lib/Drupal/Core/Render/Element/Textfield.php
@@ -77,14 +77,10 @@ public function getInfo() {
    */
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
     if ($input !== FALSE && $input !== NULL) {
-      // This should be a string, but allow other scalars since they might be
-      // valid input in programmatic form submissions.
-      if (!is_scalar($input)) {
-        $input = '';
-      }
+      // Equate $input to the form value to ensure it's marked for
+      // validation.
       return str_replace(array("\r", "\n"), '', $input);
     }
-    return NULL;
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Render/Element/Token.php b/core/lib/Drupal/Core/Render/Element/Token.php
index b45bde3..8b526c2 100644
--- a/core/lib/Drupal/Core/Render/Element/Token.php
+++ b/core/lib/Drupal/Core/Render/Element/Token.php
@@ -39,12 +39,9 @@ public function getInfo() {
    * {@inheritdoc}
    */
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input !== FALSE && $input !== NULL) {
-      // This should be a string, but allow other scalars since they might be
-      // valid input in programmatic form submissions.
-      return is_scalar($input) ? (string) $input : '';
+    if ($input !== FALSE) {
+      return (string) $input;
     }
-    return NULL;
   }
 
 }
diff --git a/core/lib/Drupal/Core/Render/Element/VerticalTabs.php b/core/lib/Drupal/Core/Render/Element/VerticalTabs.php
index adf6bd0..4c40aa7 100644
--- a/core/lib/Drupal/Core/Render/Element/VerticalTabs.php
+++ b/core/lib/Drupal/Core/Render/Element/VerticalTabs.php
@@ -71,10 +71,6 @@ public static function preRenderVerticalTabs($element) {
    *   The processed element.
    */
   public static function processVerticalTabs(&$element, FormStateInterface $form_state, &$complete_form) {
-    if (isset($element['#access']) && !$element['#access']) {
-      return $element;
-    }
-
     // Inject a new details as child, so that form_process_details() processes
     // this details element like any other details.
     $element['group'] = array(
diff --git a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
index 19edef1..cc20063 100644
--- a/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
+++ b/core/lib/Drupal/Core/Render/HtmlResponseAttachmentsProcessor.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Asset\AssetResolverInterface;
 use Drupal\Core\Asset\AttachedAssets;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Form\EnforcedResponseException;
 use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
@@ -104,18 +103,7 @@ public function processAttachments(AttachmentsInterface $response) {
     // attachments to be added to the response, which the attachment
     // placeholders rendered by renderHtmlResponseAttachmentPlaceholders() will
     // need to include.
-    //
-    // @todo Exceptions should not be used for code flow control. However, the
-    //   Form API does not integrate with the HTTP Kernel based architecture of
-    //   Drupal 8. In order to resolve this issue properly it is necessary to
-    //   completely separate form submission from rendering.
-    //   @see https://www.drupal.org/node/2367555
-    try {
-      $response = $this->renderPlaceholders($response);
-    }
-    catch (EnforcedResponseException $e) {
-      return $e->getResponse();
-    }
+    $response = $this->renderPlaceholders($response);
 
     $attached = $response->getAttachments();
 
diff --git a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
index 31192f3..c54799d 100644
--- a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php
@@ -64,7 +64,7 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
       }
     }
 
-    $html = $this->drupalRenderRoot($main_content);
+    $html = (string) $this->drupalRenderRoot($main_content);
     $response->setAttachments($main_content['#attached']);
 
     // The selector for the insert command is NULL as the new content will
@@ -72,7 +72,7 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
     // behavior can be changed with #ajax['method'].
     $response->addCommand(new InsertCommand(NULL, $html));
     $status_messages = array('#type' => 'status_messages');
-    $output = $this->drupalRenderRoot($status_messages);
+    $output = (string) $this->drupalRenderRoot($status_messages);
     if (!empty($output)) {
       $response->addCommand(new PrependCommand(NULL, $output));
     }
diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
index dffd2cf..6bf591a 100644
--- a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
+++ b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php
@@ -118,14 +118,4 @@ public function __sleep() {
     return array('string', 'arguments', 'options');
   }
 
-  /**
-   * Returns a representation of the object for use in JSON serialization.
-   *
-   * @return string
-   *   The safe string content.
-   */
-  public function jsonSerialize() {
-    return $this->__toString();
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php
index cc0d591..8fe6788 100644
--- a/core/lib/Drupal/Core/Template/Attribute.php
+++ b/core/lib/Drupal/Core/Template/Attribute.php
@@ -302,14 +302,4 @@ public function storage() {
     return $this->storage;
   }
 
-  /**
-   * Returns a representation of the object for use in JSON serialization.
-   *
-   * @return string
-   *   The safe string content.
-   */
-  public function jsonSerialize() {
-    return (string) $this;
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Template/TwigExtension.php b/core/lib/Drupal/Core/Template/TwigExtension.php
index 7edc7c4..443cf73 100644
--- a/core/lib/Drupal/Core/Template/TwigExtension.php
+++ b/core/lib/Drupal/Core/Template/TwigExtension.php
@@ -112,6 +112,7 @@ public function getFunctions() {
       // in \Symfony\Bridge\Twig\Extension\RoutingExtension
       new \Twig_SimpleFunction('url', array($this, 'getUrl'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
       new \Twig_SimpleFunction('path', array($this, 'getPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
+      new \Twig_SimpleFunction('url_from_path', array($this, 'getUrlFromPath'), array('is_safe_callback' => array($this, 'isUrlGenerationSafe'))),
       new \Twig_SimpleFunction('link', array($this, 'getLink')),
       new \Twig_SimpleFunction('file_url', 'file_create_url'),
       new \Twig_SimpleFunction('attach_library', [$this, 'attachLibrary']),
@@ -141,7 +142,7 @@ public function getFilters() {
       // Implements safe joining.
       // @todo Make that the default for |join? Upstream issue:
       //   https://github.com/fabpot/Twig/issues/1420
-      new \Twig_SimpleFilter('safe_join', [$this, 'safeJoin'], ['needs_environment' => true, 'is_safe' => ['html']]),
+      new \Twig_SimpleFilter('safe_join', 'twig_drupal_join_filter', array('is_safe' => array('html'))),
 
       // Array filters.
       new \Twig_SimpleFilter('without', 'twig_without'),
@@ -229,6 +230,31 @@ public function getUrl($name, $parameters = array(), $options = array()) {
   }
 
   /**
+   * Generates an absolute URL given a path.
+   *
+   * @param string $path
+   *   The path.
+   * @param array $options
+   *   (optional) An associative array of additional options. The 'absolute'
+   *   option is forced to be TRUE.
+   *
+   * @return string
+   *   The generated absolute URL for the given path.
+   *
+   * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 8.0.0.
+   */
+  public function getUrlFromPath($path, $options = array()) {
+    // Generate URL.
+    $options['absolute'] = TRUE;
+    $generated_url = $this->urlGenerator->generateFromPath($path, $options, TRUE);
+
+    // Return as render array, so we can bubble the bubbleable metadata.
+    $build = ['#markup' => $generated_url->getGeneratedUrl()];
+    $generated_url->applyTo($build);
+    return $build;
+  }
+
+  /**
    * Gets a rendered link from an url object.
    *
    * @param string $text
@@ -488,26 +514,4 @@ public function renderVar($arg) {
     return $this->renderer->render($arg);
   }
 
-  /**
-   * Joins several strings together safely.
-   *
-   * @param \Twig_Environment $env
-   *   A Twig_Environment instance.
-   * @param mixed[]|\Traversable $value
-   *   The pieces to join.
-   * @param string $glue
-   *   The delimiter with which to join the string. Defaults to an empty string.
-   *   This value is expected to be safe for output and user provided data
-   *   should never be used as a glue.
-   *
-   * @return string
-   *   The strings joined together.
-   */
-  public function safeJoin(\Twig_Environment $env, $value, $glue = '') {
-    return implode($glue, array_map(function($item) use ($env) {
-      // If $item is not marked safe then it will be escaped.
-      return $this->escapeFilter($env, $item, 'html', NULL, TRUE);
-    }, $value));
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php
index 6fb3733..29b6e39 100644
--- a/core/lib/Drupal/Core/Theme/Registry.php
+++ b/core/lib/Drupal/Core/Theme/Registry.php
@@ -669,9 +669,8 @@ protected function postProcessExtension(array &$cache, ActiveTheme $theme) {
     // will go missing. This will add the expected function. It also allows
     // modules or themes to have a variable process function based on a pattern
     // even if the hook does not exist.
-    ksort($suggestion_level);
-    foreach ($suggestion_level as $level => $item) {
-      foreach ($item as $preprocessor => $hook) {
+    for ($level = 1; $level <= count($suggestion_level); $level++) {
+      foreach ($suggestion_level[$level] as $preprocessor => $hook) {
         if (isset($cache[$hook]['preprocess functions']) && !in_array($hook, $cache[$hook]['preprocess functions'])) {
           // Add missing preprocessor to existing hook.
           $cache[$hook]['preprocess functions'][] = $preprocessor;
diff --git a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
index 38c2014..8c1ef03 100644
--- a/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
+++ b/core/lib/Drupal/Core/Theme/ThemeNegotiator.php
@@ -14,6 +14,9 @@
  *
  * It therefore uses ThemeNegotiatorInterface objects which are passed in
  * using the 'theme_negotiator' tag.
+ *
+ * @see \Drupal\Core\Theme\ThemeNegotiatorPass
+ * @see \Drupal\Core\Theme\ThemeNegotiatorInterface
  */
 class ThemeNegotiator implements ThemeNegotiatorInterface {
 
diff --git a/core/misc/drupal.js b/core/misc/drupal.js
index befb9d8..505175d 100644
--- a/core/misc/drupal.js
+++ b/core/misc/drupal.js
@@ -1,29 +1,19 @@
 /**
  * @file
- * Defines the Drupal JavaScript API.
+ * Defines the Drupal JS API.
  */
 
 /**
- * A jQuery object, typically the return value from a `$(selector)` call.
- *
- * Holds an HTMLElement or a collection of HTMLElements.
+ * A jQuery object.
  *
  * @typedef {object} jQuery
  *
  * @prop {number} length=0
- *   Number of elements contained in the jQuery object.
  */
 
 /**
  * Variable generated by Drupal that holds all translated strings from PHP.
  *
- * Content of this variable is automatically created by Drupal when using the
- * Interface Translation module. It holds the translation of strings used on
- * the page.
- *
- * This variable is used to pass data from the backend to the frontend. Data
- * contained in `drupalSettings` is used during behavior initialization.
- *
  * @global
  *
  * @var {object} drupalTranslations
@@ -32,15 +22,13 @@
 /**
  * Global Drupal object.
  *
- * All Drupal JavaScript APIs are contained in this namespace.
- *
  * @global
  *
  * @namespace
  */
 window.Drupal = {behaviors: {}, locale: {}};
 
-// Class indicating that JavaScript is enabled; used for styling purpose.
+// Class indicating that JS is enabled; used for styling purpose.
 document.documentElement.className += ' js';
 
 // Allow other JavaScript libraries to use $.
@@ -68,30 +56,25 @@ if (window.jQuery) {
   };
 
   /**
-   * Custom error thrown after attach/detach if one or more behaviors failed.
-   * Initializes the JavaScript behaviors for page loads and Ajax requests.
+   * Callback function initializing code run on page load and Ajax requests.
    *
    * @callback Drupal~behaviorAttach
    *
-   * @param {HTMLDocument|HTMLElement} context
-   *   An element to detach behaviors from.
-   * @param {?object} settings
-   *   An object containing settings for the current context. It is rarely used.
+   * @param {HTMLElement} context
+   * @param {object} settings
    *
    * @see Drupal.attachBehaviors
    */
 
   /**
-   * Reverts and cleans up JavaScript behavior initialization.
+   * Callback function for reverting and cleaning up behavior initialization.
    *
    * @callback Drupal~behaviorDetach
    *
-   * @param {HTMLDocument|HTMLElement} context
-   *   An element to attach behaviors to.
+   * @param {HTMLElement} context
    * @param {object} settings
-   *   An object containing settings for the current context.
    * @param {string} trigger
-   *   One of `'unload'`, `'move'`, or `'serialize'`.
+   *   One of 'unload', 'serialize' or 'move'.
    *
    * @see Drupal.detachBehaviors
    */
@@ -100,7 +83,7 @@ if (window.jQuery) {
    * @typedef {object} Drupal~behavior
    *
    * @prop {Drupal~behaviorAttach} attach
-   *   Function run on page load and after an Ajax call.
+   *   Function run on page load and after an AJAX call.
    * @prop {Drupal~behaviorDetach} detach
    *   Function run when content is serialized or removed from the page.
    */
@@ -114,42 +97,42 @@ if (window.jQuery) {
    */
 
   /**
-   * Defines a behavior to be run during attach and detach phases.
-   *
-   * Attaches all registered behaviors to a page element.
+   * Attach all registered behaviors to a page element.
    *
    * Behaviors are event-triggered actions that attach to page elements,
    * enhancing default non-JavaScript UIs. Behaviors are registered in the
    * {@link Drupal.behaviors} object using the method 'attach' and optionally
-   * also 'detach'.
+   * also 'detach' as follows:
    *
-   * {@link Drupal.attachBehaviors} is added below to the `jQuery.ready` event
-   * and therefore runs on initial page load. Developers implementing Ajax in
-   * their solutions should also call this function after new page content has
-   * been loaded, feeding in an element to be processed, in order to attach all
+   * {@link Drupal.attachBehaviors} is added below to the jQuery.ready event and
+   * therefore runs on initial page load. Developers implementing Ajax in their
+   * solutions should also call this function after new page content has been
+   * loaded, feeding in an element to be processed, in order to attach all
    * behaviors to the new content.
    *
-   * Behaviors should use `var elements =
-   * $(context).find(selector).once('behavior-name');` to ensure the behavior is
-   * attached only once to a given element. (Doing so enables the reprocessing
-   * of given elements, which may be needed on occasion despite the ability to
-   * limit behavior attachment to a particular element.)
+   * Behaviors should use
+   *     `var elements = $(context).find(selector).once('behavior-name');`
+   * to ensure the behavior is attached only once to a given element. (Doing so
+   * enables the reprocessing of given elements, which may be needed on
+   * occasion despite the ability to limit behavior attachment to a particular
+   * element.)
    *
    * @example
    * Drupal.behaviors.behaviorName = {
    *   attach: function (context, settings) {
-   *     // ...
+   *     ...
    *   },
    *   detach: function (context, settings, trigger) {
-   *     // ...
+   *     ...
    *   }
    * };
    *
-   * @param {HTMLDocument|HTMLElement} [context=document]
-   *   An element to attach behaviors to.
-   * @param {object} [settings=drupalSettings]
+   * @param {Element} context
+   *   An element to attach behaviors to. If none is given, the document
+   *   element is used.
+   * @param {object} settings
    *   An object containing settings for the current context. If none is given,
-   *   the global {@link drupalSettings} object is used.
+   *   the global drupalSettings object is used.
    *
    * @see Drupal~behaviorAttach
    * @see Drupal.detachBehaviors
@@ -178,27 +161,29 @@ if (window.jQuery) {
   domready(function () { Drupal.attachBehaviors(document, drupalSettings); });
 
   /**
-   * Detaches registered behaviors from a page element.
+   * Detach registered behaviors from a page element.
    *
-   * Developers implementing Ajax in their solutions should call this function
-   * before page content is about to be removed, feeding in an element to be
-   * processed, in order to allow special behaviors to detach from the content.
+   * Developers implementing AHAH/Ajax in their solutions should call this
+   * function before page content is about to be removed, feeding in an element
+   * to be processed, in order to allow special behaviors to detach from the
+   * content.
    *
-   * Such implementations should use `.findOnce()` and `.removeOnce()` to find
-   * elements with their corresponding `Drupal.behaviors.behaviorName.attach`
-   * implementation, i.e. `.removeOnce('behaviorName')`, to ensure the behavior
+   * Such implementations should use .findOnce() and .removeOnce() to find
+   * elements with their corresponding Drupal.behaviors.behaviorName.attach
+   * implementation, i.e. .removeOnce('behaviorName'), to ensure the behavior
    * is detached only from previously processed elements.
    *
-   * @param {HTMLDocument|HTMLElement} [context=document]
-   *   An element to detach behaviors from.
-   * @param {object} [settings=drupalSettings]
+   * @param {Element} context
+   *   An element to detach behaviors from. If none is given, the document
+   *   element is used.
+   * @param {object} settings
    *   An object containing settings for the current context. If none given,
-   *   the global {@link drupalSettings} object is used.
-   * @param {string} [trigger='unload']
+   *   the global drupalSettings object is used.
+   * @param {string} trigger
    *   A string containing what's causing the behaviors to be detached. The
    *   possible triggers are:
-   *   - `'unload'`: The context element is being removed from the DOM.
-   *   - `'move'`: The element is about to be moved within the DOM (for example,
+   *   - unload: (default) The context element is being removed from the DOM.
+   *   - move: The element is about to be moved within the DOM (for example,
    *     during a tabledrag row swap). After the move is completed,
    *     {@link Drupal.attachBehaviors} is called, so that the behavior can undo
    *     whatever it did in response to the move. Many behaviors won't need to
@@ -206,7 +191,7 @@ if (window.jQuery) {
    *     IFRAME elements reload their "src" when being moved within the DOM,
    *     behaviors bound to IFRAME elements (like WYSIWYG editors) may need to
    *     take some action.
-   *   - `'serialize'`: When an Ajax form is submitted, this is called with the
+   *   - serialize: When an Ajax form is submitted, this is called with the
    *     form as the context. This provides every behavior within the form an
    *     opportunity to ensure that the field elements have correct content
    *     in them before the form is serialized. The canonical use-case is so
@@ -238,14 +223,11 @@ if (window.jQuery) {
   };
 
   /**
-   * Tests the document width for mobile configurations.
+   * Helper to test document width for mobile configurations.
    *
    * @param {number} [width=640]
-   *   Value of the width to check for.
    *
    * @return {bool}
-   *   true if the document's `clientWidth` is bigger than `width`, returns
-   *   false otherwise.
    *
    * @deprecated Temporary solution for the mobile initiative.
    */
@@ -255,7 +237,7 @@ if (window.jQuery) {
   };
 
   /**
-   * Encodes special characters in a plain-text string for display as HTML.
+   * Encode special characters in a plain-text string for display as HTML.
    *
    * @param {string} str
    *   The string to be encoded.
@@ -275,7 +257,7 @@ if (window.jQuery) {
   };
 
   /**
-   * Replaces placeholders with sanitized values in a string.
+   * Replace placeholders with sanitized values in a string.
    *
    * @param {string} str
    *   A string with placeholders.
@@ -283,11 +265,11 @@ if (window.jQuery) {
    *   An object of replacements pairs to make. Incidences of any key in this
    *   array are replaced with the corresponding value. Based on the first
    *   character of the key, the value is escaped and/or themed:
-   *    - `'!variable'`: inserted as is.
-   *    - `'@variable'`: escape plain text to HTML ({@link Drupal.checkPlain}).
-   *    - `'%variable'`: escape text and theme as a placeholder for user-
-   *      submitted content ({@link Drupal.checkPlain} +
-   *      `{@link Drupal.theme}('placeholder')`).
+   *    - !variable: inserted as is
+   *    - @variable: escape plain text to HTML ({@link Drupal.checkPlain})
+   *    - %variable: escape text and theme as a placeholder for user-submitted
+   *      content ({@link Drupal.checkPlain} +
+   *      {@link Drupal.theme}('placeholder'))
    *
    * @return {string}
    *
@@ -322,7 +304,7 @@ if (window.jQuery) {
   };
 
   /**
-   * Replaces substring.
+   * Replace substring.
    *
    * The longest keys will be tried first. Once a substring has been replaced,
    * its new value will not be searched again.
@@ -332,10 +314,10 @@ if (window.jQuery) {
    * @param {object} args
    *   Key-value pairs.
    * @param {Array|null} keys
-   *   Array of keys from `args`. Internal use only.
+   *   Array of keys from the "args".  Internal use only.
    *
    * @return {string}
-   *   The replaced string.
+   *   Returns the replaced string.
    */
   Drupal.stringReplace = function (str, args, keys) {
     if (str.length === 0) {
@@ -374,7 +356,7 @@ if (window.jQuery) {
   };
 
   /**
-   * Translates strings to the page language, or a given language.
+   * Translate strings to the page language or a given language.
    *
    * See the documentation of the server-side t() function for further details.
    *
@@ -385,12 +367,10 @@ if (window.jQuery) {
    *   of any key in this array are replaced with the corresponding value.
    *   See {@link Drupal.formatString}.
    * @param {object} [options]
-   *   Additional options for translation.
    * @param {string} [options.context='']
    *   The context the source string belongs to.
    *
    * @return {string}
-   *   The formatted string.
    *   The translated string.
    */
   Drupal.t = function (str, args, options) {
@@ -415,7 +395,6 @@ if (window.jQuery) {
    *   Drupal path to transform to URL.
    *
    * @return {string}
-   *   The full URL.
    */
   Drupal.url = function (path) {
     return drupalSettings.path.baseUrl + drupalSettings.path.pathPrefix + path;
@@ -424,10 +403,10 @@ if (window.jQuery) {
   /**
    * Returns the passed in URL as an absolute URL.
    *
-   * @param {string} url
+   * @param url
    *   The URL string to be normalized to an absolute URL.
    *
-   * @return {string}
+   * @return
    *   The normalized, absolute URL.
    *
    * @see https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js
@@ -456,11 +435,11 @@ if (window.jQuery) {
   /**
    * Returns true if the URL is within Drupal's base path.
    *
-   * @param {string} url
+   * @param url
    *   The URL string to be tested.
    *
-   * @return {bool}
-   *   `true` if local.
+   * @return
+   *   Boolean true if local.
    *
    * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58
    */
@@ -497,7 +476,7 @@ if (window.jQuery) {
   };
 
   /**
-   * Formats a string containing a count of items.
+   * Format a string containing a count of items.
    *
    * This function ensures that the string is pluralized correctly. Since
    * {@link Drupal.t} is called by this function, make sure not to pass
@@ -557,24 +536,22 @@ if (window.jQuery) {
    *   Unencoded path.
    *
    * @return {string}
-   *   The encoded path.
    */
   Drupal.encodePath = function (item) {
     return window.encodeURIComponent(item).replace(/%2F/g, '/');
   };
 
   /**
-   * Generates the themed representation of a Drupal object.
+   * Generate the themed representation of a Drupal object.
    *
    * All requests for themed output must go through this function. It examines
    * the request and routes it to the appropriate theme function. If the current
    * theme does not provide an override function, the generic theme function is
    * called.
    *
-   * @example
-   * <caption>To retrieve the HTML for text that should be emphasized and
-   * displayed as a placeholder inside a sentence.</caption>
-   * Drupal.theme('placeholder', text);
+   * For example, to retrieve the HTML for text that should be emphasized and
+   * displayed as a placeholder inside a sentence, call
+   * `Drupal.theme('placeholder', text)`.
    *
    * @namespace
    *
diff --git a/core/modules/aggregator/aggregator.theme.inc b/core/modules/aggregator/aggregator.theme.inc
index a47a611..e2a4591 100644
--- a/core/modules/aggregator/aggregator.theme.inc
+++ b/core/modules/aggregator/aggregator.theme.inc
@@ -5,7 +5,6 @@
  * Preprocessors and theme functions of Aggregator module.
  */
 
-use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Render\Element;
 
 /**
@@ -25,7 +24,7 @@ function template_preprocess_aggregator_item(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 
-  $variables['url'] = UrlHelper::stripDangerousProtocols($item->getLink());
+  $variables['url'] = check_url($item->getLink());
   $variables['title'] = $item->label();
 }
 
diff --git a/core/modules/block/block.api.php b/core/modules/block/block.api.php
index a60f35e..468f893 100644
--- a/core/modules/block/block.api.php
+++ b/core/modules/block/block.api.php
@@ -127,61 +127,6 @@ function hook_block_view_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\B
 }
 
 /**
- * Alter the result of \Drupal\Core\Block\BlockBase::build().
- *
- * Unlike hook_block_view_alter(), this hook is called very early, before the
- * block is being assembled. Therefore, it is early enough to alter the
- * cacheability metadata (change #cache), or to explicitly placeholder the block
- * (set #create_placeholder).
- *
- * In addition to hook_block_build_alter(), which is called for all blocks,
- * there is hook_block_build_BASE_BLOCK_ID_alter(), which can be used to target
- * a specific block or set of similar blocks.
- *
- * @param array &$build
- *   A renderable array of data, only containing #cache.
- * @param \Drupal\Core\Block\BlockPluginInterface $block
- *   The block plugin instance.
- *
- * @see hook_block_build_BASE_BLOCK_ID_alter()
- * @see entity_crud
- *
- * @ingroup block_api
- */
-function hook_block_build_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
-  // Add the 'user' cache context to some blocks.
-  if ($some_condition) {
-    $build['#contexts'][] = 'user';
-  }
-}
-
-/**
- * Provide a block plugin specific block_build alteration.
- *
- * In this hook name, BASE_BLOCK_ID refers to the block implementation's plugin
- * id, regardless of whether the plugin supports derivatives. For example, for
- * the \Drupal\system\Plugin\Block\SystemPoweredByBlock block, this would be
- * 'system_powered_by_block' as per that class's annotation. And for the
- * \Drupal\system\Plugin\Block\SystemMenuBlock block, it would be
- * 'system_menu_block' as per that class's annotation, regardless of which menu
- * the derived block is for.
- *
- * @param array $build
- *   A renderable array of data, only containing #cache.
- * @param \Drupal\Core\Block\BlockPluginInterface $block
- *   The block plugin instance.
- *
- * @see hook_block_build_alter()
- * @see entity_crud
- *
- * @ingroup block_api
- */
-function hook_block_build_BASE_BLOCK_ID_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
-  // Explicitly enable placeholdering of the specific block.
-  $build['#create_placeholder'] = TRUE;
-}
-
-/**
  * Control access to a block instance.
  *
  * Modules may implement this hook if they want to have a say in whether or not
diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php
index c0a3b2e..43d7a1c 100644
--- a/core/modules/block/src/BlockListBuilder.php
+++ b/core/modules/block/src/BlockListBuilder.php
@@ -9,6 +9,7 @@
 
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Serialization\Json;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
@@ -260,7 +261,7 @@ protected function buildBlocksForm() {
             $form[$entity_id]['#attributes']['class'][] = 'js-block-placed';
           }
           $form[$entity_id]['info'] = array(
-            '#plain_text' => $info['label'],
+            '#markup' => SafeMarkup::checkPlain($info['label']),
             '#wrapper_attributes' => array(
               'class' => array('block'),
             ),
diff --git a/core/modules/block/src/BlockViewBuilder.php b/core/modules/block/src/BlockViewBuilder.php
index 6e99faa..187692d 100644
--- a/core/modules/block/src/BlockViewBuilder.php
+++ b/core/modules/block/src/BlockViewBuilder.php
@@ -8,17 +8,12 @@
 namespace Drupal\block;
 
 use Drupal\Component\Utility\SafeMarkup;
-use Drupal\Core\Block\MainContentBlockPluginInterface;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\CacheableMetadata;
-use Drupal\Core\Entity\EntityManagerInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
+use Drupal\Core\Entity\EntityViewBuilderInterface;
 use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Render\Element;
-use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a Block view builder.
@@ -26,42 +21,6 @@
 class BlockViewBuilder extends EntityViewBuilder {
 
   /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * Constructs a new BlockViewBuilder.
-   *
-   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
-   *   The entity type definition.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager service.
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   *   The language manager.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   */
-  public function __construct(EntityTypeInterface $entity_type, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, ModuleHandlerInterface $module_handler) {
-    parent::__construct($entity_type, $entity_manager, $language_manager);
-    $this->moduleHandler = $module_handler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
-    return new static(
-      $entity_type,
-      $container->get('entity.manager'),
-      $container->get('language_manager'),
-      $container->get('module_handler')
-    );
-  }
-
-  /**
    * {@inheritdoc}
    */
   public function buildComponents(array &$build, array $entities, array $displays, $view_mode, $langcode = NULL) {
@@ -81,9 +40,13 @@ public function view(EntityInterface $entity, $view_mode = 'full', $langcode = N
   public function viewMultiple(array $entities = array(), $view_mode = 'full', $langcode = NULL) {
     /** @var \Drupal\block\BlockInterface[] $entities */
     $build = array();
-    foreach ($entities as $entity) {
+    foreach ($entities as  $entity) {
       $entity_id = $entity->id();
       $plugin = $entity->getPlugin();
+      $plugin_id = $plugin->getPluginId();
+      $base_id = $plugin->getBaseId();
+      $derivative_id = $plugin->getDerivativeId();
+      $configuration = $plugin->getConfiguration();
 
       $cache_tags = Cache::mergeTags($this->getCacheTags(), $entity->getCacheTags());
       $cache_tags = Cache::mergeTags($cache_tags, $plugin->getCacheTags());
@@ -91,6 +54,20 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
       // Create the render array for the block as a whole.
       // @see template_preprocess_block().
       $build[$entity_id] = array(
+        '#theme' => 'block',
+        '#attributes' => array(),
+        // All blocks get a "Configure block" contextual link.
+        '#contextual_links' => array(
+          'block' => array(
+            'route_parameters' => array('block' => $entity->id()),
+          ),
+        ),
+        '#weight' => $entity->getWeight(),
+        '#configuration' => $configuration,
+        '#plugin_id' => $plugin_id,
+        '#base_plugin_id' => $base_id,
+        '#derivative_plugin_id' => $derivative_id,
+        '#id' => $entity->id(),
         '#cache' => [
           'keys' => ['entity_view', 'block', $entity->id()],
           'contexts' => Cache::mergeContexts(
@@ -100,97 +77,23 @@ public function viewMultiple(array $entities = array(), $view_mode = 'full', $la
           'tags' => $cache_tags,
           'max-age' => $plugin->getCacheMaxAge(),
         ],
+        '#pre_render' => [
+          [$this, 'buildBlock'],
+        ],
+        // Add the entity so that it can be used in the #pre_render method.
+        '#block' => $entity,
       );
+      $build[$entity_id]['#configuration']['label'] = SafeMarkup::checkPlain($configuration['label']);
 
-      // Allow altering of cacheability metadata or setting #create_placeholder.
-      $this->moduleHandler->alter(['block_build', "block_build_" . $plugin->getBaseId()], $build[$entity_id], $plugin);
-
-      if ($plugin instanceof MainContentBlockPluginInterface) {
-        // Immediately build a #pre_render-able block, since this block cannot
-        // be built lazily.
-        $build[$entity_id] += static::buildPreRenderableBlock($entity, $this->moduleHandler());
-      }
-      else {
-        // Assign a #lazy_builder callback, which will generate a #pre_render-
-        // able block lazily (when necessary).
-        $build[$entity_id] += [
-          '#lazy_builder' => [static::class . '::lazyBuilder', [$entity_id, $view_mode, $langcode]],
-        ];
-      }
+      // Don't run in ::buildBlock() to ensure cache keys can be altered. If an
+      // alter hook wants to modify the block contents, it can append another
+      // #pre_render hook.
+      $this->moduleHandler()->alter(array('block_view', "block_view_$base_id"), $build[$entity_id], $plugin);
     }
-
     return $build;
   }
 
   /**
-   * Builds a #pre_render-able block render array.
-   *
-   * @param \Drupal\block\BlockInterface $entity
-   *   A block config entity.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler service.
-   *
-   * @return array
-   *   A render array with a #pre_render callback to render the block.
-   */
-  protected static function buildPreRenderableBlock($entity, ModuleHandlerInterface $module_handler) {
-    $plugin = $entity->getPlugin();
-    $plugin_id = $plugin->getPluginId();
-    $base_id = $plugin->getBaseId();
-    $derivative_id = $plugin->getDerivativeId();
-    $configuration = $plugin->getConfiguration();
-
-    // Create the render array for the block as a whole.
-    // @see template_preprocess_block().
-    $build = [
-      '#theme' => 'block',
-      '#attributes' => [],
-      // All blocks get a "Configure block" contextual link.
-      '#contextual_links' => [
-        'block' => [
-          'route_parameters' => ['block' => $entity->id()],
-        ],
-      ],
-      '#weight' => $entity->getWeight(),
-      '#configuration' => $configuration,
-      '#plugin_id' => $plugin_id,
-      '#base_plugin_id' => $base_id,
-      '#derivative_plugin_id' => $derivative_id,
-      '#id' => $entity->id(),
-      '#pre_render' => [
-        static::class . '::preRender',
-      ],
-      // Add the entity so that it can be used in the #pre_render method.
-      '#block' => $entity,
-    ];
-
-    $build['#configuration']['label'] = SafeMarkup::checkPlain($configuration['label']);
-
-    // If an alter hook wants to modify the block contents, it can append
-    // another #pre_render hook.
-    $module_handler->alter(['block_view', "block_view_$base_id"], $build, $plugin);
-
-    return $build;
-  }
-
-  /**
-   * #lazy_builder callback; builds a #pre_render-able block.
-   *
-   * @param $entity_id
-   *   A block config entity ID.
-   * @param $view_mode
-   *   The view mode the block is being viewed in.
-   * @param $langcode
-   *   The langcode the block is being viewed in.
-   *
-   * @return array
-   *   A render array with a #pre_render callback to render the block.
-   */
-  public static function lazyBuilder($entity_id, $view_mode, $langcode) {
-    return static::buildPreRenderableBlock(entity_load('block', $entity_id), \Drupal::service('module_handler'));
-  }
-
-  /**
    * #pre_render callback for building a block.
    *
    * Renders the content using the provided block plugin, and then:
@@ -199,7 +102,7 @@ public static function lazyBuilder($entity_id, $view_mode, $langcode) {
    * - if there is content, moves the contextual links from the block content to
    *   the block itself.
    */
-  public static function preRender($build) {
+  public function buildBlock($build) {
     $content = $build['#block']->getPlugin()->build();
     // Remove the block entity from the render array, to ensure that blocks
     // can be rendered without the block config entity.
diff --git a/core/modules/block/src/Tests/BlockInterfaceTest.php b/core/modules/block/src/Tests/BlockInterfaceTest.php
index 7215765..5e8b54c 100644
--- a/core/modules/block/src/Tests/BlockInterfaceTest.php
+++ b/core/modules/block/src/Tests/BlockInterfaceTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\block\Tests;
 
 use Drupal\Core\Cache\Cache;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormState;
 use Drupal\simpletest\KernelTestBase;
 use Drupal\block\BlockInterface;
@@ -72,7 +73,7 @@ public function testBlockInterface() {
       'admin_label' => array(
         '#type' => 'item',
         '#title' => t('Block description'),
-        '#plain_text' => $definition['admin_label'],
+        '#markup' => SafeMarkup::checkPlain($definition['admin_label']),
       ),
       'label' => array(
         '#type' => 'textfield',
diff --git a/core/modules/block/src/Tests/BlockTest.php b/core/modules/block/src/Tests/BlockTest.php
index cff4a24..17fd982 100644
--- a/core/modules/block/src/Tests/BlockTest.php
+++ b/core/modules/block/src/Tests/BlockTest.php
@@ -410,22 +410,6 @@ public function testBlockCacheTags() {
   }
 
   /**
-   * Tests that a link exists to block layout from the appearance form.
-   */
-  public function testThemeAdminLink() {
-    $this->drupalPlaceBlock('help_block', ['region' => 'help']);
-    $theme_admin = $this->drupalCreateUser([
-      'administer blocks',
-      'administer themes',
-      'access administration pages',
-    ]);
-    $this->drupalLogin($theme_admin);
-    $this->drupalGet('admin/appearance');
-    $this->assertText('You can place blocks for each theme on the block layout page');
-    $this->assertLinkByHref('admin/structure/block');
-  }
-
-  /**
    * Tests that uninstalling a theme removes its block configuration.
    */
   public function testUninstallTheme() {
diff --git a/core/modules/block/src/Tests/BlockViewBuilderTest.php b/core/modules/block/src/Tests/BlockViewBuilderTest.php
index bd35f1d..7e3c39a 100644
--- a/core/modules/block/src/Tests/BlockViewBuilderTest.php
+++ b/core/modules/block/src/Tests/BlockViewBuilderTest.php
@@ -186,27 +186,61 @@ protected function verifyRenderCacheHandling() {
 
   /**
    * Tests block view altering.
-   *
-   * @see hook_block_view_alter()
-   * @see hook_block_view_BASE_BLOCK_ID_alter()
    */
-  public function testBlockViewBuilderViewAlter() {
+  public function testBlockViewBuilderAlter() {
     // Establish baseline.
     $build = $this->getBlockRenderArray();
-    $this->setRawContent((string) $this->renderer->renderRoot($build));
-    $this->assertIdentical(trim((string) $this->cssSelect('div')[0]), 'Llamas > unicorns!');
+    $this->assertIdentical((string) $this->renderer->renderRoot($build), 'Llamas &gt; unicorns!');
 
-    // Enable the block view alter hook that adds a foo=bar attribute.
+    // Enable the block view alter hook that adds a suffix, for basic testing.
     \Drupal::state()->set('block_test_view_alter_suffix', TRUE);
     Cache::invalidateTags($this->block->getCacheTagsToInvalidate());
     $build = $this->getBlockRenderArray();
-    $this->setRawContent((string) $this->renderer->renderRoot($build));
-    $this->assertIdentical(trim((string) $this->cssSelect('[foo=bar]')[0]), 'Llamas > unicorns!');
+    $this->assertTrue(isset($build['#suffix']) && $build['#suffix'] === '<br>Goodbye!', 'A block with content is altered.');
+    $this->assertIdentical((string) $this->renderer->renderRoot($build), 'Llamas &gt; unicorns!<br>Goodbye!');
     \Drupal::state()->set('block_test_view_alter_suffix', FALSE);
 
+    // Force a request via GET so we can test the render cache.
+    $request = \Drupal::request();
+    $request_method = $request->server->get('REQUEST_METHOD');
+    $request->setMethod('GET');
+
     \Drupal::state()->set('block_test.content', NULL);
     Cache::invalidateTags($this->block->getCacheTagsToInvalidate());
 
+    $default_keys = array('entity_view', 'block', 'test_block');
+    $default_tags = array('block_view', 'config:block.block.test_block');
+
+    // Advanced: cached block, but an alter hook adds an additional cache key.
+    $alter_add_key = $this->randomMachineName();
+    \Drupal::state()->set('block_test_view_alter_cache_key', $alter_add_key);
+    $cid = 'entity_view:block:test_block:' . $alter_add_key . ':' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys(['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'])->getKeys());
+    $expected_keys = array_merge($default_keys, array($alter_add_key));
+    $build = $this->getBlockRenderArray();
+    $this->assertIdentical($expected_keys, $build['#cache']['keys'], 'An altered cacheable block has the expected cache keys.');
+    $this->assertIdentical((string) $this->renderer->renderRoot($build), '');
+    $cache_entry = $this->container->get('cache.render')->get($cid);
+    $this->assertTrue($cache_entry, 'The block render element has been cached with the expected cache ID.');
+    $expected_tags = array_merge($default_tags, ['rendered']);
+    sort($expected_tags);
+    $this->assertIdentical($cache_entry->tags, $expected_tags, 'The block render element has been cached with the expected cache tags.');
+    $this->container->get('cache.render')->delete($cid);
+
+    // Advanced: cached block, but an alter hook adds an additional cache tag.
+    $alter_add_tag = $this->randomMachineName();
+    \Drupal::state()->set('block_test_view_alter_cache_tag', $alter_add_tag);
+    $expected_tags = Cache::mergeTags($default_tags, array($alter_add_tag));
+    $build = $this->getBlockRenderArray();
+    sort($build['#cache']['tags']);
+    $this->assertIdentical($expected_tags, $build['#cache']['tags'], 'An altered cacheable block has the expected cache tags.');
+    $this->assertIdentical((string) $this->renderer->renderRoot($build), '');
+    $cache_entry = $this->container->get('cache.render')->get($cid);
+    $this->assertTrue($cache_entry, 'The block render element has been cached with the expected cache ID.');
+    $expected_tags = array_merge($default_tags, [$alter_add_tag, 'rendered']);
+    sort($expected_tags);
+    $this->assertIdentical($cache_entry->tags, $expected_tags, 'The block render element has been cached with the expected cache tags.');
+    $this->container->get('cache.render')->delete($cid);
+
     // Advanced: cached block, but an alter hook adds a #pre_render callback to
     // alter the eventual content.
     \Drupal::state()->set('block_test_view_alter_append_pre_render_prefix', TRUE);
@@ -214,122 +248,24 @@ public function testBlockViewBuilderViewAlter() {
     $this->assertFalse(isset($build['#prefix']), 'The appended #pre_render callback has not yet run before rendering.');
     $this->assertIdentical((string) $this->renderer->renderRoot($build), 'Hiya!<br>');
     $this->assertTrue(isset($build['#prefix']) && $build['#prefix'] === 'Hiya!<br>', 'A cached block without content is altered.');
-  }
-
-  /**
-   * Tests block build altering.
-   *
-   * @see hook_block_build_alter()
-   * @see hook_block_build_BASE_BLOCK_ID_alter()
-   */
-  public function testBlockViewBuilderBuildAlter() {
-    // Force a request via GET so we can test the render cache.
-    $request = \Drupal::request();
-    $request_method = $request->server->get('REQUEST_METHOD');
-    $request->setMethod('GET');
-
-    $default_keys = ['entity_view', 'block', 'test_block'];
-    $default_contexts = [];
-    $default_tags = ['block_view', 'config:block.block.test_block'];
-    $default_max_age = Cache::PERMANENT;
-
-    // hook_block_build_alter() adds an additional cache key.
-    $alter_add_key = $this->randomMachineName();
-    \Drupal::state()->set('block_test_block_alter_cache_key', $alter_add_key);
-    $this->assertBlockRenderedWithExpectedCacheability(array_merge($default_keys, [$alter_add_key]), $default_contexts, $default_tags, $default_max_age);
-    \Drupal::state()->set('block_test_block_alter_cache_key', NULL);
-
-    // hook_block_build_alter() adds an additional cache context.
-    $alter_add_context = 'url.query_args:' . $this->randomMachineName();
-    \Drupal::state()->set('block_test_block_alter_cache_context', $alter_add_context);
-    $this->assertBlockRenderedWithExpectedCacheability($default_keys, Cache::mergeContexts($default_contexts, [$alter_add_context]), $default_tags, $default_max_age);
-    \Drupal::state()->set('block_test_block_alter_cache_context', NULL);
-
-    // hook_block_build_alter() adds an additional cache tag.
-    $alter_add_tag = $this->randomMachineName();
-    \Drupal::state()->set('block_test_block_alter_cache_tag', $alter_add_tag);
-    $this->assertBlockRenderedWithExpectedCacheability($default_keys, $default_contexts, Cache::mergeTags($default_tags, [$alter_add_tag]), $default_max_age);
-    \Drupal::state()->set('block_test_block_alter_cache_tag', NULL);
-
-    // hook_block_build_alter() alters the max-age.
-    $alter_max_age = 300;
-    \Drupal::state()->set('block_test_block_alter_cache_max_age', $alter_max_age);
-    $this->assertBlockRenderedWithExpectedCacheability($default_keys, $default_contexts, $default_tags, $alter_max_age);
-    \Drupal::state()->set('block_test_block_alter_cache_max_age', NULL);
-
-    // hook_block_build_alter() alters cache keys, contexts, tags and max-age.
-    \Drupal::state()->set('block_test_block_alter_cache_key', $alter_add_key);
-    \Drupal::state()->set('block_test_block_alter_cache_context', $alter_add_context);
-    \Drupal::state()->set('block_test_block_alter_cache_tag', $alter_add_tag);
-    \Drupal::state()->set('block_test_block_alter_cache_max_age', $alter_max_age);
-    $this->assertBlockRenderedWithExpectedCacheability(array_merge($default_keys, [$alter_add_key]), Cache::mergeContexts($default_contexts, [$alter_add_context]), Cache::mergeTags($default_tags, [$alter_add_tag]), $alter_max_age);
-    \Drupal::state()->set('block_test_block_alter_cache_key', NULL);
-    \Drupal::state()->set('block_test_block_alter_cache_context', NULL);
-    \Drupal::state()->set('block_test_block_alter_cache_tag', NULL);
-    \Drupal::state()->set('block_test_block_alter_cache_max_age', NULL);
-
-    // hook_block_build_alter() sets #create_placeholder.
-    foreach ([TRUE, FALSE] as $value) {
-      \Drupal::state()->set('block_test_block_alter_create_placeholder', $value);
-      $build = $this->getBlockRenderArray();
-      $this->assertTrue(isset($build['#create_placeholder']));
-      $this->assertIdentical($value, $build['#create_placeholder']);
-    }
-    \Drupal::state()->set('block_test_block_alter_create_placeholder', NULL);
 
     // Restore the previous request method.
     $request->setMethod($request_method);
   }
 
   /**
-   * Asserts that a block is built/rendered/cached with expected cacheability.
-   *
-   * @param string[] $expected_keys
-   *   The expected cache keys.
-   * @param string[] $expected_contexts
-   *   The expected cache contexts.
-   * @param string[] $expected_tags
-   *   The expected cache tags.
-   * @param int $expected_max_age
-   *   The expected max-age.
-   */
-  protected function assertBlockRenderedWithExpectedCacheability(array $expected_keys, array $expected_contexts, array $expected_tags, $expected_max_age) {
-    $required_cache_contexts = ['languages:' . LanguageInterface::TYPE_INTERFACE, 'theme', 'user.permissions'];
-
-    // Check that the expected cacheability metadata is present in:
-    // - the built render array;
-    $this->pass('Built render array');
-    $build = $this->getBlockRenderArray();
-    $this->assertIdentical($expected_keys, $build['#cache']['keys']);
-    $this->assertIdentical($expected_contexts, $build['#cache']['contexts']);
-    $this->assertIdentical($expected_tags, $build['#cache']['tags']);
-    $this->assertIdentical($expected_max_age, $build['#cache']['max-age']);
-    $this->assertFalse(isset($build['#create_placeholder']));
-    // - the rendered render array;
-    $this->pass('Rendered render array');
-    $this->renderer->renderRoot($build);
-    // - the render cache item.
-    $this->pass('Render cache item');
-    $final_cache_contexts = Cache::mergeContexts($expected_contexts, $required_cache_contexts);
-    $cid = implode(':', $expected_keys) . ':' . implode(':', \Drupal::service('cache_contexts_manager')->convertTokensToKeys($final_cache_contexts)->getKeys());
-    $cache_item = $this->container->get('cache.render')->get($cid);
-    $this->assertTrue($cache_item, 'The block render element has been cached with the expected cache ID.');
-    $this->assertIdentical(Cache::mergeTags($expected_tags, ['rendered']), $cache_item->tags);
-    $this->assertIdentical($final_cache_contexts, $cache_item->data['#cache']['contexts']);
-    $this->assertIdentical($expected_tags, $cache_item->data['#cache']['tags']);
-    $this->assertIdentical($expected_max_age, $cache_item->data['#cache']['max-age']);
-
-    $this->container->get('cache.render')->delete($cid);
-  }
-
-  /**
    * Get a fully built render array for a block.
    *
    * @return array
    *   The render array.
    */
   protected function getBlockRenderArray() {
-    return $this->container->get('entity.manager')->getViewBuilder('block')->view($this->block, 'block');
+    $build = $this->container->get('entity.manager')->getViewBuilder('block')->view($this->block, 'block');
+
+    // Mock the build array to not require the theme registry.
+    unset($build['#theme']);
+
+    return $build;
   }
 
 }
diff --git a/core/modules/block/src/Tests/Update/BlockContextMappingUpdateTest.php b/core/modules/block/src/Tests/Update/BlockContextMappingUpdateTest.php
index 5116084..4aa0ac0 100644
--- a/core/modules/block/src/Tests/Update/BlockContextMappingUpdateTest.php
+++ b/core/modules/block/src/Tests/Update/BlockContextMappingUpdateTest.php
@@ -32,8 +32,6 @@ protected function setDatabaseDumpFiles() {
     $this->databaseDumpFiles = [
       __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.bare.standard.php.gz',
       __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.block-context-manager-2354889.php',
-      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.language-enabled.php',
-      __DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.block-test-enabled.php',
     ];
   }
 
@@ -96,7 +94,7 @@ public function testUpdateHookN() {
     $disabled_block = Block::load('thirdtestfor2354889');
     $this->assertFalse($disabled_block->status(), 'Block with invalid context is disabled');
 
-    $this->assertEqual(['thirdtestfor2354889' => ['missing_context_ids' => ['baloney_spam' => ['node_type']], 'status' => TRUE]], \Drupal::keyValue('update_backup')->get('block_update_8001'));
+    $this->assertEqual(['thirdtestfor2354889' => ['missing_context_ids' => ['baloney.spam' => ['node_type']], 'status' => TRUE]], \Drupal::keyValue('update_backup')->get('block_update_8001'));
 
     $disabled_block_visibility = $disabled_block->get('visibility');
     $this->assertTrue(!isset($disabled_block_visibility['node_type']), 'The problematic visibility condition has been removed.');
diff --git a/core/modules/block/tests/modules/block_test/block_test.module b/core/modules/block/tests/modules/block_test/block_test.module
index 74ea34c..cec0b24 100644
--- a/core/modules/block/tests/modules/block_test/block_test.module
+++ b/core/modules/block/tests/modules/block_test/block_test.module
@@ -22,34 +22,16 @@ function block_test_block_alter(&$block_info) {
  */
 function block_test_block_view_test_cache_alter(array &$build, BlockPluginInterface $block) {
   if (\Drupal::state()->get('block_test_view_alter_suffix') !== NULL) {
-    $build['#attributes']['foo'] = 'bar';
+    $build['#suffix'] = '<br>Goodbye!';
   }
-  if (\Drupal::state()->get('block_test_view_alter_append_pre_render_prefix') !== NULL) {
-    $build['#pre_render'][] = 'block_test_pre_render_alter_content';
-  }
-}
-
-/**
- * Implements hook_block_build_BASE_BLOCK_ID_alter().
- */
-function block_test_block_build_test_cache_alter(array &$build, BlockPluginInterface $block) {
-  // Test altering cache keys, contexts, tags and max-age.
-  if (\Drupal::state()->get('block_test_block_alter_cache_key') !== NULL) {
-    $build['#cache']['keys'][] = \Drupal::state()->get('block_test_block_alter_cache_key');
-  }
-  if (\Drupal::state()->get('block_test_block_alter_cache_context') !== NULL) {
-    $build['#cache']['contexts'][] = \Drupal::state()->get('block_test_block_alter_cache_context');
-  }
-  if (\Drupal::state()->get('block_test_block_alter_cache_tag') !== NULL) {
-    $build['#cache']['tags'] = Cache::mergeTags($build['#cache']['tags'], [\Drupal::state()->get('block_test_block_alter_cache_tag')]);
+  if (\Drupal::state()->get('block_test_view_alter_cache_key') !== NULL) {
+    $build['#cache']['keys'][] = \Drupal::state()->get('block_test_view_alter_cache_key');
   }
-  if (\Drupal::state()->get('block_test_block_alter_cache_max_age') !== NULL) {
-    $build['#cache']['max-age'] = \Drupal::state()->get('block_test_block_alter_cache_max_age');
+  if (\Drupal::state()->get('block_test_view_alter_cache_tag') !== NULL) {
+    $build['#cache']['tags'][] = \Drupal::state()->get('block_test_view_alter_cache_tag');
   }
-
-  // Test setting #create_placeholder.
-  if (\Drupal::state()->get('block_test_block_alter_create_placeholder') !== NULL) {
-    $build['#create_placeholder'] = \Drupal::state()->get('block_test_block_alter_create_placeholder');
+  if (\Drupal::state()->get('block_test_view_alter_append_pre_render_prefix') !== NULL) {
+    $build['#pre_render'][] = 'block_test_pre_render_alter_content';
   }
 }
 
diff --git a/core/modules/block/tests/modules/block_test/config/schema/block_test.schema.yml b/core/modules/block/tests/modules/block_test/config/schema/block_test.schema.yml
index 166ce8d..e0b13cb 100644
--- a/core/modules/block/tests/modules/block_test/config/schema/block_test.schema.yml
+++ b/core/modules/block/tests/modules/block_test/config/schema/block_test.schema.yml
@@ -5,6 +5,3 @@ block.settings.test_block_instantiation:
     display_message:
       type: string
       label: 'Message text'
-
-condition.plugin.baloney_spam:
-  type: condition.plugin
diff --git a/core/modules/block/tests/modules/block_test/src/Plugin/Condition/BaloneySpam.php b/core/modules/block/tests/modules/block_test/src/Plugin/Condition/BaloneySpam.php
index 6aebcbf..55e12ab 100644
--- a/core/modules/block/tests/modules/block_test/src/Plugin/Condition/BaloneySpam.php
+++ b/core/modules/block/tests/modules/block_test/src/Plugin/Condition/BaloneySpam.php
@@ -10,10 +10,10 @@
 use Drupal\Core\Condition\ConditionPluginBase;
 
 /**
- * Provides a 'baloney_spam' condition.
+ * Provides a 'baloney.spam' condition.
  *
  * @Condition(
- *   id = "baloney_spam",
+ *   id = "baloney.spam",
  *   label = @Translation("Baloney spam"),
  * )
  *
diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc
index 500533e..5b11466 100644
--- a/core/modules/comment/comment.tokens.inc
+++ b/core/modules/comment/comment.tokens.inc
@@ -6,7 +6,6 @@
  */
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
 use Drupal\Core\Datetime\Entity\DateFormat;
 use Drupal\Core\Render\BubbleableMetadata;
@@ -150,7 +149,7 @@ function comment_tokens($type, $tokens, array $data, array $options, BubbleableM
           break;
 
         case 'homepage':
-          $replacements[$original] = $sanitize ? UrlHelper::filterBadProtocol($comment->getHomepage()) : $comment->getHomepage();
+          $replacements[$original] = $sanitize ? check_url($comment->getHomepage()) : $comment->getHomepage();
           break;
 
         case 'title':
diff --git a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php b/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
index 0bc6be6..0267346 100644
--- a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
+++ b/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
@@ -8,7 +8,6 @@
 namespace Drupal\comment\Tests;
 
 use Drupal\Component\Utility\Html;
-use Drupal\Component\Utility\UrlHelper;
 use Drupal\Component\Utility\Xss;
 use Drupal\comment\Entity\Comment;
 use Drupal\Core\Render\BubbleableMetadata;
@@ -56,7 +55,7 @@ function testCommentTokenReplacement() {
     $tests['[comment:hostname]'] = Html::escape($comment->getHostname());
     $tests['[comment:author]'] = Xss::filter($comment->getAuthorName());
     $tests['[comment:mail]'] = Html::escape($this->adminUser->getEmail());
-    $tests['[comment:homepage]'] = UrlHelper::filterBadProtocol($comment->getHomepage());
+    $tests['[comment:homepage]'] = check_url($comment->getHomepage());
     $tests['[comment:title]'] = Xss::filter($comment->getSubject());
     $tests['[comment:body]'] = $comment->comment_body->processed;
     $tests['[comment:langcode]'] = Html::escape($comment->language()->getId());
diff --git a/core/modules/config/src/Tests/ConfigImportUITest.php b/core/modules/config/src/Tests/ConfigImportUITest.php
index 8c2e5bf..dd00edf 100644
--- a/core/modules/config/src/Tests/ConfigImportUITest.php
+++ b/core/modules/config/src/Tests/ConfigImportUITest.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\config\Tests;
 
-use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\InstallStorage;
 use Drupal\simpletest\WebTestBase;
@@ -276,41 +275,23 @@ function testImportDiff() {
     $change_key = 'foo';
     $remove_key = '404';
     $add_key = 'biff';
-    $add_data = '<em>bangpow</em>';
-    $change_data = '<p><em>foobar</em></p>';
+    $add_data = 'bangpow';
+    $change_data = 'foobar';
     $original_data = array(
-      'foo' => '<p>foobar</p>',
-      'baz' => '<strong>no change</strong>',
-      '404' => '<em>herp</em>',
+      'foo' => 'bar',
+      '404' => 'herp',
     );
-    // Update active storage to have html in config data.
-    $this->config($config_name)->setData($original_data)->save();
 
     // Change a configuration value in staging.
     $staging_data = $original_data;
     $staging_data[$change_key] = $change_data;
     $staging_data[$add_key] = $add_data;
-    unset($staging_data[$remove_key]);
     $staging->write($config_name, $staging_data);
 
     // Load the diff UI and verify that the diff reflects the change.
     $this->drupalGet('admin/config/development/configuration/sync/diff/' . $config_name);
     $this->assertTitle(format_string('View changes of @config_name | Drupal', array('@config_name' => $config_name)));
 
-    // The following assertions do not use $this::assertEscaped() because
-    // \Drupal\Component\Diff\DiffFormatter adds markup that signifies what has
-    // changed.
-
-    // Changed values are escaped.
-    $this->assertText(Html::escape("foo: '<p><em>foobar</em></p>'"));
-    $this->assertText(Html::escape("foo: '<p>foobar</p>'"));
-    // The no change values are escaped.
-    $this->assertText(Html::escape("baz: '<strong>no change</strong>'"));
-    // Added value is escaped.
-    $this->assertText(Html::escape("biff: '<em>bangpow</em>'"));
-    // Deleted value is escaped.
-    $this->assertText(Html::escape("404: '<em>herp</em>'"));
-
     // Reset data back to original, and remove a key
     $staging_data = $original_data;
     unset($staging_data[$remove_key]);
@@ -318,11 +299,6 @@ function testImportDiff() {
 
     // Load the diff UI and verify that the diff reflects a removed key.
     $this->drupalGet('admin/config/development/configuration/sync/diff/' . $config_name);
-    // The no change values are escaped.
-    $this->assertText(Html::escape("foo: '<p>foobar</p>'"));
-    $this->assertText(Html::escape("baz: '<strong>no change</strong>'"));
-    // Removed key is escaped.
-    $this->assertText(Html::escape("404: '<em>herp</em>'"));
 
     // Reset data back to original and add a key
     $staging_data = $original_data;
@@ -331,11 +307,6 @@ function testImportDiff() {
 
     // Load the diff UI and verify that the diff reflects an added key.
     $this->drupalGet('admin/config/development/configuration/sync/diff/' . $config_name);
-    // The no change values are escaped.
-    $this->assertText(Html::escape("baz: '<strong>no change</strong>'"));
-    $this->assertText(Html::escape("404: '<em>herp</em>'"));
-    // Added key is escaped.
-    $this->assertText(Html::escape("biff: '<em>bangpow</em>'"));
   }
 
   /**
diff --git a/core/modules/contact/src/MessageViewBuilder.php b/core/modules/contact/src/MessageViewBuilder.php
index def70f9..24f58f5 100644
--- a/core/modules/contact/src/MessageViewBuilder.php
+++ b/core/modules/contact/src/MessageViewBuilder.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Mail\MailFormatHelper;
 use Drupal\Core\Render\Element;
 
@@ -41,7 +42,7 @@ public function buildComponents(array &$build, array $entities, array $displays,
         $build[$id]['message'] = array(
           '#type' => 'item',
           '#title' => t('Message'),
-          '#plain_text' => $entity->getMessage(),
+          '#markup' => SafeMarkup::checkPlain($entity->getMessage()),
         );
       }
     }
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index cea6b2e..5623f75 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -5,6 +5,7 @@
  * The content translation administration forms.
  */
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Config\Entity\ThirdPartySettingsInterface;
 use Drupal\Core\Entity\ContentEntityTypeInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
@@ -215,10 +216,10 @@ function _content_translation_preprocess_language_content_settings_table(&$varia
               'bundle' => array(
                 '#prefix' => '<span class="visually-hidden">',
                 '#suffix' => '</span> ',
-                '#plain_text' => $element[$bundle]['settings']['#label'],
+                '#markup' => SafeMarkup::checkPlain($element[$bundle]['settings']['#label']),
               ),
               'field' => array(
-                '#plain_text' => $field_element['#label'],
+                '#markup' => SafeMarkup::checkPlain($field_element['#label']),
               ),
             ),
             'class' => array('field'),
@@ -249,15 +250,15 @@ function _content_translation_preprocess_language_content_settings_table(&$varia
                   'bundle' => array(
                     '#prefix' => '<span class="visually-hidden">',
                     '#suffix' => '</span> ',
-                    '#plain_text' => $element[$bundle]['settings']['#label'],
+                    '#markup' => SafeMarkup::checkPlain($element[$bundle]['settings']['#label']),
                   ),
                   'field' => array(
                     '#prefix' => '<span class="visually-hidden">',
                     '#suffix' => '</span> ',
-                    '#plain_text' => $field_element['#label'],
+                    '#markup' => SafeMarkup::checkPlain($field_element['#label']),
                   ),
                   'columns' => array(
-                    '#plain_text' => $column_label,
+                    '#markup' => SafeMarkup::checkPlain($column_label),
                   ),
                 ),
                 'class' => array('column'),
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 8449c9d..da02771 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -267,8 +267,7 @@ function content_translation_menu_links_discovered_alter(array &$links) {
  */
 function content_translation_translate_access(EntityInterface $entity) {
   $account = \Drupal::currentUser();
-  $condition = $entity instanceof ContentEntityInterface && $entity->access('view') &&
-    !$entity->getUntranslated()->language()->isLocked() && \Drupal::languageManager()->isMultilingual() && $entity->isTranslatable() &&
+  $condition = $entity instanceof ContentEntityInterface && !$entity->getUntranslated()->language()->isLocked() && \Drupal::languageManager()->isMultilingual() && $entity->isTranslatable() &&
     ($account->hasPermission('create content translations') || $account->hasPermission('update content translations') || $account->hasPermission('delete content translations'));
   return AccessResult::allowedIf($condition)->cachePerPermissions()->cacheUntilEntityChanges($entity);
 }
diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php
index 3979fff..10cf5f3 100644
--- a/core/modules/content_translation/src/ContentTranslationHandler.php
+++ b/core/modules/content_translation/src/ContentTranslationHandler.php
@@ -290,8 +290,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En
       $title = $this->entityFormTitle($entity);
       // When editing the original values display just the entity label.
       if ($form_langcode != $entity_langcode) {
-        $t_args = array('%language' => $languages[$form_langcode]->getName(), '%title' => $entity->label(), '@title' => $title);
-        $title = empty($source_langcode) ? t('@title [%language translation]', $t_args) : t('Create %language translation of %title', $t_args);
+        $t_args = array('%language' => $languages[$form_langcode]->getName(), '%title' => $entity->label(), '!title' => $title);
+        $title = empty($source_langcode) ? t('!title [%language translation]', $t_args) : t('Create %language translation of %title', $t_args);
       }
       $form['#title'] = $title;
     }
diff --git a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
index 91d4314..1aa35b9 100644
--- a/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/src/Routing/ContentTranslationRouteSubscriber.php
@@ -69,7 +69,6 @@ protected function alterRoutes(RouteCollection $collection) {
           'entity_type_id' => $entity_type_id,
         ),
         array(
-          '_entity_access' =>  $entity_type_id . '.view',
           '_access_content_translation_overview' => $entity_type_id,
         ),
         array(
@@ -95,7 +94,6 @@ protected function alterRoutes(RouteCollection $collection) {
 
         ),
         array(
-          '_entity_access' =>  $entity_type_id . '.view',
           '_access_content_translation_manage' => 'create',
         ),
         array(
diff --git a/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php b/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
index 3569a45..bb7597c 100644
--- a/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
+++ b/core/modules/content_translation/src/Tests/ContentTestTranslationUITest.php
@@ -39,7 +39,7 @@ protected function setUp() {
    * Overrides \Drupal\content_translation\Tests\ContentTranslationUITestBase::getTranslatorPermission().
    */
   protected function getTranslatorPermissions() {
-    return array_merge(parent::getTranslatorPermissions(), array('administer entity_test content', 'view test entity'));
+    return array_merge(parent::getTranslatorPermissions(), array('administer entity_test content'));
   }
 
 }
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
index f987494..8d0c063 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationOperationsTest.php
@@ -9,7 +9,6 @@
 
 use Drupal\language\Entity\ConfigurableLanguage;
 use Drupal\node\Tests\NodeTestBase;
-use Drupal\user\Entity\Role;
 
 /**
  * Tests the content translation operations available in the content listing.
@@ -76,63 +75,6 @@ function testOperationTranslateLink() {
     $this->drupalLogin($this->baseUser2);
     $this->drupalGet('admin/content');
     $this->assertLinkByHref('node/' . $node->id() . '/translations');
-
-    // Ensure that an unintended misconfiguration of permissions does not open
-    // access to the translation form, see https://www.drupal.org/node/2558905.
-    $this->drupalLogout();
-    user_role_change_permissions(
-      Role::AUTHENTICATED_ID,
-      [
-        'create content translations' => TRUE,
-        'access content' => FALSE,
-      ]
-    );
-    $this->drupalLogin($this->baseUser1);
-    $this->drupalGet($node->urlInfo('drupal:content-translation-overview'));
-    $this->assertResponse(403);
-
-    // Ensure that the translation overview is also not accessible when the user
-    // has 'access content', but the node is not published.
-    user_role_change_permissions(
-      Role::AUTHENTICATED_ID,
-      [
-        'create content translations' => TRUE,
-        'access content' => TRUE,
-      ]
-    );
-    $node->setPublished(FALSE)->save();
-    $this->drupalGet($node->urlInfo('drupal:content-translation-overview'));
-    $this->assertResponse(403);
-  }
-
-  /**
-   * @see content_translation_translate_access()
-   */
-  public function testContentTranslationOverviewAccess() {
-    $access_control_handler = \Drupal::entityManager()->getAccessControlHandler('node');
-    $user = $this->createUser(['create content translations', 'access content']);
-    $this->drupalLogin($user);
-
-    $node = $this->drupalCreateNode(['status' => FALSE, 'type' => 'article']);
-    $this->assertFalse(content_translation_translate_access($node)->isAllowed());
-    $access_control_handler->resetCache();
-
-    $node->setPublished(TRUE);
-    $node->save();
-    $this->assertTrue(content_translation_translate_access($node)->isAllowed());
-    $access_control_handler->resetCache();
-
-    user_role_change_permissions(
-      Role::AUTHENTICATED_ID,
-      [
-        'access content' => FALSE,
-      ]
-    );
-
-    $user = $this->createUser(['create content translations']);
-    $this->drupalLogin($user);
-    $this->assertFalse(content_translation_translate_access($node)->isAllowed());
-    $access_control_handler->resetCache();
   }
 
 }
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
index b602be0..223bb81 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationWorkflowsTest.php
@@ -39,16 +39,6 @@ protected function setUp() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  protected function getTranslatorPermissions() {
-    $permissions = parent::getTranslatorPermissions();
-    $permissions[] = 'view test entity';
-
-    return $permissions;
-  }
-
-  /**
    * Overrides \Drupal\content_translation\Tests\ContentTranslationTestBase::getEditorPermissions().
    */
   protected function getEditorPermissions() {
@@ -119,7 +109,7 @@ function testWorkflows() {
     $ops = array('create' => t('Add'), 'update' => t('Edit'), 'delete' => t('Delete'));
     $translations_url = $this->entity->urlInfo('drupal:content-translation-overview');
     foreach ($ops as $current_op => $item) {
-      $user = $this->drupalCreateUser(array($this->getTranslatePermission(), "$current_op content translations", 'view test entity'));
+      $user = $this->drupalCreateUser(array($this->getTranslatePermission(), "$current_op content translations"));
       $this->drupalLogin($user);
       $this->drupalGet($translations_url);
 
diff --git a/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php b/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
index bb349e2..485f6f5 100644
--- a/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
+++ b/core/modules/content_translation/src/Tests/Views/TranslationLinkTest.php
@@ -55,15 +55,6 @@ protected function setUp() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  protected function getTranslatorPermissions() {
-    $permissions = parent::getTranslatorPermissions();
-    $permissions[] = 'access user profiles';
-    return $permissions;
-  }
-
-  /**
    * Tests the content translation overview link field handler.
    */
   public function testTranslationLink() {
diff --git a/core/modules/contextual/src/ContextualController.php b/core/modules/contextual/src/ContextualController.php
index 975113d..ca248d1 100644
--- a/core/modules/contextual/src/ContextualController.php
+++ b/core/modules/contextual/src/ContextualController.php
@@ -44,7 +44,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] = (string) $this->container->get('renderer')->renderRoot($element);
     }
 
     return new JsonResponse($rendered);
diff --git a/core/modules/editor/js/editor.formattedTextEditor.js b/core/modules/editor/js/editor.formattedTextEditor.js
index 0c0419f..98d79ba 100644
--- a/core/modules/editor/js/editor.formattedTextEditor.js
+++ b/core/modules/editor/js/editor.formattedTextEditor.js
@@ -63,13 +63,7 @@
 
       // Store the actual value of this field. We'll need this to restore the
       // original value when the user discards his modifications.
-      var $fieldItems = this.$el.find('.field__item');
-      if ($fieldItems.length) {
-        this.$textElement = $fieldItems.eq(0);
-      }
-      else {
-        this.$textElement = this.$el;
-      }
+      this.$textElement = this.$el.find('.field__item').eq(0);
       this.model.set('originalValue', this.$textElement.html());
     },
 
diff --git a/core/modules/editor/src/EditorController.php b/core/modules/editor/src/EditorController.php
index 44feda3..192f341 100644
--- a/core/modules/editor/src/EditorController.php
+++ b/core/modules/editor/src/EditorController.php
@@ -48,7 +48,7 @@ public function getUntransformedText(EntityInterface $entity, $field_name, $lang
     // Direct text editing is only supported for single-valued fields.
     $field = $entity->getTranslation($langcode)->$field_name;
     $editable_text = check_markup($field->value, $field->format, $langcode, array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE));
-    $response->addCommand(new GetUntransformedTextCommand($editable_text));
+    $response->addCommand(new GetUntransformedTextCommand((string) $editable_text));
 
     return $response;
   }
diff --git a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php
index 6bdbd26..c897764 100644
--- a/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php
+++ b/core/modules/field/src/Tests/EntityReference/EntityReferenceFormatterTest.php
@@ -174,7 +174,7 @@ public function testIdFormatter() {
     $formatter = 'entity_reference_entity_id';
     $build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter);
 
-    $this->assertEqual($build[0]['#plain_text'], $this->referencedEntity->id(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
+    $this->assertEqual($build[0]['#markup'], $this->referencedEntity->id(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
     $this->assertEqual($build[0]['#cache']['tags'], $this->referencedEntity->getCacheTags(), sprintf('The %s formatter has the expected cache tags.', $formatter));
     $this->assertTrue(!isset($build[1]), sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
   }
@@ -244,7 +244,7 @@ public function testLabelFormatter() {
     // The second referenced entity is "autocreated", therefore not saved and
     // lacking any URL info.
     $expected_item_2 = array(
-      '#plain_text' => $this->unsavedReferencedEntity->label(),
+      '#markup' => $this->unsavedReferencedEntity->label(),
       '#cache' => array(
         'contexts' => [
           'user.permissions',
@@ -257,8 +257,8 @@ public function testLabelFormatter() {
 
     // Test with the 'link' setting set to FALSE.
     $build = $this->buildRenderArray([$this->referencedEntity, $this->unsavedReferencedEntity], $formatter, array('link' => FALSE));
-    $this->assertEqual($build[0]['#plain_text'], $this->referencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
-    $this->assertEqual($build[1]['#plain_text'], $this->unsavedReferencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
+    $this->assertEqual($build[0]['#markup'], $this->referencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a saved entity.', $formatter));
+    $this->assertEqual($build[1]['#markup'], $this->unsavedReferencedEntity->label(), sprintf('The markup returned by the %s formatter is correct for an item with a unsaved entity.', $formatter));
 
     // Test an entity type that doesn't have any link templates, which means
     // \Drupal\Core\Entity\EntityInterface::urlInfo() will throw an exception
@@ -273,7 +273,7 @@ public function testLabelFormatter() {
     $referenced_entity_with_no_link_template->save();
 
     $build = $this->buildRenderArray([$referenced_entity_with_no_link_template], $formatter, array('link' => TRUE));
-    $this->assertEqual($build[0]['#plain_text'], $referenced_entity_with_no_link_template->label(), sprintf('The markup returned by the %s formatter is correct for an entity type with no valid link template.', $formatter));
+    $this->assertEqual($build[0]['#markup'], $referenced_entity_with_no_link_template->label(), sprintf('The markup returned by the %s formatter is correct for an entity type with no valid link template.', $formatter));
   }
 
   /**
diff --git a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
index e807073..b2275d0 100644
--- a/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
+++ b/core/modules/field_ui/src/Form/EntityDisplayFormBase.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Plugin\Factory\DefaultFactory;
 use Drupal\Component\Plugin\PluginManagerBase;
 use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
@@ -289,7 +290,7 @@ protected function buildFieldRow(FieldDefinitionInterface $field_definition, arr
         'defaultPlugin' => $this->getDefaultPlugin($field_definition->getType()),
       ),
       'human_name' => array(
-        '#plain_text' => $label,
+        '#markup' => SafeMarkup::checkPlain($label),
       ),
       'weight' => array(
         '#type' => 'textfield',
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index 8552da0..a80a4bd 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -143,7 +143,6 @@ function template_preprocess_file_widget_multiple(&$variables) {
         'group' => $weight_class,
       ),
     ),
-    '#access' => !empty($rows),
   );
 
   $variables['element'] = $element;
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 45376dd..888c29e 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -629,7 +629,7 @@ function file_file_download($uri) {
 }
 
 /**
- * Implements hook_cron().
+ * Implements file_cron()
  */
 function file_cron() {
   $age = \Drupal::config('system.file')->get('temporary_maximum_age');
diff --git a/core/modules/file/src/Tests/FileFieldWidgetTest.php b/core/modules/file/src/Tests/FileFieldWidgetTest.php
index e2f4aa2..7c24aab 100644
--- a/core/modules/file/src/Tests/FileFieldWidgetTest.php
+++ b/core/modules/file/src/Tests/FileFieldWidgetTest.php
@@ -9,9 +9,7 @@
 
 use Drupal\comment\Entity\Comment;
 use Drupal\comment\Tests\CommentTestTrait;
-use Drupal\Component\Utility\Unicode;
 use Drupal\field\Entity\FieldConfig;
-use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\field_ui\Tests\FieldUiTestTrait;
 use Drupal\user\RoleInterface;
 use Drupal\file\Entity\File;
@@ -421,32 +419,4 @@ function testWidgetValidation() {
       $this->assertNoRaw($error_message, t('Validation error removed when file with correct extension uploaded (JSMode=%type).', array('%type' => $type)));
     }
   }
-
-  /**
-   * Tests file widget element.
-   */
-  public function testWidgetElement() {
-    $field_name = Unicode::strtolower($this->randomMachineName());
-    $html_name = str_replace('_', '-', $field_name);
-    $this->createFileField($field_name, 'node', 'article', ['cardinality' => FieldStorageConfig::CARDINALITY_UNLIMITED]);
-    $file = $this->getTestFile('text');
-    $xpath = "//details[@data-drupal-selector='edit-$html_name']/div[@class='details-wrapper']/table";
-
-    $this->drupalGet('node/add/article');
-
-    $elements = $this->xpath($xpath);
-
-    // If the field has no item, the table should not be visible.
-    $this->assertIdentical(count($elements), 0);
-
-    // Upload a file.
-    $edit['files[' . $field_name . '_0][]'] = $this->container->get('file_system')->realpath($file->getFileUri());
-    $this->drupalPostAjaxForm(NULL, $edit, "{$field_name}_0_upload_button");
-
-    $elements = $this->xpath($xpath);
-
-    // If the field has at least a item, the table should be visible.
-    $this->assertIdentical(count($elements), 1);
-  }
-
 }
diff --git a/core/modules/file/src/Tests/FileManagedFileElementTest.php b/core/modules/file/src/Tests/FileManagedFileElementTest.php
index 9953217..c91c494 100644
--- a/core/modules/file/src/Tests/FileManagedFileElementTest.php
+++ b/core/modules/file/src/Tests/FileManagedFileElementTest.php
@@ -37,18 +37,6 @@ function testManagedFile() {
           $this->drupalPostForm($path, array(), t('Save'));
           $this->assertRaw(t('The file ids are %fids.', array('%fids' => implode(',', array()))), 'Submitted without a file.');
 
-          // Submit with a file, but with an invalid form token. Ensure the file
-          // was not saved.
-          $last_fid_prior = $this->getLastFileId();
-          $edit = [
-            $file_field_name => drupal_realpath($test_file->getFileUri()),
-            'form_token' => 'invalid token',
-          ];
-          $this->drupalPostForm($path, $edit, t('Save'));
-          $this->assertText('The form has become outdated. Copy any unsaved work in the form below');
-          $last_fid = $this->getLastFileId();
-          $this->assertEqual($last_fid_prior, $last_fid, 'File was not saved when uploaded with an invalid form token.');
-
           // Submit a new file, without using the Upload button.
           $last_fid_prior = $this->getLastFileId();
           $edit = array($file_field_name => drupal_realpath($test_file->getFileUri()));
diff --git a/core/modules/filter/filter.admin.js b/core/modules/filter/filter.admin.js
index 3af5624..e14634c 100644
--- a/core/modules/filter/filter.admin.js
+++ b/core/modules/filter/filter.admin.js
@@ -8,12 +8,8 @@
   "use strict";
 
   /**
-   * Displays and updates the status of filters on the admin page.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behaviors to the filter admin view.
    */
   Drupal.behaviors.filterStatus = {
     attach: function (context, settings) {
@@ -26,8 +22,8 @@
         var $filterSettings = $context.find('#' + $checkbox.attr('id').replace(/-status$/, '-settings'));
         var filterSettingsTab = $filterSettings.data('verticalTab');
 
-        // Bind click handler to this checkbox to conditionally show and hide
-        // the filter's tableDrag row and vertical tab pane.
+        // Bind click handler to this checkbox to conditionally show and hide the
+        // filter's tableDrag row and vertical tab pane.
         $checkbox.on('click.filterUpdate', function () {
           if ($checkbox.is(':checked')) {
             $row.show();
diff --git a/core/modules/filter/filter.filter_html.admin.js b/core/modules/filter/filter.filter_html.admin.js
index 75a9824..1a20cfa 100644
--- a/core/modules/filter/filter.filter_html.admin.js
+++ b/core/modules/filter/filter.filter_html.admin.js
@@ -19,7 +19,6 @@
 
       /**
        * @return {Array}
-       *   An array of filter rules.
        */
       getRules: function () {
         var currentValue = $('#edit-filters-filter-html-settings-allowed-html').val();
@@ -46,14 +45,10 @@
   }
 
   /**
-   * Displays and updates what HTML tags are allowed to use in a filter.
    *
    * @type {Drupal~behavior}
    *
    * @todo Remove everything but 'attach' and 'detach' and make a proper object.
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior for updating allowed HTML tags.
    */
   Drupal.behaviors.filterFilterHtmlUpdating = {
 
diff --git a/core/modules/filter/filter.js b/core/modules/filter/filter.js
index cdb0795..58b595f 100644
--- a/core/modules/filter/filter.js
+++ b/core/modules/filter/filter.js
@@ -11,9 +11,6 @@
    * Displays the guidelines of the selected text format automatically.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior for updating filter guidelines.
    */
   Drupal.behaviors.filterGuidelines = {
     attach: function (context) {
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 217dbc8..1b29288 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -495,12 +495,11 @@ function _filter_url($text, $filter) {
   $tasks = array();
 
   // Prepare protocols pattern for absolute URLs.
-  // \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() will replace
-  // any bad protocols with HTTP, so we need to support the identical list.
-  // While '//' is technically optional for MAILTO only, we cannot cleanly
-  // differ between protocols here without hard-coding MAILTO, so '//' is
-  // optional for all protocols.
-  // @see \Drupal\Component\Utility\UrlHelper::stripDangerousProtocols()
+  // check_url() will replace any bad protocols with HTTP, so we need to support
+  // the identical list. While '//' is technically optional for MAILTO only,
+  // we cannot cleanly differ between protocols here without hard-coding MAILTO,
+  // so '//' is optional for all protocols.
+  // @see \Drupal\Component\Utility\UrlHelper::filterBadProtocol()
   $protocols = \Drupal::getContainer()->getParameter('filter_protocols');
   $protocols = implode(':(?://)?|', $protocols) . ':(?://)?';
 
diff --git a/core/modules/image/src/Form/ImageStyleEditForm.php b/core/modules/image/src/Form/ImageStyleEditForm.php
index d17a129..b07090b 100644
--- a/core/modules/image/src/Form/ImageStyleEditForm.php
+++ b/core/modules/image/src/Form/ImageStyleEditForm.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Url;
 use Drupal\image\ConfigurableImageEffectInterface;
 use Drupal\image\ImageEffectManager;
+use Drupal\Component\Utility\SafeMarkup;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -98,7 +99,7 @@ public function form(array $form, FormStateInterface $form_state) {
         '#tree' => FALSE,
         'data' => array(
           'label' => array(
-            '#plain_text' => $effect->label(),
+            '#markup' => SafeMarkup::checkPlain($effect->label()),
           ),
         ),
       );
diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 3f860de..8c35c6b 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -5,6 +5,7 @@
  * Administration functions for language.module.
  */
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Template\Attribute;
 use Drupal\Core\Url;
@@ -169,7 +170,7 @@ function template_preprocess_language_content_settings_table(&$variables) {
           'data' => array(
             '#prefix' => '<label>',
             '#suffix' => '</label>',
-            '#plain_text' => $element[$bundle]['settings']['#label'],
+            '#markup' => SafeMarkup::checkPlain($element[$bundle]['settings']['#label']),
           ),
           'class' => array('bundle'),
         ),
diff --git a/core/modules/language/migration_templates/d7_language_negotiation_settings.yml b/core/modules/language/migration_templates/d7_language_negotiation_settings.yml
deleted file mode 100644
index aace5fd..0000000
--- a/core/modules/language/migration_templates/d7_language_negotiation_settings.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-id: d7_language_negotiation_settings
-label: Drupal 7 language negotiation settings
-migration_tags:
-  - Drupal 7
-source:
-  plugin: variable
-  variables:
-    - locale_language_negotiation_session_param
-    - locale_language_negotiation_url_part
-process:
-  'session/parameter': locale_language_negotiation_session_param
-  'url/source': locale_language_negotiation_url_part
-destination:
-  plugin: config
-  config_name: language.negotiation
diff --git a/core/modules/language/src/Tests/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php b/core/modules/language/src/Tests/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php
deleted file mode 100644
index 242d818..0000000
--- a/core/modules/language/src/Tests/Migrate/d7/MigrateLanguageNegotiationSettingsTest.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\language\Tests\Migrate\d7\MigrateLanguageNegotiationSettingsTest.
- */
-
-namespace Drupal\language\Tests\Migrate\d7;
-
-use Drupal\migrate_drupal\Tests\d7\MigrateDrupal7TestBase;
-
-/**
- * Tests migration of language negotiation variables.
- *
- * @group language
- */
-class MigrateLanguageNegotiationSettingsTest extends MigrateDrupal7TestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = ['language'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->executeMigration('d7_language_negotiation_settings');
-  }
-
-  /**
-   * Tests migration of language negotiation variables to language.negotiation.yml.
-   */
-  public function testLanguageNegotiation() {
-    $config = $this->config('language.negotiation');
-    $this->assertIdentical($config->get('session.parameter'), 'language');
-    $this->assertIdentical($config->get('url.source'), 'domain');
-  }
-
-}
diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
index ed80376..eb3804a 100644
--- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
+++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\link\Plugin\Field\FieldFormatter;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Field\FieldDefinitionInterface;
@@ -200,7 +201,7 @@ public function viewElements(FieldItemListInterface $items) {
 
       if (!empty($settings['url_only']) && !empty($settings['url_plain'])) {
         $element[$delta] = array(
-          '#plain_text' => $link_title,
+          '#markup' => SafeMarkup::checkPlain($link_title),
         );
 
         if (!empty($item->_attributes)) {
diff --git a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
index 1947114..e3b1087 100644
--- a/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
+++ b/core/modules/menu_link_content/src/MenuLinkContentAccessControlHandler.php
@@ -54,9 +54,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI
   protected function checkAccess(EntityInterface $entity, $operation, $langcode, AccountInterface $account) {
     switch ($operation) {
       case 'view':
-        // There is no direct viewing of a menu link, but still for purposes of
-        // content_translation we need a generic way to check access.
-        return AccessResult::allowedIfHasPermission($account, 'administer menu');
+        // There is no direct view.
+        return AccessResult::neutral();
 
       case 'update':
         if (!$account->hasPermission('administer menu')) {
diff --git a/core/modules/migrate/config/schema/migrate.data_types.schema.yml b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
index 7521ee1..d887785 100644
--- a/core/modules/migrate/config/schema/migrate.data_types.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
@@ -27,3 +27,7 @@ migrate_source_sql:
     target:
       type: string
       label: 'The migration database target'
+
+migrate_load:
+  type: migrate_plugin
+  label: 'Load'
diff --git a/core/modules/migrate/src/Tests/MigrateEmbeddedDataTest.php b/core/modules/migrate/src/Tests/MigrateEmbeddedDataTest.php
index 17d0499..9058485 100644
--- a/core/modules/migrate/src/Tests/MigrateEmbeddedDataTest.php
+++ b/core/modules/migrate/src/Tests/MigrateEmbeddedDataTest.php
@@ -44,6 +44,7 @@ public function testEmbeddedData() {
       ],
       'process' => [],
       'destination' => ['plugin' => 'null'],
+      'load' => ['plugin' => 'null'],
     ];
 
     $migration = Migration::create($config);
diff --git a/core/modules/migrate/src/Tests/MigrateEventsTest.php b/core/modules/migrate/src/Tests/MigrateEventsTest.php
index ccc82ac..a366c63 100644
--- a/core/modules/migrate/src/Tests/MigrateEventsTest.php
+++ b/core/modules/migrate/src/Tests/MigrateEventsTest.php
@@ -80,6 +80,7 @@ public function testMigrateEvents() {
       ],
       'process' => ['value' => 'data'],
       'destination' => ['plugin' => 'dummy'],
+      'load' => ['plugin' => 'null'],
     ];
 
     $migration = Migration::create($config);
diff --git a/core/modules/migrate/src/Tests/MigrateInterruptionTest.php b/core/modules/migrate/src/Tests/MigrateInterruptionTest.php
index 3ffd22b..ca98a86 100644
--- a/core/modules/migrate/src/Tests/MigrateInterruptionTest.php
+++ b/core/modules/migrate/src/Tests/MigrateInterruptionTest.php
@@ -59,6 +59,7 @@ public function testMigrateEvents() {
       ],
       'process' => ['value' => 'data'],
       'destination' => ['plugin' => 'dummy'],
+      'load' => ['plugin' => 'null'],
     ];
 
     $migration = Migration::create($config);
diff --git a/core/modules/migrate/src/Tests/MigrateStatusTest.php b/core/modules/migrate/src/Tests/MigrateStatusTest.php
index 5d1b8ce..2f13894 100644
--- a/core/modules/migrate/src/Tests/MigrateStatusTest.php
+++ b/core/modules/migrate/src/Tests/MigrateStatusTest.php
@@ -31,6 +31,7 @@ public function testStatus() {
         'config_name' => 'migrate_test.settings',
       ],
       'process' => ['foo' => 'bar'],
+      'load' => ['plugin' => 'null'],
     ];
     $migration = Migration::create($configuration);
     $migration->save();
diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
index 177ec92..18351af 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
@@ -200,12 +200,6 @@ public function load() {
       'name' => 'language_types',
       'value' => 'a:3:{s:8:"language";b:1;s:16:"language_content";b:0;s:12:"language_url";b:0;}',
     ))->values(array(
-      'name' => 'locale_language_negotiation_session_param',
-      'value' => 's:8:"language";',
-    ))->values(array(
-      'name' => 'locale_language_negotiation_url_part',
-      'value' => 's:6:"domain";',
-    ))->values(array(
       'name' => 'maintenance_mode',
       'value' => 'i:0;',
     ))->values(array(
@@ -488,4 +482,4 @@ public function load() {
   }
 
 }
-#6c379107303f95fe9118597506168dc2
+#e9148e9bed6f5b345cc1a281afe38dd0
diff --git a/core/modules/node/src/Controller/NodeViewController.php b/core/modules/node/src/Controller/NodeViewController.php
index fc43770..8a756b3 100644
--- a/core/modules/node/src/Controller/NodeViewController.php
+++ b/core/modules/node/src/Controller/NodeViewController.php
@@ -20,7 +20,7 @@ class NodeViewController extends EntityViewController {
    * {@inheritdoc}
    */
   public function view(EntityInterface $node, $view_mode = 'full', $langcode = NULL) {
-    $build = parent::view($node, $view_mode, $langcode);
+    $build = parent::view($node);
 
     foreach ($node->uriRelationships() as $rel) {
       // Set the node path as the canonical URL to prevent duplicate content.
diff --git a/core/modules/node/src/Tests/Views/NodeFieldTokensTest.php b/core/modules/node/src/Tests/Views/NodeFieldTokensTest.php
deleted file mode 100644
index 3aef9b2..0000000
--- a/core/modules/node/src/Tests/Views/NodeFieldTokensTest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\node\Tests\NodeFieldTokensTest.
- */
-
-namespace Drupal\node\Tests\Views;
-
-use Drupal\views\Views;
-use Drupal\node\Tests\Views\NodeTestBase;
-
-/**
- * Tests replacement of Views tokens supplied by the Node module.
- *
- * @group node
- * @see \Drupal\node\Tests\NodeTokenReplaceTest
- */
-class NodeFieldTokensTest extends NodeTestBase {
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = array('test_node_tokens');
-
-  /**
-   * Tests token replacement for Views tokens supplied by the Node module.
-   */
-  public function testViewsTokenReplacement() {
-    // Create the Article content type with a standard body field.
-    /* @var $node_type \Drupal\node\NodeTypeInterface */
-    $node_type = entity_create('node_type', ['type' => 'article', 'name' => 'Article']);
-    $node_type->save();
-    node_add_body_field($node_type);
-
-    // Create a user and a node.
-    $account = $this->createUser();
-    $body = $this->randomMachineName(32);
-    $summary = $this->randomMachineName(16);
-
-    /** @var $node \Drupal\node\NodeInterface */
-    $node = entity_create('node', [
-      'type' => 'article',
-      'tnid' => 0,
-      'uid' => $account->id(),
-      'title' => 'Testing Views tokens',
-      'body' => [['value' => $body, 'summary' => $summary, 'format' => 'plain_text']],
-    ]);
-    $node->save();
-
-    $this->drupalGet('test_node_tokens');
-
-    // Body: {{ body }}<br />
-    $this->assertRaw("Body: <p>$body</p>");
-
-    // Raw value: {{ body__value }}<br />
-    $this->assertRaw("Raw value: $body");
-
-    // Raw summary: {{ body__summary }}<br />
-    $this->assertRaw("Raw summary: $summary");
-
-    // Raw format: {{ body__format }}<br />
-    $this->assertRaw("Raw format: plain_text");
-  }
-
-}
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_tokens.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_tokens.yml
deleted file mode 100644
index 746a23c..0000000
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_tokens.yml
+++ /dev/null
@@ -1,194 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  config:
-    - field.storage.node.body
-  module:
-    - node
-    - text
-    - user
-id: test_node_tokens
-label: test_node_tokens
-module: views
-description: 'Verifies tokens provided by the Node module are replaced correctly.'
-tag: ''
-base_table: node_field_data
-base_field: nid
-core: 8.x
-display:
-  default:
-    display_plugin: default
-    id: default
-    display_title: Master
-    position: 0
-    display_options:
-      access:
-        type: perm
-        options:
-          perm: 'access content'
-      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: full
-        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: '‹ previous'
-            next: 'next ›'
-            first: '« first'
-            last: 'last »'
-          quantity: 9
-      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:
-        body:
-          id: body
-          table: node__body
-          field: body
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: ''
-          exclude: false
-          alter:
-            alter_text: true
-            text: "Body: {{ body }}<br />\nRaw value: {{ body__value }}<br />\nRaw summary: {{ body__summary }}<br />\nRaw format: {{ body__format }}"
-            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: text_default
-          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
-          plugin_id: field
-      filters: {  }
-      sorts:
-        created:
-          id: created
-          table: node_field_data
-          field: created
-          order: DESC
-          entity_type: node
-          entity_field: created
-          plugin_id: date
-          relationship: none
-          group_type: group
-          admin_label: ''
-          exposed: false
-          expose:
-            label: ''
-          granularity: second
-      header: {  }
-      footer: {  }
-      empty: {  }
-      relationships: {  }
-      arguments: {  }
-      display_extenders: {  }
-    cache_metadata:
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url.query_args
-        - 'user.node_grants:view'
-        - user.permissions
-      cacheable: false
-  page_1:
-    display_plugin: page
-    id: page_1
-    display_title: Page
-    position: 1
-    display_options:
-      display_extenders: {  }
-      path: test_node_tokens
-    cache_metadata:
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url.query_args
-        - 'user.node_grants:view'
-        - user.permissions
-      cacheable: false
diff --git a/core/modules/quickedit/js/models/EntityModel.js b/core/modules/quickedit/js/models/EntityModel.js
index 12cc59e..300c545 100644
--- a/core/modules/quickedit/js/models/EntityModel.js
+++ b/core/modules/quickedit/js/models/EntityModel.js
@@ -635,7 +635,9 @@
       this.stopListening();
 
       // Destroy all fields of this entity.
-      this.get('fields').reset();
+      this.get('fields').each(function (fieldModel) {
+        fieldModel.destroy();
+      });
     },
 
     /**
diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php
index bf0b62d..067a73a 100644
--- a/core/modules/quickedit/src/QuickEditController.php
+++ b/core/modules/quickedit/src/QuickEditController.php
@@ -216,7 +216,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
       $response->addCommand(new FieldFormSavedCommand($output, $other_view_modes));
     }
     else {
-      $output = $this->renderer->renderRoot($form);
+      $output = (string) $this->renderer->renderRoot($form);
       // When working with a hidden form, we don't want its CSS/JS to be loaded.
       if ($request->request->get('nocssjs') !== 'true') {
         $response->setAttachments($form['#attached']);
@@ -228,7 +228,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
         $status_messages = array(
           '#type' => 'status_messages'
         );
-        $response->addCommand(new FieldFormValidationErrorsCommand($this->renderer->renderRoot($status_messages)));
+        $response->addCommand(new FieldFormValidationErrorsCommand((string) $this->renderer->renderRoot($status_messages)));
       }
     }
 
@@ -255,7 +255,7 @@ public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view
    *   The view mode the field should be rerendered in. Either an Entity Display
    *   view mode ID, or a custom one. See hook_quickedit_render_field().
    *
-   * @return \Drupal\Component\Utility\SafeStringInterface
+   * @return string
    *   Rendered HTML.
    *
    * @see hook_quickedit_render_field()
@@ -275,7 +275,7 @@ protected function renderField(EntityInterface $entity, $field_name, $langcode,
       $output = $this->moduleHandler()->invoke($module, 'quickedit_render_field', $args);
     }
 
-    return $this->renderer->renderRoot($output);
+    return (string) $this->renderer->renderRoot($output);
   }
 
   /**
diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index 702c276..0e2b719 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -270,6 +270,15 @@ function rdf_preprocess_html(&$variables) {
 }
 
 /**
+ * Implements hook_preprocess_HOOK().
+ *
+ * @todo remove after https://www.drupal.org/node/2556785 is fixed.
+ */
+function rdf_preprocess_field__node(&$variables) {
+  // Just an empty hook to avoid https://www.drupal.org/node/2556785.
+}
+
+/**
  * Implements hook_preprocess_HOOK() for UID field templates.
  */
 function rdf_preprocess_field__node__uid(&$variables) {
diff --git a/core/modules/responsive_image/responsive_image.module b/core/modules/responsive_image/responsive_image.module
index 5628bf0..6d2559a 100644
--- a/core/modules/responsive_image/responsive_image.module
+++ b/core/modules/responsive_image/responsive_image.module
@@ -91,20 +91,10 @@ function responsive_image_theme() {
  *   - url: An optional \Drupal\Core\Url object.
  */
 function template_preprocess_responsive_image_formatter(&$variables) {
-  // Provide fallback to standard image if valid responsive image style is not
-  // provided in the responsive image formatter.
-  $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']);
-  if ($responsive_image_style) {
-    $variables['responsive_image'] = array(
-      '#type' => 'responsive_image',
-      '#responsive_image_style_id' => $variables['responsive_image_style_id'],
-    );
-  }
-  else {
-    $variables['responsive_image'] = array(
-      '#theme' => 'image',
-    );
-  }
+  $variables['responsive_image'] = array(
+    '#type' => 'responsive_image',
+    '#responsive_image_style_id' => $variables['responsive_image_style_id'],
+  );
   $item = $variables['item'];
   $attributes = array();
   // Do not output an empty 'title' attribute.
@@ -157,13 +147,6 @@ function template_preprocess_responsive_image(&$variables) {
 
   $image = \Drupal::service('image.factory')->get($variables['uri']);
   $responsive_image_style = ResponsiveImageStyle::load($variables['responsive_image_style_id']);
-  // If a responsive image style is not selected, log the error and stop
-  // execution.
-  if (!$responsive_image_style) {
-    $variables['img_element'] = [];
-    \Drupal::logger('responsive_image')->log(\Drupal\Core\Logger\RfcLogLevel::ERROR, 'Failed to load responsive image style: “@style“ while displaying responsive image.', ['@style' => $variables['responsive_image_style_id']]);
-    return;
-  }
   // Retrieve all breakpoints and multipliers and reverse order of breakpoints.
   // By default, breakpoints are ordered from smallest weight to largest:
   // the smallest weight is expected to have the smallest breakpoint width,
diff --git a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
index 06fd862..410bd89 100644
--- a/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
+++ b/core/modules/responsive_image/src/Tests/ResponsiveImageFieldDisplayTest.php
@@ -12,7 +12,6 @@
 use Drupal\image\Entity\ImageStyle;
 use Drupal\node\Entity\Node;
 use Drupal\file\Entity\File;
-use Drupal\responsive_image\Plugin\Field\FieldFormatter\ResponsiveImageFormatter;
 use Drupal\user\RoleInterface;
 
 /**
@@ -191,28 +190,6 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles =
     );
     $default_output = str_replace("\n", NULL, $renderer->renderRoot($image));
     $this->assertRaw($default_output, 'Default formatter displaying correctly on full node view.');
-
-    // Test field not being configured. This should not cause a fatal error.
-    $display_options = array(
-      'type' => 'responsive_image_test',
-      'settings' => ResponsiveImageFormatter::defaultSettings(),
-    );
-    $display = $this->container->get('entity.manager')
-      ->getStorage('entity_view_display')
-      ->load('node.article.default');
-    if (!$display) {
-      $values = [
-        'targetEntityType' => 'node',
-        'bundle' => 'article',
-        'mode' => 'default',
-        'status' => TRUE,
-      ];
-      $display = $this->container->get('entity.manager')->getStorage('entity_view_display')->create($values);
-    }
-    $display->setComponent($field_name, $display_options)->save();
-
-    $this->drupalGet('node/' . $nid);
-
     // Test theme function for responsive image, but using the test formatter.
     $display_options = array(
       'type' => 'responsive_image_test',
diff --git a/core/modules/rest/src/Plugin/views/display/RestExport.php b/core/modules/rest/src/Plugin/views/display/RestExport.php
index 2d3a5b0..e3a587c 100644
--- a/core/modules/rest/src/Plugin/views/display/RestExport.php
+++ b/core/modules/rest/src/Plugin/views/display/RestExport.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\rest\Plugin\views\display;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableResponse;
 use Drupal\Core\Render\RenderContext;
@@ -317,12 +318,11 @@ public function render() {
     $this->view->element['#content_type'] = $this->getMimeType();
     $this->view->element['#cache_properties'][] = '#content_type';
 
-    // Encode and wrap the output in a pre tag if this is for a live preview.
+      // Wrap the output in a pre tag if this is for a live preview.
     if (!empty($this->view->live_preview)) {
       $build['#prefix'] = '<pre>';
-      $build['#plain_text'] = $build['#markup'];
+      $build['#markup'] = SafeMarkup::checkPlain($build['#markup']);
       $build['#suffix'] = '</pre>';
-      unset($build['#markup']);
     }
     elseif ($this->view->getRequest()->getFormat($this->view->element['#content_type']) !== 'html') {
       // This display plugin is primarily for returning non-HTML formats.
diff --git a/core/modules/rest/src/Tests/ResourceTest.php b/core/modules/rest/src/Tests/ResourceTest.php
index f699a4b..f55ad54 100644
--- a/core/modules/rest/src/Tests/ResourceTest.php
+++ b/core/modules/rest/src/Tests/ResourceTest.php
@@ -6,8 +6,6 @@
  */
 
 namespace Drupal\rest\Tests;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\user\Entity\Role;
 
 /**
  * Tests the structure of a REST resource.
@@ -40,10 +38,6 @@ protected function setUp() {
     // Create an entity programmatically.
     $this->entity = $this->entityCreate('entity_test');
     $this->entity->save();
-
-    Role::load(AccountInterface::ANONYMOUS_ROLE)
-      ->grantPermission('view test entity')
-      ->save();
   }
 
   /**
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index 498942f..de114d4 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -480,16 +480,16 @@ public function testLivePreview() {
       $entities[] = $row->_entity;
     }
 
-    $expected = $serializer->serialize($entities, 'json');
+    $expected = Html::escape($serializer->serialize($entities, 'json'));
 
     $view->live_preview = TRUE;
 
     $build = $view->preview();
-    $rendered_json = $build['#plain_text'];
-    $this->assertTrue(!isset($build['#markup']) && $rendered_json == $expected, 'Ensure the previewed json is escaped.');
+    $rendered_json = $build['#markup'];
+    $this->assertEqual($rendered_json, $expected, 'Ensure the previewed json is escaped.');
     $view->destroy();
 
-    $expected = $serializer->serialize($entities, 'xml');
+    $expected = Html::escape($serializer->serialize($entities, 'xml'));
 
     // Change the request format to xml.
     $view->setDisplay('rest_export_1');
@@ -505,7 +505,7 @@ public function testLivePreview() {
 
     $this->executeView($view);
     $build = $view->preview();
-    $rendered_xml = $build['#plain_text'];
+    $rendered_xml = $build['#markup'];
     $this->assertEqual($rendered_xml, $expected, 'Ensure we preview xml when we change the request format.');
   }
 
diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc
index 409ce2d..518a08b 100644
--- a/core/modules/search/search.pages.inc
+++ b/core/modules/search/search.pages.inc
@@ -5,7 +5,6 @@
  * User page callbacks for the Search module.
  */
 
-use Drupal\Component\Utility\UrlHelper;
 use Drupal\Core\Language\LanguageInterface;
 
 /**
@@ -35,7 +34,7 @@ function template_preprocess_search_result(&$variables) {
   $language_interface = \Drupal::languageManager()->getCurrentLanguage();
 
   $result = $variables['result'];
-  $variables['url'] = UrlHelper::stripDangerousProtocols($result['link']);
+  $variables['url'] = check_url($result['link']);
   $variables['title'] = $result['title'];
   if (isset($result['language']) && $result['language'] != $language_interface->getId() && $result['language'] != LanguageInterface::LANGCODE_NOT_SPECIFIED) {
     $variables['title_attributes']['lang'] = $result['language'];
diff --git a/core/modules/simpletest/src/BrowserTestBase.php b/core/modules/simpletest/src/BrowserTestBase.php
index e0ece50..4224421 100644
--- a/core/modules/simpletest/src/BrowserTestBase.php
+++ b/core/modules/simpletest/src/BrowserTestBase.php
@@ -12,6 +12,8 @@
 use Behat\Mink\Exception\Exception;
 use Behat\Mink\Mink;
 use Behat\Mink\Session;
+use Drupal\Component\Utility\Crypt;
+use Drupal\Component\Utility\Random;
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Database\ConnectionNotDefinedException;
@@ -50,7 +52,6 @@
  */
 abstract class BrowserTestBase extends \PHPUnit_Framework_TestCase {
 
-  use RandomGeneratorTrait;
   use SessionTestTrait;
 
   /**
@@ -146,6 +147,13 @@
   protected $configImporter;
 
   /**
+   * The random data generator.
+   *
+   * @var \Drupal\Component\Utility\Random
+   */
+  protected $randomGenerator;
+
+  /**
    * The profile to install as a basis for testing.
    *
    * @var string
@@ -565,6 +573,69 @@ protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NUL
   }
 
   /**
+   * Gets the random generator for the utility methods.
+   *
+   * @return \Drupal\Component\Utility\Random
+   *   The random generator
+   */
+  protected function getRandomGenerator() {
+    if (!is_object($this->randomGenerator)) {
+      $this->randomGenerator = new Random();
+    }
+    return $this->randomGenerator;
+  }
+
+  /**
+   * Generates a unique random string containing letters and numbers.
+   *
+   * Do not use this method when testing unvalidated user input. Instead, use
+   * \Drupal\simpletest\BrowserTestBase::randomString().
+   *
+   * @param int $length
+   *   (optional) Length of random string to generate.
+   *
+   * @return string
+   *   Randomly generated unique string.
+   *
+   * @see \Drupal\Component\Utility\Random::name()
+   */
+  public function randomMachineName($length = 8) {
+    return $this->getRandomGenerator()->name($length, TRUE);
+  }
+
+  /**
+   * Generates a pseudo-random string of ASCII characters of codes 32 to 126.
+   *
+   * Do not use this method when special characters are not possible (e.g., in
+   * machine or file names that have already been validated); instead, use
+   * \Drupal\simpletest\TestBase::randomMachineName(). If $length is greater
+   * than 2 the random string will include at least one ampersand ('&')
+   * character to ensure coverage for special characters and avoid the
+   * introduction of random test failures.
+   *
+   * @param int $length
+   *   (optional) Length of random string to generate.
+   *
+   * @return string
+   *   Pseudo-randomly generated unique string including special characters.
+   *
+   * @see \Drupal\Component\Utility\Random::string()
+   */
+  public function randomString($length = 8) {
+    if ($length < 3) {
+      return $this->getRandomGenerator()->string($length, TRUE, array($this, 'randomStringValidate'));
+    }
+
+    // To prevent the introduction of random test failures, ensure that the
+    // returned string contains a character that needs to be escaped in HTML by
+    // injecting an ampersand into it.
+    $replacement_pos = floor($length / 2);
+    // Remove 1 from the length to account for the ampersand character.
+    $string = $this->getRandomGenerator()->string($length - 1, TRUE, array($this, 'randomStringValidate'));
+    return substr_replace($string, '&', $replacement_pos, 0);
+  }
+
+  /**
    * Checks whether a given list of permission names is valid.
    *
    * @param array $permissions
diff --git a/core/modules/simpletest/src/Form/SimpletestTestForm.php b/core/modules/simpletest/src/Form/SimpletestTestForm.php
index a46be86..aadc4a9 100644
--- a/core/modules/simpletest/src/Form/SimpletestTestForm.php
+++ b/core/modules/simpletest/src/Form/SimpletestTestForm.php
@@ -8,6 +8,7 @@
 namespace Drupal\simpletest\Form;
 
 use Drupal\Component\Utility\SortArray;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\RendererInterface;
@@ -178,7 +179,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         );
         $form['tests'][$class]['description'] = array(
           '#prefix' => '<div class="description">',
-          '#plain_text' => $info['description'],
+          '#markup' => SafeMarkup::checkPlain($info['description']),
           '#suffix' => '</div>',
           '#wrapper_attributes' => array(
             'class' => array('simpletest-test-description', 'table-filter-text-source'),
diff --git a/core/modules/system/css/components/node.theme.css b/core/modules/system/css/components/node.theme.css
new file mode 100644
index 0000000..6b7cd52
--- /dev/null
+++ b/core/modules/system/css/components/node.theme.css
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Visual styles for nodes.
+ */
+
+.node--unpublished {
+  background-color: #fff4f4;
+}
diff --git a/core/modules/system/css/system.diff.css b/core/modules/system/css/system.diff.css
index 09809de..251ff57 100644
--- a/core/modules/system/css/system.diff.css
+++ b/core/modules/system/css/system.diff.css
@@ -1,4 +1,45 @@
 /**
+ * Inline diff metadata
+ */
+.diff-inline-metadata {
+  padding:4px;
+  border:1px solid #ddd;
+  background:#fff;
+  margin:0 0 10px;
+}
+
+.diff-inline-legend {
+  font-size:11px;
+}
+
+.diff-inline-legend span,
+.diff-inline-legend label {
+  margin-right:5px;
+}
+
+/**
+ * Inline diff markup
+ */
+span.diff-deleted {
+  color:#ccc;
+}
+span.diff-deleted img {
+  border: solid 2px #ccc;
+}
+span.diff-changed {
+  background:#ffb;
+}
+span.diff-changed img {
+  border:solid 2px #ffb;
+}
+span.diff-added {
+  background:#cfc;
+}
+span.diff-added img {
+  border: solid 2px #cfc;
+}
+
+/**
  * Traditional split diff theming
  */
 table.diff {
@@ -7,8 +48,25 @@ table.diff {
   table-layout: fixed;
   width: 100%;
 }
+table.diff .even, table.diff .odd {
+  background-color: inherit;
+  border: none;
+}
+table.diff .diff-prevlink {
+  text-align: left;
+}
+table.diff .diff-nextlink {
+  text-align: right;
+}
+table.diff .diff-section-title,
+table.diff  .diff-section-title {
+  background-color: #f0f0ff;
+  font-size: 0.83em;
+  font-weight: bold;
+  padding: 0.1em 1em;
+}
 table.diff .diff-context {
-  background-color: #fafafa;
+    background-color: #fafafa;
 }
 table.diff .diff-deletedline {
   background-color: #ffa;
@@ -22,9 +80,13 @@ table.diff .diffchange {
   color: #f00;
   font-weight: bold;
 }
+
 table.diff .diff-marker {
   width: 1.4em;
 }
+table.diff .diff-content {
+  width: 50%;
+}
 table.diff th {
   padding-right: inherit;
 }
diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php
index fa8104d..28ab72b 100644
--- a/core/modules/system/src/Controller/DbUpdateController.php
+++ b/core/modules/system/src/Controller/DbUpdateController.php
@@ -228,8 +228,7 @@ protected function info(Request $request) {
       '#type' => 'link',
       '#title' => $this->t('Continue'),
       '#attributes' => array('class' => array('button', 'button--primary')),
-      // @todo Revisit once https://www.drupal.org/node/2548095 is in.
-      '#url' => Url::fromUri('base://selection'),
+      '#url' => Url::fromUri($request->getUriForPath('/selection')),
     );
     return $build;
   }
@@ -485,9 +484,6 @@ protected function results(Request $request) {
    */
   public function requirements($severity, array $requirements, Request $request) {
     $options = $severity == REQUIREMENT_WARNING ? array('continue' => 1) : array();
-    // @todo Revisit once https://www.drupal.org/node/2548095 is in. Something
-    // like Url::fromRoute('system.db_update')->setOptions() should then be
-    // possible.
     $try_again_url = Url::fromUri($request->getUriForPath(''))->setOptions(['query' => $options])->toString(TRUE)->getGeneratedUrl();
 
     $build['status_report'] = array(
@@ -584,8 +580,7 @@ protected function triggerBatch(Request $request) {
     );
     batch_set($batch);
 
-    // @todo Revisit once https://www.drupal.org/node/2548095 is in.
-    return batch_process(Url::fromUri('base://results'), Url::fromUri('base://start'));
+    return batch_process(Url::fromUri($request->getUriForPath('/results')), Url::fromUri($request->getUriForPath('/start')));
   }
 
   /**
diff --git a/core/modules/system/src/SystemManager.php b/core/modules/system/src/SystemManager.php
index 1ea232b..cc86c03 100644
--- a/core/modules/system/src/SystemManager.php
+++ b/core/modules/system/src/SystemManager.php
@@ -119,7 +119,7 @@ public function listRequirements() {
     usort($requirements, function($a, $b) {
       if (!isset($a['weight'])) {
         if (!isset($b['weight'])) {
-          return strcasecmp($a['title'], $b['title']);
+          return strcmp($a['title'], $b['title']);
         }
         return -$b['weight'];
       }
diff --git a/core/modules/system/src/Tests/Common/UrlTest.php b/core/modules/system/src/Tests/Common/UrlTest.php
index 7584c10..e597139 100644
--- a/core/modules/system/src/Tests/Common/UrlTest.php
+++ b/core/modules/system/src/Tests/Common/UrlTest.php
@@ -33,14 +33,14 @@ function testLinkXSS() {
     // Test \Drupal::l().
     $text = $this->randomMachineName();
     $path = "<SCRIPT>alert('XSS')</SCRIPT>";
-    $encoded_path = "3CSCRIPT%3Ealert%28%27XSS%27%29%3C/SCRIPT%3E";
-
     $link = \Drupal::l($text, Url::fromUserInput('/' . $path));
-    $this->assertTrue(strpos($link, $encoded_path) !== FALSE && strpos($link, $path) === FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
+    $sanitized_path = check_url(Url::fromUri('base:' . $path)->toString());
+    $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by _l().', array('@path' => $path)));
 
     // Test \Drupal\Core\Url.
     $link = Url::fromUri('base:' . $path)->toString();
-    $this->assertTrue(strpos($link, $encoded_path) !== FALSE && strpos($link, $path) === FALSE, format_string('XSS attack @path was filtered by #theme', ['@path' => $path]));
+    $sanitized_path = check_url(Url::fromUri('base:' . $path)->toString());
+    $this->assertTrue(strpos($link, $sanitized_path) !== FALSE, format_string('XSS attack @path was filtered by #theme', ['@path' => $path]));
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Common/XssUnitTest.php b/core/modules/system/src/Tests/Common/XssUnitTest.php
index 2890f55..f1358e0 100644
--- a/core/modules/system/src/Tests/Common/XssUnitTest.php
+++ b/core/modules/system/src/Tests/Common/XssUnitTest.php
@@ -56,8 +56,6 @@ function testBadProtocolStripping() {
     $expected_plain = 'http://www.example.com/?x=1&y=2';
     $expected_html = 'http://www.example.com/?x=1&amp;y=2';
     $this->assertIdentical(check_url($url), $expected_html, 'check_url() filters a URL and encodes it for HTML.');
-    $this->assertIdentical(UrlHelper::filterBadProtocol($url), $expected_html, '\Drupal\Component\Utility\UrlHelper::filterBadProtocol() filters a URL and encodes it for HTML.');
-    $this->assertIdentical(UrlHelper::stripDangerousProtocols($url), $expected_plain, '\Drupal\Component\Utility\UrlHelper::stripDangerousProtocols() filters a URL and returns plain text.');
-
+    $this->assertIdentical(UrlHelper::stripDangerousProtocols($url), $expected_plain, '\Drupal\Component\Utility\Url::stripDangerousProtocols() filters a URL and returns plain text.');
   }
 }
diff --git a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
index 5aeef20..a80b984 100644
--- a/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
+++ b/core/modules/system/src/Tests/Entity/EntityViewControllerTest.php
@@ -39,7 +39,6 @@ protected function setUp() {
       $this->entities[] = $entity_test;
     }
 
-    $this->drupalLogin($this->drupalCreateUser(['view test entity']));
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Form/ElementsAccessTest.php b/core/modules/system/src/Tests/Form/ElementsAccessTest.php
deleted file mode 100644
index 478f500..0000000
--- a/core/modules/system/src/Tests/Form/ElementsAccessTest.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\system\Tests\Form\ElementsAccessTest.
- */
-
-namespace Drupal\system\Tests\Form;
-
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Tests access control for form elements.
- *
- * @group Form
- */
-class ElementsAccessTest extends WebTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('form_test');
-
-  /**
-   * Ensures that child values are still processed when #access = FALSE.
-   */
-  public function testAccessFalse() {
-    $this->drupalPostForm('form_test/vertical-tabs-access', NULL, t('Submit'));
-    $this->assertNoText(t('This checkbox inside a vertical tab does not have its default value.'));
-    $this->assertNoText(t('This textfield inside a vertical tab does not have its default value.'));
-    $this->assertNoText(t('This checkbox inside a fieldset does not have its default value.'));
-    $this->assertNoText(t('This checkbox inside a container does not have its default value.'));
-    $this->assertNoText(t('This checkbox inside a nested container does not have its default value.'));
-    $this->assertNoText(t('This checkbox inside a vertical tab whose fieldset access is allowed does not have its default value.'));
-    $this->assertText(t('The form submitted correctly.'));
-  }
-
-}
diff --git a/core/modules/system/src/Tests/Form/FormTest.php b/core/modules/system/src/Tests/Form/FormTest.php
index e89b78f..4585ad1 100644
--- a/core/modules/system/src/Tests/Form/FormTest.php
+++ b/core/modules/system/src/Tests/Form/FormTest.php
@@ -12,7 +12,6 @@
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Render\Element;
-use Drupal\Core\Url;
 use Drupal\form_test\Form\FormTestDisabledElementsForm;
 use Drupal\simpletest\WebTestBase;
 use Drupal\user\RoleInterface;
@@ -234,67 +233,6 @@ function testRequiredCheckboxesRadio() {
   }
 
   /**
-   * Tests that input is retained for safe elements even with an invalid token.
-   *
-   * Submits a test form containing several types of form elements.
-   */
-  public function testInputWithInvalidToken() {
-    // We need to be logged in to have CSRF tokens.
-    $account = $this->createUser();
-    $this->drupalLogin($account);
-    // Submit again with required fields set but an invalid form token and
-    // verify that all the values are retained.
-    $edit = array(
-      'textfield' => $this->randomString(),
-      'checkboxes[bar]' => TRUE,
-      'select' => 'bar',
-      'radios' => 'foo',
-      'form_token' => 'invalid token',
-    );
-    $this->drupalPostForm(Url::fromRoute('form_test.validate_required'), $edit, 'Submit');
-    $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.');
-    $this->assertText('The form has become outdated. Copy any unsaved work in the form below');
-    // Verify that input elements retained the posted values.
-    $this->assertFieldByName('textfield', $edit['textfield']);
-    $this->assertNoFieldChecked('edit-checkboxes-foo');
-    $this->assertFieldChecked('edit-checkboxes-bar');
-    $this->assertOptionSelected('edit-select', 'bar');
-    $this->assertFieldChecked('edit-radios-foo');
-
-    // Check another form that has a textarea input.
-    $edit = array(
-      'textfield' => $this->randomString(),
-      'textarea' => $this->randomString() . "\n",
-      'form_token' => 'invalid token',
-    );
-    $this->drupalPostForm(Url::fromRoute('form_test.required'), $edit, 'Submit');
-    $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.');
-    $this->assertText('The form has become outdated. Copy any unsaved work in the form below');
-    $this->assertFieldByName('textfield', $edit['textfield']);
-    $this->assertFieldByName('textarea', $edit['textarea']);
-
-    // Check another form that has a number input.
-    $edit = array(
-      'integer_step' => mt_rand(1, 100),
-      'form_token' => 'invalid token',
-    );
-    $this->drupalPostForm(Url::fromRoute('form_test.number'), $edit, 'Submit');
-    $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.');
-    $this->assertText('The form has become outdated. Copy any unsaved work in the form below');
-    $this->assertFieldByName('integer_step', $edit['integer_step']);
-
-    // Check a form with a Url field
-    $edit = array(
-      'url' => $this->randomString(),
-      'form_token' => 'invalid token',
-    );
-    $this->drupalPostForm(Url::fromRoute('form_test.url'), $edit, 'Submit');
-    $this->assertFieldByXpath('//div[contains(@class, "error")]', NULL, 'Error message is displayed with invalid token even when required fields are filled.');
-    $this->assertText('The form has become outdated. Copy any unsaved work in the form below');
-    $this->assertFieldByName('url', $edit['url']);
-  }
-
-  /**
    * Tests validation for required textfield element without title.
    *
    * Submits a test form containing a textfield form element without title.
diff --git a/core/modules/system/src/Tests/Theme/RegistryTest.php b/core/modules/system/src/Tests/Theme/RegistryTest.php
index 1fc3715..e6c80be 100644
--- a/core/modules/system/src/Tests/Theme/RegistryTest.php
+++ b/core/modules/system/src/Tests/Theme/RegistryTest.php
@@ -139,7 +139,6 @@ public function testSuggestionPreprocessFunctions() {
     $preprocess_functions = $registry_theme->get()['theme_test_preprocess_suggestions__kitten__bearcat']['preprocess functions'];
     $this->assertIdentical($expected_preprocess_functions, $preprocess_functions, 'Suggestion implemented as a template correctly inherits preprocess functions.');
 
-    $this->assertTrue(isset($registry_theme->get()['theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose']), 'Preprocess function with an unimplemented lower-level suggestion is added to the registry.');
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Theme/TwigExtensionTest.php b/core/modules/system/src/Tests/Theme/TwigExtensionTest.php
index 7ca45fb..7e25ae5 100644
--- a/core/modules/system/src/Tests/Theme/TwigExtensionTest.php
+++ b/core/modules/system/src/Tests/Theme/TwigExtensionTest.php
@@ -47,8 +47,6 @@ function testTwigExtensionFilter() {
 
     $this->drupalGet('twig-extension-test/filter');
     $this->assertText('Every plant is not a mineral.', 'Success: String filtered.');
-    // Test safe_join filter.
-    $this->assertRaw('&lt;em&gt;will be escaped&lt;/em&gt;<br/><em>will be markup</em><br/><strong>will be rendered</strong>');
   }
 
   /**
diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php
index fc8d4c3..c5197a2 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php
@@ -179,15 +179,16 @@ protected function setUp() {
     // Add the config directories to settings.php.
     drupal_install_config_directories();
 
+    // Install any additional modules.
+    $this->installModulesFromClassProperty($container);
+
     // Restore the original Simpletest batch.
     $this->restoreBatch();
 
-    // Set the container. parent::rebuildAll() would normally do this, but this
-    // not safe to do here, because the database has not been updated yet.
-    $this->container = \Drupal::getContainer();
+    // Rebuild and reset.
+    $this->rebuildAll();
 
     // Replace User 1 with the user created here.
-    // @todo: do this without saving the user account.
     /** @var \Drupal\user\UserInterface $account */
     $account = User::load(1);
     $account->setPassword($this->rootUser->pass_raw);
@@ -266,4 +267,25 @@ protected function runUpdates() {
     $this->assertFalse(\Drupal::service('entity.definition_update_manager')->needsUpdates(), 'After all updates ran, entity schema is up to date.');
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function rebuildAll() {
+    // We know the rebuild causes notices, so don't exit on failure.
+    $die_on_fail = $this->dieOnFail;
+    $this->dieOnFail = FALSE;
+    parent::rebuildAll();
+
+    // Remove the notices we get due to the menu link rebuild prior to running
+    // the system updates for the schema change.
+    foreach ($this->assertions as $key => $assertion) {
+      if ($assertion['message_group'] == 'Notice' && basename($assertion['file']) == 'MenuTreeStorage.php' && strpos($assertion['message'], 'unserialize(): Error at offset 0') !== FALSE) {
+        unset($this->assertions[$key]);
+        $this->deleteAssert($assertion['message_id']);
+        $this->results['#exception']--;
+      }
+    }
+    $this->dieOnFail = $die_on_fail;
+  }
+
 }
diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
index 623a400..30ed37d 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathTestBaseFilledTest.php
@@ -18,7 +18,6 @@ class UpdatePathTestBaseFilledTest extends UpdatePathTestBaseTest {
    * {@inheritdoc}
    */
   protected function setDatabaseDumpFiles() {
-    parent::setDatabaseDumpFiles();
     $this->databaseDumpFiles[0] = __DIR__ . '/../../../tests/fixtures/update/drupal-8.filled.standard.php.gz';
   }
 
diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php b/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php
index 65e0b21..28e003a 100644
--- a/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php
+++ b/core/modules/system/src/Tests/Update/UpdatePathTestBaseTest.php
@@ -25,10 +25,7 @@ class UpdatePathTestBaseTest extends UpdatePathTestBase {
    * {@inheritdoc}
    */
   protected function setDatabaseDumpFiles() {
-    $this->databaseDumpFiles = [
-      __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
-      __DIR__ . '/../../../tests/fixtures/update/drupal-8.update-test-schema-enabled.php',
-    ];
+    $this->databaseDumpFiles = [__DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz'];
   }
 
   /**
diff --git a/core/modules/system/system.libraries.yml b/core/modules/system/system.libraries.yml
index 9493f52..7c5e178 100644
--- a/core/modules/system/system.libraries.yml
+++ b/core/modules/system/system.libraries.yml
@@ -37,6 +37,7 @@ base:
       css/components/menu.theme.css: { weight: -10 }
       css/components/messages.theme.css: { weight: -10 }
       css/components/more-link.theme.css: { weight: -10 }
+      css/components/node.theme.css: { weight: -10 }
       css/components/pager.theme.css: { weight: -10 }
       css/components/progress.theme.css: { weight: -10 }
       css/components/tableselect.theme.css: { weight: -10 }
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index c12a2d4..b1bdee7 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -105,9 +105,6 @@ function system_help($route_name, RouteMatchInterface $route_match) {
 
     case 'system.themes_page':
       $output = '<p>' . t('Set and configure the default theme for your website.  Alternative <a href="!themes">themes</a> are available.', array('!themes' => 'https://www.drupal.org/project/themes')) . '</p>';
-      if (\Drupal::moduleHandler()->moduleExists('block')) {
-        $output .= '<p>' . t('You can place blocks for each theme on the <a href="@blocks">block layout</a> page.', array('@blocks' => \Drupal::url('block.admin_display'))) . '</p>';
-      }
       return $output;
 
     case 'system.theme_settings_theme':
@@ -244,7 +241,7 @@ function system_theme_suggestions_html(array $variables) {
     $path_args = [''];
   }
   else {
-    $path_args = explode('/', ltrim(\Drupal::service('path.current')->getPath(), '/'));
+    $path_args = explode('/', Url::fromRoute('<current>')->getInternalPath());
   }
   return theme_get_suggestions($path_args, 'html');
 }
diff --git a/core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml b/core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml
index 03498b8..472e131 100644
--- a/core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml
+++ b/core/modules/system/tests/fixtures/update/block.block.thirdtestfor2354889.yml
@@ -27,4 +27,4 @@ visibility:
       page: page
     negate: false
     context_mapping:
-      baloney: baloney_spam
+      baloney: baloney.spam
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
deleted file mode 100644
index f3edf28..0000000
--- a/core/modules/system/tests/fixtures/update/drupal-8.block-test-enabled.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * @file
- * Partial database to mimic the installation of the block_test module.
- */
-
-use Drupal\Core\Database\Database;
-use Symfony\Component\Yaml\Yaml;
-
-$connection = Database::getConnection();
-
-// Set the schema version.
-$connection->insert('key_value')
-  ->fields([
-    'collection' => 'system.schema',
-    'name' => 'block_test',
-    'value' => 'i:8000;',
-  ])
-  ->execute();
-
-// Update core.extension.
-$extensions = $connection->select('config')
-  ->fields('config', ['data'])
-  ->condition('collection', '')
-  ->condition('name', 'core.extension')
-  ->execute()
-  ->fetchField();
-$extensions = unserialize($extensions);
-$extensions['module']['block_test'] = 8000;
-$connection->update('config')
-  ->fields([
-    'data' => serialize($extensions),
-  ])
-  ->condition('collection', '')
-  ->condition('name', 'core.extension')
-  ->execute();
-
-// Install the block configuration.
-$config = file_get_contents(__DIR__ . '/../../../../block/tests/modules/block_test/config/install/block.block.test_block.yml');
-$config = Yaml::parse($config);
-$connection->insert('config')
-  ->fields(['data', 'name', 'collection'])
-  ->values([
-    'name' => 'block.block.test_block',
-    'data' => serialize($config),
-    'collection' => '',
-  ])
-  ->execute();
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php
deleted file mode 100644
index 6be5c24..0000000
Binary files a/core/modules/system/tests/fixtures/update/drupal-8.language-enabled.php and /dev/null differ
diff --git a/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php
deleted file mode 100644
index 7250741..0000000
--- a/core/modules/system/tests/fixtures/update/drupal-8.update-test-schema-enabled.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-/**
- * @file
- * Partial database to mimic the installation of the update_test_schema module.
- */
-
-use Drupal\Core\Database\Database;
-
-$connection = Database::getConnection();
-
-// Create the table.
-$connection->schema()->createTable('update_test_schema_table', array(
-  'fields' => array(
-    'a' => array(
-      'type' => 'int',
-      'not null' => TRUE,
-      'size' => 'normal',
-    ),
-    'b' => array(
-      'type' => 'blob',
-      'not null' => FALSE,
-      'size' => 'normal',
-    ),
-  ),
-));
-
-// Set the schema version.
-$connection->merge('key_value')
-  ->condition('collection', 'system.schema')
-  ->condition('name', 'update_test_schema')
-  ->fields([
-    'collection' => 'system.schema',
-    'name' => 'update_test_schema',
-    'value' => 'i:8000;',
-  ])
-  ->execute();
-
-// Update core.extension.
-$extensions = $connection->select('config')
-  ->fields('config', ['data'])
-  ->condition('collection', '')
-  ->condition('name', 'core.extension')
-  ->execute()
-  ->fetchField();
-$extensions = unserialize($extensions);
-$extensions['module']['update_test_schema'] = 8000;
-$connection->update('config')
-  ->fields([
-    'data' => serialize($extensions),
-  ])
-  ->condition('collection', '')
-  ->condition('name', 'core.extension')
-  ->execute();
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
index 026c8a7..461219f 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
+++ b/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
@@ -5,7 +5,7 @@
  * Batch callbacks for the Batch API tests.
  */
 
-use Drupal\Component\Utility\Html;
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
@@ -90,7 +90,7 @@ function _batch_test_nested_batch_callback() {
 function _batch_test_finished_helper($batch_id, $success, $results, $operations) {
   if ($results) {
     foreach ($results as $op => $op_results) {
-      $messages[] = 'op '. Html::escape($op) . ': processed ' . count($op_results) . ' elements';
+      $messages[] = 'op '. SafeMarkup::escape($op) . ': processed ' . count($op_results) . ' elements';
     }
   }
   else {
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
index 542a14e..630f715 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
+++ b/core/modules/system/tests/modules/entity_test/entity_test.routing.yml
@@ -4,7 +4,7 @@ entity.entity_test.canonical:
     _entity_view: 'entity_test.full'
     _title: 'Test full view mode'
   requirements:
-    _entity_access: 'entity_test.view'
+    _access: 'TRUE'
 
 entity.entity_test.render_options:
   path: '/entity_test_converter/{foo}'
@@ -15,7 +15,7 @@ entity.entity_test.render_options:
   defaults:
     _entity_view: 'entity_test.full'
   requirements:
-    _entity_access: 'foo.view'
+    _access: 'TRUE'
 
 entity.entity_test.render_no_view_mode:
   path: '/entity_test_no_view_mode/{entity_test}'
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
index e1042e9..7cfec16 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilder.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\entity_test;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityViewBuilder;
 
@@ -35,7 +36,7 @@ public function buildComponents(array &$build, array $entities, array $displays,
     foreach ($entities as $id => $entity) {
       $build[$id]['label'] = array(
         '#weight' => -100,
-        '#plain_text' => $entity->label(),
+        '#markup' => SafeMarkup::checkPlain($entity->label()),
       );
       $build[$id]['separator'] = array(
         '#weight' => -150,
@@ -43,7 +44,7 @@ public function buildComponents(array &$build, array $entities, array $displays,
       );
       $build[$id]['view_mode'] = array(
         '#weight' => -200,
-        '#plain_text' => $view_mode,
+        '#markup' => SafeMarkup::checkPlain($view_mode),
       );
     }
   }
diff --git a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilderOverriddenView.php b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilderOverriddenView.php
index 8d44386..f4b719f 100644
--- a/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilderOverriddenView.php
+++ b/core/modules/system/tests/modules/entity_test/src/EntityTestViewBuilderOverriddenView.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\entity_test;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
@@ -19,7 +20,7 @@ class EntityTestViewBuilderOverriddenView extends EntityTestViewBuilder {
    */
   public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
     $build = [];
-    $build[$entity->id()]['#plain_text'] = $entity->label();
+    $build[$entity->id()]['#markup'] = SafeMarkup::checkPlain($entity->label());
     return $build;
   }
 
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module
index ee4c137..2a970a2 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/system/tests/modules/form_test/form_test.module
@@ -93,14 +93,3 @@ function form_test_user_register_form_rebuild($form, FormStateInterface $form_st
   drupal_set_message('Form rebuilt.');
   $form_state->setRebuild();
 }
-
-/**
- * Implements hook_form_FORM_ID_alter() for form_test_vertical_tabs_access_form().
- */
-function form_test_form_form_test_vertical_tabs_access_form_alter(&$form, &$form_state, $form_id) {
-  $form['vertical_tabs1']['#access'] = FALSE;
-  $form['vertical_tabs2']['#access'] = FALSE;
-  $form['tabs3']['#access'] = TRUE;
-  $form['fieldset1']['#access'] = FALSE;
-  $form['container']['#access'] = FALSE;
-}
diff --git a/core/modules/system/tests/modules/form_test/form_test.routing.yml b/core/modules/system/tests/modules/form_test/form_test.routing.yml
index 82243fa..8a200a3 100644
--- a/core/modules/system/tests/modules/form_test/form_test.routing.yml
+++ b/core/modules/system/tests/modules/form_test/form_test.routing.yml
@@ -172,14 +172,6 @@ form_test.storage:
   requirements:
     _access: 'TRUE'
 
-form_test.vertical_tabs_access:
-  path: '/form_test/vertical-tabs-access'
-  defaults:
-    _form: '\Drupal\form_test\Form\FormTestVerticalTabsAccessForm'
-    _title: 'Vertical tabs tests'
-  requirements:
-    _access: 'TRUE'
-
 form_test.state_clean:
   path: '/form_test/form-state-values-clean'
   defaults:
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php
index ae93d75..5f7d5d0 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestRequiredAttributeForm.php
@@ -33,10 +33,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
         '#title' => $type,
       );
     }
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => 'Submit',
-    );
+
     return $form;
   }
 
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php
index 865fd0e..9f3ab5a 100644
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php
+++ b/core/modules/system/tests/modules/form_test/src/Form/FormTestStoragePageCacheForm.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\form_test\Form;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 
@@ -56,7 +57,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    */
   function form_test_storage_page_cache_old_build_id($form) {
     if (isset($form['#build_id_old'])) {
-      $form['test_build_id_old']['#plain_text'] = $form['#build_id_old'];
+      $form['test_build_id_old']['#markup'] = SafeMarkup::checkPlain($form['#build_id_old']);
     }
     return $form;
   }
diff --git a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php b/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php
deleted file mode 100644
index 0f3a2cc..0000000
--- a/core/modules/system/tests/modules/form_test/src/Form/FormTestVerticalTabsAccessForm.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\form_test\Form\FormTestVerticalTabsAccessForm.
- */
-
-namespace Drupal\form_test\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormStateInterface;
-
-class FormTestVerticalTabsAccessForm extends FormBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'form_test_vertical_tabs_access_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $form['vertical_tabs1'] = array(
-      '#type' => 'vertical_tabs',
-    );
-    $form['tab1'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Tab 1'),
-      '#collapsible' => TRUE,
-      '#group' => 'vertical_tabs1',
-    );
-    $form['tab1']['field1'] = array(
-      '#title' => t('Field 1'),
-      '#type' => 'checkbox',
-      '#default_value' => TRUE,
-    );
-    $form['tab2'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Tab 2'),
-      '#collapsible' => TRUE,
-      '#group' => 'vertical_tabs1',
-    );
-    $form['tab2']['field2'] = array(
-      '#title' => t('Field 2'),
-      '#type' => 'textfield',
-      '#default_value' => 'field2',
-    );
-
-    $form['fieldset1'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Fieldset'),
-    );
-    $form['fieldset1']['field3'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Field 3'),
-      '#default_value' => TRUE,
-    );
-
-    $form['container'] = array(
-      '#type' => 'container',
-    );
-    $form['container']['field4'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Field 4'),
-      '#default_value' => TRUE,
-    );
-    $form['container']['subcontainer'] = array(
-      '#type' => 'container',
-    );
-    $form['container']['subcontainer']['field5'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Field 5'),
-      '#default_value' => TRUE,
-    );
-
-    $form['vertical_tabs2'] = array(
-      '#type' => 'vertical_tabs',
-    );
-    $form['tab3'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Tab 3'),
-      '#collapsible' => TRUE,
-      '#group' => 'vertical_tabs2',
-    );
-    $form['tab3']['field6'] = array(
-      '#title' => t('Field 6'),
-      '#type' => 'checkbox',
-      '#default_value' => TRUE,
-    );
-
-    $form['actions'] = array(
-      '#type' => 'actions',
-    );
-    $form['actions']['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Submit'),
-    );
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    $values = $form_state->getValues();
-    if (empty($values['field1'])) {
-      $form_state->setErrorByName('tab1][field1', t('This checkbox inside a vertical tab does not have its default value.'));
-    }
-    if ($values['field2'] != 'field2') {
-      $form_state->setErrorByName('tab2][field2', t('This textfield inside a vertical tab does not have its default value.'));
-    }
-    if (empty($values['field3'])) {
-      $form_state->setErrorByName('fieldset][field3', t('This checkbox inside a fieldset does not have its default value.'));
-    }
-    if (empty($values['field4'])) {
-      $form_state->setErrorByName('container][field4', t('This checkbox inside a container does not have its default value.'));
-    }
-    if (empty($values['field5'])) {
-      $form_state->setErrorByName('container][subcontainer][field5', t('This checkbox inside a nested container does not have its default value.'));
-    }
-    if (empty($values['field5'])) {
-      $form_state->setErrorByName('tab3][field6', t('This checkbox inside a vertical tab whose fieldset access is allowed does not have its default value.'));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    drupal_set_message(t('The form submitted correctly.'));
-  }
-
-}
diff --git a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php
index bbfe65e..4ff849a 100644
--- a/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php
+++ b/core/modules/system/tests/modules/twig_extension_test/src/TwigExtensionTestController.php
@@ -7,13 +7,10 @@
 
 namespace Drupal\twig_extension_test;
 
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-
 /**
  * Controller routines for Twig extension test routes.
  */
 class TwigExtensionTestController {
-  use StringTranslationTrait;
 
   /**
    * Menu callback for testing Twig filters in a Twig template.
@@ -22,11 +19,6 @@ public function testFilterRender() {
     return array(
       '#theme' => 'twig_extension_test_filter',
       '#message' => 'Every animal is not a mineral.',
-      '#safe_join_items' => [
-        '<em>will be escaped</em>',
-        $this->t('<em>will be markup</em>'),
-        ['#markup' => '<strong>will be rendered</strong>']
-      ]
     );
   }
 
diff --git a/core/modules/system/tests/modules/twig_extension_test/templates/twig_extension_test.filter.html.twig b/core/modules/system/tests/modules/twig_extension_test/templates/twig_extension_test.filter.html.twig
index 981874f..1e224d0 100644
--- a/core/modules/system/tests/modules/twig_extension_test/templates/twig_extension_test.filter.html.twig
+++ b/core/modules/system/tests/modules/twig_extension_test/templates/twig_extension_test.filter.html.twig
@@ -1,6 +1,3 @@
 <div class="testfilter">
   {{ message|testfilter }}
 </div>
-<div>
-  {{ safe_join_items|safe_join('<br/>') }}
-</div>
diff --git a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module
index 1c2729b..7e89470 100644
--- a/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module
+++ b/core/modules/system/tests/modules/twig_extension_test/twig_extension_test.module
@@ -11,7 +11,7 @@
 function twig_extension_test_theme($existing, $type, $theme, $path) {
   return array(
     'twig_extension_test_filter' => array(
-      'variables' => array('message' => NULL, 'safe_join_items' => NULL),
+      'variables' => array('message' => NULL),
       'template' => 'twig_extension_test.filter',
     ),
     'twig_extension_test_function' => array(
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.theme b/core/modules/system/tests/themes/test_theme/test_theme.theme
index 36cb4d5..3ce72e3 100644
--- a/core/modules/system/tests/themes/test_theme/test_theme.theme
+++ b/core/modules/system/tests/themes/test_theme/test_theme.theme
@@ -142,10 +142,3 @@ function test_theme_preprocess_theme_test_preprocess_suggestions__kitten(&$varia
 function test_theme_preprocess_theme_test_preprocess_suggestions__kitten__flamingo(&$variables) {
   $variables['bar'] = 'Flamingo';
 }
-
-/**
- * Tests a preprocess function with suggestions.
- */
-function test_theme_preprocess_theme_test_preprocess_suggestions__kitten__meerkat__tarsier__moose(&$variables) {
-  $variables['bar'] = 'Moose';
-}
diff --git a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
index 3f40fc8..4fab01c 100644
--- a/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
+++ b/core/modules/taxonomy/src/Plugin/views/field/TaxonomyIndexTid.php
@@ -169,15 +169,16 @@ function render_item($count, $item) {
   }
 
   protected function documentSelfTokens(&$tokens) {
-    $tokens['{{ ' . $this->options['id'] . '__tid' . ' }}'] = $this->t('The taxonomy term ID for the term.');
-    $tokens['{{ ' . $this->options['id'] . '__name' . ' }}'] = $this->t('The taxonomy term name for the term.');
-    $tokens['{{ ' . $this->options['id'] . '__vocabulary_vid' . ' }}'] = $this->t('The machine name for the vocabulary the term belongs to.');
-    $tokens['{{ ' . $this->options['id'] . '__vocabulary' . ' }}'] = $this->t('The name for the vocabulary the term belongs to.');
+    $tokens['[' . $this->options['id'] . '-tid' . ']'] = $this->t('The taxonomy term ID for the term.');
+    $tokens['[' . $this->options['id'] . '-name' . ']'] = $this->t('The taxonomy term name for the term.');
+    $tokens['[' . $this->options['id'] . '-vocabulary-vid' . ']'] = $this->t('The machine name for the vocabulary the term belongs to.');
+    $tokens['[' . $this->options['id'] . '-vocabulary' . ']'] = $this->t('The name for the vocabulary the term belongs to.');
   }
 
   protected function addSelfTokens(&$tokens, $item) {
     foreach (array('tid', 'name', 'vocabulary_vid', 'vocabulary') as $token) {
-      $tokens['{{ ' . $this->options['id'] . '__' . $token . ' }}'] = isset($item[$token]) ? $item[$token] : '';
+      // Replace _ with - for the vocabulary vid.
+      $tokens['[' . $this->options['id'] . '-' . str_replace('_', '-', $token) . ']'] = isset($item[$token]) ? $item[$token] : '';
     }
   }
 
diff --git a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
index 8329d04..f1ca0dd 100644
--- a/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
+++ b/core/modules/taxonomy/src/Tests/Views/TaxonomyFieldAllTermsTest.php
@@ -8,7 +8,6 @@
 namespace Drupal\taxonomy\Tests\Views;
 
 use Drupal\views\Views;
-use Drupal\taxonomy\Entity\Vocabulary;
 
 /**
  * Tests the "All terms" taxonomy term field handler.
@@ -24,10 +23,7 @@ class TaxonomyFieldAllTermsTest extends TaxonomyTestBase {
    */
   public static $testViews = array('taxonomy_all_terms_test');
 
-  /**
-   * Tests the "all terms" field handler.
-   */
-  public function testViewsHandlerAllTermsField() {
+  function testViewsHandlerAllTermsField() {
     $view = Views::getView('taxonomy_all_terms_test');
     $this->executeView($view);
     $this->drupalGet('taxonomy_all_terms_test');
@@ -43,28 +39,4 @@ public function testViewsHandlerAllTermsField() {
     $this->assertEqual($actual[1]->__toString(), $this->term2->label());
   }
 
-  /**
-   * Tests token replacement in the "all terms" field handler.
-   */
-  public function testViewsHandlerAllTermsWithTokens() {
-    $view = Views::getView('taxonomy_all_terms_test');
-    $this->drupalGet('taxonomy_all_terms_token_test');
-
-    // Term itself: {{ term_node_tid }}
-    $this->assertText('Term: ' . $this->term1->getName());
-
-    // The taxonomy term ID for the term: {{ term_node_tid__tid }}
-    $this->assertText('The taxonomy term ID for the term: ' . $this->term1->id());
-
-    // The taxonomy term name for the term: {{ term_node_tid__name }}
-    $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());
-
-    // The name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary }}
-    $vocabulary = Vocabulary::load($this->term1->bundle());
-    $this->assertText('The name for the vocabulary the term belongs to: ' .  $vocabulary->label());
-  }
-
 }
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_all_terms_test.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_all_terms_test.yml
index ce71f76..7e2673c 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_all_terms_test.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_all_terms_test.yml
@@ -162,7 +162,7 @@ display:
     cache_metadata:
       contexts:
         - 'languages:language_interface'
-        - url.query_args
+        - 'url.query_args.pagers:0'
         - 'user.node_grants:view'
         - user.permissions
       cacheable: false
@@ -177,82 +177,7 @@ display:
     cache_metadata:
       contexts:
         - 'languages:language_interface'
-        - url.query_args
-        - 'user.node_grants:view'
-        - user.permissions
-      cacheable: false
-  page_2:
-    display_plugin: page
-    id: page_2
-    display_title: 'Token tests'
-    position: 2
-    display_options:
-      display_extenders: {  }
-      display_description: ''
-      fields:
-        term_node_tid:
-          id: term_node_tid
-          table: node_field_data
-          field: term_node_tid
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: ''
-          exclude: false
-          alter:
-            alter_text: true
-            text: "Term: {{ term_node_tid }}<br />\nThe taxonomy term ID for the term: {{ term_node_tid__tid }}<br />\nThe taxonomy term name for the term: {{ term_node_tid__name }}<br />\nThe machine name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary_vid }}<br />\nThe name for the vocabulary the term belongs to: {{ term_node_tid__vocabulary }}<br />"
-            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
-          type: separator
-          separator: '<br />'
-          link_to_taxonomy: false
-          limit: false
-          vids:
-            tags: '0'
-          entity_type: node
-          plugin_id: taxonomy_index_tid
-      defaults:
-        fields: false
-      path: taxonomy_all_terms_token_test
-    cache_metadata:
-      contexts:
-        - 'languages:language_interface'
-        - url.query_args
+        - 'url.query_args.pagers:0'
         - 'user.node_grants:view'
         - user.permissions
       cacheable: false
diff --git a/core/modules/toolbar/js/escapeAdmin.js b/core/modules/toolbar/js/escapeAdmin.js
index 26b8a26..f47b8b9 100644
--- a/core/modules/toolbar/js/escapeAdmin.js
+++ b/core/modules/toolbar/js/escapeAdmin.js
@@ -11,10 +11,10 @@
   var escapeAdminPath = sessionStorage.getItem('escapeAdminPath');
   var windowLocation = window.location;
 
-  // Saves the last non-administrative page in the browser to be able to link
-  // back to it when browsing administrative pages. If there is a destination
-  // parameter there is not need to save the current path because the page is
-  // loaded within an existing "workflow".
+  // Saves the last non-administrative page in the browser to be able to link back
+  // to it when browsing administrative pages. If there is a destination parameter
+  // there is not need to save the current path because the page is loaded within
+  // an existing "workflow".
   if (!pathInfo.currentPathIsAdmin && !/destination=/.test(windowLocation.search)) {
     sessionStorage.setItem('escapeAdminPath', windowLocation);
   }
@@ -22,13 +22,10 @@
   /**
    * Replaces the "Home" link with "Back to site" link.
    *
-   * Back to site link points to the last non-administrative page the user
-   * visited within the same browser tab.
+   * Back to site link points to the last non-administrative page the user visited
+   * within the same browser tab.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the replacement functionality to the toolbar-escape-admin element.
    */
   Drupal.behaviors.escapeAdmin = {
     attach: function () {
diff --git a/core/modules/toolbar/js/models/ToolbarModel.js b/core/modules/toolbar/js/models/ToolbarModel.js
index 357692c..0ddabfa 100644
--- a/core/modules/toolbar/js/models/ToolbarModel.js
+++ b/core/modules/toolbar/js/models/ToolbarModel.js
@@ -138,12 +138,9 @@
      * @inheritdoc
      *
      * @param {object} attributes
-     *   Attributes for the toolbar.
      * @param {object} options
-     *   Options for the toolbar.
      *
-     * @return {string|undefined}
-     *   Returns an error message if validation failed.
+     * @return {string}
      */
     validate: function (attributes, options) {
       // Prevent the orientation being set to horizontal if it is locked, unless
diff --git a/core/modules/toolbar/js/toolbar.js b/core/modules/toolbar/js/toolbar.js
index 9a19205..e45021d 100644
--- a/core/modules/toolbar/js/toolbar.js
+++ b/core/modules/toolbar/js/toolbar.js
@@ -35,9 +35,6 @@
    * Modules register tabs with hook_toolbar().
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the toolbar rendering functionality to the toolbar element.
    */
   Drupal.behaviors.toolbar = {
     attach: function (context) {
@@ -184,11 +181,8 @@
      * Respond to configured narrow media query changes.
      *
      * @param {Drupal.toolbar.ToolbarModel} model
-     *   A toolbar model
      * @param {string} label
-     *   Media query label.
      * @param {object} mql
-     *   A MediaQueryList object.
      */
     mediaQueryChangeHandler: function (model, label, mql) {
       switch (label) {
@@ -244,11 +238,8 @@
    * Ajax command to set the toolbar subtrees.
    *
    * @param {Drupal.Ajax} ajax
-   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
    * @param {object} response
-   *   JSON response from the Ajax request.
    * @param {number} [status]
-   *   XMLHttpRequest status.
    */
   Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (ajax, response, status) {
     Drupal.toolbar.setSubtrees.resolve(response.subtrees);
diff --git a/core/modules/toolbar/js/toolbar.menu.js b/core/modules/toolbar/js/toolbar.menu.js
index f3c2301..990c56a 100644
--- a/core/modules/toolbar/js/toolbar.menu.js
+++ b/core/modules/toolbar/js/toolbar.menu.js
@@ -179,13 +179,9 @@
    * A toggle is an interactive element often bound to a click handler.
    *
    * @param {object} options
-   *   Options for the button.
    * @param {string} options.class
-   *   Class to set on the button.
    * @param {string} options.action
-   *   Action for the button.
    * @param {string} options.text
-   *   Used as label for the button.
    *
    * @return {string}
    *   A string representing a DOM fragment.
diff --git a/core/modules/toolbar/js/views/ToolbarAuralView.js b/core/modules/toolbar/js/views/ToolbarAuralView.js
index 00f5aa5..b6cac03 100644
--- a/core/modules/toolbar/js/views/ToolbarAuralView.js
+++ b/core/modules/toolbar/js/views/ToolbarAuralView.js
@@ -17,9 +17,7 @@
      * @augments Backbone.View
      *
      * @param {object} options
-     *   Options for the view.
      * @param {object} options.strings
-     *   Various strings to use in the view.
      */
     initialize: function (options) {
       this.strings = options.strings;
@@ -32,7 +30,6 @@
      * Announces an orientation change.
      *
      * @param {Drupal.toolbar.ToolbarModel} model
-     *   The toolbar model in question.
      * @param {string} orientation
      *   The new value of the orientation attribute in the model.
      */
@@ -46,7 +43,6 @@
      * Announces a changed active tray.
      *
      * @param {Drupal.toolbar.ToolbarModel} model
-     *   The toolbar model in question.
      * @param {HTMLElement} tray
      *   The new value of the tray attribute in the model.
      */
diff --git a/core/modules/toolbar/js/views/ToolbarVisualView.js b/core/modules/toolbar/js/views/ToolbarVisualView.js
index be7ab06..a63e2a2 100644
--- a/core/modules/toolbar/js/views/ToolbarVisualView.js
+++ b/core/modules/toolbar/js/views/ToolbarVisualView.js
@@ -10,10 +10,7 @@
   Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{
 
     /**
-     * Event map for the `ToolbarVisualView`.
-     *
      * @return {object}
-     *   A map of events.
      */
     events: function () {
       // Prevents delay and simulated mouse events.
@@ -38,9 +35,7 @@
      * @augments Backbone.View
      *
      * @param {object} options
-     *   Options for the view object.
      * @param {object} options.strings
-     *   Various strings to use in the view.
      */
     initialize: function (options) {
       this.strings = options.strings;
@@ -63,7 +58,6 @@
      * @inheritdoc
      *
      * @return {Drupal.toolbar.ToolbarVisualView}
-     *   The `ToolbarVisualView` instance.
      */
     render: function () {
       this.updateTabs();
@@ -97,7 +91,6 @@
      * Responds to a toolbar tab click.
      *
      * @param {jQuery.Event} event
-     *   The event triggered.
      */
     onTabClick: function (event) {
       // If this tab has a tray associated with it, it is considered an
@@ -118,7 +111,6 @@
      * Toggles the orientation of a toolbar tray.
      *
      * @param {jQuery.Event} event
-     *   The event triggered.
      */
     onOrientationToggleClick: function (event) {
       var orientation = this.model.get('orientation');
diff --git a/core/modules/user/src/Plugin/views/field/Roles.php b/core/modules/user/src/Plugin/views/field/Roles.php
index 00a1918..403e9a4 100644
--- a/core/modules/user/src/Plugin/views/field/Roles.php
+++ b/core/modules/user/src/Plugin/views/field/Roles.php
@@ -101,14 +101,14 @@ function render_item($count, $item) {
   }
 
   protected function documentSelfTokens(&$tokens) {
-    $tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $this->t('The name of the role.');
-    $tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $this->t('The role machine-name of the role.');
+    $tokens['[' . $this->options['id'] . '-role' . ']'] = $this->t('The name of the role.');
+    $tokens['[' . $this->options['id'] . '-rid' . ']'] = $this->t('The role machine-name of the role.');
   }
 
   protected function addSelfTokens(&$tokens, $item) {
     if (!empty($item['role'])) {
-      $tokens['{{ ' . $this->options['id'] . '__role' . ' }}'] = $item['role'];
-      $tokens['{{ ' . $this->options['id'] . '__rid' . ' }}'] = $item['rid'];
+      $tokens['[' . $this->options['id'] . '-role' . ']'] = $item['role'];
+      $tokens['[' . $this->options['id'] . '-rid' . ']'] = $item['rid'];
     }
   }
 
diff --git a/core/modules/views/config/schema/views.sort.schema.yml b/core/modules/views/config/schema/views.sort.schema.yml
index b4b5314..e61c3d2 100644
--- a/core/modules/views/config/schema/views.sort.schema.yml
+++ b/core/modules/views/config/schema/views.sort.schema.yml
@@ -41,6 +41,10 @@ views.sort_expose.date:
 views.sort_expose.standard:
   type: views_sort_expose
   label: 'Standard sort expose settings'
+  mapping:
+    order:
+      type: string
+      label: 'Order'
 
 views.sort_expose.random:
   type: views.sort_expose.standard
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index 9145ea9..edfba50 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -8,12 +8,10 @@
   "use strict";
 
   /**
-   * Attaches the AJAX behavior to exposed filters forms and key View links.
+   * Attaches the AJAX behavior to Views exposed filter forms and key View
+   * links.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches ajaxView functionality to relevant elements.
    */
   Drupal.behaviors.ViewsAjaxView = {};
   Drupal.behaviors.ViewsAjaxView.attach = function () {
@@ -43,9 +41,7 @@
    * @constructor
    *
    * @param {object} settings
-   *   Settings object for the ajax view.
    * @param {string} settings.view_dom_id
-   *   The DOM id of the view.
    */
   Drupal.views.ajaxView = function (settings) {
     var selector = '.js-view-dom-id-' + settings.view_dom_id;
@@ -146,10 +142,8 @@
   /**
    * Attach the ajax behavior to a singe link.
    *
-   * @param {string} [id]
-   *   The ID of the link.
+   * @param {string} id
    * @param {HTMLElement} link
-   *   The link element.
    */
   Drupal.views.ajaxView.prototype.attachPagerLinkAjax = function (id, link) {
     var $link = $(link);
@@ -174,14 +168,10 @@
   };
 
   /**
-   * Views scroll to top ajax command.
    *
    * @param {Drupal.Ajax} [ajax]
-   *   A {@link Drupal.ajax} object.
    * @param {object} response
-   *   Ajax response.
    * @param {string} response.selector
-   *   Selector to use.
    */
   Drupal.AjaxCommands.prototype.viewsScrollTop = function (ajax, response) {
     // Scroll to the top of the view. This will allow users
diff --git a/core/modules/views/js/base.js b/core/modules/views/js/base.js
index 2fa7f79..d428229 100644
--- a/core/modules/views/js/base.js
+++ b/core/modules/views/js/base.js
@@ -16,10 +16,8 @@
    * Helper function to parse a querystring.
    *
    * @param {string} query
-   *   The querystring to parse.
    *
    * @return {object}
-   *   A map of query parameters.
    */
   Drupal.Views.parseQueryString = function (query) {
     var args = {};
@@ -43,12 +41,9 @@
    * Helper function to return a view's arguments based on a path.
    *
    * @param {string} href
-   *   The href to check.
    * @param {string} viewPath
-   *   The views path to check.
    *
    * @return {object}
-   *   An object containing `view_args` and `view_path`.
    */
   Drupal.Views.parseViewArgs = function (href, viewPath) {
     var returnObj = {};
@@ -66,10 +61,8 @@
    * Strip off the protocol plus domain from an href.
    *
    * @param {string} href
-   *   The href to strip.
    *
    * @return {string}
-   *   The href without the protocol and domain.
    */
   Drupal.Views.pathPortion = function (href) {
     // Remove e.g. http://example.com if present.
@@ -85,10 +78,8 @@
    * Return the Drupal path portion of an href.
    *
    * @param {string} href
-   *   The href to check.
    *
    * @return {string}
-   *   An internal path.
    */
   Drupal.Views.getPath = function (href) {
     href = Drupal.Views.pathPortion(href);
diff --git a/core/modules/views/js/views-contextual.js b/core/modules/views/js/views-contextual.js
index e6586eb..e0fe169 100644
--- a/core/modules/views/js/views-contextual.js
+++ b/core/modules/views/js/views-contextual.js
@@ -8,12 +8,8 @@
   "use strict";
 
   /**
-   * Attaches contextual region classes to views elements.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Adds class `contextual-region` to views elements.
    */
   Drupal.behaviors.viewsContextualLinks = {
     attach: function (context) {
diff --git a/core/modules/views/src/Plugin/views/PluginBase.php b/core/modules/views/src/Plugin/views/PluginBase.php
index 49b7f1d..4bad5f9 100644
--- a/core/modules/views/src/Plugin/views/PluginBase.php
+++ b/core/modules/views/src/Plugin/views/PluginBase.php
@@ -365,12 +365,6 @@ protected function viewsTokenReplace($text, $tokens) {
       if (strpos($token, '{{') !== FALSE) {
         // Twig wants a token replacement array stripped of curly-brackets.
         $token = trim(str_replace(array('{', '}'), '', $token));
-
-        // We need to validate tokens are valid Twig variables. Twig uses the
-        // same variable naming rules as PHP.
-        // @see http://php.net/manual/en/language.variables.basics.php
-        assert('preg_match(\'/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/\', $token) === 1', 'Tokens need to be valid Twig variables.');
-
         $twig_tokens[$token] = $replacement;
       }
       else {
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index 216a675..e4da10e 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -99,7 +99,7 @@ public function preview() {
     if (!empty($this->view->live_preview)) {
       $output = array(
         '#prefix' => '<pre>',
-        '#plain_text' => drupal_render_root($output),
+        '#markup' => SafeMarkup::checkPlain(drupal_render_root($output)),
         '#suffix' => '</pre>',
       );
     }
diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php
index e4e3b0a..251d025 100644
--- a/core/modules/views/src/Plugin/views/field/Field.php
+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\views\Plugin\views\field;
 
-use Drupal\Component\Utility\Xss;
+use Drupal\Component\Utility\Xss as CoreXss;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
@@ -670,7 +670,7 @@ public function renderItems($items) {
     if (!empty($items)) {
       $items = $this->prepareItemsByDelta($items);
       if ($this->options['multi_type'] == 'separator' || !$this->options['group_rows']) {
-        $separator = $this->options['multi_type'] == 'separator' ? Xss::filterAdmin($this->options['separator']) : '';
+        $separator = $this->options['multi_type'] == 'separator' ? CoreXss::filterAdmin($this->options['separator']) : '';
         $build = [
           '#type' => 'inline_template',
           '#template' => '{{ items | safe_join(separator) }}',
@@ -903,7 +903,7 @@ function render_item($count, $item) {
   protected function documentSelfTokens(&$tokens) {
     $field = $this->getFieldDefinition();
     foreach ($field->getColumns() as $id => $column) {
-      $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id));
+      $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = $this->t('Raw @column', array('@column' => $id));
     }
   }
 
@@ -913,29 +913,19 @@ protected function addSelfTokens(&$tokens, $item) {
       // Use \Drupal\Component\Utility\Xss::filterAdmin() because it's user data
       // and we can't be sure it is safe. We know nothing about the data,
       // though, so we can't really do much else.
-      if (isset($item['raw'])) {
-        $raw = $item['raw'];
-
-        if (is_array($raw)) {
-          if (isset($raw[$id]) && is_scalar($raw[$id])) {
-            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($raw[$id]);
-          }
-          else {
-            // Make sure that empty values are replaced as well.
-            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = '';
-          }
-        }
 
-        if (is_object($raw)) {
-          $property = $raw->get($id);
-          if (!empty($property)) {
-            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getValue());
-          }
-          else {
-            // Make sure that empty values are replaced as well.
-            $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = '';
-          }
-        }
+      if (isset($item['raw'])) {
+        // If $item['raw'] is an array then we can use as is, if it's an object
+        // we cast it to an array, if it's neither, we can't use it.
+        $raw = is_array($item['raw']) ? $item['raw'] :
+               (is_object($item['raw']) ? (array)$item['raw'] : NULL);
+      }
+      if (isset($raw) && isset($raw[$id]) && is_scalar($raw[$id])) {
+        $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = CoreXss::filterAdmin($raw[$id]);
+      }
+      else {
+        // Make sure that empty values are replaced as well.
+        $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = '';
       }
     }
   }
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 152d4e9..310997c 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -1676,11 +1676,10 @@ protected function getTokenValuesRecursive(array $array, array $parent_keys = ar
    * fields as a list. For example, the field that displays all terms
    * on a node might have tokens for the tid and the term.
    *
-   * By convention, tokens should follow the format of {{ token
-   * subtoken }}
+   * By convention, tokens should follow the format of {{ token-subtoken }}
    * where token is the field ID and subtoken is the field. If the
-   * field ID is terms, then the tokens might be {{ terms__tid }} and
-   * {{ terms__name }}.
+   * field ID is terms, then the tokens might be {{ terms-tid }} and
+   * {{ terms-name }}.
    */
   protected function addSelfTokens(&$tokens, $item) { }
 
diff --git a/core/modules/views/src/Plugin/views/query/Sql.php b/core/modules/views/src/Plugin/views/query/Sql.php
index c481a85..7ee7316 100644
--- a/core/modules/views/src/Plugin/views/query/Sql.php
+++ b/core/modules/views/src/Plugin/views/query/Sql.php
@@ -1454,7 +1454,7 @@ function execute(ViewExecutable $view) {
           drupal_set_message($e->getMessage(), 'error');
         }
         else {
-          throw new DatabaseExceptionWrapper("Exception in {$view->storage->label()}[{$view->storage->id()}]: {$e->getMessage()}");
+          throw new DatabaseExceptionWrapper("Exception in {$view->storage->label()}[$view->storage->id()]: {$e->getMessage()}");
         }
       }
 
diff --git a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
index 81b4505..98f3797 100644
--- a/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
+++ b/core/modules/views/src/Plugin/views/sort/SortPluginBase.php
@@ -220,6 +220,7 @@ public function buildExposeForm(&$form, FormStateInterface $form_state) {
    */
   public function defaultExposeOptions() {
     $this->options['expose'] = array(
+      'order' => $this->options['order'],
       'label' => $this->definition['title'],
     );
   }
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php b/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
index 0ab8409..01a66ec 100644
--- a/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldEntityLinkTest.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Session\AccountInterface;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\simpletest\UserCreationTrait;
-use Drupal\user\Entity\Role;
 use Drupal\views\Tests\ViewKernelTestBase;
 use Drupal\views\Views;
 
@@ -52,7 +51,6 @@ protected function setUpFixtures() {
 
     $this->installEntitySchema('user');
     $this->installEntitySchema('entity_test');
-    $this->installConfig(['user']);
 
     // Create some test entities.
     for ($i = 0; $i < 5; $i++) {
@@ -60,11 +58,7 @@ protected function setUpFixtures() {
     }
 
     // Create and admin user.
-    $this->adminUser = $this->createUser(['view test entity'], FALSE, TRUE);
-
-    Role::load(AccountInterface::ANONYMOUS_ROLE)
-      ->grantPermission('view test entity')
-      ->save();
+    $this->adminUser = $this->createUser([], FALSE, TRUE);
   }
 
   /**
diff --git a/core/modules/views/src/Tests/Plugin/PluginBaseTest.php b/core/modules/views/src/Tests/Plugin/PluginBaseTest.php
deleted file mode 100644
index f4b5c2d..0000000
--- a/core/modules/views/src/Tests/Plugin/PluginBaseTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views\Tests\Plugin\PluginBaseTest.
- */
-
-namespace Drupal\views\Tests\Plugin;
-
-use Drupal\Core\Render\RenderContext;
-use Drupal\Core\Render\SafeString;
-use Drupal\simpletest\KernelTestBase;
-use Drupal\views\Plugin\views\PluginBase;
-
-/**
- * Tests the PluginBase class.
- *
- * @group views
- */
-class PluginBaseTest extends KernelTestBase {
-
-  /**
-   * @var TestPluginBase
-   */
-  var $testPluginBase;
-
-  public function setUp() {
-    parent::setUp();
-    $this->testPluginBase = new TestPluginBase();
-  }
-
-  /**
-   * Test that the token replacement in views works correctly.
-   */
-  public function testViewsTokenReplace() {
-    $text = '{{ langcode__value }} means {{ langcode }}';
-    $tokens = ['{{ langcode }}' => SafeString::create('English'), '{{ langcode__value }}' => 'en'];
-
-    $result = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($text, $tokens) {
-      return $this->testPluginBase->viewsTokenReplace($text, $tokens);
-    });
-
-    $this->assertIdentical($result, 'en means English');
-  }
-
-}
-
-/**
- * Helper class for using the PluginBase abstract class.
- */
-class TestPluginBase extends PluginBase {
-
-  public function __construct() {
-    parent::__construct([], '', []);
-  }
-
-  public function viewsTokenReplace($text, $tokens) {
-    return parent::viewsTokenReplace($text, $tokens);
-  }
-
-}
diff --git a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php b/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
deleted file mode 100644
index aded838..0000000
--- a/core/modules/views/src/Tests/Plugin/ViewsSqlExceptionTest.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views\Tests\Plugin\ViewsSqlExceptionTest.
- */
-
-namespace Drupal\views\Tests\Plugin;
-
-use Drupal\views\Views;
-use Drupal\Core\Database\DatabaseExceptionWrapper;
-
-/**
- * Tests the views exception handling.
- *
- * @group views
- */
-class ViewsSqlExceptionTest extends PluginTestBase {
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = array('test_filter');
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->enableViewsTestModule();
-  }
-
-  /**
-   * Overrides Drupal\views\Tests\ViewTestBase::viewsData().
-   */
-  protected function viewsData() {
-    $data = parent::viewsData();
-    $data['views_test_data']['name']['filter']['id'] = 'test_exception_filter';
-
-    return $data;
-  }
-
-  /**
-   * Test for the SQL exception.
-   */
-  public function testSqlException() {
-    $view = Views::getView('test_filter');
-    $view->initDisplay();
-
-    // Adding a filter that will result in an invalid query.
-    $view->displayHandlers->get('default')->overrideOption('filters', array(
-      'test_filter' => array(
-        'id' => 'test_exception_filter',
-        'table' => 'views_test_data',
-        'field' => 'name',
-        'operator' => '=',
-        'value' => 'John',
-        'group' => 0,
-      ),
-    ));
-
-    try {
-      $this->executeView($view);
-      $this->fail('Expected exception not thrown.');
-    }
-    catch (DatabaseExceptionWrapper $e) {
-      $exception_assert_message = "Exception in {$view->storage->label()}[{$view->storage->id()}]";
-      $this->assertEqual(strstr($e->getMessage(), ':', TRUE), $exception_assert_message);
-    }
-  }
-
-}
diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/field/FieldTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/field/FieldTest.php
index 0f8feef..74d5d3d 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/field/FieldTest.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/field/FieldTest.php
@@ -46,7 +46,7 @@ public function getTestValue() {
    * Overrides Drupal\views\Plugin\views\field\FieldPluginBase::addSelfTokens().
    */
   protected function addSelfTokens(&$tokens, $item) {
-    $tokens['[test__token]'] = $this->getTestValue();
+    $tokens['[test-token]'] = $this->getTestValue();
   }
 
   /**
diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterExceptionTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterExceptionTest.php
deleted file mode 100644
index 05b3f36..0000000
--- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterExceptionTest.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_test_data\Plugin\views\filter\FilterExceptionTest.
- */
-
-namespace Drupal\views_test_data\Plugin\views\filter;
-
-use Drupal\views\Plugin\views\filter\FilterPluginBase;
-
-/**
- * Breaks the query with adding an invalid where expression.
- *
- * @ViewsFilter("test_exception_filter")
- */
-class FilterExceptionTest extends FilterPluginBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    $this->query->addWhereExpression(NULL, "syntax error");
-  }
-
-}
diff --git a/core/modules/views_ui/js/ajax.js b/core/modules/views_ui/js/ajax.js
index 1e37607..09a1c04 100644
--- a/core/modules/views_ui/js/ajax.js
+++ b/core/modules/views_ui/js/ajax.js
@@ -8,16 +8,11 @@
   "use strict";
 
   /**
-   * Ajax command for highlighting elements.
    *
    * @param {Drupal.Ajax} [ajax]
-   *   An Ajax object.
    * @param {object} response
-   *   The Ajax response.
    * @param {string} response.selector
-   *   The selector in question.
    * @param {number} [status]
-   *   The HTTP status code.
    */
   Drupal.AjaxCommands.prototype.viewsHighlight = function (ajax, response, status) {
     $('.hilited').removeClass('hilited');
@@ -25,16 +20,11 @@
   };
 
   /**
-   * Ajax command to show certain buttons in the views edit form.
    *
    * @param {Drupal.Ajax} [ajax]
-   *   An Ajax object.
    * @param {object} response
-   *   The Ajax response.
    * @param {bool} response.changed
-   *   Whether the state changed for the buttons or not.
    * @param {number} [status]
-   *   The HTTP status code.
    */
   Drupal.AjaxCommands.prototype.viewsShowButtons = function (ajax, response, status) {
     $('div.views-edit-view div.form-actions').removeClass('js-hide');
@@ -44,14 +34,10 @@
   };
 
   /**
-   * Ajax command for triggering preview.
    *
    * @param {Drupal.Ajax} [ajax]
-   *   An Ajax object.
    * @param {object} [response]
-   *   The Ajax response.
    * @param {number} [status]
-   *   The HTTP status code.
    */
   Drupal.AjaxCommands.prototype.viewsTriggerPreview = function (ajax, response, status) {
     if ($('input#edit-displays-live-preview').is(':checked')) {
@@ -60,18 +46,12 @@
   };
 
   /**
-   * Ajax command to replace the title of a page.
    *
    * @param {Drupal.Ajax} [ajax]
-   *   An Ajax object.
    * @param {object} response
-   *   The Ajax response.
    * @param {string} response.siteName
-   *   The site name.
    * @param {string} response.title
-   *   The new page title.
    * @param {number} [status]
-   *   The HTTP status code.
    */
   Drupal.AjaxCommands.prototype.viewsReplaceTitle = function (ajax, response, status) {
     var doc = document;
@@ -92,7 +72,6 @@
    * Get rid of irritating tabledrag messages.
    *
    * @return {Array}
-   *   An array of messages. Always empty array, to get rid of the messages.
    */
   Drupal.theme.tableDragChangedWarning = function () {
     return [];
@@ -102,10 +81,6 @@
    * Trigger preview when the "live preview" checkbox is checked.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior to trigger live preview if the live preview option is
-   *   checked.
    */
   Drupal.behaviors.livePreview = {
     attach: function (context) {
@@ -121,9 +96,6 @@
    * Sync preview display.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior to sync the preview display when needed.
    */
   Drupal.behaviors.syncPreviewDisplay = {
     attach: function (context) {
@@ -138,12 +110,8 @@
   };
 
   /**
-   * Ajax behaviors for the views_ui module.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches ajax behaviors to the elements with the classes in question.
    */
   Drupal.behaviors.viewsAjax = {
     collapseReplaced: false,
diff --git a/core/modules/views_ui/js/dialog.views.js b/core/modules/views_ui/js/dialog.views.js
index b68039a..6f22e7f 100644
--- a/core/modules/views_ui/js/dialog.views.js
+++ b/core/modules/views_ui/js/dialog.views.js
@@ -31,14 +31,8 @@
   }
 
   /**
-   * Functionality for views modals.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches modal functionality for views.
-   * @prop {Drupal~behaviorDetach} detach
-   *   Detaches the modal functionality.
    */
   Drupal.behaviors.viewsModalContent = {
     attach: function (context) {
diff --git a/core/modules/views_ui/js/views-admin.js b/core/modules/views_ui/js/views-admin.js
index f47f270..d16731f 100644
--- a/core/modules/views_ui/js/views-admin.js
+++ b/core/modules/views_ui/js/views-admin.js
@@ -16,9 +16,6 @@
    * Improve the user experience of the views edit interface.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches toggling of SQL rewrite warning on the corresponding checkbox.
    */
   Drupal.behaviors.viewsUiEditView = {
     attach: function () {
@@ -35,10 +32,6 @@
    * as page title and menu link.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior for prepopulating page title and menu links, based on
-   *   view name.
    */
   Drupal.behaviors.viewsUiAddView = {
     attach: function (context) {
@@ -149,18 +142,14 @@
     var self = this;
 
     /**
-     * Populate the target form field with the altered source field value.
      *
      * @return {*}
-     *   The result of the _populate call, which should be undefined.
      */
     this.populate = function () { return self._populate.call(self); };
 
     /**
-     * Stop prepopulating the form fields.
      *
      * @return {*}
-     *   The result of the _unbind call, which should be undefined.
      */
     this.unbind = function () { return self._unbind.call(self); };
 
@@ -185,7 +174,6 @@
      * Get the source form field value as altered by the passed-in parameters.
      *
      * @return {string}
-     *   The source form field value.
      */
     getTransliterated: function () {
       var from = this.source.val();
@@ -220,7 +208,6 @@
      * Bind event handlers to new form fields, after they're replaced via Ajax.
      *
      * @param {jQuery} $fields
-     *   Fields to rebind functionality to.
      */
     rebind: function ($fields) {
       this.target = $fields;
@@ -229,13 +216,8 @@
   });
 
   /**
-   * Adds functionality for the add item form.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the functionality in {@link Drupal.viewsUi.AddItemForm} to the
-   *   forms in question.
    */
   Drupal.behaviors.addItemForm = {
     attach: function (context) {
@@ -254,12 +236,10 @@
   };
 
   /**
-   * Constructs a new AddItemForm.
    *
    * @constructor
    *
    * @param {jQuery} $form
-   *   The form element used.
    */
   Drupal.viewsUi.AddItemForm = function ($form) {
 
@@ -284,10 +264,8 @@
   };
 
   /**
-   * Handles a checkbox check.
    *
    * @param {jQuery.Event} event
-   *   The event triggered.
    */
   Drupal.viewsUi.AddItemForm.prototype.handleCheck = function (event) {
     var $target = $(event.target);
@@ -333,9 +311,6 @@
    * tabs.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Fixes the input elements needed.
    */
   Drupal.behaviors.viewsUiRenderAddViewButton = {
     attach: function (context) {
@@ -384,10 +359,7 @@
   };
 
   /**
-   * Toggle menu visibility.
-   *
    * @param {jQuery} $trigger
-   *   The element where the toggle was triggered.
    *
    *
    * @note [@jessebeach] I feel like the following should be a more generic
@@ -400,13 +372,8 @@
   };
 
   /**
-   * Add search options to the views ui.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches {@link Drupal.viewsUi.OptionsSearch} to the views ui filter
-   *   options.
    */
   Drupal.behaviors.viewsUiSearchOptions = {
     attach: function (context) {
@@ -433,7 +400,6 @@
    * @constructor
    *
    * @param {jQuery} $form
-   *   The form element.
    */
   Drupal.viewsUi.OptionsSearch = function ($form) {
 
@@ -475,7 +441,6 @@
      *   shown and hidden depending on the user's search terms.
      *
      * @return {Array}
-     *   An array of all the filterable options.
      */
     getOptions: function ($allOptions) {
       var $label;
@@ -504,7 +469,6 @@
      * options.
      *
      * @param {jQuery.Event} event
-     *   The keyup event.
      */
     handleKeyup: function (event) {
       var found;
@@ -550,12 +514,8 @@
   });
 
   /**
-   * Preview functionality in the views edit form.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the preview functionality to the view edit form.
    */
   Drupal.behaviors.viewsUiPreview = {
     attach: function (context) {
@@ -584,14 +544,8 @@
   };
 
   /**
-   * Rearranges the filters.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attach handlers to make it possible to rearange the filters in the form
-   *   in question.
-   *   @see Drupal.viewsUi.RearrangeFilterHandler
    */
   Drupal.behaviors.viewsUiRearrangeFilter = {
     attach: function (context) {
@@ -614,9 +568,7 @@
    * @constructor
    *
    * @param {jQuery} $table
-   *   The table in the filter form.
    * @param {jQuery} $operator
-   *   The filter groups operator element.
    */
   Drupal.viewsUi.RearrangeFilterHandler = function ($table, $operator) {
 
@@ -736,7 +688,6 @@
      * Dynamically click the button that adds a new filter group.
      *
      * @param {jQuery.Event} event
-     *   The event triggered.
      */
     clickAddGroupButton: function (event) {
       // Due to conflicts between Drupal core's AJAX system and the Views AJAX
@@ -765,7 +716,6 @@
      * duplicate it between any subsequent groups.
      *
      * @return {jQuery}
-     *   An operator element.
      */
     duplicateGroupsOperator: function () {
       var dropdowns;
@@ -828,7 +778,6 @@
      * Forces all operator dropdowns to have the same value.
      *
      * @param {jQuery.Event} event
-     *   The event triggered.
      */
     operatorChangeHandler: function (event) {
       var $target = $(event.target);
@@ -855,13 +804,15 @@
        * - The operator cells that span multiple rows need their rowspan
        * attributes updated to reflect the number of rows in each group.
        * - The operator labels that are displayed next to each filter need to
-       * be redrawn, to account for the row's new location.
+       * be
+       *   redrawn, to account for the row's new location.
        */
       tableDrag.row.prototype.onSwap = function () {
         if (filterHandler.hasGroupOperator) {
           // Make sure the row that just got moved (this.group) is inside one
-          // of the filter groups (i.e. below an empty marker row or a
-          // draggable). If it isn't, move it down one.
+          // of
+          // the filter groups (i.e. below an empty marker row or a draggable).
+          // If it isn't, move it down one.
           var thisRow = $(this.group);
           var previousRow = thisRow.prev('tr');
           if (previousRow.length && !previousRow.hasClass('group-message') && !previousRow.hasClass('draggable')) {
@@ -996,9 +947,6 @@
    * Add a select all checkbox, which checks each checkbox at once.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches select all functionality to the views filter form.
    */
   Drupal.behaviors.viewsFilterConfigSelectAll = {
     attach: function (context) {
@@ -1030,9 +978,6 @@
    * Remove icon class from elements that are themed as buttons or dropbuttons.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Removes the icon class from certain views elements.
    */
   Drupal.behaviors.viewsRemoveIconClass = {
     attach: function (context) {
@@ -1044,9 +989,6 @@
    * Change "Expose filter" buttons into checkboxes.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Changes buttons into checkboxes via {@link Drupal.viewsUi.Checkboxifier}.
    */
   Drupal.behaviors.viewsUiCheckboxify = {
     attach: function (context, settings) {
@@ -1064,9 +1006,6 @@
    * selected widget for the exposed group.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Changes the default widget based on user input.
    */
   Drupal.behaviors.viewsUiChangeDefaultWidget = {
     attach: function (context) {
@@ -1117,7 +1056,6 @@
    * When the checkbox is checked or unchecked, simulate a button press.
    *
    * @param {jQuery.Event} e
-   *   The event triggered.
    */
   Drupal.viewsUi.Checkboxifier.prototype.clickHandler = function (e) {
     this.$button
@@ -1129,10 +1067,6 @@
    * Change the Apply button text based upon the override select state.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior to change the Apply button according to the current
-   *   state.
    */
   Drupal.behaviors.viewsUiOverrideSelect = {
     attach: function (context) {
@@ -1169,12 +1103,8 @@
   };
 
   /**
-   * Functionality for the remove link in the views UI.
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches behavior for the remove view and remove display links.
    */
   Drupal.behaviors.viewsUiHandlerRemoveLink = {
     attach: function (context) {
diff --git a/core/modules/views_ui/js/views_ui.listing.js b/core/modules/views_ui/js/views_ui.listing.js
index ee2199f..4c13d79 100644
--- a/core/modules/views_ui/js/views_ui.listing.js
+++ b/core/modules/views_ui/js/views_ui.listing.js
@@ -15,9 +15,6 @@
    * Source text:       .views-table-filter-text-source
    *
    * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches the filter functionality to the views admin text search field.
    */
   Drupal.behaviors.viewTableFilterByText = {
     attach: function (context, settings) {
diff --git a/core/modules/views_ui/src/Controller/ViewsUIController.php b/core/modules/views_ui/src/Controller/ViewsUIController.php
index 2837508..bed5aaa 100644
--- a/core/modules/views_ui/src/Controller/ViewsUIController.php
+++ b/core/modules/views_ui/src/Controller/ViewsUIController.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views_ui\Controller;
 
+use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Url;
 use Drupal\views\ViewExecutable;
@@ -88,7 +89,7 @@ public function reportFields() {
     $header = array(t('Field name'), t('Used in'));
     $rows = array();
     foreach ($fields as $field_name => $views) {
-      $rows[$field_name]['data'][0]['data']['#plain_text'] = $field_name;
+      $rows[$field_name]['data'][0] = SafeMarkup::checkPlain($field_name);
       foreach ($views as $view) {
         $rows[$field_name]['data'][1][] = $this->l($view, new Url('entity.view.edit_form', array('view' => $view)));
       }
diff --git a/core/modules/views_ui/src/Tests/ExposedFormUITest.php b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
index e42b822..b867a26 100644
--- a/core/modules/views_ui/src/Tests/ExposedFormUITest.php
+++ b/core/modules/views_ui/src/Tests/ExposedFormUITest.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\views_ui\Tests;
 
-use Drupal\views\Entity\View;
-
 /**
  * Tests exposed forms UI functionality.
  *
@@ -153,25 +151,5 @@ function testExposedAdminUi() {
     // Check the label of the expose button.
     $this->helperButtonHasLabel('edit-options-expose-button-button', t('Hide sort'));
     $this->assertFieldById('edit-options-expose-label', '', 'Make sure a label field is shown');
-
-    // Test adding a new exposed sort criteria.
-    $view_id = $this->randomView()['id'];
-    $this->drupalGet("admin/structure/views/nojs/add-handler/$view_id/default/sort");
-    $this->drupalPostForm(NULL, ['name[node_field_data.created]' => 1], t('Add and configure @handler', ['@handler' => t('sort criteria')]));
-    $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'ASC', 'The default order is set.');
-    // Change the order and expose the sort.
-    $this->drupalPostForm(NULL, ['options[order]' => 'DESC'], t('Apply'));
-    $this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/sort/created", [], t('Expose sort'));
-    $this->assertFieldByXPath('//input[@name="options[order]" and @checked="checked"]', 'DESC');
-    $this->assertFieldByName('options[expose][label]', 'Authored on', 'The default label is set.');
-    // Change the label and save the view.
-    $edit = ['options[expose][label]' => $this->randomString()];
-    $this->drupalPostForm(NULL, $edit, t('Apply'));
-    $this->drupalPostForm(NULL, [], t('Save'));
-    // Check that the values were saved.
-    $display = View::load($view_id)->getDisplay('default');
-    $this->assertTrue($display['display_options']['sorts']['created']['exposed']);
-    $this->assertEqual($display['display_options']['sorts']['created']['expose'], ['label' => $edit['options[expose][label]']]);
-    $this->assertEqual($display['display_options']['sorts']['created']['order'], 'DESC');
   }
 }
diff --git a/core/modules/views_ui/src/ViewListBuilder.php b/core/modules/views_ui/src/ViewListBuilder.php
index ece0acf..16abf60 100644
--- a/core/modules/views_ui/src/ViewListBuilder.php
+++ b/core/modules/views_ui/src/ViewListBuilder.php
@@ -102,7 +102,7 @@ public function buildRow(EntityInterface $view) {
         ),
         'description' => array(
           'data' => array(
-            '#plain_text' => $view->get('description'),
+            '#markup' => SafeMarkup::checkPlain($view->get('description')),
           ),
           'class' => array('views-table-filter-text-source'),
         ),
diff --git a/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php b/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php
index a23b690..d02deee 100644
--- a/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php
+++ b/core/tests/Drupal/Tests/Component/Plugin/DefaultFactoryTest.php
@@ -7,7 +7,11 @@
 
 namespace Drupal\Tests\Component\Plugin;
 
+use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
 use Drupal\Component\Plugin\Factory\DefaultFactory;
+use Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry;
+use Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface;
+use Drupal\plugin_test\Plugin\plugin_test\fruit\Kale;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -17,41 +21,110 @@
 class DefaultFactoryTest extends UnitTestCase {
 
   /**
-   * Tests getPluginClass() with a valid plugin.
+   * Tests getPluginClass() with a valid array plugin definition.
+   *
+   * @covers ::getPluginClass
    */
-  public function testGetPluginClassWithValidPlugin() {
-    $plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry';
+  public function testGetPluginClassWithValidArrayPluginDefinition() {
+    $plugin_class = Cherry::class;
     $class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class]);
 
     $this->assertEquals($plugin_class, $class);
   }
 
   /**
+   * Tests getPluginClass() with a valid object plugin definition.
+   *
+   * @covers ::getPluginClass
+   */
+  public function testGetPluginClassWithValidObjectPluginDefinition() {
+    $plugin_class = Cherry::class;
+    $plugin_definition = $this->getMock(PluginDefinitionInterface::class);
+    $plugin_definition->expects($this->atLeastOnce())
+      ->method('getClass')
+      ->willReturn($plugin_class);
+    $class = DefaultFactory::getPluginClass('cherry', $plugin_definition);
+
+    $this->assertEquals($plugin_class, $class);
+  }
+
+  /**
    * Tests getPluginClass() with a missing class definition.
    *
+   * @covers ::getPluginClass
+   *
    * @expectedException \Drupal\Component\Plugin\Exception\PluginException
    * @expectedExceptionMessage The plugin (cherry) did not specify an instance class.
    */
-  public function testGetPluginClassWithMissingClass() {
+  public function testGetPluginClassWithMissingClassWithArrayPluginDefinition() {
     DefaultFactory::getPluginClass('cherry', []);
   }
 
   /**
+   * Tests getPluginClass() with a missing class definition.
+   *
+   * @covers ::getPluginClass
+   *
+   * @expectedException \Drupal\Component\Plugin\Exception\PluginException
+   * @expectedExceptionMessage The plugin (cherry) did not specify an instance class.
+   */
+  public function testGetPluginClassWithMissingClassWithObjectPluginDefinition() {
+    $plugin_definition = $this->getMock(PluginDefinitionInterface::class);
+    DefaultFactory::getPluginClass('cherry', $plugin_definition);
+  }
+
+  /**
    * Tests getPluginClass() with a not existing class definition.
    *
+   * @covers ::getPluginClass
+   *
    * @expectedException \Drupal\Component\Plugin\Exception\PluginException
    * @expectedExceptionMessage Plugin (kiwifruit) instance class "\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit" does not exist.
    */
-  public function testGetPluginClassWithNotExistingClass() {
+  public function testGetPluginClassWithNotExistingClassWithArrayPluginDefinition() {
     DefaultFactory::getPluginClass('kiwifruit', ['class' => '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit']);
   }
 
   /**
+   * Tests getPluginClass() with a not existing class definition.
+   *
+   * @covers ::getPluginClass
+   *
+   * @expectedException \Drupal\Component\Plugin\Exception\PluginException
+   */
+  public function testGetPluginClassWithNotExistingClassWithObjectPluginDefinition() {
+    $plugin_class = '\Drupal\plugin_test\Plugin\plugin_test\fruit\Kiwifruit';
+    $plugin_definition = $this->getMock(PluginDefinitionInterface::class);
+    $plugin_definition->expects($this->atLeastOnce())
+      ->method('getClass')
+      ->willReturn($plugin_class);
+    DefaultFactory::getPluginClass('kiwifruit', $plugin_definition);
+  }
+
+  /**
+   * Tests getPluginClass() with a required interface.
+   *
+   * @covers ::getPluginClass
+   */
+  public function testGetPluginClassWithInterfaceWithArrayPluginDefinition() {
+    $plugin_class = Cherry::class;
+    $class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class], FruitInterface::class);
+
+    $this->assertEquals($plugin_class, $class);
+  }
+
+  /**
    * Tests getPluginClass() with a required interface.
+   *
+   * @covers ::getPluginClass
    */
-  public function testGetPluginClassWithInterface() {
-    $plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Cherry';
-    $class = DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class], '\Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface');
+  public function testGetPluginClassWithInterfaceWithObjectPluginDefinition() {
+    $plugin_class = Cherry::class;
+    $plugin_definition = $this->getMock(PluginDefinitionInterface::class);
+    $plugin_definition->expects($this->atLeastOnce())
+      ->method('getClass')
+      ->willReturn($plugin_class);
+    $class = DefaultFactory::getPluginClass('cherry', $plugin_definition, FruitInterface::class);
 
     $this->assertEquals($plugin_class, $class);
   }
@@ -59,12 +132,30 @@ public function testGetPluginClassWithInterface() {
   /**
    * Tests getPluginClass() with a required interface but no implementation.
    *
+   * @covers ::getPluginClass
+   *
+   * @expectedException \Drupal\Component\Plugin\Exception\PluginException
+   * @expectedExceptionMessage Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.
+   */
+  public function testGetPluginClassWithInterfaceAndInvalidClassWithArrayPluginDefinition() {
+    $plugin_class = Kale::class;
+    DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class, 'provider' => 'core'], FruitInterface::class);
+  }
+
+  /**
+   * Tests getPluginClass() with a required interface but no implementation.
+   *
+   * @covers ::getPluginClass
+   *
    * @expectedException \Drupal\Component\Plugin\Exception\PluginException
-   * @expectedExceptionMessage Plugin "cherry" (Drupal\plugin_test\Plugin\plugin_test\fruit\Kale) must implement interface \Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface.
    */
-  public function testGetPluginClassWithInterfaceAndInvalidClass() {
-    $plugin_class = 'Drupal\plugin_test\Plugin\plugin_test\fruit\Kale';
-    DefaultFactory::getPluginClass('cherry', ['class' => $plugin_class, 'provider' => 'core'], '\Drupal\plugin_test\Plugin\plugin_test\fruit\FruitInterface');
+  public function testGetPluginClassWithInterfaceAndInvalidClassWithObjectPluginDefinition() {
+    $plugin_class = Kale::class;
+    $plugin_definition = $this->getMock(PluginDefinitionInterface::class);
+    $plugin_definition->expects($this->atLeastOnce())
+      ->method('getClass')
+      ->willReturn($plugin_class);
+    DefaultFactory::getPluginClass('cherry', $plugin_definition, FruitInterface::class);
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
index ec83229..1278a6d 100644
--- a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
@@ -9,7 +9,6 @@
 
 use Drupal\Component\Utility\SafeMarkup;
 use Drupal\Component\Utility\SafeStringInterface;
-use Drupal\Component\Utility\SafeStringTrait;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -161,7 +160,7 @@ function providerCheckPlain() {
    *
    * @param string $string
    *   The string to run through SafeMarkup::format().
-   * @param string[] $args
+   * @param string $args
    *   The arguments to pass into SafeMarkup::format().
    * @param string $expected
    *   The expected result from calling the function.
@@ -170,14 +169,10 @@ function providerCheckPlain() {
    * @param bool $expected_is_safe
    *   Whether the result is expected to be safe for HTML display.
    */
-  public function testFormat($string, array $args, $expected, $message, $expected_is_safe) {
+  function testFormat($string, $args, $expected, $message, $expected_is_safe) {
     $result = SafeMarkup::format($string, $args);
     $this->assertEquals($expected, $result, $message);
     $this->assertEquals($expected_is_safe, SafeMarkup::isSafe($result), 'SafeMarkup::format correctly sets the result as safe or not safe.');
-
-    foreach ($args as $arg) {
-      $this->assertSame($arg instanceof SafeMarkupTestSafeString, SafeMarkup::isSafe($arg));
-    }
   }
 
   /**
@@ -197,6 +192,25 @@ function providerFormat() {
     return $tests;
   }
 
+  /**
+   * Tests the interaction between the safe list and XSS filtering.
+   *
+   * @covers ::escape
+   */
+  public function testAdminXss() {
+    // Mark the string as safe. This is for test purposes only.
+    $text = '<marquee>text</marquee>';
+    SafeMarkup::set($text);
+
+    // SafeMarkup::escape() will not escape the markup tag since the string was
+    // marked safe above.
+    $this->assertEquals('<marquee>text</marquee>', SafeMarkup::escape($text));
+
+    // SafeMarkup::checkPlain() will escape the markup tag even though the
+    // string was marked safe above.
+    $this->assertEquals('&lt;marquee&gt;text&lt;/marquee&gt;', SafeMarkup::checkPlain($text));
+  }
+
 }
 
 class SafeMarkupTestString {
@@ -220,5 +234,19 @@ public function __toString() {
  * SafeMarkup::set() is a global static that affects all tests.
  */
 class SafeMarkupTestSafeString implements SafeStringInterface {
-  use SafeStringTrait;
+
+  protected $string;
+
+  public function __construct($string) {
+    $this->string = $string;
+  }
+
+  public function __toString() {
+    return $this->string;
+  }
+
+  public static function create($string) {
+    $safe_string = new static($string);
+    return $safe_string;
+  }
 }
diff --git a/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
index 761fa69..6823dc1 100644
--- a/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/UrlHelperTest.php
@@ -380,10 +380,8 @@ public static function providerTestIsExternal() {
    */
   public function testFilterBadProtocol($uri, $expected, $protocols) {
     UrlHelper::setAllowedProtocols($protocols);
-    $this->assertEquals($expected, UrlHelper::filterBadProtocol($uri));
-    // Multiple calls to UrlHelper::filterBadProtocol() do not cause double
-    // escaping.
-    $this->assertEquals($expected, UrlHelper::filterBadProtocol(UrlHelper::filterBadProtocol($uri)));
+    $filtered = UrlHelper::filterBadProtocol($uri);
+    $this->assertEquals($expected, $filtered);
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php
index 157349d..0df17c4 100644
--- a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerBuilderTest.php
@@ -70,14 +70,4 @@ public function testRegisterException() {
     $container->register('Bar');
   }
 
-  /**
-   * Tests serialization.
-   *
-   * @expectedException \AssertionError
-   */
-  public function testSerialize() {
-    $container = new ContainerBuilder();
-    serialize($container);
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php
index ffbb591..377f7be 100644
--- a/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/ContainerTest.php
@@ -20,7 +20,7 @@ class ContainerTest extends UnitTestCase {
   /**
    * Tests serialization.
    *
-   * @expectedException \AssertionError
+   * @expectedException \PHPUnit_Framework_Error
    */
   public function testSerialize() {
     $container = new Container();
diff --git a/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
index 23a286c..0865933 100644
--- a/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
+++ b/core/tests/Drupal/Tests/Core/Entity/EntityAccessCheckTest.php
@@ -9,9 +9,6 @@
 
 use Drupal\Core\Cache\Context\CacheContextsManager;
 use Drupal\Core\DependencyInjection\Container;
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\node\NodeInterface;
 use Symfony\Component\HttpFoundation\ParameterBag;
 use Symfony\Component\Routing\Route;
 use Drupal\Core\Access\AccessResult;
@@ -21,67 +18,37 @@
 /**
  * Unit test of entity access checking system.
  *
- * @coversDefaultClass \Drupal\Core\Entity\EntityAccessCheck
- *
  * @group Access
  * @group Entity
  */
 class EntityAccessCheckTest extends UnitTestCase {
 
   /**
-   * {@inheritdoc}
+   * Tests the method for checking access to routes.
    */
-  protected function setUp() {
+  public function testAccess() {
     $cache_contexts_manager = $this->prophesize(CacheContextsManager::class)->reveal();
     $container = new Container();
     $container->set('cache_contexts_manager', $cache_contexts_manager);
     \Drupal::setContainer($container);
-  }
-
-  /**
-   * Tests the method for checking access to routes.
-   */
-  public function testAccess() {
-    $route = new Route('/foo/{var_name}', [], ['_entity_access' => 'var_name.update'], ['parameters' => ['var_name' => ['type' => 'entity:node']]]);
-    /** @var \Drupal\Core\Session\AccountInterface $account */
-    $account = $this->prophesize(AccountInterface::class)->reveal();
-
-    /** @var \Drupal\node\NodeInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
-    $node = $this->prophesize(NodeInterface::class);
-    $node->access('update', $account, TRUE)->willReturn(AccessResult::allowed());
-    $node = $node->reveal();
-
-    /** @var \Drupal\Core\Routing\RouteMatchInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
-    $route_match = $this->prophesize(RouteMatchInterface::class);
-    $route_match->getRawParameters()->willReturn(new ParameterBag(['var_name' => 1]));
-    $route_match->getParameters()->willReturn(new ParameterBag(['var_name' => $node]));
-    $route_match = $route_match->reveal();
-
-    $access_check = new EntityAccessCheck();
-    $this->assertEquals(AccessResult::allowed(), $access_check->access($route, $route_match, $account));
-  }
-
-  /**
-   * @covers ::access
-   */
-  public function testAccessWithTypePlaceholder() {
-    $route = new Route('/foo/{entity_type}/{var_name}', [], ['_entity_access' => 'var_name.update'], ['parameters' => ['var_name' => ['type' => 'entity:{entity_type}']]]);
-    /** @var \Drupal\Core\Session\AccountInterface $account */
-    $account = $this->prophesize(AccountInterface::class)->reveal();
-
-    /** @var \Drupal\node\NodeInterface|\Prophecy\Prophecy\ObjectProphecy $node */
-    $node = $this->prophesize(NodeInterface::class);
-    $node->access('update', $account, TRUE)->willReturn(AccessResult::allowed());
-    $node = $node->reveal();
-
-    /** @var \Drupal\Core\Routing\RouteMatchInterface|\Prophecy\Prophecy\ObjectProphecy $route_match */
-    $route_match = $this->prophesize(RouteMatchInterface::class);
-    $route_match->getRawParameters()->willReturn(new ParameterBag(['entity_type' => 'node', 'var_name' => 1]));
-    $route_match->getParameters()->willReturn(new ParameterBag(['entity_type' => 'node', 'var_name' => $node]));
-    $route_match = $route_match->reveal();
 
+    $route = new Route('/foo', array(), array('_entity_access' => 'node.update'));
+    $upcasted_arguments = new ParameterBag();
+    $route_match = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
+    $route_match->expects($this->once())
+      ->method('getParameters')
+      ->will($this->returnValue($upcasted_arguments));
+    $node = $this->getMockBuilder('Drupal\node\Entity\Node')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $node->expects($this->any())
+      ->method('access')
+      ->will($this->returnValue(AccessResult::allowed()->cachePerPermissions()));
     $access_check = new EntityAccessCheck();
-    $this->assertEquals(AccessResult::allowed(), $access_check->access($route, $route_match, $account));
+    $upcasted_arguments->set('node', $node);
+    $account = $this->getMock('Drupal\Core\Session\AccountInterface');
+    $access = $access_check->access($route, $route_match, $account);
+    $this->assertEquals(AccessResult::allowed()->cachePerPermissions(), $access);
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 86b1fcb..11f66ef 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -12,12 +12,10 @@
 use Drupal\Core\Access\AccessResultForbidden;
 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Form\EnforcedResponseException;
-use Drupal\Core\Form\FormBuilder;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Form\FormInterface;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
@@ -683,90 +681,6 @@ public function providerTestChildAccessInheritance() {
     return $data;
   }
 
-  /**
-   * @covers ::valueCallableIsSafe
-   *
-   * @dataProvider providerTestValueCallableIsSafe
-   */
-  public function testValueCallableIsSafe($callback, $expected) {
-    $method = new \ReflectionMethod(FormBuilder::class, 'valueCallableIsSafe');
-    $method->setAccessible(true);
-    $is_safe = $method->invoke($this->formBuilder, $callback);
-    $this->assertSame($expected, $is_safe);
-  }
-
-  public function providerTestValueCallableIsSafe() {
-    $data = [];
-    $data['string_no_slash'] = [
-      'Drupal\Core\Render\Element\Token::valueCallback',
-      TRUE,
-    ];
-    $data['string_with_slash'] = [
-      '\Drupal\Core\Render\Element\Token::valueCallback',
-      TRUE,
-    ];
-    $data['array_no_slash'] = [
-      ['Drupal\Core\Render\Element\Token', 'valueCallback'],
-      TRUE,
-    ];
-    $data['array_with_slash'] = [
-      ['\Drupal\Core\Render\Element\Token', 'valueCallback'],
-      TRUE,
-    ];
-    $data['closure'] = [
-      function () {},
-      FALSE,
-    ];
-    return $data;
-  }
-
-  /**
-   * @covers ::doBuildForm
-   *
-   * @dataProvider providerTestInvalidToken
-   */
-  public function testInvalidToken($expected, $valid_token, $user_is_authenticated) {
-    $form_token = 'the_form_token';
-    $form_id = 'test_form_id';
-
-    if (is_bool($valid_token)) {
-      $this->csrfToken->expects($this->any())
-        ->method('get')
-        ->willReturnArgument(0);
-      $this->csrfToken->expects($this->atLeastOnce())
-        ->method('validate')
-        ->will($this->returnValueMap([
-          [$form_token, $form_id, $valid_token],
-          [$form_id, $form_id, $valid_token],
-        ]));
-    }
-
-    $current_user = $this->prophesize(AccountInterface::class);
-    $current_user->isAuthenticated()->willReturn($user_is_authenticated);
-    $property = new \ReflectionProperty(FormBuilder::class, 'currentUser');
-    $property->setAccessible(TRUE);
-    $property->setValue($this->formBuilder, $current_user->reveal());
-
-    $expected_form = $form_id();
-    $form_arg = $this->getMockForm($form_id, $expected_form);
-
-    $form_state = new FormState();
-    $input['form_id'] = $form_id;
-    $input['form_token'] = $form_token;
-    $form_state->setUserInput($input);
-    $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
-    $this->assertSame($expected, $form_state->hasInvalidToken());
-  }
-
-  public function providerTestInvalidToken() {
-    $data = [];
-    $data['authenticated_invalid'] = [TRUE, FALSE, TRUE];
-    $data['authenticated_valid'] = [FALSE, TRUE, TRUE];
-    // If the user is not authenticated, we will not have a token.
-    $data['anonymous'] = [FALSE, NULL, FALSE];
-    return $data;
-  }
-
 }
 
 class TestForm implements FormInterface {
diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
index 83aec87..bbda6f8 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
@@ -209,7 +209,8 @@ protected function tearDown() {
    * Provides a mocked form object.
    *
    * @param string $form_id
-   *   The form ID to be used.
+   *   (optional) The form ID to be used. If none is provided, the form will be
+   *   set with no expectation about getFormId().
    * @param mixed $expected_form
    *   (optional) If provided, the expected form response for buildForm() to
    *   return. Defaults to NULL.
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/MachineNameTest.php b/core/tests/Drupal/Tests/Core/Render/Element/MachineNameTest.php
deleted file mode 100644
index 7546c27..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/MachineNameTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\MachineNameTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\MachineName;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\MachineName
- * @group Render
- */
-class MachineNameTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $input) {
-    $element = [];
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, MachineName::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [NULL, FALSE];
-    $data[] = [NULL, NULL];
-    $data[] = ['', ['test']];
-    $data[] = ['test', 'test'];
-    $data[] = ['123', 123];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/PasswordConfirmTest.php b/core/tests/Drupal/Tests/Core/Render/Element/PasswordConfirmTest.php
deleted file mode 100644
index 7f1e186..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/PasswordConfirmTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\PasswordConfirmTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\PasswordConfirm;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\PasswordConfirm
- * @group Render
- */
-class PasswordConfirmTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $element, $input) {
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, PasswordConfirm::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [['pass1' => '', 'pass2' => ''], [], NULL];
-    $data[] = [['pass1' => '', 'pass2' => ''], ['#default_value' => ['pass2' => 'value']], NULL];
-    $data[] = [['pass2' => 'value', 'pass1' => ''], ['#default_value' => ['pass2' => 'value']], FALSE];
-    $data[] = [['pass1' => '123456', 'pass2' => 'qwerty'], [], ['pass1' => '123456', 'pass2' => 'qwerty']];
-    $data[] = [['pass1' => '123', 'pass2' => '234'], [], ['pass1' => 123, 'pass2' => 234]];
-    $data[] = [['pass1' => '', 'pass2' => '234'], [], ['pass1' => ['array'], 'pass2' => 234]];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/PasswordTest.php b/core/tests/Drupal/Tests/Core/Render/Element/PasswordTest.php
deleted file mode 100644
index 7bb3053..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/PasswordTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\PasswordTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\Password;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\Password
- * @group Render
- */
-class PasswordTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $input) {
-    $element = [];
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, Password::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [NULL, FALSE];
-    $data[] = [NULL, NULL];
-    $data[] = ['', ['test']];
-    $data[] = ['test', 'test'];
-    $data[] = ['123', 123];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/TextareaTest.php b/core/tests/Drupal/Tests/Core/Render/Element/TextareaTest.php
deleted file mode 100644
index 2ebf419..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/TextareaTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\TextareaTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\Textarea;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\Textarea
- * @group Render
- */
-class TextareaTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $input) {
-    $element = [];
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, Textarea::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [NULL, FALSE];
-    $data[] = [NULL, NULL];
-    $data[] = ['', ['test']];
-    $data[] = ['test', 'test'];
-    $data[] = ['123', 123];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/TextfieldTest.php b/core/tests/Drupal/Tests/Core/Render/Element/TextfieldTest.php
deleted file mode 100644
index 7a1860b..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/TextfieldTest.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\TextfieldTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\Textfield;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\Textfield
- * @group Render
- */
-class TextfieldTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $input) {
-    $element = [];
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, Textfield::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [NULL, FALSE];
-    $data[] = [NULL, NULL];
-    $data[] = ['', ['test']];
-    $data[] = ['test', 'test'];
-    $data[] = ['123', 123];
-    $data[] = ['testwithnewline', "test\nwith\rnewline"];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Render/Element/TokenTest.php b/core/tests/Drupal/Tests/Core/Render/Element/TokenTest.php
deleted file mode 100644
index bd13966..0000000
--- a/core/tests/Drupal/Tests/Core/Render/Element/TokenTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\Render\Element\TokenTest.
- */
-
-namespace Drupal\Tests\Core\Render\Element;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\Token;
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\Core\Render\Element\Token
- * @group Render
- */
-class TokenTest extends UnitTestCase {
-
-  /**
-   * @covers ::valueCallback
-   *
-   * @dataProvider providerTestValueCallback
-   */
-  public function testValueCallback($expected, $input) {
-    $element = [];
-    $form_state = $this->prophesize(FormStateInterface::class)->reveal();
-    $this->assertSame($expected, Token::valueCallback($element, $input, $form_state));
-  }
-
-  /**
-   * Data provider for testValueCallback().
-   */
-  public function providerTestValueCallback() {
-    $data = [];
-    $data[] = [NULL, FALSE];
-    $data[] = [NULL, NULL];
-    $data[] = ['', ['test']];
-    $data[] = ['test', 'test'];
-    $data[] = ['123', 123];
-
-    return $data;
-  }
-
-}
diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
index de02997..e8718d5 100644
--- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
+++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php
@@ -7,9 +7,6 @@
 
 namespace Drupal\Tests\Core\Template;
 
-use Drupal\Component\Utility\SafeMarkup;
-use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Template\TwigEnvironment;
 use Drupal\Core\Template\TwigExtension;
 use Drupal\Tests\UnitTestCase;
 
@@ -127,31 +124,6 @@ public function testSafeStringEscaping() {
     $this->assertSame('&lt;script&gt;alert(&#039;here&#039;);&lt;/script&gt;', $twig_extension->escapeFilter($twig, $string_object, 'html', 'UTF-8', TRUE));
   }
 
-  /**
-   * @covers ::safeJoin
-   */
-  public function testSafeJoin() {
-    $renderer = $this->prophesize(RendererInterface::class);
-    $renderer->render(['#markup' => '<strong>will be rendered</strong>', '#printed' => FALSE])->willReturn('<strong>will be rendered</strong>');
-    $renderer = $renderer->reveal();
-
-    $twig_extension = new TwigExtension($renderer);
-    $twig_environment = $this->prophesize(TwigEnvironment::class)->reveal();
-
-
-    // Simulate t().
-    $string = '<em>will be markup</em>';
-    SafeMarkup::setMultiple([$string => ['html' => TRUE]]);
-
-    $items = [
-      '<em>will be escaped</em>',
-      $string,
-      ['#markup' => '<strong>will be rendered</strong>']
-    ];
-    $result = $twig_extension->safeJoin($twig_environment, $items, '<br/>');
-    $this->assertEquals('&lt;em&gt;will be escaped&lt;/em&gt;<br/><em>will be markup</em><br/><strong>will be rendered</strong>', $result);
-  }
-
 }
 
 class TwigExtensionTestString {
diff --git a/core/themes/bartik/templates/node.html.twig b/core/themes/bartik/templates/node.html.twig
index 7231922..25144bf 100644
--- a/core/themes/bartik/templates/node.html.twig
+++ b/core/themes/bartik/templates/node.html.twig
@@ -72,7 +72,6 @@
     'clearfix',
   ]
 %}
-{{ attach_library('classy/node') }}
 <article{{ attributes.addClass(classes) }}>
   <header>
     {{ title_prefix }}
diff --git a/core/themes/classy/classy.libraries.yml b/core/themes/classy/classy.libraries.yml
index af0f891..a5bde77 100644
--- a/core/themes/classy/classy.libraries.yml
+++ b/core/themes/classy/classy.libraries.yml
@@ -16,12 +16,6 @@ drupal.comment.threaded:
     theme:
       css/comment/comment.theme.css: {}
 
-node:
-  version: VERSION
-  css:
-    component:
-      css/components/node.css: { weight: -10 }
-
 search.results:
   version: VERSION
   css:
diff --git a/core/themes/classy/css/components/node.css b/core/themes/classy/css/components/node.css
deleted file mode 100644
index 6b7cd52..0000000
--- a/core/themes/classy/css/components/node.css
+++ /dev/null
@@ -1,8 +0,0 @@
-/**
- * @file
- * Visual styles for nodes.
- */
-
-.node--unpublished {
-  background-color: #fff4f4;
-}
diff --git a/core/themes/classy/templates/content/node.html.twig b/core/themes/classy/templates/content/node.html.twig
index 6afe7b5..5d746a6 100644
--- a/core/themes/classy/templates/content/node.html.twig
+++ b/core/themes/classy/templates/content/node.html.twig
@@ -75,7 +75,6 @@
     view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
   ]
 %}
-{{ attach_library('classy/node') }}
 <article{{ attributes.addClass(classes) }}>
 
   {{ title_prefix }}
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index 977f094..96d0124 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -151,3 +151,29 @@ function twig_without($element) {
   }
   return $filtered_element;
 }
+
+/**
+ * Overrides twig_join_filter().
+ *
+ * Safely joins several strings together.
+ *
+ * @param array|Traversable $value
+ *   The pieces to join.
+ * @param string $glue
+ *   The delimiter with which to join the string. Defaults to an empty string.
+ *   This value is expected to be safe for output and user provided data should
+ *   never be used as a glue.
+ *
+ * @return \Twig_Markup
+ *   The imploded string, which is wrapped in \Twig_Markup because it is safe.
+ */
+function twig_drupal_join_filter($value, $glue = '') {
+  $separator = '';
+  $output = '';
+  foreach ($value as $item) {
+    $output .= $separator . SafeMarkup::escape($item);
+    $separator = $glue;
+  }
+
+  return new \Twig_Markup($output, 'UTF-8');
+}
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index f590613..e3e76ad 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -612,8 +612,7 @@
  * specific pattern:
  * - $conf['system.performance']['fast_404']['exclude_paths']: A regular
  *   expression to match paths to exclude, such as images generated by image
- *   styles, or dynamically-resized images. The default pattern provided below
- *   also excludes the private file system. If you need to add more paths, you
+ *   styles, or dynamically-resized images. If you need to add more paths, you
  *   can add '|path' to the expression.
  * - $conf['system.performance']['fast_404']['paths']: A regular expression to
  *   match paths that should return a simple 404 page, rather than the fully
@@ -624,7 +623,7 @@
  *
  * Remove the leading hash signs if you would like to alter this functionality.
  */
-# $config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)|(?:system\/files)\//';
+# $config['system.performance']['fast_404']['exclude_paths'] = '/\/(?:styles)\//';
 # $config['system.performance']['fast_404']['paths'] = '/\.(?:txt|png|gif|jpe?g|css|js|ico|swf|flv|cgi|bat|pl|dll|exe|asp)$/i';
 # $config['system.performance']['fast_404']['html'] = '<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL "@path" was not found on this server.</p></body></html>';
 
