diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index c77ddd0..aa17773 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -18,6 +18,7 @@
 use Drupal\Core\Utility\ThemeRegistry;
 use Drupal\Core\Theme\ThemeSettings;
 use Drupal\Component\Utility\NestedArray;
+use Drupal\Component\Utility\MapArray;
 
 /**
  * @defgroup content_flags Content markers
@@ -1641,8 +1642,6 @@ function template_preprocess_status_messages(&$variables) {
  *     http://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
  */
 function theme_links($variables) {
-  $language_url = language(Language::TYPE_URL);
-
   $links = $variables['links'];
   $attributes = $variables['attributes'];
   $heading = $variables['heading'];
@@ -1677,6 +1676,12 @@ function theme_links($variables) {
     foreach ($links as $key => $link) {
       $i++;
 
+      $link += array(
+        'href' => NULL,
+        'route_name' => NULL,
+        'route_parameters' => NULL,
+      );
+
       $class = array();
       // Use the array key as class name.
       $class[] = drupal_html_class($key);
@@ -1689,31 +1694,42 @@ function theme_links($variables) {
         $class[] = 'last';
       }
 
-      // Handle links.
-      if (isset($link['href'])) {
+      $link_element = array(
+        '#type' => 'link',
+        '#title' => $link['title'],
+        '#options' => array_diff_key($link, MapArray::copyValuesToKeys(array('title', 'href', 'route_name', 'route_parameters'))),
+        '#href' => $link['href'],
+        '#route_name' => $link['route_name'],
+        '#route_parameters' => $link['route_parameters'],
+      );
+
+      // @todo Reconcile Views usage of 'ajax' as a boolean with the rest of
+      //   core's usage of it as an array.
+      if (isset($link['ajax']) && is_array($link['ajax'])) {
+        $link_element['#ajax'] = $link['ajax'];
+      }
+
+      // Handle links and ensure that the active class is added on the LIs.
+      if (isset($link['route_name'])) {
+        $variables = array(
+          'options' => array(),
+        );
+        if (!empty($link['language'])) {
+          $variables['options']['language'] = $link['language'];
+        }
+        if (\Drupal::linkGenerator()->isRouteActive($link['route_name'], $link['route_parameters'], $variables)) {
+          $class[] = 'active';
+        }
+        $item = drupal_render($link_element);
+      }
+      elseif (isset($link['href'])) {
+        $language_url = language(Language::TYPE_URL);
         $is_current_path = ($link['href'] == current_path() || ($link['href'] == '<front>' && drupal_is_front_page()));
         $is_current_language = (empty($link['language']) || $link['language']->id == $language_url->id);
         if ($is_current_path && $is_current_language) {
           $class[] = 'active';
         }
-        // @todo Reconcile Views usage of 'ajax' as a boolean with the rest of
-        //   core's usage of it as an array.
-        if (isset($link['ajax']) && is_array($link['ajax'])) {
-          // To attach Ajax behavior, render a link element, rather than just
-          // call l().
-          $link_element = array(
-            '#type' => 'link',
-            '#title' => $link['title'],
-            '#href' => $link['href'],
-            '#ajax' => $link['ajax'],
-            '#options' => array_diff_key($link, drupal_map_assoc(array('title', 'href', 'ajax'))),
-          );
-          $item = drupal_render($link_element);
-        }
-        else {
-          // Pass in $link as $options, they share the same keys.
-          $item = l($link['title'], $link['href'], $link);
-        }
+        $item = drupal_render($link_element);
       }
       // Handle title-only text items.
       else {
diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index 12dc3d6..d9c2e98 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -119,10 +119,7 @@ public function generate($text, $route_name, array $parameters = array(), array
     // URL path and query string as the current page. Note that this may be
     // removed from l() in https://drupal.org/node/1979468 and would be removed
     // or altered here also.
-    $variables['url_is_active'] = $route_name == $this->active['route_name']
-      // The language of an active link is equal to the current language.
-      && (empty($variables['options']['language']) || $variables['options']['language']->id == $this->active['language'])
-      && $full_parameters == $this->active['parameters'];
+    $variables['url_is_active'] = $this->isRouteActive($route_name, $full_parameters, $variables);
 
     // Add the "active" class if appropriate.
     if ($variables['url_is_active']) {
@@ -152,4 +149,16 @@ public function generate($text, $route_name, array $parameters = array(), array
     return '<a href="' . $url . '"' . $attributes . '>' . $text . '</a>';
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function isRouteActive($route_name, array $route_parameters, array $variables) {
+    $url_is_active = $route_name == $this->active['route_name']
+      // The language of an active link is equal to the current language.
+      && (empty($variables['options']['language']) || $variables['options']['language']->id == $this->active['language'])
+      && $route_parameters == $this->active['parameters'];
+
+    return $url_is_active;
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
index cf1b0d8..313c4ab 100644
--- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
+++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php
@@ -71,4 +71,19 @@
    */
   public function generate($text, $route_name, array $parameters = array(), array $options = array());
 
+  /**
+   * Determines whether a given route is the current active route.
+   *
+   * @param string $route_name
+   *   The route name to check whether it is the current active one.
+   * @param array $route_parameters
+   *   The route parameters belonging to $route_name to check.
+   * @param array $variables
+   *   A link variables array containing the link options.
+   *
+   * @return bool
+   *   Returns TRUE if the route matches the current route, otherwise FALSE.
+   */
+  public function isRouteActive($route_name, array $route_parameters, array $variables);
+
 }
diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
index bfbf5b0..5af190c 100644
--- a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
+++ b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php
@@ -186,19 +186,23 @@ public function adminOverview() {
       $links = array();
       $links['edit'] = array(
         'title' => $this->t('Edit'),
-        'href' => "admin/config/services/aggregator/edit/feed/$feed->fid",
+        'route_name' => 'aggregator.feed_edit',
+        'route_parameters' => array('aggregator_feed' => $feed->fid),
       );
       $links['delete'] = array(
         'title' => $this->t('Delete'),
-        'href' => "admin/config/services/aggregator/delete/feed/$feed->fid",
+        'route_name' => 'aggregator.feed_delete',
+        'route_parameters' => array('aggregator_feed' => $feed->fid),
       );
       $links['remove'] = array(
         'title' => $this->t('Remove items'),
-        'href' => "admin/config/services/aggregator/remove/$feed->fid",
+        'route_name' => 'aggregator.feed_items_delete',
+        'route_parameters' => array('aggregator_feed' => $feed->fid),
       );
       $links['update'] = array(
         'title' => $this->t('Update items'),
-        'href' => "admin/config/services/aggregator/update/$feed->fid",
+        'route_name' => 'aggregator.feed_refresh',
+        'route_parameters' => array('aggregator_feed' => $feed->fid),
         'query' => array('token' => drupal_get_token("aggregator/update/$feed->fid")),
       );
       $row[] = array(
@@ -228,11 +232,13 @@ public function adminOverview() {
       $links = array();
       $links['edit'] = array(
         'title' => $this->t('Edit'),
-        'href' => "admin/config/services/aggregator/edit/category/$category->cid",
+        'route_name' => 'aggregator.category_admin_edit',
+        'route_parameters' => array('cid' => $category->cid),
       );
       $links['delete'] = array(
         'title' => $this->t('Delete'),
-        'href' => "admin/config/services/aggregator/delete/category/$category->cid",
+        'route_name' => 'aggregator.category_delete',
+        'route_parameters' => array('cid' => $category->cid),
       );
       $row[] = array(
         'data' => array(
diff --git a/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php b/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php
index c47bdcc..4aadec0 100644
--- a/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php
+++ b/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php
@@ -63,7 +63,8 @@ public function buildForm(array $form, array &$form_state, $default_ip = '') {
       $links = array();
       $links['delete'] = array(
         'title' => $this->t('delete'),
-        'href' => "admin/config/people/ban/delete/$ip->iid",
+        'route_name' => 'ban.delete',
+        'route_parameters' => array('ban_id' => $ip->iid),
       );
       $row[] = array(
         'data' => array(
diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc
index 1d7061b..0ffefc5 100644
--- a/core/modules/book/book.admin.inc
+++ b/core/modules/book/book.admin.inc
@@ -53,12 +53,14 @@ function theme_book_admin_table($variables) {
     if ($access) {
       $links['edit'] = array(
         'title' => t('Edit'),
-        'href' => "node/$nid/edit",
+        'route_name' => 'node.page_edit',
+        'route_parameters' => array('node' => $nid),
         'query' => $destination,
       );
       $links['delete'] = array(
         'title' => t('Delete'),
-        'href' => "node/$nid/delete",
+        'route_name' => 'node.delete_confirm',
+        'route_parameters' => array('node' => $nid),
         'query' => $destination,
       );
     }
diff --git a/core/modules/book/lib/Drupal/book/Controller/BookController.php b/core/modules/book/lib/Drupal/book/Controller/BookController.php
index 214a801..b9920d2 100644
--- a/core/modules/book/lib/Drupal/book/Controller/BookController.php
+++ b/core/modules/book/lib/Drupal/book/Controller/BookController.php
@@ -77,7 +77,8 @@ public function adminOverview() {
       $links = array();
       $links['edit'] = array(
         'title' => t('Edit order and titles'),
-        'href' => 'admin/structure/book/' . $book['nid'],
+        'route_name' => 'book.admin_edit',
+        'route_parameters' => array('node' => $book['nid']),
       );
       $row[] = array(
         'data' => array(
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index 02f2278..c4360dc 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -156,13 +156,16 @@ function comment_admin_overview($form, &$form_state, $arg) {
     $links = array();
     $links['edit'] = array(
       'title' => t('edit'),
-      'href' => 'comment/' . $comment->id() . '/edit',
+      'route_name' => 'comment.edit_page',
+      'route_parameters' => array('comment' => $comment->id()),
       'query' => $destination,
     );
     if (module_invoke('content_translation', 'translate_access', $comment)) {
       $links['translate'] = array(
         'title' => t('translate'),
         'href' => 'comment/' . $comment->id() . '/translations',
+        'route_name' => 'content_translation.translation_overview_comment',
+        'route_parameters' => array('comment' => $comment->id()),
         'query' => $destination,
       );
     }
diff --git a/core/modules/content_translation/content_translation.local_tasks.yml b/core/modules/content_translation/content_translation.local_tasks.yml
index 6e4a6bb..151c584 100644
--- a/core/modules/content_translation/content_translation.local_tasks.yml
+++ b/core/modules/content_translation/content_translation.local_tasks.yml
@@ -1,4 +1,3 @@
 content_translation.local_tasks:
   derivative: 'Drupal\content_translation\Plugin\Derivative\ContentTranslationLocalTasks'
-  class: 'Drupal\content_translation\Plugin\ContentTranslationLocalTasks'
   weight: 100
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
index 3a53710..8cafd5b 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
@@ -46,7 +46,10 @@ public function appliesTo() {
    * {@inheritdoc}
    */
   public function access(Route $route, Request $request) {
-    if ($entity = $request->attributes->get('entity')) {
+    if (($entity_type = $request->attributes->get('entity_type')) && $request->attributes->has($entity_type)) {
+      // Get the entity based on the returned type.
+      $entity = $request->attributes->get($entity_type);
+
       $route_requirements = $route->getRequirements();
       $operation = $route_requirements['_access_content_translation_manage'];
       $entity_type = $entity->entityType();
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
index 116e9c5..4d6e839 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
@@ -45,9 +45,9 @@ public function appliesTo() {
    * {@inheritdoc}
    */
   public function access(Route $route, Request $request) {
-    if ($entity = $request->attributes->get('entity')) {
-      // Get entity base info.
-      $entity_type = $entity->entityType();
+    if (($entity_type = $request->attributes->get('entity_type')) && $request->attributes->has($entity_type)) {
+      // Get the entity based on the returned type.
+      $entity = $request->attributes->get($entity_type);
       $bundle = $entity->bundle();
 
       // Get account details from request.
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php
index ec229e1..21297f5 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\content_translation\Controller;
 
-use Drupal\Core\Entity\EntityInterface;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Base class for entity translation controllers.
@@ -17,28 +17,28 @@ class ContentTranslationController {
   /**
    * @todo Remove content_translation_overview().
    */
-  public function overview(EntityInterface $entity) {
+  public function overview(Request $request, $entity_type) {
     module_load_include('pages.inc', 'content_translation');
-    return content_translation_overview($entity);
+    return content_translation_overview($request->attributes->get($entity_type));
   }
 
   /**
    * @todo Remove content_translation_add_page().
    */
-  public function add(EntityInterface $entity, $source, $target) {
+  public function add(Request $request, $entity_type, $source, $target) {
     module_load_include('pages.inc', 'content_translation');
     $source = language_load($source);
     $target = language_load($target);
-    return content_translation_add_page($entity, $source, $target);
+    return content_translation_add_page($request->attributes->get($entity_type), $source, $target);
   }
 
   /**
    * @todo Remove content_translation_edit_page().
    */
-  public function edit(EntityInterface $entity, $language) {
+  public function edit(Request $request, $entity_type, $language) {
     module_load_include('pages.inc', 'content_translation');
     $language = language_load($language);
-    return content_translation_edit_page($entity, $language);
+    return content_translation_edit_page($request->attributes->get($entity_type), $language);
   }
 
 }
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationForm.php b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationForm.php
index 7142a49..034d220 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationForm.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Form/ContentTranslationForm.php
@@ -1,4 +1,5 @@
 <?php
+
 /**
  * @file
  * Contains \Drupal\content_translation\Form\ContentTranslationForm.
@@ -6,8 +7,7 @@
 
 namespace Drupal\content_translation\Form;
 
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Language\Language;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Temporary form controller for content_translation module.
@@ -19,10 +19,10 @@ class ContentTranslationForm {
    *
    * @todo Remove content_translation_delete_confirm().
    */
-  public function deleteTranslation(EntityInterface $entity, $language) {
+  public function deleteTranslation(Request $request, $entity_type, $language) {
     module_load_include('pages.inc', 'content_translation');
     $language = language_load($language);
-    return drupal_get_form('content_translation_delete_confirm', $entity, $language);
+    return drupal_get_form('content_translation_delete_confirm', $request->attributes->get($entity_type), $language);
   }
 
 }
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Plugin/ContentTranslationLocalTasks.php b/core/modules/content_translation/lib/Drupal/content_translation/Plugin/ContentTranslationLocalTasks.php
deleted file mode 100644
index 50c4c60..0000000
--- a/core/modules/content_translation/lib/Drupal/content_translation/Plugin/ContentTranslationLocalTasks.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\content_translation\Plugin\ContentTranslationLocalTasks.
- */
-
-namespace Drupal\content_translation\Plugin;
-
-use Drupal\Core\Menu\LocalTaskDefault;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Provides route parameter manipulation for content translation local tasks.
- */
-class ContentTranslationLocalTasks extends LocalTaskDefault {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRouteParameters(Request $request) {
-    $parameters = parent::getRouteParameters($request);
-    $entity_type = $this->pluginDefinition['entity_type'];
-    if ($raw_variables = $request->attributes->get('_raw_variables')) {
-      // When the entity type is in the path, populate 'entity' for any dynamic
-      // local tasks.
-      if ($raw_variables->has($entity_type)) {
-        $entity = $raw_variables->get($entity_type);
-        $parameters['entity'] = $entity;
-      }
-      // When 'entity' is in the path, populate the parameters with the value
-      // for the actual entity type.
-      elseif ($raw_variables->has('entity')) {
-        $entity = $raw_variables->get('entity');
-        $parameters[$entity_type] = $entity;
-      }
-    }
-    return $parameters;
-  }
-
-}
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
index 5d30c4c..e3271df 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
@@ -50,24 +50,18 @@ public function routes(RouteBuildEvent $event) {
     $collection = $event->getRouteCollection();
     foreach ($this->entityManager->getDefinitions() as $entity_type => $entity_info) {
       if ($entity_info['translatable'] && isset($entity_info['translation'])) {
-        $path = '/' . str_replace($entity_info['menu_path_wildcard'], '{entity}', $entity_info['menu_base_path']) . '/translations';
+        $path = '/' . preg_replace('/%(.*)/', '{$1}', $entity_info['menu_base_path']) . '/translations';
         $route = new Route(
          $path,
           array(
             '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
             '_title' => 'Translate',
             'account' => 'NULL',
+            'entity_type' => $entity_type,
           ),
           array(
             '_access_content_translation_overview' => $entity_type,
             '_permission' => 'translate any entity',
-          ),
-          array(
-            'parameters' => array(
-              'entity' => array(
-                'type' => 'entity:' . $entity_type,
-              ),
-            ),
           )
         );
         $collection->add("content_translation.translation_overview_$entity_type", $route);
@@ -79,18 +73,11 @@ public function routes(RouteBuildEvent $event) {
             'source' => NULL,
             'target' => NULL,
             '_title' => 'Add',
-
+            'entity_type' => $entity_type,
           ),
           array(
             '_permission' => 'translate any entity',
             '_access_content_translation_manage' => 'create',
-          ),
-          array(
-            'parameters' => array(
-              'entity' => array(
-                'type' => 'entity:' . $entity_type,
-              ),
-            ),
           )
         );
         $collection->add("content_translation.translation_add_$entity_type", $route);
@@ -101,17 +88,11 @@ public function routes(RouteBuildEvent $event) {
             '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::edit',
             'language' => NULL,
             '_title' => 'Edit',
+            'entity_type' => $entity_type,
           ),
           array(
             '_permission' => 'translate any entity',
             '_access_content_translation_manage' => 'update',
-          ),
-          array(
-            'parameters' => array(
-              'entity' => array(
-                'type' => 'entity:' . $entity_type,
-              ),
-            ),
           )
         );
         $collection->add("content_translation.translation_edit_$entity_type", $route);
@@ -122,17 +103,11 @@ public function routes(RouteBuildEvent $event) {
             '_content' => '\Drupal\content_translation\Form\ContentTranslationForm::deleteTranslation',
             'language' => NULL,
             '_title' => 'Delete',
+            'entity_type' => $entity_type,
           ),
           array(
             '_permission' => 'translate any entity',
             '_access_content_translation_manage' => 'delete',
-          ),
-          array(
-            'parameters' => array(
-              'entity' => array(
-                'type' => 'entity:' . $entity_type,
-              ),
-            ),
           )
         );
         $collection->add("content_translation.delete_$entity_type", $route);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
index 635883c..7c0ac6f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php
@@ -13,6 +13,14 @@
  * Tests for common theme functions.
  */
 class FunctionsTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('router_test');
+
   public static function getInfo() {
     return array(
       'name' => 'Theme functions',
@@ -158,13 +166,19 @@ function testLinks() {
         'title' => 'Front page',
         'href' => '<front>',
       ),
+      'router-test' => array(
+        'title' => 'Test route',
+        'route_name' => 'router_test.1',
+        'route_parameters' => array(),
+      ),
     );
 
     $expected_links = '';
     $expected_links .= '<ul id="somelinks">';
     $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '">' . check_plain('A <link>') . '</a></li>';
     $expected_links .= '<li class="plain-text even">' . check_plain('Plain "text"') . '</li>';
-    $expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
     $expected_links .= '</ul>';
 
     // Verify that passing a string as heading works.
@@ -196,7 +210,8 @@ function testLinks() {
     $expected_links .= '<ul id="somelinks">';
     $expected_links .= '<li class="a-link odd first"><a href="' . url('a/link') . '" class="a/class">' . check_plain('A <link>') . '</a></li>';
     $expected_links .= '<li class="plain-text even"><span class="a/class">' . check_plain('Plain "text"') . '</span></li>';
-    $expected_links .= '<li class="front-page odd last active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="front-page odd active"><a href="' . url('<front>') . '" class="active">' . check_plain('Front page') . '</a></li>';
+    $expected_links .= '<li class="router-test even last"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . check_plain('Test route') . '</a></li>';
     $expected_links .= '</ul>';
     $expected = $expected_heading . $expected_links;
     $this->assertThemeOutput('links', $variables, $expected);
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Controller/EntityTestController.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Controller/EntityTestController.php
index 053163b..03d7dc0 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Controller/EntityTestController.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Controller/EntityTestController.php
@@ -7,7 +7,7 @@
 
 namespace Drupal\entity_test\Controller;
 
-use Drupal\Core\Entity\EntityInterface;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Controller routines for entity_test routes.
@@ -24,8 +24,8 @@ public function testAdd($entity_type) {
   /**
    * @todo Remove entity_test_edit()
    */
-  public function testEdit(EntityInterface $entity) {
-    return entity_test_edit($entity);
+  public function testEdit(Request $request, $entity_type) {
+    return entity_test_edit($request->attributes->get($entity_type));
   }
 
 }
diff --git a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Routing/RouteSubscriber.php b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Routing/RouteSubscriber.php
index 8834b4a..bb8a8e0 100644
--- a/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Routing/RouteSubscriber.php
+++ b/core/modules/system/tests/modules/entity_test/lib/Drupal/entity_test/Routing/RouteSubscriber.php
@@ -42,12 +42,9 @@ public function routes(RouteBuildEvent $event) {
       $collection->add("entity_test.add_$entity_type", $route);
 
       $route = new Route(
-        "$entity_type/manage/{entity}",
-        array('_content' => '\Drupal\entity_test\Controller\EntityTestController::testEdit'),
-        array('_permission' => 'administer entity_test content'),
-        array('parameters' => array(
-          'entity' => array('type' => 'entity:' . $entity_type),
-        ))
+        "$entity_type/manage/{{$entity_type}}",
+        array('_content' => '\Drupal\entity_test\Controller\EntityTestController::testEdit', 'entity_type' => $entity_type),
+        array('_permission' => 'administer entity_test content')
       );
       $collection->add("entity_test.edit_$entity_type", $route);
     }
diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
index 6b7334f..a6cdac3 100644
--- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
+++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php
@@ -333,6 +333,7 @@ public function testGenerateActive() {
     $request = new Request(array(), array(), array('system_path' => 'test-route-2'));
     $this->linkGenerator->setRequest($request);
     $result = $this->linkGenerator->generate('Test', 'test_route_1');
+    $this->assertFalse($this->linkGenerator->isRouteActive('test_route_1', array(), array()));
     $this->assertNotTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -346,6 +347,7 @@ public function testGenerateActive() {
     $request->attributes->set('_raw_variables', $raw_variables);
     $this->linkGenerator->setRequest($request);
     $result = $this->linkGenerator->generate('Test', 'test_route_1');
+    $this->assertTrue($this->linkGenerator->isRouteActive('test_route_1', array(), array()));
     $this->assertTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -353,6 +355,7 @@ public function testGenerateActive() {
 
     // Render a link with the same path and language as the current path.
     $result = $this->linkGenerator->generate('Test', 'test_route_1');
+    $this->assertTrue($this->linkGenerator->isRouteActive('test_route_1', array(), array()));
     $this->assertTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -366,6 +369,7 @@ public function testGenerateActive() {
       array(),
       array('language' => new Language(array('id' => 'de')))
     );
+    $this->assertFalse($this->linkGenerator->isRouteActive('test_route_1', array(), array('options' => array('language' => new Language(array('id' => 'de'))))));
     $this->assertNotTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -382,6 +386,7 @@ public function testGenerateActive() {
       array(),
       array('query' => array('value' => 'example_1')
     ));
+    $this->assertTrue($this->linkGenerator->isRouteActive('test_route_3', array('value' => 'example_1'), array()));
     $this->assertTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -395,6 +400,7 @@ public function testGenerateActive() {
       array(),
       array('query' => array('value' => 'example_2'))
     );
+    $this->assertFalse($this->linkGenerator->isRouteActive('test_route_3', array('value' => 'example_2'), array()));
     $this->assertNotTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
@@ -410,6 +416,7 @@ public function testGenerateActive() {
       array('object' => '1'),
       array('query' => array('value' => 'example_1'))
     );
+    $this->assertTrue($this->linkGenerator->isRouteActive('test_route_4', array('object' => '1', 'value' => 'example_1'), array()));
     $this->assertTag(array(
       'tag' => 'a',
       'attributes' => array('class' => 'active'),
