diff --git a/core/includes/common.inc b/core/includes/common.inc
index a608ba4..cbf03f9 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -7,6 +7,7 @@
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Database\Database;
+use Drupal\Core\SystemListingInfo;
 use Drupal\Core\Template\Attribute;
 
 /**
@@ -5159,81 +5160,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,
-      // Do not recurse into ./lib directories; they cannot contain extensions.
-      // We also skip templates, css, and js directories.
-      // @todo Find a way to skip ./config directories (but not modules/config).
-      'nomask' => '/^(CVS|lib|templates|css|js)$/',
-    ));
-
-    // 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 = DRUPAL_ROOT . '/' . 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/includes/install.core.inc b/core/includes/install.core.inc
index 2b117bc..d1c0bac 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1504,7 +1504,7 @@ function install_bootstrap_full(&$install_state) {
   module_list_reset();
 
   // Instantiate the kernel.
-  $kernel = new DrupalKernel('prod', FALSE, NULL);
+  $kernel = new DrupalKernel('prod', FALSE, drupal_classloader());
   $kernel->boot();
   drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 }
diff --git a/core/includes/module.inc b/core/includes/module.inc
index 0c1a30b..a711cf1 100644
--- a/core/includes/module.inc
+++ b/core/includes/module.inc
@@ -507,7 +507,7 @@ function module_enable($module_list, $enable_dependencies = TRUE) {
       // @todo The if statement is here because install_begin_request() creates
       //   a container without a kernel. It probably shouldn't.
       if ($kernel = drupal_container()->get('kernel', ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
-        $kernel->updateModules(module_list());
+        $kernel->updateModules(module_list(), array($module => drupal_get_path('module', $module)));
       }
       // Refresh the schema to include it.
       drupal_get_schema(NULL, TRUE);
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 892571f..46d8357 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -8,6 +8,8 @@
 namespace Drupal\Core;
 
 use Drupal\Core\Cache\CacheBackendInterface;
+use Symfony\Component\ClassLoader\UniversalClassLoader;
+use Drupal\Core\Config\FileStorage;
 use Drupal\Core\CoreBundle;
 use Drupal\Component\PhpStorage\PhpStorageInterface;
 use Symfony\Component\HttpKernel\Kernel;
@@ -36,6 +38,13 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
   protected $moduleList;
 
   /**
+   * An array of module data as returned by system_rebuild_module_data().
+   *
+   * @var array
+   */
+  protected $moduleData;
+
+  /**
    * Cache object for getting or setting the compiled container's class name.
    *
    * @var \Drupal\Core\Cache\CacheBackendInterface
@@ -50,6 +59,18 @@ class DrupalKernel extends Kernel implements DrupalKernelInterface {
   protected $storage;
 
   /**
+   * The classloader object.
+   *
+   * @var \Symfony\Component\ClassLoader\UniversalClassLoader
+   */
+  protected $classLoader;
+
+  /**
+   * @var array
+   */
+  protected $bundleClasses;
+
+  /**
    * Constructs a DrupalKernel object.
    *
    * @param string $environment
@@ -62,24 +83,19 @@ 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 \Symfony\Component\ClassLoader\UniversalClassLoader $class_loader
+   *   (optional) A classloader object. Required when $storage is set and
+   *   also when $module_list is not set.
+   * @param \Drupal\Component\PhpStorage\PhpStorageInterface $storage
+   *   (Optional) An object handling PHP load and save.
    */
