diff --git a/core/core.services.yml b/core/core.services.yml
index 9af8ff1..c58820d 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -252,6 +252,8 @@ services:
       - { name: route_filter }
   paramconverter_manager:
     class: Drupal\Core\ParamConverter\ParamConverterManager
+    calls:
+      - [setContainer, ['@service_container']]
     tags:
       - { name: route_enhancer }
   paramconverter.entity:
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
index 6fe1447..3ecc006 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
@@ -23,26 +23,12 @@ class RegisterParamConvertersPass implements CompilerPassInterface {
    *   The container to process.
    */
   public function process(ContainerBuilder $container) {
-
     if (!$container->hasDefinition('paramconverter_manager')) {
       return;
     }
-
-    $manager = $container->getDefinition('paramconverter_manager');
-
-    $services = array();
+    $access_manager = $container->getDefinition('paramconverter_manager');
     foreach ($container->findTaggedServiceIds('paramconverter') as $id => $attributes) {
-      $priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
-
-      $services[$priority][] = new Reference($id);
-    }
-
-    krsort($services);
-
-    foreach ($services as $priority) {
-      foreach ($priority as $service) {
-        $manager->addMethodCall('addConverter', array($service));
-      }
+      $access_manager->addMethodCall('addConverterService', array($id));
     }
   }
 }
diff --git a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
index f28906f..2db30d0 100644
--- a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
+++ b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
@@ -35,72 +35,13 @@ public function __construct(EntityManager $entityManager) {
   }
 
   /**
-   * Tries to upcast every variable to an entity type.
-   *
-   * If there is a type denoted in the route options it will try to upcast to
-   * it, if there is no definition in the options it will try to upcast to an
-   * entity type of that name. If the chosen enity type does not exists it will
-   * leave the variable untouched.
-   * If the entity type exist, but there is no entity with the given id it will
-   * convert the variable to NULL.
-   *
-   * Example:
-   *
-   * pattern: '/a/{user}/some/{foo}/and/{bar}/'
-   * options:
-   *   converters:
-   *     foo: 'node'
-   *
-   * The value for {user} will be converted to a user entity and the value
-   * for {foo} to a node entity, but it will not touch the value for {bar}.
-   *
-   * It will not process variables which are marked as converted. It will mark
-   * any variable it processes as converted.
-   *
-   * @param array &$variables
-   *   Array of values to convert to their corresponding objects, if applicable.
-   * @param \Symfony\Component\Routing\Route $route
-   *   The route object.
-   * @param array &$converted
-   *   Array collecting the names of all variables which have been
-   *   altered by a converter.
+   * {@inheritdoc}
    */
-  public function process(array &$variables, Route $route, array &$converted) {
-    $variable_names = $route->compile()->getVariables();
-
-    $options = $route->getOptions();
-    $configuredTypes = isset($options['converters']) ? $options['converters'] : array();
-
-    $entityTypes = array_keys($this->entityManager->getDefinitions());
-
-    foreach ($variable_names as $name) {
-      // Do not process this variable if it's already marked as converted.
-      if (in_array($name, $converted)) {
-        continue;
-      }
-
-      // Obtain entity type to convert to from the route configuration or just
-      // use the variable name as default.
-      if (array_key_exists($name, $configuredTypes)) {
-        $type = $configuredTypes[$name];
-      }
-      else {
-        $type = $name;
-      }
-
-      if (in_array($type, $entityTypes)) {
-        $value = $variables[$name];
-
-        $storageController = $this->entityManager->getStorageController($type);
-        $entities = $storageController->load(array($value));
-
-        // Make sure $entities is null, if upcasting fails.
-        $entity = $entities ? reset($entities) : NULL;
-        $variables[$name] = $entity;
-
-        // Mark this variable as converted.
-        $converted[] = $name;
-      }
-    }
+  public function convert($value, $options, Route $route, array $defaults) {
+    $storageController = $this->entityManager->getStorageController($options['type']);
+    $entities = $storageController->load(array($value));
+    $entity = $entities ? reset($entities) : NULL;
+    return $entity;
   }
+
 }
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
index 74307c2..1c5a899 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
@@ -17,13 +17,20 @@
   /**
    * Allows to convert variables to their corresponding objects.
    *
-   * @param array &$variables
-   *   Array of values to convert to their corresponding objects, if applicable.
+   * @param mixed $value
+   *   The current value of the variable.
+   * @param mixed $options
+   *   The variable options provided in the route definition.
    * @param \Symfony\Component\Routing\Route $route
    *   The route object.
-   * @param array &$converted
-   *   Array collecting the names of all variables which have been
-   *   altered by a converter.
+   * @param array $defaults
+   *   The complete array of parameters returned by
+   *   \Symfony\Component\Routing\Matcher\RequestMatcherInterface::matchRequest()
+   *   and processed by prior route enhancers and parameter converters.
+   *
+   * @return mixed
+   *   The converted variable value.
    */
