diff --git a/core/core.services.yml b/core/core.services.yml
index 1ee07fe..7d38991 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1259,7 +1259,7 @@ services:
       - { name: backend_overridable }
   plugin.manager.mail:
     class: Drupal\Core\Mail\MailManager
-    arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@config.factory', '@logger.factory', '@string_translation', '@renderer']
+    arguments: ['@container.namespaces', '@cache.discovery', '@module_handler', '@config.factory', '@logger.factory', '@string_translation']
   plugin.manager.condition:
     class: Drupal\Core\Condition\ConditionManager
     parent: default_plugin_manager
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 1019270..2b1fca2 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -2182,6 +2182,16 @@ function install_write_profile($install_state) {
       'value' => $install_state['parameters']['profile'],
       'required' => TRUE,
     );
+  }
+  // Add specified base_profile to the settings profile_directories.
+  if (!empty($install_state['profile_info']['base_profile']) && isset($install_state['profiles'][$install_state['profile_info']['base_profile']]) && empty(Settings::get('profile_directories'))) {
+    $path = $install_state['profiles'][$install_state['profile_info']['base_profile']]->getPath();
+    $settings['settings']['profile_directories'] = (object) array(
+      'value' => array($path),
+      'required' => TRUE,
+    );
+  }
+  if (!empty($settings)) {
     drupal_rewrite_settings($settings);
   }
 }
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 1c8068b..08826c3 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -744,6 +744,10 @@ protected function moduleData($module) {
       $profile_directories = array_map(function ($profile) {
         return $profile->getPath();
       }, $profiles);
+
+      // Allow additional profile directories to be added from settings.php.
+      // This provides support for "base profiles".
+      $profile_directories = array_merge(Settings::get('profile_directories', []), $profile_directories);
       $listing->setProfileDirectories($profile_directories);
 
       // Now find modules.
diff --git a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
index 337629b..83d0b6b 100644
--- a/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -16,6 +16,13 @@
  * $settings['extension_discovery_scan_tests'] = TRUE;
  * @endcode
  * to your settings.php.
+ *
+ * To add additional profile directories, add
+ * @code
+ * $settings['profile_directories'] = array(path);
+ * @encode
+ * to your settings.php.  If multiple paths are specified, they are searched
+ * from last to first.
  */
 class ExtensionDiscovery {
 
@@ -250,6 +257,11 @@ public function setProfileDirectoriesFromSettings() {
     if ($profile) {
       $this->profileDirectories[] = drupal_get_path('profile', $profile);
     }
+
+    // Allow additional profile directories to be added from settings.php.
+    // This provides support for "base profiles".
+    $this->profileDirectories = array_merge(Settings::get('profile_directories', []), $this->profileDirectories);
+
     return $this;
   }
 
diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php
index f86eac7..1df00cb 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldType/PasswordItem.php
@@ -28,8 +28,6 @@ public static function propertyDefinitions(FieldStorageDefinitionInterface $fiel
       ->setSetting('case_sensitive', TRUE);
     $properties['existing'] = DataDefinition::create('string')
       ->setLabel(new TranslatableMarkup('Existing password'));
-    $properties['pre_hashed'] = DataDefinition::create('boolean')
-      ->setLabel(new TranslatableMarkup('Determines if a password needs hashing'));
 
     return $properties;
   }
@@ -42,11 +40,8 @@ public function preSave() {
 
     $entity = $this->getEntity();
 
-    if ($this->pre_hashed) {
-      // Reset the pre_hashed value since it has now been used.
-      $this->pre_hashed = FALSE;
-    }
-    elseif ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
+    // Update the user password if it has changed.
+    if ($entity->isNew() || (strlen(trim($this->value)) > 0 && $this->value != $entity->original->{$this->getFieldDefinition()->getName()}->value)) {
       // Allow alternate password hashing schemes.
       $this->value = \Drupal::service('password')->hash(trim($this->value));
       // Abort if the hashing failed and returned FALSE.
diff --git a/core/lib/Drupal/Core/Mail/MailManager.php b/core/lib/Drupal/Core/Mail/MailManager.php
index 2abba6b..87ff04e 100644
--- a/core/lib/Drupal/Core/Mail/MailManager.php
+++ b/core/lib/Drupal/Core/Mail/MailManager.php
@@ -8,8 +8,6 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Render\RenderContext;
-use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\StringTranslation\TranslationInterface;
 
@@ -39,13 +37,6 @@ class MailManager extends DefaultPluginManager implements MailManagerInterface {
   protected $loggerFactory;
 
   /**
-   * The renderer.
-   *
-   * @var \Drupal\Core\Render\RendererInterface
-   */
-  protected $renderer;
-
-  /**
    * List of already instantiated mail plugins.
    *
    * @var array
@@ -68,17 +59,14 @@ class MailManager extends DefaultPluginManager implements MailManagerInterface {
    *   The logger channel factory.
    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
    *   The string translation service.
-   * @param \Drupal\Core\Render\RendererInterface $renderer
-   *   The renderer.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, TranslationInterface $string_translation, RendererInterface $renderer) {
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, TranslationInterface $string_translation) {
     parent::__construct('Plugin/Mail', $namespaces, $module_handler, 'Drupal\Core\Mail\MailInterface', 'Drupal\Core\Annotation\Mail');
     $this->alterInfo('mail_backend_info');
     $this->setCacheBackend($cache_backend, 'mail_backend_plugins');
     $this->configFactory = $config_factory;
     $this->loggerFactory = $logger_factory;
     $this->stringTranslation = $string_translation;
-    $this->renderer = $renderer;
   }
 
   /**
@@ -164,58 +152,6 @@ public function getInstance(array $options) {
    * {@inheritdoc}
    */
   public function mail($module, $key, $to, $langcode, $params = array(), $reply = NULL, $send = TRUE) {
-    // Mailing can invoke rendering (e.g., generating URLs, replacing tokens),
-    // but e-mails are not HTTP responses: they're not cached, they don't have
-    // attachments. Therefore we perform mailing inside its own render context,
-    // to ensure it doesn't leak into the render context for the HTTP response
-    // to the current request.
-    return $this->renderer->executeInRenderContext(new RenderContext(), function() use ($module, $key, $to, $langcode, $params, $reply, $send) {
-      return $this->doMail($module, $key, $to, $langcode, $params, $reply, $send);
-    });
-  }
-
-  /**
-   * Composes and optionally sends an email message.
-   *
-   * @param string $module
-   *   A module name to invoke hook_mail() on. The {$module}_mail() hook will be
-   *   called to complete the $message structure which will already contain
-   *   common defaults.
-   * @param string $key
-   *   A key to identify the email sent. The final message ID for email altering
-   *   will be {$module}_{$key}.
-   * @param string $to
-   *   The email address or addresses where the message will be sent to. The
-   *   formatting of this string will be validated with the
-   *   @link http://php.net/manual/filter.filters.validate.php PHP email validation filter. @endlink
-   *   Some examples are:
-   *   - user@example.com
-   *   - user@example.com, anotheruser@example.com
-   *   - User <user@example.com>
-   *   - User <user@example.com>, Another User <anotheruser@example.com>
-   * @param string $langcode
-   *   Language code to use to compose the email.
-   * @param array $params
-   *   (optional) Parameters to build the email.
-   * @param string|null $reply
-   *   Optional email address to be used to answer.
-   * @param bool $send
-   *   If TRUE, call an implementation of
-   *   \Drupal\Core\Mail\MailInterface->mail() to deliver the message, and
-   *   store the result in $message['result']. Modules implementing
-   *   hook_mail_alter() may cancel sending by setting $message['send'] to
-   *   FALSE.
-   *
-   * @return array
-   *   The $message array structure containing all details of the message. If
-   *   already sent ($send = TRUE), then the 'result' element will contain the
-   *   success indicator of the email, failure being already written to the
-   *   watchdog. (Success means nothing more than the message being accepted at
-   *   php-level, which still doesn't guarantee it to be delivered.)
-   *
-   * @see \Drupal\Core\Mail\MailManagerInterface::mail()
-   */
-  public function doMail($module, $key, $to, $langcode, $params = array(), $reply = NULL, $send = TRUE) {
     $site_config = $this->configFactory->get('system.site');
     $site_mail = $site_config->get('mail');
     if (empty($site_mail)) {
diff --git a/core/lib/Drupal/Core/Render/Element/Checkboxes.php b/core/lib/Drupal/Core/Render/Element/Checkboxes.php
index fe4a43b..8487a09 100644
--- a/core/lib/Drupal/Core/Render/Element/Checkboxes.php
+++ b/core/lib/Drupal/Core/Render/Element/Checkboxes.php
@@ -122,40 +122,4 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
     }
   }
 
-  /**
-   * Determines which checkboxes were checked when a form is submitted.
-   *
-   * @param array $input
-   *   An array returned by the FormAPI for a set of checkboxes.
-   *
-   * @return array
-   *   An array of keys that were checked.
-   */
-  public static function getCheckedCheckboxes(array $input) {
-    // Browsers do not include unchecked options in a form submission. The
-    // FormAPI tries to normalize this to keep checkboxes consistent with other
-    // form elements. Checkboxes show up as an array in the form of option_id =>
-    // option_id|0, where integer 0 is an unchecked option.
-    //
-    // @see \Drupal\Core\Render\Element\Checkboxes::valueCallback()
-    // @see https://www.w3.org/TR/html401/interact/forms.html#checkbox
-    $checked = array_filter($input, function($value) {
-      return $value !== 0;
-    });
-    return array_keys($checked);
-  }
-
-  /**
-   * Determines if all checkboxes in a set are unchecked.
-   *
-   * @param array $input
-   *   An array returned by the FormAPI for a set of checkboxes.
-   *
-   * @return bool
-   *   TRUE if all options are unchecked. FALSE otherwise.
-   */
-  public static function detectEmptyCheckboxes(array $input) {
-    return empty(static::getCheckedCheckboxes($input));
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Render/RenderContext.php b/core/lib/Drupal/Core/Render/RenderContext.php
index 0d79520..7c60c62 100644
--- a/core/lib/Drupal/Core/Render/RenderContext.php
+++ b/core/lib/Drupal/Core/Render/RenderContext.php
@@ -10,6 +10,8 @@
  * @see \Drupal\Core\Render\RendererInterface
  * @see \Drupal\Core\Render\Renderer
  * @see \Drupal\Core\Render\BubbleableMetadata
+ *
+ * @internal
  */
 class RenderContext extends \SplStack {
 
diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 6a58319..f29e146 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -272,11 +272,7 @@ public static function fromUri($uri, $options = []) {
     if ($uri_parts === FALSE) {
       throw new \InvalidArgumentException("The URI '$uri' is malformed.");
     }
-    // We support protocol-relative URLs.
-    if (strpos($uri, '//') === 0) {
-      $uri_parts['scheme'] = '';
-    }
-    elseif (empty($uri_parts['scheme'])) {
+    if (empty($uri_parts['scheme'])) {
       throw new \InvalidArgumentException("The URI '$uri' is invalid. You must use a valid URI scheme.");
     }
     $uri_parts += ['path' => ''];
diff --git a/core/modules/dblog/dblog.links.task.yml b/core/modules/dblog/dblog.links.task.yml
deleted file mode 100644
index 7098748..0000000
--- a/core/modules/dblog/dblog.links.task.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-dblog.view_logs:
-  title: 'View'
-  route_name: dblog.overview
-  base_route: dblog.overview
-dblog.clear_logs:
-  title: 'Delete'
-  route_name: dblog.confirm
-  base_route: dblog.overview
diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php
index 572b9ae..7c83cce 100644
--- a/core/modules/dblog/src/Controller/DbLogController.php
+++ b/core/modules/dblog/src/Controller/DbLogController.php
@@ -128,6 +128,7 @@ public function overview() {
     $this->moduleHandler->loadInclude('dblog', 'admin.inc');
 
     $build['dblog_filter_form'] = $this->formBuilder->getForm('Drupal\dblog\Form\DblogFilterForm');
+    $build['dblog_clear_log_form'] = $this->formBuilder->getForm('Drupal\dblog\Form\DblogClearLogForm');
 
     $header = array(
       // Icon column.
diff --git a/core/modules/dblog/src/Form/DblogClearLogForm.php b/core/modules/dblog/src/Form/DblogClearLogForm.php
new file mode 100644
index 0000000..134cfc1
--- /dev/null
+++ b/core/modules/dblog/src/Form/DblogClearLogForm.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\dblog\Form;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides the form that clears out the log.
+ */
+class DblogClearLogForm extends FormBase {
+
+  /**
+   * The database connection.
+   *
+   * @var \Drupal\Core\Database\Connection
+   */
+  protected $connection;
+
+  /**
+   * Constructs a new DblogClearLogForm.
+   *
+   * @param \Drupal\Core\Database\Connection $connection
+   *   The database connection.
+   */
+  public function __construct(Connection $connection) {
+    $this->connection = $connection;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('database')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'dblog_clear_log_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['dblog_clear'] = array(
+      '#type' => 'details',
+      '#title' => $this->t('Clear log messages'),
+      '#description' => $this->t('This will permanently remove the log messages from the database.'),
+    );
+    $form['dblog_clear']['clear'] = array(
+      '#type' => 'submit',
+      '#value' => $this->t('Clear log messages'),
+    );
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    $form_state->setRedirect('dblog.confirm');
+  }
+
+}
diff --git a/core/modules/dblog/src/Form/DblogFilterForm.php b/core/modules/dblog/src/Form/DblogFilterForm.php
index 0434f12..11bd54b 100644
--- a/core/modules/dblog/src/Form/DblogFilterForm.php
+++ b/core/modules/dblog/src/Form/DblogFilterForm.php
@@ -26,7 +26,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['filters'] = array(
       '#type' => 'details',
       '#title' => $this->t('Filter log messages'),
-      '#open' => TRUE,
+      '#open' => !empty($_SESSION['dblog_overview_filter']),
     );
     foreach ($filters as $key => $filter) {
       $form['filters']['status'][$key] = array(
diff --git a/core/modules/dblog/src/Tests/DbLogTest.php b/core/modules/dblog/src/Tests/DbLogTest.php
index 90cb6c2..1706645 100644
--- a/core/modules/dblog/src/Tests/DbLogTest.php
+++ b/core/modules/dblog/src/Tests/DbLogTest.php
@@ -221,32 +221,6 @@ private function generateLogEntries($count, $options = array()) {
   }
 
   /**
-   * Clear the entry logs by clicking on 'Clear log messages' button.
-   */
-  protected function clearLogsEntries() {
-    $this->drupalGet(Url::fromRoute('dblog.confirm'));
-  }
-
-  /**
-   * Filters the logs according to the specific severity and log entry type.
-   *
-   * @param string $type
-   *   (optional) The log entry type.
-   * @param string $severity
-   *   (optional) The log entry severity.
-  */
-  protected function filterLogsEntries($type = NULL, $severity = NULL) {
-     $edit = array();
-     if (!is_null($type)) {
-       $edit['type[]'] = $type;
-     }
-     if (!is_null($severity)) {
-       $edit['severity[]'] = $severity;
-     }
-     $this->drupalPostForm(NULL, $edit, t('Filter'));
-  }
-
-  /**
    * Confirms that database log reports are displayed at the correct paths.
    *
    * @param int $response
@@ -573,7 +547,7 @@ public function testDBLogAddAndClear() {
     // Log in the admin user.
     $this->drupalLogin($this->adminUser);
     // Post in order to clear the database table.
-    $this->clearLogsEntries();
+    $this->drupalPostForm('admin/reports/dblog', array(), t('Clear log messages'));
     // Confirm that the logs should be cleared.
     $this->drupalPostForm(NULL, array(), 'Confirm');
     // Count the rows in watchdog that previously related to the deleted user.
@@ -621,7 +595,10 @@ public function testFilter() {
     // Filter by each type and confirm that entries with various severities are
     // displayed.
     foreach ($type_names as $type_name) {
-      $this->filterLogsEntries($type_name);
+      $edit = array(
+        'type[]' => array($type_name),
+      );
+      $this->drupalPostForm(NULL, $edit, t('Filter'));
 
       // Count the number of entries of this type.
       $type_count = 0;
@@ -638,7 +615,11 @@ public function testFilter() {
     // Set the filter to match each of the two filter-type attributes and
     // confirm the correct number of entries are displayed.
     foreach ($types as $type) {
-      $this->filterLogsEntries($type['type'], $type['severity']);
+      $edit = array(
+        'type[]' => array($type['type']),
+        'severity[]' => array($type['severity']),
+      );
+      $this->drupalPostForm(NULL, $edit, t('Filter'));
 
       $count = $this->getTypeCount($types);
       $this->assertEqual(array_sum($count), $type['count'], 'Count matched');
@@ -649,7 +630,7 @@ public function testFilter() {
     $this->assertText(t('Operations'), 'Operations text found');
 
     // Clear all logs and make sure the confirmation message is found.
-    $this->clearLogsEntries();
+    $this->drupalPostForm('admin/reports/dblog', array(), t('Clear log messages'));
     // Confirm that the logs should be cleared.
     $this->drupalPostForm(NULL, array(), 'Confirm');
     $this->assertText(t('Database log cleared.'), 'Confirmation message found');
@@ -667,7 +648,7 @@ public function testFilter() {
    */
   protected function getLogEntries() {
     $entries = array();
-    if ($table = $this->getLogsEntriesTable()) {
+    if ($table = $this->xpath('.//table[@id="admin-dblog"]')) {
       $table = array_shift($table);
       foreach ($table->tbody->tr as $row) {
         $entries[] = array(
@@ -682,16 +663,6 @@ protected function getLogEntries() {
   }
 
   /**
-   * Find the Logs table in the DOM.
-   *
-   * @return \SimpleXMLElement[]
-   *   The return value of a xpath search.
-   */
-  protected function getLogsEntriesTable() {
-    return $this->xpath('.//table[@id="admin-dblog"]');
-  }
-
-  /**
    * Gets the count of database log entries by database log event type.
    *
    * @param array $types
diff --git a/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php b/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
index 9a41f6b..4de9eca 100644
--- a/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
+++ b/core/modules/editor/src/Tests/QuickEditIntegrationLoadingTest.php
@@ -102,7 +102,7 @@ public function testUserWithPermission() {
     // Ensure the text is transformed.
     $this->assertRaw('<p>Do you also love Drupal?</p><figure role="group" class="caption caption-img"><img src="druplicon.png" /><figcaption>Druplicon</figcaption></figure>');
 
-    $response = $this->drupalPost('editor/' . 'node/1/body/en/full', '', [], ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('editor/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', array());
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The untransformed text POST request results in one AJAX command.');
diff --git a/core/modules/file/css/file.admin.css b/core/modules/file/css/file.admin.css
new file mode 100644
index 0000000..6a45644
--- /dev/null
+++ b/core/modules/file/css/file.admin.css
@@ -0,0 +1,18 @@
+/**
+ * @file
+ * Admin stylesheet for file module.
+ */
+
+/* File upload widget.*/
+.form-managed-file .form-submit {
+  margin: 0 0.5em;
+}
+.form-managed-file div.ajax-progress-bar {
+  display: none;
+  margin-top: 4px;
+  padding: 0;
+  width: 28em;
+}
+.form-managed-file .ajax-progress-bar .bar {
+  margin: 0;
+}
diff --git a/core/modules/file/file.libraries.yml b/core/modules/file/file.libraries.yml
index def38d9..ccc0c3b 100644
--- a/core/modules/file/file.libraries.yml
+++ b/core/modules/file/file.libraries.yml
@@ -2,6 +2,9 @@ drupal.file:
   version: VERSION
   js:
     file.js: {}
+  css:
+    theme:
+      css/file.admin.css: {}
   dependencies:
     - core/jquery
     - core/jquery.once
diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
index 2797b6c..fb307f0 100644
--- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php
+++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php
@@ -40789,7 +40789,7 @@
 ->values(array(
   'uid' => '2',
   'name' => 'Odo',
-  'pass' => '$S$DGFZUE.FhrXbe4y52eC7p0ZVRGD/gOPtVctDlmC89qkujnBokAlJ',
+  'pass' => '$S$DZ4P7zZOh92vgrgZDBbv8Pu6lQB337OJ1wsOy21602G4A5F7.M9K',
   'mail' => 'odo@local.host',
   'theme' => '',
   'signature' => '',
diff --git a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php
index ea0b588..d073c18 100644
--- a/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/src/Tests/d6/MigrateUpgrade6Test.php
@@ -3,7 +3,6 @@
 namespace Drupal\migrate_drupal_ui\Tests\d6;
 
 use Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase;
-use Drupal\user\Entity\User;
 
 /**
  * Tests Drupal 6 upgrade using the migrate UI.
@@ -71,16 +70,4 @@ protected function getEntityCounts() {
     ];
   }
 
-  /**
-   * Executes all steps of migrations upgrade.
-   */
-  protected function testMigrateUpgrade() {
-    parent::testMigrateUpgrade();
-
-    // Ensure migrated users can log in.
-    $user = User::load(2);
-    $user->pass_raw = 'john.doe_pass';
-    $this->drupalLogin($user);
-  }
-
 }
diff --git a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php
index 1d3ce61..084f8ba 100644
--- a/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/src/Tests/d7/MigrateUpgrade7Test.php
@@ -3,7 +3,6 @@
 namespace Drupal\migrate_drupal_ui\Tests\d7;
 
 use Drupal\migrate_drupal_ui\Tests\MigrateUpgradeTestBase;
-use Drupal\user\Entity\User;
 
 /**
  * Tests Drupal 7 upgrade using the migrate UI.
@@ -71,16 +70,4 @@ protected function getEntityCounts() {
     ];
   }
 
-  /**
-   * Executes all steps of migrations upgrade.
-   */
-  protected function testMigrateUpgrade() {
-    parent::testMigrateUpgrade();
-
-    // Ensure migrated users can log in.
-    $user = User::load(2);
-    $user->pass_raw = 'a password';
-    $this->drupalLogin($user);
-  }
-
 }
diff --git a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
index 1eedb1c..aa46a77 100644
--- a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\quickedit\Tests;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Language\LanguageInterface;
 use Drupal\field\Tests\EntityReference\EntityReferenceTestTrait;
@@ -131,7 +130,7 @@ public function testAutocompleteQuickEdit() {
 
     $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full';
     $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post);
     $ajax_commands = Json::decode($response);
 
     // Prepare form values for submission. drupalPostAJAX() is not suitable for
@@ -149,7 +148,7 @@ public function testAutocompleteQuickEdit() {
       );
 
       // Submit field form and check response. Should render back all the terms.
-      $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->setRawContent($ajax_commands[0]['data']);
@@ -162,7 +161,7 @@ public function testAutocompleteQuickEdit() {
       // PrivateTempStore.
       $quickedit_uri = 'quickedit/form/node/' . $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full';
       $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData();
-      $response = $this->drupalPost($quickedit_uri, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post);
       $ajax_commands = Json::decode($response);
 
       // The AjaxResponse's first command is an InsertCommand which contains
diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
index 2a91fec..78c4d5b 100644
--- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -188,7 +188,7 @@ public function testUserWithPermission() {
     //  1. a settings command with useless metadata: AjaxController is dumb
     //  2. an insert command that loads the required in-place editors
     $post = array('editors[0]' => 'form') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost('quickedit/attachments', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('quickedit/attachments', 'application/vnd.drupal-ajax', $post);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(2, count($ajax_commands), 'The attachments HTTP request results in two AJAX commands.');
     // First command: settings.
@@ -200,7 +200,7 @@ public function testUserWithPermission() {
     // Retrieving the form for this field should result in a 200 response,
     // containing only a quickeditFieldForm command.
     $post = array('nocssjs' => 'true', 'reset' => 'true') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -228,7 +228,7 @@ public function testUserWithPermission() {
 
       // Submit field form and check response. This should store the updated
       // entity in PrivateTempStore on the server.
-      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -270,7 +270,7 @@ public function testUserWithPermission() {
 
       // Retrieve field form.
       $post = array('nocssjs' => 'true', 'reset' => 'true');
-      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -287,7 +287,7 @@ public function testUserWithPermission() {
         'form_build_id' => $build_id_match[1],
       );
       $post += $edit + $this->getAjaxPageStatePostData();
-      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -345,7 +345,7 @@ public function testTitleBaseField() {
     // Retrieving the form for this field should result in a 200 response,
     // containing only a quickeditFieldForm command.
     $post = array('nocssjs' => 'true', 'reset' => 'true') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', 'application/vnd.drupal-ajax', $post);
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -372,7 +372,7 @@ public function testTitleBaseField() {
 
       // Submit field form and check response. This should store the
       // updated entity in PrivateTempStore on the server.
-      $response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -424,7 +424,7 @@ public function testCustomPipeline() {
 
     // Request editing to render results with the custom render pipeline.
     $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost($custom_render_url, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost($custom_render_url, 'application/vnd.drupal-ajax', $post);
     $ajax_commands = Json::decode($response);
 
     // Prepare form values for submission. drupalPostAJAX() is not suitable for
@@ -448,7 +448,7 @@ public function testCustomPipeline() {
 
       // Submit field form and check response. Should render with the custom
       // render pipeline.
-      $response = $this->drupalPost($custom_render_url, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost($custom_render_url, 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(1, count($ajax_commands), 'The field form HTTP request results in one AJAX command.');
@@ -468,7 +468,7 @@ public function testConcurrentEdit() {
     $this->drupalLogin($this->editorUser);
 
     $post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
 
@@ -496,7 +496,7 @@ public function testConcurrentEdit() {
 
       // Submit field form and check response. Should throw a validation error
       // because the node was changed in the meantime.
-      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+      $response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
       $this->assertResponse(200);
       $ajax_commands = Json::decode($response);
       $this->assertIdentical(2, count($ajax_commands), 'The field form HTTP request results in two AJAX commands.');
@@ -560,7 +560,7 @@ public function testImageField() {
     ], t('Save'));
 
     // The image field form should load normally.
-    $response = $this->drupalPost('quickedit/form/node/1/field_image/en/full', '', ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData(), ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('quickedit/form/node/1/field_image/en/full', 'application/vnd.drupal-ajax', ['nocssjs' => 'true'] + $this->getAjaxPageStatePostData());
     $this->assertResponse(200);
     $ajax_commands = Json::decode($response);
     $this->assertIdentical('<form ', Unicode::substr($ajax_commands[0]['data'], 0, 6), 'The quickeditFieldForm command contains a form.');
diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
index bc6f053..a884342 100644
--- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
+++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\rest\Tests\Views;
 
 use Drupal\Core\Cache\Cache;
-use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\entity_test\Entity\EntityTest;
 use Drupal\field\Entity\FieldConfig;
@@ -501,7 +500,8 @@ public function testFieldRawOutput() {
   public function testLivePreview() {
     // We set up a request so it looks like an request in the live preview.
     $request = new Request();
-    $request->query->add([MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']);
+    $request->setFormat('drupal_ajax', 'application/vnd.drupal-ajax');
+    $request->headers->set('Accept', 'application/vnd.drupal-ajax');
       /** @var \Symfony\Component\HttpFoundation\RequestStack $request_stack */
     $request_stack = \Drupal::service('request_stack');
     $request_stack->push($request);
diff --git a/core/modules/system/css/components/container-inline.module.css b/core/modules/system/css/components/container-inline.module.css
index ba99a36..b68da65 100644
--- a/core/modules/system/css/components/container-inline.module.css
+++ b/core/modules/system/css/components/container-inline.module.css
@@ -5,7 +5,7 @@
 
 .container-inline div,
 .container-inline label {
-  display: inline-block;
+  display: inline;
 }
 /* Details contents always need to be rendered as block. */
 .container-inline .details-wrapper {
diff --git a/core/modules/system/tests/src/Kernel/System/ExtensionDiscoveryProfilesTest.php b/core/modules/system/tests/src/Kernel/System/ExtensionDiscoveryProfilesTest.php
new file mode 100644
index 0000000..9f0c03a
--- /dev/null
+++ b/core/modules/system/tests/src/Kernel/System/ExtensionDiscoveryProfilesTest.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\Tests\system\Kernel\System;
+
+use Drupal\Core\Extension\ExtensionDiscovery;
+use Drupal\Core\Site\Settings;
+use Drupal\KernelTests\KernelTestBase;
+use org\bovigo\vfs\vfsStream;
+use Symfony\Component\Yaml\Yaml;
+
+/**
+ * Tests setting profileDirectories from settings.
+ *
+ * @group Common
+ */
+class ExtensionDiscoveryProfilesTest extends KernelTestBase {
+  /**
+   * Tests that files in different directories take precedence as expected.
+   */
+  function testDirectoryPrecedence() {
+    // Set up the file system.
+    $filesystem = [];
+    $files_by_type_and_name_expected = $this->populateFilesystemStructure($filesystem);
+
+    $vfs = vfsStream::setup('root', NULL, $filesystem);
+    $root = $vfs->url();
+
+    // Define the module files we will search for, and the directory precedence
+    // we expect.
+    $expected_directories = array(
+      // When both copies of the module are compatible with Drupal core, the
+      // copy in the profile directory takes precedence.
+      'drupal_system_listing_compatible_test' => array(
+        'core/profiles/testing/modules',
+        'core/modules/system/tests/modules',
+      ),
+    );
+
+    // This test relies on two versions of the same module existing in
+    // different places in the filesystem. Without that, the test has no
+    // meaning, so assert their presence first.
+    foreach ($expected_directories as $module => $directories) {
+      foreach ($directories as $directory) {
+        $filename = "$directory/$module/$module.info.yml";
+        $this->assertFileExists($root . $filename);
+      }
+    }
+
+    // Now add the testing profile path to settings.
+    $settings = Settings::getAll();
+    $settings['profile_directories'] = array (
+      0 => 'core/profiles/testing',
+    );
+    new Settings($settings);
+
+    // Now scan the directories and check that the files take precedence as
+    // expected.
+    $listing = new ExtensionDiscovery($root);
+    $files = $listing->scan('module');
+    foreach ($expected_directories as $module => $directories) {
+      $expected_directory = array_shift($directories);
+      $expected_uri = "$expected_directory/$module/$module.info.yml";
+      $this->assertEqual($files[$module]->getPathname(), $expected_uri, format_string('Module @actual was found at @expected.', array(
+        '@actual' => $files[$module]->getPathname(),
+        '@expected' => $expected_uri,
+      )));
+    }
+  }
+}
diff --git a/core/modules/user/src/MigratePassword.php b/core/modules/user/src/MigratePassword.php
new file mode 100644
index 0000000..4116c16
--- /dev/null
+++ b/core/modules/user/src/MigratePassword.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Drupal\user;
+
+use Drupal\Core\Password\PasswordInterface;
+
+/**
+ * Replaces the original 'password' service in order to prefix the MD5 re-hashed
+ * passwords with the 'U' flag. The new salted hash is recreated on first login
+ * similarly to the D6->D7 upgrade path.
+ */
+class MigratePassword implements PasswordInterface {
+
+  /**
+   * The original password service.
+   *
+   * @var \Drupal\Core\Password\PasswordInterface
+   */
+  protected $originalPassword;
+
+  /**
+   * Indicates if MD5 password prefixing is enabled.
+   */
+  protected $enabled = FALSE;
+
+  /**
+   * Builds the replacement password service class.
+   *
+   * @param \Drupal\Core\Password\PasswordInterface $original_password
+   *   The password object.
+   */
+  public function __construct(PasswordInterface $original_password) {
+    $this->originalPassword = $original_password;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function check($password, $hash) {
+    return $this->originalPassword->check($password, $hash);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function needsRehash($hash) {
+    return $this->originalPassword->needsRehash($hash);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hash($password) {
+    $hash = $this->originalPassword->hash($password);
+
+    // Allow prefixing only if the service was asked to prefix. Check also if
+    // the $password pattern is conforming to a MD5 result.
+    if ($this->enabled && preg_match('/^[0-9a-f]{32}$/', $password)) {
+      $hash = 'U' . $hash;
+    }
+
+    return $hash;
+  }
+
+  /**
+   * Enables the MD5 password prefixing.
+   */
+  public function enableMd5Prefixing() {
+    $this->enabled = TRUE;
+  }
+
+  /**
+   * Disables the MD5 password prefixing.
+   */
+  public function disableMd5Prefixing() {
+    $this->enabled = FALSE;
+  }
+
+  /**
+   * Implements the PhpassHashedPassword::getCountLog2() method.
+   *
+   * @todo: Revisit this whole alternate password service:
+   *   https://www.drupal.org/node/2540594.
+   */
+  public function getCountLog2($setting) {
+    return $this->originalPassword->getCountLog2($setting);
+  }
+
+}
diff --git a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
index 6ec88ad..4187121 100644
--- a/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
+++ b/core/modules/user/src/Plugin/migrate/destination/EntityUser.php
@@ -3,13 +3,14 @@
 namespace Drupal\user\Plugin\migrate\destination;
 
 use Drupal\Component\Utility\Unicode;
-use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\Field\FieldTypePluginManagerInterface;
 use Drupal\Core\Field\Plugin\Field\FieldType\EmailItem;
 use Drupal\Core\Password\PasswordInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
+use Drupal\migrate\MigrateException;
+use Drupal\user\MigratePassword;
 use Drupal\migrate\Plugin\migrate\destination\EntityContentBase;
 use Drupal\migrate\Row;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -54,7 +55,9 @@ class EntityUser extends EntityContentBase {
    */
   public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityManagerInterface $entity_manager, FieldTypePluginManagerInterface $field_type_manager, PasswordInterface $password) {
     parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_manager, $field_type_manager);
-    $this->password = $password;
+    if (isset($configuration['md5_passwords'])) {
+      $this->password = $password;
+    }
   }
 
   /**
@@ -80,29 +83,24 @@ public static function create(ContainerInterface $container, array $configuratio
    * @throws \Drupal\migrate\MigrateException
    */
   public function import(Row $row, array $old_destination_id_values = array()) {
+    if ($this->password) {
+      if ($this->password instanceof MigratePassword) {
+        $this->password->enableMd5Prefixing();
+      }
+      else {
+        throw new MigrateException('Password service has been altered by another module, aborting.');
+      }
+    }
     // Do not overwrite the root account password.
     if ($row->getDestinationProperty('uid') == 1) {
       $row->removeDestinationProperty('pass');
     }
-    return parent::import($row, $old_destination_id_values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function save(ContentEntityInterface $entity, array $old_destination_id_values = array()) {
-    // Do not overwrite the root account password.
-    if ($entity->id() != 1) {
-      // Set the pre_hashed password so that the PasswordItem field does not hash
-      // already hashed passwords. If the md5_passwords configuration option is
-      // set we need to rehash the password and prefix with a U.
-      // @see \Drupal\Core\Field\Plugin\Field\FieldType\PasswordItem::preSave()
-      $entity->pass->pre_hashed = TRUE;
-      if (isset($this->configuration['md5_passwords'])) {
-        $entity->pass->value = 'U' . $this->password->hash($entity->pass->value);
-      }
+    $ids = parent::import($row, $old_destination_id_values);
+    if ($this->password) {
+      $this->password->disableMd5Prefixing();
     }
-    return parent::save($entity, $old_destination_id_values);
+
+    return $ids;
   }
 
   /**
diff --git a/core/modules/user/src/UserServiceProvider.php b/core/modules/user/src/UserServiceProvider.php
new file mode 100644
index 0000000..ae3c7ed
--- /dev/null
+++ b/core/modules/user/src/UserServiceProvider.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace Drupal\user;
+
+use Drupal\Core\DependencyInjection\ServiceModifierInterface;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+
+/**
+ * Swaps the original 'password' service in order to handle password hashing for
+ * user migrations that have passwords hashed to MD5.
+ *
+ * @see \Drupal\migrate\MigratePassword
+ * @see \Drupal\Core\Password\PhpassHashedPassword
+ */
+class UserServiceProvider implements ServiceModifierInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function alter(ContainerBuilder $container) {
+    $container->setDefinition('password_original', $container->getDefinition('password'));
+    $container->setDefinition('password', $container->getDefinition('password_migrate'));
+  }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php
index 2e0965d..61ff800 100644
--- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php
+++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php
@@ -44,8 +44,6 @@ protected function setUp() {
    *   The username.
    * @param string $mail
    *   The user's email address.
-   * @param string $password
-   *   The password for this user.
    * @param int $access
    *   The last access time.
    * @param int $login
@@ -61,7 +59,7 @@ protected function setUp() {
    * @param bool $has_picture
    *   Whether the user is expected to have a picture attached.
    */
-  protected function assertEntity($id, $label, $mail, $password, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) {
+  protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) {
     /** @var \Drupal\user\UserInterface $user */
     $user = User::load($id);
     $this->assertTrue($user instanceof UserInterface);
@@ -79,29 +77,13 @@ protected function assertEntity($id, $label, $mail, $password, $access, $login,
     $this->assertIdentical($init, $user->getInitialEmail());
     $this->assertIdentical($roles, $user->getRoles());
     $this->assertIdentical($has_picture, !$user->user_picture->isEmpty());
-    $this->assertIdentical($password, $user->getPassword());
   }
 
   /**
    * Tests the Drupal 7 user to Drupal 8 migration.
    */
   public function testUser() {
-    $password = '$S$DGFZUE.FhrXbe4y52eC7p0ZVRGD/gOPtVctDlmC89qkujnBokAlJ';
-    $this->assertEntity(2, 'Odo', 'odo@local.host', $password, '0', '0', FALSE, '', 'odo@local.host');
-
-    // Ensure that the user can authenticate.
-    $this->assertEquals(2, \Drupal::service('user.auth')->authenticate('Odo', 'a password'));
-    // After authenticating the password will be rehashed because the password
-    // stretching iteration count has changed from 15 in Drupal 7 to 16 in
-    // Drupal 8.
-    $user = User::load(2);
-    $rehash = $user->getPassword();
-    $this->assertNotEquals($password, $rehash);
-
-    // Authenticate again and there should be no re-hash.
-    $this->assertEquals(2, \Drupal::service('user.auth')->authenticate('Odo', 'a password'));
-    $user = User::load(2);
-    $this->assertEquals($rehash, $user->getPassword());
+    $this->assertEntity(2, 'Odo', 'odo@local.host', '0', '0', FALSE, '', 'odo@local.host');
   }
 
 }
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index c273cb3..8fc9bf5 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -66,6 +66,9 @@ services:
     arguments: ['@current_user', '@entity.manager']
     tags:
       - { name: 'context_provider' }
+  password_migrate:
+    class: Drupal\user\MigratePassword
+    arguments: ['@password_original']
 
 parameters:
   user.tempstore.expire: 604800
diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php
index bacd554..bea6152 100644
--- a/core/modules/views/src/Form/ViewsExposedForm.php
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -5,7 +5,6 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Render\Element\Checkboxes;
 use Drupal\Core\Url;
 use Drupal\views\ExposedFormCache;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -147,46 +146,26 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
-    // Form input keys that will not be included in $view->exposed_raw_data.
-    $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset');
-    $values = $form_state->getValues();
     foreach (array('field', 'filter') as $type) {
       /** @var \Drupal\views\Plugin\views\ViewsHandlerInterface[] $handlers */
       $handlers = &$form_state->get('view')->$type;
       foreach ($handlers as $key => $info) {
-        if ($handlers[$key]->acceptExposedInput($values)) {
-          $handlers[$key]->submitExposed($form, $form_state);
-        }
-        else {
-          // The input from the form did not validate, exclude it from the
-          // stored raw data.
-          $exclude[] = $key;
-        }
+        $handlers[$key]->submitExposed($form, $form_state);
       }
     }
 
     $view = $form_state->get('view');
-    $view->exposed_data = $values;
+    $view->exposed_data = $form_state->getValues();
     $view->exposed_raw_input = [];
 
     $exclude = array('submit', 'form_build_id', 'form_id', 'form_token', 'exposed_form_plugin', 'reset');
-    /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase $exposed_form_plugin */
+    /** @var \Drupal\views\Plugin\views\exposed_form\ExposedFormPluginInterface $exposed_form_plugin */
     $exposed_form_plugin = $view->display_handler->getPlugin('exposed_form');
     $exposed_form_plugin->exposedFormSubmit($form, $form_state, $exclude);
-    foreach ($values as $key => $value) {
-      if (!empty($key) && !in_array($key, $exclude)) {
-        if (is_array($value)) {
-          // Handle checkboxes, we only want to include the checked options.
-          // @todo: revisit the need for this when
-          //   https://www.drupal.org/node/342316 is resolved.
-          $checked = Checkboxes::getCheckedCheckboxes($value);
-          foreach ($checked as $option_id) {
-            $view->exposed_raw_input[$option_id] = $value[$option_id];
-          }
-        }
-        else {
-          $view->exposed_raw_input[$key] = $value;
-        }
+
+    foreach ($form_state->getValues() as $key => $value) {
+      if (!in_array($key, $exclude)) {
+        $view->exposed_raw_input[$key] = $value;
       }
     }
   }
diff --git a/core/modules/views/src/Plugin/ViewsHandlerManager.php b/core/modules/views/src/Plugin/ViewsHandlerManager.php
index d918696..d138d72 100644
--- a/core/modules/views/src/Plugin/ViewsHandlerManager.php
+++ b/core/modules/views/src/Plugin/ViewsHandlerManager.php
@@ -86,7 +86,7 @@ public function getHandler($item, $override = NULL) {
 
     if (isset($data[$field][$this->handlerType])) {
       $definition = $data[$field][$this->handlerType];
-      foreach (array('group', 'title', 'title short', 'label', 'help', 'real field', 'real table', 'entity type', 'entity field') as $key) {
+      foreach (array('group', 'title', 'title short', 'help', 'real field', 'real table', 'entity type', 'entity field') as $key) {
         if (!isset($definition[$key])) {
           // First check the field level.
           if (!empty($data[$field][$key])) {
diff --git a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
index 7078032..616666b 100644
--- a/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
+++ b/core/modules/views/src/Plugin/views/filter/BooleanOperator.php
@@ -93,14 +93,9 @@ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$o
     parent::init($view, $display, $options);
 
     $this->value_value = $this->t('True');
-
     if (isset($this->definition['label'])) {
       $this->value_value = $this->definition['label'];
     }
-    elseif (isset($this->definition['title'])) {
-      $this->value_value = $this->definition['title'];
-    }
-
     if (isset($this->definition['accept null'])) {
       $this->accept_null = (bool) $this->definition['accept null'];
     }
diff --git a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
index 34b8cb4..c458e63 100644
--- a/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/src/Plugin/views/filter/FilterPluginBase.php
@@ -7,7 +7,6 @@
 use Drupal\Core\Form\FormHelper;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
-use Drupal\Core\Render\Element\Checkboxes;
 use Drupal\user\RoleInterface;
 use Drupal\views\Plugin\views\HandlerBase;
 use Drupal\Component\Utility\Html;
@@ -1333,20 +1332,15 @@ public function storeGroupInput($input, $status) {
   }
 
   /**
-   * Determines if the input from a filter should change the generated query.
-   *
-   * @param array $input
-   *   The exposed data for this view.
-   *
-   * @return bool
-   *   TRUE if the input for this filter should be included in the view query.
-   *   FALSE otherwise.
+   * Check to see if input from the exposed filters should change
+   * the behavior of this filter.
    */
   public function acceptExposedInput($input) {
     if (empty($this->options['exposed'])) {
       return TRUE;
     }
 
+
     if (!empty($this->options['expose']['use_operator']) && !empty($this->options['expose']['operator_id']) && isset($input[$this->options['expose']['operator_id']])) {
       $this->operator = $input[$this->options['expose']['operator_id']];
     }
@@ -1364,12 +1358,6 @@ public function acceptExposedInput($input) {
           if ($value == 'All' || $value === array()) {
             return FALSE;
           }
-
-          // If checkboxes are used to render this filter, do not include the
-          // filter if no options are checked.
-          if (is_array($value) && Checkboxes::detectEmptyCheckboxes($value)) {
-            return FALSE;
-          }
         }
 
         if (!empty($this->alwaysMultiple) && $value === '') {
diff --git a/core/modules/views/src/Plugin/views/filter/InOperator.php b/core/modules/views/src/Plugin/views/filter/InOperator.php
index 593e97b..f3f1ca4 100644
--- a/core/modules/views/src/Plugin/views/filter/InOperator.php
+++ b/core/modules/views/src/Plugin/views/filter/InOperator.php
@@ -282,17 +282,15 @@ public function reduceValueOptions($input = NULL) {
     return $options;
   }
 
-  /**
-   * {@inheritdoc}
-   */
   public function acceptExposedInput($input) {
+    // A very special override because the All state for this type of
+    // filter could have a default:
     if (empty($this->options['exposed'])) {
       return TRUE;
     }
 
-    // The "All" state for this type of filter could have a default value. If
-    // this is a non-multiple and non-required option, then this filter will
-    // participate by using the default settings *if* 'limit' is true.
+    // If this is non-multiple and non-required, then this filter will
+    // participate, but using the default settings, *if* 'limit is true.
     if (empty($this->options['expose']['multiple']) && empty($this->options['expose']['required']) && !empty($this->options['expose']['limit'])) {
       $identifier = $this->options['expose']['identifier'];
       if ($input[$identifier] == 'All') {
diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
index 0204468..c5cdd08 100644
--- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
+++ b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php
@@ -207,48 +207,6 @@ public function testExposedFormRender() {
   }
 
   /**
-   * Tests overriding the default render option with checkboxes.
-   */
-  public function testExposedFormRenderCheckboxes() {
-    // Make sure we have at least two options for node type.
-    $this->drupalCreateContentType(['type' => 'page']);
-    $this->drupalCreateNode(['type' => 'page']);
-
-    // Use a test theme to convert multi-select elements into checkboxes.
-    \Drupal::service('theme_handler')->install(array('views_test_checkboxes_theme'));
-    $this->config('system.theme')
-      ->set('default', 'views_test_checkboxes_theme')
-      ->save();
-
-    // Set the "type" filter to multi-select.
-    $view = Views::getView('test_exposed_form_buttons');
-    $filter = $view->getHandler('page_1', 'filter', 'type');
-    $filter['expose']['multiple'] = TRUE;
-    $view->setHandler('page_1', 'filter', 'type', $filter);
-
-    // Only display 5 items per page so we can test that paging works.
-    $display = &$view->storage->getDisplay('default');
-    $display['display_options']['pager']['options']['items_per_page'] = 5;
-
-    $view->save();
-    $this->drupalGet('test_exposed_form_buttons');
-
-    $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[article]"]');
-    $this->assertEqual(count($actual), 1, 'Article option renders as a checkbox.');
-    $actual = $this->xpath('//form//input[@type="checkbox" and @name="type[page]"]');
-    $this->assertEqual(count($actual), 1, 'Page option renders as a checkbox');
-
-    // Ensure that all results are displayed.
-    $rows = $this->xpath("//div[contains(@class, 'views-row')]");
-    $this->assertEqual(count($rows), 5, '5 rows are displayed by default on the first page when no options are checked.');
-
-    $this->clickLink('Page 2');
-    $rows = $this->xpath("//div[contains(@class, 'views-row')]");
-    $this->assertEqual(count($rows), 1, '1 row is displayed by default on the second page when no options are checked.');
-    $this->assertNoText('An illegal choice has been detected. Please contact the site administrator.');
-  }
-
-  /**
    * Tests the exposed block functionality.
    */
   public function testExposedBlock() {
diff --git a/core/modules/views/src/Tests/ViewAjaxTest.php b/core/modules/views/src/Tests/ViewAjaxTest.php
index c1705a5..9219b20 100644
--- a/core/modules/views/src/Tests/ViewAjaxTest.php
+++ b/core/modules/views/src/Tests/ViewAjaxTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\views\Tests;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 
 /**
  * Tests the ajax view functionality.
@@ -47,7 +46,7 @@ public function testAjaxView() {
       'view_display_id' => 'page_1',
     );
     $post += $this->getAjaxPageStatePostData();
-    $response = $this->drupalPost('views/ajax', '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]);
+    $response = $this->drupalPost('views/ajax', 'application/vnd.drupal-ajax', $post);
     $data = Json::decode($response);
 
     $this->assertTrue(isset($data[0]['settings']['views']['ajaxViews']));
diff --git a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml
deleted file mode 100644
index 50bf73e..0000000
--- a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.info.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-name: Views test checkboxes theme
-type: theme
-description: Theme for testing Views rendering of checkboxes.
-version: VERSION
-core: 8.x
diff --git a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme b/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme
deleted file mode 100644
index cab52ac..0000000
--- a/core/modules/views/tests/themes/views_test_checkboxes_theme/views_test_checkboxes_theme.theme
+++ /dev/null
@@ -1,15 +0,0 @@
-<?php
-
-/**
- * @file
- * Changes an exposed "type" filter from a multi-select to checkboxes.
- */
-
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Changes an exposed "type" filter from a multi-select to checkboxes.
- */
-function views_test_checkboxes_theme_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) {
-  $form['type']['#type'] = 'checkboxes';
-}
diff --git a/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php b/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php
index 668cc4c..3faca0c 100644
--- a/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php
+++ b/core/modules/views_ui/src/Tests/FilterBooleanWebTest.php
@@ -23,10 +23,6 @@ class FilterBooleanWebTest extends UITestBase {
   public function testFilterBooleanUI() {
     $this->drupalPostForm('admin/structure/views/nojs/add-handler/test_view/default/filter', array('name[views_test_data.status]' => TRUE), t('Add and configure @handler', array('@handler' => t('filter criteria'))));
 
-    // Check the field widget label. 'title' should be used as a fallback.
-    $result = $this->cssSelect('#edit-options-value--wrapper legend span');
-    $this->assertEqual((string) $result[0], 'Status');
-
     $this->drupalPostForm(NULL, array(), t('Expose filter'));
     $this->drupalPostForm(NULL, array(), t('Grouped filters'));
 
diff --git a/core/modules/views_ui/src/Tests/PreviewTest.php b/core/modules/views_ui/src/Tests/PreviewTest.php
index 3b4dd9b..1be86cc 100644
--- a/core/modules/views_ui/src/Tests/PreviewTest.php
+++ b/core/modules/views_ui/src/Tests/PreviewTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\views_ui\Tests;
 
 use Drupal\Component\Serialization\Json;
-use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
 
 /**
  * Tests the UI preview functionality.
@@ -325,7 +324,7 @@ protected function clickPreviewLinkAJAX($url, $row_count) {
     );
     $url = $this->getAbsoluteUrl($url);
     $post = array('js' => 'true') + $this->getAjaxPageStatePostData();
-    $result = Json::decode($this->drupalPost($url, '', $post, ['query' => [MainContentViewSubscriber::WRAPPER_FORMAT => 'drupal_ajax']]));
+    $result = Json::decode($this->drupalPost($url, 'application/vnd.drupal-ajax', $post));
     if (!empty($result)) {
       $this->drupalProcessAjaxResponse($content, $result, $ajax_settings, $drupal_settings);
     }
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
index a71c3fe..400206d 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
@@ -62,9 +62,9 @@ protected function setUp() {
     // Enable all core modules.
     $all_modules = system_rebuild_module_data();
     $all_modules = array_filter($all_modules, function ($module) {
-      // Filter contrib, hidden, experimental, already enabled modules, and
-      // modules in the Testing package.
-      if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing' || $module->info['package'] == 'Core (Experimental)') {
+      // Filter contrib, hidden, already enabled modules and modules in the
+      // Testing package.
+      if ($module->origin !== 'core' || !empty($module->info['hidden']) || $module->status == TRUE || $module->info['package'] == 'Testing') {
         return FALSE;
       }
       return TRUE;
diff --git a/core/tests/Drupal/Tests/BrowserTestBase.php b/core/tests/Drupal/Tests/BrowserTestBase.php
index 14cacec..5a9b0c0 100644
--- a/core/tests/Drupal/Tests/BrowserTestBase.php
+++ b/core/tests/Drupal/Tests/BrowserTestBase.php
@@ -523,10 +523,8 @@ protected function tearDown() {
     }
 
     // Restore original shutdown callbacks.
-    if (function_exists('drupal_register_shutdown_function')) {
-      $callbacks = &drupal_register_shutdown_function();
-      $callbacks = $this->originalShutdownCallbacks;
-    }
+    $callbacks = &drupal_register_shutdown_function();
+    $callbacks = $this->originalShutdownCallbacks;
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Mail/MailManagerTest.php b/core/tests/Drupal/Tests/Core/Mail/MailManagerTest.php
index cff3415..2ca4d11 100644
--- a/core/tests/Drupal/Tests/Core/Mail/MailManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Mail/MailManagerTest.php
@@ -6,8 +6,6 @@
 
 namespace Drupal\Tests\Core\Mail;
 
-use Drupal\Core\Render\RenderContext;
-use Drupal\Core\Render\RendererInterface;
 use Drupal\Tests\UnitTestCase;
 use Drupal\Core\Mail\MailManager;
 use Drupal\Component\Plugin\Discovery\DiscoveryInterface;
@@ -47,13 +45,6 @@ class MailManagerTest extends UnitTestCase {
   protected $discovery;
 
   /**
-   * The renderer.
-   *
-   * @var \Drupal\Core\Render\RendererInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $renderer;
-
-  /**
    * The mail manager under test.
    *
    * @var \Drupal\Tests\Core\Mail\TestMailManager
@@ -105,9 +96,8 @@ protected function setUpMailManager($interface = array()) {
     ));
     $logger_factory = $this->getMock('\Drupal\Core\Logger\LoggerChannelFactoryInterface');
     $string_translation = $this->getStringTranslationStub();
-    $this->renderer = $this->getMock(RendererInterface::class);
     // Construct the manager object and override its discovery.
-    $this->mailManager = new TestMailManager(new \ArrayObject(), $this->cache, $this->moduleHandler, $this->configFactory, $logger_factory, $string_translation, $this->renderer);
+    $this->mailManager = new TestMailManager(new \ArrayObject(), $this->cache, $this->moduleHandler, $this->configFactory, $logger_factory, $string_translation);
     $this->mailManager->setDiscovery($this->discovery);
   }
 
@@ -119,7 +109,7 @@ protected function setUpMailManager($interface = array()) {
   public function testGetInstance() {
     $interface = array(
       'default' => 'php_mail',
-      'default' => 'test_mail_collector',
+      'example_testkey' => 'test_mail_collector',
     );
     $this->setUpMailManager($interface);
 
@@ -134,28 +124,6 @@ public function testGetInstance() {
     $this->assertInstanceOf('Drupal\Core\Mail\Plugin\Mail\TestMailCollector', $instance);
   }
 
-
-  /**
-   * Tests that mails are sent in a separate render context.
-   *
-   * @covers ::mail
-   */
-  public function testMailInRenderContext() {
-    $interface = array(
-      'default' => 'php_mail',
-      'example_testkey' => 'test_mail_collector',
-    );
-    $this->setUpMailManager($interface);
-
-    $this->renderer->expects($this->exactly(1))
-      ->method('executeInRenderContext')
-      ->willReturnCallback(function (RenderContext $render_context, $callback) {
-        $message = $callback();
-        $this->assertEquals('example', $message['module']);
-      });
-    $this->mailManager->mail('example', 'key', 'to@example.org', 'en');
-  }
-
 }
 
 /**
@@ -172,26 +140,4 @@ public function setDiscovery(DiscoveryInterface $discovery) {
     $this->discovery = $discovery;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function doMail($module, $key, $to, $langcode, $params = array(), $reply = NULL, $send = TRUE) {
-    // Build a simplified message array and return it.
-    $message = array(
-      'id' => $module . '_' . $key,
-      'module' => $module,
-      'key' => $key,
-      'to' => $to,
-      'from' => 'from@example.org',
-      'reply-to' => $reply,
-      'langcode' => $langcode,
-      'params' => $params,
-      'send' => TRUE,
-      'subject' => '',
-      'body' => array(),
-    );
-
-    return $message;
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php
index ef6dd25..2674b36 100644
--- a/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UnroutedUrlTest.php
@@ -82,8 +82,6 @@ public function providerFromUri() {
       // [$uri, $is_external]
       // An external URI.
       ['https://www.drupal.org', TRUE],
-      // A protocol-relative URL.
-      ['//www.drupal.org', TRUE],
       // An internal, unrouted, base-relative URI.
       ['base:robots.txt', FALSE],
       // Base-relative URIs with special characters.
@@ -116,6 +114,7 @@ public function providerFromInvalidUri() {
       // Schemeless paths.
       ['test'],
       ['/test'],
+      ['//test'],
       // Schemeless path with a query string.
       ['foo?bar'],
       // Only a query string.
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index 2808a20..66013c4 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -336,18 +336,6 @@ public function testGetUriForExternalUrl() {
   }
 
   /**
-   * Tests the getUri() and isExternal() methods for protocol-relative URLs.
-   *
-   * @covers ::getUri
-   * @covers ::isExternal
-   */
-  public function testGetUriForProtocolRelativeUrl() {
-    $url = Url::fromUri('//example.com/test');
-    $this->assertEquals('//example.com/test', $url->getUri());
-    $this->assertTrue($url->isExternal());
-  }
-
-  /**
    * Tests the getInternalPath method().
    *
    * @param \Drupal\Core\Url[] $urls
