diff --git a/core/includes/config.inc b/core/includes/config.inc
index 06e0e67..ee01f19 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -1,9 +1,9 @@
 <?php
 
 use Drupal\Core\Config\Config;
+use Drupal\Core\Config\ConfigSync;
+use Drupal\Core\Config\ConfigSyncInstall;
 use Drupal\Core\Config\FileStorage;
-use Drupal\Core\Config\NullStorage;
-use Drupal\Core\Config\StorageInterface;
 
 /**
  * @file
@@ -24,34 +24,17 @@
  *   The name of the module or theme to install default configuration for.
  */
 function config_install_default_config($type, $name) {
+  // If this module defines any ConfigEntity types, then create a manifest file
+  // for each of them with a listing of the objects it maintains.
+  foreach (config_get_module_config_entities($name) as $entity_type => $entity_info) {
+    config('manifest.' . $entity_info['config_prefix'])->save();
+  }
+
   $config_dir = drupal_get_path($type, $name) . '/config';
   if (is_dir($config_dir)) {
-    $source_storage = new FileStorage($config_dir);
-    $target_storage = drupal_container()->get('config.storage');
-
-    // If this module defines any ConfigEntity types, then create a manifest file
-    // for each of them with a listing of the objects it maintains.
-    foreach (config_get_module_config_entities($name) as $entity_type => $entity_info) {
-      $manifest_config = config('manifest.' . $entity_info['config_prefix']);
-      $manifest_data = array();
-      foreach ($source_storage->listAll($entity_info['config_prefix']) as $config_name) {
-        list(, , $id) = explode('.', $config_name);
-        $manifest_data[$id]['name'] = $config_name;
-      }
-      $manifest_config->setData($manifest_data)->save();
-    }
-
-    $config_changes = array(
-      'delete' => array(),
-      'create' => array(),
-      'change' => array(),
-    );
-    $config_changes['create'] = $source_storage->listAll();
-    if (empty($config_changes['create'])) {
-      return;
-    }
-    $remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
-    config_sync_changes($remaining_changes, $source_storage, $target_storage);
+    $config_sync = new ConfigSyncInstall(new FileStorage($config_dir), drupal_container()->get('config.storage'));
+    $config_sync->setChangelist();
+    $config_sync->doSync();
   }
 }
 