-  public function process(array &$variables, Route $route, array &$converted);
+  public function convert($value, $options, Route $route, array $defaults);
+
 }
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
index be5676e..d35663d 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
@@ -1,5 +1,4 @@
 <?php
-
 /**
  * @file
  * Contains Drupal\Core\ParamConverter\ParamConverterManager.
@@ -7,14 +6,14 @@
 
 namespace Drupal\Core\ParamConverter;
 
-use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Routing\RouteCollection;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\DependencyInjection\ContainerAware;
 use Symfony\Component\HttpFoundation\Request;
 
-use Drupal\Core\ParamConverter\ParamConverterInterface;
-
 /**
  * Provides a service which allows to enhance (say alter) the arguments coming
  * from the URL.
@@ -24,66 +23,101 @@
  * This class will not enhance any of the arguments itself, but allow other
  * services to register to do so.
  */
-class ParamConverterManager implements RouteEnhancerInterface {
+class ParamConverterManager extends ContainerAware implements RouteEnhancerInterface {
 
   /**
-   * Converters managed by the ParamConverterManager.
+   * Array of registered parameter converter service ids.
    *
    * @var array
    */
-  protected $converters;
+  protected $converterIds;
 
   /**
-   * Adds a converter to the paramconverter service.
+   * Array of parameter converter objects keyed by service id.
    *
-   * @see \Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass
+   * @var array
+   */
+  protected $converters;
+
+  /**
+   * Registers a new ParamConverter by service ID.
    *
-   * @param \Drupal\Core\ParamConverter\ParamConverterInterface $converter
-   *   The converter to add.
+   * @param string $service_id
+   *   The ID of the service in the Container that provides a converter.
    */
-  public function addConverter(ParamConverterInterface $converter) {
-    $this->converters[] = $converter;
-    return $this;
+  public function addConverterService($service_id) {
+    $this->converterIds[] = $service_id;
   }
 
   /**
-   * Implements \Symfony\Cmf\Component\Routing\Enhancer\ŖouteEnhancerIterface.
-   *
-   * Iterates over all registered converters and allows them to alter the
-   * defaults.
+   * Invokes each registered converter for a given route.
    *
    * @param array $defaults
    *   The getRouteDefaults array.
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The current request.
    *
+   * @throws \InvalidArgumentException
+   *   If a given parameter does not exist on the route.
+   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+   *   If a variable has been converted to NULL.
+   *
    * @return array
    *   The modified defaults.
    */
   public function enhance(array $defaults, Request $request) {
-    // This array will collect the names of all variables which have been
-    // altered by a converter.
-    // This serves two purposes:
-    // 1. It might prevent converters later in the pipeline to process
-    //    a variable again.
-    // 2. To check if upcasting was successfull after each converter had
-    //    a go. See below.
-    $converters = array();
-
     $route = $defaults[RouteObjectInterface::ROUTE_OBJECT];
+    $parameters = $route->getOption('parameters') ?: array();
 
-    foreach ($this->converters as $converter) {
-      $converter->process($defaults, $route, $converters);
+    // Bail out if no converter has been registered for any parameter on the
+    // given route.
+    if (empty($parameters)) {
+      return $defaults;
     }
 
-    // Check if all upcasting yielded a result.
-    // If an upcast value is NULL do a 404.
-    foreach ($converters as $variable) {
-      if ($defaults[$variable] === NULL) {
+    foreach ($parameters as $parameter => $options) {
+      if (!isset($options['converter'])) {
+        // No converter specified.
+        continue;
+      }
+
+      if (!isset($defaults[$parameter])) {
+        // The given parameter does not exist on the route.
+        throw new \InvalidArgumentException(sprintf('Unknown parameter %s.', $parameter));
+      }
+
+      $converter = $options['converter'];
+      if (empty($this->converters[$converter])) {
+        $this->loadConverter($converter);
+      }
+
+      // If a converter returns NULL it means that the parameter could not
+      // be converted in which case we throw a 404.
+      $defaults[$parameter] = $this->converters[$converter]->convert($defaults[$parameter], $options, $route, $defaults);
+      if ($defaults[$parameter] === NULL) {
         throw new NotFoundHttpException();
       }
     }
 
     return $defaults;
   }
+
+  /**
+   * Lazy-loads converter services.
+   *
+   * @param string $service_id
+   *   The service id of the access check service to load.
+   *
+   * @throws \InvalidArgumentException
+   *   If the given service has not been registered as a converter.
+   */
+  protected function loadConverter($service_id) {
+    if (!in_array($service_id, $this->converterIds)) {
+      throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $service_id));
+    }
+
+    $this->converters[$service_id] = $this->container->get($service_id);
+  }
+
 }
+
diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml
index c41cf0e..3c39be5 100644
--- a/core/modules/aggregator/aggregator.routing.yml
+++ b/core/modules/aggregator/aggregator.routing.yml
@@ -18,6 +18,11 @@ aggregator_feed_items_delete:
     _form: '\Drupal\aggregator\Form\FeedItemsDelete'
   requirements:
     _permission: 'administer news feeds'
+  options:
+    parameters:
+      aggregator_feed:
+        converter: 'paramconverter.entity'
+        type: 'aggregator_feed'
 
 aggregator_feed_delete:
   pattern: '/admin/config/services/aggregator/delete/feed/{aggregator_feed}'
@@ -25,6 +30,11 @@ aggregator_feed_delete:
     _form: '\Drupal\aggregator\Form\FeedDelete'
   requirements:
     _permission: 'administer news feeds'
+  options:
+    parameters:
+      aggregator_feed:
+        converter: 'paramconverter.entity'
+        type: 'aggregator_feed'
 
 aggregator_feed_add:
   pattern: '/admin/config/services/aggregator/add/feed'
diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml
index af247b0..234ff86 100644
--- a/core/modules/block/block.routing.yml
+++ b/core/modules/block/block.routing.yml
@@ -4,3 +4,8 @@ block_admin_block_delete:
     _form: '\Drupal\block\Form\AdminBlockDeleteForm'
   requirements:
     _permission: 'administer blocks'
+  options:
+    parameters:
+      block:
+        converter: 'paramconverter.entity'
+        type: 'block'
diff --git a/core/modules/contact/contact.routing.yml b/core/modules/contact/contact.routing.yml
index 1f34937..8b77f26 100644
--- a/core/modules/contact/contact.routing.yml
+++ b/core/modules/contact/contact.routing.yml
@@ -4,3 +4,8 @@ contact_category_delete:
     _form: '\Drupal\contact\Form\DeleteForm'
   requirements:
     _permission: 'administer contact forms'
+  options:
+    parameters:
+      contact_category:
+        converter: 'paramconverter.entity'
+        type: 'contact_category'
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
index 94e7b09..69c5bf8 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Routing/RouteSubscriber.php
@@ -55,28 +55,48 @@ public function routes(RouteBuildEvent $event) {
         $route = new Route(
           "$path/fields/{field_instance}",
           array('_form' => '\Drupal\field_ui\Form\FieldInstanceEditForm'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array(
+              'entity' => 'field_instance',
+            ),
+          ))
         );
         $collection->add("field_ui.instance_edit.$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/widget-type",
           array('_form' => '\Drupal\field_ui\Form\FieldWidgetTypeForm'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array(
+              'entity' => 'field_instance',
+            ),
+          ))
         );
         $collection->add("field_ui.widget_type.$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/field-settings",
           array('_form' => '\Drupal\field_ui\Form\FieldSettingsForm'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array(
+              'entity' => 'field_instance',
+            ),
+          ))
         );
         $collection->add("field_ui.settings.$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/delete",
           array('_form' => '\Drupal\field_ui\Form\FieldDeleteForm'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array(
+              'entity' => 'field_instance',
+            ),
+          ))
         );
         $collection->add("field_ui.delete.$entity_type", $route);
 
