diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index eac2f97..e81a55b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2547,6 +2547,7 @@ function drupal_valid_test_ua($new_prefix = NULL) {
     // and the HMAC must match.
     if ($time_diff >= 0 && $time_diff <= 5 && $hmac == drupal_hmac_base64($check_string, $key)) {
       $test_prefix = $prefix;
+      $GLOBALS['drupal_test_info']['original_config_directory_active'] = $GLOBALS['config_directories']['active'];
       return $test_prefix;
     }
   }
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 540f42b..4026136 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1,6 +1,7 @@
 <?php
 
 use Symfony\Component\DependencyInjection\Container;
+use Drupal\Core\SystemListingInfo;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Component\Utility\NestedArray;
@@ -253,7 +254,6 @@ function drupal_get_profile() {
   return $profile;
 }
 
-
 /**
  * Sets the breadcrumb trail for the current page.
  *
@@ -5164,74 +5164,8 @@ function drupal_cron_cleanup() {
  *   - 'name': Name of file without the extension.
  */
 function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1) {
-  $config = conf_path();
-  $files = array();
-
-  // Search for the directory in core.
-  $searchdir = array('core/' . $directory);
-
-  // The 'core/profiles' directory contains pristine collections of modules and
-  // themes as provided by a distribution. It is pristine in the same way that
-  // the 'core/modules' directory is pristine for core; users should avoid
-  // any modification by using the top-level or sites/<domain> directories.
-  $profile = drupal_get_profile();
-  // For SimpleTest to be able to test modules packaged together with a
-  // distribution we need to include the profile of the parent site (in which
-  // test runs are triggered).
-  if (drupal_valid_test_ua()) {
-    $testing_profile = config('simpletest.settings')->get('parent_profile');
-    if ($testing_profile && $testing_profile != $profile) {
-      $searchdir[] = drupal_get_path('profile', $testing_profile) . '/' . $directory;
-    }
-  }
-  // In case both profile directories contain the same extension, the actual
-  // profile always has precedence.
-  $searchdir[] = drupal_get_path('profile', $profile) . '/' . $directory;
-
-  // Always search for contributed and custom extensions in top-level
-  // directories as well as sites/all/* directories. If the same extension is
-  // located in both directories, then the latter wins for legacy/historical
-  // reasons.
-  $searchdir[] = $directory;
-  $searchdir[] = 'sites/all/' . $directory;
-
-  if (file_exists("$config/$directory")) {
-    $searchdir[] = "$config/$directory";
-  }
-
-  // Get current list of items.
-  if (!function_exists('file_scan_directory')) {
-    require_once DRUPAL_ROOT . '/core/includes/file.inc';
-  }
-  foreach ($searchdir as $dir) {
-    $files_to_add = file_scan_directory($dir, $mask, array('key' => $key, 'min_depth' => $min_depth));
-
-    // Duplicate files found in later search directories take precedence over
-    // earlier ones, so we want them to overwrite keys in our resulting
-    // $files array.
-    // The exception to this is if the later file is from a module or theme not
-    // compatible with Drupal core. This may occur during upgrades of Drupal
-    // core when new modules exist in core while older contrib modules with the
-    // same name exist in a directory such as /modules.
-    foreach (array_intersect_key($files_to_add, $files) as $file_key => $file) {
-      // If it has no info file, then we just behave liberally and accept the
-      // new resource on the list for merging.
-      if (file_exists($info_file = dirname($file->uri) . '/' . $file->name . '.info')) {
-        // Get the .info file for the module or theme this file belongs to.
-        $info = drupal_parse_info_file($info_file);
-
-        // If the module or theme is incompatible with Drupal core, remove it
-        // from the array for the current search directory, so it is not
-        // overwritten when merged with the $files array.
-        if (isset($info['core']) && $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
-          unset($files_to_add[$file_key]);
-        }
-      }
-    }
-    $files = array_merge($files, $files_to_add);
-  }
-
-  return $files;
+  $listing = new SystemListingInfo();
+  return $listing->scan($mask, $directory, $key, $min_depth);
 }
 
 /**
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 892571f..529da55 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core;
 
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\FileStorage;
 use Drupal\Core\CoreBundle;
 use Drupal\Component\PhpStorage\PhpStorageInterface;
 use Symfony\Component\HttpKernel\Kernel;
@@ -50,6 +51,18 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
   protected $storage;
 
   /**
+   * TRUE to attempt to use a dumped and stored container.
+   *
+   * @var bool
+   */
+  protected $dump;
+
+  /**
+   * @var array
+   */
+  protected $bundleClasses;
+
+  /**
    * Constructs a DrupalKernel object.
    *
    * @param string $environment
@@ -62,24 +75,14 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
    *   this value currently. Pass TRUE.
    * @param array $module_list
    *   (optional) The array of enabled modules as returned by module_list().
-   * @param Drupal\Core\Cache\CacheBackendInterface $compilation_index_cache
-   *   (optional) If wanting to dump a compiled container to disk or use a
-   *   previously compiled container, the cache object for the bin that stores
-   *   the class name of the compiled container.
+   * @param bool $dump
+   *   (optional) TRUE to attempt to use a dumped and stored container.
    */