@@ -106,97 +89,6 @@ function config($name) {
 }
 
 /**
- * Returns a list of differences between configuration storages.
- *
- * @param Drupal\Core\Config\StorageInterface $source_storage
- *   The storage to synchronize configuration from.
- * @param Drupal\Core\Config\StorageInterface $target_storage
- *   The storage to synchronize configuration to.
- *
- * @return array|bool
- *   An assocative array containing the differences between source and target
- *   storage, or FALSE if there are no differences.
- */
-function config_sync_get_changes(StorageInterface $source_storage, StorageInterface $target_storage) {
-  // Config entities maintain 'manifest' files that list the objects they
-  // are currently handling. Each file is a simple indexed array of config
-  // object names. In order to generate a list of objects that have been
-  // created or deleted we need to open these files in both the source and
-  // target storage, generate an array of the objects, and compare them.
-  $source_config_data = array();
-  $target_config_data = array();
-  foreach ($source_storage->listAll('manifest') as $name) {
-    if ($source_manifest_data = $source_storage->read($name)) {
-      $source_config_data = array_merge($source_config_data, $source_manifest_data);
-    }
-
-    if ($target_manifest_data = $target_storage->read($name)) {
-      $target_config_data = array_merge($target_config_data, $target_manifest_data);
-    }
-  }
-
-  $config_changes = array(
-    'create' => array(),
-    'change' => array(),
-    'delete' => array(),
-  );
-
-  foreach (array_diff_key($target_config_data, $source_config_data) as $name => $value) {
-    $config_changes['delete'][] = $value['name'];
-  }
-
-  foreach (array_diff_key($source_config_data, $target_config_data) as $name => $value) {
-    $config_changes['create'][] = $value['name'];
-  }
-
-  foreach (array_intersect($source_storage->listAll(), $target_storage->listAll()) as $name) {
-    // Ignore manifest files
-    if (substr($name, 0, 9) != 'manifest.') {
-      $source_config_data = $source_storage->read($name);
-      $target_config_data = $target_storage->read($name);
-      if ($source_config_data !== $target_config_data) {
-        $config_changes['change'][] = $name;
-      }
-    }
-  }
-
-  // Do not trigger subsequent synchronization operations if there are no
-  // changes in any category.
-  if (empty($config_changes['create']) && empty($config_changes['change']) && empty($config_changes['delete'])) {
-    return FALSE;
-  }
-  return $config_changes;
-}
-
-/**
- * Writes an array of config file changes from a source storage to a target storage.
- *
- * @param array $config_changes
- *   An array of changes to be written.
- * @param Drupal\Core\Config\StorageInterface $source_storage
- *   The storage to synchronize configuration from.
- * @param Drupal\Core\Config\StorageInterface $target_storage
- *   The storage to synchronize configuration to.
- */
-function config_sync_changes(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
-  $factory = drupal_container()->get('config.factory');
-  foreach (array('delete', 'create', 'change') as $op) {
-    foreach ($config_changes[$op] as $name) {
-      $config = new Config($name, $target_storage);
-      if ($op == 'delete') {
-        $config->delete();
-      }
-      else {
-        $data = $source_storage->read($name);
-        $config->setData($data ? $data : array());
-        $config->save();
-      }
-      $factory->reset($name);
-    }
-  }
-}
-
-/**
  * Imports configuration into the active configuration.
  *
  * @return bool|null
@@ -205,11 +97,8 @@ function config_sync_changes(array $config_changes, StorageInterface $source_sto
  */
 function config_import() {
   // Retrieve a list of differences between staging and the active configuration.
-  $source_storage = drupal_container()->get('config.storage.staging');
-  $target_storage = drupal_container()->get('config.storage');
-
-  $config_changes = config_sync_get_changes($source_storage, $target_storage);
-  if (empty($config_changes)) {
+  $config_sync = new ConfigSync(drupal_container()->get('config.storage.staging'), drupal_container()->get('config.storage'));
+  if (!$config_sync->setChangelist()->hasChanges()) {
     return;
   }
 
@@ -224,8 +113,7 @@ function config_import() {
 
   $success = TRUE;
   try {
-    $remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
-    config_sync_changes($remaining_changes, $source_storage, $target_storage);
+    $config_sync->doSync();
   }
   catch (ConfigException $e) {
     watchdog_exception('config_import', $e);
@@ -237,52 +125,6 @@ function config_import() {
 }
 
 /**
- * Invokes MODULE_config_import() callbacks for configuration changes.
- *
- * @param array $config_changes
- *   An array of changes to be loaded.
- * @param Drupal\Core\Config\StorageInterface $source_storage
- *   The storage to synchronize configuration from.
- * @param Drupal\Core\Config\StorageInterface $target_storage
- *   The storage to synchronize configuration to.
- *
- * @todo Add support for other extension types; e.g., themes etc.
- */
-function config_import_invoke_owner(array $config_changes, StorageInterface $source_storage, StorageInterface $target_storage) {
-  // Allow modules to take over configuration change operations for
-  // higher-level configuration data.
-  // First pass deleted, then new, and lastly changed configuration, in order to
-  // handle dependencies correctly.
-  $manager = drupal_container()->get('plugin.manager.entity');
-  foreach (array('delete', 'create', 'change') as $op) {
-    foreach ($config_changes[$op] as $key => $name) {
-      // Call to the configuration entity's storage controller to handle the
-      // configuration change.
-      $handled_by_module = FALSE;
-      // Validate the configuration object name before importing it.
-      Config::validateName($name);
-      if ($entity_type = config_get_entity_type_by_name($name)) {
-        $old_config = new Config($name, $target_storage);
-        $old_config->load();
-
-        $data = $source_storage->read($name);
-        $new_config = new Config($name, $target_storage);
-        if ($data !== FALSE) {
-          $new_config->setData($data);
-        }
-
-        $method = 'import' . ucfirst($op);
-        $handled_by_module = $manager->getStorageController($entity_type)->$method($name, $new_config, $old_config);
-      }
-      if (!empty($handled_by_module)) {
-        unset($config_changes[$op][$key]);
-      }
-    }
-  }
-  return $config_changes;
-}
-
-/**
  * Return a list of all config entity types provided by a module.
  *
  * @param string $module
diff --git a/core/modules/config/config.admin.inc b/core/modules/config/config.admin.inc
index c15e02a..cdaa475 100644
--- a/core/modules/config/config.admin.inc
+++ b/core/modules/config/config.admin.inc
@@ -6,6 +6,7 @@
  */
 
 use Drupal\Core\Config\StorageInterface;
+use Drupal\Core\Config\ConfigSync;
 
 /**
  * Helper function to construct the storage changes in a configuration synchronization form.
@@ -28,15 +29,15 @@ function config_admin_sync_form(array &$form, array &$form_state, StorageInterfa
     return $form;
   }
 
-  $config_changes = config_sync_get_changes($source_storage, $target_storage);
-  if (empty($config_changes)) {
+  $config_sync = new ConfigSync($source_storage, $target_storage);
+  if (!$config_sync->setChangelist()->hasChanges()) {
     $form['no_changes'] = array(
       '#markup' => t('There are no configuration changes.'),
     );
     return $form;
   }
 
-  foreach ($config_changes as $config_change_type => $config_files) {
+  foreach ($config_sync->getChangelist() as $config_change_type => $config_files) {
     if (empty($config_files)) {
       continue;
     }
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
index 95089f7..541dcaf 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImportTest.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\config\Tests;
 
+use Drupal\Core\Config\ConfigSync;
 use Drupal\simpletest\DrupalUnitTestBase;
 
 /**
@@ -85,7 +86,8 @@ function testDeleted() {
     $this->assertTrue(isset($GLOBALS['hook_config_test']['delete']));
 
     // Verify that there is nothing more to import.
-    $this->assertFalse(config_sync_get_changes($staging, $storage));
+    $config_sync = new ConfigSync($staging, $storage);
+    $this->assertFalse($config_sync->setChangelist()->hasChanges());
   }
 
   /**
@@ -134,7 +136,8 @@ function testNew() {
     $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
 
     // Verify that there is nothing more to import.
-    $this->assertFalse(config_sync_get_changes($staging, $storage));
+    $config_sync = new ConfigSync($staging, $storage);
+    $this->assertFalse($config_sync->setChangelist()->hasChanges());
   }
 
   /**
@@ -191,7 +194,8 @@ function testUpdated() {
     $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
 
     // Verify that there is nothing more to import.
-    $this->assertFalse(config_sync_get_changes($staging, $storage));
+    $config_sync = new ConfigSync($staging, $storage);
+    $this->assertFalse($config_sync->setChangelist()->hasChanges());
   }
 
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/RegressionTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/RegressionTest.php
index f38b49f..4ad4417 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/RegressionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/RegressionTest.php
@@ -12,13 +12,6 @@
  */
 class RegressionTest extends DatabaseTestBase {
 
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = array('node');
-
   public static function getInfo() {
     return array(
       'name' => 'Regression tests',
diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
index 5547a00..ccfa5fa 100644
--- a/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
+++ b/core/modules/views/lib/Drupal/views/Tests/ViewTestData.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views\Tests;
 
+use Drupal\Core\Config\ConfigSync;
 use Drupal\Core\Config\FileStorage;
 
 /**
@@ -39,12 +40,6 @@ public static function importTestViews($class, $modules = array()) {
       $class = get_parent_class($class);
     }
     if (!empty($views)) {
-      $target_storage = drupal_container()->get('config.storage');
-      $config_changes = array(
-        'delete' => array(),
-        'create' => array(),
-        'change' => array(),
-      );
       foreach ($modules as $module) {
         $config_dir = drupal_get_path('module', $module) . '/test_views';
         if (!is_dir($config_dir) || !module_exists($module)) {
@@ -52,16 +47,18 @@ public static function importTestViews($class, $modules = array()) {
         }
 
         $source_storage = new FileStorage($config_dir);
+        $config_sync = new ConfigSync($source_storage, drupal_container()->get('config.storage'));
+        // Get the existing empty change list.
+        $config_changes = $config_sync->getChangelist();
         foreach ($source_storage->listAll() as $config_name) {
           list(, , $id) = explode('.', $config_name);
           if (in_array($id, $views)) {
             $config_changes['create'][] = $config_name;
           }
         }
-      }
-      if (!empty($config_changes['create'])) {
-        $remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
-        config_sync_changes($remaining_changes, $source_storage, $target_storage);
+        // Override the changelist with the specific views we need to import.
+        $config_sync->setChangelist($config_changes);
+        $config_sync->doSync();
       }
     }
   }