diff --git a/core/modules/filter/filter.routing.yml b/core/modules/filter/filter.routing.yml
index de9e9cb..74d0a39 100644
--- a/core/modules/filter/filter.routing.yml
+++ b/core/modules/filter/filter.routing.yml
@@ -4,3 +4,8 @@ filter_admin_disable:
     _form: '\Drupal\filter\Form\DisableForm'
   requirements:
     _filter_disable_format_access: 'TRUE'
+  options:
+    parameters:
+      filter_format:
+        converter: 'paramconverter.entity'
+        type: 'filter_format'
diff --git a/core/modules/forum/forum.routing.yml b/core/modules/forum/forum.routing.yml
index f7d90f8..6df24a0 100644
--- a/core/modules/forum/forum.routing.yml
+++ b/core/modules/forum/forum.routing.yml
@@ -4,6 +4,12 @@ forum_delete:
     _form: 'Drupal\forum\Form\DeleteForm'
   requirements:
     _permission: 'administer forums'
+  options:
+    parameters:
+      taxonomy_term:
+        converter: 'paramconverter.entity'
+        type: 'taxonomy_term'
+
 forum_settings:
   pattern: '/admin/structure/forum/settings'
   defaults:
diff --git a/core/modules/image/image.routing.yml b/core/modules/image/image.routing.yml
index 0aa23ba..09bbf25 100644
--- a/core/modules/image/image.routing.yml
+++ b/core/modules/image/image.routing.yml
@@ -4,6 +4,11 @@ image_style_delete:
     _form: '\Drupal\image\Form\ImageStyleDeleteForm'
   requirements:
     _permission: 'administer image styles'
