diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 2076707..af957a2 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -156,6 +156,8 @@ public function build(ContainerBuilder $container) {
       ->addArgument(new Reference('path.alias_manager'))
       ->addArgument(new Reference('cache.path'));
 
+    $container->register('path.alias_manager.memory', 'Drupal\Core\Path\MemoryAliasManager');
+
     $container->register('path.crud', 'Drupal\Core\Path\Path')
       ->addArgument(new Reference('database'))
       ->addArgument(new Reference('path.alias_manager'));
diff --git a/core/lib/Drupal/Core/Path/MemoryAliasManager.php b/core/lib/Drupal/Core/Path/MemoryAliasManager.php
new file mode 100644
index 0000000..71fc734
--- /dev/null
+++ b/core/lib/Drupal/Core/Path/MemoryAliasManager.php
@@ -0,0 +1,92 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Path\MemoryAliasManager.
+ */
+
+namespace Drupal\Core\Path;
+
+/**
+ * Defines an alias manager which uses the memory as storage.
+ *
+ * The primary use-cases for this alias manager are tests and 'update.php'.
+ */
+class MemoryAliasManager implements AliasManagerInterface {
+
+  /**
+   * Holds the actual path aliases.
+   *
+   * This array has the langcodes has first level keys and pairs of
+   * path alias and internal paths as values.
+   *
+   * @var array
+   */
+  protected $pathAliasMap = array();
+
+  /**
+   * The default langcode to use when none is specified for path lookups.
+   *
+   * @var string
+   */
+  protected $langcode;
+
+  /**
+   * Constructs a EmemoryAliasManager object.
+   */
+  public function __construct() {
+    $this->langcode = language(LANGUAGE_TYPE_URL)->langcode;
+  }
+
+  /**
+   * Implements \Drupal\Core\Path\AliasManagerInterface::getSystemPath().
+   */
+  public function getSystemPath($path, $path_language = NULL) {
+    $result = $path;
+    $langcode = $path_language ?: $this->langcode;
+
+    // A specific langcode overrides in the not specified case.
+    if (isset($this->pathAliasMap[$langcode][$path])) {
+      $result = $this->pathAliasMap[$langcode][$path];
+    }
+    elseif (isset($this->pathAliasMap[LANGUAGE_NOT_SPECIFIED][$path])) {
+      $result = $this->pathAliasMap[LANGUAGE_NOT_SPECIFIED][$path];
+    }
+    return $result;
+  }
+
+  /**
+   * Implements \Drupal\Core\Path\AliasManagerInterface::getPathAlias().
+   */
+  public function getPathAlias($path, $path_language = NULL) {
+    $result = $path;
+    $langcode = $path_language ?: $this->langcode;
+
+    // @todo Should we store both possible maps to not use arraySearch.
+    // A specific langcode overrides in the not specified case.
+    // array_reverse is used, because newer path aliases should be preferred.
+    if (isset($this->pathAliasMap[$langcode]) && $alias = array_search($path, array_reverse($this->pathAliasMap[$langcode]))) {
+      $result = $alias;
+    }
+    elseif (isset($this->pathAliasMap[LANGUAGE_NOT_SPECIFIED]) && $alias = array_search($path, array_reverse($this->pathAliasMap[LANGUAGE_NOT_SPECIFIED]))) {
+      $result = $alias;
+    }
+    return $result;
+
+  }
+
+  /**
+   * Implements \Drupal\Core\Path\AliasManagerInterface::getPathLookups().
+   */
+  public function getPathLookups() {
+    return $this->pathAliasMap;
+  }
+
+  /**
+   * Implements \Drupal\Core\Path\AliasManagerInterface::preloadPathLookups().
+   */
+  public function preloadPathLookups(array $path_list) {
+    $this->pathAliasMap = $path_list;
+  }
+
+}
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
index b09df75..7c93af9 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
@@ -154,6 +154,9 @@ public function containerBuild($container) {
         ->register('keyvalue', 'Drupal\Core\KeyValueStore\KeyValueFactory')
         ->addArgument(new Reference('service_container'));
     }
+    $container->register('path.alias_manager.cached', 'Drupal\Core\CacheDecorator\AliasManagerCacheDecorator')
+      ->addArgument(new Reference('path.alias_manager.memory'))
+      ->addArgument(new Reference('cache.path'));
   }
 
   /**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Path/MemoryAliasTest.php b/core/modules/system/lib/Drupal/system/Tests/Path/MemoryAliasTest.php
new file mode 100644
index 0000000..1efafd8
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Path/MemoryAliasTest.php
@@ -0,0 +1,121 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Path\MemoryAliasTest.
+ */
+
+namespace Drupal\system\Tests\Path;
+
+use Drupal\Core\Path\MemoryAliasManager;
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests the memory alias manager.
+ *
+ * @see \Drupal\Core\Path\MemoryAliasManager
+ */
+class MemoryAliasTest extends DrupalUnitTestBase {
+
+  /**
+   * Stores the memory path alias manager used by this test.
+   *
+   * @var \Drupal\Core\Path\MemoryAliasManager
+   */
+  protected $aliasManager;
+
+  public static function getInfo() {
+    return array(
+      'name' => t('Memory Path Alias Unit Tests'),
+      'description' => t('Tests the memory path alias manager.'),
+      'group' => t('Path API'),
+    );
+  }
+
+  protected function setUp() {
+    parent::setUp();
+
+    //Create AliasManager.
+    $this->aliasManager = $this->container->get('path.alias_manager.memory');
+  }
+
+  /**
+   * Prepares
+   */
+
+  /**
+   * Test the getPathLookups() method.
+   */
+  protected function testLookupPath() {
+
+    // Test the situation where the source is the same for multiple aliases.
+    // Start with a language-neutral alias, which we will override.
+    $path = array(
+      'source' => 'user/1',
+      'alias' => 'foo',
+    );
+    $lookups = array();
+    $lookups[LANGUAGE_NOT_SPECIFIED][$path['alias']] = $path['source'];
+
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), $path['alias'], 'Basic alias lookup works.');
+    $this->assertEqual($this->aliasManager->getSystemPath($path['alias']), $path['source'], 'Basic source lookup works.');
+
+    // Create a language specific alias for the default language (English).
+    $path = array(
+      'source' => 'user/1',
+      'alias' => 'users/Dries',
+    );
+    $lookups['en'][$path['alias']] = $path['source'];
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), $path['alias'], 'English alias overrides language-neutral alias.');
+    $this->assertEqual($this->aliasManager->getSystemPath($path['alias']), $path['source'], 'English source overrides language-neutral source.');
+
+    // Create a language-neutral alias for the same path, again.
+    $path = array(
+      'source' => "user/1",
+      'alias' => 'bar',
+    );
+
+    $lookups[LANGUAGE_NOT_SPECIFIED][$path['alias']] = $path['source'];
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), "users/Dries", 'English alias still returned after entering a language-neutral alias.');
+
+    // Create a language-specific (xx-lolspeak) alias for the same path.
+    $path = array(
+      'source' => "user/1",
+      'alias' => 'LOL',
+      'langcode' => 'xx-lolspeak',
+    );
+    $lookups['xx-lolspeak'][$path['alias']] = $path['source'];
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), "users/Dries", 'English alias still returned after entering a LOLspeak alias.');
+    // The LOLspeak alias should be returned if we really want LOLspeak.
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source'], 'xx-lolspeak'), 'LOL', 'LOLspeak alias returned if we specify xx-lolspeak to the alias manager.');
+
+    // Create a new alias for this path in English, which should override the
+    // previous alias for "user/1".
+    $path = array(
+      'source' => "user/1",
+      'alias' => 'users/my-new-path',
+      'langcode' => 'en',
+    );
+    $lookups['en'][$path['alias']] = $path['source'];
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), $path['alias'], 'Recently created English alias returned.');
+    $this->assertEqual($this->aliasManager->getSystemPath($path['alias']), $path['source'], 'Recently created English source returned.');
+
+    // Remove the English aliases, which should cause a fallback to the most
+    // recently created language-neutral alias, 'bar'.
+    unset($lookups['en']);
+
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getPathAlias($path['source']), 'bar', 'Path lookup falls back to recently created language-neutral alias.');
+
+    // Test the situation where the alias and language are the same, but
+    // the source differs. The newer alias record should be returned.
+    $lookups[LANGUAGE_NOT_SPECIFIED]['bar'] = 'user/2';
+    $this->aliasManager->preloadPathLookups($lookups);
+    $this->assertEqual($this->aliasManager->getSystemPath('bar'), 'user/2', 'Newer alias record is returned when comparing two LANGUAGE_NOT_SPECIFIED paths with the same alias.');
+  }
+}
