diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 035f282..f257f9f 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\RegisterPathProcessorsPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteFiltersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterRouteEnhancersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass;
@@ -239,6 +240,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_processor_manager'))
       ->addTag('event_subscriber');
     $container->register('legacy_request_subscriber', 'Drupal\Core\EventSubscriber\LegacyRequestSubscriber')
       ->addTag('event_subscriber');
@@ -264,6 +266,8 @@ public function build(ContainerBuilder $container) {
       ->addTag('event_subscriber')
       ->addArgument(array(new Reference('exception_controller'), 'execute'));
 
+    $this->registerPathProcessors($container);
+
     $container
       ->register('transliteration', 'Drupal\Core\Transliteration\PHPTransliteration');
 
@@ -367,4 +371,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 processing.
+   */
+  protected function registerPathProcessors(ContainerBuilder $container) {
+    // Register the path processor manager service.
+    $container->register('path_processor_manager', 'Drupal\Core\PathProcessor\PathProcessorManager');
+    // Register the processor that urldecodes the path.
+    $container->register('path_processor_decode', 'Drupal\Core\PathProcessor\PathProcessorDecode')
+      ->addTag('path_processor_inbound', array('priority' => 1000));
+    // Register the processor that resolves the front page.
+    $container->register('path_processor_front', 'Drupal\Core\PathProcessor\PathProcessorFront')
+      ->addArgument(new Reference('config.factory'))
+      ->addTag('path_processor_inbound', array('priority' => 200));
+    // Register the alias path processor.
+    $container->register('path_processor_alias', 'Drupal\Core\PathProcessor\PathProcessorAlias')
+      ->addArgument(new Reference('path.alias_manager'))
+      ->addTag('path_processor_inbound', array('priority' => 100));
+
+    // Add the compiler pass that will process the tagged services.
+    $container->addCompilerPass(new RegisterPathProcessorsPass());
+  }
+
 }
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterPathProcessorsPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterPathProcessorsPass.php
new file mode 100644
index 0000000..6e298da
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterPathProcessorsPass.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\DependencyInjection\Compiler\RegisterPathProcessorsPass.
+ */
+
+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_processor_manager service.
+ */
+class RegisterPathProcessorsPass implements CompilerPassInterface {
+
+  /**
+   * Adds services tagged 'path_processor_inbound' to the path processor manager.
+   *
+   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+   *  The container to process.
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('path_processor_manager')) {
+      return;
+    }
+    $manager = $container->getDefinition('path_processor_manager');
+    foreach ($container->findTaggedServiceIds('path_processor_inbound') as $id => $attributes) {
+      $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
+      $manager->addMethodCall('addInbound', array(new Reference($id), $priority));
+    }
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
index 6e5b7a9..5915d4b 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\PathProcessor\InboundPathProcessorInterface;
 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 $pathProcessor;
 
-  public function __construct(AliasManagerCacheDecorator $alias_manager) {
+  public function __construct(AliasManagerCacheDecorator $alias_manager, InboundPathProcessorInterface $path_processor) {
     $this->aliasManager = $alias_manager;
+    $this->pathProcessor = $path_processor;
   }
 
   /**
-   * 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->pathProcessor->processInbound($path, $request);
+    $request->attributes->set('system_path', $path);
     if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
       $this->aliasManager->setCacheKey($path);
     }
@@ -51,84 +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.
-   *
-   * @param Symfony\Component\HttpKernel\Event\GetResponseEvent $event
-   *   The Event to process.
-   */
-  public function onKernelRequestLanguageResolve(GetResponseEvent $event) {
-    // We need to act only on the master request, otherwise subrequests will
-    // inherit the main request path and an infinite loop will be started.
-    if ($event->getRequestType() == HttpKernelInterface::MASTER_REQUEST) {
-      $path = _language_resolved_path();
-      if ($path !== NULL) {
-        $this->setPath($event->getRequest(), $path);
-      }
-    }
-  }
-
-  /**
-   * 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/PathProcessor/InboundPathProcessorInterface.php b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
new file mode 100644
index 0000000..946b29c
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/InboundPathProcessorInterface.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathProcessor\InboundPathProcessorInterface.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines an interface for classes that process the inbound path.
+ */
+interface InboundPathProcessorInterface {
+
+  /**
+   * Processes the inbound path.
+   *
+   * @param string $path
+   *   The path to process.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The HttpRequest object representing the current request.
+   */
+  public function processInbound($path, Request $request);
+
+}
diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php
new file mode 100644
index 0000000..7020710
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorAlias.php
@@ -0,0 +1,43 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\PathProcessor\PathProcessorAlias.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Drupal\Core\Path\AliasManagerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Processes the inbound path using path alias lookups.
+ */
+class PathProcessorAlias implements InboundPathProcessorInterface {
+
+  /**
+   * An alias manager for looking up the system path.
+   *
+   * @var \Drupal\Core\Path\AliasManagerInterface
+   */
+  protected $aliasManager;
+
+  /**
+   * Constructs a PathProcessorAlias object.
+   *
+   * @param \Drupal\Core\Path\AliasManagerInterface $alias_manager
+   *   An alias manager for looking up the system path.
+   */
+  public function __construct(AliasManagerInterface $alias_manager) {
+    $this->aliasManager = $alias_manager;
+  }
+
+  /**
+   * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
+   */
+  public function processInbound($path, Request $request) {
+    $path = $this->aliasManager->getSystemPath($path);
+    return $path;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorDecode.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorDecode.php
new file mode 100644
index 0000000..0674cda
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorDecode.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathProcessor\PathProcessorDecode.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Processes the inbound 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 PathProcessorDecode implements InboundPathProcessorInterface {
+
+  /**
+   * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
+   */
+  public function processInbound($path, Request $request) {
+    return urldecode($path);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
new file mode 100644
index 0000000..872885a
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorFront.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathProcessor\PathProcessorFront.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Drupal\Core\Config\ConfigFactory;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Processes the inbound path by resolving it to the front page if empty.
+ */
+class PathProcessorFront implements InboundPathProcessorInterface {
+
+  /**
+   * A config factory for retrieving required config settings.
+   *
+   * @var \Drupal\Core\Config\ConfigFactory
+   */
+  protected $config;
+
+  /**
+   * Constructs a PathProcessorFront object.
+   *
+   * @param Drupal\Core\Config\ConfigFactory $config
+   *   A config factory for retrieving the site front page configuration.
+   */
+  public function __construct(ConfigFactory $config) {
+    $this->config = $config;
+  }
+
+  /**
+   * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
+   */
+  public function processInbound($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/PathProcessor/PathProcessorManager.php b/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php
new file mode 100644
index 0000000..1d0adff
--- /dev/null
+++ b/core/lib/Drupal/Core/PathProcessor/PathProcessorManager.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\PathProcessor\PathProcessorManager.
+ */
+
+namespace Drupal\Core\PathProcessor;
+
+use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Path processor manager.
+ *
+ * Holds an array of path processor objects and uses them to sequentially process
+ * a path, in order of processor priority.
+ */
+class PathProcessorManager implements InboundPathProcessorInterface {
+
+  /**
+   * Holds the array of processors to cycle through.
+   *
+   * @var array
+   *   An array whose keys are priorities and whose values are arrays of path
+   *   processor objects.
+   */
+  protected $inboundProcessors = array();
+
+  /**
+   * Holds the array of processors, sorted by priority.
+   *
+   * @var array
+   *   An array of path processor objects.
+   */
+  protected $sortedInbound = array();
+
+  /**
+   * Adds an inbound processor object to the $inboundProcessors property.
+   *
+   * @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $processor
+   *   The processor object to add.
+   *
+   * @param int $priority
+   *   The priority of the processor being added.
+   */
+  public function addInbound(InboundPathProcessorInterface $processor, $priority = 0) {
+    $this->inboundProcessors[$priority][] = $processor;
+    $this->sortedInbound = array();
+  }
+
+  /**
+   * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
+   */
+  public function processInbound($path, Request $request) {
+    $processors = $this->getInbound();
+    foreach ($processors as $processor) {
+      $path = $processor->processInbound($path, $request);
+    }
+    return $path;
+  }
+
+  /**
+   * Returns the sorted array of inbound processors.
+   *
+   * @return array
+   *   An array of processor objects.
+   */
+  protected function getInbound() {
+    if (empty($this->sortedInbound)) {
+      $this->sortedInbound = $this->sortProcessors('inboundProcessors');
+    }
+
+    return $this->sortedInbound;
+  }
+
+  /**
+   * Sorts the processors according to priority.
+   *
+   * @param string $type
+   *   The processor type to sort, e.g. 'inboundProcessors'.
+   */
+  protected function sortProcessors($type) {
+    $sorted = array();
+    krsort($this->{$type});
+
+    foreach ($this->{$type} as $processors) {
+      $sorted = array_merge($sorted, $processors);
+    }
+    return $sorted;
+  }
+}
diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc
index 9521247..6565c6d 100644
--- a/core/modules/language/language.negotiation.inc
+++ b/core/modules/language/language.negotiation.inc
@@ -282,11 +282,7 @@ function language_from_url($languages, Request $request = NULL) {
     case LANGUAGE_NEGOTIATION_URL_PREFIX:
 
       $request_path = urldecode(trim($request->getPathInfo(), '/'));
-
       list($language, $path) = language_url_split_prefix($request_path, $languages);
-      // Store the correct system path, i.e., the request path without the
-      // language prefix.
-      _language_resolved_path($path);
 
       if ($language !== FALSE) {
         $language_url = $language->langcode;
diff --git a/core/modules/language/lib/Drupal/language/HttpKernel/PathProcessorLanguage.php b/core/modules/language/lib/Drupal/language/HttpKernel/PathProcessorLanguage.php
new file mode 100644
index 0000000..ad16ac6
--- /dev/null
+++ b/core/modules/language/lib/Drupal/language/HttpKernel/PathProcessorLanguage.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\language\HttpKernel\PathProcessorLanguage.
+ */
+
+namespace Drupal\language\HttpKernel;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Processes the inbound path using path alias lookups.
+ */
+class PathProcessorLanguage implements InboundPathProcessorInterface {
+
+  protected $moduleHandler;
+
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * Implements Drupal\Core\PathProcessor\InboundPathProcessorInterface::processInbound().
+   */
+  public function processInbound($path, Request $request) {
+    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/LanguageBundle.php b/core/modules/language/lib/Drupal/language/LanguageBundle.php
new file mode 100644
index 0000000..1e788aa
--- /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 language-based path processor.
+    $container->register('path_processor_language', 'Drupal\language\HttpKernel\PathProcessorLanguage')
+      ->addArgument(new Reference('module_handler'))
+      ->addTag('path_processor_inbound', array('priority' => 300));
+  }
+
+}
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 275e1c4..5dc3158 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/AliasTest.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\system\Tests\Path\CrudTest.
+ * Contains Drupal\system\Tests\Path\AliasTest.
  */
 
 namespace Drupal\system\Tests\Path;
@@ -15,7 +15,7 @@
 /**
  * Tests path alias CRUD and lookup functionality.
  */
-class AliasTest extends DrupalUnitTestBase {
+class AliasTest extends PathUnitTestBase {
 
   public static function getInfo() {
     return array(
@@ -25,18 +25,6 @@ public static function getInfo() {
     );
   }
 
-  public function setUp() {
-    parent::setUp();
-    $this->fixtures = new UrlAliasFixtures();
-  }
-
-  public function tearDown() {
-    $this->fixtures->dropTables(Database::getConnection());
-
-    parent::tearDown();
-  }
-
-
   function testCRUD() {
     //Prepare database table.
     $connection = Database::getConnection();
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/PathUnitTestBase.php b/core/modules/system/lib/Drupal/system/Tests/Path/PathUnitTestBase.php
new file mode 100644
index 0000000..c24506d
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/PathUnitTestBase.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\Path\PathUnitTestBase.
+ */
+
+namespace Drupal\system\Tests\Path;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+use Drupal\Core\Database\Database;
+
+/**
+ * Defines a base class for path unit testing.
+ */
+class PathUnitTestBase extends DrupalUnitTestBase {
+
+  public function setUp() {
+    parent::setUp();
+    $this->fixtures = new UrlAliasFixtures();
+  }
+
+  public function tearDown() {
+    $this->fixtures->dropTables(Database::getConnection());
+
+    parent::tearDown();
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAliasFixtures.php b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAliasFixtures.php
index 6fb02da..a51e3bf 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Path/UrlAliasFixtures.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/UrlAliasFixtures.php
@@ -16,7 +16,7 @@ class UrlAliasFixtures {
    *   The connection to use to create the tables.
    */
   public function createTables(Connection $connection) {
-    $tables = $this->urlAliasTableDefinition();
+    $tables = $this->tableDefinition();
     $schema = $connection->schema();
 
     foreach ($tables as $name => $table) {
@@ -32,7 +32,7 @@ public function createTables(Connection $connection) {
    *   The connection to use to drop the tables.
    */
   public function dropTables(Connection $connection) {
-    $tables = $this->urlAliasTableDefinition();
+    $tables = $this->tableDefinition();
     $schema = $connection->schema();
 
     foreach ($tables as $name => $table) {
@@ -77,7 +77,7 @@ public function sampleUrlAliases() {
    * @return array
    *   Table definitions.
    */
-  public function urlAliasTableDefinition() {
+  public function tableDefinition() {
     $tables = array();
 
     module_load_install('system');
diff --git a/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorFixtures.php b/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorFixtures.php
new file mode 100644
index 0000000..dbc987d
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorFixtures.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Drupal\system\Tests\PathProcessor;
+
+use Drupal\Core\Database\Connection;
+use Drupal\system\Tests\Path\UrlAliasFixtures;
+
+/**
+ * Utility methods to provide necessary database tables for tests.
+ */
+class PathProcessorFixtures extends UrlAliasFixtures {
+
+  /**
+   * Overrides Drupal\system\Tests\Path\UrlAliasFixtures::tableDefinition() .
+   */
+  public function tableDefinition() {
+    // In addition to the tables added by the parent method, we also need the
+    // language and variable tables for the path processor tests.
+    $tables = parent::tableDefinition();
+    $schema = system_schema();
+    $tables['variable'] = $schema['variable'];
+    module_load_install('language');
+    $schema = language_schema();
+    $tables['language'] = $schema['language'];
+    return $tables;
+  }
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorTest.php b/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorTest.php
new file mode 100644
index 0000000..5b10c2a
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/PathProcessor/PathProcessorTest.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\PathProcessor\PathProcessorTest.
+ */
+
+namespace Drupal\system\Tests\PathProcessor;
+
+use Drupal\system\Tests\Path\PathUnitTestBase;
+use Drupal\Core\Database\Database;
+use Drupal\Core\Path\Path;
+use Drupal\Core\Path\AliasManager;
+use Drupal\Core\PathProcessor\PathProcessorAlias;
+use Drupal\Core\PathProcessor\PathProcessorDecode;
+use Drupal\Core\PathProcessor\PathProcessorFront;
+use Drupal\Core\PathProcessor\PathProcessorManager;
+use Drupal\language\HttpKernel\PathProcessorLanguage;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Tests path processor functionality.
+ */
+class PathProcessorTest extends PathUnitTestBase {
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Path Processor Unit Tests'),
+      'description' => t('Tests processing of the inbound path.'),
+      'group' => t('Path API'),
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+    $this->fixtures = new PathProcessorFixtures();
+  }
+
+  /**
+   * Tests resolving the inbound path to the system path.
+   */
+  function testProcessInbound() {
+
+    // Ensure all tables needed for these tests are created.
+    $connection = Database::getConnection();
+    $this->fixtures->createTables($connection);
+
+    // Create dependecies needed by various path processors.
+    $alias_manager = new AliasManager($connection, $this->container->get('state'), $this->container->get('language_manager'));
+    $module_handler = $this->container->get('module_handler');
+
+    // Create the processors.
+    $alias_processor = new PathProcessorAlias($alias_manager);
+    $decode_processor = new PathProcessorDecode();
+    $front_processor = new PathProcessorFront($this->container->get('config.factory'));
+    $language_processor = new PathProcessorLanguage($module_handler);
+
+    // Add a url alias for testing the alias-based processor.
+    $path_crud = new Path($connection, $alias_manager);
+    $path_crud->save('user/1', 'foo');
+
+    // Add a language for testing the language-based processor.
+    $module_handler->setModuleList(array('language' => 'core/modules/language/language.module'));
+    $module_handler->load('language');
+    $language = new \stdClass();
+    $language->langcode = 'fr';
+    $language->name = 'French';
+    language_save($language);
+
+    // First, test the processor manager with the processors in the incorrect
+    // order. The alias processor will run before the language processor, meaning
+    // aliases will not be found.
+    $priorities = array(
+      1000 => $alias_processor,
+      500 => $decode_processor,
+      300 => $front_processor,
+      200 => $language_processor,
+    );
+
+    // Create the processor manager and add the processors.
+    $processor_manager = new PathProcessorManager();
+    foreach ($priorities as $priority => $processor) {
+      $processor_manager->addInbound($processor, $priority);
+    }
+
+    // Test resolving the French homepage using the incorrect processor order.
+    $test_path = 'fr';
+    $request = Request::create($test_path);
+    $processed = $processor_manager->processInbound($test_path, $request);
+    $this->assertEqual($processed, '', 'Processing in the incorrect order fails to resolve the system path from the empty path');
+
+    // Test resolving an existing alias using the incorrect processor order.
+    $test_path = 'fr/foo';
+    $request = Request::create($test_path);
+    $processed = $processor_manager->processInbound($test_path, $request);
+    $this->assertEqual($processed, 'foo', 'Processing in the incorrect order fails to resolve the system path from an alias');
+
+    // Now create a new processor manager and add the processors, this time in
+    // the correct order.
+    $processor_manager = new PathProcessorManager();
+    $priorities = array(
+      1000 => $decode_processor,
+      500 => $language_processor,
+      300 => $front_processor,
+      200 => $alias_processor,
+    );
+    foreach ($priorities as $priority => $processor) {
+      $processor_manager->addInbound($processor, $priority);
+    }
+
+    // Test resolving the French homepage using the correct processor order.
+    $test_path = 'fr';
+    $request = Request::create($test_path);
+    $processed = $processor_manager->processInbound($test_path, $request);
+    $this->assertEqual($processed, 'user', 'Processing in the correct order resolves the system path from the empty path.');
+
+    // Test resolving an existing alias using the correct processor order.
+    $test_path = 'fr/foo';
+    $request = Request::create($test_path);
+    $processed = $processor_manager->processInbound($test_path, $request);
+    $this->assertEqual($processed, 'user/1', 'Processing in the correct order resolves the system path from an alias.');
+  }
+
+}
