diff --git a/composer.json b/composer.json
index d6cdc7f..4969900 100644
--- a/composer.json
+++ b/composer.json
@@ -26,7 +26,8 @@
     "phpunit/phpunit": "4.1.*",
     "phpunit/phpunit-mock-objects": "dev-master#e60bb929c50ae4237aaf680a4f6773f4ee17f0a2",
     "zendframework/zend-feed": "2.2.*",
-    "mikey179/vfsStream": "1.*"
+    "mikey179/vfsStream": "1.*",
+    "stack/builder": "1.0.*"
   },
   "autoload": {
     "psr-4": {
diff --git a/core/core.services.yml b/core/core.services.yml
index 83ab732..9d7a87c 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -342,6 +342,13 @@ services:
     arguments: ['@controller_resolver', '@string_translation']
   http_kernel:
     class: Symfony\Component\HttpKernel\HttpKernel
+    factory_method: resolve
+    factory_service: http_kernel_factory
+    arguments: ['@http_kernel.basic']
+  http_kernel_factory:
+    class: Stack\Builder
+  http_kernel.basic:
+    class: Symfony\Component\HttpKernel\HttpKernel
     arguments: ['@event_dispatcher', '@controller_resolver', '@request_stack']
   language_manager:
     class: Drupal\Core\Language\LanguageManager
diff --git a/core/lib/Drupal/Core/Authentication/AuthenticationManager.php b/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
index 1a7ca6e..b3d5c2a 100644
--- a/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
+++ b/core/lib/Drupal/Core/Authentication/AuthenticationManager.php
@@ -182,7 +182,7 @@ public function handleException(GetResponseForExceptionEvent $event) {
     $active_providers = ($route && $route->getOption('_auth')) ? $route->getOption('_auth') : array($this->defaultProviderId());
 
     // Get the sorted list of active providers for the given route.
-    $providers = array_intersect($active_providers, array_keys($this->providers));
+    $providers = array_intersect($active_providers, array_keys($this->getSortedProviders()));
 
     foreach ($providers as $provider_id) {
       if ($this->providers[$provider_id]->handleException($event) == TRUE) {
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index 11b9e3e..2ac11dd 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Cache\CacheContextsPass;
 use Drupal\Core\Cache\ListCacheBinsPass;
 use Drupal\Core\DependencyInjection\Compiler\BackendCompilerPass;
+use Drupal\Core\DependencyInjection\Compiler\StackedKernelPass;
 use Drupal\Core\DependencyInjection\ServiceProviderInterface;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\DependencyInjection\Compiler\ModifyServiceDefinitionsPass;
@@ -54,6 +55,8 @@ public function register(ContainerBuilder $container) {
 
     $container->addCompilerPass(new BackendCompilerPass());
 
+    $container->addCompilerPass(new StackedKernelPass());
+
     // Collect tagged handler services as method calls on consumer services.
     $container->addCompilerPass(new TaggedHandlersPass());
 
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/StackedKernelPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/StackedKernelPass.php
new file mode 100644
index 0000000..bf8efc0
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/StackedKernelPass.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\StackedKernelPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+
+/**
+ * Provides a compiler pass for stacked HTTP kernels.
+ *
+ * @see \Stack\Builder
+ */
+class StackedKernelPass implements CompilerPassInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('http_kernel_factory')) {
+      return;
+    }
+
+    $http_kernel_factory = $container->getDefinition('http_kernel_factory');
+    $middleware_priorities = array();
+    $middleware_arguments = array();
+    foreach ($container->findTaggedServiceIds('http_middleware') as $id => $attributes) {
+      $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
+      $middleware_priorities[$id] = $priority;
+      $definition = $container->getDefinition($id);
+      $middleware_arguments[$id] = $definition->getArguments();
+      array_unshift($middleware_arguments[$id], $definition->getClass());
+    }
+    array_multisort($middleware_priorities, SORT_DESC, $middleware_arguments, SORT_DESC);
+
+    foreach ($middleware_arguments as $id => $push_arguments) {
+      $http_kernel_factory->addMethodCall('push', $push_arguments);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 6aeeffd..d3872de 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -121,7 +121,7 @@ class FormBuilder implements FormBuilderInterface, FormValidatorInterface, FormS
    * @param \Drupal\Core\HttpKernel $http_kernel
    *   The HTTP kernel.
    */
-  public function __construct(FormValidatorInterface $form_validator, FormSubmitterInterface $form_submitter, ModuleHandlerInterface $module_handler, KeyValueExpirableFactoryInterface $key_value_expirable_factory, EventDispatcherInterface $event_dispatcher, RequestStack $request_stack, ClassResolverInterface $class_resolver, CsrfTokenGenerator $csrf_token = NULL, HttpKernel $http_kernel = NULL) {
+  public function __construct(FormValidatorInterface $form_validator, FormSubmitterInterface $form_submitter, ModuleHandlerInterface $module_handler, KeyValueExpirableFactoryInterface $key_value_expirable_factory, EventDispatcherInterface $event_dispatcher, RequestStack $request_stack, ClassResolverInterface $class_resolver, CsrfTokenGenerator $csrf_token = NULL, HttpKernelInterface $http_kernel = NULL) {
     $this->formValidator = $form_validator;
     $this->formSubmitter = $form_submitter;
     $this->moduleHandler = $module_handler;
diff --git a/core/modules/system/src/Tests/HttpKernel/StackKernelIntegrationTest.php b/core/modules/system/src/Tests/HttpKernel/StackKernelIntegrationTest.php
new file mode 100644
index 0000000..ee37f7e
--- /dev/null
+++ b/core/modules/system/src/Tests/HttpKernel/StackKernelIntegrationTest.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\HttpKernel\StackKernelIntegrationTest.
+ */
+
+namespace Drupal\system\Tests\HttpKernel;
+
+use Drupal\simpletest\KernelTestBase;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests the stacked kernel functionality.
+ *
+ * @group Routing.
+ */
+class StackKernelIntegrationTest extends KernelTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('httpkernel_test', 'system');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    $this->installSchema('system', 'router');
+  }
+
+  /**
+   * Tests a request.
+   */
+  public function testRequest() {
+    $request = new Request();
+    /** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
+    $http_kernel = \Drupal::service('http_kernel');
+    $http_kernel->handle($request);
+
+    $this->assertEqual($request->attributes->get('_hello'), 'world');
+    $this->assertEqual($request->attributes->get('_previous_optional_argument'), 'test_argument');
+  }
+
+}
+
diff --git a/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml
new file mode 100644
index 0000000..5f1375f
--- /dev/null
+++ b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.info.yml
@@ -0,0 +1,6 @@
+name: 'HttpKernel test'
+type: module
+description: 'Support module for httpkernel tests.'
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.services.yml b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.services.yml
new file mode 100644
index 0000000..c4784de
--- /dev/null
+++ b/core/modules/system/tests/modules/httpkernel_test/httpkernel_test.services.yml
@@ -0,0 +1,10 @@
+services:
+  httpkernel_test.test_middleware:
+    class: Drupal\httpkernel_test\HttpKernel\TestMiddleware
+    tags:
+      - { name: http_middleware }
+  httpkernel_test.test_middleware2:
+    class: Drupal\httpkernel_test\HttpKernel\TestMiddleware
+    arguments: ['test_argument']
+    tags:
+      - { name: http_middleware, priority: 20 }
diff --git a/core/modules/system/tests/modules/httpkernel_test/src/HttpKernel/TestMiddleware.php b/core/modules/system/tests/modules/httpkernel_test/src/HttpKernel/TestMiddleware.php
new file mode 100644
index 0000000..93e1a89
--- /dev/null
+++ b/core/modules/system/tests/modules/httpkernel_test/src/HttpKernel/TestMiddleware.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\httpkernel_test\HttpKernel\TestMiddleware.
+ */
+
+namespace Drupal\httpkernel_test\HttpKernel;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+
+/**
+ * Provides a test middleware.
+ */
+class TestMiddleware implements HttpKernelInterface {
+
+ /**
+  * The decorated kernel.
+  *
+  * @var \Symfony\Component\HttpKernel\HttpKernelInterface
+  */
+ protected $kernel;
+
+  /**
+   * An optional argument.
+   *
+   * @var mixed
+   */
+  protected $optionalArgument;
+
+  /**
+   * Constructs a new TestMiddleware object.
+   *
+   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $kernel
+   *   The decorated kernel.
+   * @param mixed $optional_argument
+   *   (optional) An optional argument.
+   */
+  public function __construct(HttpKernelInterface $kernel, $optional_argument = NULL) {
+    $this->kernel = $kernel;
+    $this->optionalArgument = $optional_argument;
+ }
+
+ /**
+  * {@inheritdoc}
+  */
+ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = TRUE) {
+   $request->attributes->set('_hello', 'world');
+   if ($request->attributes->has('_optional_argument')) {
+     $request->attributes->set('_previous_optional_argument', $request->attributes->get('_optional_argument'));
+   }
+   elseif (isset($this->optionalArgument)) {
+     $request->attributes->set('_optional_argument', $this->optionalArgument);
+   }
+
+   return $this->kernel->handle($request, $type, $catch);
+ }
+
+}