+  options:
+    parameters:
+      image_style:
+        converter: 'paramconverter.entity'
+        type: 'image_style'
 
 image_effect_delete:
   pattern: 'admin/config/media/image-styles/manage/{image_style}/effects/{image_effect}/delete'
@@ -11,3 +16,8 @@ image_effect_delete:
     _form: '\Drupal\image\Form\ImageEffectDeleteForm'
   requirements:
     _permission: 'administer image styles'
+  options:
+    parameters:
+      image_style:
+        converter: 'paramconverter.entity'
+        type: 'image_style'
diff --git a/core/modules/menu/menu.routing.yml b/core/modules/menu/menu.routing.yml
index aafe5c3..843a771 100644
--- a/core/modules/menu/menu.routing.yml
+++ b/core/modules/menu/menu.routing.yml
@@ -11,6 +11,11 @@ menu_link_reset:
     _form: '\Drupal\menu\Form\MenuLinkResetForm'
   requirements:
     _permission: 'administer menu'
+  options:
+    parameters:
+      menu_link:
+        converter: 'paramconverter.entity'
+        type: 'menu_link'
 
 menu_link_delete:
   pattern: 'admin/structure/menu/item/{menu_link}/delete'
@@ -18,6 +23,11 @@ menu_link_delete:
     _form: '\Drupal\menu\Form\MenuLinkDeleteForm'
   requirements:
     _access_menu_delete_link: 'TRUE'
+  options:
+    parameters:
+      menu_link:
+        converter: 'paramconverter.entity'
+        type: 'menu_link'
 
 menu_delete_menu:
   pattern: 'admin/structure/menu/manage/{menu}/delete'
