diff --git a/core/core.services.yml b/core/core.services.yml
index 589c5f6..8d3f9e7 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -1143,7 +1143,7 @@ services:
     arguments: ['@module_handler']
   date.formatter:
     class: Drupal\Core\Datetime\DateFormatter
-    arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory', '@request_stack']
+    arguments: ['@entity.manager', '@language_manager', '@string_translation', '@config.factory']
   feed.bridge.reader:
     class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer
     calls:
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 121da17..fa83a1b 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -1362,9 +1362,9 @@ function template_preprocess_page(&$variables) {
   // Move some variables to the top level for themer convenience and template cleanliness.
   $variables['title'] = $variables['page']['#title'];
 
-  foreach (\Drupal::theme()->getActiveTheme()->getRegions() as $region) {
-    if (!isset($variables['page'][$region])) {
-      $variables['page'][$region] = array();
+  foreach (system_region_list(\Drupal::theme()->getActiveTheme()->getName()) as $region_key => $region_name) {
+    if (!isset($variables['page'][$region_key])) {
+      $variables['page'][$region_key] = array();
     }
   }
 
diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index ed50735..bae7618 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -755,7 +755,7 @@ protected function validate() {
   protected function processConfiguration($collection, $op, $name) {
     try {
       $processed = FALSE;
-      if ($collection == StorageInterface::DEFAULT_COLLECTION) {
+      if ($this->configManager->supportsConfigurationEntities($collection)) {
         $processed = $this->importInvokeOwner($collection, $op, $name);
       }
       if (!$processed) {
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
index 929731b..0ac79c0 100644
--- a/core/lib/Drupal/Core/Config/ConfigInstaller.php
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -175,39 +175,49 @@ public function installOptionalConfig(StorageInterface $storage = NULL, $depende
       $profile_storage = NULL;
     }
 
+    $collection_info = $this->configManager->getConfigCollectionInfo();
     $enabled_extensions = $this->getEnabledExtensions();
-    $existing_config = $this->getActiveStorages()->listAll();
-
-    $list = array_filter($storage->listAll(), function($config_name) use ($existing_config) {
-      // Only list configuration that:
-      // - does not already exist
-      // - is a configuration entity (this also excludes config that has an
-      //   implicit dependency on modules that are not yet installed)
-      return !in_array($config_name, $existing_config) && $this->configManager->getEntityTypeIdByName($config_name);
-    });
 
-    $all_config = array_merge($existing_config, $list);
-    $config_to_create = $storage->readMultiple($list);
-    // Check to see if the corresponding override storage has any overrides.
-    if ($profile_storage) {
-      $config_to_create = $profile_storage->readMultiple($list) + $config_to_create;
-    }
-    foreach ($config_to_create as $config_name => $data) {
-      // Exclude configuration where its dependencies cannot be met.
-      if (!$this->validateDependencies($config_name, $data, $enabled_extensions, $all_config)) {
-        unset($config_to_create[$config_name]);
+    foreach ($collection_info->getCollectionNames() as $collection) {
+      if (!$this->configManager->supportsConfigurationEntities($collection)) {
+        continue;
       }
-      // Exclude configuration that does not have a matching dependency.
-      elseif (!empty($dependency)) {
-        // Create a light weight dependency object to check dependencies.
-        $config_entity = new ConfigEntityDependency($config_name, $data);
-        if (!$config_entity->hasDependency(key($dependency), reset($dependency))) {
+      $existing_config = $this->getActiveStorages($collection)->listAll();
+
+      $list = array_filter($storage->listAll(), function($config_name) use ($existing_config) {
+        // Only list configuration that:
+        // - does not already exist
+        // - is a configuration entity (this also excludes config that has an
+        //   implicit dependency on modules that are not yet installed)
+        return !in_array($config_name, $existing_config) && $this->configManager->getEntityTypeIdByName($config_name);
+      });
+
+      $all_config = array_merge($existing_config, $list);
+      $config_to_create = $storage->readMultiple($list);
+      // Check to see if the corresponding override storage has any overrides.
+      if ($profile_storage) {
+        if ($profile_storage->getCollectionName() != $collection) {
+          $profile_storage = $profile_storage->createCollection($collection);
+        }
+        $config_to_create = $profile_storage->readMultiple($list) + $config_to_create;
+      }
+      foreach ($config_to_create as $config_name => $data) {
+        // Exclude configuration where its dependencies cannot be met.
+        if (!$this->validateDependencies($config_name, $data, $enabled_extensions, $all_config)) {
           unset($config_to_create[$config_name]);
         }
+        // Exclude configuration that does not have a matching dependency.
+        elseif (!empty($dependency)) {
+          // Create a light weight dependency object to check dependencies.
+          $config_entity = new ConfigEntityDependency($config_name, $data);
+          if (!$config_entity->hasDependency(key($dependency), reset($dependency))) {
+            unset($config_to_create[$config_name]);
+          }
+        }
+      }
+      if (!empty($config_to_create)) {
+        $this->createConfiguration($collection, $config_to_create, TRUE);
       }
-    }
-    if (!empty($config_to_create)) {
-      $this->createConfiguration(StorageInterface::DEFAULT_COLLECTION, $config_to_create, TRUE);
     }
   }
 
@@ -251,7 +261,8 @@ protected function getConfigToCreate(StorageInterface $storage, $collection, $pr
    */
   protected function createConfiguration($collection, array $config_to_create) {
     // Order the configuration to install in the order of dependencies.
-    if ($collection == StorageInterface::DEFAULT_COLLECTION) {
+    $config_entity_support = $this->configManager->supportsConfigurationEntities($collection);
+    if ($config_entity_support) {
       $dependency_manager = new ConfigDependencyManager();
       $config_names = $dependency_manager
         ->setData($config_to_create)
@@ -274,7 +285,7 @@ protected function createConfiguration($collection, array $config_to_create) {
       if ($config_to_create[$name] !== FALSE) {
         $new_config->setData($config_to_create[$name]);
       }
-      if ($collection == StorageInterface::DEFAULT_COLLECTION && $entity_type = $this->configManager->getEntityTypeIdByName($name)) {
+      if ($config_entity_support && $entity_type = $this->configManager->getEntityTypeIdByName($name)) {
         // If we are syncing do not create configuration entities. Pluggable
         // configuration entities can have dependencies on modules that are
         // not yet enabled. This approach means that any code that expects
diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php
index fb8f658..c70dd4c 100644
--- a/core/lib/Drupal/Core/Config/ConfigManager.php
+++ b/core/lib/Drupal/Core/Config/ConfigManager.php
@@ -355,6 +355,13 @@ public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names
   /**
    * {@inheritdoc}
    */
+  public function supportsConfigurationEntities($collection) {
+    return $collection == StorageInterface::DEFAULT_COLLECTION;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getConfigCollectionInfo() {
     if (!isset($this->configCollectionInfo)) {
       $this->configCollectionInfo = new ConfigCollectionInfo();
diff --git a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php
index d908e3f..7da86f7 100644
--- a/core/lib/Drupal/Core/Config/ConfigManagerInterface.php
+++ b/core/lib/Drupal/Core/Config/ConfigManagerInterface.php
@@ -162,6 +162,17 @@ public function findConfigEntityDependentsAsEntities($type, array $names);
   public function getConfigEntitiesToChangeOnDependencyRemoval($type, array $names, $dry_run = TRUE);
 
   /**
+   * Determines if the provided collection supports configuration entities.
+   *
+   * @param string $collection
+   *   The collection to check.
+   *
+   * @return bool
+   *   TRUE if the collection support configuration entities, FALSE if not.
+   */
+  public function supportsConfigurationEntities($collection);
+
+  /**
    * Gets available collection information using the event system.
    *
    * @return \Drupal\Core\Config\ConfigCollectionInfo
diff --git a/core/lib/Drupal/Core/Config/StorageComparer.php b/core/lib/Drupal/Core/Config/StorageComparer.php
index 2e61f96..7b3b3d4 100644
--- a/core/lib/Drupal/Core/Config/StorageComparer.php
+++ b/core/lib/Drupal/Core/Config/StorageComparer.php
@@ -212,7 +212,7 @@ public function createChangelist() {
       $this->addChangelistUpdate($collection);
       $this->addChangelistDelete($collection);
       // Only collections that support configuration entities can have renames.
-      if ($collection == StorageInterface::DEFAULT_COLLECTION) {
+      if ($this->configManager->supportsConfigurationEntities($collection)) {
         $this->addChangelistRename($collection);
       }
     }
@@ -415,7 +415,7 @@ protected function getAndSortConfigData($collection) {
     $source_data = $source_storage->readMultiple($source_names);
     // If the collection only supports simple configuration do not use
     // configuration dependencies.
-    if ($collection == StorageInterface::DEFAULT_COLLECTION) {
+    if ($this->configManager->supportsConfigurationEntities($collection)) {
       $dependency_manager = new ConfigDependencyManager();
       $this->targetNames[$collection] = $dependency_manager->setData($target_data)->sortAll();
       $this->sourceNames[$collection] = $dependency_manager->setData($source_data)->sortAll();
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php b/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php
new file mode 100644
index 0000000..ea69504
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/ConditionResolver.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\ConditionResolver.
+ */
+
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Query\Condition;
+
+class ConditionResolver {
+
+  /**
+   * Match a row against a group of conditions.
+   *
+   * @param \Drupal\Core\Database\Driver\fake\DatabaseRowInterface $row
+   *   The database row object.
+   * @param \Drupal\Core\Database\Query\Condition $condition_group
+   *   The condition group object.
+   *
+   * @return bool
+   *   TRUE if there is a match.
+   */
+  public static function matchGroup(DatabaseRowInterface $row, Condition $condition_group) {
+    $conditions = $condition_group->conditions();
+    $and = $conditions['#conjunction'] == 'AND';
+    unset($conditions['#conjunction']);
+    $match = TRUE;
+    foreach ($conditions as $condition) {
+      $match = $condition['field'] instanceof Condition ? static::matchGroup($row, $condition['field']) : static::matchSingle($row, $condition);
+      // For AND, finish matching on the first fail. For OR, finish on first
+      // success.
+      if ($and != $match) {
+        break;
+      }
+    }
+    return $match;
+  }
+
+  /**
+   * Match a single row and its condition.
+   *
+   * @param \Drupal\migrate\tests\DatabaseRowInterface $row
+   *   The row to match.
+   *
+   * @param array $condition
+   *   An array representing a single condition.
+   *
+   * @return bool
+   *   TRUE if the condition matches.
+   *
+   * @throws \Exception
+   */
+  protected static function matchSingle(DatabaseRowInterface $row, array $condition) {
+    $row_value = $row->getValue($condition['field']);
+    switch ($condition['operator']) {
+      case '=':
+        return $row_value == $condition['value'];
+
+      case '<=':
+        return $row_value <= $condition['value'];
+
+      case '>=':
+        return $row_value >= $condition['value'];
+
+      case '!=':
+        return $row_value != $condition['value'];
+
+      case '<>':
+        return $row_value != $condition['value'];
+
+      case '<':
+        return $row_value < $condition['value'];
+
+      case '>':
+        return $row_value > $condition['value'];
+
+      case 'IN':
+        return in_array($row_value, $condition['value']);
+
+      case 'IS NULL':
+        return !isset($row_value);
+
+      case 'IS NOT NULL':
+        return isset($row_value);
+
+      default:
+        throw new \Exception(sprintf('operator %s is not supported', $condition['operator']));
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php
new file mode 100644
index 0000000..ca98582
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRow.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\DatabaseRow.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+class DatabaseRow implements DatabaseRowInterface {
+
+  /**
+   * Construct a new row.
+   *
+   * @param array $row
+   *   The row data.
+   */
+  public function __construct(array $row) {
+    $this->row = $row;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue($field) {
+    return $this->row[$field];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php
new file mode 100644
index 0000000..9aa3965
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\DatabaseRowInterface.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+interface DatabaseRowInterface {
+
+  /**
+   * Get the field value from the row.
+   *
+   * @param mixed $field
+   *   The field to get the value of.
+   *
+   * @return mixed
+   *   The field value from the row.
+   */
+  public function getValue($field);
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowSelect.php b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowSelect.php
new file mode 100644
index 0000000..41bbf55
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/DatabaseRowSelect.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\DatabaseRowSelect.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+class DatabaseRowSelect extends DatabaseRow {
+
+  /**
+   * Construct a new database row.
+   *
+   * @param array $row
+   *   The row data.
+   * @param array $fields_with_table
+   *   The fields with a table.
+   * @param array $fields
+   *   The fields.
+   */
+  public function __construct(array $row, array $fields_with_table, array $fields) {
+    $this->fieldsWithTable = $fields_with_table;
+    $this->fields = $fields;
+    parent::__construct($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue($field) {
+    $field_info = isset($this->fieldsWithTable[$field]) ? $this->fieldsWithTable[$field] : $this->fields[$field];
+    if (array_key_exists($field_info['field'], $this->row[$field_info['table']]['result'])) {
+      $index = 'result';
+    }
+    else {
+      $index = 'all';
+    }
+    return $this->row[$field_info['table']][$index][$field_info['field']];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php
new file mode 100644
index 0000000..1be5147
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeConnection.php
@@ -0,0 +1,167 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeConnection.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Connection;
+
+/**
+ * Defines a fake connection for use during testing.
+ */
+class FakeConnection extends Connection {
+
+  /**
+   * Table prefix on the database.
+   *
+   * @var string
+   */
+  protected $tablePrefix;
+
+  /**
+   * Connection options for the database.
+   *
+   * @var array
+   */
+  protected $connectionOptions;
+
+  /**
+   * Constructs a FakeConnection.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param array $connection_options
+   *   (optional) The array of connection options for the database.
+   * @param string $prefix
+   *   (optional) The table prefix on the database.
+   */
+  public function __construct(array $database_contents, $connection_options = array(), $prefix = '') {
+    $this->databaseContents = $database_contents;
+    $this->connectionOptions = $connection_options;
+    $this->tablePrefix = $prefix;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getConnectionOptions() {
+    return $this->connectionOptions;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function tablePrefix($table = 'default') {
+    return $this->tablePrefix;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function select($table, $alias = NULL, array $options = array()) {
+    return new FakeSelect($this->databaseContents, $table, $alias);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function insert($table, array $options = array()) {
+    return new FakeInsert($this->databaseContents, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function merge($table, array $options = array()) {
+    return new FakeMerge($this->databaseContents, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function update($table, array $options = array()) {
+    return new FakeUpdate($this->databaseContents, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function delete($table, array $options = array()) {
+    return new FakeDelete($this->databaseContents, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function truncate($table, array $options = array()) {
+    return new FakeTruncate($this->databaseContents, $table);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function schema() {
+    return new FakeDatabaseSchema($this->databaseContents);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query($query, array $args = array(), $options = array()) {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function queryRange($query, $from, $count, array $args = array(), array $options = array()) {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function queryTemporary($query, array $args = array(), array $options = array()) {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function driver() {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function databaseType() {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createDatabase($database) {
+    // There is nothing to do.
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function mapConditionOperator($operator) {
+    throw new \Exception('Method not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nextId($existing_id = 0) {
+    throw new \Exception('Method not supported');
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php
new file mode 100644
index 0000000..d3e9161
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeDatabaseSchema.php
@@ -0,0 +1,230 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeDatabaseSchema.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Schema;
+
+class FakeDatabaseSchema extends Schema {
+
+  /**
+   * As set on MigrateSqlSourceTestCase::databaseContents.
+   *
+   * @var array
+   */
+  public $databaseContents;
+
+  /**
+   * Constructs a fake database schema.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   */
+  public function __construct(array &$database_contents) {
+    $this->uniqueIdentifier = uniqid('', TRUE);
+
+    // @todo Maybe we can generate an internal representation.
+    $this->databaseContents = &$database_contents;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function tableExists($table) {
+    return in_array($table, array_keys($this->databaseContents));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prefixNonTable($table) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function buildTableNameCondition($table_name, $operator = '=', $add_prefix = TRUE) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getPrefixInfo($table = 'default', $add_prefix = TRUE) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addField($table, $field, $spec, $keys_new = array()) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addIndex($table, $name, $fields) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addPrimaryKey($table, $fields) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addUniqueKey($table, $name, $fields) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function changeField($table, $field, $field_new, $spec, $keys_new = array()) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * PHP magic __clone() method.
+   */
+  public function __clone() {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function createTable($name, $table) {
+    #throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function dropField($table, $field) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function dropIndex($table, $name) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function dropPrimaryKey($table) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function dropTable($table) {
+    unset($this->databaseContents[$table]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function dropUniqueKey($table, $name) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fieldExists($table, $column) {
+    if (!empty($this->databaseContents[$table])) {
+      $row = reset($this->databaseContents[$table]);
+      return isset($row[$column]);
+    }
+    else {
+      throw new \Exception("Can't determine whether field exists with an empty / nonexistent table.");
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fieldNames($fields) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fieldSetDefault($table, $field, $default) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fieldSetNoDefault($table, $field) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function findTables($table_expression) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFieldTypeMap() {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function indexExists($table, $name) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function nextPlaceholder() {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareComment($comment, $length = NULL) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function renameTable($table, $new_name) {
+    throw new \Exception(sprintf('Unsupported method "%s"', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function uniqueIdentifier() {
+    return $this->uniqueIdentifier;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php
new file mode 100644
index 0000000..4a75bfb
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeDelete.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeDelete.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Query\Condition;
+use Drupal\Core\Database\Query\Delete;
+use Drupal\Core\Database\Query\SelectInterface;
+
+/**
+ * Defines FakeDelete for use in database tests.
+ */
+class FakeDelete extends Delete {
+
+  /**
+   * The database table to delete from.
+   *
+   * @var string
+   */
+  protected $table;
+
+  /**
+   * The database contents.
+   *
+   * @var array
+   */
+  protected $databaseContents;
+
+  /**
+   * Constructs a FakeDelete object.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param string $table
+   *   The table to delete from.
+   */
+  public function __construct(array &$database_contents, $table) {
+    $this->databaseContents = &$database_contents;
+    $this->table = $table;
+    $this->condition = new Condition('AND');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    $affected = 0;
+    if (isset($this->databaseContents[$this->table])) {
+      $original_row_count = count($this->databaseContents[$this->table]);
+      $condition = $this->condition;
+      $this->databaseContents[$this->table] = array_filter($this->databaseContents[$this->table], function ($row_array) use ($condition) {
+        $row = new DatabaseRow($row_array);
+        return !ConditionResolver::matchGroup($row, $condition);
+      });
+      $affected = $original_row_count - count($this->databaseContents[$this->table]);
+    }
+    return $affected;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists(SelectInterface $select) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function where($snippet, $args = array()) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php
new file mode 100644
index 0000000..9d7012b
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeInsert.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeInsert.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Query\Insert;
+use Drupal\Core\Database\Query\SelectInterface;
+
+/**
+ * Defines FakeInsert for use in database tests.
+ */
+class FakeInsert extends Insert {
+
+  /**
+   * The database contents.
+   *
+   * @var array
+   */
+  protected $databaseContents;
+
+  /**
+   * The database table to insert into.
+   *
+   * @var string
+   */
+  protected $table;
+
+  /**
+   * Constructs a fake insert object.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param string $table
+   *   The table to insert into.
+   * @param array $options
+   *   (optional) The database options. Not used.
+   */
+  public function __construct(array &$database_contents, $table, array $options = array()) {
+    $this->databaseContents = &$database_contents;
+    $this->table = $table;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function useDefaults(array $fields) {
+    throw new \Exception('This method is not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function from(SelectInterface $query) {
+    throw new \Exception('This method is not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    foreach ($this->insertValues as $values) {
+      $this->databaseContents[$this->table][] = array_combine($this->insertFields, $values);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php
new file mode 100644
index 0000000..dd3117e
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeMerge.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeMerge.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Query\Condition;
+use Drupal\Core\Database\Query\InvalidMergeQueryException;
+use Drupal\Core\Database\Query\Merge;
+
+/**
+ * Defines FakeMerge for use in database tests.
+ */
+class FakeMerge extends Merge {
+
+  /**
+   * Constructs a fake merge object and initializes the conditions.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param string $table
+   *   The database table to merge into.
+   */
+  public function __construct(array &$database_contents, $table) {
+    $this->databaseContents = &$database_contents;
+    $this->table = $table;
+    $this->conditionTable = $table;
+    $this->condition = new Condition('AND');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    if (!count($this->condition)) {
+      throw new InvalidMergeQueryException(t('Invalid merge query: no conditions'));
+    }
+    $select = new FakeSelect($this->databaseContents, $this->conditionTable, 'c');
+    $count = $select
+      ->condition($this->condition)
+      ->countQuery()
+      ->execute()
+      ->fetchField();
+    if ($count) {
+      $update = new FakeUpdate($this->databaseContents, $this->table);
+      $update
+        ->fields($this->updateFields)
+        ->condition($this->condition)
+        ->execute();
+      return self::STATUS_UPDATE;
+    }
+    $insert = new FakeInsert($this->databaseContents, $this->table);
+    $insert->fields($this->insertFields)->execute();
+    return self::STATUS_INSERT;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php
new file mode 100644
index 0000000..9a95a6e
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeSelect.php
@@ -0,0 +1,529 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeSelect.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Database\Query\Condition;
+use Drupal\Core\Database\Query\PlaceholderInterface;
+use Drupal\Core\Database\Query\Select;
+use Drupal\Core\Database\Query\SelectInterface;
+
+class FakeSelect extends Select {
+
+  /**
+   * Contents of the pseudo-database.
+   *
+   * Keys are table names and values are arrays of rows in the table.
+   * Every row there contains all table field values keyed by field name.
+   *
+   * @code
+   * array(
+   *   'user' => array(
+   *     array(
+   *       'uid' => 1,
+   *       'name' => 'admin',
+   *     ),
+   *     array(
+   *       'uid' => 2,
+   *       'name' => 'alice',
+   *     ),
+   *   ),
+   *   'node' => array(
+   *     array(
+   *       'nid' => 1,
+   *     )
+   *   )
+   * )
+   * @endcode
+   *
+   * @var array
+   */
+  protected $databaseContents;
+
+  protected $countQuery = FALSE;
+  protected $fieldsWithTable = array();
+
+  /**
+   * Constructs a new FakeSelect.
+   *
+   * @param array $database_contents
+   *   An array of mocked database content.
+   * @param string $table
+   *   The base table name used within fake select.
+   * @param string $alias
+   *   The base table alias used within fake select.
+   * @param string $conjunction
+   *   The operator to use to combine conditions: 'AND' or 'OR'.
+   */
+  public function __construct(array $database_contents, $table, $alias, $conjunction = 'AND') {
+    $this->databaseContents = $database_contents;
+    $this->addJoin(NULL, $table, $alias);
+    $this->where = new Condition($conjunction);
+    $this->having = new Condition($conjunction);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function leftJoin($table, $alias = NULL, $condition = NULL, $arguments = array()) {
+    return $this->addJoin('LEFT', $table, $alias, $condition, $arguments);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addJoin($type, $table, $alias = NULL, $condition = NULL, $arguments = array()) {
+    if ($table instanceof SelectInterface) {
+      // @todo implement this.
+      throw new \Exception('Subqueries are not supported at this moment.');
+    }
+    $alias = parent::addJoin($type, $table, $alias, $condition, $arguments);
+    if (isset($type)) {
+      if ($type != 'INNER' && $type != 'LEFT') {
+        throw new \Exception(sprintf('%s type not supported, only INNER and LEFT.', $type));
+      }
+      if (!preg_match('/^(\w+\.)?(\w+)\s*=\s*(\w+)\.(\w+)$/', $condition, $matches)) {
+        throw new \Exception('Only x.field1 = y.field2 conditions are supported.' . $condition);
+      }
+      if (!$matches[1] && count($this->tables) == 2) {
+        $aliases = array_keys($this->tables);
+        $matches[1] = $aliases[0];
+      }
+      else {
+        $matches[1] = substr($matches[1], 0, -1);
+      }
+      if (!$matches[1]) {
+        throw new \Exception('Only x.field1 = y.field2 conditions are supported.' . $condition);
+      }
+      if ($matches[1] == $alias) {
+        $this->tables[$alias] += array(
+          'added_field' => $matches[2],
+          'original_table_alias' => $matches[3],
+          'original_field' => $matches[4],
+        );
+      }
+      elseif ($matches[3] == $alias) {
+        $this->tables[$alias] += array(
+          'added_field' => $matches[4],
+          'original_table_alias' => $matches[1],
+          'original_field' => $matches[2],
+        );
+      }
+      else {
+        throw new \Exception('The JOIN condition does not contain the alias of the joined table.');
+      }
+    }
+    return $alias;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    // @todo: Implement distinct() handling.
+
+    // Single table count queries often do not contain fields which this class
+    // does not support otherwise, so add a shortcut.
+    if (count($this->tables) == 1 && $this->countQuery) {
+      $table_info = reset($this->tables);
+      $where = $this->where;
+      if (!empty($this->databaseContents[$table_info['table']])) {
+        $results = array_filter($this->databaseContents[$table_info['table']], function ($row_array) use ($where) {
+          return ConditionResolver::matchGroup(new DatabaseRow($row_array), $where);
+        });
+      }
+      else {
+        $results = array();
+      }
+    }
+    else {
+      $all_rows = $this->executeJoins();
+      $all_rows = $this->resolveConditions($this->where, $all_rows);
+      if (!empty($this->order)) {
+        usort($all_rows, array($this, 'sortCallback'));
+      }
+      // Now flatten the rows so that each row becomes a field alias => value
+      // array.
+      $results = array();
+      foreach ($all_rows as $table_rows) {
+        $result_row = array();
+        foreach ($table_rows as $row) {
+          $result_row += $row['result'];
+        }
+        $results[] = $result_row;
+      }
+    }
+    if (!empty($this->range)) {
+      $results = array_slice($results, $this->range['start'], $this->range['length']);
+    }
+    if ($this->countQuery) {
+      $results = array(array(count($results)));
+    }
+    return new FakeStatement($results);
+  }
+
+  /**
+   * Create an initial result set by executing the joins and picking fields.
+   *
+   * @return array
+   *   A multidimensional array, the first key are table aliases, the second
+   *   are field aliases, the values are the database contents or NULL in case
+   *   of JOINs.
+   */
+  protected function executeJoins() {
+    $fields = array();
+    foreach ($this->fields as $field_info) {
+      $this->fieldsWithTable[$field_info['table'] . '.' . $field_info['field']] = $field_info;
+      $fields[$field_info['table']][$field_info['field']] = $field_info['alias'];
+    }
+    foreach ($this->tables as $alias => $table_info) {
+      if ($table = reset($this->databaseContents[$table_info['table']])) {
+        foreach (array_keys($table) as $field) {
+          if (!isset($this->fields[$field])) {
+            $this->fieldsWithTable[$field] = array(
+              'table' => $alias,
+              'field' => $field,
+            );
+            $this->fieldsWithTable["$alias.$field"] = array(
+              'table' => $alias,
+              'field' => $field,
+            );
+          }
+        }
+      }
+    }
+    // This will contain a multiple dimensional array. The first key will be a
+    // table alias, the second either result or all, the third will be a field
+    // alias. all contains every field in the table with the original field
+    // names while result contains only the fields requested. This allows for
+    // filtering on fields that were not added via addField().
+    $results = array();
+    foreach ($this->tables as $table_alias => $table_info) {
+      // The base table for this query.
+      if (empty($table_info['join type'])) {
+        foreach ($this->databaseContents[$table_info['table']] as $candidate_row) {
+          $results[] = $this->getNewRow($table_alias, $fields, $candidate_row);
+        }
+      }
+      else {
+        $new_rows = array();
+
+        // Dynamically build a set of joined rows. Check existing rows and see
+        // if they can be joined with incoming rows.
+        foreach ($results as $row) {
+          $joined = FALSE;
+          foreach ($this->databaseContents[$table_info['table']] as $candidate_row) {
+            if ($row[$table_info['original_table_alias']]['result'][$table_info['original_field']] == $candidate_row[$table_info['added_field']]) {
+              $joined = TRUE;
+              $new_rows[] = $this->getNewRow($table_alias, $fields, $candidate_row, $row);
+            }
+          }
+          if (!$joined && $table_info['join type'] == 'LEFT') {
+            // Because PHP doesn't scope their foreach statements,
+            // $candidate_row may contain the last value assigned to it from the
+            // previous statement.
+            // @TODO: empty tables? Those are a problem.
+            $keys = array_keys($candidate_row);
+            $values = array_fill(0, count($keys), NULL);
+            $new_row = array(
+              'result' => $fields[$table_alias],
+              'all' => array_combine($keys, $values),
+            );
+            $new_rows[] = array($table_alias => $new_row) + $row;
+          }
+        }
+        $results = $new_rows;
+      }
+    }
+    return $results;
+  }
+
+  /**
+   * Retrieves a new row.
+   *
+   * @param string $table_alias
+   * @param array $fields
+   * @param array $candidate_row
+   * @param array $row
+   *
+   * @return array
+   */
+  protected function getNewRow($table_alias, $fields, $candidate_row, $row = array()) {
+    $new_row[$table_alias]['all'] = $candidate_row;
+    foreach ($fields[$table_alias] as $field => $alias) {
+      $new_row[$table_alias]['result'][$alias] = $candidate_row[$field];
+    }
+    return $new_row + $row;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function countQuery() {
+    $query = clone $this;
+    return $query->setCountQuery();
+  }
+
+  /**
+   * Set this query to be a count query.
+   */
+  protected function setCountQuery() {
+    $this->countQuery = TRUE;
+    return $this;
+  }
+
+  /**
+   * usort callback to order the results.
+   */
+  protected function sortCallback($a, $b) {
+    $a_row = new DatabaseRowSelect($a, $this->fieldsWithTable, $this->fields);
+    $b_row = new DatabaseRowSelect($b, $this->fieldsWithTable, $this->fields);
+    foreach ($this->order as $field => $direction) {
+      $a_value = $a_row->getValue($field);
+      $b_value = $b_row->getValue($field);
+      if ($a_value != $b_value) {
+        return (($a_value < $b_value) == ($direction == 'ASC')) ? -1 : 1;
+      }
+    }
+    return 0;
+  }
+
+  /**
+   * Resolves conditions by removing non-matching rows.
+   *
+   * @param \Drupal\Core\Database\Query\Condition $condition_group
+   *   The condition group to check.
+   * @param array $rows
+   *   An array of rows excluding non-matching rows.
+   *
+   * @return \Drupal\Core\Database\Driver\fake\ConditionResolver
+   *   The condition resolver object.
+   */
+  protected function resolveConditions(Condition $condition_group, array &$rows) {
+    $fields_with_table = $this->fieldsWithTable;
+    $fields = $this->fields;
+    return array_filter($rows, function ($row_array) use ($condition_group, $fields_with_table, $fields) {
+      $row = new DatabaseRowSelect($row_array, $fields_with_table, $fields);
+      return ConditionResolver::matchGroup($row, $condition_group);
+    });
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function orderBy($field, $direction = 'ASC') {
+    $this->order[$field] = strtoupper($direction);
+    return $this;
+  }
+
+  // ================== we could support these.
+  /**
+   * {@inheritdoc}
+   */
+  public function groupBy($field) {
+    // @todo: Implement groupBy() method.
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function havingCondition($field, $value = NULL, $operator = NULL) {
+    // @todo: Implement havingCondition() method.
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function uniqueIdentifier() {
+    // TODO: Implement uniqueIdentifier() method.
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  // ================== the rest won't be supported, ever.
+  /**
+   * {@inheritdoc}
+   */
+  public function nextPlaceholder() {
+    // TODO: Implement nextPlaceholder() method.
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isPrepared() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function preExecute(SelectInterface $query = NULL) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function where($snippet, $args = array()) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extend($extender_name) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getExpressions() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getGroupBy() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getUnion() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function forUpdate($set = TRUE) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rightJoin($table, $alias = NULL, $condition = NULL, $arguments = array()) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &conditions() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function orderRandom() {
+    // We could implement this but why bother.
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function union(SelectInterface $query, $type = '') {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function addExpression($expression, $alias = NULL, $arguments = array()) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getTables() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getArguments(PlaceholderInterface $query_place_holder = NULL) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getOrderBy() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function &getFields() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists(SelectInterface $select) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function notExists(SelectInterface $select) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function arguments() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function compile(Connection $connection, PlaceholderInterface $query_place_holder) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function compiled() {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields($table_alias, array $fields = array()) {
+    if (!$fields) {
+      $table = $this->tables[$table_alias]['table'];
+      if (!empty($this->databaseContents[$table])) {
+        $fields = array_keys(reset($this->databaseContents[$table]));
+      }
+      else {
+        throw new \Exception(SafeMarkup::format('All fields on empty table @table is not supported.', array('@table' => $table)));
+      }
+    }
+    return parent::fields($table_alias, $fields);
+  }
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php
new file mode 100644
index 0000000..7aaf574
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeStatement.php
@@ -0,0 +1,104 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeStatement.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\RowCountException;
+use Drupal\Core\Database\StatementInterface;
+
+/**
+ * Represents a fake prepared statement.
+ */
+class FakeStatement extends \ArrayIterator implements StatementInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute($args = array(), $options = array()) {
+    throw new \Exception('This method is not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getQueryString() {
+    throw new \Exception('This method is not supported');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function rowCount() {
+    throw new RowCountException();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchField($index = 0) {
+    $row = array_values($this->current());
+    $return = $row[$index];
+    $this->next();
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchAssoc() {
+    $return = FALSE;
+    if ($this->valid()) {
+      $return = $this->current();
+      $this->next();
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchCol($index = 0) {
+    $return = array();
+    foreach ($this as $row) {
+      $row = array_values($row);
+      $return[] = $row[$index];
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchAllKeyed($key_index = 0, $value_index = 1) {
+    $return = array();
+    foreach ($this as $row) {
+      $row = array_values($row);
+      $return[$row[$key_index]] = $row[$value_index];
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchAllAssoc($key, $fetch = NULL) {
+    $return = array();
+    foreach ($this as $row) {
+      $return[$row[$key]] = $row;
+    }
+    return $return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fetchObject() {
+    $return = $this->fetchAssoc();
+    return $return === FALSE ? FALSE : (object) $return;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php
new file mode 100644
index 0000000..d0be873
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeTruncate.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeTruncate.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+/**
+ * Defines FakeTruncate for use in database tests.
+ */
+class FakeTruncate {
+
+  /**
+   * Constructs a FakeTruncate object.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param string $table
+   *   The table to truncate.
+   */
+  public function __construct(array &$database_contents, $table) {
+    $this->databaseContents = &$database_contents;
+    $this->table = $table;
+  }
+
+  /**
+   * Executes the TRUNCATE query.
+   */
+  public function execute() {
+    $this->databaseContents[$this->table] = array();
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php b/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php
new file mode 100644
index 0000000..0505c22
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/FakeUpdate.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Database\Driver\fake\FakeUpdate.
+ */
+
+namespace Drupal\Core\Database\Driver\fake;
+
+use Drupal\Core\Database\Query\Condition;
+use Drupal\Core\Database\Query\SelectInterface;
+use Drupal\Core\Database\Query\Update;
+
+/**
+ * Defines FakeUpdate for use in database tests.
+ */
+class FakeUpdate extends Update {
+
+  /**
+   * The database table to update.
+   *
+   * @var string
+   */
+  protected $table;
+
+  /**
+   * The database contents.
+   *
+   * @var array
+   */
+  protected $databaseContents;
+
+  /**
+   * Constructs a FakeUpdate object and initializes the condition.
+   *
+   * @param array $database_contents
+   *   The database contents faked as an array. Each key is a table name, each
+   *   value is a list of table rows.
+   * @param string $table
+   *   The table to update.
+   */
+  public function __construct(array &$database_contents, $table) {
+    $this->databaseContents = &$database_contents;
+    $this->table = $table;
+    $this->condition = new Condition('AND');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function execute() {
+    $affected = 0;
+    if (isset($this->databaseContents[$this->table])) {
+      $fields = $this->fields;
+      $condition = $this->condition;
+      array_walk($this->databaseContents[$this->table], function (&$row_array) use ($fields, $condition, &$affected) {
+        $row = new DatabaseRow($row_array);
+        if (ConditionResolver::matchGroup($row, $condition)) {
+          $row_array = $fields + $row_array;
+          $affected++;
+        }
+      });
+    }
+    return $affected;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function exists(SelectInterface $select) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function where($snippet, $args = array()) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function expression($field, $expression, array $arguments = NULL) {
+    throw new \Exception(sprintf('Method "%s" is not supported', __METHOD__));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php b/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php
new file mode 100644
index 0000000..11ed2f3
--- /dev/null
+++ b/core/lib/Drupal/Core/Database/Driver/fake/Install/Tasks.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Database\Driver\fake\Install\Tasks
+ */
+
+namespace Drupal\Core\Database\Driver\fake\Install;
+
+use Drupal\Core\Database\Install\Tasks as InstallTasks;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Database\Driver\mysql\Connection;
+use Drupal\Core\Database\DatabaseNotFoundException;
+
+/**
+ * Usually used to specify installation tasks but here we're only interested
+ * in setting $error to TRUE.
+ */
+class Tasks extends InstallTasks {
+  /**
+   * Prevent the installer from recognising this as a potential database driver.
+   * @TODO Looks like this is needed only if we define $pdoDriver to something valid e.g. mysql.
+   * Not sure we need to do that. We may not need this file at all?
+   *
+   * @var bool
+   */
+  protected $error = TRUE;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function name() {
+    return t('Fake database connection for use in unit tests');
+  }
+}
diff --git a/core/lib/Drupal/Core/Datetime/DateFormatter.php b/core/lib/Drupal/Core/Datetime/DateFormatter.php
index 0aad043..82e9969 100644
--- a/core/lib/Drupal/Core/Datetime/DateFormatter.php
+++ b/core/lib/Drupal/Core/Datetime/DateFormatter.php
@@ -15,7 +15,6 @@
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Symfony\Component\HttpFoundation\RequestStack;
 
 /**
  * Provides a service to handler various date related functionality.
@@ -53,13 +52,6 @@ class DateFormatter {
    */
   protected $configFactory;
 
-  /**
-   * The request stack.
-   *
-   * @var \Symfony\Component\HttpFoundation\RequestStack
-   */
-  protected $requestStack;
-
   protected $country = NULL;
   protected $dateFormats = array();
 
@@ -93,15 +85,12 @@ class DateFormatter {
    *   The string translation.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The configuration factory.
-   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
-   *   The request stack.
    */
-  public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
+  public function __construct(EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager, TranslationInterface $translation, ConfigFactoryInterface $config_factory) {
     $this->dateFormatStorage = $entity_manager->getStorage('date_format');
     $this->languageManager = $language_manager;
     $this->stringTranslation = $translation;
     $this->configFactory = $config_factory;
-    $this->requestStack = $request_stack;
   }
 
   /**
@@ -122,13 +111,13 @@ public function __construct(EntityManagerInterface $entity_manager, LanguageMana
    *   (optional) If $type is 'custom', a PHP date format string suitable for
    *   input to date(). Use a backslash to escape ordinary text, so it does not
    *   get interpreted as date format characters.
-   * @param string|null $timezone
+   * @param string $timezone
    *   (optional) Time zone identifier, as described at
    *   http://php.net/manual/timezones.php Defaults to the time zone used to
    *   display the page.
-   * @param string|null $langcode
-   *   (optional) Language code to translate to. NULL (default) means to use
-   *   the user interface language for the page.
+   * @param string $langcode
+   *   (optional) Language code to translate to. Defaults to the language used to
+   *   display the page.
    *
    * @return string
    *   A translated date string in the requested format.
@@ -174,26 +163,17 @@ public function format($timestamp, $type = 'medium', $format = '', $timezone = N
   /**
    * Formats a time interval with the requested granularity.
    *
-   * Note that for intervals over 30 days, the output is approximate: a "month"
-   * is always exactly 30 days, and a "year" is always 365 days. It is not
-   * possible to make a more exact representation, given that there is only one
-   * input in seconds. If you are formatting an interval between two specific
-   * timestamps, use \Drupal\Core\Datetime\DateFormatter::formatDiff() instead.
-   *
    * @param int $interval
    *   The length of the interval in seconds.
    * @param int $granularity
    *   (optional) How many different units to display in the string (2 by
    *   default).
-   * @param string|null $langcode
-   *   (optional) langcode: The language code for the language used to format
-   *   the date. Defaults to NULL, which results in the user interface language
-   *   for the page being used.
+   * @param string $langcode
+   *   (optional) Language code to translate to a language other than what is
+   *   used to display the page. Defaults to NULL.
    *
    * @return string
    *   A translated string representation of the interval.
-   *
-   * @see \Drupal\Core\Datetime\DateFormatter::formatDiff()
    */
   public function formatInterval($interval, $granularity = 2, $langcode = NULL) {
     $output = '';
@@ -234,186 +214,12 @@ public function getSampleDateFormats($langcode = NULL, $timestamp = NULL, $timez
     // All date format characters for the PHP date() function.
     $date_chars = str_split('dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU');
     $date_elements = array_combine($date_chars, $date_chars);
-    return array_map(function ($character) use ($timestamp, $timezone, $langcode) {
+    return array_map(function($character) use ($timestamp, $timezone, $langcode) {
       return $this->format($timestamp, 'custom', $character, $timezone, $langcode);
     }, $date_elements);
   }
 
   /**
-   * Formats the time difference from the current request time to a timestamp.
-   *
-   * @param $timestamp
-   *   A UNIX timestamp to compare against the current request time.
-   * @param array $options
-   *   (optional) An associative array with additional options. The following
-   *   keys can be used:
-   *   - granularity: An integer value that signals how many different units to
-   *     display in the string. Defaults to 2.
-   *   - langcode: The language code for the language used to format the date.
-   *     Defaults to NULL, which results in the user interface language for the
-   *     page being used.
-   *   - strict: A Boolean value indicating whether or not the timestamp can be
-   *     before the current request time. If TRUE (default) and $timestamp is
-   *     before the current request time, the result string will be "0 seconds".
-   *     If FALSE and $timestamp is before the current request time, the result
-   *     string will be the formatted time difference.
-   *
-   * @return string
-   *   A translated string representation of the difference between the given
-   *   timestamp and the current request time. This interval is always positive.
-   *
-   * @see \Drupal\Core\Datetime\DateFormatter::formatDiff()
-   * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffSince()
-   */
-  public function formatTimeDiffUntil($timestamp, $options = array()) {
-    $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME');
-    return $this->formatDiff($request_time, $timestamp, $options);
-  }
-
-  /**
-   * Formats the time difference from a timestamp to the current request time.
-   *
-   * @param $timestamp
-   *   A UNIX timestamp to compare against the current request time.
-   * @param array $options
-   *   (optional) An associative array with additional options. The following
-   *   keys can be used:
-   *   - granularity: An integer value that signals how many different units to
-   *     display in the string. Defaults to 2.
-   *   - langcode: The language code for the language used to format the date.
-   *     Defaults to NULL, which results in the user interface language for the
-   *     page being used.
-   *   - strict: A Boolean value indicating whether or not the timestamp can be
-   *     after the current request time. If TRUE (default) and $timestamp is
-   *     after the current request time, the result string will be "0 seconds".
-   *     If FALSE and $timestamp is after the current request time, the result
-   *     string will be the formatted time difference.
-   *
-   * @return string
-   *   A translated string representation of the difference between the given
-   *   timestamp and the current request time. This interval is always positive.
-   *
-   * @see \Drupal\Core\Datetime\DateFormatter::formatDiff()
-   * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffUntil()
-   */
-  public function formatTimeDiffSince($timestamp, $options = array()) {
-    $request_time = $this->requestStack->getCurrentRequest()->server->get('REQUEST_TIME');
-    return $this->formatDiff($timestamp, $request_time, $options);
-  }
-
-  /**
-   * Formats a time interval between two timestamps.
-   *
-   * @param int $from
-   *   A UNIX timestamp, defining the from date and time.
-   * @param int $to
-   *   A UNIX timestamp, defining the to date and time.
-   * @param array $options
-   *   (optional) An associative array with additional options. The following
-   *   keys can be used:
-   *   - granularity: An integer value that signals how many different units to
-   *     display in the string. Defaults to 2.
-   *   - langcode: The language code for the language used to format the date.
-   *     Defaults to NULL, which results in the user interface language for the
-   *     page being used.
-   *   - strict: A Boolean value indicating whether or not the $from timestamp
-   *     can be after the $to timestamp. If TRUE (default) and $from is after
-   *     $to, the result string will be "0 seconds". If FALSE and $from is
-   *     after $to, the result string will be the formatted time difference.
-   *
-   * @return string
-   *   A translated string representation of the interval. This interval is
-   *   always positive.
-   *
-   * @see \Drupal\Core\Datetime\DateFormatter::formatInterval()
-   * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffSince()
-   * @see \Drupal\Core\Datetime\DateFormatter::formatTimeDiffUntil()
-   */
-  public function formatDiff($from, $to, $options = array()) {
-
-    $options += array(
-      'granularity' => 2,
-      'langcode' => NULL,
-      'strict' => TRUE,
-    );
-
-    if ($options['strict'] && $from > $to) {
-      return $this->t('0 seconds');
-    }
-
-    $date_time_from = new \DateTime();
-    $date_time_from->setTimestamp($from);
-
-    $date_time_to = new \DateTime();
-    $date_time_to->setTimestamp($to);
-
-    $interval = $date_time_to->diff($date_time_from);
-
-    $granularity = $options['granularity'];
-    $output = '';
-
-    // We loop over the keys provided by \DateInterval explicitly. Since we
-    // don't take the "invert" property into account, the resulting output value
-    // will always be positive.
-    foreach (array('y', 'm', 'd', 'h', 'i', 's') as $value) {
-      if ($interval->$value > 0) {
-        // Switch over the keys to call formatPlural() explicitly with literal
-        // strings for all different possibilities.
-        switch ($value) {
-          case 'y':
-            $interval_output = $this->formatPlural($interval->y, '1 year', '@count years', array(), array('langcode' => $options['langcode']));
-            break;
-
-          case 'm':
-            $interval_output = $this->formatPlural($interval->m, '1 month', '@count months', array(), array('langcode' => $options['langcode']));
-            break;
-
-          case 'd':
-            // \DateInterval doesn't support weeks, so we need to calculate them
-            // ourselves.
-            $interval_output = '';
-            $days = $interval->d;
-            if ($days >= 7) {
-              $weeks = floor($days / 7);
-              $interval_output .= $this->formatPlural($weeks, '1 week', '@count weeks', array(), array('langcode' => $options['langcode']));
-              $days -= $weeks * 7;
-              $granularity--;
-            }
-            if ($granularity > 0 && $days > 0) {
-              $interval_output .= ($interval_output ? ' ' : '') . $this->formatPlural($days, '1 day', '@count days', array(), array('langcode' => $options['langcode']));
-            }
-            break;
-
-          case 'h':
-            $interval_output = $this->formatPlural($interval->h, '1 hour', '@count hours', array(), array('langcode' => $options['langcode']));
-            break;
-
-          case 'i':
-            $interval_output = $this->formatPlural($interval->i, '1 minute', '@count minutes', array(), array('langcode' => $options['langcode']));
-            break;
-
-          case 's':
-            $interval_output = $this->formatPlural($interval->s, '1 second', '@count seconds', array(), array('langcode' => $options['langcode']));
-            break;
-
-        }
-        $output .= ($output ? ' ' : '') . $interval_output;
-        $granularity--;
-      }
-
-      if ($granularity == 0) {
-        break;
-      }
-    }
-
-    if (empty($output)) {
-      $output = $this->t('0 seconds');
-    }
-
-    return $output;
-  }
-
-  /**
    * Loads the given format pattern for the given langcode.
    *
    * @param string $format
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index b8eeb4f..d21a8fa 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -311,7 +311,7 @@ public static function findSitePath(Request $request, $require_settings = TRUE)
     if (!$script_name) {
       $script_name = $request->server->get('SCRIPT_FILENAME');
     }
-    $http_host = $request->getHttpHost();
+    $http_host = $request->getHost();
 
     $sites = array();
     include DRUPAL_ROOT . '/sites/sites.php';
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 30dae80..04f96fa 100644
--- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php
+++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php
@@ -87,7 +87,7 @@ public function viewElements(FieldItemListInterface $items) {
 
     foreach ($items as $delta => $item) {
       if ($item->value) {
-        $updated = $this->t('@time ago', array('@time' => $this->dateFormatter->formatTimeDiffSince($item->value)));
+        $updated = $this->t('@time ago', array('@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $item->value)));
       }
       else {
         $updated = $this->t('never');
diff --git a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
index d61bb24..5f84857 100644
--- a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
@@ -220,8 +220,8 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte
 
     // $page is now fully built. Find all non-empty page regions, and add a
     // theme wrapper function that allows them to be consistently themed.
-    $regions = \Drupal::theme()->getActiveTheme()->getRegions();
-    foreach ($regions as $region) {
+    $regions = system_region_list(\Drupal::theme()->getActiveTheme()->getName());
+    foreach (array_keys($regions) as $region) {
       if (!empty($page[$region])) {
         $page[$region]['#theme_wrappers'][] = 'region';
         $page[$region]['#region'] = $region;
diff --git a/core/lib/Drupal/Core/Theme/ActiveTheme.php b/core/lib/Drupal/Core/Theme/ActiveTheme.php
index c35afad..aace6f9 100644
--- a/core/lib/Drupal/Core/Theme/ActiveTheme.php
+++ b/core/lib/Drupal/Core/Theme/ActiveTheme.php
@@ -74,13 +74,6 @@ class ActiveTheme {
   protected $libraries;
 
   /**
-   * The regions provided by the theme.
-   *
-   * @var array
-   */
-  protected $regions;
-
-  /**
    * Constructs an ActiveTheme object.
    *
    * @param array $values
@@ -95,7 +88,6 @@ public function __construct(array $values) {
       'libraries' => [],
       'extension' => 'html.twig',
       'base_themes' => [],
-      'regions' => [],
     ];
 
     $this->name = $values['name'];
@@ -106,7 +98,6 @@ public function __construct(array $values) {
     $this->libraries = $values['libraries'];
     $this->extension = $values['extension'];
     $this->baseThemes = $values['base_themes'];
-    $this->regions = $values['regions'];
   }
 
   /**
@@ -186,16 +177,4 @@ public function getBaseThemes() {
     return $this->baseThemes;
   }
 
-  /**
-   * The regions used by the theme.
-   *
-   * @return string[]
-   *   The list of region machine names supported by the theme.
-   *
-   * @see system_region_list()
-   */
-  public function getRegions() {
-    return array_keys($this->regions);
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Theme/ThemeInitialization.php b/core/lib/Drupal/Core/Theme/ThemeInitialization.php
index 3f055c1..a77271e 100644
--- a/core/lib/Drupal/Core/Theme/ThemeInitialization.php
+++ b/core/lib/Drupal/Core/Theme/ThemeInitialization.php
@@ -214,9 +214,6 @@ public function getActiveTheme(Extension $theme, array $base_themes = []) {
     }
 
     $values['base_themes'] = $base_active_themes;
-    if (!empty($theme->info['regions'])) {
-      $values['regions'] = $theme->info['regions'];
-    }
 
     return new ActiveTheme($values);
   }
diff --git a/core/modules/action/tests/action_bulk_test/config/install/views.view.test_bulk_form.yml b/core/modules/action/tests/action_bulk_test/config/install/views.view.test_bulk_form.yml
index 8ea6534..6727525 100644
--- a/core/modules/action/tests/action_bulk_test/config/install/views.view.test_bulk_form.yml
+++ b/core/modules/action/tests/action_bulk_test/config/install/views.view.test_bulk_form.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/aggregator/config/optional/views.view.aggregator_rss_feed.yml b/core/modules/aggregator/config/optional/views.view.aggregator_rss_feed.yml
index a3c0b71..bfc7abf 100644
--- a/core/modules/aggregator/config/optional/views.view.aggregator_rss_feed.yml
+++ b/core/modules/aggregator/config/optional/views.view.aggregator_rss_feed.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'access news feeds'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml b/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml
index cccd45b..bacfa46 100644
--- a/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml
+++ b/core/modules/aggregator/config/optional/views.view.aggregator_sources.yml
@@ -27,7 +27,7 @@ display:
         options:
           perm: 'access news feeds'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/aggregator/src/Controller/AggregatorController.php b/core/modules/aggregator/src/Controller/AggregatorController.php
index eaa82e5..303b43c 100644
--- a/core/modules/aggregator/src/Controller/AggregatorController.php
+++ b/core/modules/aggregator/src/Controller/AggregatorController.php
@@ -127,8 +127,8 @@ public function adminOverview() {
       $row[] = $this->formatPlural($entity_manager->getStorage('aggregator_item')->getItemCount($feed), '1 item', '@count items');
       $last_checked = $feed->getLastCheckedTime();
       $refresh_rate = $feed->getRefreshRate();
-      $row[] = ($last_checked ? $this->t('@time ago', array('@time' => $this->dateFormatter->formatTimeDiffSince($last_checked))) : $this->t('never'));
-      $row[] = ($last_checked && $refresh_rate ? $this->t('@time left', array('@time' => $this->dateFormatter->formatTimeDiffUntil($last_checked + $refresh_rate))) : $this->t('never'));
+      $row[] = ($last_checked ? $this->t('@time ago', array('@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $last_checked))) : $this->t('never'));
+      $row[] = ($last_checked && $refresh_rate ? $this->t('%time left', array('%time' => $this->dateFormatter->formatInterval($last_checked + $refresh_rate - REQUEST_TIME))) : $this->t('never'));
       $links['edit'] = [
         'title' => $this->t('Edit'),
         'url' => Url::fromRoute('entity.aggregator_feed.edit_form', ['aggregator_feed' => $feed->id()]),
diff --git a/core/modules/aggregator/tests/modules/aggregator_test_views/test_views/views.view.test_aggregator_items.yml b/core/modules/aggregator/tests/modules/aggregator_test_views/test_views/views.view.test_aggregator_items.yml
index 281cdde..690a03a 100644
--- a/core/modules/aggregator/tests/modules/aggregator_test_views/test_views/views.view.test_aggregator_items.yml
+++ b/core/modules/aggregator/tests/modules/aggregator_test_views/test_views/views.view.test_aggregator_items.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/block/src/BlockRepository.php b/core/modules/block/src/BlockRepository.php
index 980e0ad..485a66f 100644
--- a/core/modules/block/src/BlockRepository.php
+++ b/core/modules/block/src/BlockRepository.php
@@ -47,15 +47,34 @@ public function __construct(EntityManagerInterface $entity_manager, ThemeManager
   }
 
   /**
+   * Returns the human-readable list of regions keyed by machine name.
+   *
+   * @return array
+   *   An array of human-readable region names keyed by machine name.
+   */
+  protected function getRegionNames() {
+    return system_region_list($this->getTheme());
+  }
+
+  /**
+   * Gets the current theme for this page.
+   *
+   * @return string
+   *   The current theme.
+   */
+  protected function getTheme() {
+    return $this->themeManager->getActiveTheme()->getName();
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getVisibleBlocksPerRegion(array $contexts) {
-    $active_theme = $this->themeManager->getActiveTheme();
     // Build an array of the region names in the right order.
-    $empty = array_fill_keys($active_theme->getRegions(), array());
+    $empty = array_fill_keys(array_keys($this->getRegionNames()), array());
 
     $full = array();
-    foreach ($this->blockStorage->loadByProperties(array('theme' => $active_theme->getName())) as $block_id => $block) {
+    foreach ($this->blockStorage->loadByProperties(array('theme' => $this->getTheme())) as $block_id => $block) {
       /** @var \Drupal\block\BlockInterface $block */
       // Set the contexts on the block before checking access.
       if ($block->setContexts($contexts)->access('view')) {
diff --git a/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block.yml b/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block.yml
index d540aee..d0e4771 100644
--- a/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block.yml
+++ b/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block2.yml b/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block2.yml
index 97ed6fb..1a79010 100644
--- a/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block2.yml
+++ b/core/modules/block/tests/modules/block_test_views/test_views/views.view.test_view_block2.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/block/tests/src/Unit/BlockRepositoryTest.php b/core/modules/block/tests/src/Unit/BlockRepositoryTest.php
index 56b90ca..f589e82 100644
--- a/core/modules/block/tests/src/Unit/BlockRepositoryTest.php
+++ b/core/modules/block/tests/src/Unit/BlockRepositoryTest.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Tests\block\Unit;
 
-use Drupal\block\BlockRepository;
 use Drupal\Core\Block\BlockPluginInterface;
 use Drupal\Core\Plugin\ContextAwarePluginInterface;
 use Drupal\Tests\UnitTestCase;
@@ -50,13 +49,6 @@ protected function setUp() {
     $active_theme->expects($this->atLeastOnce())
       ->method('getName')
       ->willReturn($this->theme);
-    $active_theme->expects($this->atLeastOnce())
-      ->method('getRegions')
-      ->willReturn([
-        'top',
-        'center',
-        'bottom',
-      ]);
 
     $theme_manager = $this->getMock('Drupal\Core\Theme\ThemeManagerInterface');
     $theme_manager->expects($this->once())
@@ -70,7 +62,17 @@ protected function setUp() {
       ->method('getStorage')
       ->willReturn($this->blockStorage);
 
-    $this->blockRepository = new BlockRepository($entity_manager, $theme_manager, $this->contextHandler);
+    $this->blockRepository = $this->getMockBuilder('Drupal\block\BlockRepository')
+      ->setConstructorArgs([$entity_manager, $theme_manager, $this->contextHandler])
+      ->setMethods(['getRegionNames'])
+      ->getMock();
+    $this->blockRepository->expects($this->once())
+      ->method('getRegionNames')
+      ->willReturn([
+        'top' => 'Top',
+        'center' => 'Center',
+        'bottom' => 'Bottom',
+      ]);
   }
 
   /**
diff --git a/core/modules/block_content/config/optional/views.view.block_content.yml b/core/modules/block_content/config/optional/views.view.block_content.yml
index ad5e1f9..7c2bba8 100644
--- a/core/modules/block_content/config/optional/views.view.block_content.yml
+++ b/core/modules/block_content/config/optional/views.view.block_content.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'administer blocks'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_block_content_view.yml b/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_block_content_view.yml
index e5c2d9b..cbd4511 100644
--- a/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_block_content_view.yml
+++ b/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_block_content_view.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_field_filters.yml b/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_field_filters.yml
index 45eb3af..52c52a5 100644
--- a/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_field_filters.yml
+++ b/core/modules/block_content/tests/modules/block_content_test_views/test_views/views.view.test_field_filters.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/comment/config/optional/views.view.comments_recent.yml b/core/modules/comment/config/optional/views.view.comments_recent.yml
index 6f9c5cd..a15ecd1 100644
--- a/core/modules/comment/config/optional/views.view.comments_recent.yml
+++ b/core/modules/comment/config/optional/views.view.comments_recent.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access comments'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php b/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
index c3808e6..c45c0f7 100644
--- a/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
+++ b/core/modules/comment/src/Tests/CommentTokenReplaceTest.php
@@ -60,8 +60,8 @@ function testCommentTokenReplacement() {
     $tests['[comment:langcode]'] = SafeMarkup::checkPlain($comment->language()->getId());
     $tests['[comment:url]'] = $comment->url('canonical', $url_options + array('fragment' => 'comment-' . $comment->id()));
     $tests['[comment:edit-url]'] = $comment->url('edit-form', $url_options);
-    $tests['[comment:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getCreatedTime(), array('langcode' => $language_interface->getId()));
-    $tests['[comment:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($comment->getChangedTimeAcrossTranslations(), array('langcode' => $language_interface->getId()));
+    $tests['[comment:created:since]'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $comment->getCreatedTime(), 2, $language_interface->getId());
+    $tests['[comment:changed:since]'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $comment->getChangedTimeAcrossTranslations(), 2, $language_interface->getId());
     $tests['[comment:parent:cid]'] = $comment->hasParentComment() ? $comment->getParentComment()->id() : NULL;
     $tests['[comment:parent:title]'] = SafeMarkup::checkPlain($parent_comment->getSubject());
     $tests['[comment:entity]'] = SafeMarkup::checkPlain($node->getTitle());
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml
index 9938a65..a4ad1c1 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_field_name.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access comments'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rest.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rest.yml
index 0c74efa..6350455 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rest.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rest.yml
@@ -29,7 +29,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_row.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_row.yml
index d7b1b3d..f6588b8 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_row.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_row.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rss.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rss.yml
index be6210a..7fb1644 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rss.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_rss.yml
@@ -23,7 +23,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_user_uid.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_user_uid.yml
index 030b4a7..2104d70 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_user_uid.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_comment_user_uid.yml
@@ -34,7 +34,7 @@ display:
           plugin_id: argument_comment_user_uid
           entity_type: node
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml
index 76c67c6..60f6554 100644
--- a/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml
+++ b/core/modules/comment/tests/modules/comment_test_views/test_views/views.view.test_field_filters.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/comment/tests/src/Unit/CommentStatisticsUnitTest.php b/core/modules/comment/tests/src/Unit/CommentStatisticsUnitTest.php
index e2e21ec..6439fec 100644
--- a/core/modules/comment/tests/src/Unit/CommentStatisticsUnitTest.php
+++ b/core/modules/comment/tests/src/Unit/CommentStatisticsUnitTest.php
@@ -55,7 +55,7 @@ class CommentStatisticsUnitTest extends UnitTestCase {
    * Sets up required mocks and the CommentStatistics service under test.
    */
   protected function setUp() {
-    $this->statement = $this->getMockBuilder('Drupal\Core\Database\Driver\sqlite\Statement')
+    $this->statement = $this->getMockBuilder('Drupal\Core\Database\Driver\fake\FakeStatement')
       ->disableOriginalConstructor()
       ->getMock();
 
diff --git a/core/modules/contact/src/Tests/ContactSitewideTest.php b/core/modules/contact/src/Tests/ContactSitewideTest.php
index c815d35..ff8d115 100644
--- a/core/modules/contact/src/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/src/Tests/ContactSitewideTest.php
@@ -231,7 +231,7 @@ function testSiteWideContact() {
     }
     // Submit contact form one over limit.
     $this->submitContact($this->randomMachineName(16), $recipients[0], $this->randomMachineName(16), $id, $this->randomMachineName(64));
-    $this->assertRaw(t('You cannot send more than %number messages in 10 min. Try again later.', array('%number' => $this->config('contact.settings')->get('flood.limit'))));
+    $this->assertRaw(t('You cannot send more than %number messages in @interval. Try again later.', array('%number' => $this->config('contact.settings')->get('flood.limit'), '@interval' => \Drupal::service('date.formatter')->formatInterval(600))));
 
     // Test listing controller.
     $this->drupalLogin($admin_user);
diff --git a/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml b/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml
index 84b2a2b..339f4ff 100644
--- a/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml
+++ b/core/modules/contact/tests/modules/contact_test_views/test_views/views.view.test_contact_link.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/content_translation/tests/modules/content_translation_test_views/test_views/views.view.test_entity_translations_link.yml b/core/modules/content_translation/tests/modules/content_translation_test_views/test_views/views.view.test_entity_translations_link.yml
index d7a21c3..87da0bb 100644
--- a/core/modules/content_translation/tests/modules/content_translation_test_views/test_views/views.view.test_entity_translations_link.yml
+++ b/core/modules/content_translation/tests/modules/content_translation_test_views/test_views/views.view.test_entity_translations_link.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml
index d3ebfc8..06dd35f 100644
--- a/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml
+++ b/core/modules/dblog/tests/modules/dblog_test_views/test_views/views.view.test_dblog.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference.yml b/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference.yml
index 919028b..5b6ba8f 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference.yml
@@ -24,7 +24,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference_entity_test.yml b/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference_entity_test.yml
index ec3ab5b..7902c23 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference_entity_test.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test/config/install/views.view.test_entity_reference_entity_test.yml
@@ -23,7 +23,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml
index 489ea04..8f81302 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_mul_view.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml
index 291b474..bb381c2 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_entity_test_view.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml
index 33911a6..993d843 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_mul_view.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml
index c281ef5c..f7c25ab 100644
--- a/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml
+++ b/core/modules/entity_reference/tests/modules/entity_reference_test_views/test_views/views.view.test_entity_reference_reverse_entity_test_view.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/field/tests/modules/field_test_views/test_views/views.view.test_view_fieldapi.yml b/core/modules/field/tests/modules/field_test_views/test_views/views.view.test_view_fieldapi.yml
index 869e441..e5098e3 100644
--- a/core/modules/field/tests/modules/field_test_views/test_views/views.view.test_view_fieldapi.yml
+++ b/core/modules/field/tests/modules/field_test_views/test_views/views.view.test_view_fieldapi.yml
@@ -47,7 +47,7 @@ display:
           entity_type: node
           entity_field: field_no_view_access
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/file/config/optional/views.view.files.yml b/core/modules/file/config/optional/views.view.files.yml
index 5e727fb..fc1b540 100644
--- a/core/modules/file/config/optional/views.view.files.yml
+++ b/core/modules/file/config/optional/views.view.files.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access files overview'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/file/tests/modules/file_test_views/test_views/views.view.test_file_user_file_data.yml b/core/modules/file/tests/modules/file_test_views/test_views/views.view.test_file_user_file_data.yml
index 1b630e4..4404085 100644
--- a/core/modules/file/tests/modules/file_test_views/test_views/views.view.test_file_user_file_data.yml
+++ b/core/modules/file/tests/modules/file_test_views/test_views/views.view.test_file_user_file_data.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access user profiles'
       cache:
-        type: tag
+        type: none
       style:
         type: table
         options:
diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module
index eb25bf8..7ec7422 100644
--- a/core/modules/forum/forum.module
+++ b/core/modules/forum/forum.module
@@ -633,5 +633,5 @@ function template_preprocess_forum_submitted(&$variables) {
     $username = array('#theme' => 'username', '#account' => User::load($variables['topic']->uid));
     $variables['author'] = drupal_render($username);
   }
-  $variables['time'] = isset($variables['topic']->created) ? \Drupal::service('date.formatter')->formatTimeDiffSince($variables['topic']->created) : '';
+  $variables['time'] = isset($variables['topic']->created) ? \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $variables['topic']->created) : '';
 }
diff --git a/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml b/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml
index a874401..32a9306 100644
--- a/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml
+++ b/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/image/tests/modules/image_test_views/test_views/views.view.test_image_user_image_data.yml b/core/modules/image/tests/modules/image_test_views/test_views/views.view.test_image_user_image_data.yml
index 8ea166b..3c02a8b 100644
--- a/core/modules/image/tests/modules/image_test_views/test_views/views.view.test_image_user_image_data.yml
+++ b/core/modules/image/tests/modules/image_test_views/test_views/views.view.test_image_user_image_data.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access user profiles'
       cache:
-        type: tag
+        type: none
       style:
         type: table
         options:
diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc
index d58d955..41ce0b8 100644
--- a/core/modules/locale/locale.pages.inc
+++ b/core/modules/locale/locale.pages.inc
@@ -119,6 +119,6 @@ function template_preprocess_locale_translation_update_info(array &$variables) {
 function template_preprocess_locale_translation_last_check(array &$variables) {
   $last = $variables['last'];
   $variables['last_checked'] = ($last != NULL);
-  $variables['time'] = \Drupal::service('date.formatter')->formatTimeDiffSince($last);
+  $variables['time'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $last);
   $variables['link'] = \Drupal::l(t('Check manually'), new Url('locale.check_translation', array(), array('query' => \Drupal::destination()->getAsArray())));
 }
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 edb628a..d887785 100644
--- a/core/modules/migrate/config/schema/migrate.data_types.schema.yml
+++ b/core/modules/migrate/config/schema/migrate.data_types.schema.yml
@@ -14,6 +14,10 @@ migrate_destination:
 migrate_source:
   type: migrate_plugin
   label: 'Source'
+  mapping:
+    constants:
+      type: ignore
+      label: 'Constants'
 
 # Base schema for migrate source plugins that extend
 # \Drupal\migrate\Plugin\migrate\source\SqlBase.
diff --git a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
index 258eb9c..b741780 100644
--- a/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
+++ b/core/modules/migrate/tests/src/Unit/MigrateSqlIdMapTest.php
@@ -24,21 +24,17 @@ class MigrateSqlIdMapTest extends MigrateTestCase {
    *
    * @var array
    */
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     'id' => 'sql_idmap_test',
-  ];
+  );
 
-  protected $sourceIds = [
-    'source_id_property' => [
-      'type' => 'string',
-    ],
-  ];
+  protected $sourceIds = array(
+    'source_id_property' => array(),
+  );
 
-  protected $destinationIds = [
-    'destination_id_property' => [
-      'type' => 'string',
-    ],
-  ];
+  protected $destinationIds = array(
+    'destination_id_property' => array(),
+  );
 
   /**
    * The database connection.
@@ -47,66 +43,41 @@ class MigrateSqlIdMapTest extends MigrateTestCase {
    */
   protected $database;
 
-  public function setUp() {
-    $this->database = $this->getDatabase([]);
-  }
-
-  /**
-   * Saves a single ID mapping row in the database.
-   *
-   * @param array $map
-   *  The row to save.
-   */
-  protected function saveMap(array $map) {
-    $table = 'migrate_map_sql_idmap_test';
-
-    $schema = $this->database->schema();
-    // If the table already exists, add any columns which are in the map array,
-    // but don't yet exist in the table. Yay, flexibility!
-    if ($schema->tableExists($table)) {
-      foreach (array_keys($map) as $field) {
-        if (!$schema->fieldExists($table, $field)) {
-          $schema->addField($table, $field, ['type' => 'text']);
-        }
-      }
-    }
-    else {
-      $schema->createTable($table, $this->createSchemaFromRow($map));
-    }
-
-    $this->database->insert($table)->fields($map)->execute();
-  }
-
   /**
    * Creates a test SQL ID map plugin.
    *
+   * @param array $database_contents
+   *   (optional) An array keyed by table names. Value are list of rows where
+   *   each row is an associative array of field => value.
+   * @param array $connection_options
+   *   (optional) An array of database connection options.
+   * @param string $prefix
+   *   (optional) The database prefix.
+   *
    * @return \Drupal\Tests\migrate\Unit\TestSqlIdMap
    *   A SQL ID map plugin test instance.
    */
-  protected function getIdMap() {
+  protected function getIdMap($database_contents = array(), $connection_options = array(), $prefix = '') {
     $migration = $this->getMigration();
-
     $plugin = $this->getMock('Drupal\migrate\Plugin\MigrateSourceInterface');
-    $plugin
+    $plugin->expects($this->any())
       ->method('getIds')
-      ->willReturn($this->sourceIds);
-    $migration
+      ->will($this->returnValue($this->sourceIds));
+    $migration->expects($this->any())
       ->method('getSourcePlugin')
-      ->willReturn($plugin);
-
-    $plugin = $this->getMock('Drupal\migrate\Plugin\MigrateDestinationInterface');
-    $plugin
+      ->will($this->returnValue($plugin));
+    $plugin = $this->getMock('Drupal\migrate\Plugin\MigrateSourceInterface');
+    $plugin->expects($this->any())
       ->method('getIds')
-      ->willReturn($this->destinationIds);
-    $migration
+      ->will($this->returnValue($this->destinationIds));
+    $migration->expects($this->any())
       ->method('getDestinationPlugin')
-      ->willReturn($plugin);
-
-    $id_map = new TestSqlIdMap($this->database, [], 'sql', [], $migration);
-    $migration
+      ->will($this->returnValue($plugin));
+    $this->database = $this->getDatabase($database_contents, $connection_options, $prefix);
+    $id_map = new TestSqlIdMap($this->database, array(), 'sql', array(), $migration);
+    $migration->expects($this->any())
       ->method('getIdMap')
-      ->willReturn($id_map);
-
+      ->will($this->returnValue($id_map));
     return $id_map;
   }
 
@@ -114,22 +85,11 @@ protected function getIdMap() {
    * Sets defaults for SQL ID map plugin tests.
    */
   protected function idMapDefaults() {
-    $defaults = array(
+    return array(
       'source_row_status' => MigrateIdMapInterface::STATUS_IMPORTED,
       'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
       'hash' => '',
     );
-    // By default, the PDO SQLite driver strongly prefers to return strings
-    // from SELECT queries. Even for columns that don't store strings. Even
-    // if the connection's STRINGIFY_FETCHES attribute is FALSE. This can cause
-    // assertSame() calls to fail, since 0 !== '0'. Casting these values to
-    // strings isn't the most elegant workaround, but it allows the assertions
-    // to pass properly.
-    if ($this->database->driver() == 'sqlite') {
-      $defaults['source_row_status'] = (string) $defaults['source_row_status'];
-      $defaults['rollback_action'] = (string) $defaults['rollback_action'];
-    }
-    return $defaults;
   }
 
   /**
@@ -144,29 +104,29 @@ public function testSaveIdMapping() {
     $source = array(
       'source_id_property' => 'source_value',
     );
-    $row = new Row($source, ['source_id_property' => []]);
+    $row = new Row($source, array('source_id_property' => array()));
     $id_map = $this->getIdMap();
-    $id_map->saveIdMapping($row, ['destination_id_property' => 2]);
-    $expected_result = [
-      [
+    $id_map->saveIdMapping($row, array('destination_id_property' => 2));
+    $expected_result = array(
+      array(
         'sourceid1' => 'source_value',
         'destid1' => 2,
-      ] + $this->idMapDefaults(),
-    ];
-    $this->queryResultTest($this->getIdMapContents(), $expected_result);
-    $source = [
+      ) + $this->idMapDefaults(),
+    );
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_result);
+    $source = array(
       'source_id_property' => 'source_value_1',
-    ];
-    $row = new Row($source, ['source_id_property' => []]);
-    $id_map->saveIdMapping($row, ['destination_id_property' => 3]);
-    $expected_result[] = [
+    );
+    $row = new Row($source, array('source_id_property' => array()));
+    $id_map->saveIdMapping($row, array('destination_id_property' => 3));
+    $expected_result[] = array(
       'sourceid1' => 'source_value_1',
       'destid1' => 3,
-    ] + $this->idMapDefaults();
-    $this->queryResultTest($this->getIdMapContents(), $expected_result);
-    $id_map->saveIdMapping($row, ['destination_id_property' => 4]);
+    ) + $this->idMapDefaults();
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_result);
+    $id_map->saveIdMapping($row, array('destination_id_property' => 4));
     $expected_result[1]['destid1'] = 4;
-    $this->queryResultTest($this->getIdMapContents(), $expected_result);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_result);
   }
 
   /**
@@ -184,12 +144,12 @@ public function testSetMessage() {
    */
   public function testClearMessages() {
     $message = 'Hello world.';
-    $expected_results = [0, 1, 2, 3];
+    $expected_results = array(0, 1, 2, 3);
     $id_map = $this->getIdMap();
 
     // Insert 4 message for later delete.
     foreach ($expected_results as $key => $expected_result) {
-      $id_map->saveMessage([$key], $message);
+      $id_map->saveMessage(array($key), $message);
     }
 
     // Truncate and check that 4 messages were deleted.
@@ -204,25 +164,25 @@ public function testClearMessages() {
    */
   public function testGetRowsNeedingUpdate() {
     $id_map = $this->getIdMap();
-    $row_statuses = [
+    $row_statuses = array(
       MigrateIdMapInterface::STATUS_IMPORTED,
       MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
       MigrateIdMapInterface::STATUS_IGNORED,
       MigrateIdMapInterface::STATUS_FAILED,
-    ];
+    );
     // Create a mapping row for each STATUS constant.
     foreach ($row_statuses as $status) {
-      $source = ['source_id_property' => 'source_value_' . $status];
-      $row = new Row($source, ['source_id_property' => []]);
-      $destination = ['destination_id_property' => 'destination_value_' . $status];
+      $source = array('source_id_property' => 'source_value_' . $status);
+      $row = new Row($source, array('source_id_property' => array()));
+      $destination = array('destination_id_property' => 'destination_value_' . $status);
       $id_map->saveIdMapping($row, $destination, $status);
-      $expected_results[] = [
+      $expected_results[] = array(
         'sourceid1' => 'source_value_' . $status,
         'destid1' => 'destination_value_' . $status,
         'source_row_status' => $status,
         'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
         'hash' => '',
-      ];
+      );
       // Assert zero rows need an update.
       if ($status == MigrateIdMapInterface::STATUS_IMPORTED) {
         $rows_needing_update = $id_map->getRowsNeedingUpdate(1);
@@ -230,7 +190,7 @@ public function testGetRowsNeedingUpdate() {
       }
     }
     // Assert that test values exist.
-    $this->queryResultTest($this->getIdMapContents(), $expected_results);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_results);
 
     // Assert a single row needs an update.
     $row_needing_update = $id_map->getRowsNeedingUpdate(1);
@@ -238,15 +198,13 @@ public function testGetRowsNeedingUpdate() {
 
     // Assert the row matches its original source.
     $source_id = $expected_results[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]['sourceid1'];
-    $test_row = $id_map->getRowBySource([$source_id]);
-    // $row_needing_update is an array of objects returned from the database,
-    // but $test_row is an array, so the cast is necessary.
-    $this->assertSame($test_row, (array) $row_needing_update[0]);
+    $test_row = $id_map->getRowBySource(array($source_id));
+    $this->assertSame($test_row, $row_needing_update[0]);
 
     // Add additional row that needs an update.
-    $source = ['source_id_property' => 'source_value_multiple'];
-    $row = new Row($source, ['source_id_property' => []]);
-    $destination = ['destination_id_property' => 'destination_value_multiple'];
+    $source = array('source_id_property' => 'source_value_multiple');
+    $row = new Row($source, array('source_id_property' => array()));
+    $destination = array('destination_id_property' => 'destination_value_multiple');
     $id_map->saveIdMapping($row, $destination, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
 
     // Assert multiple rows need an update.
@@ -259,14 +217,14 @@ public function testGetRowsNeedingUpdate() {
    */
   public function testMessageCount() {
     $message = 'Hello world.';
-    $expected_results = [0, 1, 2, 3];
+    $expected_results = array(0, 1, 2, 3);
     $id_map = $this->getIdMap();
 
     // Test count message multiple times starting from 0.
     foreach ($expected_results as $key => $expected_result) {
       $count = $id_map->messageCount();
       $this->assertEquals($expected_result, $count);
-      $id_map->saveMessage([$key], $message);
+      $id_map->saveMessage(array($key), $message);
     }
   }
 
@@ -275,16 +233,16 @@ public function testMessageCount() {
    */
   public function testMessageSave() {
     $message = 'Hello world.';
-    $expected_results = [
-      1 => ['message' => $message, 'level' => MigrationInterface::MESSAGE_ERROR],
-      2 => ['message' => $message, 'level' => MigrationInterface::MESSAGE_WARNING],
-      3 => ['message' => $message, 'level' => MigrationInterface::MESSAGE_NOTICE],
-      4 => ['message' => $message, 'level' => MigrationInterface::MESSAGE_INFORMATIONAL],
-    ];
+    $expected_results = array(
+      1 => array('message' => $message, 'level' => MigrationInterface::MESSAGE_ERROR),
+      2 => array('message' => $message, 'level' => MigrationInterface::MESSAGE_WARNING),
+      3 => array('message' => $message, 'level' => MigrationInterface::MESSAGE_NOTICE),
+      4 => array('message' => $message, 'level' => MigrationInterface::MESSAGE_INFORMATIONAL),
+    );
     $id_map = $this->getIdMap();
 
     foreach ($expected_results as $key => $expected_result) {
-      $id_map->saveMessage([$key], $message, $expected_result['level']);
+      $id_map->saveMessage(array($key), $message, $expected_result['level']);
       $message_row = $this->database->select($id_map->messageTableName(), 'message')
                        ->fields('message')
                        ->condition('level', $expected_result['level'])
@@ -296,7 +254,7 @@ public function testMessageSave() {
 
     // Insert with default level.
     $message_default = 'Hello world default.';
-    $id_map->saveMessage([5], $message_default);
+    $id_map->saveMessage(array(5), $message_default);
     $message_row = $this->database->select($id_map->messageTableName(), 'message')
                      ->fields('message')
                      ->condition('level', MigrationInterface::MESSAGE_ERROR)
@@ -310,30 +268,29 @@ public function testMessageSave() {
    * Tests the getRowBySource method.
    */
   public function testGetRowBySource() {
-    $this->getDatabase([]);
-    $row = [
+    $row = array(
       'sourceid1' => 'source_id_value_1',
       'sourceid2' => 'source_id_value_2',
       'destid1' => 'destination_id_value_1',
-    ] + $this->idMapDefaults();
-    $this->saveMap($row);
-    $row = [
+    ) + $this->idMapDefaults();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $row = array(
       'sourceid1' => 'source_id_value_3',
       'sourceid2' => 'source_id_value_4',
       'destid1' => 'destination_id_value_2',
-    ] + $this->idMapDefaults();
-    $this->saveMap($row);
-    $source_id_values = [$row['sourceid1'], $row['sourceid2']];
-    $id_map = $this->getIdMap();
+    ) + $this->idMapDefaults();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $source_id_values = array($row['sourceid1'], $row['sourceid2']);
+    $id_map = $this->getIdMap($database_contents);
     $result_row = $id_map->getRowBySource($source_id_values);
     $this->assertSame($row, $result_row);
-    $source_id_values = ['missing_value_1', 'missing_value_2'];
+    $source_id_values = array('missing_value_1', 'missing_value_2');
     $result_row = $id_map->getRowBySource($source_id_values);
     $this->assertFalse($result_row);
   }
 
   /**
-   * Data provider for testLookupDestinationIdMapping().
+   * Tests the destination ID lookup method.
    *
    * Scenarios to test (for both hits and misses) are:
    * - Single-value source ID to single-value destination ID.
@@ -341,13 +298,11 @@ public function testGetRowBySource() {
    * - Single-value source ID to multi-value destination ID.
    * - Multi-value source ID to single-value destination ID.
    */
-  public function lookupDestinationIdMappingDataProvider() {
-    return [
-      [1, 1],
-      [2, 2],
-      [1, 2],
-      [2, 1],
-    ];
+  public function testLookupDestinationIdMapping() {
+    $this->performLookupDestinationIdTest(1, 1);
+    $this->performLookupDestinationIdTest(2, 2);
+    $this->performLookupDestinationIdTest(1, 2);
+    $this->performLookupDestinationIdTest(2, 1);
   }
 
   /**
@@ -357,30 +312,29 @@ public function lookupDestinationIdMappingDataProvider() {
    *   Number of source fields to test.
    * @param int $num_destination_fields
    *   Number of destination fields to test.
-   * @dataProvider lookupDestinationIdMappingDataProvider
    */
-  public function testLookupDestinationIdMapping($num_source_fields, $num_destination_fields) {
+  protected function performLookupDestinationIdTest($num_source_fields, $num_destination_fields) {
     // Adjust the migration configuration according to the number of source and
     // destination fields.
-    $this->sourceIds = [];
-    $this->destinationIds = [];
-    $source_id_values = [];
-    $nonexistent_id_values = [];
+    $this->sourceIds = array();
+    $this->destinationIds = array();
+    $source_id_values = array();
+    $nonexistent_id_values = array();
     $row = $this->idMapDefaults();
     for ($i = 1; $i <= $num_source_fields; $i++) {
       $row["sourceid$i"] = "source_id_value_$i";
       $source_id_values[] = "source_id_value_$i";
       $nonexistent_id_values[] = "nonexistent_source_id_value_$i";
-      $this->sourceIds["source_id_property_$i"] = [];
+      $this->sourceIds["source_id_property_$i"] = array();
     }
-    $expected_result = [];
+    $expected_result = array();
     for ($i = 1; $i <= $num_destination_fields; $i++) {
       $row["destid$i"] = "destination_id_value_$i";
       $expected_result[] = "destination_id_value_$i";
-      $this->destinationIds["destination_id_property_$i"] = [];
+      $this->destinationIds["destination_id_property_$i"] = array();
     }
-    $this->saveMap($row);
-    $id_map = $this->getIdMap();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $id_map = $this->getIdMap($database_contents);
     // Test for a valid hit.
     $destination_id = $id_map->lookupDestinationId($source_id_values);
     $this->assertSame($expected_result, $destination_id);
@@ -393,31 +347,31 @@ public function testLookupDestinationIdMapping($num_source_fields, $num_destinat
    * Tests the getRowByDestination method.
    */
   public function testGetRowByDestination() {
-    $row = [
+    $row = array(
       'sourceid1' => 'source_id_value_1',
       'sourceid2' => 'source_id_value_2',
       'destid1' => 'destination_id_value_1',
-    ] + $this->idMapDefaults();
-    $this->saveMap($row);
-    $row = [
+    ) + $this->idMapDefaults();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $row = array(
       'sourceid1' => 'source_id_value_3',
       'sourceid2' => 'source_id_value_4',
       'destid1' => 'destination_id_value_2',
-    ] + $this->idMapDefaults();
-    $this->saveMap($row);
-    $dest_id_values = [$row['destid1']];
-    $id_map = $this->getIdMap();
+    ) + $this->idMapDefaults();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $dest_id_values = array($row['destid1']);
+    $id_map = $this->getIdMap($database_contents);
     $result_row = $id_map->getRowByDestination($dest_id_values);
     $this->assertSame($row, $result_row);
     // This value does not exist.
-    $dest_id_values = ['invalid_destination_id_property'];
-    $id_map = $this->getIdMap();
+    $dest_id_values = array('invalid_destination_id_property');
+    $id_map = $this->getIdMap($database_contents);
     $result_row = $id_map->getRowByDestination($dest_id_values);
     $this->assertFalse($result_row);
   }
 
   /**
-   * Data provider for testLookupSourceIDMapping().
+   * Tests the source ID lookup method.
    *
    * Scenarios to test (for both hits and misses) are:
    * - Single-value destination ID to single-value source ID.
@@ -425,13 +379,11 @@ public function testGetRowByDestination() {
    * - Single-value destination ID to multi-value source ID.
    * - Multi-value destination ID to single-value source ID.
    */
-  public function lookupSourceIDMappingDataProvider() {
-    return [
-      [1, 1],
-      [2, 2],
-      [1, 2],
-      [2, 1],
-    ];
+  public function testLookupSourceIDMapping() {
+    $this->performLookupSourceIdTest(1, 1);
+    $this->performLookupSourceIdTest(2, 2);
+    $this->performLookupSourceIdTest(1, 2);
+    $this->performLookupSourceIdTest(2, 1);
   }
 
   /**
@@ -441,30 +393,29 @@ public function lookupSourceIDMappingDataProvider() {
    *   Number of source fields to test.
    * @param int $num_destination_fields
    *   Number of destination fields to test.
-   * @dataProvider lookupSourceIDMappingDataProvider
    */
-  public function testLookupSourceIDMapping($num_source_fields, $num_destination_fields) {
+  protected function performLookupSourceIdTest($num_source_fields, $num_destination_fields) {
     // Adjust the migration configuration according to the number of source and
     // destination fields.
-    $this->sourceIds = [];
-    $this->destinationIds = [];
+    $this->sourceIds = array();
+    $this->destinationIds = array();
     $row = $this->idMapDefaults();
-    $expected_result = [];
+    $expected_result = array();
     for ($i = 1; $i <= $num_source_fields; $i++) {
       $row["sourceid$i"] = "source_id_value_$i";
       $expected_result[] = "source_id_value_$i";
-      $this->sourceIds["source_id_property_$i"] = [];
+      $this->sourceIds["source_id_property_$i"] = array();
     }
-    $destination_id_values = [];
-    $nonexistent_id_values = [];
+    $destination_id_values = array();
+    $nonexistent_id_values = array();
     for ($i = 1; $i <= $num_destination_fields; $i++) {
       $row["destid$i"] = "destination_id_value_$i";
       $destination_id_values[] = "destination_id_value_$i";
       $nonexistent_id_values[] = "nonexistent_destination_id_value_$i";
-      $this->destinationIds["destination_id_property_$i"] = [];
+      $this->destinationIds["destination_id_property_$i"] = array();
     }
-    $this->saveMap($row);
-    $id_map = $this->getIdMap();
+    $database_contents['migrate_map_sql_idmap_test'][] = $row;
+    $id_map = $this->getIdMap($database_contents);
     // Test for a valid hit.
     $source_id = $id_map->lookupSourceID($destination_id_values);
     $this->assertSame($expected_result, $source_id);
@@ -484,25 +435,28 @@ public function testLookupSourceIDMapping($num_source_fields, $num_destination_f
   public function testImportedCount() {
     $id_map = $this->getIdMap();
     // Add a single failed row and assert zero imported rows.
-    $source = ['source_id_property' => 'source_value_failed'];
-    $row = new Row($source, ['source_id_property' => []]);
-    $destination = ['destination_id_property' => 'destination_value_failed'];
+    $source = array('source_id_property' => 'source_value_failed');
+    $row = new Row($source, array('source_id_property' => array()));
+    $destination = array('destination_id_property' => 'destination_value_failed');
     $id_map->saveIdMapping($row, $destination, MigrateIdMapInterface::STATUS_FAILED);
-    $this->assertSame(0, (int) $id_map->importedCount());
+    $imported_count = $id_map->importedCount();
+    $this->assertSame(0, $imported_count);
 
     // Add an imported row and assert single count.
-    $source = ['source_id_property' => 'source_value_imported'];
-    $row = new Row($source, ['source_id_property' => []]);
-    $destination = ['destination_id_property' => 'destination_value_imported'];
+    $source = array('source_id_property' => 'source_value_imported');
+    $row = new Row($source, array('source_id_property' => array()));
+    $destination = array('destination_id_property' => 'destination_value_imported');
     $id_map->saveIdMapping($row, $destination, MigrateIdMapInterface::STATUS_IMPORTED);
-    $this->assertSame(1, (int) $id_map->importedCount());
+    $imported_count = $id_map->importedCount();
+    $this->assertSame(1, $imported_count);
 
     // Add a row needing update and assert multiple imported rows.
-    $source = ['source_id_property' => 'source_value_update'];
-    $row = new Row($source, ['source_id_property' => []]);
-    $destination = ['destination_id_property' => 'destination_value_update'];
+    $source = array('source_id_property' => 'source_value_update');
+    $row = new Row($source, array('source_id_property' => array()));
+    $destination = array('destination_id_property' => 'destination_value_update');
     $id_map->saveIdMapping($row, $destination, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
-    $this->assertSame(2, (int) $id_map->importedCount());
+    $imported_count = $id_map->importedCount();
+    $this->assertSame(2, $imported_count);
   }
 
   /**
@@ -516,42 +470,43 @@ public function testImportedCount() {
   public function testProcessedCount() {
     $id_map = $this->getIdMap();
     // Assert zero rows have been processed before adding rows.
-    $this->assertSame(0, (int) $id_map->processedCount());
-    $row_statuses = [
+    $processed_count = $id_map->processedCount();
+    $this->assertSame(0, $processed_count);
+    $row_statuses = array(
       MigrateIdMapInterface::STATUS_IMPORTED,
       MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
       MigrateIdMapInterface::STATUS_IGNORED,
       MigrateIdMapInterface::STATUS_FAILED,
-    ];
+    );
     // Create a mapping row for each STATUS constant.
     foreach ($row_statuses as $status) {
-      $source = ['source_id_property' => 'source_value_' . $status];
-      $row = new Row($source, ['source_id_property' => []]);
-      $destination = ['destination_id_property' => 'destination_value_' . $status];
+      $source = array('source_id_property' => 'source_value_' . $status);
+      $row = new Row($source, array('source_id_property' => array()));
+      $destination = array('destination_id_property' => 'destination_value_' . $status);
       $id_map->saveIdMapping($row, $destination, $status);
       if ($status == MigrateIdMapInterface::STATUS_IMPORTED) {
         // Assert a single row has been processed.
-        $this->assertSame(1, (int) $id_map->processedCount());
+        $processed_count = $id_map->processedCount();
+        $this->assertSame(1, $processed_count);
       }
     }
     // Assert multiple rows have been processed.
-    $this->assertSame(count($row_statuses), (int) $id_map->processedCount());
+    $processed_count = $id_map->processedCount();
+    $this->assertSame(count($row_statuses), $processed_count);
   }
 
   /**
-   * Data provider for testUpdateCount().
+   * Tests the update count method.
    *
    * Scenarios to test for:
    * - No updates.
    * - One update.
    * - Multiple updates.
    */
-  public function updateCountDataProvider() {
-    return [
-      [0],
-      [1],
-      [3],
-    ];
+  public function testUpdateCount() {
+    $this->performUpdateCountTest(0);
+    $this->performUpdateCountTest(1);
+    $this->performUpdateCountTest(3);
   }
 
   /**
@@ -559,41 +514,40 @@ public function updateCountDataProvider() {
    *
    * @param int $num_update_rows
    *   The number of update rows to test.
-   * @dataProvider updateCountDataProvider
    */
-  public function testUpdateCount($num_update_rows) {
+  protected function performUpdateCountTest($num_update_rows) {
+    $database_contents['migrate_map_sql_idmap_test'] = array();
     for ($i = 0; $i < 5; $i++) {
       $row = $this->idMapDefaults();
       $row['sourceid1'] = "source_id_value_$i";
       $row['destid1'] = "destination_id_value_$i";
       $row['source_row_status'] = MigrateIdMapInterface::STATUS_IMPORTED;
-      $this->saveMap($row);
+      $database_contents['migrate_map_sql_idmap_test'][] = $row;
     }
     for (; $i < 5 + $num_update_rows; $i++) {
       $row = $this->idMapDefaults();
       $row['sourceid1'] = "source_id_value_$i";
       $row['destid1'] = "destination_id_value_$i";
       $row['source_row_status'] = MigrateIdMapInterface::STATUS_NEEDS_UPDATE;
-      $this->saveMap($row);
+      $database_contents['migrate_map_sql_idmap_test'][] = $row;
     }
-    $id_map = $this->getIdMap();
-    $this->assertSame($num_update_rows, (int) $id_map->updateCount());
+    $id_map = $this->getIdMap($database_contents);
+    $count = $id_map->updateCount();
+    $this->assertSame($num_update_rows, $count);
   }
 
   /**
-   * Data provider for testErrorCount().
+   * Tests the error count method.
    *
    * Scenarios to test for:
    * - No errors.
    * - One error.
    * - Multiple errors.
    */
-  public function errorCountDataProvider() {
-    return [
-      [0],
-      [1],
-      [3],
-    ];
+  public function testErrorCount() {
+    $this->performErrorCountTest(0);
+    $this->performErrorCountTest(1);
+    $this->performErrorCountTest(3);
   }
 
   /**
@@ -601,25 +555,27 @@ public function errorCountDataProvider() {
    *
    * @param int $num_error_rows
    *   Number of error rows to test.
-   * @dataProvider errorCountDataProvider
    */
-  public function testErrorCount($num_error_rows) {
+  protected function performErrorCountTest($num_error_rows) {
+    $database_contents['migrate_map_sql_idmap_test'] = array();
     for ($i = 0; $i < 5; $i++) {
       $row = $this->idMapDefaults();
       $row['sourceid1'] = "source_id_value_$i";
       $row['destid1'] = "destination_id_value_$i";
       $row['source_row_status'] = MigrateIdMapInterface::STATUS_IMPORTED;
-      $this->saveMap($row);
+      $database_contents['migrate_map_sql_idmap_test'][] = $row;
     }
     for (; $i < 5 + $num_error_rows; $i++) {
       $row = $this->idMapDefaults();
       $row['sourceid1'] = "source_id_value_$i";
       $row['destid1'] = "destination_id_value_$i";
       $row['source_row_status'] = MigrateIdMapInterface::STATUS_FAILED;
-      $this->saveMap($row);
+      $database_contents['migrate_map_sql_idmap_test'][] = $row;
     }
 
-    $this->assertSame($num_error_rows, (int) $this->getIdMap()->errorCount());
+    $id_map = $this->getIdMap($database_contents);
+    $count = $id_map->errorCount();
+    $this->assertSame($num_error_rows, $count);
   }
 
   /**
@@ -627,41 +583,41 @@ public function testErrorCount($num_error_rows) {
    */
   public function testSetUpdate() {
     $id_map = $this->getIdMap();
-    $row_statuses = [
+    $row_statuses = array(
       MigrateIdMapInterface::STATUS_IMPORTED,
       MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
       MigrateIdMapInterface::STATUS_IGNORED,
       MigrateIdMapInterface::STATUS_FAILED,
-    ];
+    );
     // Create a mapping row for each STATUS constant.
     foreach ($row_statuses as $status) {
-      $source = ['source_id_property' => 'source_value_' . $status];
-      $row = new Row($source, ['source_id_property' => []]);
-      $destination = ['destination_id_property' => 'destination_value_' . $status];
+      $source = array('source_id_property' => 'source_value_' . $status);
+      $row = new Row($source, array('source_id_property' => array()));
+      $destination = array('destination_id_property' => 'destination_value_' . $status);
       $id_map->saveIdMapping($row, $destination, $status);
-      $expected_results[] = [
+      $expected_results[] = array(
         'sourceid1' => 'source_value_' . $status,
         'destid1' => 'destination_value_' . $status,
         'source_row_status' => $status,
         'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
         'hash' => '',
-      ];
+      );
     }
     // Assert that test values exist.
-    $this->queryResultTest($this->getIdMapContents(), $expected_results);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_results);
     // Mark each row as STATUS_NEEDS_UPDATE.
     foreach ($row_statuses as $status) {
-      $id_map->setUpdate(['source_value_' . $status]);
+      $id_map->setUpdate(array('source_value_' . $status));
     }
     // Update expected results.
     foreach ($expected_results as $key => $value) {
       $expected_results[$key]['source_row_status'] = MigrateIdMapInterface::STATUS_NEEDS_UPDATE;
     }
     // Assert that updated expected values match.
-    $this->queryResultTest($this->getIdMapContents(), $expected_results);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_results);
     // Assert an exception is thrown when source identifiers are not provided.
     try {
-      $id_map->setUpdate([]);
+      $id_map->setUpdate(array());
       $this->assertFalse(FALSE, 'MigrateException not thrown, when source identifiers were provided to update.');
     }
     catch (MigrateException $e) {
@@ -674,30 +630,30 @@ public function testSetUpdate() {
    */
   public function testPrepareUpdate() {
     $id_map = $this->getIdMap();
-    $row_statuses = [
+    $row_statuses = array(
       MigrateIdMapInterface::STATUS_IMPORTED,
       MigrateIdMapInterface::STATUS_NEEDS_UPDATE,
       MigrateIdMapInterface::STATUS_IGNORED,
       MigrateIdMapInterface::STATUS_FAILED,
-    ];
+    );
 
     // Create a mapping row for each STATUS constant.
     foreach ($row_statuses as $status) {
-      $source = ['source_id_property' => 'source_value_' . $status];
-      $row = new Row($source, ['source_id_property' => []]);
-      $destination = ['destination_id_property' => 'destination_value_' . $status];
+      $source = array('source_id_property' => 'source_value_' . $status);
+      $row = new Row($source, array('source_id_property' => array()));
+      $destination = array('destination_id_property' => 'destination_value_' . $status);
       $id_map->saveIdMapping($row, $destination, $status);
-      $expected_results[] = [
+      $expected_results[] = array(
         'sourceid1' => 'source_value_' . $status,
         'destid1' => 'destination_value_' . $status,
         'source_row_status' => $status,
         'rollback_action' => MigrateIdMapInterface::ROLLBACK_DELETE,
         'hash' => '',
-      ];
+      );
     }
 
     // Assert that test values exist.
-    $this->queryResultTest($this->getIdMapContents(), $expected_results);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_results);
 
     // Mark all rows as STATUS_NEEDS_UPDATE.
     $id_map->prepareUpdate();
@@ -707,7 +663,7 @@ public function testPrepareUpdate() {
       $expected_results[$key]['source_row_status'] = MigrateIdMapInterface::STATUS_NEEDS_UPDATE;
     }
     // Assert that updated expected values match.
-    $this->queryResultTest($this->getIdMapContents(), $expected_results);
+    $this->queryResultTest($this->database->databaseContents['migrate_map_sql_idmap_test'], $expected_results);
   }
 
   /**
@@ -724,9 +680,9 @@ public function testDestroy() {
     $id_map->getDatabase();
     $map_table_name = $id_map->mapTableName();
     $message_table_name = $id_map->messageTableName();
-    $row = new Row(['source_id_property' => 'source_value'], ['source_id_property' => []]);
-    $id_map->saveIdMapping($row, ['destination_id_property' => 2]);
-    $id_map->saveMessage(['source_value'], 'A message');
+    $row = new Row(array('source_id_property' => 'source_value'), array('source_id_property' => array()));
+    $id_map->saveIdMapping($row, array('destination_id_property' => 2));
+    $id_map->saveMessage(array('source_value'), 'A message');
     $this->assertTrue($this->database->schema()->tableExists($map_table_name),
                       "$map_table_name exists");
     $this->assertTrue($this->database->schema()->tableExists($message_table_name),
@@ -739,20 +695,21 @@ public function testDestroy() {
   }
 
   /**
+   * Tests the getQualifiedMapTable method with an unprefixed database.
+   */
+  public function testGetQualifiedMapTableNoPrefix() {
+    $id_map = $this->getIdMap(array(), array('database' => 'source_database'));
+    $qualified_map_table = $id_map->getQualifiedMapTableName();
+    $this->assertEquals('source_database.migrate_map_sql_idmap_test', $qualified_map_table);
+  }
+
+  /**
    * Tests the getQualifiedMapTable method with a prefixed database.
    */
   public function testGetQualifiedMapTablePrefix() {
-    $this->database = $this->getDatabase([], ['database' => 'source_database', 'prefix' => 'prefix']);
-    $qualified_map_table = $this->getIdMap()->getQualifiedMapTableName();
-    // The SQLite driver is a special flower. It will prefix tables with
-    // PREFIX.TABLE, instead of the standard PREFIXTABLE.
-    // @see \Drupal\Core\Database\Driver\sqlite\Connection::__construct()
-    if ($this->database->driver() == 'sqlite') {
-      $this->assertEquals('prefix.migrate_map_sql_idmap_test', $qualified_map_table);
-    }
-    else {
-      $this->assertEquals('source_database.prefixmigrate_map_sql_idmap_test', $qualified_map_table);
-    }
+    $id_map = $this->getIdMap(array(), array('database' => 'source_database'), 'prefix');
+    $qualified_map_table = $id_map->getQualifiedMapTableName();
+    $this->assertEquals('source_database.prefixmigrate_map_sql_idmap_test', $qualified_map_table);
   }
 
   /**
@@ -766,32 +723,18 @@ public function testGetQualifiedMapTablePrefix() {
    * - Sql::current()
    */
   public function testIterators() {
+    $database_contents['migrate_map_sql_idmap_test'] = array();
     for ($i = 0; $i < 3; $i++) {
       $row = $this->idMapDefaults();
       $row['sourceid1'] = "source_id_value_$i";
       $row['destid1'] = "destination_id_value_$i";
       $row['source_row_status'] = MigrateIdMapInterface::STATUS_IMPORTED;
-      $expected_results[serialize(['sourceid1' => $row['sourceid1']])] = ['destid1' => $row['destid1']];
-      $this->saveMap($row);
+      $expected_results[serialize(array('sourceid1' => $row['sourceid1']))] = array('destid1' => $row['destid1']);
+      $database_contents['migrate_map_sql_idmap_test'][] = $row;
     }
 
-    $this->assertSame(iterator_to_array($this->getIdMap()), $expected_results);
-  }
-
-  private function getIdMapContents() {
-    $result = $this->database
-      ->select('migrate_map_sql_idmap_test', 't')
-      ->fields('t')
-      ->execute();
-
-    // The return value needs to be countable, or it will fail certain
-    // assertions. iterator_to_array() will not suffice because it won't
-    // respect the PDO fetch mode, if specified.
-    $contents = [];
-    foreach ($result as $row) {
-      $contents[] = (array) $row;
-    }
-    return $contents;
+    $id_map = $this->getIdMap($database_contents);
+    $this->assertSame(iterator_to_array($id_map), $expected_results);
   }
 
 }
diff --git a/core/modules/migrate/tests/src/Unit/MigrateTestCase.php b/core/modules/migrate/tests/src/Unit/MigrateTestCase.php
index 7a84125..5f8154b 100644
--- a/core/modules/migrate/tests/src/Unit/MigrateTestCase.php
+++ b/core/modules/migrate/tests/src/Unit/MigrateTestCase.php
@@ -7,16 +7,15 @@
 
 namespace Drupal\Tests\migrate\Unit;
 
-use Drupal\Core\Database\Driver\sqlite\Connection;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Tests\UnitTestCase;
+use Drupal\Core\Database\Driver\fake\FakeConnection;
 
 /**
  * Provides setup and helper methods for Migrate module tests.
  */
 abstract class MigrateTestCase extends UnitTestCase {
 
-  protected $migrationConfiguration = [];
+  protected $migrationConfiguration = array();
 
   /**
    * Retrieve a mocked migration.
@@ -55,59 +54,21 @@ protected function getMigration() {
   }
 
   /**
-   * Get an SQLite database connection object for use in tests.
+   * Get a fake database connection object for use in tests.
    *
    * @param array $database_contents
    *   The database contents faked as an array. Each key is a table name, each
    *   value is a list of table rows, an associative array of field => value.
    * @param array $connection_options
-   *  (optional) Options for the database connection.
+   *   (optional) The array of connection options for the database.
+   * @param string $prefix
+   *   (optional) The table prefix on the database.
    *
-   * @return \Drupal\Core\Database\Driver\sqlite\Connection
+   * @return \Drupal\Core\Database\Driver\fake\FakeConnection
    *   The database connection.
    */
-  protected function getDatabase(array $database_contents, $connection_options = []) {
-    if (extension_loaded('pdo_sqlite')) {
-      $connection_options['database'] = ':memory:';
-      $pdo = Connection::open($connection_options);
-      $connection = new Connection($pdo, $connection_options);
-    }
-    else {
-      throw new \Exception('pdo_sqlite extension is required.');
-    }
-
-    // Initialize the DIC with a fake module handler for alterable queries.
-    $container = new ContainerBuilder();
-    $container->set('module_handler', $this->getMock('\Drupal\Core\Extension\ModuleHandlerInterface'));
-    \Drupal::setContainer($container);
-
-    // Create the tables and load them up with data, skipping empty ones.
-    foreach (array_filter($database_contents) as $table => $rows) {
-      $pilot_row = reset($rows);
-      $connection->schema()->createTable($table, $this->createSchemaFromRow($pilot_row));
-
-      $insert = $connection->insert($table)->fields(array_keys($pilot_row));
-      array_walk($rows, [$insert, 'values']);
-      $insert->execute();
-    }
-
-    return $connection;
-  }
-
-  /**
-   * Generates a table schema from a row.
-   *
-   * @param array $row
-   *  The reference row on which to base the schema.
-   *
-   * @return array
-   *  The Schema API-ready table schema.
-   */
-  protected function createSchemaFromRow(array $row) {
-    // SQLite uses loose ("affinity") typing, so it's OK for every column
-    // to be a text field.
-    $fields = array_map(function() { return ['type' => 'text']; }, $row);
-    return ['fields' => $fields];
+  protected function getDatabase(array $database_contents, $connection_options = array(), $prefix = '') {
+    return new FakeConnection($database_contents, $connection_options, $prefix);
   }
 
   /**
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_display.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_display.yml
index dd6be79..7101ee9 100644
--- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_display.yml
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_display.yml
@@ -3,7 +3,7 @@ label: Drupal 6 user picture display configuration
 migration_tags:
   - Drupal 6
 source:
-  plugin: d6_user_picture_instance
+  plugin: user_picture_instance
   constants:
     entity_type: user
     bundle: user
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_form_display.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_form_display.yml
index 9d2182b..6262eb8 100644
--- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_form_display.yml
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_entity_form_display.yml
@@ -3,7 +3,7 @@ label: Drupal 6 user picture form display configuration
 migration_tags:
   - Drupal 6
 source:
-  plugin: d6_user_picture_instance
+  plugin: user_picture_instance
   constants:
     entity_type: user
     bundle: user
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_field_instance.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_field_instance.yml
index 14dfc0e..a2459a0 100644
--- a/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_field_instance.yml
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d6_user_picture_field_instance.yml
@@ -3,7 +3,7 @@ label: Drupal 6 user picture field instance configuration
 migration_tags:
   - Drupal 6
 source:
-  plugin: d6_user_picture_instance
+  plugin: user_picture_instance
   constants:
     entity_type: user
     bundle: user
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user.yml
new file mode 100755
index 0000000..c5efbe3
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user.yml
@@ -0,0 +1,34 @@
+id: d7_user
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_user
+destination:
+  plugin: entity:user
+process:
+  uid: uid
+  name: name
+  pass: pass
+  mail: mail
+  status: status
+  created: created
+  changed: changed
+  access: access
+  login: login
+  timezone: timezone
+  langcode: language
+  preferred_langcode: language
+  preferred_admin_langcode: language
+  init: init
+  roles:
+    plugin: migration
+    migration: d7_user_role
+    source: roles
+migration_dependencies:
+  required:
+    - d7_user_role
+dependencies:
+  module:
+    - user
+  config:
+    - migrate.migration.d7_user_role
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_flood.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_flood.yml
new file mode 100755
index 0000000..b568949
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_flood.yml
@@ -0,0 +1,23 @@
+id: d7_user_flood
+migration_tags:
+  - Drupal 7
+source:
+  plugin: variable
+  variables:
+    - user_failed_login_identifier_uid_only
+    - user_failed_login_ip_limit
+    - user_failed_login_ip_window
+    - user_failed_login_user_window
+    - user_failed_login_user_limit
+process:
+  uid_only: user_failed_login_identifier_uid_only
+  ip_limit: user_failed_login_ip_limit
+  ip_window: user_failed_login_ip_window
+  user_limit: user_failed_login_user_limit
+  user_window: user_failed_login_user_window
+destination:
+  plugin: config
+  config_name: user.flood
+dependencies:
+  module:
+    - user
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_mail.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_mail.yml
new file mode 100644
index 0000000..8111e59
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_mail.yml
@@ -0,0 +1,42 @@
+id: d7_user_mail
+label: Drupal 7 user mail configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: variable
+  variables:
+    - user_mail_status_activated_subject
+    - user_mail_status_activated_body
+    - user_mail_password_reset_subject
+    - user_mail_password_reset_body
+    - user_mail_status_deleted_subject
+    - user_mail_status_deleted_body
+    - user_mail_register_admin_created_subject
+    - user_mail_register_admin_created_body
+    - user_mail_register_no_approval_required_subject
+    - user_mail_register_no_approval_required_body
+    - user_mail_user_mail_register_pending_approval_subject
+    - user_mail_user_mail_register_pending_approval_body
+    - user_mail_status_blocked_subject
+    - user_mail_status_blocked_body
+process:
+  'status_activated/subject': user_mail_status_activated_subject
+  'status_activated/body': user_mail_status_activated_body
+  'password_reset/subject': user_mail_password_reset_subject
+  'password_reset/body': user_mail_password_reset_body
+  'cancel_confirm/subject': user_mail_status_deleted_subject
+  'cancel_confirm/body': user_mail_status_deleted_body
+  'register_admin_created/subject': user_mail_register_admin_created_subject
+  'register_admin_created/body': user_mail_register_admin_created_body
+  'register_no_approval_required/subject': user_mail_register_no_approval_required_subject
+  'register_no_approval_required/body': user_mail_register_no_approval_required_body
+  'register_pending_approval/subject': user_mail_user_mail_register_pending_approval_subject
+  'register_pending_approval/body': user_mail_user_mail_register_pending_approval_body
+  'status_blocked/subject': user_mail_status_blocked_subject
+  'status_blocked/body': user_mail_status_blocked_body
+destination:
+  plugin: config
+  config_name: user.mail
+dependencies:
+  module:
+    - user
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_display.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_display.yml
new file mode 100755
index 0000000..8d88d86
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_display.yml
@@ -0,0 +1,30 @@
+id: d7_user_picture_entity_display
+label: Drupal 7 user picture display configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: user_picture_instance
+  constants:
+    entity_type: user
+    bundle: user
+    view_mode: default
+    name: user_picture
+    type: image
+    options:
+      label: hidden
+      settings:
+        image_style: ''
+        image_link: content
+process:
+  entity_type: 'constants/entity_type'
+  bundle: 'constants/bundle'
+  view_mode: 'constants/view_mode'
+  field_name: 'constants/name'
+  type: 'constants/type'
+  options: 'constants/options'
+  'options/type': @type
+destination:
+  plugin: component_entity_display
+migration_dependencies:
+  required:
+    - d7_user_picture_field_instance
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_form_display.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_form_display.yml
new file mode 100755
index 0000000..1cf89be
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_entity_form_display.yml
@@ -0,0 +1,29 @@
+id: d7_user_picture_entity_form_display
+label: Drupal 7 user picture form display configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: user_picture_instance
+  constants:
+    entity_type: user
+    bundle: user
+    form_mode: default
+    name: user_picture
+    type: image_image
+    options:
+      settings:
+        progress_indicator: throbber
+        preview_image_style: thumbnail
+process:
+  entity_type: 'constants/entity_type'
+  bundle: 'constants/bundle'
+  field_name: 'constants/name'
+  form_mode: 'constants/form_mode'
+  type: 'constants/type'
+  options: 'constants/options'
+  'options/type': @type
+destination:
+  plugin: component_entity_form_display
+migration_dependencies:
+  required:
+    - d7_user_picture_field_instance
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field.yml
new file mode 100755
index 0000000..f9060d1
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field.yml
@@ -0,0 +1,20 @@
+id: d7_user_picture_field
+label: Drupal 7 user picture field configuration
+migration_tags:
+  - Drupal 7
+source:
+  # We do an empty source and a proper destination to have an idmap for
+  # dependencies.
+  plugin: empty
+  constants:
+    entity_type: user
+    type: image
+    name: user_picture
+    cardinality: 1
+process:
+  entity_type: 'constants/entity_type'
+  field_name: 'constants/name'
+  type: 'constants/type'
+  cardinality: 'constants/cardinality'
+destination:
+  plugin: entity:field_storage_config
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field_instance.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field_instance.yml
new file mode 100755
index 0000000..2d3927e
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_picture_field_instance.yml
@@ -0,0 +1,30 @@
+id: d7_user_picture_field_instance
+label: Drupal 7 user picture field instance configuration
+migration_tags:
+  - Drupal 7
+source:
+  plugin: user_picture_instance
+  constants:
+    entity_type: user
+    bundle: user
+    name: user_picture
+    settings:
+      file_extensions: 'png gif jpg jpeg'
+      alt_field: false
+      title_field: false
+      min_resolution: ''
+      alt_field_required: false
+      title_field_required: false
+process:
+  entity_type: 'constants/entity_type'
+  bundle: 'constants/bundle'
+  field_name: 'constants/name'
+  settings: 'constants/settings'
+  'settings/file_directory': file_directory
+  'settings/max_filesize': max_filesize
+  'settings/max_resolution': max_resolution
+destination:
+  plugin: entity:field_config
+migration_dependencies:
+  required:
+    - d7_user_picture_field
diff --git a/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_role.yml b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_role.yml
new file mode 100755
index 0000000..01eeb85
--- /dev/null
+++ b/core/modules/migrate_drupal/config/optional/migrate.migration.d7_user_role.yml
@@ -0,0 +1,46 @@
+id: d7_user_role
+label: Drupal 7 user roles
+migration_tags:
+  - Drupal 7
+source:
+  plugin: d7_user_role
+process:
+  id:
+    -
+      plugin: machine_name
+      source: name
+    -
+      plugin: dedupe_entity
+      entity_type: user_role
+      field: id
+      length: 32
+  label: name
+  permissions:
+    -
+      plugin: static_map
+      source: permissions
+      bypass: true
+      map:
+        'use PHP for block visibility': 'use PHP for settings'
+        'administer site-wide contact form': 'administer contact forms'
+        'post comments without approval': 'skip comment approval'
+        'edit own blog entries' : 'edit own blog content'
+        'edit any blog entry' : 'edit any blog content'
+        'delete own blog entries' : 'delete own blog content'
+        'delete any blog entry' : 'delete any blog content'
+        'create forum topics' : 'create forum content'
+        'delete any forum topic' : 'delete any forum content'
+        'delete own forum topics' : 'delete own forum content'
+        'edit any forum topic' : 'edit any forum content'
+        'edit own forum topics' : 'edit own forum content'
+    # - plugin: system_update_7000
+    # - plugin: node_update_7008
+    - plugin: flatten
+destination:
+  plugin: entity:user_role
+migration_dependencies:
+  optional:
+    - d7_filter_format
+dependencies:
+  module:
+    - user
diff --git a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
index 2f23e0c..93299a4 100644
--- a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
+++ b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml
@@ -264,7 +264,7 @@ migrate.source.d6_user_picture_file:
           type: boolean
           label: 'Public'
 
-migrate.source.d6_user_picture_instance:
+migrate.source.user_picture_instance:
   type: migrate_source_sql
   label: 'Drupal 6 user picure display'
   mapping:
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/UserPictureInstance.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/UserPictureInstance.php
new file mode 100644
index 0000000..0111c76
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/UserPictureInstance.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Plugin\migrate\source\UserPictureInstance.
+ */
+
+namespace Drupal\migrate_drupal\Plugin\migrate\source;
+
+/**
+ * User picture field instance source.
+ *
+ * @todo Support default picture?
+ *
+ * @MigrateSource(
+ *   id = "user_picture_instance"
+ * )
+ */
+class UserPictureInstance extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function initializeIterator() {
+    return new \ArrayIterator(array(
+      array(
+        'id' => '',
+        'file_directory' => $this->variableGet('user_picture_path', 'pictures'),
+        'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB',
+        'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'),
+      )));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'file_directory' => 'The directory to store images..',
+      'max_filesize' => 'The maximum allowed file size in KBs.',
+      'max_resolution' => "The maximum resolution.",
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    $ids['id']['type'] = 'string';
+    return $ids;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    // Nothing to do here.
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Action.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Action.php
index d3c7533..274190b 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Action.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Action.php
@@ -22,7 +22,8 @@ class Action extends DrupalSqlBase {
    * {@inheritdoc}
    */
   public function query() {
-    $query = $this->select('actions', 'a')
+    $query = $this->database
+      ->select('actions', 'a')
       ->fields('a', array(
         'aid',
         'type',
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Term.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Term.php
index 8d64d39..98aac3d 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Term.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/Term.php
@@ -32,8 +32,7 @@ public function query() {
       ->fields('td', array('tid', 'vid', 'name', 'description', 'weight'))
     // This works, but we cannot test that, because there is no support for
     // distinct() in FakeSelect, yet.
-      ->distinct()
-      ->orderBy('tid');
+      ->distinct();
     if (isset($this->configuration['vocabulary'])) {
       $query->condition('vid', $this->configuration['vocabulary'], 'IN');
     }
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPicture.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPicture.php
index c45f269..9efa99d 100644
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPicture.php
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPicture.php
@@ -24,7 +24,8 @@ class UserPicture extends DrupalSqlBase {
    * {@inheritdoc}
    */
   public function query() {
-    $query = $this->select('users', 'u')
+    $query = $this->getDatabase()
+      ->select('users', 'u')
       ->condition('picture', '', '<>')
       ->fields('u', array('uid', 'access', 'picture'))
       ->orderBy('access');
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPictureInstance.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPictureInstance.php
deleted file mode 100644
index 667a551..0000000
--- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/UserPictureInstance.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\migrate_drupal\Plugin\migrate\source\d6\UserPictureInstance.
- */
-
-namespace Drupal\migrate_drupal\Plugin\migrate\source\d6;
-
-use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
-
-/**
- * Drupal 6 user picture field instance source.
- *
- * @todo Support default picture?
- *
- * @MigrateSource(
- *   id = "d6_user_picture_instance"
- * )
- */
-class UserPictureInstance extends DrupalSqlBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initializeIterator() {
-    return new \ArrayIterator(array(
-      array(
-        'id' => '',
-        'file_directory' => $this->variableGet('user_picture_path', 'pictures'),
-        'max_filesize' => $this->variableGet('user_picture_file_size', '30') . 'KB',
-        'max_resolution' => $this->variableGet('user_picture_dimensions', '85x85'),
-      )));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function fields() {
-    return array(
-      'file_directory' => 'The directory to store images..',
-      'max_filesize' => 'The maximum allowed file size in KBs.',
-      'max_resolution' => "The maximum resolution.",
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getIds() {
-    $ids['id']['type'] = 'string';
-    return $ids;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function query() {
-    // Nothing to do here.
-  }
-
-}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/Role.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/Role.php
new file mode 100755
index 0000000..f150954
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/Role.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Plugin\migrate\source\d7\Role.
+ */
+
+namespace Drupal\migrate_drupal\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+
+/**
+ * Drupal 7 role source from database.
+ *
+ * @MigrateSource(
+ *   id = "d7_user_role"
+ * )
+ */
+class Role extends DrupalSqlBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('role', 'r')
+      ->fields('r', array('rid', 'name'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function fields() {
+    return array(
+      'rid' => $this->t('Role ID.'),
+      'name' => $this->t('The name of the user role.'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $permissions = $this->select('role_permission', 'rp')
+      ->fields('rp', ['permission'])
+      ->condition('rid', $row->getSourceProperty('rid'))
+      ->execute()
+      ->fetchCol();
+    $row->setSourceProperty('permissions', $permissions);
+
+    return parent::prepareRow($row);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return ['rid' => ['type' => 'integer']];
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/User.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/User.php
new file mode 100755
index 0000000..a1ea43d
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d7/User.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Plugin\migrate\source\d7\User.
+ */
+
+namespace Drupal\migrate_drupal\Plugin\migrate\source\d7;
+
+use Drupal\migrate\Plugin\SourceEntityInterface;
+use Drupal\migrate\Row;
+use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
+
+/**
+ * Extract users from Drupal 7 database.
+ *
+ * @MigrateSource(
+ *   id = "d7_user"
+ * )
+ */
+class User extends DrupalSqlBase implements SourceEntityInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {
+    return $this->select('users', 'u')
+      ->fields('u', array_keys($this->fields()))
+      ->condition('uid', 0, '>');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepareRow(Row $row) {
+    $roles = $this->select('role', 'r')
+      ->fields('r', ['rid', 'name']);
+    $roles->join('users_roles', 'ur', 'ur.rid = r.rid');
+    // These extra fields are not needed once #2499835 lands.
+    $roles->fields('ur', ['uid', 'rid']);
+    $roles->condition('ur.uid', $row->getSourceProperty('uid'));
+    $row->setSourceProperty('roles', $roles->execute()->fetchAllKeyed(2, 3));
+  }
+
+  /**
+  * {@inheritdoc}
+  */
+  public function fields() {
+    return array(
+      'uid' => $this->t('User ID'),
+      'name' => $this->t('Username'),
+      'pass' => $this->t('Password'),
+      'mail' => $this->t('Email address'),
+      'signature' => $this->t('Signature'),
+      'signature_format' => $this->t('Signature format'),
+      'created' => $this->t('Registered timestamp'),
+      'access' => $this->t('Last access timestamp'),
+      'login' => $this->t('Last login timestamp'),
+      'status' => $this->t('Status'),
+      'timezone' => $this->t('Timezone'),
+      'language' => $this->t('Language'),
+      'picture' => $this->t('Picture'),
+      'init' => $this->t('Init'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getIds() {
+    return array(
+      'uid' => array(
+        'type' => 'integer',
+        'alias' => 'u',
+      ),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function bundleMigrationRequired() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function entityTypeId() {
+    return 'user';
+  }
+
+}
\ No newline at end of file
diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Users.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Users.php
index 33d7f59..e5d9f1d 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Users.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Users.php
@@ -88,7 +88,7 @@ public function load() {
         'status' => array(
           'type' => 'int',
           'not null' => TRUE,
-          'length' => '4',
+          'length' => '11',
           'default' => '0',
         ),
         'timezone' => array(
@@ -139,8 +139,25 @@ public function load() {
       'init',
       'data',
     ))
-    ->execute();
+    ->values(array(
+      'uid' => '2',
+      'name' => 'Odo',
+      'pass' => '$S$DVpvPItXvnsmF3giVEe7Jy2lG.SCoEs8uKwpHsyPvdeNAaNZYxZ8',
+      'mail' => 'odo@local.host',
+      'theme' => '',
+      'signature' => '',
+      'signature_format' => 'filtered_html',
+      'created' => '1432750741',
+      'access' => '0',
+      'login' => '0',
+      'status' => '1',
+      'timezone' => 'America/Chicago',
+      'language' => '',
+      'picture' => '0',
+      'init' => 'odo@local.host',
+      'data' => 'a:1:{s:7:"contact";i:1;}',
+    ))->execute();
   }
 
 }
-#bb60d488e9420b75be9bb507fc35df8b
+#e53c042361fbbccb2bbc9918c072e19f
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 c66d152..423be1c 100644
--- a/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
+++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Variable.php
@@ -101,7 +101,7 @@ public function load() {
       'value' => 's:43:"_vWFj-dRR2rNoHDwl7N__J9uZNutDcLz3w4tlPJzRAM";',
     ))->values(array(
       'name' => 'cron_last',
-      'value' => 'i:1432653550;',
+      'value' => 'i:1432750697;',
     ))->values(array(
       'name' => 'css_js_query_string',
       'value' => 's:6:"nihmmw";',
@@ -304,6 +304,12 @@ public function load() {
       'name' => 'suppress_itok_output',
       'value' => 'b:1;',
     ))->values(array(
+      'name' => 'taxonomy_override_selector',
+      'value' => 'b:1;',
+    ))->values(array(
+      'name' => 'taxonomy_terms_per_page_admin',
+      'value' => 'i:84;',
+    ))->values(array(
       'name' => 'theme_default',
       'value' => 's:6:"bartik";',
     ))->values(array(
@@ -418,4 +424,4 @@ public function load() {
   }
 
 }
-#d17f3e6a80f5f51c105acf809f1b4851
+#59776f583c1268ef59315caaef4996e5
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserFloodTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserFloodTest.php
new file mode 100644
index 0000000..afdb7ba
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserFloodTest.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserFloodTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * Migrates user flood control configuration.
+ *
+ * @group migrate_drupal 7.x
+ * @dumpFile d7/Variable.php
+ * @migration d7_user_flood
+ */
+class MigrateUserFloodTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = array('system');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig(['user']);
+
+    // Load database dumps to provide source data.
+    $dumps = array(
+      $this->getDumpDirectory() . '/Variable.php',
+    );
+    $this->loadDumps($dumps);
+
+    // Migrate users.
+    $migration = entity_load('migration', 'd7_user_flood');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Tests the migration.
+   */
+  public function testMigration() {
+    $expected = [
+      'uid_only' => TRUE,
+      'ip_limit' => 30,
+      'ip_window' => 7200,
+      'user_limit' => 22,
+      'user_window' => 86400,
+    ];
+    $this->assertIdentical($expected, \Drupal::config('user.flood')->get());
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserMailTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserMailTest.php
new file mode 100644
index 0000000..878a40f
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserMailTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserMailTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * Migrates user mail configuration.
+ *
+ * @group migrate_drupal 7.x
+ * @dumpFile d7/Variable.php
+ * @migration d7_user_mail
+ */
+class MigrateUserMailTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = ['system', 'user'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installConfig(['user']);
+
+    // Load database dumps to provide source data.
+    $dumps = [
+      $this->getDumpDirectory() . '/Variable.php',
+    ];
+    $this->loadDumps($dumps);
+
+    // Migrate users.
+    $migration = entity_load('migration', 'd7_user_mail');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Tests the migration.
+   */
+  public function testMigration() {
+    $config = \Drupal::config('user.mail');
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityDisplayTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityDisplayTest.php
new file mode 100644
index 0000000..24d5d22
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityDisplayTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserPictureEntityDisplayTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * User picture entity display.
+ *
+ * @group migrate_drupal 7.x
+ * @migration d7_user_picture_entity_display
+ */
+class MigrateUserPictureEntityDisplayTest extends MigrateDrupal7TestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  static $modules = array('image');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $id_mappings = array(
+      'd7_user_picture_field_instance' => array(
+        array(array(1), array('user', 'user', 'user_picture')),
+      ),
+    );
+    $this->prepareMigrations($id_mappings);
+
+    $migration = entity_load('migration', 'd7_user_picture_entity_display');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Tests the Drupal 7 user picture to Drupal 8 entity display migration.
+   */
+  public function testUserPictureEntityDisplay() {
+    $component = entity_get_display('user', 'user', 'default')->getComponent('user_picture');
+    $this->assertIdentical('image', $component['type']);
+    $this->assertIdentical('', $component['settings']['image_style']);
+    $this->assertIdentical('content', $component['settings']['image_link']);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityFormDisplayTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityFormDisplayTest.php
new file mode 100644
index 0000000..c35b0c6
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureEntityFormDisplayTest.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserPictureEntityFormDisplayTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * Tests migration of the user_picture field's entity form display settings.
+ *
+ * @group migrate_drupal 7.x
+ * @migration d7_user_picture_field
+ * @migration d7_user_picture_field_instance
+ * @migration d7_user_picture_entity_form_display
+ */
+class MigrateUserPictureEntityFormDisplayTest extends MigrateDrupal7TestBase {
+
+  static $modules = array('image', 'file');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $migration = entity_load('migration', 'd7_user_picture_field');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+
+    $migration = entity_load('migration', 'd7_user_picture_field_instance');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+
+    $migration = entity_load('migration', 'd7_user_picture_entity_form_display');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Tests the field's entity form display settings.
+   */
+  public function testEntityFormDisplaySettings() {
+    $component = entity_get_form_display('user', 'user', 'default')->getComponent('user_picture');
+    $this->assertIdentical('image_image', $component['type']);
+    $this->assertIdentical('throbber', $component['settings']['progress_indicator']);
+    $this->assertIdentical('thumbnail', $component['settings']['preview_image_style']);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldInstanceTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldInstanceTest.php
new file mode 100644
index 0000000..1a9dad8
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldInstanceTest.php
@@ -0,0 +1,52 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserPictureFieldInstanceTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\Core\Field\FieldConfigInterface;
+use Drupal\field\Entity\FieldConfig;
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * User picture field instance migration.
+ *
+ * @group migrate_drupal 7.x
+ * @migration d7_user_picture_field
+ * @migration d7_user_picture_field_instance
+ */
+class MigrateUserPictureFieldInstanceTest extends MigrateDrupal7TestBase {
+
+  static $modules = array('image', 'file');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $migration = entity_load('migration', 'd7_user_picture_field');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+
+    $migration = entity_load('migration', 'd7_user_picture_field_instance');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Test the user picture field migration.
+   */
+  public function testUserPictureField() {
+    /** @var \Drupal\field\FieldConfigInterface $field */
+    $field = FieldConfig::load('user.user.user_picture');
+    $this->assertTrue($field instanceof FieldConfigInterface);
+    $this->assertIdentical('user', $field->getTargetEntityTypeId());
+    $this->assertIdentical('user', $field->getTargetBundle());
+    $this->assertIdentical('user_picture', $field->getName());
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldTest.php
new file mode 100644
index 0000000..b415ad6
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserPictureFieldTest.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserPictureFieldTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\field\Entity\FieldStorageConfig;
+use Drupal\field\FieldStorageConfigInterface;
+use Drupal\migrate\MigrateExecutable;
+
+/**
+ * User picture field migration.
+ *
+ * @group migrate_drupal 7.x
+ * @migration d7_user_picture_field
+ */
+class MigrateUserPictureFieldTest extends MigrateDrupal7TestBase {
+
+  static $modules = array('image', 'file');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $migration = entity_load('migration', 'd7_user_picture_field');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  /**
+   * Test the user picture field migration.
+   */
+  public function testUserPictureField() {
+    /** @var \Drupal\field\FieldStorageConfigInterface $field_storage */
+    $field_storage = FieldStorageConfig::load('user.user_picture');
+    $this->assertTrue($field_storage instanceof FieldStorageConfigInterface);
+    $this->assertIdentical('user.user_picture', $field_storage->id());
+    $this->assertIdentical('image', $field_storage->getType());
+    $this->assertIdentical('user', $field_storage->getTargetEntityTypeId());
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserRoleTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserRoleTest.php
new file mode 100644
index 0000000..7786804
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserRoleTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserRoleTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\Core\Database\Database;
+use Drupal\migrate\MigrateExecutable;
+use Drupal\user\Entity\Role;
+use Drupal\user\RoleInterface;
+
+/**
+ * Upgrade user roles to user.role.*.yml.
+ *
+ * @group migrate_drupal 7.x
+ * @dumpFile d7/Role.php
+ * @dumpFile d7/RolePermission.php
+ * @dumpFile d7/Variable.php
+ * @migration d7_user_role
+ */
+class MigrateUserRoleTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = array('user');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    /** @var \Drupal\migrate\entity\Migration $migration */
+    $migration = entity_load('migration', 'd7_user_role');
+    $dumps = array(
+      $this->getDumpDirectory() . '/Role.php',
+      $this->getDumpDirectory() . '/RolePermission.php',
+      $this->getDumpDirectory() . '/Variable.php',
+    );
+    $this->prepare($migration, $dumps);
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  protected function assertEntity($id, $label, $original_rid = NULL) {
+    /** @var \Drupal\user\RoleInterface $entity */
+    $entity = Role::load($id);
+    $this->assertTrue($entity instanceof RoleInterface);
+    $this->assertIdentical($label, $entity->label());
+    if (isset($original_rid)) {
+      $permissions = Database::getConnection('default', 'migrate')
+        ->select('role_permission', 'rp')
+        ->fields('rp', ['permission'])
+        ->condition('rid', $original_rid)
+        ->execute()
+        ->fetchCol();
+      $this->assertIdentical($permissions, $entity->getPermissions());
+    }
+  }
+
+  /**
+   * Tests user role migration.
+   */
+  public function testUserRole() {
+    $this->assertEntity('anonymous_user', 'anonymous user', 1);
+    $this->assertEntity('authenticated_user', 'authenticated user', 2);
+    $this->assertEntity('administrator', 'administrator', 3);
+  }
+
+}
diff --git a/core/modules/migrate_drupal/src/Tests/d7/MigrateUserTest.php b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserTest.php
new file mode 100644
index 0000000..368ae28
--- /dev/null
+++ b/core/modules/migrate_drupal/src/Tests/d7/MigrateUserTest.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\migrate_drupal\Tests\d7\MigrateUserTest.
+ */
+
+namespace Drupal\migrate_drupal\Tests\d7;
+
+use Drupal\user\Entity\User;
+use Drupal\file\Entity\File;
+use Drupal\Core\Database\Database;
+use Drupal\migrate\MigrateExecutable;
+use Drupal\user\RoleInterface;
+use Drupal\user\UserInterface;
+
+/**
+ * Users migration.
+ *
+ * @group migrate_drupal 7.x
+ * @dumpFile d7/Role.php
+ * @dumpFile d7/RolePermission.php
+ * @dumpFile d7/Users.php
+ * @dumpFile d7/UsersRoles.php
+ * @migration d7_user_role
+ * @migration d7_user
+ */
+class MigrateUserTest extends MigrateDrupal7TestBase {
+
+  /**
+   * The modules to be enabled during the test.
+   *
+   * @var array
+   */
+  static $modules = array('user');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // Load database dumps to provide source data.
+    $dumps = array(
+      $this->getDumpDirectory() . '/Role.php',
+      $this->getDumpDirectory() . '/RolePermission.php',
+      $this->getDumpDirectory() . '/Users.php',
+      $this->getDumpDirectory() . '/UsersRoles.php',
+    );
+    $this->loadDumps($dumps);
+
+    $migration = entity_load('migration', 'd7_user_role');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+
+    $migration = entity_load('migration', 'd7_user');
+    $executable = new MigrateExecutable($migration, $this);
+    $executable->import();
+  }
+
+  protected function assertEntity($id, $label, $mail, $created, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID]) {
+    /** @var \Drupal\user\UserInterface $user */
+    $user = User::load($id);
+    $this->assertTrue($user instanceof UserInterface);
+    $this->assertIdentical($label, $user->label());
+    $this->assertIdentical($mail, $user->getEmail());
+    $this->assertIdentical($created, $user->getCreatedTime());
+    $this->assertIdentical($access, $user->getLastAccessedTime());
+    $this->assertIdentical($login, $user->getLastLoginTime());
+    $this->assertIdentical($blocked, $user->isBlocked());
+    // $user->getPreferredLangcode() might fallback to default language if the
+    // user preferred language is not configured on the site. We just want to
+    // test if the value was imported correctly.
+    $this->assertIdentical($langcode, $user->langcode->value);
+    $this->assertIdentical($langcode, $user->preferred_langcode->value);
+    $this->assertIdentical($langcode, $user->preferred_admin_langcode->value);
+    $this->assertIdentical($init, $user->getInitialEmail());
+    $this->assertIdentical($roles, $user->getRoles());
+  }
+
+  /**
+   * Tests the Drupal 7 user to Drupal 8 migration.
+   */
+  public function testUser() {
+    $this->assertEntity(2, 'Odo', 'odo@local.host', '1432750741', '0', '0', FALSE, '', 'odo@local.host');
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/FieldInstanceTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/FieldInstanceTest.php
index 5a987fc..1eaeef9 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/FieldInstanceTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/FieldInstanceTest.php
@@ -21,20 +21,20 @@ class FieldInstanceTest extends MigrateSqlSourceTestCase {
   const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\FieldInstance';
 
   // The fake Migration configuration entity.
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     // The id of the entity, can be any string.
     'id' => 'test_fieldinstance',
     // Leave it empty for now.
-    'idlist' => [],
-    'source' => [
-      'plugin' => 'd6_field_instance',
-    ],
-  ];
+    'idlist' => array(),
+    'source' => array(
+      'plugin' => 'd6_fieldinstance',
+    ),
+  );
 
   // We need to set up the database contents; it's easier to do that below.
   // These are sample result queries.
-  protected $expectedResults = [
-    [
+  protected $expectedResults = array(
+    array(
       'field_name' => 'field_body',
       'type_name' => 'page',
       'weight' => 1,
@@ -47,51 +47,50 @@ class FieldInstanceTest extends MigrateSqlSourceTestCase {
       'widget_active' => 1,
       'required' => 1,
       'active' => 1,
-      'global_settings' => [],
-    ],
-  ];
+      'global_settings' => array(),
+    ),
+  );
 
   /**
    * Prepopulate contents with results.
    */
   protected function setUp() {
-    $this->expectedResults[0]['widget_settings'] = [
+    $this->expectedResults[0]['widget_settings'] = array(
       'rows' => 5,
       'size' => 60,
-      'default_value' => [
-        [
+      'default_value' => array(
+        array(
           'value' => '',
           '_error_element' => 'default_value_widget][field_body][0][value',
           'default_value_php' => '',
-        ],
-      ],
-    ];
-    $this->expectedResults[0]['display_settings'] = [
-      'label' => [
+        ),
+      ),
+    );
+    $this->expectedResults[0]['display_settings'] = array(
+      'label' => array(
         'format' => 'above',
         'exclude' => 0,
-      ],
-      'teaser' => [
+      ),
+      'teaser' => array(
         'format' => 'default',
         'exclude' => 0,
-      ],
-      'full' => [
+      ),
+      'full' => array(
         'format' => 'default',
         'exclude' => 0,
-      ],
-    ];
+      ),
+    );
     $this->databaseContents['content_node_field_instance'] = $this->expectedResults;
     $this->databaseContents['content_node_field_instance'][0]['widget_settings'] = serialize($this->expectedResults[0]['widget_settings']);
     $this->databaseContents['content_node_field_instance'][0]['display_settings'] = serialize($this->expectedResults[0]['display_settings']);
-    $this->databaseContents['content_node_field_instance'][0]['global_settings'] = 'a:0:{}';
 
-    $this->databaseContents['content_node_field'][0] = [
+    $this->databaseContents['content_node_field'][0] = array(
       'field_name' => 'field_body',
       'required' => 1,
       'type' => 'text',
       'active' => 1,
-      'global_settings' => serialize([]),
-    ];
+      'global_settings' => serialize(array()),
+    );
     parent::setUp();
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
index e4e7acb..9abbd63 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionByNodeTypeTest.php
@@ -19,118 +19,30 @@ class NodeRevisionByNodeTypeTest extends MigrateSqlSourceTestCase {
   const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\NodeRevision';
 
   // The fake Migration configuration entity.
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     'id' => 'test',
     // Leave it empty for now.
-    'idlist' => [],
+    'idlist' => array(),
     // The fake configuration for the source.
-    'source' => [
+    'source' => array(
       'plugin' => 'd6_node_revision',
       'node_type' => 'page',
-    ],
-    'sourceIds' => [
-      'vid' => [
+    ),
+    'sourceIds' => array(
+      'vid' => array(
         'alias' => 'v',
-      ],
-    ],
-    'destinationIds' => [
-      'vid' => [
+      ),
+    ),
+    'destinationIds' => array(
+      'vid' => array(
         // This is where the field schema would go.
-      ],
-    ],
-  ];
-
-  protected $databaseContents = [
-    'node' => [
-      [
-        'nid' => 1,
-        'type' => 'page',
-        'language' => 'en',
-        'status' => 1,
-        'created' => 1279051598,
-        'changed' => 1279051598,
-        'comment' => 2,
-        'promote' => 1,
-        'moderate' => 0,
-        'sticky' => 0,
-        'tnid' => 0,
-        'translate' => 0,
-        'vid' => 4,
-        'uid' => 1,
-        'title' => 'title for revision 4 (node 1)',
-      ],
-      [
-        'nid' => 2,
-        'type' => 'article',
-        'language' => 'en',
-        'status' => 1,
-        'created' => 1279290908,
-        'changed' => 1279308993,
-        'comment' => 0,
-        'promote' => 1,
-        'moderate' => 0,
-        'sticky' => 0,
-        'tnid' => 0,
-        'translate' => 0,
-        'vid' => 2,
-        'uid' => 1,
-        'title' => 'title for revision 2 (node 2)',
-      ],
-    ],
-    'node_revisions' => [
-      [
-        'nid' => 1,
-        'vid' => 1,
-        'uid' => 1,
-        'title' => 'title for revision 1 (node 1)',
-        'body' => 'body for revision 1 (node 1)',
-        'teaser' => 'teaser for revision 1 (node 1)',
-        'log' => 'log for revision 1 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 1,
-        'vid' => 3,
-        'uid' => 1,
-        'title' => 'title for revision 3 (node 1)',
-        'body' => 'body for revision 3 (node 1)',
-        'teaser' => 'teaser for revision 3 (node 1)',
-        'log' => 'log for revision 3 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 1,
-        'vid' => 4,
-        'uid' => 1,
-        'title' => 'title for revision 4 (node 1)',
-        'body' => 'body for revision 4 (node 1)',
-        'teaser' => 'teaser for revision 4 (node 1)',
-        'log' => 'log for revision 4 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 2,
-        'vid' => 2,
-        'uid' => 1,
-        'title' => 'title for revision 2 (node 2)',
-        'body' => 'body for revision 2 (node 2)',
-        'teaser' => 'teaser for revision 2 (node 2)',
-        'log' => 'log for revision 2 (node 2)',
-        'format' => 1,
-        'timestamp' => 1279308993,
-      ],
-    ],
-  ];
-
-  // There are three revisions of nid 1; vid 4 is the current one. The
-  // NodeRevision plugin should capture every revision EXCEPT that one.
-  // nid 2 will be ignored because $this->migrationConfiguration specifies
-  // a particular node type.
-  protected $expectedResults = [
-    [
+      ),
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
+      // Node fields.
       'nid' => 1,
       'type' => 'page',
       'language' => 'en',
@@ -143,16 +55,27 @@ class NodeRevisionByNodeTypeTest extends MigrateSqlSourceTestCase {
       'sticky' => 0,
       'tnid' => 0,
       'translate' => 0,
+      // Node revision fields.
       'vid' => 1,
-      'node_uid' => 1,
-      'revision_uid' => 1,
+      'uid' => 1,
       'title' => 'title for revision 1 (node 1)',
       'body' => 'body for revision 1 (node 1)',
       'teaser' => 'teaser for revision 1 (node 1)',
       'log' => 'log for revision 1 (node 1)',
       'format' => 1,
-    ],
-    [
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
       'nid' => 1,
       'type' => 'page',
       'language' => 'en',
@@ -165,15 +88,251 @@ class NodeRevisionByNodeTypeTest extends MigrateSqlSourceTestCase {
       'sticky' => 0,
       'tnid' => 0,
       'translate' => 0,
+      // Node revision fields.
       'vid' => 3,
-      'node_uid' => 1,
-      'revision_uid' => 1,
+      'uid' => 1,
       'title' => 'title for revision 3 (node 1)',
       'body' => 'body for revision 3 (node 1)',
       'teaser' => 'teaser for revision 3 (node 1)',
       'log' => 'log for revision 3 (node 1)',
       'format' => 1,
-    ],
-  ];
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
+      'nid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 4,
+      'uid' => 1,
+      'title' => 'title for revision 4 (node 1)',
+      'body' => 'body for revision 4 (node 1)',
+      'teaser' => 'teaser for revision 4 (node 1)',
+      'log' => 'log for revision 4 (node 1)',
+      'format' => 1,
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+  );
+
+  protected $fields = array(
+    'field_test_one' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_one',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_one',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 0,
+        'db_storage' => 1,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+    ),
+    'field_test_two' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_two',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_two',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 1,
+        'db_storage' => 0,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+
+      // Multi field values.
+      'values' => array(
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 2,
+          'nid' => 2,
+          'field_test_two_value' => 'test field node 2',
+          'delta' => 0,
+        ),
+      ),
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $database_contents = $this->expectedResults;
+
+    $database_contents[] = array(
+      // Node fields.
+      'nid' => 2,
+      'type' => 'article',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 2,
+      'uid' => 1,
+      'title' => 'title for revision 2 (node 2)',
+      'body' => 'body for revision 2 (node 2)',
+      'teaser' => 'teaser for revision 2 (node 2)',
+      'log' => 'log for revision 2 (node 2)',
+      'format' => 1,
+      'field_test_two' => array(
+        'test field node 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 2',
+      ),
+    );
+
+    foreach ($database_contents as $k => $row) {
+      $this->databaseContents['node_revisions'][$k]['nid'] = $row['nid'];
+      $this->databaseContents['node_revisions'][$k]['vid'] = $row['vid'];
+      $this->databaseContents['node_revisions'][$k]['uid'] = $row['uid'];
+      $this->databaseContents['node_revisions'][$k]['title'] = $row['title'];
+      $this->databaseContents['node_revisions'][$k]['body'] = $row['body'];
+      $this->databaseContents['node_revisions'][$k]['teaser'] = $row['teaser'];
+      $this->databaseContents['node_revisions'][$k]['format'] = $row['format'];
+      $this->databaseContents['node_revisions'][$k]['log'] = $row['log'];
+
+      unset($row['body']);
+      unset($row['teaser']);
+      unset($row['format']);
+      unset($row['log']);
+
+      //$this->databaseContents['node'][$k] = $row;
+      $this->databaseContents['node'][$row['nid']] = $row;
+
+      // Add the column field storage data.
+      $table = 'content_type_' . $row['type'];
+      foreach ($row['fields'] as $field_name => $value) {
+        $this->databaseContents[$table][$k][$field_name . "_value"] = $value;
+        $this->databaseContents[$table][$k]['vid'] = $row['vid'];
+        $this->databaseContents[$table][$k]['nid'] = $row['nid'];
+      }
+      // Unset from results.
+      unset($row['fields']);
+      unset($this->expectedResults[$k]['fields']);
+    }
+
+    // Setup field tables.
+    foreach ($this->fields as $field) {
+      $cnf = $field['content_node_field'];
+      $this->databaseContents['content_node_field'][] = $cnf;
+      $this->databaseContents['content_node_field_instance'][] = $field['content_node_field_instance'];
+
+      // If it's a multi-field then setup a new table.
+      if ($cnf['multiple']) {
+        foreach ($field['values'] as $value) {
+          $this->databaseContents['content_' . $cnf['field_name']][] = $value;
+        }
+      }
+    }
+
+    parent::setUp();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function testRetrieval() {
+    // @todo: Fix this as per https://www.drupal.org/node/2299795
+    $this->markTestIncomplete('FakeSelect does not support multiple source identifiers, can not test.');
+  }
 
 }
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
index 4dde4b1..d9b17b1 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/NodeRevisionTest.php
@@ -19,116 +19,28 @@ class NodeRevisionTest extends MigrateSqlSourceTestCase {
   const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\NodeRevision';
 
   // The fake Migration configuration entity.
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     'id' => 'test',
     // Leave it empty for now.
-    'idlist' => [],
+    'idlist' => array(),
     // The fake configuration for the source.
-    'source' => [
+    'source' => array(
       'plugin' => 'd6_node_revision',
-    ],
-    'sourceIds' => [
-      'vid' => [
+    ),
+    'sourceIds' => array(
+      'vid' => array(
         'alias' => 'v',
-      ],
-    ],
-    'destinationIds' => [
-      'vid' => [
+      ),
+    ),
+    'destinationIds' => array(
+      'vid' => array(
         // This is where the field schema would go.
-      ],
-    ],
-  ];
-
-  protected $databaseContents = [
-    'node' => [
-      [
-        'nid' => 1,
-        'type' => 'page',
-        'language' => 'en',
-        'status' => 1,
-        'created' => 1279051598,
-        'changed' => 1279051598,
-        'comment' => 2,
-        'promote' => 1,
-        'moderate' => 0,
-        'sticky' => 0,
-        'tnid' => 0,
-        'translate' => 0,
-        'vid' => 4,
-        'uid' => 1,
-        'title' => 'title for revision 1 (node 1)',
-      ],
-      [
-        'nid' => 2,
-        'type' => 'article',
-        'language' => 'en',
-        'status' => 1,
-        'created' => 1279290908,
-        'changed' => 1279308993,
-        'comment' => 0,
-        'promote' => 1,
-        'moderate' => 0,
-        'sticky' => 0,
-        'tnid' => 0,
-        'translate' => 0,
-        'vid' => 2,
-        'uid' => 1,
-        'title' => 'title for revision 2 (node 2)',
-      ],
-    ],
-    'node_revisions' => [
-      [
-        'nid' => 1,
-        'vid' => 1,
-        'uid' => 1,
-        'title' => 'title for revision 1 (node 1)',
-        'body' => 'body for revision 1 (node 1)',
-        'teaser' => 'teaser for revision 1 (node 1)',
-        'log' => 'log for revision 1 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 1,
-        'vid' => 3,
-        'uid' => 1,
-        'title' => 'title for revision 3 (node 1)',
-        'body' => 'body for revision 3 (node 1)',
-        'teaser' => 'teaser for revision 3 (node 1)',
-        'log' => 'log for revision 3 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 1,
-        'vid' => 4,
-        'uid' => 1,
-        'title' => 'title for revision 4 (node 1)',
-        'body' => 'body for revision 4 (node 1)',
-        'teaser' => 'teaser for revision 4 (node 1)',
-        'log' => 'log for revision 4 (node 1)',
-        'format' => 1,
-        'timestamp' => 1279051598,
-      ],
-      [
-        'nid' => 2,
-        'vid' => 2,
-        'uid' => 1,
-        'title' => 'title for revision 2 (node 2)',
-        'body' => 'body for revision 2 (node 2)',
-        'teaser' => 'teaser for revision 2 (node 2)',
-        'log' => 'log for revision 2 (node 2)',
-        'format' => 1,
-        'timestamp' => 1279308993,
-      ],
-    ],
-  ];
-
-  // There are three revisions of nid 1, but the NodeRevision source ignores
-  // the current revision. So only two revisions will be returned here. nid 2
-  // is ignored because it only has one revision (the current one).
-  protected $expectedResults = [
-    [
+      ),
+    ),
+  );
+
+  protected $expectedResults = array(
+    array(
       // Node fields.
       'nid' => 1,
       'type' => 'page',
@@ -144,15 +56,24 @@ class NodeRevisionTest extends MigrateSqlSourceTestCase {
       'translate' => 0,
       // Node revision fields.
       'vid' => 1,
-      'node_uid' => 1,
-      'revision_uid' => 1,
+      'uid' => 1,
       'title' => 'title for revision 1 (node 1)',
       'body' => 'body for revision 1 (node 1)',
       'teaser' => 'teaser for revision 1 (node 1)',
       'log' => 'log for revision 1 (node 1)',
       'format' => 1,
-    ],
-    [
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
       // Node fields.
       'nid' => 1,
       'type' => 'page',
@@ -168,14 +89,246 @@ class NodeRevisionTest extends MigrateSqlSourceTestCase {
       'translate' => 0,
       // Node revision fields.
       'vid' => 3,
-      'node_uid' => 1,
-      'revision_uid' => 1,
+      'uid' => 1,
       'title' => 'title for revision 3 (node 1)',
       'body' => 'body for revision 3 (node 1)',
       'teaser' => 'teaser for revision 3 (node 1)',
       'log' => 'log for revision 3 (node 1)',
       'format' => 1,
-    ],
-  ];
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
+      'nid' => 1,
+      'type' => 'page',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279051598,
+      'changed' => 1279051598,
+      'comment' => 2,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 4,
+      'uid' => 1,
+      'title' => 'title for revision 4 (node 1)',
+      'body' => 'body for revision 4 (node 1)',
+      'teaser' => 'teaser for revision 4 (node 1)',
+      'log' => 'log for revision 4 (node 1)',
+      'format' => 1,
+      'field_test_one_value' => 'text for node 1',
+      'field_test_two' => array(
+        'test field node 1, value 1',
+        'test field node 1, value 2',
+      ),
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 1',
+      ),
+    ),
+    array(
+      // Node fields.
+      'nid' => 2,
+      'type' => 'article',
+      'language' => 'en',
+      'status' => 1,
+      'created' => 1279290908,
+      'changed' => 1279308993,
+      'comment' => 0,
+      'promote' => 1,
+      'moderate' => 0,
+      'sticky' => 0,
+      'tnid' => 0,
+      'translate' => 0,
+      // Node revision fields.
+      'vid' => 2,
+      'uid' => 1,
+      'title' => 'title for revision 2 (node 2)',
+      'body' => 'body for revision 2 (node 2)',
+      'teaser' => 'teaser for revision 2 (node 2)',
+      'log' => 'log for revision 2 (node 2)',
+      'format' => 1,
+      'field_test_two' => array(
+        'test field node 2',
+      ),
+
+      // This is just to help with databaseContents and gets unset later.
+      'fields' => array(
+        'field_test_one' => 'text for node 2',
+      ),
+    ),
+  );
+
+  protected $fields = array(
+    'field_test_one' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_one',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_one',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 0,
+        'db_storage' => 1,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+    ),
+    'field_test_two' => array(
+      'content_node_field_instance' => array(
+        'field_name' => 'field_test_two',
+        'type_name' => 'page',
+        'weight' => 1,
+        'label' => 'Field Label One',
+        'widget_type' => 'text_textfield',
+        'widget_settings' => 'a:4:{s:4:"rows";i:5;s:4:"size";s:2:"60";s:13:"default_value";a:1:{i:0;a:2:{s:5:"value";s:0:"";s:14:"_error_element";s:42:"default_value_widget][field_test][0][value";}}s:17:"default_value_php";N;}',
+        'display_settings' => 'a:6:{s:6:"weight";s:2:"31";s:6:"parent";s:0:"";s:5:"label";a:1:{s:6:"format";s:5:"above";}s:6:"teaser";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}s:4:"full";a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}i:4;a:2:{s:6:"format";s:7:"default";s:7:"exclude";i:0;}}',
+        'description' => '',
+        'widget_module' => 'text',
+        'widget_active' => 1,
+      ),
+      'content_node_field' => array(
+        'field_name' => 'field_test_two',
+        'type' => 'text',
+        'global_settings' => 'a:4:{s:15:"text_processing";s:1:"0";s:10:"max_length";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";}',
+        'required' => 0,
+        'multiple' => 1,
+        'db_storage' => 0,
+        'module' => 'text',
+        'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:4:"text";s:4:"size";s:3:"big";s:8:"not null";b:0;s:8:"sortable";b:1;s:5:"views";b:1;}}',
+        'active' => 1,
+        'locked' => 0,
+      ),
+
+      // Multi field values.
+      'values' => array(
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 1,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 3,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 1',
+          'delta' => 0,
+        ),
+        array(
+          'vid' => 4,
+          'nid' => 1,
+          'field_test_two_value' => 'test field node 1, value 2',
+          'delta' => 1,
+        ),
+        array(
+          'vid' => 2,
+          'nid' => 2,
+          'field_test_two_value' => 'test field node 2',
+          'delta' => 0,
+        ),
+      ),
+    ),
+  );
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    foreach ($this->expectedResults as $k => $row) {
+      $this->databaseContents['node_revisions'][$k]['nid'] = $row['nid'];
+      $this->databaseContents['node_revisions'][$k]['vid'] = $row['vid'];
+      $this->databaseContents['node_revisions'][$k]['uid'] = $row['uid'];
+      $this->databaseContents['node_revisions'][$k]['title'] = $row['title'];
+      $this->databaseContents['node_revisions'][$k]['body'] = $row['body'];
+      $this->databaseContents['node_revisions'][$k]['teaser'] = $row['teaser'];
+      $this->databaseContents['node_revisions'][$k]['format'] = $row['format'];
+      $this->databaseContents['node_revisions'][$k]['log'] = $row['log'];
+
+      unset($row['body']);
+      unset($row['teaser']);
+      unset($row['format']);
+      unset($row['log']);
+
+      //$this->databaseContents['node'][$k] = $row;
+      $this->databaseContents['node'][$row['nid']] = $row;
+
+      // Add the column field storage data.
+      $table = 'content_type_' . $row['type'];
+      foreach ($row['fields'] as $field_name => $value) {
+        $this->databaseContents[$table][$k][$field_name . "_value"] = $value;
+        $this->databaseContents[$table][$k]['vid'] = $row['vid'];
+        $this->databaseContents[$table][$k]['nid'] = $row['nid'];
+      }
+      // Unset from results.
+      unset($row['fields']);
+      unset($this->expectedResults[$k]['fields']);
+    }
+
+    // Setup field tables.
+    foreach ($this->fields as $field) {
+      $cnf = $field['content_node_field'];
+      $this->databaseContents['content_node_field'][] = $cnf;
+      $this->databaseContents['content_node_field_instance'][] = $field['content_node_field_instance'];
+
+      // If it's a multi-field then setup a new table.
+      if ($cnf['multiple']) {
+        foreach ($field['values'] as $value) {
+          $this->databaseContents['content_' . $cnf['field_name']][] = $value;
+        }
+      }
+    }
+
+    parent::setUp();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function testRetrieval() {
+    // @todo: Fix this as per https://www.drupal.org/node/2299795
+    $this->markTestIncomplete('FakeSelect does not support multiple source identifiers, can not test.');
+  }
 
 }
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/ProfileFieldTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/ProfileFieldTest.php
index fe54877..b66c3c9 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/ProfileFieldTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/ProfileFieldTest.php
@@ -21,21 +21,21 @@ class ProfileFieldTest extends MigrateSqlSourceTestCase {
   const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\ProfileField';
 
   // The fake Migration configuration entity.
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     // The id of the entity, can be any string.
     'id' => 'test_profile_fields',
     // Leave it empty for now.
-    'idlist' => [],
-    'source' => [
+    'idlist' => array(),
+    'source' => array(
       'plugin' => 'd6_profile_field',
-    ],
-  ];
+    ),
+  );
 
   // We need to set up the database contents; it's easier to do that below.
   // These are sample result queries.
   // @todo Add multiple cases.
-  protected $expectedResults = [
-    [
+  protected $expectedResults = array(
+    array(
       'fid' => 1,
       'title' => 'First name',
       'name' => 'profile_first_name',
@@ -48,9 +48,9 @@ class ProfileFieldTest extends MigrateSqlSourceTestCase {
       'register' => 0,
       'visibility' => 2,
       'autocomplete' => 0,
-      'options' => [],
-    ],
-    [
+      'options' => array(),
+    ),
+    array(
       'fid' => 2,
       'title' => 'Last name',
       'name' => 'profile_last_name',
@@ -63,9 +63,9 @@ class ProfileFieldTest extends MigrateSqlSourceTestCase {
       'register' => 0,
       'visibility' => 2,
       'autocomplete' => 0,
-      'options' => [],
-    ],
-    [
+      'options' => array(),
+    ),
+    array(
       'fid' => 3,
       'title' => 'Policy',
       'name' => 'profile_policy',
@@ -78,18 +78,15 @@ class ProfileFieldTest extends MigrateSqlSourceTestCase {
       'register' => 1,
       'visibility' => 2,
       'autocomplete' => 0,
-      'options' => [],
-    ],
-  ];
+      'options' => array(),
+    ),
+  );
 
   /**
    * Prepopulate contents with results.
    */
   protected function setUp() {
     $this->databaseContents['profile_fields'] = $this->expectedResults;
-    foreach ($this->databaseContents['profile_fields'] as &$row) {
-      $row['options'] = serialize([]);
-    }
     parent::setUp();
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/UserTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/UserTest.php
index 3e6dd4e..7adb352 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/UserTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/UserTest.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\CommentTest.
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d6\UserTest.
  */
 
 namespace Drupal\Tests\migrate_drupal\Unit\source\d6;
@@ -75,14 +75,7 @@ protected function setUp() {
     foreach ($this->expectedResults as $k => $row) {
       $this->databaseContents['users'][$k] = $row;
     }
-    // getDatabase() will not create empty tables, so we need to insert data
-    // even if it's irrelevant to the test.
-    $this->databaseContents['users_roles'] = array(
-      array(
-        'uid' => 99,
-        'rid' => 99,
-      ),
-    );
+    $this->databaseContents['users_roles'] = array();
     parent::setUp();
   }
 
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/VocabularyTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/VocabularyTest.php
index adf3c30..d6db86c 100644
--- a/core/modules/migrate_drupal/tests/src/Unit/source/d6/VocabularyTest.php
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/VocabularyTest.php
@@ -19,18 +19,18 @@ class VocabularyTest extends MigrateSqlSourceTestCase {
   const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d6\Vocabulary';
 
   // The fake Migration configuration entity.
-  protected $migrationConfiguration = [
+  protected $migrationConfiguration = array(
     // The ID of the entity, can be any string.
     'id' => 'test',
     // Leave it empty for now.
-    'idlist' => [],
-    'source' => [
+    'idlist' => array(),
+    'source' => array(
       'plugin' => 'd6_vocabulary',
-    ],
-  ];
+    ),
+  );
 
-  protected $expectedResults = [
-    [
+  protected $expectedResults = array(
+    array(
       'vid' => 1,
       'name' => 'Tags',
       'description' => 'Tags description.',
@@ -42,9 +42,9 @@ class VocabularyTest extends MigrateSqlSourceTestCase {
       'tags' => 1,
       'module' => 'taxonomy',
       'weight' => 0,
-      'node_types' => ['page', 'article'],
-    ],
-    [
+      'node_types' => array('page', 'article'),
+    ),
+    array(
       'vid' => 2,
       'name' => 'Categories',
       'description' => 'Categories description.',
@@ -56,20 +56,20 @@ class VocabularyTest extends MigrateSqlSourceTestCase {
       'tags' => 0,
       'module' => 'taxonomy',
       'weight' => 0,
-      'node_types' => ['article'],
-    ],
-  ];
+      'node_types' => array('article'),
+    ),
+  );
 
   /**
    * {@inheritdoc}
    */
   protected function setUp() {
-    foreach ($this->expectedResults as &$row) {
+    foreach ($this->expectedResults as $row) {
       foreach ($row['node_types'] as $type) {
-        $this->databaseContents['vocabulary_node_types'][] = [
+        $this->databaseContents['vocabulary_node_types'][] = array(
           'type' => $type,
           'vid' => $row['vid'],
-        ];
+        );
       }
       unset($row['node_types']);
     }
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d7/RoleTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d7/RoleTest.php
new file mode 100644
index 0000000..6a3aa9c
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d7/RoleTest.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d7\RoleTest.
+ */
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d7 {
+
+  use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+  /**
+   * Tests D7 role source plugin.
+   *
+   * @group migrate_drupal
+   */
+  class RoleTest extends MigrateSqlSourceTestCase {
+
+    // The plugin system is not working during unit testing so the source plugin
+    // class needs to be manually specified.
+    const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d7\Role';
+
+    // The fake Migration configuration entity.
+    protected $migrationConfiguration = array(
+      // The ID of the entity, can be any string.
+      'id' => 'test',
+      // Leave it empty for now.
+      'idlist' => array(),
+      // This needs to be the identifier of the actual key: cid for comment, nid
+      // for node and so on.
+      'source' => array(
+        'plugin' => 'd7_user_role',
+      ),
+    );
+
+    protected $expectedResults = array(
+      array(
+        'rid' => 1,
+        'name' => 'anonymous user',
+        'permissions' => array(
+          'access content',
+        ),
+      ),
+      array(
+        'rid' => 2,
+        'name' => 'authenticated user',
+        'permissions' => array(
+          'access comments',
+          'access content',
+          'post comments',
+          'post comments without approval',
+        ),
+      ),
+      array(
+        'rid' => 3,
+        'name' => 'administrator',
+        'permissions' => array(
+          'access comments',
+          'administer comments',
+          'post comments',
+          'post comments without approval',
+          'access content',
+          'administer content types',
+          'administer nodes',
+        ),
+      ),
+    );
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function setUp() {
+      foreach ($this->expectedResults as $row) {
+        foreach ($row['permissions'] as $permission) {
+          $this->databaseContents['role_permission'][] = array(
+            'permission' => $permission,
+            'rid' => $row['rid'],
+          );
+        }
+        unset($row['permissions']);
+        $this->databaseContents['role'][] = $row;
+      }
+      parent::setUp();
+    }
+
+  }
+
+}
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d7 {
+
+  use Drupal\Core\Database\Connection;
+  use Drupal\Core\Extension\ModuleHandlerInterface;
+  use Drupal\migrate_drupal\Plugin\migrate\source\d7\Role;
+
+  class TestRole extends Role {
+    public function setDatabase(Connection $database) {
+      $this->database = $database;
+    }
+
+    public function setModuleHandler(ModuleHandlerInterface $module_handler) {
+      $this->moduleHandler = $module_handler;
+    }
+  }
+
+}
diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d7/UserTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d7/UserTest.php
new file mode 100644
index 0000000..6b4afdb
--- /dev/null
+++ b/core/modules/migrate_drupal/tests/src/Unit/source/d7/UserTest.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\migrate_drupal\Unit\source\d7\UserTest.
+ */
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d7;
+
+use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase;
+
+/**
+ * Tests D7 user source plugin.
+ *
+ * @group migrate_drupal
+ */
+class UserTest extends MigrateSqlSourceTestCase {
+
+  const PLUGIN_CLASS = 'Drupal\migrate_drupal\Plugin\migrate\source\d7\User';
+
+  protected $migrationConfiguration = [
+    'id' => 'test',
+    'idlist' => [],
+    'source' => [
+      'plugin' => 'd7_user',
+    ],
+  ];
+
+  protected $expectedResults = [
+    [
+      'uid' => '2',
+      'name' => 'Odo',
+      'pass' => '$S$DVpvPItXvnsmF3giVEe7Jy2lG.SCoEs8uKwpHsyPvdeNAaNZYxZ8',
+      'mail' => 'odo@local.host',
+      'signature' => '',
+      'signature_format' => 'filtered_html',
+      'created' => '1432750741',
+      'access' => '0',
+      'login' => '0',
+      'status' => '1',
+      'timezone' => 'America/Chicago',
+      'language' => '',
+      'picture' => '0',
+      'init' => 'odo@local.host',
+      'roles' => [
+        2 => 'authenticated user',
+      ],
+    ],
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->databaseContents['users'][] = [
+      'uid' => '2',
+      'name' => 'Odo',
+      'pass' => '$S$DVpvPItXvnsmF3giVEe7Jy2lG.SCoEs8uKwpHsyPvdeNAaNZYxZ8',
+      'mail' => 'odo@local.host',
+      'theme' => '',
+      'signature' => '',
+      'signature_format' => 'filtered_html',
+      'created' => '1432750741',
+      'access' => '0',
+      'login' => '0',
+      'status' => '1',
+      'timezone' => 'America/Chicago',
+      'language' => '',
+      'picture' => '0',
+      'init' => 'odo@local.host',
+      'data' => 'a:1:{s:7:"contact";i:1;}',
+    ];
+    $this->databaseContents['users_roles'][] = [
+      'uid' => 2,
+      'rid' => 2,
+    ];
+    $this->databaseContents['role'][] = [
+      'rid' => 2,
+      'name' => 'authenticated user',
+      'weight' => 0,
+    ];
+    parent::setUp();
+  }
+
+}
+
+namespace Drupal\Tests\migrate_drupal\Unit\source\d7;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\migrate_drupal\Plugin\migrate\source\d7\User;
+
+class TestUser extends User {
+  public function setDatabase(Connection $database) {
+    $this->database = $database;
+  }
+  public function setModuleHandler(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+}
diff --git a/core/modules/node/config/optional/views.view.archive.yml b/core/modules/node/config/optional/views.view.archive.yml
index 56ae50e..209346d 100644
--- a/core/modules/node/config/optional/views.view.archive.yml
+++ b/core/modules/node/config/optional/views.view.archive.yml
@@ -32,7 +32,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       exposed_form:
         type: basic
diff --git a/core/modules/node/config/optional/views.view.content.yml b/core/modules/node/config/optional/views.view.content.yml
index c8201f2..7849a0c 100644
--- a/core/modules/node/config/optional/views.view.content.yml
+++ b/core/modules/node/config/optional/views.view.content.yml
@@ -20,7 +20,7 @@ display:
         options:
           perm: 'access content overview'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/node/config/optional/views.view.content_recent.yml b/core/modules/node/config/optional/views.view.content_recent.yml
index 1d46cf5..500e1fa 100644
--- a/core/modules/node/config/optional/views.view.content_recent.yml
+++ b/core/modules/node/config/optional/views.view.content_recent.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/node/config/optional/views.view.glossary.yml b/core/modules/node/config/optional/views.view.glossary.yml
index 63bf6f7..1738e43 100644
--- a/core/modules/node/config/optional/views.view.glossary.yml
+++ b/core/modules/node/config/optional/views.view.glossary.yml
@@ -33,7 +33,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       exposed_form:
         type: basic
diff --git a/core/modules/node/src/Tests/NodeTokenReplaceTest.php b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
index 1ba3003..ffef457 100644
--- a/core/modules/node/src/Tests/NodeTokenReplaceTest.php
+++ b/core/modules/node/src/Tests/NodeTokenReplaceTest.php
@@ -73,8 +73,8 @@ function testNodeTokenReplacement() {
     $tests['[node:author]'] = SafeMarkup::checkPlain($account->getUsername());
     $tests['[node:author:uid]'] = $node->getOwnerId();
     $tests['[node:author:name]'] = SafeMarkup::checkPlain($account->getUsername());
-    $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getCreatedTime(), array('langcode' => $this->interfaceLanguage->getId()));
-    $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime(), array('langcode' => $this->interfaceLanguage->getId()));
+    $tests['[node:created:since]'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $node->getCreatedTime(), 2, $this->interfaceLanguage->getId());
+    $tests['[node:changed:since]'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $node->getChangedTime(), 2, $this->interfaceLanguage->getId());
 
     // Test to make sure that we generated something for each token.
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
index bd561b1..b25fafc 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_contextual_links.yml
@@ -20,7 +20,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       pager:
         type: full
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml
index e476eae..ef61852 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_field_filters.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_uid_revision.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_uid_revision.yml
index 4f8ba50..2bcce2f 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_uid_revision.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_filter_node_uid_revision.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
index 1ac8f79..bfa5215 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_row_plugin.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_row_plugin.yml
index 165180f..7e76af9 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_row_plugin.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_row_plugin.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       filters:
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
index f9c2bdf..e047e68 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_node_view.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_status_extra.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_status_extra.yml
index 8c6f7cf..b690589 100644
--- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_status_extra.yml
+++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_status_extra.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_numeric.yml b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_numeric.yml
index a950bc2..23a2e78 100644
--- a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_numeric.yml
+++ b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_numeric.yml
@@ -26,7 +26,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_string.yml b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_string.yml
index 3037d6d..7c3b85d 100644
--- a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_string.yml
+++ b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_argument_string.yml
@@ -26,7 +26,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_filter.yml b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_filter.yml
index ae55b85..d2dbb92 100644
--- a/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_filter.yml
+++ b/core/modules/options/tests/options_test_views/test_views/views.view.test_options_list_filter.yml
@@ -26,7 +26,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
index 2a5818e..eef38d3 100644
--- a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
+++ b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_entity.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
index 7f7769d..49673d5 100644
--- a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
+++ b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_display_field.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_node_display_field.yml b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_node_display_field.yml
index ab50920..7032875 100644
--- a/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_node_display_field.yml
+++ b/core/modules/rest/tests/modules/rest_test_views/test_views/views.view.test_serializer_node_display_field.yml
@@ -29,7 +29,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml b/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml
index a320c4f..b8d3c4a 100644
--- a/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml
+++ b/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/system/module.api.php b/core/modules/system/module.api.php
index 63f81b2..24fb741 100644
--- a/core/modules/system/module.api.php
+++ b/core/modules/system/module.api.php
@@ -761,7 +761,7 @@ function hook_requirements($phase) {
     $cron_last = \Drupal::state()->get('system.cron_last');
 
     if (is_numeric($cron_last)) {
-      $requirements['cron']['value'] = t('Last run !time ago', array('!time' => \Drupal::service('date.formatter')->formatTimeDiffSince($cron_last)));
+      $requirements['cron']['value'] = t('Last run !time ago', array('!time' => \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $cron_last)));
     }
     else {
       $requirements['cron'] = array(
diff --git a/core/modules/system/src/Form/CronForm.php b/core/modules/system/src/Form/CronForm.php
index c57ceae..9df9414 100644
--- a/core/modules/system/src/Form/CronForm.php
+++ b/core/modules/system/src/Form/CronForm.php
@@ -101,7 +101,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#value' => t('Run cron'),
       '#submit' => array('::submitCron'),
     );
-    $status = '<p>' . $this->t('Last run: %time ago.', array('%time' => $this->dateFormatter->formatTimeDiffSince($this->state->get('system.cron_last')))) . '</p>';
+
+    $status = '<p>' . t('Last run: %cron-last ago.', array('%cron-last' => $this->dateFormatter->formatInterval(REQUEST_TIME - $this->state->get('system.cron_last')))) . '</p>';
     $form['status'] = array(
       '#markup' => $status,
     );
diff --git a/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php b/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
index f98c373..6cf92ef 100644
--- a/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
+++ b/core/modules/system/src/Tests/System/TokenReplaceUnitTest.php
@@ -154,7 +154,7 @@ public function testSystemDateTokenReplacement() {
     $tests['[date:medium]'] = $date_formatter->format($date, 'medium', '', NULL, $this->interfaceLanguage->getId());
     $tests['[date:long]'] = $date_formatter->format($date, 'long', '', NULL, $this->interfaceLanguage->getId());
     $tests['[date:custom:m/j/Y]'] = $date_formatter->format($date, 'custom', 'm/j/Y', NULL, $this->interfaceLanguage->getId());
-    $tests['[date:since]'] = $date_formatter->formatTimeDiffSince($date, array('langcode' => $this->interfaceLanguage->getId()));
+    $tests['[date:since]'] = $date_formatter->formatInterval(REQUEST_TIME - $date, 2, $this->interfaceLanguage->getId());
     $tests['[date:raw]'] = Xss::filter($date);
 
     // Test to make sure that we generated something for each token.
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index a0849b1..488db27 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -359,7 +359,7 @@ function system_requirements($phase) {
     }
 
     // Set summary and description based on values determined above.
-    $summary = t('Last run !time ago', array('!time' => \Drupal::service('date.formatter')->formatTimeDiffSince($cron_last)));
+    $summary = t('Last run !time ago', array('!time' => \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $cron_last)));
     $description = '';
     if ($severity != REQUIREMENT_INFO) {
       $description = t('Cron has not run recently.') . ' ' . $help;
diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc
index 20d5ec1..8ce5825 100644
--- a/core/modules/system/system.tokens.inc
+++ b/core/modules/system/system.tokens.inc
@@ -68,7 +68,7 @@ function system_token_info() {
   );
   $date['since'] = array(
     'name' => t("Time-since"),
-    'description' => t("A date in 'time-since' format. (%date)", array('%date' => \Drupal::service('date.formatter')->formatTimeDiffSince(REQUEST_TIME - 360))),
+    'description' => t("A date in 'time-since' format. (%date)", array('%date' => \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - 360, 2))),
   );
   $date['raw'] = array(
     'name' => t("Raw timestamp"),
@@ -157,7 +157,7 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a
           break;
 
         case 'since':
-          $replacements[$original] = \Drupal::service('date.formatter')->formatTimeDiffSince($date, array('langcode' => $langcode));
+          $replacements[$original] = \Drupal::service('date.formatter')->formatInterval((REQUEST_TIME - $date), 2, $langcode);
           break;
 
         case 'raw':
diff --git a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
index e1086d1..a343b9f 100644
--- a/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
+++ b/core/modules/taxonomy/config/optional/views.view.taxonomy_term.yml
@@ -35,7 +35,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       exposed_form:
         type: basic
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
index 615972b..dcb0bc4 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.taxonomy_default_argument_test.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml
index b2a7c9e..baa59ff 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_field_filters.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
index 32a5a8b..b32e452 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
index b564d69..500e8b9 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_filter_taxonomy_index_tid_depth.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_groupwise_term.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_groupwise_term.yml
index a802762..c4e18a0 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_groupwise_term.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_groupwise_term.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_node_term_data.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_node_term_data.yml
index beb3c63..0623f98 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_node_term_data.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_node_term_data.yml
@@ -48,7 +48,7 @@ display:
           entity_type: taxonomy_term
           entity_field: tid
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_parent.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_parent.yml
index fbb97fd..eb6d298 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_parent.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_parent.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_name.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_name.yml
index cdcec2c..6fae130 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_name.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_name.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
index 22521bc..eb561c6 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_term_relationship.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml
index 35ad6de..6fab886 100644
--- a/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml
+++ b/core/modules/taxonomy/tests/modules/taxonomy_test_views/test_views/views.view.test_taxonomy_tid_field.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/tracker/src/Tests/TrackerTest.php b/core/modules/tracker/src/Tests/TrackerTest.php
index bc2f564..c5c8500 100644
--- a/core/modules/tracker/src/Tests/TrackerTest.php
+++ b/core/modules/tracker/src/Tests/TrackerTest.php
@@ -91,7 +91,7 @@ function testTrackerAll() {
 
     $this->drupalGet('activity');
     $this->assertText($node->label(), 'Published node shows up in the tracker listing.');
-    $this->assertText(\Drupal::service('date.formatter')->formatTimeDiffSince($node->getChangedTime()), 'The changed time was displayed on the tracker listing.');
+    $this->assertText(\Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $node->getChangedTime()), 'The changed time was displayed on the tracker listing.');
   }
 
   /**
diff --git a/core/modules/tracker/tests/modules/tracker_test_views/test_views/views.view.test_tracker_user_uid.yml b/core/modules/tracker/tests/modules/tracker_test_views/test_views/views.view.test_tracker_user_uid.yml
index 04bdd4d..7b11ddc 100644
--- a/core/modules/tracker/tests/modules/tracker_test_views/test_views/views.view.test_tracker_user_uid.yml
+++ b/core/modules/tracker/tests/modules/tracker_test_views/test_views/views.view.test_tracker_user_uid.yml
@@ -23,7 +23,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/tracker/tracker.pages.inc b/core/modules/tracker/tracker.pages.inc
index 4ce372d..5eac748 100644
--- a/core/modules/tracker/tracker.pages.inc
+++ b/core/modules/tracker/tracker.pages.inc
@@ -114,7 +114,7 @@ function tracker_page($account = NULL) {
         ),
         'last updated' => array(
           'data' => t('!time ago', array(
-            '!time' => \Drupal::service('date.formatter')->formatTimeDiffSince($node->last_activity),
+            '!time' => \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $node->last_activity),
           )),
         ),
       );
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index 4aed1ef..63ed8d0 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -574,7 +574,7 @@ function _update_project_status_sort($a, $b) {
  * @see theme_update_report()
  */
 function template_preprocess_update_last_check(&$variables) {
-  $variables['time'] = \Drupal::service('date.formatter')->formatTimeDiffSince($variables['last']);
+  $variables['time'] = \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $variables['last']);
   $variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', array(), array('query' => \Drupal::destination()->getAsArray())));
 }
 
diff --git a/core/modules/user/config/optional/views.view.user_admin_people.yml b/core/modules/user/config/optional/views.view.user_admin_people.yml
index 2d6114f..004471c 100644
--- a/core/modules/user/config/optional/views.view.user_admin_people.yml
+++ b/core/modules/user/config/optional/views.view.user_admin_people.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'administer users'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
         options:
diff --git a/core/modules/user/config/optional/views.view.who_s_new.yml b/core/modules/user/config/optional/views.view.who_s_new.yml
index dc7cde7..7905b35 100644
--- a/core/modules/user/config/optional/views.view.who_s_new.yml
+++ b/core/modules/user/config/optional/views.view.who_s_new.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/user/config/optional/views.view.who_s_online.yml b/core/modules/user/config/optional/views.view.who_s_online.yml
index e48c0d3..d34de2a 100644
--- a/core/modules/user/config/optional/views.view.who_s_online.yml
+++ b/core/modules/user/config/optional/views.view.who_s_online.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'access user profiles'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/user/src/Tests/UserAdminListingTest.php b/core/modules/user/src/Tests/UserAdminListingTest.php
index 76fc674..fbf3197 100644
--- a/core/modules/user/src/Tests/UserAdminListingTest.php
+++ b/core/modules/user/src/Tests/UserAdminListingTest.php
@@ -91,7 +91,7 @@ public function testUserListing() {
     $expected_roles = array('custom_role_1', 'custom_role_2');
     $this->assertEqual($result_accounts[$role_account_name]['roles'], $expected_roles, 'Ensure roles are listed properly.');
 
-    $this->assertEqual($result_accounts[$timestamp_user]['member_for'], \Drupal::service('date.formatter')->formatTimeDiffSince($accounts[$timestamp_user]->created->value), 'Ensure the right member time is displayed.');
+    $this->assertEqual($result_accounts[$timestamp_user]['member_for'], \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $accounts[$timestamp_user]->created->value), 'Ensure the right member time is displayed.');
   }
 
 }
diff --git a/core/modules/user/src/UserListBuilder.php b/core/modules/user/src/UserListBuilder.php
index 7575b86..fc7daee 100644
--- a/core/modules/user/src/UserListBuilder.php
+++ b/core/modules/user/src/UserListBuilder.php
@@ -151,8 +151,10 @@ public function buildRow(EntityInterface $entity) {
       '#theme' => 'item_list',
       '#items' => $users_roles,
     );
-    $row['member_for'] = $this->dateFormatter->formatTimeDiffSince($entity->getCreatedTime());
-    $row['access'] = $entity->access ? $this->t('@time ago', array('@time' => $this->dateFormatter->formatTimeDiffSince($entity->getLastAccessedTime()))) : t('never');
+    $row['member_for'] = $this->dateFormatter->formatInterval(REQUEST_TIME - $entity->getCreatedTime());
+    $row['access'] = $entity->access ? $this->t('@time ago', array(
+      '@time' => $this->dateFormatter->formatInterval(REQUEST_TIME - $entity->getLastAccessedTime()),
+    )) : t('never');
     return $row + parent::buildRow($entity);
   }
 
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_perm.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_perm.yml
index 7862066..a5c11e8 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_perm.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_perm.yml
@@ -19,7 +19,7 @@ display:
         options:
           perm: 'views_test_data test permission'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_role.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_role.yml
index f07b429..f089b5e 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_role.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_access_role.yml
@@ -23,7 +23,7 @@ display:
       access:
         type: role
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_field_permission.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_field_permission.yml
index 04948cd..7ddb9d2 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_field_permission.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_field_permission.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_filter_permission.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_filter_permission.yml
index a389464..53c2355 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_filter_permission.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_filter_permission.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_groupwise_user.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_groupwise_user.yml
index 789dffe..99db821 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_groupwise_user.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_groupwise_user.yml
@@ -20,7 +20,7 @@ display:
           perm: 'access user profiles'
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_plugin_argument_default_current_user.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_plugin_argument_default_current_user.yml
index a080e26..4c8c708 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_plugin_argument_default_current_user.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_plugin_argument_default_current_user.yml
@@ -26,7 +26,7 @@ display:
           table: views
           plugin_id: 'null'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_changed.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_changed.yml
index 65c9899..d929079 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_changed.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_changed.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_data.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_data.yml
index c33be6f..9bdb32a 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_data.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_data.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'access user profiles'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_name.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_name.yml
index 55b5d1a..33706cd 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_name.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_name.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_relationship.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_relationship.yml
index 6926bb1..7e44245 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_relationship.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_user_relationship.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_user.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_user.yml
index 60f9bf8..fe9b4f5 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_user.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_user.yml
@@ -25,7 +25,7 @@ display:
             type: 'entity:user'
           plugin_id: 'null'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_username.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_username.yml
index d7fc245..b3b962f 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_username.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_view_argument_validate_username.yml
@@ -25,7 +25,7 @@ display:
             type: user_name
           plugin_id: 'null'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_role.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_role.yml
index 9e72554..7cfbca9 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_role.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_role.yml
@@ -23,7 +23,7 @@ display:
         options:
           perm: 'access user profiles'
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_user_name.yml b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_user_name.yml
index 13f5959..c0c3e94 100644
--- a/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_user_name.yml
+++ b/core/modules/user/tests/modules/user_test_views/test_views/views.view.test_views_handler_field_user_name.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 1d59201..f2c2414 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -370,7 +370,7 @@ function user_user_view(array &$build, UserInterface $account, EntityViewDisplay
   if ($display->getComponent('member_for')) {
     $build['member_for'] = array(
       '#type' => 'item',
-      '#markup' => '<h4 class="label">' . t('Member for') . '</h4> ' . \Drupal::service('date.formatter')->formatTimeDiffSince($account->getCreatedTime()),
+      '#markup' => '<h4 class="label">' . t('Member for') . '</h4> ' . \Drupal::service('date.formatter')->formatInterval(REQUEST_TIME - $account->getCreatedTime()),
     );
   }
 }
diff --git a/core/modules/views/src/Plugin/views/area/Result.php b/core/modules/views/src/Plugin/views/area/Result.php
index 52ce7f2..5852c16 100644
--- a/core/modules/views/src/Plugin/views/area/Result.php
+++ b/core/modules/views/src/Plugin/views/area/Result.php
@@ -84,6 +84,7 @@ public function render($empty = FALSE) {
     // Calculate the page totals.
     $current_page = (int) $this->view->getCurrentPage() + 1;
     $per_page = (int) $this->view->getItemsPerPage();
+    $count = count($this->view->result);
     // @TODO: Maybe use a possible is views empty functionality.
     // Not every view has total_rows set, use view->result instead.
     $total = isset($this->view->total_rows) ? $this->view->total_rows : count($this->view->result);
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index 3245bd2..8f6999d 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -561,7 +561,7 @@ protected function defineOptions() {
       ),
       'cache' => array(
         'contains' => array(
-          'type' => array('default' => 'tag'),
+          'type' => array('default' => 'none'),
           'options' => array('default' => array()),
         ),
         'merge_defaults' => array($this, 'mergePlugin'),
@@ -2311,7 +2311,7 @@ public function calculateCacheMetadata () {
    */
   public function getCacheMetadata() {
     if (!isset($this->display['cache_metadata'])) {
-      list($this->display['cache_metadata']['cacheable'], $this->display['cache_metadata']['contexts']) = $this->calculateCacheMetadata();
+      $this->display['cache_metadata'] = $this->calculateCacheMetadata();
     }
     return $this->display['cache_metadata'];
   }
diff --git a/core/modules/views/src/Plugin/views/field/Date.php b/core/modules/views/src/Plugin/views/field/Date.php
index 2a7886a..8857c1a 100644
--- a/core/modules/views/src/Plugin/views/field/Date.php
+++ b/core/modules/views/src/Plugin/views/field/Date.php
@@ -151,33 +151,24 @@ public function render(ResultRow $values) {
       $time_diff = REQUEST_TIME - $value; // will be positive for a datetime in the past (ago), and negative for a datetime in the future (hence)
       switch ($format) {
         case 'raw time ago':
-          return $this->dateFormatter->formatTimeDiffSince($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2));
-
+          return $this->dateFormatter->formatInterval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
         case 'time ago':
-          return $this->t('%time ago', array('%time' => $this->dateFormatter->formatTimeDiffSince($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2))));
-
+          return $this->t('%time ago', array('%time' => $this->dateFormatter->formatInterval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
         case 'raw time hence':
-          return $this->dateFormatter->formatTimeDiffUntil($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2));
-
+          return $this->dateFormatter->formatInterval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2);
         case 'time hence':
-          return $this->t('%time hence', array('%time' => $this->dateFormatter->formatTimeDiffUntil($value, array('granularity' => is_numeric($custom_format) ? $custom_format : 2))));
-
+          return $this->t('%time hence', array('%time' => $this->dateFormatter->formatInterval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2)));
         case 'raw time span':
-          return ($time_diff < 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2));
-
+          return ($time_diff < 0 ? '-' : '') . $this->dateFormatter->formatInterval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
         case 'inverse time span':
-          return ($time_diff > 0 ? '-' : '') . $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2));
-
+          return ($time_diff > 0 ? '-' : '') . $this->dateFormatter->formatInterval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
         case 'time span':
-          $time = $this->dateFormatter->formatTimeDiffSince($value, array('strict' => FALSE, 'granularity' => is_numeric($custom_format) ? $custom_format : 2));
-          return ($time_diff < 0) ? $this->t('%time hence', array('%time' => $time)) : $this->t('%time ago', array('%time' => $time));
-
+          return $this->t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => $this->dateFormatter->formatInterval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
         case 'custom':
           if ($custom_format == 'r') {
             return format_date($value, $format, $custom_format, $timezone, 'en');
           }
           return format_date($value, $format, $custom_format, $timezone);
-
         default:
           return format_date($value, $format, '', $timezone);
       }
diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php
index 5eaff38..4192719 100644
--- a/core/modules/views/src/Plugin/views/field/Field.php
+++ b/core/modules/views/src/Plugin/views/field/Field.php
@@ -232,6 +232,7 @@ public function query($use_groupby = FALSE) {
       unset($fields[$entity_type_key]);
     }
 
+    $field_definition = $this->getFieldDefinition();
     if ($use_groupby) {
       // Add the fields that we're actually grouping on.
       $options = array();
diff --git a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
index 45418c9..051955e 100644
--- a/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
+++ b/core/modules/views/src/Plugin/views/join/JoinPluginBase.php
@@ -294,6 +294,12 @@ public function buildJoin($select_query, $table, $view_query) {
           // Convert a single-valued array of values to the single-value case,
           // and transform from IN() notation to = notation
           if (is_array($info['value']) && count($info['value']) == 1) {
+            if (empty($info['operator'])) {
+              $operator = '=';
+            }
+            else {
+              $operator = $info['operator'] == 'NOT IN' ? '!=' : '=';
+            }
             $info['value'] = array_shift($info['value']);
           }
 
diff --git a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
index 292a2e3..997e8c3 100644
--- a/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
+++ b/core/modules/views/src/Plugin/views/wizard/WizardPluginBase.php
@@ -795,7 +795,7 @@ protected function addDisplays(View $view, $display_options, $form, FormStateInt
   protected function defaultDisplayOptions() {
     $display_options = array();
     $display_options['access']['type'] = 'none';
-    $display_options['cache']['type'] = 'tag';
+    $display_options['cache']['type'] = 'none';
     $display_options['query']['type'] = 'views_query';
     $display_options['exposed_form']['type'] = 'basic';
     $display_options['pager']['type'] = 'full';
diff --git a/core/modules/views/src/Tests/Handler/FieldDateTest.php b/core/modules/views/src/Tests/Handler/FieldDateTest.php
index 98eae40..3ea113d 100644
--- a/core/modules/views/src/Tests/Handler/FieldDateTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldDateTest.php
@@ -121,19 +121,19 @@ public function testFieldDate() {
     }
 
     // Check times in the past.
-    $time_since = $this->container->get('date.formatter')->formatTimeDiffSince($time);
+    $test = $this->container->get('date.formatter')->formatInterval(REQUEST_TIME - $time, 2);
     $intervals = array(
-      'raw time ago' => $time_since,
-      'time ago' => t('%time ago', array('%time' => $time_since)),
-      'raw time span' => $time_since,
-      'inverse time span' => -$time_since,
-      'time span' => t('%time ago', array('%time' => $time_since)),
+      'raw time ago' => $test,
+      'time ago' => t('%time ago', array('%time' => $test)),
+      'raw time span' => $test,
+      'inverse time span' => -$test,
+      'time span' => t('%time ago', array('%time' => $test)),
     );
     $this->assertRenderedDatesEqual($view, $intervals);
 
     // Check times in the future.
     $time = gmmktime(0, 0, 0, 1, 1, 2050);
-    $formatted = $this->container->get('date.formatter')->formatTimeDiffUntil($time);
+    $formatted = $this->container->get('date.formatter')->formatInterval($time - REQUEST_TIME, 2);
     $intervals = array(
       'raw time span' => -$formatted,
       'time span' => t('%time hence', array(
diff --git a/core/modules/views/src/Tests/Handler/FieldWebTest.php b/core/modules/views/src/Tests/Handler/FieldWebTest.php
index 3fde585..13bb95b 100644
--- a/core/modules/views/src/Tests/Handler/FieldWebTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldWebTest.php
@@ -222,6 +222,8 @@ public function testAlterUrl() {
 
     // Some generic test code adapted from the UrlTest class, which tests
     // mostly the different options for the path.
+    global $base_url, $script_path;
+
     foreach (array(FALSE, TRUE) as $absolute) {
       $alter = &$id_field->options['alter'];
       $alter['path'] = 'node/123';
diff --git a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php
index b1235b1..d498ac3 100644
--- a/core/modules/views/src/Tests/RenderCacheIntegrationTest.php
+++ b/core/modules/views/src/Tests/RenderCacheIntegrationTest.php
@@ -47,12 +47,6 @@ protected function setUp() {
    * Tests a field-based view's cache tags when using the "none" cache plugin.
    */
   public function testFieldBasedViewCacheTagsWithCachePluginNone() {
-    $view = Views::getview('entity_test_fields');
-    $view->getDisplay()->overrideOption('cache', [
-      'type' => 'none',
-    ]);
-    $view->save();
-
     $this->assertCacheTagsForFieldBasedView(FALSE);
   }
 
@@ -198,12 +192,6 @@ protected function assertCacheTagsForFieldBasedView($do_assert_views_caches) {
    * Tests a entity-based view's cache tags when using the "none" cache plugin.
    */
   public function testEntityBasedViewCacheTagsWithCachePluginNone() {
-    $view = Views::getview('entity_test_row');
-    $view->getDisplay()->overrideOption('cache', [
-      'type' => 'none',
-    ]);
-    $view->save();
-
     $this->assertCacheTagsForEntityBasedView(FALSE);
   }
 
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_fields.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_fields.yml
index 150926c..5f2592b 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_fields.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_fields.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_row.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_row.yml
index ee4578f..4bd0503 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_row.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.entity_test_row.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       sorts:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml
index 8593665..e8e99ad 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.numeric_test.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'administer views'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_access_none.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_access_none.yml
index 72be69b..6b267be 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_access_none.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_access_none.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_aggregate_count.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_aggregate_count.yml
index c8e9488..1116bcb 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_aggregate_count.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_aggregate_count.yml
@@ -27,7 +27,7 @@ display:
           entity_type: entity_test
           entity_field: name
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_alias.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_alias.yml
index 1dce6dc..da36f2f 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_alias.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_alias.yml
@@ -19,7 +19,7 @@ display:
           perm: 'access user profiles'
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_current_user.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_current_user.yml
index e5e4af4..cd481fa 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_current_user.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_current_user.yml
@@ -26,7 +26,7 @@ display:
           entity_type: node
           entity_field: uid
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_fixed.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_fixed.yml
index c1456f6..4b4f296 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_fixed.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_default_fixed.yml
@@ -26,7 +26,7 @@ display:
           table: views
           plugin_id: 'null'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml
index c6b72e3..f406543 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_argument_dependency.yml
@@ -32,7 +32,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attached_disabled.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attached_disabled.yml
index 1dd5edc..d07216f 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attached_disabled.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attached_disabled.yml
@@ -26,7 +26,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
index 17bcdb7..89089c2 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_attachment_ui.yml
@@ -19,7 +19,7 @@ display:
         options:
           perm: 'views_test_data test permission'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
index f5ada7a..82d10ad 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_click_sort.yml
@@ -33,7 +33,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       style:
         type: table
         options:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_destroy.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_destroy.yml
index bf0df9a..47bd959 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_destroy.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_destroy.yml
@@ -41,7 +41,7 @@ display:
           plugin_id: date_month
           entity_type: node
       cache:
-        type: tag
+        type: none
       empty:
         area:
           empty: false
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_disabled_display.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_disabled_display.yml
index c8de50a..c0c45c3 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_disabled_display.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_disabled_display.yml
@@ -26,7 +26,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display.yml
index 8936310..9a0b910 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_attachment.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_attachment.yml
index 615ae8c..715158c 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_attachment.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_attachment.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_defaults.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_defaults.yml
index b969c34..224019c 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_defaults.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_defaults.yml
@@ -20,7 +20,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
index 452d934..1f8dbc9 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_display_feed.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml
index e7a2760..3e5fcea 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_dropbutton.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_operations.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_operations.yml
index 9ccd9a9..ee58e8b 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_operations.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_operations.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml
index 509826c..8eb7a42 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_link.yml
@@ -22,7 +22,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
index 6894d76..55f5b1c 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_entity_test_protected_access.yml
@@ -25,7 +25,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area.yml
index baa055c..b90c153 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       header:
         test_example:
           field: test_example
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area_access.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area_access.yml
index ab27d07..2ec7214 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area_access.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_example_area_access.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       empty:
         test_example:
           field: test_example
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml
index db16bcb..32b0692 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_admin_ui.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         options:
           reset_button: true
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
index be96ab4..3818532 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_block.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         options:
           reset_button: true
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
index d33174a..bed02ca 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_buttons.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         options:
           reset_button: true
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_sort_items_per_page.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_sort_items_per_page.yml
index d7d2d93..f2d3364 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_sort_items_per_page.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form_sort_items_per_page.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         options:
           expose_sort_order: true
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml
index a5bb9f5..dc81943 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_feed_icon.yml
@@ -27,7 +27,7 @@ display:
           role:
             authenticated: authenticated
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_alias_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_alias_test.yml
index 0c72f88..6e178cc 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_alias_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_alias_test.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_classes.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_classes.yml
index 28b3dad..2480aa3 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_classes.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_classes.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_complex_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_complex_test.yml
index 869d282..58ee430 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_complex_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_complex_test.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_complex_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_complex_test.yml
index 7680027..b0122a3 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_complex_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_complex_test.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_test.yml
index d1e5c50..d85d4d1 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_revision_test.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_test.yml
index 49a88cf..aa37836 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_field_test.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         id:
           id: id
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_get_entity.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_get_entity.yml
index cc3b66c..3613335 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_get_entity.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_get_entity.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_output.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_output.yml
index 8b3ae47..c3d2bc1 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_output.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_output.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       fields:
         name:
           id: name
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_tokens.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_tokens.yml
index 2a2626c..718b27c 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_tokens.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_tokens.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter.yml
index c6f9807..86313c1 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between.yml
index 47556800..16afa71 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_date_between.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_group_override.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_group_override.yml
index 7734d1c..85c4de2 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_group_override.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_group_override.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_groups.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_groups.yml
index 6ea46a9..4d57f77 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_groups.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_groups.yml
@@ -18,7 +18,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
index ef0188a..66520dc 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_filter_in_operator_ui.yml
@@ -14,7 +14,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       filters:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_get_attach_displays.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_get_attach_displays.yml
index 608efa0..6116e77 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_get_attach_displays.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_get_attach_displays.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_glossary.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_glossary.yml
index bf44f36..1e8af98 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_glossary.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_glossary.yml
@@ -34,7 +34,7 @@ display:
           entity_type: node
           entity_field: title
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count.yml
index c6aba49..4d4dd56 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count_multicardinality.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count_multicardinality.yml
index c295db5..6be6793 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count_multicardinality.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_count_multicardinality.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_in_filters.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_in_filters.yml
index da6a676..173a0e8 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_in_filters.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_by_in_filters.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_rows.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_rows.yml
index 2c34841..4dffd05 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_rows.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_group_rows.yml
@@ -26,7 +26,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_groupwise_term_ui.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_groupwise_term_ui.yml
index c29fb52..cfff08e 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_groupwise_term_ui.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_groupwise_term_ui.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
index 900852b..92962d7 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_history.yml
@@ -23,7 +23,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_http_status_code.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_http_status_code.yml
index 9183682..83192b8 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_http_status_code.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_http_status_code.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_mini_pager.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_mini_pager.yml
index e65ea4a..843b492 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_mini_pager.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_mini_pager.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_full.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_full.yml
index 68dae03..01fe100 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_full.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_full.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_none.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_none.yml
index 9757036..7b11e9e 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_none.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_none.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_some.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_some.yml
index 29dccf4..156e7dd 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_some.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_pager_some.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml
index 21877c9..86f4189 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_plugin_dependencies.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: test_static
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_preview.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_preview.yml
index d0c26bf..9461d01 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_preview.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_preview.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_redirect_view.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_redirect_view.yml
index 723d934..b3c5c70 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_redirect_view.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_redirect_view.yml
@@ -22,7 +22,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_relationship_dependency.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_relationship_dependency.yml
index f392a52..dbbbf16 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_relationship_dependency.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_relationship_dependency.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
index 28a1812..d0d5ebf 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_row_render_cache.yml
@@ -24,7 +24,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml
index f0448aa..91767f9 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_search.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_store_pager_settings.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_store_pager_settings.yml
index 1b6bc95..bae5768 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_store_pager_settings.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_store_pager_settings.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_html_list.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_html_list.yml
index 99f9bfc..35a0496 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_html_list.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_html_list.yml
@@ -20,7 +20,7 @@ display:
         type: none
         options: {  }
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
index 2764a8f..6c631b3 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_style_opml.yml
@@ -21,7 +21,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_ungroup_rows.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_ungroup_rows.yml
index 3acfc42..cafeae9 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_ungroup_rows.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_ungroup_rows.yml
@@ -25,7 +25,7 @@ display:
       access:
         type: perm
       cache:
-        type: tag
+        type: none
       query:
         type: views_query
       exposed_form:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_argument_validate_numeric.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_argument_validate_numeric.yml
index 7337fcc..865bca9 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_argument_validate_numeric.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_argument_validate_numeric.yml
@@ -25,7 +25,7 @@ display:
             type: numeric
           plugin_id: 'null'
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_delete.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_delete.yml
index fb2cff3..4ee2b75 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_delete.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_delete.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test.yml
index 48df3dd..ab61fbc 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_additional_base_field.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_additional_base_field.yml
index a1cb151..c3921a1 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_additional_base_field.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_additional_base_field.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_data.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_data.yml
index 5492480..6ccd8be 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_data.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_data.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_revision.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_revision.yml
index 8a5a477..ec4649f 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_revision.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_entity_test_revision.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_pager_full_zero_items_per_page.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_pager_full_zero_items_per_page.yml
index 82be894..a5be547 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_pager_full_zero_items_per_page.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_view_pager_full_zero_items_per_page.yml
@@ -17,7 +17,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       fields:
diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_views_groupby_save.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_views_groupby_save.yml
index a95fca3..11533bd 100644
--- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_views_groupby_save.yml
+++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_views_groupby_save.yml
@@ -15,7 +15,7 @@ display:
       access:
         type: none
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php
index 173e857..20bf579 100644
--- a/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php
+++ b/core/modules/views/tests/modules/views_test_data/src/Plugin/views/query/QueryTest.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Plugin\views\query\QueryPluginBase;
 use Drupal\views\Plugin\views\join\JoinPluginBase;
-use Drupal\views\ResultRow;
 use Drupal\views\ViewExecutable;
 
 /**
@@ -115,7 +114,7 @@ public function execute(ViewExecutable $view) {
         if ($this->fields) {
           $element = array_intersect_key($element, $this->fields);
         }
-        $result[] = new ResultRow($element);
+        $result[] = (object) $element;
       }
     }
     $this->view->result = $result;
diff --git a/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_access_static.yml b/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_access_static.yml
index 6f2ff35..b79f068 100644
--- a/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_access_static.yml
+++ b/core/modules/views/tests/modules/views_test_data/test_views/views.view.test_access_static.yml
@@ -19,7 +19,7 @@ display:
       access:
         type: test_static
       cache:
-        type: tag
+        type: none
       exposed_form:
         type: basic
       pager:
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 2018d97..98604a0 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -1042,6 +1042,7 @@ function template_preprocess_views_mini_pager(&$variables) {
     $variables['items']['previous']['attributes'] = new Attribute();
   }
 
+  $li_next = array();
   if ($pager_page_array[$element] < ($pager_total[$element] - 1)) {
     $options = array(
       'query' => pager_query_add_page($parameters, $element, $pager_page_array[$element] + 1),
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index bf7fdcf..1e3261b 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -147,7 +147,7 @@ public function form(array $form, FormStateInterface $form_state) {
       );
       $lock_message_substitutions = array(
         '!user' => drupal_render($username),
-        '!age' => $this->dateFormatter->formatTimeDiffSince($view->lock->updated),
+        '!age' => $this->dateFormatter->formatInterval(REQUEST_TIME - $view->lock->updated),
         '@url' => $view->url('break-lock-form'),
       );
       $form['locked'] = array(
diff --git a/core/modules/views_ui/tests/modules/views_ui_test/config/install/views.view.sa_contrib_2013_035.yml b/core/modules/views_ui/tests/modules/views_ui_test/config/install/views.view.sa_contrib_2013_035.yml
index d45d509..580fdad 100644
--- a/core/modules/views_ui/tests/modules/views_ui_test/config/install/views.view.sa_contrib_2013_035.yml
+++ b/core/modules/views_ui/tests/modules/views_ui_test/config/install/views.view.sa_contrib_2013_035.yml
@@ -24,7 +24,7 @@ display:
         options:
           perm: 'access content'
       cache:
-        type: tag
+        type: none
         options: {  }
       query:
         type: views_query
diff --git a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php
index 97e2fb1..34a2016 100644
--- a/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php
+++ b/core/tests/Drupal/Tests/Core/Config/StorageComparerTest.php
@@ -125,6 +125,9 @@ public function testCreateChangelistNoChange() {
     $this->targetStorage->expects($this->once())
       ->method('getAllCollectionNames')
       ->will($this->returnValue(array()));
+    $this->configManager->expects($this->any())
+      ->method('supportsConfigurationEntities')
+      ->will($this->returnValue(TRUE));
 
     $this->storageComparer->createChangelist();
     $this->assertEmpty($this->storageComparer->getChangelist('create'));
@@ -159,6 +162,9 @@ public function testCreateChangelistCreate() {
     $this->targetStorage->expects($this->once())
       ->method('getAllCollectionNames')
       ->will($this->returnValue(array()));
+    $this->configManager->expects($this->any())
+      ->method('supportsConfigurationEntities')
+      ->will($this->returnValue(TRUE));
 
     $this->storageComparer->createChangelist();
     $expected = array(
@@ -198,6 +204,9 @@ public function testCreateChangelistDelete() {
     $this->targetStorage->expects($this->once())
       ->method('getAllCollectionNames')
       ->will($this->returnValue(array()));
+    $this->configManager->expects($this->any())
+      ->method('supportsConfigurationEntities')
+      ->will($this->returnValue(TRUE));
 
     $this->storageComparer->createChangelist();
     $expected = array(
@@ -237,6 +246,9 @@ public function testCreateChangelistUpdate() {
     $this->targetStorage->expects($this->once())
       ->method('getAllCollectionNames')
       ->will($this->returnValue(array()));
+    $this->configManager->expects($this->any())
+      ->method('supportsConfigurationEntities')
+      ->will($this->returnValue(TRUE));
 
     $this->storageComparer->createChangelist();
     $expected = array(
diff --git a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
index 09c890a..1cbed5e 100644
--- a/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
+++ b/core/tests/Drupal/Tests/Core/Datetime/DateTest.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Datetime\DateFormatter;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Tests\UnitTestCase;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * @coversDefaultClass \Drupal\Core\Datetime\DateFormatter
@@ -40,37 +39,22 @@ class DateTest extends UnitTestCase {
   protected $stringTranslation;
 
   /**
-   * The mocked string translation.
-   *
-   * @var \Symfony\Component\HttpFoundation\RequestStack|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $requestStack;
-
-  /**
-   * The mocked date formatter class.
+   * The tested date service class.
    *
    * @var \Drupal\Core\Datetime\DateFormatter
    */
   protected $dateFormatter;
 
-  /**
-   * The date formatter class where methods can be stubbed.
-   *
-   * @var \Drupal\Core\Datetime\DateFormatter|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $dateFormatterStub;
-
   protected function setUp() {
     parent::setUp();
 
     $entity_storage = $this->getMock('Drupal\Core\Entity\EntityStorageInterface');
 
     $this->entityManager = $this->getMock('Drupal\Core\Entity\EntityManagerInterface');
-    $this->entityManager->expects($this->any())->method('getStorage')->with('date_format')->willReturn($entity_storage);
+    $this->entityManager->expects($this->once())->method('getStorage')->with('date_format')->willReturn($entity_storage);
 
     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
     $this->stringTranslation = $this->getMock('Drupal\Core\StringTranslation\TranslationInterface');
-    $this->requestStack = $this->getMock('Symfony\Component\HttpFoundation\RequestStack');
 
     $config_factory = $this->getConfigFactoryStub(['system.date' => ['country' => ['default' => 'GB']]]);
     $container = new ContainerBuilder();
@@ -78,20 +62,15 @@ protected function setUp() {
     $container->set('string_translation', $this->getStringTranslationStub());
     \Drupal::setContainer($container);
 
-    $this->dateFormatter = new DateFormatter($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub(), $this->requestStack);
-
-    $this->dateFormatterStub = $this->getMockBuilder('\Drupal\Core\Datetime\DateFormatter')
-      ->setConstructorArgs([$this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub(), $this->requestStack])
-      ->setMethods(['formatDiff'])
-      ->getMock();
+    $this->dateFormatter = new DateFormatter($this->entityManager, $this->languageManager, $this->stringTranslation, $this->getConfigFactoryStub());
   }
 
   /**
-   * Tests the formatInterval method.
+   * Tests the formatPlugin method.
    *
    * @dataProvider providerTestFormatInterval
    *
-   * @covers ::formatInterval
+   * @covers \Drupal\Core\Datetime\DateFormatter::formatInterval
    */
   public function testFormatInterval($interval, $granularity, $expected, $langcode = NULL) {
     // Mocks a simple formatPlural implementation.
@@ -181,218 +160,4 @@ public function testGetSampleDateFormats() {
     }
   }
 
-  /**
-   * Tests the formatTimeDiffUntil method.
-   *
-   * @covers ::formatTimeDiffUntil
-   */
-  public function testFormatTimeDiffUntil() {
-    $expected = '1 second';
-    $request_time = $this->createTimestamp('2013-12-11 10:09:08');
-    $timestamp = $this->createTimestamp('2013-12-11 10:09:09');
-    $options = array();
-
-    // Mocks the formatDiff function of the dateformatter object.
-    $this->dateFormatterStub
-      ->expects($this->any())
-      ->method('formatDiff')
-      ->with($timestamp, $request_time, $options)
-      ->will($this->returnValue($expected));
-
-    $request = Request::createFromGlobals();
-    $request->server->set('REQUEST_TIME', $request_time);
-    // Mocks a the request stack getting the current request.
-    $this->requestStack->expects($this->any())
-      ->method('getCurrentRequest')
-      ->willReturn($request);
-
-    $this->assertEquals($expected, $this->dateFormatterStub->formatTimeDiffSince($timestamp, $options));
-  }
-
-  /**
-   * Tests the formatTimeDiffSince method.
-   *
-   * @covers ::formatTimeDiffSince
-   */
-  public function testFormatTimeDiffSince() {
-    $expected = '1 second';
-    $timestamp = $this->createTimestamp('2013-12-11 10:09:07');
-    $request_time = $this->createTimestamp('2013-12-11 10:09:08');
-    $options = array();
-
-    // Mocks the formatDiff function of the dateformatter object.
-    $this->dateFormatterStub
-      ->expects($this->any())
-      ->method('formatDiff')
-      ->with($request_time, $timestamp, $options)
-      ->will($this->returnValue($expected));
-
-    $request = Request::createFromGlobals();
-    $request->server->set('REQUEST_TIME', $request_time);
-    // Mocks a the request stack getting the current request.
-    $this->requestStack->expects($this->any())
-      ->method('getCurrentRequest')
-      ->willReturn($request);
-
-    $this->assertEquals($expected, $this->dateFormatterStub->formatTimeDiffUntil($timestamp, $options));
-  }
-
-  /**
-   * Tests the formatDiff method.
-   *
-   * @dataProvider providerTestFormatDiff
-   *
-   * @covers ::formatDiff
-   */
-  public function testformatDiff($expected, $timestamp1, $timestamp2, $options = array()) {
-
-    // Mocks a simple formatPlural implementation.
-    $this->stringTranslation->expects($this->any())
-      ->method('formatPlural')
-      ->with($this->anything(), $this->anything(), $this->anything(), array(), array('langcode' => isset($options['langcode']) ? $options['langcode'] : NULL))
-      ->will($this->returnCallback(function($count, $one, $multiple) {
-        return $count == 1 ? $one : str_replace('@count', $count, $multiple);
-      }));
-
-    // Mocks a simple translate implementation.
-    $this->stringTranslation->expects($this->any())
-      ->method('translate')
-      ->with($this->anything())
-      ->will($this->returnCallback(function($string, $args, $options) {
-        return $string;
-      }));
-
-    $this->assertEquals($expected, $this->dateFormatter->formatDiff($timestamp1, $timestamp2, $options));
-  }
-
-  /**
-   * Data provider for testformatDiff().
-   */
-  public function providerTestFormatDiff() {
-    // This is the fixed request time in the test.
-    $request_time = $this->createTimestamp('2013-12-11 10:09:08');
-
-    $granularity_3 = array('granularity' => 3);
-    $granularity_4 = array('granularity' => 4);
-
-    $langcode_en = array('langcode' => 'en');
-    $langcode_lolspeak = array('langcode' => 'xxx-lolspeak');
-
-    $non_strict = array('strict' => FALSE);
-
-    $data = array(
-      // Checks for equal timestamps.
-      array('0 seconds', $request_time, $request_time),
-
-      // Checks for seconds only.
-      array('1 second', $this->createTimestamp('2013-12-11 10:09:07'), $request_time),
-      array('1 second', $this->createTimestamp('2013-12-11 10:09:07'), $request_time),
-      array('1 second', $this->createTimestamp('2013-12-11 10:09:07'), $request_time, $granularity_3 + $langcode_en),
-      array('1 second', $this->createTimestamp('2013-12-11 10:09:07'), $request_time, $granularity_4 + $langcode_lolspeak),
-      array('2 seconds', $this->createTimestamp('2013-12-11 10:09:06'), $request_time),
-      array('59 seconds', $this->createTimestamp('2013-12-11 10:08:09'), $request_time),
-      array('59 seconds', $this->createTimestamp('2013-12-11 10:08:09'), $request_time),
-
-      // Checks for minutes and possibly seconds.
-      array('1 minute', $this->createTimestamp('2013-12-11 10:08:08'), $request_time),
-      array('1 minute', $this->createTimestamp('2013-12-11 10:08:08'), $request_time),
-      array('1 minute 1 second', $this->createTimestamp('2013-12-11 10:08:07'), $request_time),
-      array('1 minute 59 seconds', $this->createTimestamp('2013-12-11 10:07:09'), $request_time),
-      array('2 minutes', $this->createTimestamp('2013-12-11 10:07:08'), $request_time),
-      array('2 minutes 1 second', $this->createTimestamp('2013-12-11 10:07:07'), $request_time),
-      array('2 minutes 2 seconds', $this->createTimestamp('2013-12-11 10:07:06'), $request_time),
-      array('2 minutes 2 seconds', $this->createTimestamp('2013-12-11 10:07:06'), $request_time, $granularity_3),
-      array('2 minutes 2 seconds', $this->createTimestamp('2013-12-11 10:07:06'), $request_time, $granularity_4),
-      array('30 minutes', $this->createTimestamp('2013-12-11 09:39:08'), $request_time),
-      array('59 minutes 59 seconds', $this->createTimestamp('2013-12-11 09:09:09'), $request_time),
-      array('59 minutes 59 seconds', $this->createTimestamp('2013-12-11 09:09:09'), $request_time),
-
-      // Checks for hours and possibly minutes or seconds.
-      array('1 hour', $this->createTimestamp('2013-12-11 09:09:08'), $request_time),
-      array('1 hour', $this->createTimestamp('2013-12-11 09:09:08'), $request_time),
-      array('1 hour 1 second', $this->createTimestamp('2013-12-11 09:09:07'), $request_time),
-      array('1 hour 2 seconds', $this->createTimestamp('2013-12-11 09:09:06'), $request_time),
-      array('1 hour 1 minute', $this->createTimestamp('2013-12-11 09:08:08'), $request_time),
-      array('1 hour 1 minute 1 second', $this->createTimestamp('2013-12-11 09:08:07'), $request_time, $granularity_3),
-      array('1 hour 1 minute 2 seconds', $this->createTimestamp('2013-12-11 09:08:06'), $request_time, $granularity_4),
-      array('1 hour 30 minutes', $this->createTimestamp('2013-12-11 08:39:08'), $request_time),
-      array('2 hours', $this->createTimestamp('2013-12-11 08:09:08'), $request_time),
-      array('23 hours 59 minutes', $this->createTimestamp('2013-12-10 10:10:08'), $request_time),
-
-      // Checks for days and possibly hours, minutes or seconds.
-      array('1 day', $this->createTimestamp('2013-12-10 10:09:08'), $request_time),
-      array('1 day 1 second', $this->createTimestamp('2013-12-10 10:09:07'), $request_time),
-      array('1 day 1 hour', $this->createTimestamp('2013-12-10 09:09:08'), $request_time),
-      array('1 day 1 hour 1 minute', $this->createTimestamp('2013-12-10 09:08:07'), $request_time, $granularity_3 + $langcode_en),
-      array('1 day 1 hour 1 minute 1 second', $this->createTimestamp('2013-12-10 09:08:07'), $request_time, $granularity_4 + $langcode_lolspeak),
-      array('1 day 2 hours 2 minutes 2 seconds', $this->createTimestamp('2013-12-10 08:07:06'), $request_time, $granularity_4),
-      array('2 days', $this->createTimestamp('2013-12-09 10:09:08'), $request_time),
-      array('2 days 2 minutes', $this->createTimestamp('2013-12-09 10:07:08'), $request_time),
-      array('2 days 2 hours', $this->createTimestamp('2013-12-09 08:09:08'), $request_time),
-      array('2 days 2 hours 2 minutes', $this->createTimestamp('2013-12-09 08:07:06'), $request_time, $granularity_3 + $langcode_en),
-      array('2 days 2 hours 2 minutes 2 seconds', $this->createTimestamp('2013-12-09 08:07:06'), $request_time, $granularity_4 + $langcode_lolspeak),
-
-      // Checks for weeks and possibly days, hours, minutes or seconds.
-      array('1 week', $this->createTimestamp('2013-12-04 10:09:08'), $request_time),
-      array('1 week 1 day', $this->createTimestamp('2013-12-03 10:09:08'), $request_time),
-      array('2 weeks', $this->createTimestamp('2013-11-27 10:09:08'), $request_time),
-      array('2 weeks 2 days', $this->createTimestamp('2013-11-25 08:07:08'), $request_time),
-      array('2 weeks 2 days 2 hours 2 minutes', $this->createTimestamp('2013-11-25 08:07:08'), $request_time, $granularity_4),
-      array('4 weeks', $this->createTimestamp('2013-11-13 10:09:08'), $request_time),
-      array('4 weeks 1 day', $this->createTimestamp('2013-11-12 10:09:08'), $request_time),
-
-      // Checks for months and possibly days, hours, minutes or seconds.
-      array('1 month', $this->createTimestamp('2013-11-11 10:09:08'), $request_time),
-      array('1 month 1 second', $this->createTimestamp('2013-11-11 10:09:07'), $request_time),
-      array('1 month 1 hour', $this->createTimestamp('2013-11-11 09:09:08'), $request_time),
-      array('1 month 1 hour 1 minute', $this->createTimestamp('2013-11-11 09:08:07'), $request_time, $granularity_3),
-      array('1 month 1 hour 1 minute 1 second', $this->createTimestamp('2013-11-11 09:08:07'), $request_time, $granularity_4),
-      array('1 month 4 weeks', $this->createTimestamp('2013-10-13 10:09:08'), $request_time),
-      array('1 month 4 weeks 1 day', $this->createTimestamp('2013-10-13 10:09:08'), $request_time, $granularity_3),
-      array('1 month 4 weeks', $this->createTimestamp('2013-10-12 10:09:08'), $request_time),
-      array('1 month 4 weeks 2 days', $this->createTimestamp('2013-10-12 10:09:08'), $request_time, $granularity_3),
-      array('2 months', $this->createTimestamp('2013-10-11 10:09:08'), $request_time),
-      array('2 months 1 day', $this->createTimestamp('2013-10-10 10:09:08'), $request_time),
-      array('2 months 2 days', $this->createTimestamp('2013-10-09 08:07:06'), $request_time),
-      array('2 months 2 days 2 hours', $this->createTimestamp('2013-10-09 08:07:06'), $request_time, $granularity_3),
-      array('2 months 2 days 2 hours 2 minutes', $this->createTimestamp('2013-10-09 08:07:06'), $request_time, $granularity_4),
-      array('6 months 2 days', $this->createTimestamp('2013-06-09 10:09:08'), $request_time),
-      array('11 months 3 hours', $this->createTimestamp('2013-01-11 07:09:08'), $request_time),
-      array('11 months 4 weeks', $this->createTimestamp('2012-12-12 10:09:08'), $request_time),
-      array('11 months 4 weeks 2 days', $this->createTimestamp('2012-12-12 10:09:08'), $request_time, $granularity_3),
-
-      // Checks for years and possibly months, days, hours, minutes or seconds.
-      array('1 year', $this->createTimestamp('2012-12-11 10:09:08'), $request_time),
-      array('1 year 1 minute', $this->createTimestamp('2012-12-11 10:08:08'), $request_time),
-      array('1 year 1 day', $this->createTimestamp('2012-12-10 10:09:08'), $request_time),
-      array('2 years', $this->createTimestamp('2011-12-11 10:09:08'), $request_time),
-      array('2 years 2 minutes', $this->createTimestamp('2011-12-11 10:07:08'), $request_time),
-      array('2 years 2 days', $this->createTimestamp('2011-12-09 10:09:08'), $request_time),
-      array('2 years 2 months 2 days', $this->createTimestamp('2011-10-09 08:07:06'), $request_time, $granularity_3),
-      array('2 years 2 months 2 days 2 hours', $this->createTimestamp('2011-10-09 08:07:06'), $request_time, $granularity_4),
-      array('10 years', $this->createTimestamp('2003-12-11 10:09:08'), $request_time),
-      array('100 years', $this->createTimestamp('1913-12-11 10:09:08'), $request_time),
-
-      // Checks the non-strict option vs. strict (default).
-      array('1 second', $this->createTimestamp('2013-12-11 10:09:08'), $this->createTimestamp('2013-12-11 10:09:07'), $non_strict),
-      array('0 seconds', $this->createTimestamp('2013-12-11 10:09:08'), $this->createTimestamp('2013-12-11 10:09:07')),
-    );
-
-    return $data;
-  }
-
-  /**
-   * Creates a UNIX timestamp given a date and time string in the format
-   * year-month-day hour:minute:seconds (e.g. 2013-12-11 10:09:08).
-   *
-   * @param string $dateTimeString
-   *   The formatted date and time string.
-   *
-   * @return int
-   *   The UNIX timestamp.
-   */
-  private function createTimestamp($dateTimeString) {
-    return \DateTime::createFromFormat('Y-m-d G:i:s', $dateTimeString)->getTimestamp();
-  }
-
 }
diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php b/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
deleted file mode 100644
index d923f9a..0000000
--- a/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTest.php
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\Core\DrupalKernel\DrupalKernelTest.
- */
-
-namespace Drupal\Tests\Core\DrupalKernel {
-
-  use Drupal\Core\DrupalKernel;
-  use Drupal\Tests\UnitTestCase;
-  use org\bovigo\vfs\vfsStream;
-  use Symfony\Component\HttpFoundation\Request;
-
-  /**
-   * @coversDefaultClass \Drupal\Core\DrupalKernel
-   * @group DrupalKernel
-   */
-  class DrupalKernelTest extends UnitTestCase {
-
-    /**
-     * Tests hostname validation with settings.
-     *
-     * @covers ::setupTrustedHosts
-     * @dataProvider providerTestTrustedHosts
-     */
-    public function testTrustedHosts($host, $server_name, $message, $expected = FALSE) {
-      $request = new Request();
-
-      $trusted_host_patterns = [
-        '^example\.com$',
-        '^.+\.example\.com$',
-        '^example\.org',
-        '^.+\.example\.org',
-      ];
-
-      if (!empty($host)) {
-        $request->headers->set('HOST', $host);
-      }
-
-      $request->server->set('SERVER_NAME', $server_name);
-
-      $method = new \ReflectionMethod('Drupal\Core\DrupalKernel', 'setupTrustedHosts');
-      $method->setAccessible(TRUE);
-      $valid_host = $method->invoke(null, $request, $trusted_host_patterns);
-
-      $this->assertSame($expected, $valid_host, $message);
-
-      // Reset the trusted hosts because it is statically stored on the request.
-      $method->invoke(null, $request, []);
-      // Reset the request factory because it is statically stored on the request.
-      Request::setFactory(NULL);
-    }
-
-    /**
-     * Provides test data for testTrustedHosts().
-     */
-    public function providerTestTrustedHosts() {
-      $data = [];
-
-      // Tests canonical URL.
-      $data[] = [
-        'www.example.com',
-        'www.example.com',
-        'canonical URL is trusted',
-        TRUE
-      ];
-
-      // Tests missing hostname for HTTP/1.0 compatibility where the Host
-      // header is optional.
-      $data[] = [NULL, 'www.example.com', 'empty Host is valid', TRUE];
-
-      // Tests the additional patterns from the settings.
-      $data[] = [
-        'example.com',
-        'www.example.com',
-        'host from settings is trusted',
-        TRUE
-      ];
-      $data[] = [
-        'subdomain.example.com',
-        'www.example.com',
-        'host from settings is trusted',
-        TRUE
-      ];
-      $data[] = [
-        'www.example.org',
-        'www.example.com',
-        'host from settings is trusted',
-        TRUE
-      ];
-      $data[] = [
-        'example.org',
-        'www.example.com',
-        'host from settings is trusted',
-        TRUE
-      ];
-
-      // Tests mismatch.
-      $data[] = [
-        'www.blackhat.com',
-        'www.example.com',
-        'unspecified host is untrusted',
-        FALSE
-      ];
-
-      return $data;
-    }
-
-    /**
-     * Tests site path finding.
-     *
-     * This test is run in a separate process since it defines DRUPAL_ROOT. This
-     * stops any possible pollution of other tests.
-     *
-     * @covers ::findSitePath
-     * @runInSeparateProcess
-     */
-    public function testFindSitePath() {
-      $vfs_root = vfsStream::setup('drupal_root');
-      $sites_php = <<<'EOD'
-<?php
-$sites['8888.www.example.org'] = 'example';
-EOD;
-
-      // Create the expected directory structure.
-      vfsStream::create(['sites' => [
-        'sites.php' => $sites_php,
-        'example' => [
-          'settings.php' => 'test'
-        ]
-      ]]);
-
-      define('DRUPAL_ROOT', $vfs_root->url('drupal_root'));
-      $request = new Request();
-      $request->server->set('SERVER_NAME', 'www.example.org');
-      $request->server->set('SERVER_PORT', '8888');
-      $request->server->set('SCRIPT_NAME', '/index.php');
-      $this->assertEquals('sites/example', DrupalKernel::findSitePath($request));
-    }
-  }
-
-}
-
-
-namespace {
-  if (!function_exists('drupal_valid_test_ua')) {
-    function drupal_valid_test_ua($new_prefix = NULL) {
-      return FALSE;
-    }
-  }
-}
\ No newline at end of file
diff --git a/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php b/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php
new file mode 100644
index 0000000..1fb30ae
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DrupalKernel/DrupalKernelTrustedHostsTest.php
@@ -0,0 +1,79 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\DrupalKernel\DrupalKernelTrustedHostsTest.
+ */
+
+namespace Drupal\Tests\Core\DrupalKernel;
+
+use Drupal\Core\DrupalKernel;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * @coversDefaultClass \Drupal\Core\DrupalKernel
+ * @group DrupalKernel
+ */
+class DrupalKernelTrustedHostsTest extends UnitTestCase {
+
+  /**
+   * Tests hostname validation with settings.
+   *
+   * @covers ::setupTrustedHosts
+   * @dataProvider providerTestTrustedHosts
+   */
+  public function testTrustedHosts($host, $server_name, $message, $expected = FALSE) {
+    $request = new Request();
+
+    $trusted_host_patterns = [
+      '^example\.com$',
+      '^.+\.example\.com$',
+      '^example\.org',
+      '^.+\.example\.org',
+    ];
+
+    if (!empty($host)) {
+      $request->headers->set('HOST', $host);
+    }
+
+    $request->server->set('SERVER_NAME', $server_name);
+
+    $method = new \ReflectionMethod('Drupal\Core\DrupalKernel', 'setupTrustedHosts');
+    $method->setAccessible(TRUE);
+    $valid_host = $method->invoke(null, $request, $trusted_host_patterns);
+
+    $this->assertSame($expected, $valid_host, $message);
+
+    // Reset the trusted hosts because it is statically stored on the request.
+    $method->invoke(null, $request, []);
+    // Reset the request factory because it is statically stored on the request.
+    Request::setFactory(NULL);
+  }
+
+  /**
+   * Provides test data for testTrustedHosts().
+   */
+  public function providerTestTrustedHosts() {
+    $data = [];
+
+    // Tests canonical URL.
+    $data[] = ['www.example.com', 'www.example.com', 'canonical URL is trusted', TRUE];
+
+    // Tests missing hostname for HTTP/1.0 compatibility where the Host
+    // header is optional.
+    $data[] = [NULL, 'www.example.com', 'empty Host is valid', TRUE];
+
+    // Tests the additional paterns from the settings.
+    $data[] = ['example.com', 'www.example.com', 'host from settings is trusted', TRUE];
+    $data[] = ['subdomain.example.com', 'www.example.com', 'host from settings is trusted', TRUE];
+    $data[] = ['www.example.org', 'www.example.com', 'host from settings is trusted', TRUE];
+    $data[] = ['example.org', 'www.example.com', 'host from settings is trusted', TRUE];
+
+    // Tests mismatch.
+    $data[] = ['www.blackhat.com', 'www.example.com', 'unspecified host is untrusted', FALSE];
+
+    return $data;
+  }
+
+}
