diff --git a/core/core.services.yml b/core/core.services.yml
index 640440b..30f4d14 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -208,6 +208,7 @@ services:
     class: Drupal\Core\TypedData\TypedDataManager
     arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
     calls:
+      - [setContainer, ['@service_container']]
       - [setValidationConstraintManager, ['@validation.constraint']]
   validation.constraint:
     class: Drupal\Core\Validation\ConstraintManager
@@ -292,13 +293,20 @@ services:
       - { name: route_filter }
   paramconverter_manager:
     class: Drupal\Core\ParamConverter\ParamConverterManager
+    calls:
+      - [setContainer, ['@service_container']]
     tags:
       - { name: route_enhancer }
-  paramconverter.entity:
-    class: Drupal\Core\ParamConverter\EntityConverter
+  paramconverter_subscriber:
+    class: Drupal\Core\EventSubscriber\ParamConverterSubscriber
     tags:
-      - { name: paramconverter }
-    arguments: ['@plugin.manager.entity']
+      - { name: event_subscriber }
+    arguments: ['@paramconverter_manager']
+  paramconverter.typeddata:
+    class: Drupal\Core\TypedData\TypedDataConverter
+    tags:
+      - { name: paramconverter, priority: -10 }
+    arguments: ['@typed_data']
   reverse_proxy_subscriber:
     class: Drupal\Core\EventSubscriber\ReverseProxySubscriber
     tags:
diff --git a/core/lib/Drupal/Core/Controller/ControllerResolver.php b/core/lib/Drupal/Core/Controller/ControllerResolver.php
index 385f198..06a449a 100644
--- a/core/lib/Drupal/Core/Controller/ControllerResolver.php
+++ b/core/lib/Drupal/Core/Controller/ControllerResolver.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\Controller;
 
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
 use Symfony\Component\HttpKernel\Log\LoggerInterface;
 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index c3b6994..c590122 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -57,7 +57,7 @@ public function register(ContainerBuilder $container) {
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
     $container->addCompilerPass(new RegisterAccessChecksPass());
-    // Add a compiler pass for upcasting of entity route parameters.
+    // Add a compiler pass for upcasting route parameters.
     $container->addCompilerPass(new RegisterParamConvertersPass());
     $container->addCompilerPass(new RegisterRouteEnhancersPass());
     // Add a compiler pass for registering services needing destruction.
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
index 6fe1447..1948727 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterParamConvertersPass.php
@@ -23,26 +23,14 @@ 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();
     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));
-      }
+      $manager->addMethodCall('addConverter', array($id, $priority));
     }
   }
 }
diff --git a/core/lib/Drupal/Core/Entity/Entity.php b/core/lib/Drupal/Core/Entity/Entity.php
index 33a62ce..77f3975 100644
--- a/core/lib/Drupal/Core/Entity/Entity.php
+++ b/core/lib/Drupal/Core/Entity/Entity.php
@@ -13,6 +13,7 @@
 use Drupal\Core\TypedData\TypedDataInterface;
 use IteratorAggregate;
 use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Defines a base entity class.