@@ -25,3 +35,8 @@ menu_delete_menu:
     _form: '\Drupal\menu\Form\MenuDeleteMenuForm'
   requirements:
     _access_menu_delete_menu: 'TRUE'
+  options:
+    parameters:
+      menu:
+        converter: 'paramconverter.entity'
+        type: 'menu'
diff --git a/core/modules/picture/picture.routing.yml b/core/modules/picture/picture.routing.yml
index 96da6d3..a723cc9 100644
--- a/core/modules/picture/picture.routing.yml
+++ b/core/modules/picture/picture.routing.yml
@@ -4,3 +4,8 @@ picture_mapping_action_confirm:
     _form: '\Drupal\picture\Form\PictureMappingActionConfirmForm'
   requirements:
     _permission: 'administer pictures'
+  options:
+    parameters:
+      picture_mapping:
+        converter: 'paramconverter.entity'
+        type: 'picture_mapping'
diff --git a/core/modules/shortcut/shortcut.routing.yml b/core/modules/shortcut/shortcut.routing.yml
index 488d187..6528ea1 100644
--- a/core/modules/shortcut/shortcut.routing.yml
+++ b/core/modules/shortcut/shortcut.routing.yml
@@ -4,6 +4,11 @@ shortcut_link_delete:
     _form: 'Drupal\shortcut\Form\LinkDelete'
   requirements:
     _access_shortcut_link_delete: 'TRUE'
+  options:
+    parameters:
+      menu_link:
+        converter: 'paramconverter.entity'
+        type: 'menu_link'
 
 shortcut_set_delete:
   pattern: '/admin/config/user-interface/shortcut/manage/{shortcut}/delete'
@@ -11,6 +16,11 @@ shortcut_set_delete:
     _form: 'Drupal\shortcut\Form\SetDelete'
   requirements:
     _entity_access: 'shortcut.delete'
+  options:
+    parameters:
+      shortcut:
+        converter: 'paramconverter.entity'
+        type: 'shortcut'
 
 shortcut_set_admin:
   pattern: '/admin/config/user-interface/shortcut'
diff --git a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
index 14a0422..f9559a0 100644
--- a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
@@ -50,14 +50,12 @@ public function testUpcasting() {
     $this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: $foo", 'user and node upcast by entity name');
 
     // paramconverter_test/test_node_user_user/{node}/{foo}/{user}
-    // converters:
-    //   foo: 'user'
+    // options.parameters.foo.entity = user
     $this->drupalGet("paramconverter_test/test_node_user_user/{$node->nid}/{$user->uid}/{$user->uid}");
     $this->assertRaw("user: {$user->label()}, node: {$node->label()}, foo: {$user->label()}", 'foo converted to user as well');
 
     // paramconverter_test/test_node_node_foo/{user}/{node}/{foo}
-    // converters:
-    //   user: 'node'
+    // options.parameters.user.entity = node
     $this->drupalGet("paramconverter_test/test_node_node_foo/{$node->nid}/{$node->nid}/$foo");
     $this->assertRaw("user: {$node->label()}, node: {$node->label()}, foo: $foo", 'user is upcast to node (rather than to user)');
   }
@@ -69,8 +67,7 @@ public function testSameTypes() {
     $node = $this->drupalCreateNode(array('title' => $this->randomName(8)));
     $parent = $this->drupalCreateNode(array('title' => $this->randomName(8)));
     // paramconverter_test/node/{node}/set/parent/{parent}
-    // converters:
-    //   parent: 'node'
+    // options.parameters.parent.entity = node
     $this->drupalGet("paramconverter_test/node/" . $node->nid . "/set/parent/" . $parent->nid);
     $this->assertRaw("Setting '" . $parent->title . "' as parent of '" . $node->title . "'.");
   }
diff --git a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.routing.yml b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.routing.yml
index 9d226e4..81c35be 100644
--- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.routing.yml
+++ b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.routing.yml
@@ -4,6 +4,14 @@ paramconverter_test_user_node_foo:
     _content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
   requirements:
     _access: 'TRUE'
