diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 48684e5..0e8f5b4 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -10,6 +10,7 @@
 use Drupal\Core\DependencyInjection\Compiler\RegisterKernelListenersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterMatchersPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterNestedMatchersPass;
+use Drupal\Core\DependencyInjection\Compiler\EntityParamConverterPass;
 use Drupal\Core\DependencyInjection\Compiler\RegisterSerializationClassesPass;
 use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -96,6 +97,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')
@@ -140,6 +147,10 @@ public function build(ContainerBuilder $container) {
     $container->addCompilerPass(new RegisterNestedMatchersPass());
     // Add a compiler pass for registering event subscribers.
     $container->addCompilerPass(new RegisterKernelListenersPass(), PassConfig::TYPE_AFTER_REMOVING);
+
+    // Add a compiler pass for upcasting of entity route parameters.
+    $container->addCompilerPass(new EntityParamConverterPass());
+
     // Add a compiler pass for adding Normalizers and Encoders to Serializer.
     $container->addCompilerPass(new RegisterSerializationClassesPass());
   }
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/EntityParamConverterPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/EntityParamConverterPass.php
new file mode 100644
index 0000000..083395c
--- /dev/null
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/EntityParamConverterPass.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\DependencyInjection\Compiler\EntityParamConverterPass.
+ */
+
+namespace Drupal\Core\DependencyInjection\Compiler;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
+
+/**
+ * Registers EntityConverter services with the ParamConverterManager.
+ */
+class EntityParamConverterPass 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..857aaaa
--- /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['entity_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..83f4696
--- /dev/null
+++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php
@@ -0,0 +1,142 @@
+<?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) {
+    $reflection = is_array($controller) ? new \ReflectionMethod($controller[0], $controller[1]) : new \ReflectionFunction($controller);
+
+    foreach ($reflection->getParameters() as $parameter) {
+      // Only process parameters that are type-hinted and not the Request
+      // object, since that's already covered by the ControllerResolver.
+      if (!$parameter->getClass() || $parameter->getClass()->isInstance($request)) {
+        continue;
+      }
+
+      $name = $parameter->getName();
+      $value = $request->attributes->get($name);
+
+      // Skip parameters that are already the objects they should be.
+      if (is_object($value) && $parameter->getClass()->isInstance($value)) {
+        continue;
+      }
+
+      $convert = $this->convertTo($request, $value, $parameter->getClass()->getName());
+      if (!is_object($convert) || !$parameter->getClass()->isInstance($convert)) {
+        throw new NotFoundHttpException;
+      }
+
+      $request->attributes->set($name, $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/modules/node/lib/Drupal/node/NodeBundle.php b/core/modules/node/lib/Drupal/node/NodeBundle.php
new file mode 100644
index 0000000..a5d21d0
--- /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\EntityParamConverterPass
+   */
+  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..1aa2e9a
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/ParamConverter/ParamConverterManagerTest.php
@@ -0,0 +1,126 @@
+<?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..eae1d42
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Routing/ParamConverterTest.php
@@ -0,0 +1,54 @@
+<?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/test7/' . $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/test8/' . $node->id());
+    $this->assertRaw($title, 'The correct node title was 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 bcf18b7..d46b9a5 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.
@@ -34,4 +37,12 @@ public function test5() {
     return "test5";
   }
 
+  public function test7(User $user) {
+    return $user->label();
+  }
+
+  public function test8(Node $node) {
+    return $node->label();
+  }
+
 }
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 cc177d3..db227d1 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
@@ -23,3 +23,13 @@ router_test_6:
   pattern: '/router_test/test6'
   defaults:
     _controller: '\Drupal\router_test\TestControllers::test1'
+
+router_test_7:
+  pattern: 'router_test/test7/{user}'
+  defaults:
+    _content: '\Drupal\router_test\TestControllers::test7'
+
+router_test_8:
+  pattern: 'router_test/test8/{node}'
+  defaults:
+    _content: '\Drupal\router_test\TestControllers::test8'
diff --git a/core/modules/user/lib/Drupal/user/UserBundle.php b/core/modules/user/lib/Drupal/user/UserBundle.php
new file mode 100644
index 0000000..7746ed3
--- /dev/null
+++ b/core/modules/user/lib/Drupal/user/UserBundle.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\user\UserBundle.
+ */
+
+namespace Drupal\user;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Defines the user module bundle.
+ */
+class UserBundle extends Bundle {
+
+  /**
+   * Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    $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'));
+  }
+
+}