-  public function __construct($environment, $debug, array $module_list = NULL, CacheBackendInterface $compilation_index_cache = NULL) {
+  public function __construct($environment, $debug, UniversalClassLoader $class_loader = NULL, PhpStorageInterface $storage = NULL, array $module_list = NULL, array $module_data = NULL) {
     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->storage = $storage;
+    $this->moduleList = $module_list ?: array();
+    $this->classLoader = $class_loader;
+    $this->moduleList = $module_list;
+    $this->moduleData = $module_data;
   }
 
   /**
@@ -93,18 +109,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 || !$this->moduleData) {
+      $storage = new FileStorage(config_get_config_directory());
+    }
+    if (!$this->moduleList) {
+      $module_list = $storage->read('system.module');
+      $module_list = $module_list['enabled'];
+      $this->moduleList = $module_list;
+    }
+    if (!$this->moduleData) {
+      // 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');
+      $profiles = array_keys(array_intersect_key($this->moduleList, $all_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.
+      if (($parent_profile_config = $storage->read('simpletest.settings')) && isset($parent_profile_config['parent_profile']) && $parent_profile_config['parent_profile'] != $profiles[0] ) {
+        // In case both profile directories contain the same extension, the
+        //  actual profile always has precedence.
+        array_unshift($profiles, $parent_profile_config['parent_profile']);
+      }
+      $modules_scanner = new SystemListing($profiles);
+      $this->moduleData = $all_profiles + $modules_scanner ->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.module$/', 'modules');
+    }
 
-    foreach ($this->moduleList as $module) {
+    $namespaces = $this->classLoader->getNamespaces();
+    foreach ($this->moduleList as $module => $weight) {
+      $namespace = 'Drupal\\' . $module;
+      if (!isset($namespaces[$namespace]) && isset($this->moduleData[$module])) {
+        $this->classLoader->registerNamespace($namespace, dirname(DRUPAL_ROOT . '/' . $this->moduleData[$module]->uri) . '/lib');
+      }
+    }
+
+    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;
@@ -113,8 +174,11 @@ public function registerBundles() {
   /**
    * Implements Drupal\Core\DrupalKernelInterface::updateModules().
    */
-  public function updateModules($module_list) {
+  public function updateModules(array $module_list, array $module_paths) {
     $this->moduleList = $module_list;
+    foreach ($module_paths as $module => $path) {
+      $this->moduleData[$module] = (object) array('uri' => $path);
+    }
     // If we haven't yet booted, we don't need to do anything: the new module
     // list will take effect when boot() is called. If we have already booted,
     // then reboot in order to refresh the bundle list and container.
@@ -126,33 +190,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->storage && !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->storage && !$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 +254,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 +300,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 +317,4 @@ protected function dumpDrupalContainer(ContainerBuilder $container, $baseClass)
    */
   public function registerContainerConfiguration(LoaderInterface $loader) {
   }
-
 }
diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php
index 828f3ba..36ad32c 100644
--- a/core/lib/Drupal/Core/DrupalKernelInterface.php
+++ b/core/lib/Drupal/Core/DrupalKernelInterface.php
@@ -25,6 +25,8 @@
    *
    * @param array $module_list
    *   The new list of modules.
+   * @param array
+   *   List of module paths, keyed by module name.
    */
-  public function updateModules($module_list);
+  public function updateModules(array $module_list, array $module_path);
 }
diff --git a/core/lib/Drupal/Core/SystemListing.php b/core/lib/Drupal/Core/SystemListing.php
new file mode 100644
index 0000000..caf8c7c
--- /dev/null
+++ b/core/lib/Drupal/Core/SystemListing.php
@@ -0,0 +1,169 @@
+<?php
+
+namespace Drupal\Core;
+
+class SystemListing {
+
+  /**
+   * Construct this listing object.
+   *
+   * @param array $profiles
+   *   A list of profiles to search their directories for in addition to the
+   *   default directories.
+   */
+  function __construct($profiles = array()) {
+    $this->profiles = $profiles;
+  }
+
+/**
+ * Returns information about system object files (modules, themes, etc.).
+ *
+ * This function is used to find all or some system object files (module files,
+ * theme files, etc.) that exist on the site. It searches in several locations,
+ * depending on what type of object you are looking for. For instance, if you
+ * are looking for modules and call:
+ * @code
+ * $scanner = new SystemListing();
+ * $all_profiles = $profiles_scanner ->scan('/^' . DRUPAL_PHP_FUNCTION_PATTERN . '\.profile$/', 'profiles');
+ * @endcode
+ * this function will search:
+ * - the core modules directory; i.e., /core/modules
+ * - the profiles directories as defined by the profiles() method.
+ * - the site-wide modules directory; i.e., /modules
+ * - the all-sites directory; i.e., /sites/all/modules
+ * - the site-specific directory; i.e., /sites/example.com/modules
+ * in that order, and return information about all of the files ending in
+ * .module in those directories.
+ *
+ * The information is returned in an associative array, which can be keyed on
+ * the file name ($key = 'filename'), the file name without the extension ($key
+ * = 'name'), or the full file stream URI ($key = 'uri'). If you use a key of
+ * 'filename' or 'name', files found later in the search will take precedence
+ * over files found earlier (unless they belong to a module or theme not
+ * compatible with Drupal core); if you choose a key of 'uri', you will get all
+ * files found.
+ *
+ * @param string $mask
+ *   The preg_match() regular expression for the files to find. The expression
+ *   must be anchored and use DRUPAL_PHP_FUNCTION_PATTERN for the file name part
+ *   before the extension, since the results could contain matches that do not
+ *   present valid Drupal extensions otherwise.
+ * @param string $directory
+ *   The subdirectory name in which the files are found. For example,
+ *   'modules' will search all 'modules' directories and their sub-directories
+ *   as explained above.
+ * @param string $key
+ *   (optional) The key to be used for the associative array returned. Possible
+ *   values are:
+ *   - 'uri' for the file's URI.
+ *   - 'filename' for the basename of the file.
+ *   - 'name' for the name of the file without the extension.
+ *   For 'name' and 'filename' only the highest-precedence file is returned.
+ *   Defaults to 'name'.
+ *
+ * @return array
+ *   An associative array of file objects, keyed on the chosen key. Each element
+ *   in the array is an object containing file information, with properties:
+ *   - 'uri': Full URI of the file.
+ *   - 'filename': File name.
+ *   - 'name': Name of file without the extension.
+ */
+  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";
+    }
+    // @todo Find a way to skip ./config directories (but not modules/config).
+    $nomask = '/^(CVS|lib|templates|css|js)$/';
+    $files = array();
+    // Get current list of items.
+    foreach ($searchdir as $dir) {
+      $files = array_merge($files, $this->process($files, $this->scanDirectory($dir, $key, $mask, $nomask)));
+    }
+    return $files;
+  }
+
+  /**
+   * List the profiles for this directory.
+   *
+   * This version only returns those passed to the constructor.
+   *
+   * @param string $directory
+   * @return array
+   */
+  protected function profiles($directory) {
+    return $this->profiles;
+  }
+
+  /**
+   * Process the files to add before adding them.
+   *
+   * @param array $files
+   *   Every file found so far.
+   * @param array $files_to_add
+   *   The files found in a single directory.
+   * @return array
+   */
+  protected function process(array $files, array $files_to_add) {
+    return $files_to_add;
+  }
+
+  /**
+   * Abbreviated version of file_scan_directory().
+   *
+   * @param $dir
+   * @param $key
+   * @param $mask
+   * @param $nomask
+   * @return array
+   */
+  protected function scanDirectory($dir, $key, $mask, $nomask) {
+    $files = array();
+    if (is_dir($dir)) {
+      // Avoid warnings when opendir does not have the permissions to open a
+      // directory.
+      if ($handle = @opendir($dir)) {
+        while (FALSE !== ($filename = readdir($handle))) {
+          // Skip this file if it matches the nomask or starts with a dot.
+          if ($filename[0] != '.' && !preg_match($nomask, $filename)) {
+            $uri = "$dir/$filename";
+            if (is_dir($uri)) {
+              // Give priority to files in this folder by merging them in after
+              // any subdirectory files.
+              $files = array_merge($this->scanDirectory($uri, $key, $mask, $nomask), $files);
+            }
+            elseif (preg_match($mask, $filename)) {
+              // Always use this match over anything already set in $files with
+              // the same $options['key'].
+              $file = new \stdClass();
+              $file->uri = $uri;
+              $file->filename = $filename;
+              $file->name = pathinfo($filename, PATHINFO_FILENAME);
+              $files[$file->$key] = $file;
+            }
+          }
+        }
+        closedir($handle);
+      }
+    }
+    return $files;
+  }
+}
diff --git a/core/lib/Drupal/Core/SystemListingInfo.php b/core/lib/Drupal/Core/SystemListingInfo.php
new file mode 100644
index 0000000..d03c7ae
--- /dev/null
+++ b/core/lib/Drupal/Core/SystemListingInfo.php
@@ -0,0 +1,55 @@
+<?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(array $files, array $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..27333e8 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -912,7 +912,7 @@ protected function rebuildContainer() {
     // container in drupal_container(). Drupal\simpletest\TestBase::tearDown()
     // restores the original container.
     // @see Drupal\Core\DrupalKernel::initializeContainer()
-    $this->kernel = new DrupalKernel('testing', FALSE, NULL);
+    $this->kernel = new DrupalKernel('testing', FALSE, drupal_classloader());
     // Booting the kernel is necessary to initialize the new DIC. While
     // normally the kernel gets booted on demand in
     // Symfony\Component\HttpKernel\handle(), this kernel needs manual booting
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..990be66 100644
--- a/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/DrupalKernel/DrupalKernelTest.php
@@ -7,8 +7,9 @@
 
 namespace Drupal\system\Tests\DrupalKernel;
 
-use Drupal\Core\Cache\MemoryBackend;
 use Drupal\Core\DrupalKernel;
+use Drupal\Component\PhpStorage\MTimeProtectedFastFileStorage;
+use Drupal\Component\PhpStorage\FileReadOnlyStorage;
 use Drupal\simpletest\UnitTestBase;
 use ReflectionClass;
 
@@ -34,21 +35,27 @@ function testCompileDIC() {
     // We need to be able to restore it to the correct one at the end of this
     // test.
     $original_container = drupal_container();
-    global $conf;
-    $conf['php_storage']['service_container'] = array(
-      'class' => 'Drupal\Component\PhpStorage\MTimeProtectedFileStorage',
+    $classloader = drupal_classloader();
+    $configuration = array(
+      'bin' => 'service_container',
+      'directory' => DRUPAL_ROOT . '/' . variable_get('file_public_path', conf_path() . '/files') . '/php',
       'secret' => $GLOBALS['drupal_hash_salt'],
     );
-    $cache = new MemoryBackend('test');
+    // @TOOD: write a memory based storage backend for testing.
+    $php_storage = new MTimeProtectedFastFileStorage($configuration);
     $module_enabled = array(
       'system' => 'system',
       'user' => 'user',
     );
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $module_paths = array(
+      'system' => 'core/modules/system/system.module',
+      'user' => 'core/modules/user/user.module',
+    );
+    $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage, $module_enabled, $module_paths);
     $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, $classloader, $php_storage, $module_enabled, $module_paths);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
@@ -62,11 +69,8 @@ function testCompileDIC() {
 
     // Now use the read-only storage implementation, simulating a "production"
     // environment.
-    drupal_static_reset('drupal_php_storage');
-    $conf['php_storage']['service_container'] = array(
-      'class' => 'Drupal\Component\PhpStorage\FileReadOnlyStorage',
-    );
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $php_storage = new FileReadOnlyStorage($configuration);
+    $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage, $module_enabled, $module_paths);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
@@ -86,17 +90,13 @@ function testCompileDIC() {
 
     // Add another module so that we can test that the new module's bundle is
     // registered to the new container.
-    $module_enabled = array(
-      'system' => 'system',
-      'user' => 'user',
-      'bundle_test' => 'bundle_test',
-    );
-    $cache->flush();
-    $kernel = new DrupalKernel('testing', FALSE, $module_enabled, $cache);
+    $module_enabled['bundle_test'] = 'bundle_test';
+    $module_paths['bundle_test'] = 'core/modules/system/tests/modules/bundle_test/bundle_test.module';
+    $kernel = new DrupalKernel('testing', FALSE, $classloader, $php_storage, $module_enabled, $module_paths);
     $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, $classloader, $php_storage, $module_enabled, $module_paths);
     $kernel->boot();
     $container = $kernel->getContainer();
     $refClass = new ReflectionClass($container);
diff --git a/core/modules/system/tests/http.php b/core/modules/system/tests/http.php
index 297e3c7..8594648 100644
--- a/core/modules/system/tests/http.php
+++ b/core/modules/system/tests/http.php
@@ -36,6 +36,6 @@
 
 drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
 
-$kernel = new DrupalKernel('prod', FALSE);
+$kernel = new DrupalKernel('prod', FALSE, drupal_classloader());
 $response = $kernel->handle($request)->prepare($request)->send();
 $kernel->terminate($request, $response);
diff --git a/core/modules/system/tests/https.php b/core/modules/system/tests/https.php
index 8e09a5d..54d8878 100644
--- a/core/modules/system/tests/https.php
+++ b/core/modules/system/tests/https.php
@@ -35,6 +35,6 @@
 
 drupal_bootstrap(DRUPAL_BOOTSTRAP_CODE);
 
-$kernel = new DrupalKernel('prod', FALSE);
+$kernel = new DrupalKernel('prod', FALSE, drupal_classloader());
 $response = $kernel->handle($request)->prepare($request)->send();
 $kernel->terminate($request, $response);
diff --git a/index.php b/index.php
index a6eb61e..4d56290 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, drupal_classloader(), drupal_php_storage('service_container'));
 
 // Create a request object from the HTTPFoundation.
 $request = Request::createFromGlobals();