+  options:
+    parameters:
+      user:
+        converter: 'paramconverter.entity'
+        type: 'user'
+      node:
+        converter: 'paramconverter.entity'
+        type: 'node'
 
 paramconverter_test_node_user_user:
   pattern: '/paramconverter_test/test_node_user_user/{node}/{foo}/{user}'
@@ -12,8 +20,16 @@ paramconverter_test_node_user_user:
   requirements:
     _access: 'TRUE'
   options:
-    converters:
-      foo: 'user'
+    parameters:
+      node:
+        converter: 'paramconverter.entity'
+        type: 'node'
+      foo:
+        converter: 'paramconverter.entity'
+        type: 'user'
+      user:
+        converter: 'paramconverter.entity'
+        type: 'user'
 
 paramconverter_test_node_node_foo:
   pattern: '/paramconverter_test/test_node_node_foo/{user}/{node}/{foo}'
@@ -22,8 +38,13 @@ paramconverter_test_node_node_foo:
   requirements:
     _access: 'TRUE'
   options:
-    converters:
-      user: 'node'
+    parameters:
+      user:
+        converter: 'paramconverter.entity'
+        type: 'node'
+      node:
+        converter: 'paramconverter.entity'
+        type: 'node'
 
 paramconverter_test_node_set_parent:
   pattern: '/paramconverter_test/node/{node}/set/parent/{parent}'
@@ -32,5 +53,10 @@ paramconverter_test_node_set_parent:
   defaults:
     _content: '\Drupal\paramconverter_test\TestControllers::testNodeSetParent'
   options:
-    converters:
-      parent: 'node'
+    parameters:
+      node:
+        converter: 'paramconverter.entity'
+        type: 'node'
+      parent:
+        converter: 'paramconverter.entity'
+        type: 'node'
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php b/core/modules/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php
index f828de1..295374e 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php
@@ -7,10 +7,11 @@
 
 namespace Drupal\views_ui\ParamConverter;
 
+use Drupal\Core\Entity\EntityManager;
+use Drupal\views\ViewStorageInterface;
 use Symfony\Component\Routing\Route;
 use Drupal\Core\ParamConverter\ParamConverterInterface;
 use Drupal\user\TempStoreFactory;
-use Drupal\views\ViewStorageInterface;
 use Drupal\views_ui\ViewUI;
 
 /**
@@ -19,6 +20,13 @@
 class ViewUIConverter implements ParamConverterInterface {
 
   /**
+   * Stores the entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManager
+   */
+  protected $entityManager;
+
+  /**
    * Stores the tempstore factory.
    *
    * @var \Drupal\user\TempStoreFactory
@@ -28,80 +36,44 @@ class ViewUIConverter implements ParamConverterInterface {
   /**
    * Constructs a new ViewUIConverter.
    *
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
    * @param \Drupal\user\TempStoreFactory $temp_store_factory
    *   The factory for the temp store object.
    */
