diff --git a/core/modules/views/src/Form/ViewsExposedForm.php b/core/modules/views/src/Form/ViewsExposedForm.php
index 72f754b..a3bcd1c 100644
--- a/core/modules/views/src/Form/ViewsExposedForm.php
+++ b/core/modules/views/src/Form/ViewsExposedForm.php
@@ -11,7 +11,9 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 use Drupal\views\ExposedFormCache;
+use Drupal\views\Plugin\views\display\DisplayRouterInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -115,7 +117,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#id' => drupal_html_id('edit-submit-' . $view->storage->id()),
     );
 
-    $form['#action'] = _url($view->display_handler->getUrl());
+    $form['#action'] = $view->display_handler instanceof DisplayRouterInterface ? $view->getUrl()->toString() : Url::fromRoute('<current>');
     $form['#theme'] = $view->buildThemeFunctions('views_exposed_form');
     $form['#id'] = Html::cleanCssIdentifier('views_exposed_form-' . String::checkPlain($view->storage->id()) . '-' . String::checkPlain($display['id']));
 
diff --git a/core/modules/views/src/Form/ViewsForm.php b/core/modules/views/src/Form/ViewsForm.php
index c1296b2..8ad7c2d 100644
--- a/core/modules/views/src/Form/ViewsForm.php
+++ b/core/modules/views/src/Form/ViewsForm.php
@@ -133,7 +133,7 @@ public function buildForm(array $form, FormStateInterface $form_state, ViewExecu
     $query = $this->requestStack->getCurrentRequest()->query->all();
     $query = UrlHelper::filterQueryParameters($query, array(), '');
 
-    $form['#action'] = $this->urlGenerator->generateFromPath($view->getUrl(), array('query' => $query));
+    $form['#action'] = $view->getUrl()->setOption('query', $query)->toString();
     // Tell the preprocessor whether it should hide the header, footer, pager...
     $form['show_view_elements'] = array(
       '#type' => 'value',
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index ac4d9ba..1171a86 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -742,7 +742,7 @@ public function getPath() {
    * {@inheritdoc}
    */
   public function getUrl() {
-    return $this->view->getUrl();
+    return $this->view->getUrl(NULL, $this->display['id']);
   }
 
   /**
@@ -2019,27 +2019,26 @@ public function renderPager() {
    */
   public function renderMoreLink() {
     if ($this->isMoreEnabled() && ($this->useMoreAlways() || (!empty($this->view->pager) && $this->view->pager->hasMoreRecords()))) {
-      $path = $this->getPath();
-
       if ($this->getOption('link_display') == 'custom_url' && $override_path = $this->getOption('link_url')) {
         $tokens = $this->getArgumentsTokens();
         $path = $this->viewsTokenReplace($override_path, $tokens);
+        $url = Url::fromUri('user-path:' . $path);
+      }
+      else {
+        $url = $this->view->getUrl(NULL, $this->display['id']);
       }
 
-      if ($path) {
-        if (empty($override_path)) {
-          $path = $this->view->getUrl(NULL, $path);
-        }
+      if ($url) {
         $url_options = array();
         if (!empty($this->view->exposed_raw_input)) {
           $url_options['query'] = $this->view->exposed_raw_input;
         }
+        $url->setOptions($url_options);
         $theme = $this->view->buildThemeFunctions('views_more');
-        $path = check_url(_url($path, $url_options));
 
         return array(
           '#theme' => $theme,
-          '#more_url' => $path,
+          '#more_url' => $url->toString(),
           '#link_text' => String::checkPlain($this->useMoreText()),
           '#view' => $this->view,
         );
diff --git a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
index 6223c52..e0bc92f 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayRouterInterface.php
@@ -46,4 +46,12 @@ public function alterRoutes(RouteCollection $collection);
    */
   public function getUrlInfo();
 
+  /**
+   * Returns the route name for the display.
+   *
+   * @return string
+   *   The name of the route
+   */
+  public function getRouteName();
+
 }
diff --git a/core/modules/views/src/Plugin/views/display/Feed.php b/core/modules/views/src/Plugin/views/display/Feed.php
index 67171ab..268b75a 100644
--- a/core/modules/views/src/Plugin/views/display/Feed.php
+++ b/core/modules/views/src/Plugin/views/display/Feed.php
@@ -268,7 +268,7 @@ public function attachTo(ViewExecutable $clone, $display_id, array &$build) {
     $clone->setDisplay($this->display['id']);
     $clone->buildTitle();
     if ($plugin = $clone->display_handler->getPlugin('style')) {
-      $plugin->attachTo($build, $display_id, $this->getPath(), $clone->getTitle());
+      $plugin->attachTo($build, $display_id, $clone->getTitle());
       foreach ($clone->feedIcons as $feed_icon) {
         $this->view->feedIcons[] = $feed_icon;
       }
diff --git a/core/modules/views/src/Plugin/views/display/PathPluginBase.php b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
index 7738933..9f82edd 100644
--- a/core/modules/views/src/Plugin/views/display/PathPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/PathPluginBase.php
@@ -490,11 +490,20 @@ public function validate() {
    * {@inheritdoc}
    */
   public function getUrlInfo() {
-    if (strpos($this->getOption('path'), '%') !== FALSE) {
-      throw new \InvalidArgumentException('No placeholders supported yet.');
-    }
-
-    return Url::fromRoute($this->getRoute($this->view->storage->id(), $this->display['id']));
+    return Url::fromRoute($this->getRouteName());
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getRouteName() {
+    $view_id = $this->view->storage->id();
+    $display_id = $this->display['id'];
+    $view_route_key = "$view_id.$display_id";
+
+    // Check for overridden route names.
+    $view_route_names = $this->state->get('views.view_route_names') ?: array();
+
+    return (isset($view_route_names[$view_route_key]) ? $view_route_names[$view_route_key] : "views.$view_route_key");
+  }
 }
diff --git a/core/modules/views/src/Plugin/views/row/RssFields.php b/core/modules/views/src/Plugin/views/row/RssFields.php
index 6d0ae5b..6e7a2bc 100644
--- a/core/modules/views/src/Plugin/views/row/RssFields.php
+++ b/core/modules/views/src/Plugin/views/row/RssFields.php
@@ -8,6 +8,7 @@
 namespace Drupal\views\Plugin\views\row;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 
 /**
  * Renders an RSS item based on fields.
@@ -143,7 +144,7 @@ public function render($row) {
     // Create the RSS item object.
     $item = new \stdClass();
     $item->title = $this->getField($row_index, $this->options['title_field']);
-    $item->link = _url($this->getField($row_index, $this->options['link_field']), array('absolute' => TRUE));
+    $item->link = Url::fromUri('user-path:' . $this->getField($row_index, $this->options['link_field']))->setAbsolute()->toString();
     $item->description = $this->getField($row_index, $this->options['description_field']);
     $item->elements = array(
       array('key' => 'pubDate', 'value' => $this->getField($row_index, $this->options['date_field'])),
@@ -157,7 +158,7 @@ public function render($row) {
     $item_guid = $this->getField($row_index, $this->options['guid_field_options']['guid_field']);
     if ($this->options['guid_field_options']['guid_field_is_permalink']) {
       $guid_is_permalink_string = 'true';
-      $item_guid = _url($item_guid, array('absolute' => TRUE));
+      $item_guid = Url::fromUri('user-path:' . $item_guid)->setAbsolute()->toString();
     }
     $item->elements[] = array(
       'key' => 'guid',
diff --git a/core/modules/views/src/Plugin/views/style/Opml.php b/core/modules/views/src/Plugin/views/style/Opml.php
index f41378f..2cbaac7 100644
--- a/core/modules/views/src/Plugin/views/style/Opml.php
+++ b/core/modules/views/src/Plugin/views/style/Opml.php
@@ -32,7 +32,7 @@ class Opml extends StylePluginBase {
   /**
    * {@inheritdoc}
    */
-  public function attachTo(array &$build, $display_id, $path, $title) {
+  public function attachTo(array &$build, $display_id, $title) {
     $display = $this->view->displayHandlers->get($display_id);
     $url_options = array();
     $input = $this->view->getExposedInput();
@@ -41,7 +41,7 @@ public function attachTo(array &$build, $display_id, $path, $title) {
     }
     $url_options['absolute'] = TRUE;
 
-    $url = _url($this->view->getUrl(NULL, $path), $url_options);
+    $url = $this->view->getUrl(NULL, $display_id)->setOptions($url_options)->toString();
     if ($display->hasPath()) {
       if (empty($this->preview)) {
         $build['#attached']['feed'][] = array($url, $title);
diff --git a/core/modules/views/src/Plugin/views/style/Rss.php b/core/modules/views/src/Plugin/views/style/Rss.php
index f597116..f8ac810 100644
--- a/core/modules/views/src/Plugin/views/style/Rss.php
+++ b/core/modules/views/src/Plugin/views/style/Rss.php
@@ -32,7 +32,7 @@ class Rss extends StylePluginBase {
    */
   protected $usesRowPlugin = TRUE;
 
-  public function attachTo(array &$build, $display_id, $path, $title) {
+  public function attachTo(array &$build, $display_id, $title) {
     $url_options = array();
     $input = $this->view->getExposedInput();
     if ($input) {
@@ -40,7 +40,7 @@ public function attachTo(array &$build, $display_id, $path, $title) {
     }
     $url_options['absolute'] = TRUE;
 
-    $url = _url($this->view->getUrl(NULL, $path), $url_options);
+    $url = $this->view->getUrl(NULL, $display_id)->setOptions($url_options)->toString();
 
     // Add the RSS icon to the view.
     $this->view->feedIcons[] = [
diff --git a/core/modules/views/src/Tests/Handler/FilterEqualityTest.php b/core/modules/views/src/Tests/Handler/FilterEqualityTest.php
index fb9300d..947861f 100644
--- a/core/modules/views/src/Tests/Handler/FilterEqualityTest.php
+++ b/core/modules/views/src/Tests/Handler/FilterEqualityTest.php
@@ -71,6 +71,8 @@ public function testEqualGroupedExposed() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Name, Operator: =, Value: Ringo
     $filters['name']['group_info']['default_group'] = 1;
@@ -124,6 +126,8 @@ public function testEqualGroupedNotExposed() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Name, Operator: !=, Value: Ringo
     $filters['name']['group_info']['default_group'] = 2;
diff --git a/core/modules/views/src/Tests/Handler/FilterNumericTest.php b/core/modules/views/src/Tests/Handler/FilterNumericTest.php
index 9277da5..2ea154a 100644
--- a/core/modules/views/src/Tests/Handler/FilterNumericTest.php
+++ b/core/modules/views/src/Tests/Handler/FilterNumericTest.php
@@ -75,6 +75,8 @@ public function testFilterNumericExposedGroupedSimple() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Age, Operator: =, Value: 28
     $filters['age']['group_info']['default_group'] = 1;
@@ -168,6 +170,8 @@ public function testFilterNumericExposedGroupedBetween() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Age, Operator: between, Value: 26 and 29
     $filters['age']['group_info']['default_group'] = 2;
@@ -196,6 +200,8 @@ public function testFilterNumericExposedGroupedNotBetween() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Age, Operator: between, Value: 26 and 29
     $filters['age']['group_info']['default_group'] = 3;
@@ -284,6 +290,8 @@ public function testFilterNumericExposedGroupedEmpty() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Age, Operator: empty, Value:
     $filters['age']['group_info']['default_group'] = 4;
@@ -300,6 +308,8 @@ public function testFilterNumericExposedGroupedNotEmpty() {
     $filters = $this->getGroupedExposedFilters();
     $view = Views::getView('test_view');
     $view->newDisplay('page', 'Page', 'page_1');
+    $view->save();
+    $view->destroy();
 
     // Filter: Age, Operator: empty, Value:
     $filters['age']['group_info']['default_group'] = 5;
diff --git a/core/modules/views/src/Tests/TokenReplaceTest.php b/core/modules/views/src/Tests/TokenReplaceTest.php
index f3f0028..d4bcc67 100644
--- a/core/modules/views/src/Tests/TokenReplaceTest.php
+++ b/core/modules/views/src/Tests/TokenReplaceTest.php
@@ -28,6 +28,7 @@ class TokenReplaceTest extends ViewUnitTestBase {
   protected function setUp() {
     parent::setUp();
     $this->installSchema('system', 'url_alias');
+    $this->container->get('router.builder')->rebuild();
   }
 
   /**
@@ -44,7 +45,7 @@ function testTokenReplacement() {
       '[view:description]' => 'Test view to token replacement tests.',
       '[view:id]' => 'test_tokens',
       '[view:title]' => 'Test token page',
-      '[view:url]' => $view->getUrlInfo('page_1')->setAbsolute(TRUE)->toString(),
+      '[view:url]' => $view->getUrl(NULL, 'page_1')->setAbsolute(TRUE)->toString(),
       '[view:total-rows]' => (string) $view->total_rows,
       '[view:base-table]' => 'views_test_data',
       '[view:base-field]' => 'id',
diff --git a/core/modules/views/src/Tests/ViewExecutableTest.php b/core/modules/views/src/Tests/ViewExecutableTest.php
index 8492790..c5a1bc4 100644
--- a/core/modules/views/src/Tests/ViewExecutableTest.php
+++ b/core/modules/views/src/Tests/ViewExecutableTest.php
@@ -319,18 +319,6 @@ public function testPropertyMethods() {
     $view->override_path = $override_path;
     $this->assertEqual($view->getPath(), $override_path);
 
-    // Test the getUrl method().
-    $url = 'foo';
-    $this->assertEqual($view->getUrl(NULL, $url), $url);
-    // Test with arguments.
-    $arg1 = 'bar';
-    $arg2 = 12345;
-    $this->assertEqual($view->getUrl(array($arg1, $arg2), $url), "$url/$arg1/$arg2");
-    // Test the override_url property override.
-    $override_url = 'baz';
-    $view->override_url = $override_url;
-    $this->assertEqual($view->getUrl(NULL, $url), $override_url);
-
     // Test the title methods.
     $title = $this->randomString();
     $view->setTitle($title);
diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php
index 64ba659..0db2973 100644
--- a/core/modules/views/src/ViewExecutable.php
+++ b/core/modules/views/src/ViewExecutable.php
@@ -10,7 +10,9 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
 use Drupal\Core\Form\FormState;
+use Drupal\Core\Routing\RouteProviderInterface;
 use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
 use Drupal\views\Plugin\views\display\DisplayRouterInterface;
 use Drupal\views\Plugin\views\query\QueryPluginBase;
 use Drupal\views\ViewEntityInterface;
@@ -239,9 +241,9 @@ class ViewExecutable {
   /**
    * Allow to override the url of the current view.
    *
-   * @var string
+   * @var \Drupal\Core\Url
    */
-  public $override_url = NULL;
+  public $override_url;
 
   /**
    * Allow to override the path used for generated urls.
@@ -426,6 +428,13 @@ class ViewExecutable {
   protected $viewsData;
 
   /**
+   * The route provider.
+   *
+   * @var \Drupal\Core\Routing\RouteProviderInterface
+   */
+  protected $routeProvider;
+
+  /**
    * Constructs a new ViewExecutable object.
    *
    * @param \Drupal\views\ViewEntityInterface $storage
@@ -434,13 +443,16 @@ class ViewExecutable {
    *   The current user.
    * @param \Drupal\views\ViewsData $views_data
    *   The views data.
+   * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
+   *   The route provider.
    */
-  public function __construct(ViewEntityInterface $storage, AccountInterface $user, ViewsData $views_data) {
+  public function __construct(ViewEntityInterface $storage, AccountInterface $user, ViewsData $views_data, RouteProviderInterface $route_provider) {
     // Reference the storage and the executable to each other.
     $this->storage = $storage;
     $this->storage->set('executable', $this);
     $this->user = $user;
     $this->viewsData = $views_data;
+    $this->routeProvider = $route_provider;
 
     // Add the default css for a view.
     $this->element['#attached']['library'][] = 'views/views.module';
@@ -1696,8 +1708,15 @@ public function buildTitle() {
    * Get the URL for the current view.
    *
    * This URL will be adjusted for arguments.
+   *
+   * @param array $args
+   *   (optional) Passed in arguments.
+   * @param string $display_id
+   *   (optional) Specify the display ID to link to, fallback to the current ID.
+   *
+   * @return \Drupal\Core\Url
    */
-  public function getUrl($args = NULL, $path = NULL) {
+  public function getUrl($args = NULL, $display_id = NULL) {
     if (!empty($this->override_url)) {
       return $this->override_url;
     }
@@ -1705,6 +1724,12 @@ public function getUrl($args = NULL, $path = NULL) {
     if (!isset($path)) {
       $path = $this->getPath();
     }
+
+    $display_handler = $this->displayHandlers->get($display_id ?: $this->current_display);
+    if (!$display_handler instanceof DisplayRouterInterface) {
+      throw new \InvalidArgumentException('You cannot create a URL to a display without routes.');
+    }
+
     if (!isset($args)) {
       $args = $this->args;
 
@@ -1721,41 +1746,41 @@ public function getUrl($args = NULL, $path = NULL) {
     }
     // Don't bother working if there's nothing to do:
     if (empty($path) || (empty($args) && strpos($path, '%') === FALSE)) {
-      return $path;
+      return $display_handler->getUrlInfo();
     }
 
-    $pieces = array();
     $argument_keys = isset($this->argument) ? array_keys($this->argument) : array();
     $id = current($argument_keys);
-    foreach (explode('/', $path) as $piece) {
-      if ($piece != '%') {
-        $pieces[] = $piece;
-      }
-      else {
-        if (empty($args)) {
-          // Try to never put % in a url; use the wildcard instead.
-          if ($id && !empty($this->argument[$id]->options['exception']['value'])) {
-            $pieces[] = $this->argument[$id]->options['exception']['value'];
-          }
-          else {
-            $pieces[] = '*'; // gotta put something if there just isn't one.
-          }
 
+    /** @var \Drupal\Core\Url $url */
+    $url = $display_handler->getUrlInfo();
+    $route = $this->routeProvider->getRouteByName($url->getRouteName());
+
+    $variables = $route->compile()->getVariables();
+    $parameters = $url->getRouteParameters();
+
+    foreach ($variables as $variable_name) {
+      if (empty($args)) {
+        // Try to never put % in a url; use the wildcard instead.
+        if ($id && !empty($this->argument[$id]->options['exception']['value'])) {
+          $parameters[$variable_name] = $this->argument[$id]->options['exception']['value'];
         }
         else {
-          $pieces[] = array_shift($args);
+          // Gotta put something if there just isn't one.
+          $parameters[$variable_name] = '*';
         }
+      }
+      else {
+        $parameters[$variable_name] = array_shift($args);
+      }
 
-        if ($id) {
-          $id = next($argument_keys);
-        }
+      if ($id) {
+        $id = next($argument_keys);
       }
     }
 
-    if (!empty($args)) {
-      $pieces = array_merge($pieces, $args);
-    }
-    return implode('/', $pieces);
+    $url->setRouteParameters($parameters);
+    return $url;
   }
 
   /**
diff --git a/core/modules/views/src/ViewExecutableFactory.php b/core/modules/views/src/ViewExecutableFactory.php
index 04f6196..0975a48 100644
--- a/core/modules/views/src/ViewExecutableFactory.php
+++ b/core/modules/views/src/ViewExecutableFactory.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views;
 
+use Drupal\Core\Routing\RouteProviderInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\views\ViewEntityInterface;
 use Symfony\Component\HttpFoundation\RequestStack;
@@ -38,6 +39,13 @@ class ViewExecutableFactory {
   protected $viewsData;
 
   /**
+   * The route provider.
+   *
+   * @var \Drupal\Core\Routing\RouteProviderInterface
+   */
+  protected $routeProvider;
+
+  /**
    * Constructs a new ViewExecutableFactory
    *
    * @param \Drupal\Core\Session\AccountInterface $user
@@ -46,11 +54,14 @@ class ViewExecutableFactory {
    *   The request stack.
    * @param \Drupal\views\ViewsData $views_data
    *   The views data.
+   * @param \Drupal\Core\Routing\RouteProviderInterface $route_provider
+   *   The route provider.
    */
-  public function __construct(AccountInterface $user, RequestStack $request_stack, ViewsData $views_data) {
+  public function __construct(AccountInterface $user, RequestStack $request_stack, ViewsData $views_data, RouteProviderInterface $route_provider) {
     $this->user = $user;
     $this->requestStack = $request_stack;
     $this->viewsData = $views_data;
+    $this->routeProvider = $route_provider;
   }
 
   /**
@@ -63,7 +74,7 @@ public function __construct(AccountInterface $user, RequestStack $request_stack,
    *   A ViewExecutable instance.
    */
   public function get(ViewEntityInterface $view) {
-    $view = new ViewExecutable($view, $this->user, $this->viewsData);
+    $view = new ViewExecutable($view, $this->user, $this->viewsData, $this->routeProvider);
     $view->setRequest($this->requestStack->getCurrentRequest());
     return $view;
   }
diff --git a/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php b/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php
index a289d8e..87c79a3d 100644
--- a/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php
+++ b/core/modules/views/tests/src/Unit/Plugin/area/ResultTest.php
@@ -46,7 +46,8 @@ protected function setUp() {
     $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
       ->disableOriginalConstructor()
       ->getMock();
-    $this->view = new ViewExecutable($storage, $user, $views_data);
+    $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+    $this->view = new ViewExecutable($storage, $user, $views_data, $route_provider);
 
     $this->resultHandler = new Result(array(), 'result', array());
     $this->resultHandler->view = $this->view;
diff --git a/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php b/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php
index 959ce3d..7b0c14d 100644
--- a/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php
+++ b/core/modules/views/tests/src/Unit/Plugin/field/CounterTest.php
@@ -75,7 +75,8 @@ protected function setUp() {
     $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
       ->disableOriginalConstructor()
       ->getMock();
-    $this->view = $this->getMock('Drupal\views\ViewExecutable', NULL, array($storage, $user, $views_data));
+    $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+    $this->view = $this->getMock('Drupal\views\ViewExecutable', NULL, array($storage, $user, $views_data, $route_provider));
 
     $this->display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
       ->disableOriginalConstructor()
diff --git a/core/modules/views/tests/src/Unit/ViewExecutableFactoryTest.php b/core/modules/views/tests/src/Unit/ViewExecutableFactoryTest.php
index e82468e..17b61c8 100644
--- a/core/modules/views/tests/src/Unit/ViewExecutableFactoryTest.php
+++ b/core/modules/views/tests/src/Unit/ViewExecutableFactoryTest.php
@@ -54,6 +54,13 @@ class ViewExecutableFactoryTest extends UnitTestCase {
   protected $viewsData;
 
   /**
+   * The mocked route provider.
+   *
+   * @var \Drupal\Core\Routing\RouteProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $routeProvider;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
@@ -65,7 +72,8 @@ protected function setUp() {
     $this->viewsData = $this->getMockBuilder('Drupal\views\ViewsData')
       ->disableOriginalConstructor()
       ->getMock();
-    $this->viewExecutableFactory = new ViewExecutableFactory($this->user, $this->requestStack, $this->viewsData);
+    $this->routeProvider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+    $this->viewExecutableFactory = new ViewExecutableFactory($this->user, $this->requestStack, $this->viewsData, $this->routeProvider);
   }
 
   /**
diff --git a/core/modules/views/tests/src/Unit/ViewExecutableUnitTest.php b/core/modules/views/tests/src/Unit/ViewExecutableUnitTest.php
deleted file mode 100644
index ecabe3f..0000000
--- a/core/modules/views/tests/src/Unit/ViewExecutableUnitTest.php
+++ /dev/null
@@ -1,304 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\Tests\views\Unit\ViewExecutableUnitTest.
- */
-
-namespace Drupal\Tests\views\Unit;
-
-use Drupal\Tests\UnitTestCase;
-use Drupal\views\Entity\View;
-use Drupal\views\ViewExecutable;
-use Symfony\Component\DependencyInjection\ContainerBuilder;
-
-/**
- * @coversDefaultClass \Drupal\views\ViewExecutable
- * @group views
- */
-class ViewExecutableUnitTest extends UnitTestCase {
-
-  /**
-   * The mocked views data.
-   *
-   * @var \Drupal\views\ViewsData|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $viewsData;
-
-  /**
-   * The mocked user.
-   *
-   * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $user;
-
-  /**
-   * A mocked display collection.
-   *
-   * @var \Drupal\views\DisplayPluginCollection|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $displayCollection;
-
-  /**
-   * The mocked view executable.
-   *
-   * @var \Drupal\views\ViewExecutableFactory|\PHPUnit_Framework_MockObject_MockObject
-   */
-  protected $viewExecutableFactory;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-
-    $this->viewsData = $this->getMockBuilder('Drupal\views\ViewsData')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $this->user = $this->getMock('Drupal\Core\Session\AccountInterface');
-
-    $this->displayCollection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $this->viewExecutableFactory = $this->getMockBuilder('Drupal\views\ViewExecutableFactory')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $translation = $this->getStringTranslationStub();
-    $container = new ContainerBuilder();
-    $container->set('string_translation', $translation);
-    $container->set('views.executable', $this->viewExecutableFactory);
-    \Drupal::setContainer($container);
-  }
-
-  /**
-   * Tests the buildThemeFunctions() method.
-   */
-  public function testBuildThemeFunctions() {
-    /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
-    /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase|\PHPUnit_Framework_MockObject_MockObject $display */
-    list($view, $display) = $this->setupBaseViewAndDisplay();
-
-    unset($view->display_handler);
-    $expected = array(
-      'test_hook__test_view',
-      'test_hook'
-    );
-    $this->assertEquals($expected, $view->buildThemeFunctions('test_hook'));
-
-    $view->display_handler = $display;
-    $expected = array(
-      'test_hook__test_view__default',
-      'test_hook__default',
-      'test_hook__one',
-      'test_hook__two',
-      'test_hook__and_three',
-      'test_hook__test_view',
-      'test_hook'
-    );
-    $this->assertEquals($expected, $view->buildThemeFunctions('test_hook'));
-
-    //Change the name of the display plugin and make sure that is in the array.
-    $view->display_handler->display['display_plugin'] = 'default2';
-
-    $expected = array(
-      'test_hook__test_view__default',
-      'test_hook__default',
-      'test_hook__one',
-      'test_hook__two',
-      'test_hook__and_three',
-      'test_hook__test_view__default2',
-      'test_hook__default2',
-      'test_hook__test_view',
-      'test_hook'
-    );
-    $this->assertEquals($expected, $view->buildThemeFunctions('test_hook'));
-  }
-
-  /**
-   * Tests the generateHandlerId method().
-   *
-   * @covers ::generateHandlerId()
-   */
-  public function testGenerateHandlerId() {
-    // Test the generateHandlerId() method.
-    $test_ids = ['test' => 'test', 'test_1' => 'test_1'];
-    $this->assertEquals(ViewExecutable::generateHandlerId('new', $test_ids), 'new');
-    $this->assertEquals(ViewExecutable::generateHandlerId('test', $test_ids), 'test_2');
-  }
-
-  /**
-   * Tests the addHandler method().
-   *
-   * @covers ::addHandler()
-   */
-  public function testAddHandler() {
-    /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
-    /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase|\PHPUnit_Framework_MockObject_MockObject $display */
-    list($view, $display) = $this->setupBaseViewAndDisplay();
-
-    $views_data = [];
-    $views_data['test_field'] = [
-      'field' => ['id' => 'standard'],
-      'filter' => ['id' => 'standard'],
-      'argument' => ['id' => 'standard'],
-      'sort' => ['id' => 'standard'],
-    ];
-
-    $this->viewsData->expects($this->atLeastOnce())
-      ->method('get')
-      ->with('test_entity')
-      ->willReturn($views_data);
-
-    foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) {
-      $display->expects($this->atLeastOnce())
-        ->method('setOption')
-        ->with($this->callback(function($argument) {
-          return $argument;
-        }), ['test_field' => [
-          'id' => 'test_field',
-          'table' => 'test_entity',
-          'field' => 'test_field',
-          'plugin_id' => 'standard',
-        ]]);
-    }
-
-    foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) {
-      $view->addHandler('default', $handler_type, 'test_entity', 'test_field');
-    }
-  }
-
-  /**
-   * Tests the addHandler method() with an entity field.
-   *
-   * @covers ::addHandler()
-   */
-  public function testAddHandlerWithEntityField() {
-    /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
-    /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase|\PHPUnit_Framework_MockObject_MockObject $display */
-    list($view, $display) = $this->setupBaseViewAndDisplay();
-
-    $views_data = [];
-    $views_data['table']['entity type'] = 'test_entity_type';
-    $views_data['test_field'] = [
-      'entity field' => 'test_field',
-      'field' => ['id' => 'standard'],
-      'filter' => ['id' => 'standard'],
-      'argument' => ['id' => 'standard'],
-      'sort' => ['id' => 'standard'],
-    ];
-
-    $this->viewsData->expects($this->atLeastOnce())
-      ->method('get')
-      ->with('test_entity')
-      ->willReturn($views_data);
-
-    foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) {
-      $display->expects($this->atLeastOnce())
-        ->method('setOption')
-        ->with($this->callback(function($argument) {
-          return $argument;
-        }), ['test_field' => [
-          'id' => 'test_field',
-          'table' => 'test_entity',
-          'field' => 'test_field',
-          'entity_type' => 'test_entity_type',
-          'entity_field' => 'test_field',
-          'plugin_id' => 'standard',
-        ]]);
-    }
-
-    foreach (['field', 'filter', 'argument', 'sort'] as $handler_type) {
-      $view->addHandler('default', $handler_type, 'test_entity', 'test_field');
-    }
-  }
-
-  /**
-   * Tests attachDisplays().
-   *
-   * @covers ::attachDisplays()
-   */
-  public function testAttachDisplays() {
-    /** @var \Drupal\views\ViewExecutable|\PHPUnit_Framework_MockObject_MockObject $view */
-    /** @var \Drupal\views\Plugin\views\display\DisplayPluginBase|\PHPUnit_Framework_MockObject_MockObject $display */
-    list($view, $display) = $this->setupBaseViewAndDisplay();
-
-    $display->expects($this->atLeastOnce())
-      ->method('acceptAttachments')
-      ->willReturn(TRUE);
-    $display->expects($this->atLeastOnce())
-      ->method('getAttachedDisplays')
-      ->willReturn(['page_1']);
-
-    $cloned_view = $this->getMockBuilder('Drupal\views\ViewExecutable')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $this->viewExecutableFactory->expects($this->atLeastOnce())
-      ->method('get')
-      ->willReturn($cloned_view);
-
-    $page_display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $display_collection = $this->getMockBuilder('Drupal\views\DisplayPluginCollection')
-      ->disableOriginalConstructor()
-      ->getMock();
-
-    $display_collection->expects($this->atLeastOnce())
-      ->method('get')
-      ->with('page_1')
-      ->willReturn($page_display);
-    $view->displayHandlers = $display_collection;
-
-    // Setup the expectations.
-    $page_display->expects($this->once())
-      ->method('attachTo')
-      ->with($cloned_view, 'default', $view->element);
-
-    $view->attachDisplays();
-  }
-
-  /**
-   * Setups a view executable and default display.
-   *
-   * @return array
-   *   Returns the view executable and default display.
-   */
-  protected function setupBaseViewAndDisplay() {
-    $config = array(
-      'id' => 'test_view',
-      'tag' => 'OnE, TWO, and three',
-      'display' => [
-        'default' => [
-          'id' => 'default',
-          'display_plugin' => 'default',
-          'display_title' => 'Default',
-        ],
-      ],
-    );
-
-    $storage = new View($config, 'view');
-    $view = new ViewExecutable($storage, $this->user, $this->viewsData);
-    $display = $this->getMockBuilder('Drupal\views\Plugin\views\display\DisplayPluginBase')
-      ->disableOriginalConstructor()
-      ->getMock();
-    $display->display = $config['display']['default'];
-
-    $view->current_display = 'default';
-    $view->display_handler = $display;
-    $view->displayHandlers = $this->displayCollection;
-    $view->displayHandlers->expects($this->any())
-      ->method('get')
-      ->with('default')
-      ->willReturn($display);
-    $view->displayHandlers->expects($this->any())
-      ->method('has')
-      ->with('default')
-      ->willReturn(TRUE);
-
-    return array($view, $display);
-  }
-
-}
diff --git a/core/modules/views/tests/src/Unit/ViewsTest.php b/core/modules/views/tests/src/Unit/ViewsTest.php
index ab9bdf8..aa7a8c9 100644
--- a/core/modules/views/tests/src/Unit/ViewsTest.php
+++ b/core/modules/views/tests/src/Unit/ViewsTest.php
@@ -34,7 +34,8 @@ protected function setUp() {
     $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
       ->disableOriginalConstructor()
       ->getMock();
-    $container->set('views.executable', new ViewExecutableFactory($user, $request_stack, $views_data));
+    $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+    $container->set('views.executable', new ViewExecutableFactory($user, $request_stack, $views_data, $route_provider));
 
     $this->view = new View(array('id' => 'test_view'), 'view');
 
diff --git a/core/modules/views/views.services.yml b/core/modules/views/views.services.yml
index f98ad1c..1a01543 100644
--- a/core/modules/views/views.services.yml
+++ b/core/modules/views/views.services.yml
@@ -64,7 +64,7 @@ services:
     arguments: ['@views.views_data']
   views.executable:
     class: Drupal\views\ViewExecutableFactory
-    arguments: ['@current_user', '@request_stack', '@views.views_data']
+    arguments: ['@current_user', '@request_stack', '@views.views_data', '@router.route_provider']
   views.analyzer:
     class: Drupal\views\Analyzer
     arguments: ['@module_handler']
diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc
index 0e70dd4..dc317e2 100644
--- a/core/modules/views/views.theme.inc
+++ b/core/modules/views/views.theme.inc
@@ -294,6 +294,7 @@ function template_preprocess_views_view_field(&$variables) {
  *   - rows: The raw row data.
  */
 function template_preprocess_views_view_summary(&$variables) {
+  /** @var \Drupal\views\ViewExecutable $view */
   $view = $variables['view'];
   $argument = $view->argument[$view->build_info['summary_level']];
 
@@ -331,11 +332,16 @@ function template_preprocess_views_view_summary(&$variables) {
     $args = $view->args;
     $args[$argument->position] = $row_args[$id];
 
-    $base_path = NULL;
     if (!empty($argument->options['summary_options']['base_path'])) {
       $base_path = $argument->options['summary_options']['base_path'];
+      $tokens = $this->getArgumentsTokens();
+      $base_path = $this->viewsTokenReplace($base_path, $tokens);
+      $url = Url::fromUri('user-path:' . $base_path);
     }
-    $variables['rows'][$id]->url = _url($view->getUrl($args, $base_path), $url_options);
+    else {
+      $url = $view->getUrl($args)->setOptions($url_options);
+    }
+    $variables['rows'][$id]->url = $url->toString();
     $variables['rows'][$id]->count = intval($row->{$argument->count_alias});
     if (isset($active_urls[$variables['rows'][$id]->url])) {
       $variables['rows'][$id]->attributes['class'][] = 'active';
@@ -395,11 +401,16 @@ function template_preprocess_views_view_summary_unformatted(&$variables) {
     $args = $view->args;
     $args[$argument->position] = $row_args[$id];
 
-    $base_path = NULL;
     if (!empty($argument->options['summary_options']['base_path'])) {
       $base_path = $argument->options['summary_options']['base_path'];
+      $tokens = $this->getArgumentsTokens();
+      $base_path = $this->viewsTokenReplace($base_path, $tokens);
+      $url = Url::fromUri('user-path:' . $base_path);
+    }
+    else {
+      $url = $view->getUrl($args)->setOptions($url_options);
     }
-    $variables['rows'][$id]->url = _url($view->getUrl($args, $base_path), $url_options);
+    $variables['rows'][$id]->url = $url->toString();
     $variables['rows'][$id]->count = intval($row->{$argument->count_alias});
     if (isset($active_urls[$variables['rows'][$id]->url])) {
       $variables['rows'][$id]->attributes['class'][] = 'active';
@@ -891,11 +902,11 @@ function template_preprocess_views_view_rss(&$variables) {
   // there isn't one, use the global $base_url
   $link_display_id = $view->display_handler->getLinkDisplay();
   if ($link_display_id && $display = $view->displayHandlers->get($link_display_id)) {
-    $path = $view->displayHandlers->get($link_display_id)->getPath();
+    $url = $view->getUrl(NULL, $link_display_id);
   }
 
-  if ($path) {
-    $path = $view->getUrl(NULL, $path);
+  /** @var \Drupal\Core\Url $url */
+  if ($url) {
     $url_options = array('absolute' => TRUE);
     if (!empty($view->exposed_raw_input)) {
       $url_options['query'] = $view->exposed_raw_input;
@@ -903,11 +914,12 @@ function template_preprocess_views_view_rss(&$variables) {
 
     // Compare the link to the default home page; if it's the default home page,
     // just use $base_url.
-    if ($path == $config->get('page.front')) {
-      $path = '';
+    $url_string = $url->setOptions($url_options)->toString();
+    if ($url_string === Url::fromUri('user-path:' . $config->get('page.front'))) {
+      $url_string = Url::fromRoute('<front>')->setAbsolute()->toString();
     }
 
-    $variables['link'] = check_url(_url($path, $url_options));
+    $variables['link'] = $url_string;
   }
 
   $variables['langcode'] = String::checkPlain(\Drupal::languageManager()->getCurrentLanguage()->getId());
@@ -935,7 +947,7 @@ function template_preprocess_views_view_row_rss(&$variables) {
   $item = $variables['row'];
 
   $variables['title'] = String::checkPlain($item->title);
-  $variables['link'] = check_url($item->link);
+  $variables['link'] = $item->link;
   $variables['description'] = String::checkPlain($item->description);
   $variables['item_elements'] = empty($item->elements) ? '' : format_xml_elements($item->elements);
 }
diff --git a/core/modules/views/views.tokens.inc b/core/modules/views/views.tokens.inc
index 4160d85..85f6ec0 100644
--- a/core/modules/views/views.tokens.inc
+++ b/core/modules/views/views.tokens.inc
@@ -80,6 +80,7 @@ function views_tokens($type, $tokens, array $data = array(), array $options = ar
   $replacements = array();
 
   if ($type == 'view' && !empty($data['view'])) {
+    /** @var \Drupal\views\ViewExecutable $view */
     $view = $data['view'];
 
     foreach ($tokens as $name => $original) {
@@ -102,8 +103,8 @@ function views_tokens($type, $tokens, array $data = array(), array $options = ar
           break;
 
         case 'url':
-          if ($path = $view->getUrl()) {
-            $replacements[$original] = _url($path, $url_options);
+          if ($url = $view->getUrl()) {
+            $replacements[$original] = $url->setOptions($url_options)->toString();
           }
           break;
         case 'base-table':
@@ -132,7 +133,7 @@ function views_tokens($type, $tokens, array $data = array(), array $options = ar
     // [view:url:*] nested tokens. This only works if Token module is installed.
     if ($url_tokens = $token_service->findWithPrefix($tokens, 'url')) {
       if ($path = $view->getUrl()) {
-        $replacements += $token_service->generate('url', $url_tokens, array('path' => $path), $options);
+        $replacements += $token_service->generate('url', $url_tokens, array('path' => $url->getInternalPath()), $options);
       }
     }
   }
diff --git a/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php b/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php
index b77f595..a42a879 100644
--- a/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php
+++ b/core/modules/views_ui/tests/src/Unit/ViewListBuilderTest.php
@@ -125,7 +125,8 @@ public function testBuildRowEntityList() {
     $views_data = $this->getMockBuilder('Drupal\views\ViewsData')
       ->disableOriginalConstructor()
       ->getMock();
-    $executable_factory = new ViewExecutableFactory($user, $request_stack, $views_data);
+    $route_provider = $this->getMock('Drupal\Core\Routing\RouteProviderInterface');
+    $executable_factory = new ViewExecutableFactory($user, $request_stack, $views_data, $route_provider);
     $container->set('views.executable', $executable_factory);
     $container->set('plugin.manager.views.display', $display_manager);
     \Drupal::setContainer($container);
