diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index e1147ac..9a5281f 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -12,6 +12,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterNestedMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
+use Drupal\Core\DependencyInjection\Compiler\RegisterEntityParamConvertersPass;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\DependencyInjection\Reference;
@@ -181,6 +182,12 @@ public function build(ContainerBuilder $container) {
     $container->register('first_entry_final_matcher', 'Drupal\Core\Routing\FirstEntryFinalMatcher')
       ->addTag('nested_matcher', array('method' => 'setFinalMatcher'));
 
+    $container->register('paramconverter_manager', 'Drupal\Core\ParamConverter\ParamConverterManager')
+      ->addMethodCall('setContainer', array(new Reference('service_container')));
+    $container->register('paramconverter.subscriber', 'Drupal\Core\EventSubscriber\ParamConverterSubscriber')
+      ->addArgument(new Reference('paramconverter_manager'))
+      ->addTag('event_subscriber');
+
     $container->register('router_processor_subscriber', 'Drupal\Core\EventSubscriber\RouteProcessorSubscriber')
       ->addTag('event_subscriber');
     $container->register('router_listener', 'Symfony\Component\HttpKernel\EventListener\RouterListener')
@@ -245,6 +252,9 @@ public function build(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.
+    $container->addCompilerPass(new RegisterEntityParamConvertersPass());
+
   }
 
 }
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEntityParamConvertersPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEntityParamConvertersPass.php
new file mode 100644
index 0000000..f787065
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterEntityParamConvertersPass.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\DependencyInjection\Compiler\RegisterEntityParamConvertersPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Registers EntityConverter services with the ParamConverterManager.
+ */
+class RegisterEntityParamConvertersPass implements CompilerPassInterface {
+
+  /**
+   * Adds 'paramconverter.entity' services to the param converter service.
+   *
+   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
+   *   The container to process.
+   */
+  public function process(ContainerBuilder $container) {
+    if (!$container->hasDefinition('paramconverter_manager')) {
+      return;
+    }
+
+    $manager = $container->getDefinition('paramconverter_manager');
+    foreach ($container->findTaggedServiceIds('paramconverter.entity') as $id => $attributes) {
+      $manager->addMethodCall('addConverterService', array($id, $attributes[0]['classname']));
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php
new file mode 100644
index 0000000..d4d15db
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ParamConverterSubscriber.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\EventSubscriber\ParamConverterSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Drupal\Core\ParamConverter\ParamConverterManager;
+
+/**
+ * Handles converting request attributes to their appropriate objects.
+ */
+class ParamConverterSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Broker object that handles actually converting parameters.
+   *
+   * @var \Drupal\Core\ParamConverter\ParamConverterManager
+   */
+  protected $paramConverterManager;
+
+  /**
+   * Constructs a new ParamConverterSubscriber.
+   *
+   * @param Drupal\Core\ParamConverter\ParamConverterManager $manager
+   *   The converter manager that will be responsible for converting
+   *   request attributes into their corresponding object values.
+   */
+  public function __construct(ParamConverterManager $manager) {
+    $this->paramConverterManager = $manager;
+  }
+
+  /**
+   * Response with the maintenance page when the site is offline.
+   *
+   * @param Symfony\Component\HttpKernel\Event\FilterControllerEvent $event
+   *   The Event to process.
+   */
+  public function onKernelControllerParamConverter(FilterControllerEvent $event) {
+    $request = $event->getRequest();
+
+    // If this is a legacy request, skip it as we're not doing conversion for
+    // those.
+    // @todo Remove this check once we eliminate the legacy router.
+    if ($request->attributes->has('drupal_menu_item')) {
+      return;
+    }
+
+    $controller = $event->getController();
+
+    $this->paramConverterManager->applyToRequest($controller, $request);
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::CONTROLLER][] = array('onKernelControllerParamConverter', 40);
+    return $events;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/EntityConverter.php b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
new file mode 100644
index 0000000..f264727
--- /dev/null
+++ b/core/lib/Drupal/Core/ParamConverter/EntityConverter.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\ParamConverter\EntityConverter.
+ */
+
+namespace Drupal\Core\ParamConverter;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Parameter converter for entities.
+ *
+ * Each entity type needs to be registered on ParamConverterManager
+ * independently, but all entities can use the same converter.
+ */
+class EntityConverter implements ParamConverterInterface {
+
+  /**
+   * Implements ParamConverterInterface::convert().
+   */
+  public function convert(Request $request, $value, $class, array $arguments = array()) {
+    // Try to retrieve the entity type of the given entity class.
+    foreach (entity_get_info() as $key => $entity_info) {
+      if ($entity_info['class'] == $class) {
+        $entity_type = $key;
+        break;
+      }
+    }
+
+    // Throw an exception if we don't know about the class we're being asked to
+    // convert to.
+    if (!isset($entity_type)) {
+      throw new \InvalidArgumentException("No entity found that uses class $class.");
+    }
+
+    // Load the entity loader, then use it to load the object.
+    // Once again, this should be coming from the Service Container eventually.
+    if ($entities = entity_get_controller($entity_type)->load(array($value))) {
+      return reset($entities);
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/EntityConverterFactory.php b/core/lib/Drupal/Core/ParamConverter/EntityConverterFactory.php
new file mode 100644
index 0000000..2c37238
--- /dev/null
+++ b/core/lib/Drupal/Core/ParamConverter/EntityConverterFactory.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\ParamConverter\EntityConverterFactory.
+ */
+
+namespace Drupal\Core\ParamConverter;
+
+/**
+ * Factory class for the EntityConverter.
+ *
+ * We only ever need one instance of the EntityConverter but every module that
+ * provides an entity type needs to register a service for it. So we use a
+ * factory to return the same instance for each service.
+ */
+class EntityConverterFactory {
+
+  /**
+   * Holds the instantiated EntityConverter object.
+   *
+   * @var \Drupal\Core\ParamConverter\EntityConverter
+   */
+  static protected $converter;
+
+  /**
+   * Returns an EntityConverter object.
+   *
+   * @return \Drupal\Core\ParamConverter\EntityConverter
+   *   The parameter converter for entities.
+   */
+  public static function getParamConverter() {
+    if (!isset(static::$converter)) {
+      static::$converter = new EntityConverter();
+    }
+    return static::$converter;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
new file mode 100644
index 0000000..3f979ce
--- /dev/null
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterInterface.php
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\ParamConverter\ParamConverterInterface.
+ */
+
+namespace Drupal\Core\ParamConverter;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Interface for parameter converters.
+ */
+interface ParamConverterInterface {
+
+  /**
+   * Converts the provided value to an object of type $class.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param mixed $value
+   *   The value to upcast to an object.
+   * @param string $class
+   *   The fully qualified name of the class to convert to.
+   * @param array $arguments
+   *   (optional) An array of arguments to direct the converter how to behave.
+   *   These values will vary with the converter.
+   */
+   public function convert(Request $request, $value, $class, array $arguments = array());
+
+}
diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
new file mode 100644
index 0000000..fb1c8cf
--- /dev/null
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
@@ -0,0 +1,153 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\ParamConverter\ParamConverterManager.
+ */
+
+namespace Drupal\Core\ParamConverter;
+
+use Symfony\Component\DependencyInjection\ContainerAware;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * This class manages conversion of request attributes to typed objects.
+ */
+class ParamConverterManager extends ContainerAware {
+
+  /**
+   * Array of Converter services to apply.
+   *
+   * The array keys are fully qualified class names; The value is an associative
+   * array containing service_id (the ID of the container service that provides
+   * the corresponding converter) and arguments, which is an associative array
+   * of options to pass to the converter at conversion time.
+   *
+   * @var array
+   */
+  protected $converterIds;
+
+  /**
+   * Array of instantiated converter objects.
+   *
+   * The array keys are full qualified class names; the values are the
+   * instantiated converter object.
+   *
+   * @var array
+   */
+  protected $converters;
+
+  /**
+   * Registers a service as a converter.
+   *
+   * @param string $service
+   *   The ID of a parameter converter service.
+   * @param string $classname
+   *   The fully qualified class name that should use this converter.
+   * @param array $arguments
+   *   (optional) An array of arguments that should be passed to the converter
+   *   on invocation.
+   *
+   * @return \Drupal\Core\ParamConverter\ParamConverterManager
+   *   The called object.
+   */
+  public function addConverterService($service, $classname, array $arguments = array()) {
+    $this->converterIds[$classname] = array(
+      'service' => $service,
+      'arguments' => $arguments,
+    );
+
+    return $this;
+  }
+
+  /**
+   * Converts all request attributes based on type hints on the controller.
+   *
+   * @param callable $controller
+   *   The controller that is to be called.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object to convert.
+   *
+   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
+   *   Thrown when a request attribute could not be properly converted.
+   */
+  public function applyToRequest($controller, Request $request) {
+    $args = $request->attributes;
+    
+    $route = $args->get('_route');
+    
+    if (empty($route)) { return; }
+    
+    // Obtain placeholder names from request attributes.
+    $placeholders = $args->keys();
+    foreach ($placeholders as $i => $key) {
+      if ($key[0] == '_' || $key == 'system_path') {
+        unset($placeholders[$i]);
+      }
+    }
+    
+    // Get converters defined in the route definition.
+    $configuredConverter = $args->get('_route')->getOption('converters');
+    
+    // Apply defined converters or guess them from the name of the placeholder.
+    // Anything else will simply pass without any upcasting.
+    foreach ($placeholders as $i => $key) {
+      $guessedConverter = "Drupal\\$key\\Plugin\\Core\\Entity\\" . ucfirst($key);
+      if (isset($configuredConverter[$key])) {
+        $upcastArgs[$key] = $configuredConverter[$key];
+      }
+      elseif (class_exists($guessedConverter)) {
+        $upcastArgs[$key] = $guessedConverter;
+      }
+    }
+
+    // Upcast everything we can.
+    foreach ($upcastArgs as $key => $converter ) {
+      $convert = $this->convertTo($request, $args->get($key), $converter);
+      if (is_object($convert)) {
+        $request->attributes->set($key, $convert);
+      }
+    }
+  }
+  /**
+   * Converts a value to the specified classname.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param mixed $value
+   *   The value to convert. It may be of any type other than object.
+   * @param string $classname
+   *   The fully qualified name of the class to which to convert the value.
+   *
+   * @return object
+   *   An object of type $classname based on $value.
+   */
+  public function convertTo(Request $request, $value, $classname) {
+    return $this->getConverter($classname)->convert($request, $value, $classname, $this->converterIds[$classname]['arguments']);
+  }
+
+  /**
+   * Retrieves a converter for the provided class.
+   *
+   * @param string $classname
+   *   The fully qualified name of the class for which to load the converter.
+   *
+   * @return \Drupal\Core\ParamConverter\ParamConverterInterface
+   *   The converter for the provided class.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown in case the given class is not registered as a converter.
+   */
+  protected function getConverter($classname) {
+    if (!empty($this->converters[$classname])) {
+      return $this->converters[$classname];
+    }
+    if (empty($this->converterIds[$classname])) {
+      throw new \InvalidArgumentException(sprintf('No converter has been registered for %s.', $classname));
+    }
+    $this->converters[$classname] = $this->container->get($this->converterIds[$classname]['service']);
+    return $this->converters[$classname];
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php
index fc12ee8..6f7a86e 100644
--- a/core/lib/Drupal/Core/Routing/RouteBuilder.php
+++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php
@@ -87,7 +87,8 @@ public function rebuild() {
           foreach ($routes as $name => $route_info) {
             $defaults = isset($route_info['defaults']) ? $route_info['defaults'] : array();
             $requirements = isset($route_info['requirements']) ? $route_info['requirements'] : array();
-            $route = new Route($route_info['pattern'], $defaults, $requirements);
+            $options = isset($route_info['options']) ? $route_info['options'] : array();
+            $route = new Route($route_info['pattern'], $defaults, $requirements, $options);
             $collection->add($name, $route);
           }
         }
diff --git a/core/modules/node/lib/Drupal/node/NodeBundle.php b/core/modules/node/lib/Drupal/node/NodeBundle.php
new file mode 100644
index 0000000..c104222
--- /dev/null
+++ b/core/modules/node/lib/Drupal/node/NodeBundle.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\node\NodeBundle.
+ */
+
+namespace Drupal\node;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Defines the node module bundle.
+ */
+class NodeBundle extends Bundle {
+
+  /**
+   * Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   *
+   * The job of converting an entity id to an entity object for controllers
+   * expecting an object is done by an EntityConverter. We register a service
+   * using the EntityConverterFactory (which ensures only one EntityConverter
+   * is instantiated for all entity types) and tag it so that the compiler
+   * pass will add it to the ParamConverterManager, using the classname
+   * attribute to tell it that the 'Drupal\node\Plugin\Core\Entity\Node' class
+   * can be converted using the EntityConverter.
+   *
+   * @see \Drupal\Core\ParamConverter\EntityConverter
+   * @see \Drupal\Core\ParamConverter\ParamConverterManager
+   * @see \Drupal\Core\DependencyInjection\Compiler\RegisterEntityParamConverterPass
+   */
+  public function build(ContainerBuilder $container) {
+    $container->register('paramconverter.entity.node', 'Drupal\Core\ParamConverter\EntityConverter')
+      ->setFactoryClass('Drupal\Core\ParamConverter\EntityConverterFactory')
+      ->setFactoryMethod('getParamConverter')
+      ->addTag('paramconverter.entity', array('classname' => 'Drupal\node\Plugin\Core\Entity\Node'));
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockConverter.php b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockConverter.php
new file mode 100644
index 0000000..a5f4231
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockConverter.php
@@ -0,0 +1,30 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\ParamConverter\MockConverter.
+ */
+
+namespace Drupal\system\Tests\ParamConverter;
+
+use Symfony\Component\HttpFoundation\Request;
+
+use Drupal\Core\ParamConverter\ParamConverterInterface;
+
+/**
+ * Fake ParamConverter for testing.
+ */
+class MockConverter implements ParamConverterInterface {
+
+  /**
+   * Implements \Drupal\Core\ParamConverter\ParamConverterInterface::convert().
+   */
+  public function convert(Request $request, $value, $class, array $arguments = array()) {
+    if ($value === FALSE) {
+      return;
+    }
+    return new MockType($value);
+  }
+
+}
+
diff --git a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockType.php b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockType.php
new file mode 100644
index 0000000..aa3999b
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/MockType.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\ParamConverter\MockConverter.
+ */
+
+namespace Drupal\system\Tests\ParamConverter;
+
+/**
+ * Fake class for testing.
+ */
+class MockType {
+
+  public $value;
+
+  public function __construct($value) {
+    $this->value = $value;
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/ParamConverter/ParamConverterManagerTest.php b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/ParamConverterManagerTest.php
new file mode 100644
index 0000000..8c00d39
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/ParamConverterManagerTest.php
@@ -0,0 +1,127 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\ParamConverter\ParamConverterManagerTest.
+ */
+
+namespace Drupal\system\Tests\ParamConverter;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\ParamConverter\ParamConverterManager;
+use Drupal\simpletest\UnitTestBase;
+
+/**
+ * Basic tests for the ParamConverter.
+ */
+class ParamConverterManagerTest extends UnitTestBase {
+
+  /**
+   * A simple container for testing purposes.
+   *
+   * @var \Drupal\Core\DependencyInjection\ContainerBuilder
+   */
+  protected $mockContainer;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'ParamConverter Manager tests',
+      'description' => 'Confirm that the ParamConverterMatcher is working correctly.',
+      'group' => 'Routing',
+    );
+  }
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->mockContainer = new ContainerBuilder();
+    $this->mockContainer->register('test_converter', 'Drupal\system\Tests\ParamConverter\MockConverter');
+  }
+
+  /**
+   * Confirms that a parameter is converted when expected.
+   */
+  public function testParamConverted() {
+    $converter = new ParamConverterManager();
+    $converter->setContainer($this->mockContainer);
+    $converter->addConverterService('test_converter', 'Drupal\system\Tests\ParamConverter\MockType');
+
+    $request = Request::create('/foo/{bar}');
+    $request->attributes->set('bar', 1);
+
+    $controller = function (MockType $bar) {};
+    $converter->applyToRequest($controller, $request);
+
+    $this->assertTrue($request->attributes->get('bar') instanceof MockType, 'The parameter was upcast successfully.');
+  }
+
+
+  /**
+   * Confirms that un-hinted parameters are not affected.
+   */
+  public function testParamNoConversionNeeded() {
+    $converter = new ParamConverterManager();
+    $converter->setContainer($this->mockContainer);
+    $converter->addConverterService('test_converter', 'Drupal\system\Tests\ParamConverter\MockType');
+
+    $request = Request::create('/foo/{bar}/{baz}');
+    $request->attributes->set('bar', 1);
+    $request->attributes->set('baz', 2);
+
+    $controller = function (MockType $bar, $baz) {};
+    $converter->applyToRequest($controller, $request);
+
+    $this->assertTrue($request->attributes->get('bar') instanceof MockType, 'Hinted parameter was upcast successfully.');
+    $this->assertEqual($request->attributes->get('baz'), 2, 'Bare parameter was not changed.');
+  }
+
+  /**
+   * Confirms that if a parameter could not be converted an exception is thrown.
+   */
+  public function testConversionFailed() {
+    $converter = new ParamConverterManager();
+    $converter->setContainer($this->mockContainer);
+    $converter->addConverterService('test_converter', 'Drupal\system\Tests\ParamConverter\MockType');
+
+    $request = Request::create('/foo/{bar}');
+    $request->attributes->set('bar', FALSE);
+
+    $controller = function (MockType $bar) {};
+
+    try {
+      $converter->applyToRequest($controller, $request);
+    }
+    catch (NotFoundHttpException $e) {
+      $this->pass('NotFoundHttpException thrown for a value that could not be converted.');
+      return;
+    }
+
+    $this->fail('No exception thrown for a value that could not be converted.');
+  }
+
+  /**
+   * Confirms that if a parameter is not convertable an exceptoin is thrown.
+   */
+  public function testNoTypeRegistered() {
+    $converter = new ParamConverterManager();
+    $converter->setContainer($this->mockContainer);
+
+    $request = Request::create('/foo/{bar}');
+    $request->attributes->set('bar', 1);
+
+    $controller = function (MockType $bar) {};
+
+    try {
+      $converter->applyToRequest($controller, $request);
+    }
+    catch (\InvalidArgumentException $e) {
+      $this->pass('InvalidArgumentException thrown for an unregistered type.');
+      return;
+    }
+
+    $this->fail('No exception thrown for unregisterd type.');
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Routing/ParamConverterTest.php b/core/modules/system/lib/Drupal/system/Tests/Routing/ParamConverterTest.php
new file mode 100644
index 0000000..c6118c2
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Routing/ParamConverterTest.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\system\Tests\ParamConverterTest.
+ */
+
+namespace Drupal\system\Tests\Routing;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\RouteNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Basic tests for the ParamConverter.
+ */
+class ParamConverterTest extends WebTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = array('block', 'router_test');
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Parameter Conversion tests',
+      'description' => 'Function Tests for parameter conversion.',
+      'group' => 'Routing',
+    );
+  }
+
+  /**
+   * Confirms that we can successfully use a route with converted parameter.
+   */
+  public function testCanRoute() {
+    $user = $this->drupalCreateUser();
+    $this->drupalGet('router_test/test9/' . $user->id());
+    $this->assertRaw($user->label(), 'The correct user name was found, and there were no fatal errors.');
+
+    $title = $this->randomString();
+    $node = $this->drupalCreateNode(array(
+      'title' => $title,
+    ));
+    $this->drupalGet('router_test/test10/' . $node->id());
+    $this->assertRaw($title, 'The correct node title was found, and there were no fatal errors.');
+
+    $title = $this->randomString();
+    $other_node = $this->drupalCreateNode(array(
+      'title' => $title,
+    ));
+    $this->drupalGet('router_test/test_node_node/' . $node->id() . '/' . $other_node->id());
+    $this->assertRaw('node: ' . $node->title . ', other_node: ' . $other_node->title, 'The correct node titles were found, and there were no fatal errors.');
+  }
+
+}
diff --git a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php
index adb5c34..0e6e680 100644
--- a/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php
+++ b/core/modules/system/tests/modules/router_test/lib/Drupal/router_test/TestControllers.php
@@ -8,6 +8,9 @@
 namespace Drupal\router_test;
 
 use Symfony\Component\HttpFoundation\Response;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\node\Plugin\Core\Entity\Node;
+use Drupal\user\Plugin\Core\Entity\User;
 
 /**
  * Controller routines for testing the routing system.
@@ -46,4 +49,15 @@ public function test8() {
     return new Response('test8');
   }
 
+  public function test9(User $user) {
+    return $user->label();
+  }
+
+  public function test10(Node $node) {
+    return $node->label();
+  }
+  
+  public function test_node_node(Node $node, Node $other_node) {
+    return 'node: ' . $node->title . ', other_node: ' . $other_node->title;
+  }
 }
diff --git a/core/modules/system/tests/modules/router_test/router_test.info b/core/modules/system/tests/modules/router_test/router_test.info
index d729865..aca88d8 100644
--- a/core/modules/system/tests/modules/router_test/router_test.info
+++ b/core/modules/system/tests/modules/router_test/router_test.info
@@ -3,4 +3,4 @@ description = "Support module for routing testing."
 package = Testing
 version = VERSION
 core = 8.x
-hidden = TRUE
+hidden = FALSE
diff --git a/core/modules/system/tests/modules/router_test/router_test.routing.yml b/core/modules/system/tests/modules/router_test/router_test.routing.yml
index 2c94ff2..36883f4 100644
--- a/core/modules/system/tests/modules/router_test/router_test.routing.yml
+++ b/core/modules/system/tests/modules/router_test/router_test.routing.yml
@@ -45,3 +45,27 @@ router_test_8:
   pattern: '/router_test/test8'
   defaults:
     _controller: '\Drupal\router_test\TestControllers::test8'
+
+router_test_9:
+  pattern: '/router_test/test9/{user}'
+  defaults:
+    _content: '\Drupal\router_test\TestControllers::test9'
+  requirements:
+    _access: 'TRUE'
+
+router_test_10:
+  pattern: '/router_test/test10/{node}'
+  defaults:
+    _content: '\Drupal\router_test\TestControllers::test10'
+  requirements:
+    _access: 'TRUE'
+
+router_test_node_node:
+  pattern: '/router_test/test_node_node/{node}/{other_node}'
+  defaults:
+    _content: '\Drupal\router_test\TestControllers::test_node_node'
+  requirements:
+    _access: 'TRUE'
+  options:
+    converters:
+      other_node: 'Drupal\node\Plugin\Core\Entity\Node'
diff --git a/core/modules/user/lib/Drupal/user/UserBundle.php b/core/modules/user/lib/Drupal/user/UserBundle.php
index a4e7d8d..087925c 100644
--- a/core/modules/user/lib/Drupal/user/UserBundle.php
+++ b/core/modules/user/lib/Drupal/user/UserBundle.php
@@ -25,5 +25,9 @@ public function build(ContainerBuilder $container) {
     $container
       ->register('user.data', 'Drupal\user\UserData')
       ->addArgument(new Reference('database'));
+    $container->register('paramconverter.entity.user', 'Drupal\Core\ParamConverter\EntityConverter')
+      ->setFactoryClass('Drupal\Core\ParamConverter\EntityConverterFactory')
+      ->setFactoryMethod('getParamConverter')
+      ->addTag('paramconverter.entity', array('classname' => 'Drupal\user\Plugin\Core\Entity\User'));
   }
 }