@@ -77,6 +78,26 @@ public function __construct(array $values, $entity_type) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public static function load($id, array $definition, ContainerInterface $container) {
+    $entity_type = substr($definition['type'], strlen('entity:'));
+    $bundle = NULL;
+    if (strpos(':', $entity_type) !== FALSE) {
+      list($entity_type, $bundle) = explode($entity_type, 2);
+    }
+
+    if (!$storage = $container->get('plugin.manager.entity')->getStorageController($entity_type)) {
+      throw new \InvalidArgumentException(sprintf('Could not retrieve storage controller for the %s entity type', $entity_type));
+    }
+
+    $entity = $storage->load($id);
+    if ($entity && (!isset($bundle) || $entity->bundle() == $bundle)) {
+      return $entity;
+    }
+  }
+
+  /**
    * Implements \Drupal\Core\Entity\EntityInterface::id().
    */
   public function id() {
diff --git a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
index a3ffcb9..f0b0c92 100644
--- a/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
+++ b/core/lib/Drupal/Core/Entity/EntityBCDecorator.php
@@ -12,6 +12,7 @@
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\TypedData\TypedDataInterface;
 use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides backwards compatible (BC) access to entity fields.
@@ -68,6 +69,13 @@ function __construct(EntityNG $decorated, array &$definitions) {
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public static function load($id, array $definition, ContainerInterface $container) {
+    return Entity::load($id, $definition, $container);
+  }
+
+  /**
    * Overrides Entity::getNGEntity().
    */
   public function getNGEntity() {
diff --git a/core/lib/Drupal/Core/Entity/EntityInterface.php b/core/lib/Drupal/Core/Entity/EntityInterface.php
index e965b8e..c4a4488 100644
--- a/core/lib/Drupal/Core/Entity/EntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityInterface.php
@@ -10,6 +10,7 @@
 use Drupal\Core\TypedData\AccessibleInterface;
 use Drupal\Core\TypedData\ComplexDataInterface;
 use Drupal\Core\TypedData\IdentifiableInterface;
+use Drupal\Core\TypedData\LoadableInterface;
 use Drupal\Core\TypedData\TranslatableInterface;
 
 /**
@@ -28,7 +29,7 @@
  * @see \Drupal\Core\TypedData\TypedDataManager
  * @see \Drupal\Core\Field\FieldInterface
  */
-interface EntityInterface extends IdentifiableInterface, ComplexDataInterface, AccessibleInterface, TranslatableInterface {
+interface EntityInterface extends IdentifiableInterface, ComplexDataInterface, AccessibleInterface, TranslatableInterface, LoadableInterface {
 
   /**
    * Returns the entity UUID (Universally Unique Identifier).
diff --git a/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php
new file mode 100644
index 0000000..f9a0a69
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\EventSubscriber\ParamConverterSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Core\ParamConverter\ParamConverterManager;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Drupal\Core\Routing\RoutingEvents;
+use Drupal\Core\Routing\RouteBuildEvent;
+
+/**
+ * Event subscriber for registering parameter converters with routes.
+ */
+class ParamConverterSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The parameter converter manager.
+   *
+   * @var \Drupal\Core\ParamConverter\ParamConverterManager
+   */
+  protected $paramConverterManager;
+
+  /**
+   * Constructs a new ParamConverterSubscriber.
+   *
+   * @param \Drupal\Core\ParamConverter\ParamConverterManager $param_converter_manager
+   *   The parameter converter manager that will be responsible for upcasting
+   *   request attributes.
+   */
+  public function __construct(ParamConverterManager $param_converter_manager) {
+    $this->paramConverterManager = $param_converter_manager;
+  }
+
+  /**
+   * Applies parameter converters to route parameters.
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The event to process.
+   */
+  public function onRoutingRouteAlterSetParameterConverters(RouteBuildEvent $event) {
+    $this->paramConverterManager->setRouteParameterConverters($event->getRouteCollection());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  static function getSubscribedEvents() {
+    $events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetParameterConverters', 10);
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/TypedDataSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/TypedDataSubscriber.php
new file mode 100644
index 0000000..9b05d6b
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/TypedDataSubscriber.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\EventSubscriber\TypedDataSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Drupal\Core\TypedData\Resolver\ResolverManager;
+use Drupal\Core\TypedData\TypedDataDetector;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Drupal\Core\Routing\RoutingEvents;
+use Drupal\Core\Routing\RouteBuildEvent;
+
+/**
+ * Typed data subscriber for route build events.
+ */
+class TypedDataSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The typed data resolver.
+   *
+   * @var \Drupal\Core\TypedData\Resolver\ResolverManager
+   */
+  protected $resolverManager;
+
+  /**
+   * Constructs a TypedDataSubscriber object.
+   */
+  public function __construct(ResolverManager $resolver_manager) {
+    $this->resolverManager = $resolver_manager;
+  }
+
+  /**
+   * Generates typed data definition for route arguments.
+   *
+   * @param \Drupal\Core\Routing\RouteBuildEvent $event
+   *   The event to process.
+   */
+  public function onRoutingRouteAlterSetAccessCheck(RouteBuildEvent $event) {
+    $this->resolverManager->resolveParameterTypes($event->getRouteCollection());
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    // Setting very low priority to ensure typed data discovery runs after
+    $events[RoutingEvents::ALTER][] = array('onRoutingRouteAlterSetAccessCheck', 20);
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
deleted file mode 100644
index 50b7d7c..0000000
--- a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\Core\ParamConverter\EntityConverter.
- */
-
-namespace Drupal\Core\ParamConverter;
-
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
-use Drupal\Core\Entity\EntityManager;
-
-/**
- * This class allows the upcasting of entity ids to the respective entity
- * object.
- */
-class EntityConverter implements ParamConverterInterface {
-
-  /**
-   * Entity manager which performs the upcasting in the end.
-   *
-   * @var \Drupal\Core\Entity\EntityManager
-   */
-  protected $entityManager;
-
-  /**
-   * Constructs a new EntityConverter.
-   *
-   * @param \Drupal\Core\Entity\EntityManager $entityManager
-   *   The entity manager.
-   */
-  public function __construct(EntityManager $entityManager) {
-    $this->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.
-   */
-  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);
-        $entity = $storageController->load($value);
-        $variables[$name] = $entity;
-
-        // Mark this variable as converted.
-        $converted[] = $name;
-      }
-    }
-  }
-}
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
index 74307c2..c1265fc 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\ParamConverter;
 
+use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -17,13 +18,34 @@
   /**
    * Allows to convert variables to their corresponding objects.
    *
-   * @param array &$variables
-   *   Array of values to convert to their corresponding objects, if applicable.
+   * @param mixed $definition
+   *   The parameter definition provided in the route options.
+   * @param string $name
+   *   The name of the parameter.
+   * @param array $defaults
+   *   The route defaults array.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   *
+   * @return mixed|null
+   *   The converted parameter value.
+   */
+  public function convert($definition, $name, array $defaults, Request $request);
+
+  /**
+   * Determines if the converter applies to a specific route and variable.
+   *
+   * @param mixed $definition
+   *   The parameter definition provided in the route options.
+   * @param string $name
+   *   The name of the parameter.
    * @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.
+   *   The route to consider attaching to.
+   *
+   * @return bool
+   *   TRUE if the converter applies to the passed route and parameter, FALSE
+   *   otherwise.
    */
-  public function process(array &$variables, Route $route, array &$converted);
+  public function applies($definition, $name, Route $route);
+
 }
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
index be5676e..5d5b0b4 100644
--- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
@@ -7,14 +7,13 @@
 
 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\DependencyInjection\ContainerAware;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\Routing\RouteCollection;
 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,167 @@
  * 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 {
+
+  /**
+   * An array of registered converter service ids.
+   *
+   * @var array
+   */
+  protected $converterIds = array();
+
+  /**
+   * Array of registered converter service ids sorted by their priority.
+   *
+   * @var array
+   */
+  protected $sortedConverterIds;
 
   /**
-   * Converters managed by the ParamConverterManager.
+   * Array of loaded converter services keyed by their ids.
    *
    * @var array
    */
-  protected $converters;
+  protected $converters = array();
 
   /**
-   * Adds a converter to the paramconverter service.
+   * Registers a parameter converter with the manager.
    *
-   * @see \Drupal\Core\DependencyInjection\Compiler\RegisterParamConvertersPass
+   * @param string $converter
+   *   The parameter converter service id to register.
+   * @param int $priority
+   *   (optional) The priority of the converter. Defaults to 0.
    *
-   * @param \Drupal\Core\ParamConverter\ParamConverterInterface $converter
-   *   The converter to add.
+   * @return \Drupal\Core\ParamConverter\ParamConverterManager
+   *   The called object for chaining.
    */
-  public function addConverter(ParamConverterInterface $converter) {
-    $this->converters[] = $converter;
+  public function addConverter($converter, $priority = 0) {
+    $converter = substr($converter, strlen('paramconverter.'));
+    if (empty($this->converterIds[$priority])) {
+      $this->converterIds[$priority] = array();
+    }
+    $this->converterIds[$priority][] = $converter;
+    unset($this->sortedConverterIds);
     return $this;
   }
 
   /**
-   * Implements \Symfony\Cmf\Component\Routing\Enhancer\ŖouteEnhancerIterface.
+   * Sorts the converter service ids and flattens them.
    *
-   * Iterates over all registered converters and allows them to alter the
-   * defaults.
+   * @return array
+   *   The sorted parameter converter service ids.
+   */
+  public function getConverterIds() {
+    if (!isset($this->sortedConverterIds)) {
+      krsort($this->converterIds);
+      $this->sortedConverterIds = array();
+      foreach ($this->converterIds as $resolvers) {
+        $this->sortedConverterIds = array_merge($this->sortedConverterIds, $resolvers);
+      }
+    }
+    return $this->sortedConverterIds;
+  }
+
+  /**
+   * For each route, saves a list of applicable converters to the route.
+   *
+   * @param \Symfony\Component\Routing\RouteCollection $routes
+   *   A collection of routes to apply converters to.
+   */
+  public function setRouteParameterConverters(RouteCollection $routes) {
+    foreach ($routes->all() as $route) {
+      if (!$parameters = $route->getOption('parameters')) {
+        // Continue with the next route if no parameters have been defined.
+        continue;
+      }
+
+      // Loop over all defined parameters and look up the right converter.
+      foreach ($parameters as $name => &$definition) {
+        if (isset($definition['converter'])) {
+          // Skip parameters that already have a manually set converter.
+          continue;
+        }
+
+        foreach ($this->getConverterIds() as $converter) {
+          if ($this->getConverter($converter)->applies($definition, $name, $route)) {
+            $definition['converter'] = $converter;
+            break;
+          }
+        }
+      }
+
+      // Override the parameters array.
+      $route->setOption('parameters', $parameters);
+    }
+  }
+
+  /**
+   * Invokes the registered converter for each defined parameter on a route.
    *
    * @param array $defaults
-   *   The getRouteDefaults array.
+   *   The route defaults array.
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The current request.
    *
+   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+   *   If one of the assigned converters returned NULL because the given
+   *   variable could not be converted.
+   *
    * @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];
 
-    foreach ($this->converters as $converter) {
-      $converter->process($defaults, $route, $converters);
+    // Skip this enhancer if there are no parameter definitions.
+    if (!$parameters = $route->getOption('parameters') ?: array()) {
+      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) {
+    // Invoke the registered converter for each parameter.
+    foreach ($parameters as $parameter => $definition) {
+      if (array_key_exists($parameter, $defaults) && $defaults[$parameter] === NULL) {
+        // Do not try to convert anything that is already set to NULL.
+        continue;
+      }
+
+      if (!isset($definition['converter'])) {
+        // Continue if no converter has been specified.
+        continue;
+      }
+
+      // If a converter returns NULL it means that the parameter could not be
+      // converted in which case we throw a 404.
+      $defaults[$parameter] = $this->getConverter($definition['converter'])->convert($definition, $parameter, $defaults, $request);
+      if (!isset($defaults[$parameter])) {
         throw new NotFoundHttpException();
       }
     }
 
     return $defaults;
   }
+
+  /**
+   * Lazy-loads converter services.
+   *
+   * @param string $converter
+   *   The service id of converter service to load.
+   *
+   * @return \Drupal\Core\ParamConverter\ParamConverterInterface
+   *   The loaded converter service identified by the given service id.
+   *
+   * @throws \InvalidArgumentException
+   *   If the given service id is not a registered converter.
+   */
+  protected function getConverter($converter) {
+    if (isset($this->converters[$converter])) {
+      return $this->converters[$converter];
+    }
+    if (!in_array($converter, $this->getConverterIds())) {
+      throw new \InvalidArgumentException(sprintf('No converter has been registered for %s', $converter));
+    }
+    return $this->converters[$converter] = $this->container->get("paramconverter.$converter");
+  }
+
 }
+
diff --git a/core/lib/Drupal/Core/TypedData/LoadableInterface.php b/core/lib/Drupal/Core/TypedData/LoadableInterface.php
new file mode 100644
index 0000000..12eeaea
--- /dev/null
+++ b/core/lib/Drupal/Core/TypedData/LoadableInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\TypedData\LoadableInterface.
+ */
+
+namespace Drupal\Core\TypedData;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Interface for loadable typed data objects.
+ */
+interface LoadableInterface {
+
+  /**
+   * Loads a typed data object.
+   *
+   * @param mixed $id
+   *   The unique identifier of the typed data object to be loaded.
+   * @param array $definition
+   *   The typed data definition.
+   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+   *   The service container this object should use.
+   *
+   * @return \Drupal\Core\TypedData\TypedDataInterface|null
+   *   The loaded typed data object or NULL if it could not be loaded.
+   */
+  public static function load($id, array $definition, ContainerInterface $container);
+
+}
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataConverter.php b/core/lib/Drupal/Core/TypedData/TypedDataConverter.php
new file mode 100644
index 0000000..83a5b5b
--- /dev/null
+++ b/core/lib/Drupal/Core/TypedData/TypedDataConverter.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\ParamConverter\TypedDataConverter.
+ */
+
+namespace Drupal\Core\TypedData;
+
+use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Component\Utility\String;
+use Drupal\Core\ParamConverter\ParamConverterInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+/**
+ * Upcasts request attributes to typed data objects.
+ */
+class TypedDataConverter implements ParamConverterInterface {
+
+  /**
+   * The typed data manager.
+   *
+   * @var \Drupal\Core\TypedData\TypedDataManager
+   */
+  protected $typedDataManager;
+
+  /**
+   * Constructs a new TypedDataConverter object.
+   *
+   * @param \Drupal\Core\TypedData\TypedDataManager $typed_data_manager
+   *   The typed data manager.
+   */
+  public function __construct(TypedDataManager $typed_data_manager) {
+    $this->typedDataManager = $typed_data_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function convert($definition, $name, array $defaults, Request $request) {
+    // Only continue if there is a value for the given parameter.
+    if (!isset($defaults[$name])) {
+      return;
+    }
+
+    // Remove keys that do not belong to the typed data definition.
+    unset($definition['converter']);
+
+    // Allow per-data definition overrides of the used classes, i.e. take over
+    // classes specified in the data definition.
+    $original = $this->typedDataManager->getDefinition($definition['type']);
+    $key = empty($definition['list']) ? 'class' : 'list class';
+    if (isset($definition[$key])) {
+      $class = $definition[$key];
+    }
+    elseif (isset($original[$key])) {
+      $class = $original[$key];
+    }
+
+    if (!isset($class)) {
+      throw new PluginException(String::format('The plugin %plugin did not specify an instance class.', array('%plugin' => $definition['type'])));
+    }
+
+    // If the given typed data type is not loadable, just create an instance.
+    if (!is_subclass_of($class, 'Drupal\Core\TypedData\LoadableInterface')) {
+      return $this->typedDataManager->create($definition, $defaults[$name]);
+    }
+
+    // Try to load the typed data object via the typed data manager.
+    return $this->typedDataManager->load($defaults[$name], $definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies($definition, $name, Route $route) {
+    return !empty($definition['type']) && $this->typedDataManager->getDefinition($definition['type']);
+  }
+
+}
diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
index 5c48fb0..e2425aa 100644
--- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php
+++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php
@@ -8,6 +8,7 @@
 namespace Drupal\Core\TypedData;
 
 use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Component\Utility\String;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Language\LanguageManager;
@@ -16,13 +17,15 @@
 use Drupal\Core\TypedData\Validation\MetadataFactory;
 use Drupal\Core\Validation\ConstraintManager;
 use Drupal\Core\Validation\DrupalTranslator;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Validator\ValidatorInterface;
 use Symfony\Component\Validator\Validation;
 
 /**
  * Manages data type plugins.
  */
-class TypedDataManager extends DefaultPluginManager {
+class TypedDataManager extends DefaultPluginManager implements ContainerAwareInterface {
 
   /**
    * The validator used for validating typed data.
@@ -45,6 +48,13 @@ class TypedDataManager extends DefaultPluginManager {
    */
   protected $prototypes = array();
 
+  /**
+   * The container.
+   *
+   * @var \Symfony\Component\DependencyInjection\ContainerInterface
+   */
+  protected $container;
+
   public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, LanguageManager $language_manager, ModuleHandlerInterface $module_handler) {
     $this->alterInfo($module_handler, 'data_type_info');
     $this->setCacheBackend($cache_backend, $language_manager, 'typed_data:types');
@@ -56,6 +66,13 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   }
 
   /**
+   * {@inheritdoc}
+   */
+  public function setContainer(ContainerInterface $container = NULL) {
+    $this->container = $container;
+  }
+
+  /**
    * Implements \Drupal\Component\Plugin\PluginManagerInterface::createInstance().
    *
    * @param string $plugin_id
@@ -382,4 +399,48 @@ public function getConstraints($definition) {
     }
     return $constraints;
   }
+
+  /**
+   * Loads a typed data object by its id.
+   *
+   * @param $id
+   *   The unique identifier of the typed data object to be loaded.
+   * @param array $definition
+   *   The data definition array.
+   *
+   * @throws \Drupal\Component\Plugin\Exception\PluginException
+   *   If no instance class was given.
+   * @throws \InvalidArgumentException
+   *   If the given instance class does not implement the LoadableInterface.
+   *
+   * @return \Drupal\Core\TypedData\TypedDataInterface|null
+   *   The loaded typed data object or NULL if it could not be loaded.
+   */
+  public function load($id, array $definition) {
+    $original_definition = $this->discovery->getDefinition($definition['type']);
+    if (!isset($original_definition)) {
+      throw new \InvalidArgumentException(String::format('Invalid data type (%plugin) has been given.', array('%plugin' => $definition['type'])));
+    }
+
+    // Allow per-data definition overrides of the used classes, i.e. take over
+    // classes specified in the data definition.
+    $key = empty($definition['list']) ? 'class' : 'list class';
+    if (isset($definition[$key])) {
+      $class = $definition[$key];
+    }
+    elseif (isset($original_definition[$key])) {
+      $class = $original_definition[$key];
+    }
+
+    if (!isset($class)) {
+      throw new PluginException(String::format('The plugin %plugin did not specify an instance class.', array('%plugin' => $definition['type'])));
+    }
+
+    // The instance class has to implement the LoadableInterface.
+    if (!in_array('Drupal\Core\TypedData\LoadableInterface', class_implements($class))) {
+      throw new \InvalidArgumentException('The given class has to implement the LoadableInterface.');
+    }
+
+    return $class::load($id, $definition, $this->container);
+  }
 }
diff --git a/core/modules/action/action.routing.yml b/core/modules/action/action.routing.yml
index 19e1703..1a134e5 100644
--- a/core/modules/action/action.routing.yml
+++ b/core/modules/action/action.routing.yml
@@ -18,6 +18,10 @@ action_admin_configure:
     _entity_form: 'action.edit'
   requirements:
     _permission: 'administer actions'
+  options:
+    parameters:
+      action:
+        type: 'entity:action'
 
 action_delete:
   pattern: 'admin/config/system/actions/configure/{action}/delete'
@@ -25,4 +29,8 @@ action_delete:
     _entity_form: 'action.delete'
   requirements:
     _permission: 'administer actions'
+  options:
+    parameters:
+      action:
+        type: 'entity:action'
 
diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml
index 2c69045..96ba963 100644
--- a/core/modules/aggregator/aggregator.routing.yml
+++ b/core/modules/aggregator/aggregator.routing.yml
@@ -18,6 +18,10 @@ aggregator_feed_items_delete:
     _entity_form: 'aggregator_feed.remove_items'
   requirements:
     _permission: 'administer news feeds'
+  options:
+    parameters:
+      aggregator_feed:
+        type: 'entity:aggregator_feed'
 
 aggregator_feed_delete:
   pattern: '/admin/config/services/aggregator/delete/feed/{aggregator_feed}'
@@ -25,6 +29,10 @@ aggregator_feed_delete:
     _entity_form: 'aggregator_feed.delete'
   requirements:
     _permission: 'administer news feeds'
+  options:
+    parameters:
+      aggregator_feed:
+        type: 'entity:aggregator_feed'
 
 aggregator_feed_add:
   pattern: '/admin/config/services/aggregator/add/feed'
@@ -39,6 +47,10 @@ aggregator_feed_refresh:
     _controller: '\Drupal\aggregator\Controller\AggregatorController::feedRefresh'
   requirements:
     _permission: 'administer news feeds'
+  options:
+    parameters:
+      aggregator_feed:
+        type: 'entity:aggregator_feed'
 
 aggregator_opml_add:
   pattern: '/admin/config/services/aggregator/add/opml'
diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml
index cabd4cb..a25b667 100644
--- a/core/modules/block/block.routing.yml
+++ b/core/modules/block/block.routing.yml
@@ -4,6 +4,10 @@ block_admin_block_delete:
     _entity_form: 'block.delete'
   requirements:
     _permission: 'administer blocks'
+  options:
+    parameters:
+      block:
+        type: 'entity:block'
 
 block_admin_edit:
   pattern: '/admin/structure/block/manage/{block}'
@@ -11,6 +15,10 @@ block_admin_edit:
     _entity_form: 'block.default'
   requirements:
     _entity_access: 'block.update'
+  options:
+    parameters:
+      block:
+        type: 'entity:block'
 
 block_admin_display:
   pattern: '/admin/structure/block'
diff --git a/core/modules/block/custom_block/custom_block.routing.yml b/core/modules/block/custom_block/custom_block.routing.yml
index 2178d91..2702b86 100644
--- a/core/modules/block/custom_block/custom_block.routing.yml
+++ b/core/modules/block/custom_block/custom_block.routing.yml
@@ -18,6 +18,10 @@ custom_block_add_form:
     _content: 'Drupal\custom_block\Controller\CustomBlockController::addForm'
   requirements:
     _permission: 'administer blocks'
+  options:
+    parameters:
+      custom_block_type:
+        type: 'entity:custom_block_type'
 
 custom_block_type_delete:
   pattern: '/admin/structure/custom-blocks/manage/{custom_block_type}/delete'
@@ -25,3 +29,7 @@ custom_block_type_delete:
     _entity_form: 'custom_block_type.delete'
   requirements:
     _permission: 'administer blocks'
+  options:
+    parameters:
+      custom_block_type:
+        type: 'entity:custom_block_type'
diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml
index b62c118..0c86816 100644
--- a/core/modules/comment/comment.routing.yml
+++ b/core/modules/comment/comment.routing.yml
@@ -4,6 +4,10 @@ comment_edit_page:
     _entity_form: 'comment.default'
   requirements:
     _entity_access: 'comment.update'
+  options:
+    parameters:
+      comment:
+        type: 'entity:comment'
 
 comment_approve:
   pattern: '/comment/{comment}/approve'
@@ -12,6 +16,10 @@ comment_approve:
     entity_type: 'comment'
   requirements:
     _entity_access: 'comment.approve'
+  options:
+    parameters:
+      comment:
+        type: 'entity:comment'
 
 comment_permalink:
   pattern: '/comment/{comment}'
@@ -19,3 +27,7 @@ comment_permalink:
     _controller: '\Drupal\comment\Controller\CommentController::commentPermalink'
   requirements:
     _entity_access: 'comment.view'
+  options:
+    parameters:
+      comment:
+        type: 'entity:comment'
diff --git a/core/modules/contact/contact.routing.yml b/core/modules/contact/contact.routing.yml
index ba47a6a..dfe6195 100644
--- a/core/modules/contact/contact.routing.yml
+++ b/core/modules/contact/contact.routing.yml
@@ -4,6 +4,10 @@ contact_category_delete:
     _entity_form: contact_category.delete
   requirements:
     _entity_access: contact_category.delete
+  options:
+    parameters:
+      contact_category:
+        type: 'entity:contact_category'
 
 contact_category_list:
   pattern: '/admin/structure/contact'
@@ -25,3 +29,7 @@ contact_category_edit:
     _entity_form: contact_category.edit
   requirements:
     _entity_access: contact_category.update
+  options:
+    parameters:
+      contact_category:
+        type: 'entity:contact_category'
diff --git a/core/modules/entity/entity.routing.yml b/core/modules/entity/entity.routing.yml
index 05d7092..f1b5646 100644
--- a/core/modules/entity/entity.routing.yml
+++ b/core/modules/entity/entity.routing.yml
@@ -25,6 +25,10 @@ entity_view_mode.edit:
     _entity_form: 'view_mode.edit'
   requirements:
     _entity_access: 'view_mode.update'
+  options:
+    parameters:
+      view_mode:
+        type: 'entity:view_mode'
 
 entity_view_mode.delete:
   pattern: '/admin/structure/display-modes/view/manage/{view_mode}/delete'
@@ -32,6 +36,10 @@ entity_view_mode.delete:
     _entity_form: 'view_mode.delete'
   requirements:
     _entity_access: 'view_mode.delete'
+  options:
+    parameters:
+      view_mode:
+        type: 'entity:view_mode'
 
 entity_form_mode.list:
   pattern: '/admin/structure/display-modes/form'
@@ -60,6 +68,10 @@ entity_form_mode.edit:
     _entity_form: 'form_mode.edit'
   requirements:
     _entity_access: 'form_mode.update'
+  options:
+    parameters:
+      form_mode:
+        type: 'entity:form_mode'
 
 entity_form_mode.delete:
   pattern: '/admin/structure/display-modes/form/manage/{form_mode}/delete'
@@ -67,3 +79,7 @@ entity_form_mode.delete:
     _entity_form: 'form_mode.delete'
   requirements:
     _entity_access: 'form_mode.delete'
+  options:
+    parameters:
+      form_mode:
+        type: 'entity:form_mode'
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 e994202..0810530 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
@@ -56,21 +56,30 @@ 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('type' => 'entity:field_instance'),
+          ))
         );
         $collection->add("field_ui.instance_edit.$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/field",
           array('_form' => '\Drupal\field_ui\Form\FieldEditForm'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array('type' => 'entity:field_instance'),
+          ))
         );
         $collection->add("field_ui.field_edit.$entity_type", $route);
 
         $route = new Route(
           "$path/fields/{field_instance}/delete",
           array('_entity_form' => 'field_instance.delete'),
-          array('_permission' => 'administer ' . $entity_type . ' fields')
+          array('_permission' => 'administer ' . $entity_type . ' fields'),
+          array('parameters' => array(
+            'field_instance' => array('type' => '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 5442fb0..194182d 100644
--- a/core/modules/filter/filter.routing.yml
+++ b/core/modules/filter/filter.routing.yml
@@ -11,6 +11,10 @@ filter_tips:
     _content: '\Drupal\filter\Controller\FilterController::filterTips'
   requirements:
     _filter_access: 'TRUE'
+  options:
+    parameters:
+      filter_format:
+        type: 'entity:filter_format'
 
 filter_admin_overview:
   pattern: '/admin/config/content/formats'
@@ -33,6 +37,10 @@ filter_format_edit:
     _entity_form: filter_format.edit
   requirements:
     _permission: 'administer filters'
+  options:
+    parameters:
+      filter_format:
+        type: 'entity:filter_format'
 
 filter_admin_disable:
   pattern: '/admin/config/content/formats/manage/{filter_format}/disable'
@@ -40,3 +48,7 @@ filter_admin_disable:
     _entity_form: 'filter_format.disable'
   requirements:
     _filter_disable_format_access: 'TRUE'
+  options:
+    parameters:
+      filter_format:
+        type: 'entity:filter_format'
diff --git a/core/modules/forum/forum.routing.yml b/core/modules/forum/forum.routing.yml
index f7d90f8..980d830 100644
--- a/core/modules/forum/forum.routing.yml
+++ b/core/modules/forum/forum.routing.yml
@@ -4,6 +4,11 @@ forum_delete:
     _form: 'Drupal\forum\Form\DeleteForm'
   requirements:
     _permission: 'administer forums'
+  options:
+    parameters:
+      taxonomy_term:
+        type: 'entity: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 b178d33..dc49706 100644
--- a/core/modules/image/image.routing.yml
+++ b/core/modules/image/image.routing.yml
@@ -4,6 +4,10 @@ image_style_delete:
     _entity_form: 'image_style.delete'
   requirements:
     _permission: 'administer image styles'
+  options:
+    parameters:
+      image_style:
+        type: 'entity:image_style'
 
 image_effect_delete:
   pattern: 'admin/config/media/image-styles/manage/{image_style}/effects/{image_effect}/delete'
@@ -11,3 +15,7 @@ image_effect_delete:
     _form: '\Drupal\image\Form\ImageEffectDeleteForm'
   requirements:
     _permission: 'administer image styles'
+  options:
+    parameters:
+      image_style:
+        type: 'entity:image_style'
diff --git a/core/modules/menu/menu.routing.yml b/core/modules/menu/menu.routing.yml
index 62c54f2..c938647 100644
--- a/core/modules/menu/menu.routing.yml
+++ b/core/modules/menu/menu.routing.yml
@@ -11,6 +11,10 @@ menu_link_reset:
     _entity_form: 'menu_link.reset'
   requirements:
     _permission: 'administer menu'
+  options:
+    parameters:
+      menu_link:
+        type: 'entity:menu_link'
 
 menu_link_delete:
   pattern: 'admin/structure/menu/item/{menu_link}/delete'
@@ -18,6 +22,10 @@ menu_link_delete:
     _entity_form: 'menu_link.delete'
   requirements:
     _access_menu_delete_link: 'TRUE'
+  options:
+    parameters:
+      menu_link:
+        type: 'entity:menu_link'
 
 menu_delete_menu:
   pattern: 'admin/structure/menu/manage/{menu}/delete'
@@ -25,3 +33,7 @@ menu_delete_menu:
     _entity_form: 'menu.delete'
   requirements:
     _access_menu_delete_menu: 'TRUE'
+  options:
+    parameters:
+      menu:
+        type: 'entity:menu'
diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml
index dfdc0a6..266e0ab 100644
--- a/core/modules/node/node.routing.yml
+++ b/core/modules/node/node.routing.yml
@@ -11,6 +11,10 @@ node_page_edit:
     _entity_form: 'node.edit'
   requirements:
     _entity_access: 'node.update'
+  options:
+    parameters:
+      node:
+        type: 'entity:node'
 
 node_delete_confirm:
   pattern: '/node/{node}/delete'
@@ -18,6 +22,10 @@ node_delete_confirm:
     _entity_form: 'node.delete'
   requirements:
     _entity_access: 'node.delete'
+  options:
+    parameters:
+      node:
+        type: 'entity:node'
 
 node_revision_revert_confirm:
   pattern: '/node/{node}/revisions/{node_revision}/revert'
@@ -25,6 +33,10 @@ node_revision_revert_confirm:
     _form: '\Drupal\node\Form\NodeRevisionRevertForm'
   requirements:
     _access_node_revision: 'update'
+  options:
+    parameters:
+      node:
+        type: 'entity:node'
 
 node_revision_delete_confirm:
   pattern: '/node/{node}/revisions/{node_revision}/delete'
@@ -32,6 +44,10 @@ node_revision_delete_confirm:
     _form: '\Drupal\node\Form\NodeRevisionDeleteForm'
   requirements:
     _access_node_revision: 'delete'
+  options:
+    parameters:
+      node:
+        type: 'entity:node'
 
 node_overview_types:
   pattern: '/admin/structure/types'
@@ -54,6 +70,10 @@ node_type_edit:
     _entity_form: 'node_type.edit'
   requirements:
     _permission: 'administer content types'
+  options:
+    parameters:
+      node_type:
+        type: 'entity:node_type'
 
 node_type_edit_default:
   pattern: '/admin/structure/types/manage/{node_type}/edit'
@@ -61,6 +81,10 @@ node_type_edit_default:
     _entity_form: 'node_type.edit'
   requirements:
     _permission: 'administer content types'
+  options:
+    parameters:
+      node_type:
+        type: 'entity:node_type'
 
 node_type_delete_confirm:
   pattern: '/admin/structure/types/manage/{node_type}/delete'
@@ -68,6 +92,10 @@ node_type_delete_confirm:
     _entity_form: 'node_type.delete'
   requirements:
     _entity_access: 'node_type.delete'
+  options:
+    parameters:
+      node_type:
+        type: 'entity:node_type'
 
 node_configure_rebuild_confirm:
   pattern: '/admin/reports/status/rebuild'
diff --git a/core/modules/picture/picture.routing.yml b/core/modules/picture/picture.routing.yml
index c953029..e9f636a 100644
--- a/core/modules/picture/picture.routing.yml
+++ b/core/modules/picture/picture.routing.yml
@@ -18,6 +18,10 @@ picture_mapping_page_edit:
     _entity_form: 'picture_mapping.edit'
   requirements:
     _permission: 'administer pictures'
+  options:
+    parameters:
+      picture_mapping:
+        type: 'entity:picture_mapping'
 
 picture_mapping_page_duplicate:
   pattern: '/admin/config/media/picturemapping/{picture_mapping}/duplicate'
@@ -25,6 +29,10 @@ picture_mapping_page_duplicate:
     _entity_form: 'picture_mapping.duplicate'
   requirements:
     _permission: 'administer pictures'
+  options:
+    parameters:
+      picture_mapping:
+        type: 'entity:picture_mapping'
 
 picture_mapping_action_confirm:
   pattern: '/admin/config/media/picturemapping/{picture_mapping}/delete'
@@ -32,3 +40,7 @@ picture_mapping_action_confirm:
     _entity_form: 'picture_mapping.delete'
   requirements:
     _permission: 'administer pictures'
+  options:
+    parameters:
+      picture_mapping:
+        type: 'entity:picture_mapping'
diff --git a/core/modules/shortcut/shortcut.routing.yml b/core/modules/shortcut/shortcut.routing.yml
index e6bb718..403da9b 100644
--- a/core/modules/shortcut/shortcut.routing.yml
+++ b/core/modules/shortcut/shortcut.routing.yml
@@ -4,6 +4,10 @@ shortcut_link_delete:
     _form: 'Drupal\shortcut\Form\LinkDelete'
   requirements:
     _access_shortcut_link_delete: 'TRUE'
+  options:
+    parameters:
+      menu_link:
+        type: 'entity:menu_link'
 
 shortcut_set_delete:
   pattern: '/admin/config/user-interface/shortcut/manage/{shortcut}/delete'
@@ -11,6 +15,10 @@ shortcut_set_delete:
     _entity_form: 'shortcut.delete'
   requirements:
     _entity_access: 'shortcut.delete'
+  options:
+    parameters:
+      shortcut:
+        type: 'entity:shortcut'
 
 shortcut_set_admin:
   pattern: '/admin/config/user-interface/shortcut'
@@ -32,6 +40,10 @@ shortcut_set_edit:
     _entity_form: 'shortcut.edit'
   requirements:
     _entity_access: 'shortcut.update'
+  options:
+    parameters:
+      shortcut:
+        type: 'entity:shortcut'
 
 shortcut_link_add_inline:
   pattern: '/admin/config/user-interface/shortcut/manage/{shortcut}/add-link-inline'
@@ -39,6 +51,10 @@ shortcut_link_add_inline:
     _controller: 'Drupal\shortcut\Controller\ShortcutController::addShortcutLinkInline'
   requirements:
     _entity_access: 'shortcut.update'
+  options:
+    parameters:
+      shortcut:
+        type: 'entity:shortcut'
 
 shortcut_set_customize:
   pattern: '/admin/config/user-interface/shortcut/manage/{shortcut}'
@@ -46,3 +62,7 @@ shortcut_set_customize:
     _entity_form: 'shortcut.customize'
   requirements:
     _entity_access: 'shortcut.update'
+  options:
+    parameters:
+      shortcut:
+        type: 'entity: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
deleted file mode 100644
index d56ee5f..0000000
--- a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/UpcastingTest.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\system\Tests\ParamConverter\UpcastingTest.
- */
-
-namespace Drupal\system\Tests\ParamConverter;
-
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Web tests for the upcasting.
- */
-class UpcastingTest extends WebTestBase {
-
-  /**
-   * Implement getInfo().
-   */
-  public static function getInfo() {
-    return array(
-      'name' => 'Upcasting tests',
-      'description' => 'Tests upcasting of url arguments to entities.',
-      'group' => 'ParamConverter',
-    );
-  }
-
-  public static $modules = array('paramconverter_test');
-
-  /**
-   * Confirms that all parameters are converted as expected.
-   *
-   * All of these requests end up being proccessed by a controller with this
-   * the signature: f($user, $node, $foo) returning either values or labels
-   * like "user: Dries, node: First post, foo: bar"
-   *
-   * The tests shuffle the parameters around an checks if the right thing is
-   * happening.
-   */
-  public function testUpcasting() {
-    $node = $this->drupalCreateNode(array('title' => $this->randomName(8)));
-    $user = $this->drupalCreateUser(array('access content'));
-    $foo = 'bar';
-
-    // paramconverter_test/test_user_node_foo/{user}/{node}/{foo}
-    $this->drupalGet("paramconverter_test/test_user_node_foo/"  . $user->id() . "/{$node->nid}/$foo");
-    $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'
-    $this->drupalGet("paramconverter_test/test_node_user_user/{$node->nid}/" . $user->id() . "/" . $user->id());
-    $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'
-    $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)');
-  }
-
-  /**
-   * Confirms we can upcast to controller arguments of the same type.
-   */
-  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'
-    $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/lib/Drupal/system/Tests/TypedData/TypedDataTest.php b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
index 3558d20..4b76fdc 100644
--- a/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/TypedData/TypedDataTest.php
@@ -614,4 +614,21 @@ public function testTypedDataValidation() {
     $this->assertEqual($violations[0]->getInvalidValue(), 'string');
     $this->assertIdentical($violations[0]->getPropertyPath(), '0.value');
   }
+
+  /**
+   * Tests loading of typed data objects that implement LoadableInterface.
+   */
+  public function testTypedDataLoading() {
+    // Generate a file for testing typed data loading.
+    file_unmanaged_copy(DRUPAL_ROOT . '/core/misc/druplicon.png', 'public://example.png');
+    $image = entity_create('file', array('uri' => 'public://example.png'));
+    $image->save();
+
+    $loaded = \Drupal::typedData()->load($image->id(), array(
+      'type' => 'entity:file',
+    ));
+
+    $this->assertNotIdentical(FALSE, $loaded, 'Successfully loaded the image entity.');
+    $this->assertIdentical($image->uuid(), $loaded->uuid(), 'Successfully loaded the right image entity..');
+  }
 }
diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml
index 301ab6d..7bfb639 100644
--- a/core/modules/system/system.routing.yml
+++ b/core/modules/system/system.routing.yml
@@ -101,6 +101,10 @@ date_format_edit:
     _entity_form: 'date_format.edit'
   requirements:
     _entity_access: 'date_format.update'
+  options:
+    parameters:
+      date_format:
+        type: 'entity:date_format'
 
 date_format_delete:
   pattern: 'admin/config/regional/date-time/formats/manage/{date_format}/delete'
@@ -108,6 +112,10 @@ date_format_delete:
     _entity_form: 'date_format.delete'
   requirements:
     _entity_access: 'date_format.delete'
+  options:
+    parameters:
+      date_format:
+        type: 'entity:date_format'
 
 date_format_localize_reset:
   pattern: 'admin/config/regional/date-time/locale/{langcode}/reset'
diff --git a/core/modules/system/tests/modules/paramconverter_test/lib/Drupal/paramconverter_test/TestControllers.php b/core/modules/system/tests/modules/paramconverter_test/lib/Drupal/paramconverter_test/TestControllers.php
deleted file mode 100644
index ca95200..0000000
--- a/core/modules/system/tests/modules/paramconverter_test/lib/Drupal/paramconverter_test/TestControllers.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\paramconverter_test\TestControllers.
- */
-
-namespace Drupal\paramconverter_test;
-
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Controller routine for testing the paramconverter.
- */
-class TestControllers {
-
-  public function testUserNodeFoo($user, $node, $foo) {
-    $retval = "user: " . (is_object($user) ? $user->label() : $user);
-    $retval .= ", node: " . (is_object($node) ? $node->label() : $node);
-    $retval .= ", foo: " . (is_object($foo) ? $foo->label() : $foo);
-    return $retval;
-  }
-
-  public function testNodeSetParent(EntityInterface $node, EntityInterface $parent) {
-    return "Setting '{$parent->title}' as parent of '{$node->title}'.";
-  }
-}
diff --git a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml
deleted file mode 100644
index 4aa2455..0000000
--- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.info.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: "ParamConverter test"
-type: module
-description: "Support module for paramconverter testing."
-package: Testing
-version: VERSION
-core: 8.x
-hidden: TRUE
diff --git a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module b/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module
deleted file mode 100644
index c37a9e2..0000000
--- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.module
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-/**
- * @file
- * Intentionally blank file.
- */
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
deleted file mode 100644
index 9d226e4..0000000
--- a/core/modules/system/tests/modules/paramconverter_test/paramconverter_test.routing.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-paramconverter_test_user_node_foo:
-  pattern: '/paramconverter_test/test_user_node_foo/{user}/{node}/{foo}'
-  defaults:
-    _content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
-  requirements:
-    _access: 'TRUE'
-
-paramconverter_test_node_user_user:
-  pattern: '/paramconverter_test/test_node_user_user/{node}/{foo}/{user}'
-  defaults:
-    _content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
-  requirements:
-    _access: 'TRUE'
-  options:
-    converters:
-      foo: 'user'
-
-paramconverter_test_node_node_foo:
-  pattern: '/paramconverter_test/test_node_node_foo/{user}/{node}/{foo}'
-  defaults:
-    _content: '\Drupal\paramconverter_test\TestControllers::testUserNodeFoo'
-  requirements:
-    _access: 'TRUE'
-  options:
-    converters:
-      user: 'node'
-
-paramconverter_test_node_set_parent:
-  pattern: '/paramconverter_test/node/{node}/set/parent/{parent}'
-  requirements:
-    _access: 'TRUE'
-  defaults:
-    _content: '\Drupal\paramconverter_test\TestControllers::testNodeSetParent'
-  options:
-    converters:
-      parent: 'node'
diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml
index 389ca7c..8b15837 100644
--- a/core/modules/taxonomy/taxonomy.routing.yml
+++ b/core/modules/taxonomy/taxonomy.routing.yml
@@ -11,3 +11,7 @@ taxonomy_term_add:
     _content: '\Drupal\taxonomy\Controller\TaxonomyController::addForm'
   requirements:
     _access_taxonomy_term_create: 'taxonomy_term'
+  options:
+    parameters:
+      taxonomy_vocabulary:
+        type: 'entity:taxonomy_vocabulary'
diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml
index 10ec95d..2235bca 100644
--- a/core/modules/user/user.routing.yml
+++ b/core/modules/user/user.routing.yml
@@ -60,6 +60,10 @@ user_role_edit:
     _entity_form: user_role.default
   requirements:
     _entity_access: user_role.update
+  options:
+    parameters:
+      user_role:
+        type: 'entity:user_role'
 
 user_role_delete:
   pattern: '/admin/people/roles/manage/{user_role}/delete'
@@ -67,6 +71,10 @@ user_role_delete:
     _entity_form: user_role.delete
   requirements:
     _entity_access: user_role.delete
+  options:
+    parameters:
+      user_role:
+        type: 'entity:user_role'
 
 user_pass:
   pattern: '/user/password'
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
deleted file mode 100644
index f828de1..0000000
--- a/core/modules/views_ui/lib/Drupal/views_ui/ParamConverter/ViewUIConverter.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\views_ui\ParamConverter\ViewUIConverter.
- */
-
-namespace Drupal\views_ui\ParamConverter;
-
-use Symfony\Component\Routing\Route;
-use Drupal\Core\ParamConverter\ParamConverterInterface;
-use Drupal\user\TempStoreFactory;
-use Drupal\views\ViewStorageInterface;
-use Drupal\views_ui\ViewUI;
-
-/**
- * Provides upcasting for a view entity to be used in the Views UI.
- */
-class ViewUIConverter implements ParamConverterInterface {
-
-  /**
-   * Stores the tempstore factory.
-   *
-   * @var \Drupal\user\TempStoreFactory
-   */
-  protected $tempStoreFactory;
-
-  /**
-   * Constructs a new ViewUIConverter.
-   *
-   * @param \Drupal\user\TempStoreFactory $temp_store_factory
-   *   The factory for the temp store object.
-   */
-  public function __construct(TempStoreFactory $temp_store_factory) {
-    $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.
-   */
-  public function process(array &$variables, Route $route, array &$converted) {
-    // If nothing was specified to convert, return.
-    $options = $route->getOptions();
-    if (!isset($options['tempstore'])) {
-      return;
-    }
-
-    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;
-      }
-    }
-  }
-
-}
diff --git a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
index e3538e6..63cd912 100644
--- a/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
+++ b/core/modules/views_ui/lib/Drupal/views_ui/ViewUI.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\views_ui;
 
+use Drupal\Core\Entity\Entity;
 use Drupal\views\Views;
 use Drupal\Core\Entity\EntityStorageControllerInterface;
 use Drupal\views\ViewExecutable;
@@ -16,6 +17,7 @@
 use Drupal\views\Plugin\views\query\Sql;
 use Drupal\views\Plugin\Core\Entity\View;
 use Drupal\views\ViewStorageInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Stores UI related temporary settings.
@@ -1243,4 +1245,34 @@ public function mergeDefaultDisplaysOptions() {
   public function uriRelationships() {
     return $this->storage->uriRelationships();
   }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function load($id, array $definition, ContainerInterface $container) {
+    $storage = $container->get('plugin.manager.entity')->getStorageController('view');
+    if (!$original = $storage->load($id)) {
+      return;
+    }
+
+    // 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.
+    $store = $container->get('user.tempstore')->get('views');
+    if ($view = $store->get($id)) {
+      if ($original->status()) {
+        $view->enable();
+      }
+      else {
+        $view->disable();
+      }
+      $view->lock = $store->getMetadata($id);
+    }
+    // Otherwise, decorate the existing view for use in the UI.
+    else {
+      $view = new static($original);
+    }
+
+    return $view;
+  }
 }
diff --git a/core/modules/views_ui/views_ui.routing.yml b/core/modules/views_ui/views_ui.routing.yml
index 0d44630..d0d55ee 100644
--- a/core/modules/views_ui/views_ui.routing.yml
+++ b/core/modules/views_ui/views_ui.routing.yml
@@ -47,6 +47,10 @@ views_ui.operation:
   requirements:
     _permission: 'administer views'
     op: 'enable|disable'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
 
 views_ui.clone:
   pattern: '/admin/structure/views/view/{view}/clone'
@@ -54,6 +58,10 @@ views_ui.clone:
     _entity_form: 'view.clone'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
 
 views_ui.delete:
   pattern: '/admin/structure/views/view/{view}/delete'
@@ -61,6 +69,10 @@ views_ui.delete:
     _entity_form: 'view.delete'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
 
 views_ui.autocomplete:
   pattern: '/admin/views/ajax/autocomplete/tag'
@@ -71,35 +83,41 @@ views_ui.autocomplete:
 
 views_ui.edit:
   pattern: '/admin/structure/views/view/{view}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Controller\ViewsUIController::edit'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.edit.display:
   pattern: '/admin/structure/views/view/{view}/edit/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Controller\ViewsUIController::edit'
     display_id: NULL
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.preview:
   pattern: '/admin/structure/views/view/{view}/preview/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _entity_form: 'view.preview'
     display_id: NULL
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.breakLock:
   pattern: '/admin/structure/views/view/{view}/break-lock'
@@ -107,114 +125,138 @@ views_ui.breakLock:
     _entity_form: 'view.break_lock'
   requirements:
     _permission: 'administer views'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
 
 views_ui.form.addItem:
   pattern: '/admin/structure/views/{js}/add-item/{view}/{display_id}/{type}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\AddItem::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.editDetails:
   pattern: '/admin/structure/views/{js}/edit-details/{view}/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\EditDetails::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.reorderDisplays:
   pattern: '/admin/structure/views/{js}/reorder-displays/{view}/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ReorderDisplays::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.analyze:
   pattern: '/admin/structure/views/{js}/analyze/{view}/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Analyze::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.rearrange:
   pattern: '/admin/structure/views/{js}/rearrange/{view}/{display_id}/{type}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Rearrange::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.rearrangeFilter:
   pattern: '/admin/structure/views/{js}/rearrange-filter/{view}/{display_id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\RearrangeFilter::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.display:
   pattern: '/admin/structure/views/{js}/display/{view}/{display_id}/{type}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\Display::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.configItem:
   pattern: '/admin/structure/views/{js}/config-item/{view}/{display_id}/{type}/{id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItem::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.configItemExtra:
   pattern: '/admin/structure/views/{js}/config-item-extra/{view}/{display_id}/{type}/{id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItemExtra::getForm'
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
 
 views_ui.form.configItemGroup:
   pattern: '/admin/structure/views/{js}/config-item-group/{view}/{display_id}/{type}/{id}'
-  options:
-    tempstore:
-      view: 'views'
   defaults:
     _controller: '\Drupal\views_ui\Form\Ajax\ConfigItemGroup::getForm'
     form_state: NULL
   requirements:
     _permission: 'administer views'
     js: 'nojs|ajax'
+  options:
+    parameters:
+      view:
+        type: 'entity:view'
+        class: '\Drupal\views_ui\ViewUI'
diff --git a/core/modules/views_ui/views_ui.services.yml b/core/modules/views_ui/views_ui.services.yml
deleted file mode 100644
index 34b2740..0000000
--- a/core/modules/views_ui/views_ui.services.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-services:
-  paramconverter.views_ui:
-    class: Drupal\views_ui\ParamConverter\ViewUIConverter
-    arguments: ['@user.tempstore']
-    tags:
-      - { name: paramconverter }