-  public function __construct($environment, $debug, array $module_list = NULL, CacheBackendInterface $compilation_index_cache = NULL) {
+  public function __construct($environment, $debug, array $module_list = NULL, $dump = FALSE) {
     parent::__construct($environment, $debug);
-    $this->compilationIndexCache = $compilation_index_cache;
     $this->storage = drupal_php_storage('service_container');
-    if (isset($module_list)) {
-      $this->moduleList = $module_list;
-    }
-    else {
-      // @todo This is a temporary measure which will no longer be necessary
-      //   once we have an ExtensionHandler for managing this list. See
-      //   http://drupal.org/node/1331486.
-      $this->moduleList = module_list();
-    }
+    $this->moduleList = $module_list ?: array();
+    $this->dump = $dump;
   }
 
   /**
@@ -93,18 +96,63 @@ public function init() {
   }
 
   /**
+   * Overrides Kernel::boot().
+   */
+  public function boot() {
+    if ($this->booted) {
+      return;
+    }
+    // init container
+    $this->initializeContainer();
+    $this->booted = TRUE;
+  }
+
+  /**
    * Returns an array of available bundles.
    */
   public function registerBundles() {
     $bundles = array(
       new CoreBundle(),
     );
+    if (!$this->moduleList) {
+      $storage = new FileStorage(config_get_config_directory());
+      $module_list = $storage->read('system.module');
+      $module_list = $module_list['enabled'];
+      $this->moduleList = $module_list;
+      // Find filenames and prime the classloader. First, we need to add
+      // profiles because modules migh tbe inside those.
+      $profiles_scanner = new SystemListing();
+      $all_profiles = $profiles_scanner ->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+      // If a module is within a profile directory but specifies another
+      // profile for testing, it needs to be found it in the parent profile.
+      // config_get_config_directory() fires drupal_valid_test_ua() so this
+      // global is populated.
+      if (!empty($GLOBALS['drupal_test_info']['original_config_directory_active'])) {
+        $config_directory = $GLOBALS['drupal_test_info']['original_config_directory_active'];
+        if (empty($config_directory['absolute'])) {
+          $path = conf_path() . '/files/' . $config_directory['path'];
+        }
+        else {
+          $path = $config_directory['path'];
+        }
+        $parent_storage = new FileStorage($path);
+        $parent_modules = $parent_storage->read('system.module');
+        $module_list += $parent_modules['enabled'];
+      }
+      $modules_scanner = new SystemListing(array_keys(array_intersect_key($module_list, $all_profiles)));
+      $module_data = $all_profiles + $modules_scanner ->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+      foreach ($this->moduleList as $module => $weight) {
+        drupal_get_filename('module', $module, $module_data[$module]->uri);
+        drupal_classloader_register($module, dirname($module_data[$module]->uri));
+      }
+    }
 
-    foreach ($this->moduleList as $module) {
+    foreach ($this->moduleList as $module => $data) {
       $camelized = ContainerBuilder::camelize($module);
       $class = "Drupal\\{$module}\\{$camelized}Bundle";
       if (class_exists($class)) {
         $bundles[] = new $class();
+        $this->bundleClasses[] = $class;
       }
     }
     return $bundles;
@@ -126,33 +174,49 @@ public function updateModules($module_list) {
   }
 
   /**
+   * Returns the classname based on environment, debug and testing prefix.
+   *
+   * @return string
+   *   The class name.
+   */
+  protected function getClassName() {
+    $parts = array('service_container', $this->environment, $this->debug);
+    if (!empty($GLOBALS['drupal_test_info']['test_run_id'])) {
+      $parts[] = $GLOBALS['drupal_test_info']['test_run_id'];
+    }
+    elseif ($prefix = drupal_valid_test_ua()) {
+      $parts[] = $prefix;
+    }
+    return implode('_', $parts);
+  }
+
+  /**
    * Initializes the service container.
    */
   protected function initializeContainer() {
     $this->container = NULL;
-    if ($this->compilationIndexCache) {
-      // The name of the compiled container class is generated from the hash of
-      // its contents and cached. This enables multiple compiled containers
-      // (for example, for different states of which modules are enabled) to
-      // exist simultaneously on disk and in memory.
-      if ($cache = $this->compilationIndexCache->get(implode(':', array('service_container', $this->environment, $this->debug)))) {
-        $class = $cache->data;
-        $cache_file = $class . '.php';
-
-        // First, try to load.
-        if (!class_exists($class, FALSE)) {
-          $this->storage->load($cache_file);
-        }
-        // If the load succeeded or the class already existed, use it.
-        if (class_exists($class, FALSE)) {
-          $fully_qualified_class_name = '\\' . $class;
-          $this->container = new $fully_qualified_class_name;
-        }
+    $class = $this->getClassName();
+    $cache_file = $class . '.php';
+
+    // First, try to load.
+    if ($this->dump && !class_exists($class, FALSE)) {
+      $this->storage->load($cache_file);
+    }
+    // If the load succeeded or the class already existed, use it.
+    if (class_exists($class, FALSE)) {
+      $fully_qualified_class_name = '\\' . $class;
+      $this->container = new $fully_qualified_class_name;
+    }
+
+    if (isset($this->container)) {
+      $module_list = array_keys($this->moduleList ?: $this->container->get('config.factory')->get('system.module')->load()->get('enabled'));
+      if ($module_list !== $this->container->getParameter('container.modules')) {
+        unset($this->container);
       }
     }
     if (!isset($this->container)) {
       $this->container = $this->buildContainer();
-      if ($this->compilationIndexCache && !$this->dumpDrupalContainer($this->container, $this->getContainerBaseClass())) {
+      if ($this->dump && !$this->dumpDrupalContainer($this->container, $this->getContainerBaseClass())) {
         // We want to log this as an error but we cannot call watchdog() until
         // the container has been fully built and set in drupal_container().
         $error = 'Container cannot be written to disk';
@@ -174,7 +238,11 @@ protected function initializeContainer() {
    * @return ContainerBuilder The compiled service container
    */
   protected function buildContainer() {
+    // init bundles
+    $this->initializeBundles();
     $container = $this->getContainerBuilder();
+    $container->setParameter('container.bundles', $this->bundleClasses);
+    $container->setParameter('container.modules', array_keys($this->moduleList));
 
     // Merge in the minimal bootstrap container.
     if ($bootstrap_container = drupal_container()) {
@@ -216,11 +284,8 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass)
     }
     // Cache the container.
     $dumper = new PhpDumper($container);
-    $content = $dumper->dump(array('class' => 'DrupalServiceContainerStub', 'base_class' => $baseClass));
-    $class = 'c' . hash('sha256', $content);
-    $content = str_replace('DrupalServiceContainerStub', $class, $content);
-    $this->compilationIndexCache->set(implode(':', array('service_container', $this->environment, $this->debug)), $class);
-
+    $class = $this->getClassName();
+    $content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass));
     return $this->storage->save($class . '.php', $content);
   }
 
@@ -236,5 +301,4 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass)
    */
   public function registerContainerConfiguration(LoaderInterface $loader) {
   }
-
 }
diff --git a/core/lib/Drupal/Core/SystemListing.php b/core/lib/Drupal/Core/SystemListing.php
new file mode 100644
index 0000000..de87456
--- /dev/null
+++ b/core/lib/Drupal/Core/SystemListing.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\Core;
+
+class SystemListing {
+
+  function __construct($profiles = array()) {
+    $this->profiles = $profiles;
+  }
+
+  function scan($mask, $directory, $key = 'name') {
+    if (!in_array($key, array('uri', 'filename', 'name'))) {
+      $key = 'uri';
+    }
+    $config = conf_path();
+    $files = array();
+
+    // Search for the directory in core.
+    $searchdir = array('core/' . $directory);
+    foreach ($this->profiles($directory) as $profile) {
+      $searchdir[] = $profile;
+    }
+
+    // Always search for contributed and custom extensions in top-level
+    // directories as well as sites/all/* directories. If the same extension is
+    // located in both directories, then the latter wins for legacy/historical
+    // reasons.
+    $searchdir[] = $directory;
+    $searchdir[] = 'sites/all/' . $directory;
+
+    if (file_exists("$config/$directory")) {
+      $searchdir[] = "$config/$directory";
+    }
+
+    // Get current list of items.
+    foreach ($searchdir as $dir) {
+      try {
+        $dir_iterator = new \RecursiveIteratorIterator(
+          new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS)
+        );
+      }
+      catch (\Exception $e) {
+        continue;
+      }
+      $files_to_add = array();
+      foreach ($dir_iterator as $file_object) {
+        $filename = $file_object->getFileName();
+        if (preg_match($mask, $filename)) {
+          $file = new \stdClass();
+          $file->uri = $file_object->getPathName();
+          $file->filename = $file->uri;
+          $file->name = pathinfo($filename, PATHINFO_FILENAME);
+          $files_to_add[$file->$key] = $file;
+        }
+      }
+      $files = array_merge($files, $this->process($files, $files_to_add));
+    }
+    return $files;
+  }
+
+  protected function profiles($directory) {
+    return $this->profiles;
+  }
+
+  protected function process($files, $files_to_add) {
+    return $files_to_add;
+  }
+}
+
diff --git a/core/lib/Drupal/Core/SystemListingInfo.php b/core/lib/Drupal/Core/SystemListingInfo.php
new file mode 100644
index 0000000..ac6dd74
--- /dev/null
+++ b/core/lib/Drupal/Core/SystemListingInfo.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\Core;
+
+class SystemListingInfo extends SystemListing {
+
+  protected function profiles($directory) {
+    $searchdir = array();
+    // The 'core/profiles' directory contains pristine collections of modules and
+    // themes as provided by a distribution. It is pristine in the same way that
+    // the 'core/modules' directory is pristine for core; users should avoid
+    // any modification by using the top-level or sites/<domain> directories.
+    $profile = drupal_get_profile();
+    // For SimpleTest to be able to test modules packaged together with a
+    // distribution we need to include the profile of the parent site (in which
+    // test runs are triggered).
+    if (drupal_valid_test_ua()) {
+      $testing_profile = config('simpletest.settings')->get('parent_profile');
+      if ($testing_profile && $testing_profile != $profile) {
+        $searchdir[] = drupal_get_path('profile', $testing_profile) . '/' . $directory;
+      }
+    }
+    // In case both profile directories contain the same extension, the actual
+    // profile always has precedence.
+    $searchdir[] = drupal_get_path('profile', $profile) . '/' . $directory;
+    return $searchdir;
+  }
+  protected function process($files, $files_to_add) {
+    // Duplicate files found in later search directories take precedence over
+    // earlier ones, so we want them to overwrite keys in our resulting
+    // $files array.
+    // The exception to this is if the later file is from a module or theme not
+    // compatible with Drupal core. This may occur during upgrades of Drupal
+    // core when new modules exist in core while older contrib modules with the
+    // same name exist in a directory such as /modules.
+    foreach (array_intersect_key($files_to_add, $files) as $file_key => $file) {
+      // If it has no info file, then we just behave liberally and accept the
+      // new resource on the list for merging.
+      if (file_exists($info_file = dirname($file->uri) . '/' . $file->name . '.info')) {
+        // Get the .info file for the module or theme this file belongs to.
+        $info = drupal_parse_info_file($info_file);
+
+        // If the module or theme is incompatible with Drupal core, remove it
+        // from the array for the current search directory, so it is not
+        // overwritten when merged with the $files array.
+        if (isset($info['core']) && $info['core'] != DRUPAL_CORE_COMPATIBILITY) {
+          unset($files_to_add[$file_key]);
+        }
+      }
+    }
+    return $files_to_add;
+  }
+
+}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index fdb819a..465538b 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -817,6 +817,7 @@ protected function prepareEnvironment() {
     $this->originalContainer = clone drupal_container();
     $this->originalLanguage = $language_interface;
     $this->originalConfigDirectories = $GLOBALS['config_directories'];
+    $GLOBALS['drupal_test_info']['original_config_directory_active'] = $GLOBALS['config_directories']['active'];
     $this->originalThemeKey = $GLOBALS['theme_key'];
     $this->originalTheme = $GLOBALS['theme'];
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php
index 41070c3..63c635d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\system\Tests\DrupalKernel;
 
-use Drupal\Core\Cache\MemoryBackend;
 use Drupal\Core\DrupalKernel;
 use Drupal\simpletest\UnitTestBase;
 use ReflectionClass;
@@ -39,16 +38,15 @@ function testCompileDIC() {
       'class' => 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage',
       'secret' => $GLOBALS['drupal_hash_salt'],
     );
-    $cache = new MemoryBackend('test');
     $module_enabled = array(
       'system' => 'system',
       'user' => 'user',
     );
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, TRUE);
     $kernel->boot();
     // Instantiate it a second time and we should get the compiled Container
     // class.
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, TRUE);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
@@ -66,7 +64,7 @@ function testCompileDIC() {
     $conf['php_storage']['service_container'] = array(
       'class' => 'Drupal\Component\PhpStorage\FileReadOnlyStorage',
     );
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, TRUE);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
@@ -91,12 +89,11 @@ function testCompileDIC() {
       'user' => 'user',
       'bundle_test' => 'bundle_test',
     );
-    $cache->flush();
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, TRUE);
     $kernel->boot();
     // Instantiate it a second time and we should still get a ContainerBuilder
     // class because we are using the read-only PHP storage.
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, TRUE);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
diff --git a/index.php b/index.php
index a6eb61e..1c7c4b8 100644
--- a/index.php
+++ b/index.php
@@ -28,7 +28,7 @@
 drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
 
 // @todo Figure out how best to handle the Kernel constructor parameters.
-$kernel = new DrupalKernel('prod', FALSE, NULL, cache('bootstrap'));
+$kernel = new DrupalKernel('prod', FALSE, NULL, TRUE);
 
 // Create a request object from the HTTPFoundation.
 $request = Request::createFromGlobals();
