diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 60b086a..8fad9b1 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2744,73 +2744,29 @@ function get_t() {
  * @see language()
  */
 function drupal_language_initialize() {
-  if (language_multilingual()) {
-    $types = language_types_get_all();
-    foreach ($types as $type) {
-      language($type);
-    }
-    // Allow modules to react on language system initialization in multilingual
-    // environments.
-    bootstrap_invoke_all('language_init');
-    // @todo D8: Remove after http://drupal.org/node/1859110.
-    drupal_container()->get('config.factory')->reset();
-  }
+  drupal_container()->get('language_manager')->init();
 }
 
 /**
  * Returns the language object for a given language type.
  *
- * The 'language_manager' service is only available within the scope of a kernel
- * request. When it's not available, we return a default language object,
- * regardless of the type passed in.
- *
  * @see Drupal\Core\Language\LanguageManager
  *
  * @param string $type
  *   The type of language object needed, e.g. LANGUAGE_TYPE_INTERFACE.
- * @param bool $reset
- *   TRUE to reset the statically cached language object for the type, or for
- *   all types if $type is NULL.
- */
-function language($type, $reset = FALSE) {
-  // We don't use drupal_static() here because resetting is not a simple case of
-  // drupal_static_reset().
-  static $languages = array();
-
-  // Reset the language manager's cache and our own.
-  if ($reset) {
-    if (drupal_container()->isScopeActive('request')) {
-      drupal_container()->get('language_manager')->reset($type);
-    }
-    if (!isset($type)) {
-      $languages = array();
-    }
-    elseif (isset($languages[$type])) {
-      unset($languages[$type]);
-    }
-  }
-
-  // If no type is passed (most likely when resetting all types), return.
-  if (!isset($type)) {
-    return;
-  }
-
-  // When the language_manager service exists (is both defined and the 'request'
-  // scope is active in the container), use it to get the language. Otherwise
-  // return the default language.
-  if (drupal_container()->isScopeActive('request')) {
-    $language_manager = drupal_container()->get('language_manager', Container::NULL_ON_INVALID_REFERENCE);
-  }
-
-  if (isset($language_manager)) {
-    return $language_manager->getLanguage($type);
+ */
+function language($type) {
+  $container = drupal_container();
+  if (!$container) {
+    return language_default();
   }
-  else {
-    if (!isset($languages[$type])) {
-      $languages[$type] = language_default();
-    }
-    return $languages[$type];
+  if (!$container->has('language_manager')) {
+    // This happens in rare situations when the container has not been built by
+    // a kernel and has no services e.g. when t() is called during unit tests for
+    // assertions.
+    $container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
   }
+  return $container->get('language_manager')->getLanguage($type);
 }
 
 /**
@@ -3016,6 +2972,21 @@ function language_default() {
 }
 
 /**
+ * Store or retrieve the path derived during language negotiation.
+ *
+ * @todo Replace this with a path processor in language module. See
+ *   http://drupal.org/node/1888424.
+ */
+function _language_resolved_path($new_path = NULL) {
+  $path = &drupal_static(__FUNCTION__, NULL);
+  if ($new_path === NULL) {
+    return $path;
+  }
+  $path = $new_path;
+  return $path;
+}
+
+/**
  * Returns the requested URL path of the page being viewed.
  *
  * Examples:
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 01bde01..b06a8cc 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -339,6 +339,9 @@ function install_begin_request(&$install_state) {
       ->addArgument(new Reference('config.storage'))
       ->addArgument(new Reference('event_dispatcher'));
 
+    // Register the 'language_manager' service.
+    $container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
+
     // The install process cannot use the database lock backend since the database
     // is not fully up, so we use a null backend implementation during the
     // installation process. This will also speed up the installation process.
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index a15279e..a44efb9 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -10,6 +10,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterAccessChecksPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterManipulatorsPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -94,7 +95,8 @@ public function build(ContainerBuilder $container) {
 
     $container->register('path.alias_manager', 'Drupal\Core\Path\AliasManager')
       ->addArgument(new Reference('database'))
-      ->addArgument(new Reference('keyvalue'));
+      ->addArgument(new Reference('state'))
+      ->addArgument(new Reference('language_manager'));
 
     $container->register('http_client_simpletest_subscriber', 'Drupal\Core\Http\Plugin\SimpletestHttpRequestSubscriber');
     $container->register('http_default_client', 'Guzzle\Http\Client')
@@ -138,9 +140,10 @@ public function build(ContainerBuilder $container) {
       ->addArgument(new Reference('event_dispatcher'))
       ->addArgument(new Reference('service_container'))
       ->addArgument(new Reference('controller_resolver'));
-    $container->register('language_manager', 'Drupal\Core\Language\LanguageManager')
-      ->addArgument(new Reference('request'))
-      ->setScope('request');
+
+    // Register the 'language_manager' service.
+    $container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
+
     $container->register('database.slave', 'Drupal\Core\Database\Connection')
       ->setFactoryClass('Drupal\Core\Database\Database')
       ->setFactoryMethod('getConnection')
@@ -224,6 +227,7 @@ public function build(ContainerBuilder $container) {
       ->addTag('event_subscriber');
     $container->register('path_subscriber', 'Drupal\Core\EventSubscriber\PathSubscriber')
       ->addArgument(new Reference('path.alias_manager.cached'))
+      ->addArgument(new Reference('path_manipulator_manager'))
       ->addTag('event_subscriber');
     $container->register('legacy_request_subscriber', 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber')
       ->addTag('event_subscriber');
@@ -238,6 +242,9 @@ public function build(ContainerBuilder $container) {
       ->addTag('event_subscriber');
     $container->register('config_global_override_subscriber', 'Drupal\Core\EventSubscriber\ConfigGlobalOverrideSubscriber')
       ->addTag('event_subscriber');
+    $container->register('language_request_subscriber', 'Drupal\Core\EventSubscriber\LanguageRequestSubscriber')
+      ->addArgument(new Reference('language_manager'))
+      ->addTag('event_subscriber');
 
     $container->register('exception_controller', 'Drupal\Core\ExceptionController')
       ->addArgument(new Reference('content_negotiation'))
@@ -246,6 +253,8 @@ public function build(ContainerBuilder $container) {
       ->addTag('event_subscriber')
       ->addArgument(array(new Reference('exception_controller'), 'execute'));
 
+    $this->registerPathManipulators($container);
+
     $container
       ->register('transliteration', 'Drupal\Core\Transliteration\PHPTransliteration');
 
@@ -364,4 +373,27 @@ protected function registerTwig(ContainerBuilder $container) {
       // @see http://drupal.org/node/1804998
       ->addMethodCall('addExtension', array(new Definition('Twig_Extension_Debug')));
   }
+
+  /**
+   * Register services related to path manipulation.
+   */
+  protected function registerPathManipulators(ContainerBuilder $container) {
+    // Register the path manipulator manager service.
+    $container->register('path_manipulator_manager', 'Drupal\Core\PathManipulator\PathManipulatorManager');
+    // Register the manipulator that urldecodes the path.
+    $container->register('path_manipulator_decode', 'Drupal\Core\PathManipulator\PathManipulatorDecode')
+      ->addTag('incoming_path_manipulator', array('priority' => 300));
+    // Register the manipulator that resolves the front page.
+    $container->register('path_manipulator_front', 'Drupal\Core\PathManipulator\PathManipulatorFront')
+      ->addArgument(new Reference('config.factory'))
+      ->addTag('incoming_path_manipulator', array('priority' => 200));
+    // Register the alias path manipulator.
+    $container->register('path_manipulator_alias', 'Drupal\Core\PathManipulator\PathManipulatorAlias')
+      ->addArgument(new Reference('path.alias_manager'))
+      ->addTag('incoming_path_manipulator', array('priority' => 100));
+
+    // Add the compiler pass that will process the tagged services.
+    $container->addCompilerPass(new RegisterManipulatorsPass());
+  }
+
 }
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterManipulatorsPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterManipulatorsPass.php
new file mode 100644
index 0000000..86fe0cc
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterManipulatorsPass.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\DependencyInjection\Compiler\RegisterManipulatorsPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Adds services to the 'path_manipulator_manager service.
+ */
+class RegisterManipulatorsPass implements CompilerPassInterface {
+
+  /**
+   * Adds services tagged 'incoming_path_manipulator' to the manipulator manager.
+   *
+   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+   *  The container to process.
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('path_manipulator_manager')) {
+      return;
+    }
+    $manager = $container->getDefinition('path_manipulator_manager');
+    foreach ($container->findTaggedServiceIds('incoming_path_manipulator') as $id => $attributes) {
+      $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
+      $manager->addMethodCall('addIncoming', array(new Reference($id), $priority));
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php
new file mode 100644
index 0000000..3e00a91
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/LanguageRequestSubscriber.php
@@ -0,0 +1,50 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\EventSubscriber\LanguageRequestSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Core\Language\LanguageManager;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Request subscriber to set the $request proprerty on the language manager.
+ */
+class LanguageRequestSubscriber implements EventSubscriberInterface {
+
+  protected $languageManager;
+
+  public function __construct(LanguageManager $language_manager) {
+    $this->languageManager = $language_manager;
+  }
+
+  /**
+   * Sets the request on the language manager.
+   *
+   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelRequestLanguage(GetResponseEvent $event) {
+    if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
+      $this->languageManager->setRequest($event->getRequest());
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestLanguage', 300);
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
index be0e779..c523658 100644
--- a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\EventSubscriber;
 
 use Drupal\Core\CacheDecorator\AliasManagerCacheDecorator;
+use Drupal\Core\PathManipulator\IncomingPathManipulatorInterface;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
@@ -20,24 +21,24 @@
 class PathSubscriber extends PathListenerBase implements EventSubscriberInterface {
 
   protected $aliasManager;
+  protected $manipulatorManager;
 
-  public function __construct(AliasManagerCacheDecorator $alias_manager) {
+  public function __construct(AliasManagerCacheDecorator $alias_manager, IncomingPathManipulatorInterface $manipulator) {
     $this->aliasManager = $alias_manager;
+    $this->manipulator = $manipulator;
   }
 
   /**
-   * Resolve the system path.
+   * Converts the request path to a system path.
    *
    * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
    *   The Event to process.
    */
-  public function onKernelRequestPathResolve(GetResponseEvent $event) {
+  public function onKernelRequestConvertPath(GetResponseEvent $event) {
     $request = $event->getRequest();
-    $path = $this->extractPath($request);
-    $path = $this->aliasManager->getSystemPath($path);
-    $this->setPath($request, $path);
-    // If this is the master request, set the cache key for the caching of all
-    // system paths looked up during the request.
+    $path = trim($request->getPathInfo(), '/');
+    $path = $this->manipulator->manipulateIncoming($path, $request);
+    $request->attributes->set('system_path', $path);
     if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
       $this->aliasManager->setCacheKey($path);
     }
@@ -51,88 +52,14 @@ public function onKernelTerminate(PostResponseEvent $event) {
   }
 
   /**
-   * Resolve the front-page default path.
-   *
-   * @todo The path system should be objectified to remove the function calls in
-   *   this method.
-   *
-   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
-   *   The Event to process.
-   */
-  public function onKernelRequestFrontPageResolve(GetResponseEvent $event) {
-    $request = $event->getRequest();
-    $path = $this->extractPath($request);
-
-    if (empty($path)) {
-      // @todo Temporary hack. Fix when configuration is injectable.
-      $path = config('system.site')->get('page.front');
-      if (empty($path)) {
-        $path = 'user';
-      }
-    }
-
-    $this->setPath($request, $path);
-  }
-
-  /**
-   * Decode language information embedded in the request path.
-   *
-   * @todo Refactor this entire method to inline the relevant portions of
-   *   drupal_language_initialize(). See the inline comment for more details.
-   *
-   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
-   *   The Event to process.
-   */
-  public function onKernelRequestLanguageResolve(GetResponseEvent $event) {
-    // drupal_language_initialize() combines:
-    // - Determination of language from $request information (e.g., path).
-    // - Determination of language from other information (e.g., site default).
-    // - Population of determined language into drupal_container().
-    // - Removal of language code from _current_path().
-    // @todo Decouple the above, but for now, invoke it and update the path
-    //   prior to front page and alias resolution. When above is decoupled, also
-    //   add 'langcode' (determined from $request only) to $request->attributes.
-    drupal_language_initialize();
-  }
-
-  /**
-   * Decodes the path of the request.
-   *
-   * Parameters in the URL sometimes represent code-meaningful strings. It is
-   * therefore useful to always urldecode() those values so that individual
-   * controllers need not concern themselves with it. This is Drupal-specific
-   * logic and may not be familiar for developers used to other Symfony-family
-   * projects.
-   *
-   * @todo Revisit whether or not this logic is appropriate for here or if
-   *   controllers should be required to implement this logic themselves. If we
-   *   decide to keep this code, remove this TODO.
-   *
-   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
-   *   The Event to process.
-   */
-  public function onKernelRequestDecodePath(GetResponseEvent $event) {
-    $request = $event->getRequest();
-    $path = $this->extractPath($request);
-
-    $path = urldecode($path);
-
-    $this->setPath($request, $path);
-  }
-
-  /**
    * Registers the methods in this class that should be listeners.
    *
    * @return array
    *   An array of event listener definitions.
    */
   static function getSubscribedEvents() {
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestDecodePath', 200);
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestLanguageResolve', 150);
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestFrontPageResolve', 101);
-    $events[KernelEvents::REQUEST][] = array('onKernelRequestPathResolve', 100);
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestConvertPath', 200);
     $events[KernelEvents::TERMINATE][] = array('onKernelTerminate', 200);
-
     return $events;
   }
 }
diff --git a/core/lib/Drupal/Core/Language/LanguageManager.php b/core/lib/Drupal/Core/Language/LanguageManager.php
index ff0177d..5ee33d9 100644
--- a/core/lib/Drupal/Core/Language/LanguageManager.php
+++ b/core/lib/Drupal/Core/Language/LanguageManager.php
@@ -2,52 +2,145 @@
 
 /**
  * @file
- * Definition of Drupal\Core\Language\LanguageManager.
+ * Contains Drupal\Core\Language\LanguageManager.
  */
 
 namespace Drupal\Core\Language;
 
+use Drupal\Core\Config\ConfigFactory;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Class responsible for initializing each language type.
- *
- * This service is dependent on the 'request' service and can therefore pass the
- * Request object to the code that deals with each particular language type.
- * This means the Request can be used directly for things like URL-based
- * language negotiation.
  */
 class LanguageManager {
 
-  private $request;
-  private $languages;
+  /**
+   * A request object.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
 
-  public function __construct(Request $request = NULL) {
+  /**
+   * An array of language objects keyed by language type.
+   *
+   * @var array
+   */
+  protected $languages;
+
+  /**
+   * Whether or not the language manager has been initialized.
+   *
+   * @var boolean
+   */
+  protected $initialized = FALSE;
+
+  /**
+   * Whether already in the process of language initialization.
+   *
+   * @todo This is only needed due to the circular dependency between language
+   *   and config. See http://drupal.org/node/1862202 for the plan to fix this.
+   */
+  protected $initializing = FALSE;
+
+  /**
+   * Initializes each language type to a language object.
+   */
+  public function init() {
+    if ($this->initialized) {
+      return;
+    }
+    if ($this->getLanguageCount() > 1) {
+      foreach ($this->getLanguageTypes() as $type) {
+        $this->getLanguage($type);
+      }
+    }
+    $this->initialized = TRUE;
+  }
+
+  /**
+   * Sets the $request property and resets all language types.
+   */
+  public function setRequest(Request $request) {
     $this->request = $request;
+    $this->reset();
+    $this->init();
   }
 
+  /**
+   * Returns a language object for the given type.
+   */
   public function getLanguage($type) {
     if (isset($this->languages[$type])) {
       return $this->languages[$type];
     }
 
     // @todo Objectify the language system so that we don't have to do this.
-    if (language_multilingual()) {
-      include_once DRUPAL_ROOT . '/core/includes/language.inc';
-      $this->languages[$type] = language_types_initialize($type, $this->request);
+    if ($this->getLanguageCount() > 1 && $this->request) {
+      if (!$this->initializing) {
+        $this->initializing = TRUE;
+        include_once DRUPAL_ROOT . '/core/includes/language.inc';
+        $this->languages[$type] = language_types_initialize($type, $this->request);
+        $this->initializing = FALSE;
+      }
+      else {
+        // Config has called getLanguage() during initialization of a language
+        // type. Simply return the default language without setting it on the
+        // $this->languages property. See the TODO in the docblock for the
+        // $initializing property.
+        return new Language($this->getLanguageDefault() + array('default' => TRUE));
+      }
     }
     else {
-      $this->languages[$type] = language_default();
+      $this->languages[$type] = new Language($this->getLanguageDefault() + array('default' => TRUE));
     }
     return $this->languages[$type];
   }
 
+  /**
+   * Resets the given language type or all types if none specified.
+   */
   public function reset($type = NULL) {
     if (!isset($type)) {
       $this->languages = array();
+      $this->initialized = FALSE;
     }
     elseif (isset($this->languages[$type])) {
       unset($this->languages[$type]);
     }
   }
+
+  /**
+   * @todo Inject state once these variables have been converted to use the
+   *  state system, then remove these methods and replace calls to them with
+   *  $this->state->get('language_count') etc.
+   */
+
+  /**
+   * Returns the number of currently enabled langauges.
+   */
+  protected function getLanguageCount() {
+    return variable_get('language_count', 1);
+  }
+
+  /**
+   * Returns the array of language types.
+   */
+  protected function getLanguageTypes() {
+    return array_keys(variable_get('language_types', language_types_get_default()));
+  }
+
+  /**
+   * Returns an array of information representing the current default language.
+   */
+  protected function getLanguageDefault() {
+    return variable_get('language_default', array(
+      'langcode' => 'en',
+      'name' => 'English',
+      'direction' => 0,
+      'weight' => 0,
+      'locked' => 0,
+    ));
+  }
 }
diff --git a/core/lib/Drupal/Core/Path/AliasManager.php b/core/lib/Drupal/Core/Path/AliasManager.php
index 47bf77b..45bdca2 100644
--- a/core/lib/Drupal/Core/Path/AliasManager.php
+++ b/core/lib/Drupal/Core/Path/AliasManager.php
@@ -8,7 +8,8 @@
 namespace Drupal\Core\Path;
 
 use Drupal\Core\Database\Connection;
-use Drupal\Core\KeyValueStore\KeyValueFactory;
+use Drupal\Core\KeyValueStore\KeyValueStoreInterface;
+use Drupal\Core\Language\LanguageManager;
 
 class AliasManager implements AliasManagerInterface {
 
@@ -27,11 +28,11 @@ class AliasManager implements AliasManagerInterface {
   protected $state;
 
   /**
-   * The default langcode to use when none is specified for path lookups.
+   * Language manager for retrieving the default langcode when none is specified.
    *
-   * @var string
+   * @var \Drupal\Core\Language\LanguageManager
    */
-  protected $langcode;
+  protected $languageManager;
 
   /**
    * Holds the map of path lookups per language.
@@ -78,11 +79,12 @@ class AliasManager implements AliasManagerInterface {
    */
   protected $preloadedPathLookups = array();
 
-  public function __construct(Connection $connection, KeyValueFactory $keyvalue) {
+  public function __construct(Connection $connection, KeyValueStoreInterface $state, LanguageManager $language_manager) {
     $this->connection = $connection;
-    $this->state = $keyvalue->get('state');
-    $this->langcode = language(LANGUAGE_TYPE_URL)->langcode;
+    $this->state = $state;
+    $this->languageManager = $language_manager;
     $this->whitelist = $this->state->get('system.path_alias_whitelist', NULL);
+
     if (!isset($this->whitelist)) {
       $this->whitelist = $this->pathAliasWhitelistRebuild();
     }
@@ -96,7 +98,7 @@ public function getSystemPath($path, $path_language = NULL) {
     // language. If we used a language different from the one conveyed by the
     // requested URL, we might end up being unable to check if there is a path
     // alias matching the URL path.
-    $path_language = $path_language ?: $this->langcode;
+    $path_language = $path_language ?: $this->languageManager->getLanguage(LANGUAGE_TYPE_URL)->langcode;
     $original_path = $path;
     // Lookup the path alias first.
     if (!empty($path) && $source = $this->lookupPathSource($path, $path_language)) {
@@ -114,7 +116,7 @@ public function getPathAlias($path, $path_language = NULL) {
     // language. If we used a language different from the one conveyed by the
     // requested URL, we might end up being unable to check if there is a path
     // alias matching the URL path.
-    $path_language = $path_language ?: $this->langcode;
+    $path_language = $path_language ?: $this->languageManager->getLanguage(LANGUAGE_TYPE_URL)->langcode;
     $result = $path;
     if (!empty($path) && $alias = $this->lookupPathAlias($path, $path_language)) {
       $result = $alias;
diff --git a/core/lib/Drupal/Core/PathManipulator/.DS_Store b/core/lib/Drupal/Core/PathManipulator/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/core/lib/Drupal/Core/PathManipulator/.DS_Store differ
diff --git a/core/lib/Drupal/Core/PathManipulator/IncomingPathManipulatorInterface.php b/core/lib/Drupal/Core/PathManipulator/IncomingPathManipulatorInterface.php
new file mode 100644
index 0000000..2472c06
--- /dev/null
+++ b/core/lib/Drupal/Core/PathManipulator/IncomingPathManipulatorInterface.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathManipulator\IncomingPathManipulatorInterface.
+ */
+
+namespace Drupal\Core\PathManipulator;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines an interface for classes that manipulate the incoming path.
+ */
+interface IncomingPathManipulatorInterface {
+
+  /**
+   * Manipulate the incoming path.
+   */
+  public function manipulateIncoming($path, Request $request);
+
+}
diff --git a/core/lib/Drupal/Core/PathManipulator/PathManipulatorAlias.php b/core/lib/Drupal/Core/PathManipulator/PathManipulatorAlias.php
new file mode 100644
index 0000000..21cd38d
--- /dev/null
+++ b/core/lib/Drupal/Core/PathManipulator/PathManipulatorAlias.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathManipulator\PathManipulatorAlias.
+ */
+
+namespace Drupal\Core\PathManipulator;
+
+use Drupal\Core\Path\AliasManagerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Manipulates the incoming path using path alias lookups.
+ */
+class PathManipulatorAlias implements IncomingPathManipulatorInterface {
+
+  protected $aliasManager;
+
+  public function __construct(AliasManagerInterface $alias_manager) {
+    $this->aliasManager = $alias_manager;
+  }
+
+  /**
+   * Implements Drupal\Core\PathManipulator\IncomingPathManipulatorInterface::manipulateIncoming().
+   */
+  public function manipulateIncoming($path, Request $request) {
+    $path = $this->aliasManager->getSystemPath($path);
+    return $path;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PathManipulator/PathManipulatorDecode.php b/core/lib/Drupal/Core/PathManipulator/PathManipulatorDecode.php
new file mode 100644
index 0000000..fc20aba
--- /dev/null
+++ b/core/lib/Drupal/Core/PathManipulator/PathManipulatorDecode.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathManipulator\PathManipulatorDecode.
+ */
+
+namespace Drupal\Core\PathManipulator;
+
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Manipulates the incoming path by urldecoding it.
+ *
+ * Parameters in the URL sometimes represent code-meaningful strings. It is
+ * therefore useful to always urldecode() those values so that individual
+ * controllers need not concern themselves with it. This is Drupal-specific
+ * logic and may not be familiar for developers used to other Symfony-family
+ * projects.
+ *
+ * @todo Revisit whether or not this logic is appropriate for here or if
+ *   controllers should be required to implement this logic themselves. If we
+ *   decide to keep this code, remove this TODO.
+ */
+class PathManipulatorDecode implements IncomingPathManipulatorInterface {
+
+  /**
+   * Implements Drupal\Core\PathManipulator\IncomingPathManipulatorInterface::manipulateIncoming().
+   */
+  public function manipulateIncoming($path, Request $request) {
+    return urldecode($path);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PathManipulator/PathManipulatorFront.php b/core/lib/Drupal/Core/PathManipulator/PathManipulatorFront.php
new file mode 100644
index 0000000..fbfb018
--- /dev/null
+++ b/core/lib/Drupal/Core/PathManipulator/PathManipulatorFront.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathManipulator\PathManipulatorFront.
+ */
+
+namespace Drupal\Core\PathManipulator;
+
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Manipulates the incoming path by resolving it to the front page if empty.
+ */
+class PathManipulatorFront implements IncomingPathManipulatorInterface {
+
+  /**
+   * A config factory for retrieving required config settings.
+   *
+   * @var \Drupal\Core\Config\ConfigFactory
+   */
+  protected $config;
+
+  public function __construct(ConfigFactory $config) {
+    $this->config = $config;
+  }
+
+  /**
+   * Implements Drupal\Core\PathManipulator\IncomingPathManipulatorInterface::manipulateIncoming().
+   */
+  public function manipulateIncoming($path, Request $request) {
+    if (empty($path)) {
+      $path = $this->config->get('system.site')->get('page.front');
+      if (empty($path)) {
+        $path = 'user';
+      }
+    }
+    return $path;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PathManipulator/PathManipulatorManager.php b/core/lib/Drupal/Core/PathManipulator/PathManipulatorManager.php
new file mode 100644
index 0000000..60b33bb
--- /dev/null
+++ b/core/lib/Drupal/Core/PathManipulator/PathManipulatorManager.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathManipulator\PathManipulatorManager.
+ */
+
+namespace Drupal\Core\PathManipulator;
+
+use Drupal\Core\PathManipulator\IncomingPathManipulatorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Composite path manipulator.
+ */
+class PathManipulatorManager implements IncomingPathManipulatorInterface {
+
+  protected $incomingManipulators = array();
+
+  protected $sortedIncoming = array();
+
+  public function addIncoming(IncomingPathManipulatorInterface $manipulator, $priority = 0) {
+    if (empty($this->incomingManipulators[$priority])) {
+      $this->incomingManipulators[$priority] = array();
+    }
+
+    $this->incomingManipulators[$priority][] = $manipulator;
+    $this->sortedIncoming = array();
+  }
+
+  public function manipulateIncoming($path, Request $request) {
+    $manipulators = $this->getIncoming();
+    foreach ($manipulators as $manipulator) {
+      $path = $manipulator->manipulateIncoming($path, $request);
+    }
+    return $path;
+  }
+
+  protected function getIncoming() {
+    if (empty($this->sortedIncoming)) {
+      $this->sortedIncoming = $this->sortManipulators('incomingManipulators');
+    }
+
+    return $this->sortedIncoming;
+  }
+
+  protected function sortManipulators($type) {
+    $sorted = array();
+    krsort($this->{$type});
+
+    foreach ($this->{$type} as $manipulators) {
+      $sorted = array_merge($sorted, $manipulators);
+    }
+    return $sorted;
+  }
+}
diff --git a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
index 350a166..20f835d 100644
--- a/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
+++ b/core/modules/config/lib/Drupal/config/Tests/LocaleConfigOverride.php
@@ -33,10 +33,6 @@ function testLocaleConfigOverride() {
     $name = 'config_test.system';
     // Verify the default configuration values exist.
     $config = config($name);
-    $this->assertIdentical($config->get('foo'), 'bar');
-    // Spoof multilingual.
-    $GLOBALS['conf']['language_count'] = 2;
-    drupal_language_initialize();
     $this->assertIdentical($config->get('foo'), 'en bar');
   }
 }
diff --git a/core/modules/language/language.module b/core/modules/language/language.module
index 3486ff4..d0b91bf 100644
--- a/core/modules/language/language.module
+++ b/core/modules/language/language.module
@@ -507,7 +507,6 @@ function language_save($language) {
 
   if (!empty($language->default)) {
     // Set the new version of this language as default in a variable.
-    $default_language = language_default();
     variable_set('language_default', (array) $language);
   }
 
diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc
index 8bf45a6..1c62206 100644
--- a/core/modules/language/language.negotiation.inc
+++ b/core/modules/language/language.negotiation.inc
@@ -209,11 +209,12 @@ function language_from_user($languages) {
  * @return
  *   A valid language code on success, FALSE otherwise.
  */
-function language_from_user_admin($languages) {
+function language_from_user_admin($languages, $request = NULL) {
   // User preference (only for authenticated users).
   global $user;
 
-  if ($user->uid && !empty($user->preferred_admin_langcode) && isset($languages[$user->preferred_admin_langcode]) && path_is_admin(current_path())) {
+  $request_path = $request ? urldecode(trim($request->getPathInfo(), '/')) : _current_path();
+  if ($user->uid && !empty($user->preferred_admin_langcode) && isset($languages[$user->preferred_admin_langcode]) && path_is_admin($request_path)) {
     return $user->preferred_admin_langcode;
   }
 
@@ -273,15 +274,8 @@ function language_from_url($languages, $request) {
   switch (config('language.negotiation')->get('url.source')) {
     case LANGUAGE_NEGOTIATION_URL_PREFIX:
 
-      $current_path = $request->attributes->get('system_path');
-      if (!isset($current_path)) {
-        $current_path = trim($request->getPathInfo(), '/');
-      }
-
-      list($language, $path) = language_url_split_prefix($current_path, $languages);
-      // Store the correct system path, i.e. minus the path prefix, in the
-      // request.
-      $request->attributes->set('system_path', $path);
+      $request_path = urldecode(trim($request->getPathInfo(), '/'));
+      list($language, $path) = language_url_split_prefix($request_path, $languages);
 
       if ($language !== FALSE) {
         $language_url = $language->langcode;
diff --git a/core/modules/language/lib/Drupal/language/LanguageBundle.php b/core/modules/language/lib/Drupal/language/LanguageBundle.php
new file mode 100644
index 0000000..f73b89e
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/LanguageBundle.php
@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\language\LanguageBundle.
+ */
+
+namespace Drupal\language;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\DependencyInjection\Reference;
+
+/**
+ * language dependency injection container.
+ */
+class LanguageBundle extends Bundle {
+
+  /**
+   * Overrides Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Register the alias path manipulator.
+    $container->register('path_manipulator_language', 'Drupal\language\PathManipulatorLanguage')
+      ->addArgument(new Reference('module_handler'))
+      ->addTag('incoming_path_manipulator', array('priority' => 250));
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/PathManipulatorLanguage.php b/core/modules/language/lib/Drupal/language/PathManipulatorLanguage.php
new file mode 100644
index 0000000..6453d42
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/PathManipulatorLanguage.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\language\PathManipulatorLanguage.
+ */
+
+namespace Drupal\language;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\PathManipulator\IncomingPathManipulatorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Manipulates the incoming path using path alias lookups.
+ */
+class PathManipulatorLanguage implements IncomingPathManipulatorInterface {
+
+  protected $moduleHandler;
+
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * Implements Drupal\Core\PathManipulator\IncomingPathManipulatorInterface::manipulateIncoming().
+   */
+  public function manipulateIncoming($path, Request $request) {
+    // Sigh.
+    include_once DRUPAL_ROOT . '/core/includes/language.inc';
+    $this->moduleHandler->loadInclude('language', 'inc', 'language.negotiation');
+    $languages = language_list();
+    list($language, $path) = language_url_split_prefix($path, $languages);
+    return $path;
+  }
+
+}
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php
index f72c51a..92a419b 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageDependencyInjectionTest.php
@@ -35,7 +35,7 @@ function setUp() {
     parent::setUp();
 
     // Ensure we are building a new Language object for each test.
-    language(NULL, TRUE);
+    $this->container->get('language_manager')->reset();
   }
 
 
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index e86ad6c..9200d89 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -369,6 +369,7 @@ protected function runTest($test) {
     if (!empty($test['language_test_domain'])) {
       state()->set('language_test.domain', $test['language_test_domain']);
     }
+    $this->container->get('language_manager')->reset();
     $this->drupalGet($test['path'], array(), $test['http_header']);
     $this->assertText($test['expect'], $test['message']);
     $this->assertText(t('Language negotiation method: @name', array('@name' => $test['expected_method_id'])));
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleBundle.php b/core/modules/locale/lib/Drupal/locale/LocaleBundle.php
new file mode 100644
index 0000000..f06ce15
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/LocaleBundle.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains LocaleBundle
+ */
+
+namespace Drupal\locale;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Reference;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Bundle for registering locale module's services to the container.
+ */
+class LocaleBundle extends Bundle {
+
+  /**
+   * Implements \Symfony\Component\HttpKernel\Bundle\BundleInterface::build().
+   */
+  public function build(ContainerBuilder $container) {
+    $container->register('locale_config_subscriber', 'Drupal\locale\LocaleConfigSubscriber')
+      ->addArgument(new Reference('language_manager'))
+      ->addTag('event_subscriber');
+  }
+
+}
diff --git a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
index 3d2fd4a..54d91e7 100644
--- a/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
+++ b/core/modules/locale/lib/Drupal/locale/LocaleConfigSubscriber.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Config\Config;
 use Drupal\Core\Config\ConfigEvent;
 use Drupal\Core\Config\StorageDispatcher;
+use Drupal\Core\Language\LanguageManager;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 
@@ -18,6 +19,24 @@
  * $config is always a DrupalConfig object.
  */
 class LocaleConfigSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The language manager for retrieving the interface language.
+   *
+   * @var \Drupal\Core\Language\LanguageManager
+   */
+  protected $languageManager;
+
+  /**
+   * Constructs a LocaleConfigSubscriber object.
+   *
+   * @param \Drupal\Core\Language\LanguageManager $language_manager
+   *   The language manager service.
+   */
+  public function __construct(LanguageManager $language_manager) {
+    $this->languageManager = $language_manager;
+  }
+
   /**
    * Override configuration values with localized data.
    *
@@ -26,7 +45,7 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
    */
   public function configLoad(ConfigEvent $event) {
     $config = $event->getConfig();
-    $language = language(LANGUAGE_TYPE_INTERFACE);
+    $language = $this->languageManager->getLanguage(LANGUAGE_TYPE_INTERFACE);
     $locale_name = $this->getLocaleConfigName($config->getName(), $language);
     if ($override = $config->getStorage()->read($locale_name)) {
       $config->setOverride($override);
diff --git a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
index e22e65d..465a4b9 100644
--- a/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
+++ b/core/modules/locale/lib/Drupal/locale/Tests/LocaleUninstallTest.php
@@ -56,8 +56,8 @@ function testUninstallProcess() {
       'default' => $this->langcode == 'fr',
     ));
     language_save($language);
-    // Reset statically cached language objects.
-    language(NULL, TRUE);
+    // Reset the language manager.
+    $this->container->get('language_manager')->reset();
     // Check the UI language.
     drupal_language_initialize();
     $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, $this->langcode, t('Current language: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode)));
@@ -101,13 +101,11 @@ function testUninstallProcess() {
     // Uninstall Locale.
     module_disable($locale_module);
     module_uninstall($locale_module);
+    $this->rebuildContainer();
 
     // Visit the front page.
     $this->drupalGet('');
-    // Reset statically cached language objects.
-    language(NULL, TRUE);
     // Check the init language logic.
-    drupal_language_initialize();
     $this->assertEqual(language(LANGUAGE_TYPE_INTERFACE)->langcode, 'en', t('Language after uninstall: %lang', array('%lang' => language(LANGUAGE_TYPE_INTERFACE)->langcode)));
 
     // Check JavaScript files deletion.
diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module
index 5ba05d2..579819e 100644
--- a/core/modules/locale/locale.module
+++ b/core/modules/locale/locale.module
@@ -1303,11 +1303,3 @@ function _locale_rebuild_js($langcode = NULL) {
       return TRUE;
   }
 }
-
-/**
- * Implements hook_language_init().
- */
-function locale_language_init() {
-  // Add locale helper to configuration subscribers.
-  drupal_container()->get('event_dispatcher')->addSubscriber(new LocaleConfigSubscriber());
-}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index b337e4c..21388a8 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -1024,13 +1024,6 @@ protected function tearDown() {
     // this second reset is guranteed to reset everything to nothing.
     drupal_static_reset();
 
-    // Reset static in language().
-    // Restoring drupal_container() makes language() return the proper languages
-    // already, but it contains an additional static that needs to be reset. The
-    // reset can happen before the container is restored, as it is unnecessary
-    // to reset the language_manager service.
-    language(NULL, TRUE);
-
     // Restore original in-memory configuration.
     $conf = $this->originalConf;
     new Settings($this->originalSettings);
diff --git a/core/modules/system/language.api.php b/core/modules/system/language.api.php
index eb8bc3c..ed81b92 100644
--- a/core/modules/system/language.api.php
+++ b/core/modules/system/language.api.php
@@ -11,33 +11,6 @@
  */
 
 /**
- * Allows modules to act after language initialization has been performed.
- *
- * This is primarily needed to provide translation for configuration variables
- * in the proper bootstrap phase. Variables are user-defined strings and
- * therefore should not be translated via t(), since the source string can
- * change without notice and any previous translation would be lost. Moreover,
- * since variables can be used in the bootstrap phase, we need a bootstrap hook
- * to provide a translation early enough to avoid misalignments between code
- * using the original values and code using the translated values. However
- * modules implementing hook_boot() should be aware that language initialization
- * did not happen yet and thus they cannot rely on translated variables.
- */
-function hook_language_init() {
-  global $conf;
-
-  switch (language(LANGUAGE_TYPE_INTERFACE)->langcode) {
-    case 'it':
-      $conf['system.site']['name'] = 'Il mio sito Drupal';
-      break;
-
-    case 'fr':
-      $conf['system.site']['name'] = 'Mon site Drupal';
-      break;
-  }
-}
-
-/**
  * Perform alterations on language switcher links.
  *
  * A language switcher link may need to point to a different path or use a
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
index 21a129a..275e1c4 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
@@ -43,7 +43,7 @@ function testCRUD() {
     $this->fixtures->createTables($connection);
 
     //Create AliasManager and Path object.
-    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue'));
+    $aliasManager = new AliasManager($connection, $this->container->get('state'), $this->container->get('language_manager'));
     $path = new Path($connection, $aliasManager);
 
     $aliases = $this->fixtures->sampleUrlAliases();
@@ -96,7 +96,7 @@ function testLookupPath() {
     $this->fixtures->createTables($connection);
 
     //Create AliasManager and Path object.
-    $aliasManager = new AliasManager($connection, $this->container->get('keyvalue'));
+    $aliasManager = new AliasManager($connection, $this->container->get('state'), $this->container->get('language_manager'));
     $pathObject = new Path($connection, $aliasManager);
 
     // Test the situation where the source is the same for multiple aliases.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php
index f5d2d9f..e1720d1 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/DateUpgradePathTest.php
@@ -37,21 +37,21 @@ public function testDateUpgrade() {
     $expected_formats['short'] = array(
       'name' => 'Short',
       'pattern' => array(
-        'php' => 'Y/m/d - H:i',
+        'php' => 'm/d/Y - H:i',
       ),
       'locked' => '1',
     );
     $expected_formats['medium'] = array(
       'name' => 'Medium',
       'pattern' => array(
-        'php' => 'D, d/m/Y - H:i',
+        'php' => 'D, m/d/Y - H:i',
       ),
       'locked' => '1',
     );
     $expected_formats['long'] = array(
       'name' => 'Long',
       'pattern' => array(
-        'php' => 'l, Y,  F j - H:i',
+        'php' => 'l, j F, Y - H:i',
       ),
       'locked' => '1',
     );
@@ -76,43 +76,24 @@ public function testDateUpgrade() {
       $this->assertNull(update_variable_get('date_format_' . $type), format_string('Date format variable for @type was deleted.', array('@type' => $type)));
     }
 
-    $expected_locale_formats = array(
+    $expected_de_formats = array(
       array(
-        'langcode' => 'en',
-        'type' => 'long',
-        'format' => 'l, j F, Y - H:i',
-      ),
-      array(
-        'langcode' => 'en',
-        'type' => 'medium',
-        'format' => 'D, m/d/Y - H:i',
-      ),
-      array(
-        'langcode' => 'en',
-        'type' => 'short',
-        'format' => 'm/d/Y - H:i',
-      ),
-      array(
-        'langcode' => 'de',
         'type' => 'long',
         'format' => 'l, j. F, Y - H:i',
       ),
       array(
-        'langcode' => 'de',
         'type' => 'medium',
         'format' => 'D, d/m/Y - H:i',
       ),
       array(
-        'langcode' => 'de',
         'type' => 'short',
         'format' => 'd/m/Y - H:i',
       ),
     );
 
-    $config['en'] = config('locale.config.en.system.date');
-    $config['de'] = config('locale.config.de.system.date');
-    foreach ($expected_locale_formats as $locale_format) {
-      $format = $config[$locale_format['langcode']]->get('formats.' . $locale_format['type'] . '.pattern.php');
+    $config = config('locale.config.de.system.date');
+    foreach ($expected_de_formats as $locale_format) {
+      $format = $config->get('formats.' . $locale_format['type'] . '.pattern.php');
       $this->assertEqual($locale_format['format'], $format);
     }
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
index c4dda65..454e3a2 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UpgradePathTestBase.php
@@ -126,6 +126,13 @@ protected function setUp() {
     drupal_save_session(FALSE);
     // Login as uid 1.
     $user = db_query('SELECT * FROM {users} WHERE uid = :uid', array(':uid' => 1))->fetchObject();
+    // Load roles for the user object.
+    $roles = array(DRUPAL_AUTHENTICATED_RID => DRUPAL_AUTHENTICATED_RID);
+    $result = db_query('SELECT rid, uid FROM {users_roles} WHERE uid = :uid', array(':uid' => 1));
+    foreach ($result as $record) {
+      $roles[$record->rid] = $record->rid;
+    }
+    $user->roles = $roles;
 
     // Generate and set a D8-compatible session cookie.
     $this->prepareD8Session();
@@ -288,6 +295,7 @@ protected function performUpgrade($register_errors = TRUE) {
    * @see WebTestBase::drupalGet()
    */
   protected function getUpdatePhp() {
+    $this->rebuildContainer();
     $path = $GLOBALS['base_url'] . '/core/update.php';
     $out = $this->curlExec(array(CURLOPT_HTTPGET => TRUE, CURLOPT_URL => $path, CURLOPT_NOBODY => FALSE));
     // Ensure that any changes to variables in the other thread are picked up.
