diff --git a/core/lib/Drupal/Core/Routing/PathBasedGeneratorInterface.php b/core/lib/Drupal/Core/Routing/PathBasedGeneratorInterface.php
index 5c91e62..79ed373 100644
--- a/core/lib/Drupal/Core/Routing/PathBasedGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Routing/PathBasedGeneratorInterface.php
@@ -30,6 +30,20 @@
   public function generateFromPath($path = NULL, $options = array());
 
   /**
+   * Gets the internal path of a route.
+   *
+   * @param string $name
+   *  The route name.
+   * @param array $parameters
+   *  An array of parameters as passed to
+   *  \Symfony\Component\Routing\Generator\UrlGeneratorInterface::generate().
+   *
+   * @return string
+   *  The internal Drupal path corresponding to the route.
+   */
+  public function getPathFromRoute($name, $parameters = array());
+
+  /**
    * Sets the $request property.
    *
    * @param \Symfony\Component\HttpFoundation\Request $request
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index 972058a..a7b6637 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -105,17 +105,29 @@ public function setRequest(Request $request) {
   }
 
   /**
-   * Implements Symfony\Component\Routing\Generator\UrlGeneratorInterface::generate().
+   * {@inheritdoc}
    */
-  public function generate($name, $parameters = array(), $absolute = FALSE) {
-
-    if ($name instanceof SymfonyRoute) {
-      $route = $name;
-    }
-    elseif (NULL === $route = $this->provider->getRouteByName($name, $parameters)) {
-      throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
-    }
+  public function getPathFromRoute($name, $parameters = array()) {
+    $route = $this->getRoute($name, $parameters);
+    $path = $this->getUrlPathFromRoute($route, $parameters);
+    // Remove any leading or trailing "/". They should not be present in an
+    // internal Drupal path.
+    return trim($path, '/');
+  }
 
+  /**
+   * Gets the path of a route.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *  The route object.
+   * @param array $parameters
+   *  An array of parameters as passed to
+   *  \Symfony\Component\Routing\Generator\UrlGeneratorInterface::generate().
+   *
+   * @return string
+   *  The url path corresponding to the route, without the base path.
+   */
+  protected function getUrlPathFromRoute(SymfonyRoute $route, $parameters = array()) {
     // The Route has a cache of its own and is not recompiled as long as it does
     // not get modified.
     $compiledRoute = $route->compile();
@@ -125,7 +137,6 @@ public function generate($name, $parameters = array(), $absolute = FALSE) {
     // We need to bypass the doGenerate() method's handling of absolute URLs as
     // we handle that ourselves after processing the path.
     if (isset($route_requirements['_scheme'])) {
-      $scheme_req = $route_requirements['_scheme'];
       unset($route_requirements['_scheme']);
     }
     $path = $this->doGenerate($compiledRoute->getVariables(), $route->getDefaults(), $route_requirements, $compiledRoute->getTokens(), $parameters, $name, FALSE, $hostTokens);
@@ -138,7 +149,17 @@ public function generate($name, $parameters = array(), $absolute = FALSE) {
       $path = substr($path, strlen($base_url));
     }
 
-    $path = $this->processPath($path);
+    return $this->processPath($path);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function generate($name, $parameters = array(), $absolute = FALSE) {
+    $route = $this->getRoute($name, $parameters);
+    $path = $this->getUrlPathFromRoute($route, $parameters);
+
+    $base_url = $this->context->getBaseUrl();
     if (!$absolute || !$host = $this->context->getHost()) {
       return $base_url . $path;
     }
@@ -146,6 +167,7 @@ public function generate($name, $parameters = array(), $absolute = FALSE) {
     // Prepare an absolute URL by getting the correct scheme, host and port from
     // the request context.
     $scheme = $this->context->getScheme();
+    $scheme_req = $route->getRequirement('_scheme');
     if (isset($scheme_req) && ($req = strtolower($scheme_req)) && $scheme !== $req) {
       $scheme = $req;
     }
@@ -356,4 +378,31 @@ protected function initialized() {
     return isset($this->basePath) && isset($this->baseUrl) && isset($this->scriptPath);
   }
 
+  /**
+   * Find the route using the provided route name (and parameters).
+   *
+   * @param string $name
+   *   The route name to fetch
+   * @param array $parameters
+   *   The parameters as they are passed to the UrlGeneratorInterface::generate
+   *   call.
+   *
+   * @return \Symfony\Component\Routing\Route
+   *   The found route.
+   *
+   * @throws \Symfony\Component\Routing\Exception\RouteNotFoundException
+   *   Thrown if there is no route with that name in this repository.
+   *
+   * @see \Drupal\Core\Routing\RouteProviderInterface
+   */
+  protected function getRoute($name, $parameters) {
+    if ($name instanceof SymfonyRoute) {
+      $route = $name;
+    }
+    elseif (NULL === $route = $this->provider->getRouteByName($name, $parameters)) {
+      throw new RouteNotFoundException(sprintf('Route "%s" does not exist.', $name));
+    }
+    return $route;
+  }
+
 }
diff --git a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
index 079213e..5bca736 100644
--- a/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/UrlGeneratorTest.php
@@ -30,6 +30,11 @@
  */
 class UrlGeneratorTest extends UnitTestCase {
 
+  /**
+   * The url generator to test.
+   *
+   * @var \Drupal\Core\Routing\UrlGenerator
+   */
   protected $generator;
 
   protected $aliasManager;
@@ -47,24 +52,50 @@ function setUp() {
     $routes = new RouteCollection();
     $first_route = new Route('/test/one');
     $second_route = new Route('/test/two/{narf}');
+    $third_route = new Route('/test/two/');
+    $fourth_route = new Route('/test/four', array(), array('_scheme' => 'https'));
     $routes->add('test_1', $first_route);
     $routes->add('test_2', $second_route);
+    $routes->add('test_3', $third_route);
+    $routes->add('test_4', $fourth_route);
 
     // Create a route provider stub.
     $provider = $this->getMockBuilder('Drupal\Core\Routing\RouteProvider')
       ->disableOriginalConstructor()
       ->getMock();
-    $route_name_return_map = array(
-      array('test_1', array(), $first_route),
-      array('test_2', array('narf' => '5'), $second_route),
+    // We need to set up return value maps for both the getRouteByName() and the
+    // getRoutesByNames() method calls on the route provider. The parameters
+    // passed in will be slightly different but based on the same information.
+    $route_name_return_map = $routes_names_return_map = array();
+    $return_map_values = array(
+      array(
+        'route_name' => 'test_1',
+        'parameters' => array(),
+        'return' => $first_route,
+      ),
+      array(
+        'route_name' => 'test_2',
+        'parameters' => array('narf' => '5'),
+        'return' => $second_route,
+      ),
+      array(
+        'route_name' => 'test_3',
+        'parameters' => array(),
+        'return' => $third_route,
+      ),
+      array(
+        'route_name' => 'test_4',
+        'parameters' => array(),
+        'return' => $fourth_route,
+      ),
     );
+    foreach ($return_map_values as $values) {
+      $route_name_return_map[] = array($values['route_name'], $values['parameters'], $values['return']);
+      $routes_names_return_map[] = array(array($values['route_name']), $values['parameters'], $values['return']);
+    }
     $provider->expects($this->any())
       ->method('getRouteByName')
       ->will($this->returnValueMap($route_name_return_map));
-    $routes_names_return_map = array(
-      array(array('test_1'), array(), array($first_route)),
-      array(array('test_2'), array('narf' => '5'), array($second_route)),
-    );
     $provider->expects($this->any())
       ->method('getRoutesByNames')
       ->will($this->returnValueMap($routes_names_return_map));
@@ -73,14 +104,10 @@ function setUp() {
     $alias_manager = $this->getMockBuilder('Drupal\Core\Path\AliasManager')
       ->disableOriginalConstructor()
       ->getMock();
-    $alias_map = array(
-      array('test/one', NULL, 'hello/world'),
-      array('test/two/5', NULL, 'goodbye/cruel/world'),
-      array('node/123', NULL, 'node/123'),
-    );
+
     $alias_manager->expects($this->any())
       ->method('getPathAlias')
-      ->will($this->returnValueMap($alias_map));
+      ->will($this->returnCallback(array($this, 'aliasManagerCallback')));
 
     $this->aliasManager = $alias_manager;
 
@@ -100,11 +127,47 @@ function setUp() {
   }
 
   /**
+   * Return value callback for the getPathAlias() method on the mock alias manager.
+   *
+   * Ensures that by default the call to getPathAlias() will return the first argument
+   * that was passed in. We special-case the paths for which we wish it to return an
+   * actual alias.
+   *
+   * @return string
+   */
+  public function aliasManagerCallback() {
+    $args = func_get_args();
+    switch($args[0]) {
+      case 'test/one':
+        return 'hello/world';
+      case 'test/two/5':
+        return 'goodbye/cruel/world';
+      case '<front>':
+        return '';
+      default:
+        return $args[0];
+    }
+  }
+
+  /**
    * Confirms that generated routes will have aliased paths.
    */
   public function testAliasGeneration() {
     $url = $this->generator->generate('test_1');
     $this->assertEquals('/hello/world', $url);
+
+    $path = $this->generator->getPathFromRoute('test_1');
+    $this->assertEquals('hello/world', $path);
+  }
+
+  /**
+   * Tests URL generation in a subdirectory.
+   */
+  public function testGetPathFromRouteWithSubdirectory() {
+    $this->generator->setBasePath('/test-base-path');
+
+    $path = $this->generator->getPathFromRoute('test_1');
+    $this->assertEquals('hello/world', $path);
   }
 
   /**
@@ -113,6 +176,17 @@ public function testAliasGeneration() {
   public function testAliasGenerationWithParameters() {
     $url = $this->generator->generate('test_2', array('narf' => '5'));
     $this->assertEquals('/goodbye/cruel/world', $url, 'Correct URL generated including alias and parameters.');
+
+    $path = $this->generator->getPathFromRoute('test_2', array('narf' => '5'));
+    $this->assertEquals('goodbye/cruel/world', $path);
+  }
+
+  /**
+   * Tests URL generation from route with trailing start and end slashes.
+   */
+  public function testGetPathFromRouteTrailing() {
+    $path = $this->generator->getPathFromRoute('test_3');
+    $this->assertEquals($path, 'test/two');
   }
 
   /**
@@ -124,6 +198,14 @@ public function testAbsoluteURLGeneration() {
   }
 
   /**
+   * Test that the 'scheme' route requirement is respected during url generation.
+   */
+  public function testUrlGenerationWithHttpsRequirement() {
+    $url = $this->generator->generate('test_4', array(), TRUE);
+    $this->assertEquals('https://localhost/test/four', $url);
+  }
+
+  /**
    * Tests path-based URL generation.
    */
   public function testPathBasedURLGeneration() {
@@ -136,7 +218,6 @@ public function testPathBasedURLGeneration() {
       foreach (array(FALSE, TRUE) as $absolute) {
         // Get the expected start of the path string.
         $base = ($absolute ? $base_url . '/' : $base_path . '/') . $script_path;
-        $absolute_string = $absolute ? 'absolute' : NULL;
         $url = $base . 'node/123';
         $result = $this->generator->generateFromPath('node/123', array('absolute' => $absolute));
         $this->assertEquals($url, $result, "$url == $result");
