diff --git a/core/includes/config.inc b/core/includes/config.inc
index 3e22534..6cebc9e 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -24,34 +24,53 @@
  *   The name of the module or theme to install default configuration for.
  */
 function config_install_default_config($type, $name) {
-  $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 ($type == 'module') {
+    $list = module_list();
+  }
+  else {
+    $list = array_keys(list_themes());
+  }
+  $config_changes = array('delete' => array(), 'change' => array());
+  $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;
+  // Determine config entity types implemented by the installed extension.
+  $config_entity_types = config_get_module_config_entities($name);
+
+  foreach ($list as $extension) {
+    if (!is_dir($config_dir = drupal_get_path($type, $extension) . '/config')) {
+      continue;
+    }
+    $source_storage = new FileStorage($config_dir);
+    // For the extension being installed, install all configuration objects.
+    if ($extension == $name) {
+      $config_changes['create'] = $source_storage->listAll($extension . '.');
+    }
+    // Other extensions may only provide default configuration for configuration
+    // entities. Static settings can neither be provided nor overridden.
+    else {
+      $config_changes['create'] = array();
+      foreach ($config_entity_types as $entity_type => $entity_info) {
+        $config_changes['create'] = $source_storage->listAll($entity_info['config_prefix'] . '.');
       }
-      $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;
+      continue;
     }
     $remaining_changes = config_import_invoke_owner($config_changes, $source_storage, $target_storage);
-    config_sync_changes($remaining_changes, $source_storage, $target_storage);
+    if ($extension == $name) {
+      config_sync_changes($remaining_changes, $source_storage, $target_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_entity_types as $entity_type => $entity_info) {
+    $manifest_config = config('manifest.' . $entity_info['config_prefix']);
+    $id_index = count(explode('.', $entity_info['config_prefix']));
+    foreach ($target_storage->listAll($entity_info['config_prefix'] . '.') as $config_name) {
+      $parts = explode('.', $config_name);
+      $manifest_config->set($parts[$id_index] . '.name', $config_name);
+    }
+    $manifest_config->save();
   }
 }
 
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php
index b549119..f578848 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallTest.php
@@ -7,12 +7,12 @@
 
 namespace Drupal\config\Tests;
 
-use Drupal\simpletest\DrupalUnitTestBase;
+use Drupal\simpletest\WebTestBase;
 
 /**
  * Tests installation of configuration objects in installation functionality.
  */
-class ConfigInstallTest extends DrupalUnitTestBase {
+class ConfigInstallTest extends WebTestBase {
   public static function getInfo() {
     return array(
       'name' => 'Installation functionality',
@@ -30,7 +30,7 @@ function setUp() {
   }
 
   /**
-   * Tests module installation.
+   * Tests installing and uninstalling a module that provides default config.
    */
   function testModuleInstallation() {
     $default_config = 'config_test.system';
@@ -38,30 +38,132 @@ function testModuleInstallation() {
 
     // Verify that default module config does not exist before installation yet.
     $config = config($default_config);
-    $this->assertIdentical($config->isNew(), TRUE);
+    $this->assertIdentical($config->isNew(), TRUE, format_string(
+      '%config config is new before import.',
+      array(
+        '%config' => $default_config,
+      )
+    ));
     $config = config($default_configuration_entity);
-    $this->assertIdentical($config->isNew(), TRUE);
+    $this->assertIdentical($config->isNew(), TRUE, format_string(
+      '%config config is new before import.',
+      array(
+        '%config' => $default_configuration_entity,
+      )
+    ));
 
     // Install the test module.
-    $this->enableModules(array('config_test'));
+    module_enable(array('config_test'));
 
     // Verify that default module config exists.
     $config = config($default_config);
-    $this->assertIdentical($config->isNew(), FALSE);
+    $this->assertIdentical($config->isNew(), FALSE, format_string(
+      '%config config exists after import.',
+      array(
+        '%config' => $default_config,
+      )
+    ));
     $config = config($default_configuration_entity);
-    $this->assertIdentical($config->isNew(), FALSE);
-
-    // Verify that configuration import callback was invoked for the dynamic
-    // configuration entity.
-    $this->assertTrue($GLOBALS['hook_config_import']);
-
-    // Verify that config_test API hooks were invoked for the dynamic default
-    // configuration entity.
-    $this->assertFalse(isset($GLOBALS['hook_config_test']['load']));
-    $this->assertTrue(isset($GLOBALS['hook_config_test']['presave']));
-    $this->assertTrue(isset($GLOBALS['hook_config_test']['insert']));
-    $this->assertFalse(isset($GLOBALS['hook_config_test']['update']));
-    $this->assertFalse(isset($GLOBALS['hook_config_test']['predelete']));
-    $this->assertFalse(isset($GLOBALS['hook_config_test']['delete']));
+    $this->assertIdentical($config->isNew(), FALSE, format_string(
+      '%config config exists after import.',
+      array(
+        '%config' => $default_configuration_entity,
+      )
+    ));
+
+    // Confirm that hook_config_import_create() was invoked for the provided
+    // default config entity.
+    $import_hooks = array(
+      'create' => TRUE,
+      'change' => FALSE,
+      'delete' => FALSE,
+    );
+    // $GLOBALS['hook_config_import'] is set in config_test.module.
+    $this->assertConfigHooks($GLOBALS['hook_config_import'], $import_hooks);
+
+    // Confirm that the insert and presave config_test API hooks were invoked
+    // for the provided default config entity.
+    $api_hooks = array(
+      'load' => FALSE,
+      'presave' => TRUE,
+      'insert' => TRUE,
+      'update' => FALSE,
+      'predelete' => FALSE,
+      'delete' => FALSE,
+    );
+    // $GLOBALS['hook_config_test'] is set in config_test.hooks.inc.
+    $this->assertConfigHooks($GLOBALS['hook_config_test'], $api_hooks);
+
+    // Disable the module and verify that the config is not removed.
+    module_disable(array('config_test'));
+    $config = config($default_config);
+    $this->assertIdentical($config->isNew(), FALSE, format_string(
+      '%config config still exists after disabling the module.',
+      array(
+        '%config' => $default_config,
+      )
+    ));
+    $config = config($default_configuration_entity);
+    $this->assertIdentical($config->isNew(), FALSE, format_string(
+      '%config config still exists after disabling the module.',
+      array(
+        '%config' => $default_configuration_entity,
+      )
+    ));
+
+    // Uninstall the module and verify that the config was removed.
+    module_uninstall(array('config_test'));
+    $config = config($default_config);
+    $this->assertIdentical($config->isNew(), TRUE, format_string(
+      '%config no longer exists after disabling the module.',
+      array(
+        '%config' => $default_config,
+      )
+    ));
+    $config = config($default_configuration_entity);
+    $this->assertIdentical($config->isNew(), TRUE, format_string(
+      '%config config no longer exists after disabling the module.',
+      array(
+        '%config' => $default_configuration_entity,
+      )
+    ));
   }
+
+  /**
+   * Asserts that a set of config hooks were invoked or not from passed data.
+   *
+   * @param array $actual
+   *   An array of the hooks that were invoked (set in globals), with the key
+   *   indicating the type of hook and the value as the hook implementation
+   *   if it was invoked.
+   * @param array $expected
+   *   An array indicating whether each hook was expected to be invoked or not,
+   *   with the key indicating the type of hook and the value a Boolean
+   *   indicating whether the hook should be invoked.
+   *
+   * @see config_test.module
+   * @see config_test.hooks.inc
+   */
+  function assertConfigHooks(array $actual, array $expected) {
+    foreach ($expected as $hook => $value) {
+      if (!empty($actual[$hook])) {
+        $function = $actual[$hook];
+      }
+      else {
+        $function = $hook . ' hook';
+      }
+      $this->assertTrue(
+        // The hook flag should evaluate to empty if it was not invoked.
+        ($value != empty($actual[$hook])),
+        format_string(
+          '%hook was @invoked when enabling config_test.module.',
+          array(
+            '%hook' => $function,
+            '@invoked' => $value ? 'invoked' : 'not invoked',
+          )
+        )
+      );
+    }
+  }
+
 }
diff --git a/core/modules/config/tests/config_test/config_test.module b/core/modules/config/tests/config_test/config_test.module
index 96d4aa0..9d465db 100644
--- a/core/modules/config/tests/config_test/config_test.module
+++ b/core/modules/config/tests/config_test/config_test.module
@@ -17,7 +17,7 @@ function config_test_config_import_create($name, $new_config, $old_config) {
     return FALSE;
   }
   // Set a global value we can check in test code.
-  $GLOBALS['hook_config_import'] = __FUNCTION__;
+  $GLOBALS['hook_config_import']['create'] = __FUNCTION__;
 
   $config_test = entity_create('config_test', $new_config->get());
   $config_test->save();
@@ -32,7 +32,7 @@ function config_test_config_import_change($name, $new_config, $old_config) {
     return FALSE;
   }
   // Set a global value we can check in test code.
-  $GLOBALS['hook_config_import'] = __FUNCTION__;
+  $GLOBALS['hook_config_import']['change'] = __FUNCTION__;
 
   // @todo Make this less ugly.
   list(, , $id) = explode('.', $name);
@@ -62,7 +62,7 @@ function config_test_config_import_delete($name, $new_config, $old_config) {
     return FALSE;
   }
   // Set a global value we can check in test code.
-  $GLOBALS['hook_config_import'] = __FUNCTION__;
+  $GLOBALS['hook_config_import']['delete'] = __FUNCTION__;
 
   // @todo Make this less ugly.
   list(, , $id) = explode('.', $name);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
index f23204b..41d0d4c 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Module/ModuleTestBase.php
@@ -105,9 +105,11 @@ function assertModuleConfig($module) {
     $this->assertTrue($names);
 
     // Look up each default configuration object name in the active
-    // configuration, and if it exists, remove it from the stack.
+    // configuration. If it exists or belongs to another module's namespace,
+    // remove it from the stack.
     foreach ($names as $key => $name) {
-      if (config($name)->get()) {
+      // @todo Replace the module check with a proper config method.
+      if ((strtok($name, '.') != $module) || config($name)->get()) {
         unset($names[$key]);
       }
     }
