diff --git a/core/includes/common.inc b/core/includes/common.inc
index d05ee0c..a70626e 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -2768,7 +2768,7 @@ function drupal_flush_all_caches() {
       $files[$name] = $extension;
     }
   }
-  \Drupal::service('kernel')->updateModules($module_handler->getModuleList(), $files);
+  \Drupal::service('kernel')->updateModules(\Drupal::config('core.extension')->get('module'), $files);
   // New container, new module handler.
   $module_handler = \Drupal::moduleHandler();
 
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 249944f..2db846a 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -16,7 +16,7 @@
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
 use Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass;
-use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterServicesForDestructionPass;
 use Drupal\Core\Plugin\PluginManagerPass;
@@ -60,7 +60,7 @@ public function register(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterStreamWrappersPass());
 
     // Add a compiler pass for registering event subscribers.
-    $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
+    $container->addCompilerPass(new RegisterEventListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
 
     $container->addCompilerPass(new RegisterAccessChecksPass());
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
similarity index 54%
rename from core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
rename to core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
index 33b2683..d9e8242 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterKernelListenersPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEventListenersPass.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass.
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass.
  */
 
 namespace Drupal\Core\DependencyInjection\Compiler;
@@ -10,7 +10,10 @@
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 
-class RegisterKernelListenersPass implements CompilerPassInterface {
+/**
+ * Registers listeners for all services tagged with 'event_subscriber'.
+ */
+class RegisterEventListenersPass implements CompilerPassInterface {
   public function process(ContainerBuilder $container) {
     if (!$container->hasDefinition('event_dispatcher')) {
       return;
@@ -19,8 +22,43 @@ public function process(ContainerBuilder $container) {
     $definition = $container->getDefinition('event_dispatcher');
 
     $event_subscriber_info = [];
-    foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {
 
+    $module_parameter = $container->hasParameter('container.modules') ? $container->getParameter('container.modules') : [];
+
+    // First collect all tagged services in order to sort them by module weight
+    // and class name.
+
+    $weights = [];
+    // First figure out all module weights.
+    $ids = array_keys($container->findTaggedServiceIds('event_subscriber'));
+    $id_class_map = [];
+    foreach ($ids as $id) {
+      $class = $container->getDefinition($id)->getClass();
+      $id_class_map[$id] = $class;
+
+      list($drupal, $provider, $rest) = explode('\\', $class, 3);
+
+      if ($drupal == 'Drupal' && isset($module_parameter[$provider]['weight'])) {
+        $weight = $module_parameter[$provider]['weight'];
+      }
+      else {
+        $weight = 0;
+      }
+      $weights[$id] = $weight;
+    }
+
+    // Sort the IDs first by module weight, than by full classname. Using the
+    // full classname takes into account the module name automatically.
+    usort($ids, function($a, $b) use ($weights, $id_class_map) {
+      if ($weights[$a] !== $weights[$b]) {
+        return $weights[$a] < $weights[$b] ? -1 : 1;
+      }
+      else {
+        return $id_class_map[$a] < $id_class_map[$b] ? -1 : 1;
+      }
+    });
+
+    foreach ($ids as $id) {
       // We must assume that the class value has been correctly filled, even if the service is created by a factory
       $class = $container->getDefinition($id)->getClass();
 
@@ -31,6 +69,7 @@ public function process(ContainerBuilder $container) {
       }
 
       // Get all subscribed events.
+      // @todo Implement sorting by module weight and class name.
       foreach ($class::getSubscribedEvents() as $event_name => $params) {
         if (is_string($params)) {
           $priority = 0;
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index 6495229..d7eba77 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -78,14 +78,16 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
    * Holds the list of enabled modules.
    *
    * @var array
-   *   An associative array whose keys are module names and whose values are
-   *   ignored.
+   *   An associative array whose keys are module names and whose values is the
+   *   module weight.
    */
   protected $moduleList;
 
   /**
    * List of available modules and installation profiles.
    *
+   * Its a list of extensions keyed by module name.
+   *
    * @var \Drupal\Core\Extension\Extension[]
    */
   protected $moduleData = array();
@@ -637,10 +639,7 @@ protected function moduleData($module) {
   }
 
   /**
-   * Implements Drupal\Core\DrupalKernelInterface::updateModules().
-   *
-   * @todo Remove obsolete $module_list parameter. Only $module_filenames is
-   *   needed.
+   * {@inheritdoc}
    */
   public function updateModules(array $module_list, array $module_filenames = array()) {
     $this->moduleList = $module_list;
@@ -1203,12 +1202,14 @@ protected function getConfigStorage() {
    */
   protected function getModulesParameter() {
     $extensions = array();
-    foreach ($this->moduleList as $name => $weight) {
+
+    foreach ($this->ensureModuleList() as $name => $weight) {
       if ($data = $this->moduleData($name)) {
         $extensions[$name] = array(
           'type' => $data->getType(),
           'pathname' => $data->getPathname(),
           'filename' => $data->getExtensionFilename(),
+          'weight' => $weight,
         );
       }
     }
@@ -1312,4 +1313,17 @@ public static function validateHostname(Request $request) {
     return TRUE;
   }
 
+  /**
+   * Determines the module list.
+   *
+   * @return array|bool
+   */
+  protected function ensureModuleList() {
+    if (isset($this->moduleList)) {
+      return $this->moduleList;
+    }
+    $extensions = $this->getConfigStorage()->read('core.extension');
+    return isset($extensions['module']) ? $extensions['module'] : [];
+  }
+
 }
diff --git a/core/lib/Drupal/Core/DrupalKernelInterface.php b/core/lib/Drupal/Core/DrupalKernelInterface.php
index e7c468f..1ec8fa1 100644
--- a/core/lib/Drupal/Core/DrupalKernelInterface.php
+++ b/core/lib/Drupal/Core/DrupalKernelInterface.php
@@ -87,7 +87,7 @@ public function getAppRoot();
    * list.
    *
    * @param array $module_list
-   *   The new list of modules.
+   *   The list of module weights, keyed by module name.
    * @param array $module_filenames
    *   List of module filenames, keyed by module name.
    */
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathRootsSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathRootsSubscriber.php
index 8d96767..d7d4b5c 100644
--- a/core/lib/Drupal/Core/EventSubscriber/PathRootsSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/PathRootsSubscriber.php
@@ -26,7 +26,7 @@ class PathRootsSubscriber implements EventSubscriberInterface {
    *
    * @var array
    */
-  protected $pathRoots;
+  protected $pathRoots = [];
 
   /**
    * The state key value store.
diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index c6f3921..5632afd 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -188,7 +188,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
         drupal_static_reset('system_rebuild_module_data');
 
         // Update the kernel to include it.
-        $this->updateKernel($module_filenames);
+        $this->updateKernel($extension_config->get('module'), $module_filenames);
 
         // Refresh the schema to include it.
         drupal_get_schema(NULL, TRUE);
@@ -403,7 +403,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
       \Drupal::service('router.builder_indicator')->setRebuildNeeded();
 
       // Update the kernel to exclude the uninstalled modules.
-      $this->updateKernel($module_filenames);
+      $this->updateKernel($extension_config->get('module'), $module_filenames);
 
       // Update the theme registry to remove the newly uninstalled module.
       drupal_theme_rebuild();
@@ -480,12 +480,12 @@ protected function removeCacheBins($module) {
    * @param string $module_filenames
    *   The list of installed modules.
    */
-  protected function updateKernel($module_filenames) {
+  protected function updateKernel($module_list, $module_filenames) {
     // This reboots the kernel to register the module's bundle and its services
     // in the service container. The $module_filenames argument is taken over as
     // %container.modules% parameter, which is passed to a fresh ModuleHandler
     // instance upon first retrieval.
-    $this->kernel->updateModules($module_filenames, $module_filenames);
+    $this->kernel->updateModules($module_list, $module_filenames);
     // After rebuilding the container we need to update the injected
     // dependencies.
     $container = $this->kernel->getContainer();
diff --git a/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php
new file mode 100644
index 0000000..a9ef0d4
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/DependencyInjection/Compiler/RegisterEventListenersPassTest.php
@@ -0,0 +1,202 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\DependencyInjection\Compiler\RegisterEventListenersPassTest.
+ */
+
+namespace Drupal\Tests\Core\DependencyInjection\Compiler {
+
+use Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @coversDefaultClass \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass
+ * @group DependencyInjection
+ */
+class RegisterEventListenersPassTest extends UnitTestCase {
+
+  /**
+   * The tested compiler pass.
+   *
+   * @var \Drupal\Core\DependencyInjection\Compiler\RegisterEventListenersPass
+   */
+  protected $pass;
+
+  protected function setUp() {
+    parent::setUp();
+
+    $this->pass = new RegisterEventListenersPass();
+  }
+
+  /**
+   * Tests process with a service with an invalid interface.
+   *
+   * @expectedException \InvalidArgumentException
+   */
+  public function testProcessWithWrongInterface() {
+    $builder = new ContainerBuilder();
+    $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\Tests\Core\DependencyInjection\Compiler\TestServiceWithoutInterface')
+      ->addTag('event_subscriber');
+    $this->pass->process($builder);
+  }
+
+  /**
+   * Tests process with a single subscriber.
+   */
+  public function testProcessWithSubscriber() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([[0 => ['service' => ['test_service', 'onExample']]]], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple listeners and priority.
+   */
+  public function testProcessWithSubscriberWithPriorities() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service', 'Drupal\register_event_listener_pass_test_module\TestService2')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      10 => [['service' => ['test_service', 'onExample2']]],
+      0 => [['service' => ['test_service', 'onExample1']]]
+    ], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple subscribers in different modules and same prio.
+   *
+   * We register the subscribers ascending in the module name.
+   */
+  public function testProcessWithMultipleSubscribersWithModuleWeightAndSamePriorities() {
+    // @FIXME Introduce the weight of the modules.
+
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+    $builder->setParameter('container.modules', [
+      'register_event_listener_pass_test_nodule' => [
+        'weight' => -10,
+      ],
+      'register_event_listener_pass_test_module' => [
+        'weight' => 0,
+      ],
+    ]);
+
+    $builder->register('test_service_0', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+    $builder->register('test_service_1', 'Drupal\register_event_listener_pass_test_nodule\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      0 => [
+        ['service' => ['test_service_1', 'onExample']],
+        ['service' => ['test_service_0', 'onExample']],
+      ],
+    ], $listeners['example']);
+  }
+
+  /**
+   * Tests process with multiple subscribers, same module and same priorities.
+   *
+   * The idea is that we sort the listeners by class name as well, so
+   * setup the later classname first in the container.
+   */
+  public function testProcessWithMultipleSubscribersSameModuleAndSamePriorities() {
+    $builder = new ContainerBuilder();
+    $event_dispatcher_definition = $builder->register('event_dispatcher', 'Symfony\Component\EventDispatcher\EventDispatcher');
+
+    $builder->register('test_service_0', 'Drupal\register_event_listener_pass_test_module\TestService2')
+      ->addTag('event_subscriber');
+    $builder->register('test_service_1', 'Drupal\register_event_listener_pass_test_module\TestService1')
+      ->addTag('event_subscriber');
+
+    $this->pass->process($builder);
+
+    $listeners = $event_dispatcher_definition->getArguments()[0];
+    $this->assertEquals([
+      10 => [['service' => ['test_service_0', 'onExample2']]],
+      0 => [
+        ['service' => ['test_service_1', 'onExample']],
+        ['service' => ['test_service_0', 'onExample1']]
+      ],
+    ], $listeners['example']);
+  }
+
+}
+
+class TestServiceWithoutInterface {
+
+}
+
+}
+
+namespace Drupal\register_event_listener_pass_test_module {
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class TestService1 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'] = 'onExample';
+
+    return $events;
+  }
+
+}
+
+class TestService2 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'][] = ['onExample1'];
+    $events['example'][] = ['onExample2', 10];
+
+    return $events;
+  }
+
+}
+}
+
+namespace Drupal\register_event_listener_pass_test_nodule {
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class TestService1 implements EventSubscriberInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events['example'] = 'onExample';
+
+    return $events;
+  }
+}
+
+}
+