-  public function __construct(TempStoreFactory $temp_store_factory) {
+  public function __construct(EntityManager $entity_manager, TempStoreFactory $temp_store_factory) {
+    $this->entityManager = $entity_manager;
     $this->tempStoreFactory = $temp_store_factory;
   }
 
   /**
-   * Tries to upcast every view entity to a decorated ViewUI object.
-   *
-   * The key refers to the portion of the route that is a view entity that
-   * should be prepared for the Views UI. If there is a non-null value, it will
-   * be used as the collection of a temp store object used for loading.
-   *
-   * Example:
-   *
-   * pattern: '/some/{view}/and/{foo}/and/{bar}'
-   * options:
-   *   converters:
-   *     foo: 'view'
-   *   tempstore:
-   *     view: 'views'
-   *     foo: NULL
-   *
-   * The values for {view} and {foo} will be converted to view entities prepared
-   * for the Views UI, with {view} being loaded from the views temp store, but
-   * it will not touch the value for {bar}.
-   *
-   * Note: This requires that the placeholder either be named {view}, or that a
-   * converter is specified as done above for {foo}.
-   *
-   * It will still process variables which are marked as converted. It will mark
-   * any variable it processes as converted.
-   *
-   * @param array &$variables
-   *   Array of values to convert to their corresponding objects, if applicable.
-   * @param \Symfony\Component\Routing\Route $route
-   *   The route object.
-   * @param array &$converted
-   *   Array collecting the names of all variables which have been
-   *   altered by a converter.
+   * {@inheritdoc}
    */
-  public function process(array &$variables, Route $route, array &$converted) {
-    // If nothing was specified to convert, return.
-    $options = $route->getOptions();
-    if (!isset($options['tempstore'])) {
-      return;
+  public function convert($value, $options, Route $route, array $defaults) {
+    $storage_controller = $this->entityManager->getStorageController('view');
+    if (!$entities = $storage_controller->load(array($value))) {
+      return NULL;
     }
+    $entity = reset($entities);
 
-    foreach ($options['tempstore'] as $name => $collection) {
-      // Only convert if the variable is a view.
-      if ($variables[$name] instanceof ViewStorageInterface) {
-        // Get the temp store for this variable if it needs one.
-        // Attempt to load the view from the temp store, synchronize its
-        // status with the existing view, and store the lock metadata.
-        if ($collection && ($temp_store = $this->tempStoreFactory->get($collection)) && ($view = $temp_store->get($variables[$name]->id()))) {
-          if ($variables[$name]->status()) {
-            $view->enable();
-          }
-          else {
-            $view->disable();
-          }
-          $view->lock = $temp_store->getMetadata($variables[$name]->id());
-        }
-        // Otherwise, decorate the existing view for use in the UI.
-        else {
-          $view = new ViewUI($variables[$name]);
-        }
-
-        // Store the new view and mark this variable as converted.
-        $variables[$name] = $view;
-        $converted[] = $name;
+    // Get the temp store for this variable if it needs one.
+    // Attempt to load the view from the temp store, synchronize its
+    // status with the existing view, and store the lock metadata.
+    if (($temp_store = $this->tempStoreFactory->get('views')) && ($view = $temp_store->get($entity->id()))) {
+      if ($entity->status()) {
+        $view->enable();
+      }
+      else {
+        $view->disable();
       }
+      $view->lock = $temp_store->getMetadata($value->id());
     }
+    // Otherwise, decorate the existing view for use in the UI.
+    else {
+      $view = new ViewUI($entity);
+    }
+
+    return $view;
   }
 
 }
diff --git a/core/modules/views_ui/views_ui.routing.yml b/core/modules/views_ui/views_ui.routing.yml
index f2046f6..e02964b 100644
--- a/core/modules/views_ui/views_ui.routing.yml
+++ b/core/modules/views_ui/views_ui.routing.yml
@@ -47,6 +47,11 @@ views_ui.operation:
   requirements:
     _permission: 'administer views'
     op: 'enable|disable'
+  options:
+    parameters:
+      view:
+        converter: 'paramconverter.entity'
+        type: 'view'
 
 views_ui.clone:
   pattern: '/admin/structure/views/view/{view}/clone'
@@ -54,6 +59,11 @@ views_ui.clone:
     _entity_form: 'view.clone'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        converter: 'paramconverter.entity'
+        type: 'view'
 
 views_ui.delete:
   pattern: '/admin/structure/views/view/{view}/delete'
@@ -61,6 +71,11 @@ views_ui.delete:
     _form: 'Drupal\views_ui\Form\DeleteForm'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        converter: 'paramconverter.entity'
+        type: 'view'
 
 views_ui.autocomplete:
   pattern: '/admin/views/ajax/autocomplete/tag'
@@ -68,12 +83,18 @@ views_ui.autocomplete:
     _controller: '\Drupal\views_ui\Routing\ViewsUIController::autocompleteTag'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        converter: 'paramconverter.entity'
+        type: 'view'
 
 views_ui.edit:
   pattern: '/admin/structure/views/view/{view}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Routing\ViewsUIController::edit'
   requirements:
@@ -82,8 +103,9 @@ views_ui.edit:
 views_ui.edit.display:
   pattern: '/admin/structure/views/view/{view}/edit/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Routing\ViewsUIController::edit'
     display_id: NULL
@@ -93,8 +115,9 @@ views_ui.edit.display:
 views_ui.preview:
   pattern: '/admin/structure/views/view/{view}/preview/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _entity_form: 'view.preview'
     display_id: NULL
@@ -103,6 +126,11 @@ views_ui.preview:
 
 views_ui.breakLock:
   pattern: '/admin/structure/views/view/{view}/break-lock'
+  options:
+    parameters:
+      view:
+        converter: 'paramconverter.entity'
+        type: 'view'
   defaults:
     _form: '\Drupal\views_ui\Form\BreakLockForm'
     display_id: NULL
@@ -112,8 +140,9 @@ views_ui.breakLock:
 views_ui.form.addItem:
   pattern: '/admin/structure/views/{js}/add-item/{view}/{display_id}/{type}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\AddItem::getForm'
   requirements:
@@ -123,8 +152,9 @@ views_ui.form.addItem:
 views_ui.form.editDetails:
   pattern: '/admin/structure/views/{js}/edit-details/{view}/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\EditDetails::getForm'
   requirements:
@@ -134,8 +164,9 @@ views_ui.form.editDetails:
 views_ui.form.reorderDisplays:
   pattern: '/admin/structure/views/{js}/reorder-displays/{view}/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ReorderDisplays::getForm'
   requirements:
@@ -145,8 +176,9 @@ views_ui.form.reorderDisplays:
 views_ui.form.analyze:
   pattern: '/admin/structure/views/{js}/analyze/{view}/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Analyze::getForm'
   requirements:
@@ -156,8 +188,9 @@ views_ui.form.analyze:
 views_ui.form.rearrange:
   pattern: '/admin/structure/views/{js}/rearrange/{view}/{display_id}/{type}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Rearrange::getForm'
   requirements:
@@ -167,8 +200,9 @@ views_ui.form.rearrange:
 views_ui.form.rearrangeFilter:
   pattern: '/admin/structure/views/{js}/rearrange-filter/{view}/{display_id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\RearrangeFilter::getForm'
   requirements:
@@ -178,8 +212,9 @@ views_ui.form.rearrangeFilter:
 views_ui.form.display:
   pattern: '/admin/structure/views/{js}/display/{view}/{display_id}/{type}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Display::getForm'
   requirements:
@@ -189,8 +224,9 @@ views_ui.form.display:
 views_ui.form.configItem:
   pattern: '/admin/structure/views/{js}/config-item/{view}/{display_id}/{type}/{id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItem::getForm'
   requirements:
@@ -200,8 +236,9 @@ views_ui.form.configItem:
 views_ui.form.configItemExtra:
   pattern: '/admin/structure/views/{js}/config-item-extra/{view}/{display_id}/{type}/{id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItemExtra::getForm'
   requirements:
@@ -211,8 +248,9 @@ views_ui.form.configItemExtra:
 views_ui.form.configItemGroup:
   pattern: '/admin/structure/views/{js}/config-item-group/{view}/{display_id}/{type}/{id}'
   options:
-    tempstore:
-      view: 'views'
+    parameters:
+      view:
+        converter: 'paramconverter.views_ui'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItemGroup::getForm'
     form_state: NULL
diff --git a/core/modules/views_ui/views_ui.services.yml b/core/modules/views_ui/views_ui.services.yml
index 34b2740..d99a544 100644
--- a/core/modules/views_ui/views_ui.services.yml
+++ b/core/modules/views_ui/views_ui.services.yml
@@ -1,6 +1,6 @@
 services:
   paramconverter.views_ui:
     class: Drupal\views_ui\ParamConverter\ViewUIConverter
-    arguments: ['@user.tempstore']
+    arguments: ['@plugin.manager.entity', '@user.tempstore']
     tags:
       - { name: paramconverter }
