diff --git a/core/core.services.yml b/core/core.services.yml
index 165b0ba..add3998 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -519,9 +519,11 @@ services:
   csrf_token:
     class: Drupal\Core\Access\CsrfTokenGenerator
     arguments: ['@private_key']
+  access_arguments_resolver:
+    class: Drupal\Core\Access\AccessArgumentsResolver
   access_manager:
     class: Drupal\Core\Access\AccessManager
-    arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager']
+    arguments: ['@router.route_provider', '@url_generator', '@paramconverter_manager', '@access_arguments_resolver']
     calls:
       - [setContainer, ['@service_container']]
       - [setRequest, ['@?request']]
@@ -556,7 +558,7 @@ services:
       - { name: access_check, applies_to: _access_theme }
   access_check.custom:
     class: Drupal\Core\Access\CustomAccessCheck
-    arguments: ['@controller_resolver']
+    arguments: ['@controller_resolver', '@access_arguments_resolver']
     tags:
       - { name: access_check, applies_to: _custom_access }
   access_check.csrf:
diff --git a/core/lib/Drupal/Core/Access/AccessArgumentsResolver.php b/core/lib/Drupal/Core/Access/AccessArgumentsResolver.php
new file mode 100644
index 0000000..b12630a
--- /dev/null
+++ b/core/lib/Drupal/Core/Access/AccessArgumentsResolver.php
@@ -0,0 +1,119 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Access\AccessArgumentsResolver.
+ */
+
+namespace Drupal\Core\Access;
+
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Resolves the arguments to pass to an access check callable.
+ */
+class AccessArgumentsResolver implements AccessArgumentsResolverInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getArguments(callable $callable, Route $route, Request $request, AccountInterface $account) {
+    $arguments = array();
+    foreach ($this->getReflector($callable)->getParameters() as $parameter) {
+      $arguments[] = $this->getArgument($parameter, $route, $request, $account);
+    }
+    return $arguments;
+  }
+
+  /**
+   * Returns the argument value for a parameter.
+   *
+   * @param \ReflectionParameter $parameter
+   *   The parameter of a callable to get the value for.
+   * @param \Symfony\Component\Routing\Route $route
+   *   The access checked route.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The current user.
+   *
+   * @return mixed
+   *   The value of the requested parameter value.
+   * @throws \RuntimeException
+   *   Thrown when there is a missing parameter.
+   */
+  protected function getArgument(\ReflectionParameter $parameter, Route $route, Request $request, AccountInterface $account) {
+    $upcasted_route_arguments = $request->attributes->all();
+    $raw_route_arguments = isset($upcasted_route_arguments['_raw_variables']) ? $upcasted_route_arguments['_raw_variables']->all() : $upcasted_route_arguments;
+    $parameter_type_hint = $parameter->getClass();
+    $parameter_name = $parameter->getName();
+
+    // If the route argument exists and is NULL, return it, regardless of
+    // parameter type hint.
+    if (!isset($upcasted_route_arguments[$parameter_name]) && array_key_exists($parameter_name, $upcasted_route_arguments)) {
+      return NULL;
+    }
+
+    if ($parameter_type_hint) {
+      // If the argument exists and complies with the type hint, return it.
+      if (isset($upcasted_route_arguments[$parameter_name]) && $parameter_type_hint->isInstance($upcasted_route_arguments[$parameter_name])) {
+        return $upcasted_route_arguments[$parameter_name];
+      }
+      // Otherwise, resolve $request, $route, and $account by type matching
+      // only. This way, the callable may rename them in case the route
+      // defines other parameters with these names.
+      foreach (array($request, $route, $account) as $special_argument) {
+        if ($parameter_type_hint->isInstance($special_argument)) {
+          return $special_argument;
+        }
+      }
+    }
+    elseif (isset($raw_route_arguments[$parameter_name])) {
+      return $raw_route_arguments[$parameter_name];
+    }
+
+    // If the callable provides a default value, use it.
+    if ($parameter->isDefaultValueAvailable()) {
+      return $parameter->getDefaultValue();
+    }
+
+    // Can't resolve it: call a method that throws an exception or can be
+    // overridden to do something else.
+    return $this->handleUnresolvedArgument($parameter);
+  }
+
+  /**
+   * Returns a reflector for the callable.
+   *
+   * @param callable $callable
+   *
+   * @return \ReflectionFunctionAbstract
+   */
+  protected function getReflector(callable $callable) {
+    return is_array($callable) ? new \ReflectionMethod($callable[0], $callable[1]) : new \ReflectionFunction($callable);
+  }
+
+  /**
+   * Called by getArgument() if an argument value can't be resolved.
+   *
+   * Subclasses that override this method may return a default value
+   * instead of throwing an exception.
+   *
+   * @throws \RuntimeException
+   *   Thrown when there is a missing parameter.
+   */
+  protected function handleUnresolvedArgument(\ReflectionParameter $parameter) {
+    $class = $parameter->getDeclaringClass();
+    $function = $parameter->getDeclaringFunction();
+    if ($class) {
+      $function_name = $class->getName() . '::' . $function->getName();
+    }
+    else {
+      $function_name = $function->getName();
+    }
+    throw new \RuntimeException(sprintf('Access callable "%s" requires a value for the "$%s" argument.', $function_name, $parameter->getName()));
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Access/AccessArgumentsResolverInterface.php b/core/lib/Drupal/Core/Access/AccessArgumentsResolverInterface.php
new file mode 100644
index 0000000..ce0ecf8
--- /dev/null
+++ b/core/lib/Drupal/Core/Access/AccessArgumentsResolverInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Access\AccessArgumentsResolverInterface.
+ */
+
+namespace Drupal\Core\Access;
+
+use Drupal\Core\Session\AccountInterface;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Resolves the arguments to pass to an access check callable.
+ */
+interface AccessArgumentsResolverInterface {
+
+  /**
+   * Returns the arguments to pass to the access check callable.
+   *
+   * @param callable $callable
+   *   A PHP callable.
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check access to.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return array
+   *   An array of arguments to pass to the callable.
+   *
+   * @throws \RuntimeException
+   *   When a value for an argument given is not provided.
+   */
+  public function getArguments(callable $callable, Route $route, Request $request, AccountInterface $account);
+
+}
diff --git a/core/lib/Drupal/Core/Access/AccessInterface.php b/core/lib/Drupal/Core/Access/AccessInterface.php
index e496e69..faa798c 100644
--- a/core/lib/Drupal/Core/Access/AccessInterface.php
+++ b/core/lib/Drupal/Core/Access/AccessInterface.php
@@ -7,9 +7,6 @@
 
 namespace Drupal\Core\Access;
 
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
-
 /**
  * Provides access check results.
  */
diff --git a/core/lib/Drupal/Core/Access/AccessManager.php b/core/lib/Drupal/Core/Access/AccessManager.php
index 3bb219f..79cb67e 100644
--- a/core/lib/Drupal/Core/Access/AccessManager.php
+++ b/core/lib/Drupal/Core/Access/AccessManager.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\ParamConverter\ParamConverterManagerInterface;
 use Drupal\Core\ParamConverter\ParamNotConvertedException;
-use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
 use Drupal\Core\Routing\RequestHelper;
 use Drupal\Core\Routing\RouteProviderInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -46,6 +45,13 @@ class AccessManager implements ContainerAwareInterface {
   protected $checks;
 
   /**
+   * Array of access check method names keyed by service id.
+   *
+   * @var array
+   */
+  protected $checkMethods = array();
+
+  /**
    * An array to map static requirement keys to service IDs.
    *
    * @var array
@@ -81,6 +87,13 @@ class AccessManager implements ContainerAwareInterface {
   protected $paramConverterManager;
 
   /**
+   * The access arguments resolver.
+   *
+   * @var \Drupal\Core\Access\AccessArgumentsResolverInterface
+   */
+  protected $argumentsResolver;
+
+  /**
    * A request object.
    *
    * @var \Symfony\Component\HttpFoundation\Request
@@ -96,11 +109,14 @@ class AccessManager implements ContainerAwareInterface {
    *   The url generator.
    * @param \Drupal\Core\ParamConverter\ParamConverterManagerInterface $paramconverter_manager
    *   The param converter manager.
+   * @param \Drupal\Core\Access\AccessArgumentsResolverInterface $arguments_resolver
+   *   The access arguments resolver.
    */
-  public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager) {
+  public function __construct(RouteProviderInterface $route_provider, UrlGeneratorInterface $url_generator, ParamConverterManagerInterface $paramconverter_manager, AccessArgumentsResolverInterface $arguments_resolver) {
     $this->routeProvider = $route_provider;
     $this->urlGenerator = $url_generator;
     $this->paramConverterManager = $paramconverter_manager;
+    $this->argumentsResolver = $arguments_resolver;
   }
 
   /**
@@ -121,12 +137,15 @@ public function setRequest(Request $request) {
    *
    * @param string $service_id
    *   The ID of the service in the Container that provides a check.
+   * @param string $service_method
+   *   The method to invoke on the service object for performing the check.
    * @param array $applies_checks
    *   (optional) An array of route requirement keys the checker service applies
    *   to.
    */
-  public function addCheckService($service_id, array $applies_checks = array()) {
+  public function addCheckService($service_id, $service_method, array $applies_checks = array()) {
     $this->checkIds[] = $service_id;
+    $this->checkMethods[$service_id] = $service_method;
     foreach ($applies_checks as $applies_check) {
       $this->staticRequirementMap[$applies_check][] = $service_id;
     }
@@ -267,11 +286,7 @@ protected function checkAll(array $checks, Route $route, Request $request, Accou
         $this->loadCheck($service_id);
       }
 
-      $service_access = $this->checks[$service_id]->access($route, $request, $account);
-
-      if (!in_array($service_access, array(AccessInterface::ALLOW, AccessInterface::DENY, AccessInterface::KILL), TRUE)) {
-        throw new AccessException("Access error in $service_id. Access services can only return AccessInterface::ALLOW, AccessInterface::DENY, or AccessInterface::KILL constants.");
-      }
+      $service_access = $this->performCheck($service_id, $route, $request, $account);
 
       if ($service_access === AccessInterface::ALLOW) {
         $access = TRUE;
@@ -310,11 +325,7 @@ protected function checkAny(array $checks, $route, $request, AccountInterface $a
         $this->loadCheck($service_id);
       }
 
-      $service_access = $this->checks[$service_id]->access($route, $request, $account);
-
-      if (!in_array($service_access, array(AccessInterface::ALLOW, AccessInterface::DENY, AccessInterface::KILL), TRUE)) {
-        throw new AccessException("Access error in $service_id. Access services can only return AccessInterface::ALLOW, AccessInterface::DENY, or AccessInterface::KILL constants.");
-      }
+      $service_access = $this->performCheck($service_id, $route, $request, $account);
 
       if ($service_access === AccessInterface::ALLOW) {
         $access = TRUE;
@@ -328,10 +339,46 @@ protected function checkAny(array $checks, $route, $request, AccountInterface $a
   }
 
   /**
+   * Performs the specified access check.
+   *
+   * @param string $service_id
+   *   The access check service ID to use.
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check access to.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The incoming request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The current user.
+   *
+   * @throws \Drupal\Core\Access\AccessException
+   *   Thrown when the access check returns an invalid value.
+   *
+   * @return string
+   *   Either the AccessInterface::ALLOW, AccessInterface::DENY, or
+   *   AccessInterface::KILL constant.
+   */
+  protected function performCheck($service_id, $route, $request, $account) {
+    $callable = array($this->checks[$service_id], $this->checkMethods[$service_id]);
+    $arguments = $this->argumentsResolver->getArguments($callable, $route, $request, $account);
+    $service_access = call_user_func_array($callable, $arguments);
+
+    if (!in_array($service_access, array(AccessInterface::ALLOW, AccessInterface::DENY, AccessInterface::KILL), TRUE)) {
+      throw new AccessException("Access error in $service_id. Access services can only return AccessInterface::ALLOW, AccessInterface::DENY, or AccessInterface::KILL constants.");
+    }
+
+    return $service_access;
+  }
+
+  /**
    * Lazy-loads access check services.
    *
    * @param string $service_id
    *   The service id of the access check service to load.
+   *
+   * @throws \InvalidArgumentException
+   *   Thrown when the service hasn't been registered in addCheckService().
+   * @throws \Drupal\Core\Access\AccessException
+   *   Thrown when the service doesn't implement the required interface.
    */
   protected function loadCheck($service_id) {
     if (!in_array($service_id, $this->checkIds)) {
@@ -340,9 +387,12 @@ protected function loadCheck($service_id) {
 
     $check = $this->container->get($service_id);
 
-    if (!($check instanceof RoutingAccessInterface)) {
+    if (!($check instanceof AccessInterface)) {
       throw new AccessException('All access checks must implement AccessInterface.');
     }
+    if (!is_callable(array($check, $this->checkMethods[$service_id]))) {
+      throw new AccessException(sprintf('Access check method %s in service %s must be callable.', $this->checkMethods[$service_id], $service_id));
+    }
 
     $this->checks[$service_id] = $check;
   }
diff --git a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
index 9744d6c..8b29b82 100644
--- a/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/CsrfAccessCheck.php
@@ -7,7 +7,6 @@
 
 namespace Drupal\Core\Access;
 
-use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
@@ -39,9 +38,16 @@ function __construct(CsrfTokenGenerator $csrf_token) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, Request $request) {
     // If this is the controller request, check CSRF access as normal.
     if ($request->attributes->get('_controller_request')) {
       return $this->csrfToken->validate($request->query->get('token'), $request->attributes->get('_system_path')) ? static::ALLOW : static::KILL;
diff --git a/core/lib/Drupal/Core/Access/CustomAccessCheck.php b/core/lib/Drupal/Core/Access/CustomAccessCheck.php
index c116e66..416d808 100644
--- a/core/lib/Drupal/Core/Access/CustomAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/CustomAccessCheck.php
@@ -33,25 +33,41 @@ class CustomAccessCheck implements RoutingAccessInterface {
   protected $controllerResolver;
 
   /**
+   * The arguments resolver.
+   *
+   * @var \Drupal\Core\Access\AccessArgumentsResolverInterface
+   */
+  protected $argumentsResolver;
+
+  /**
    * Constructs a CustomAccessCheck instance.
    *
    * @param \Drupal\Core\Controller\ControllerResolverInterface $controller_resolver
    *   The controller resolver.
+   * @param \Drupal\Core\Access\AccessArgumentsResolverInterface $arguments_resolver
+   *   The arguments resolver.
    */
-  public function __construct(ControllerResolverInterface $controller_resolver) {
+  public function __construct(ControllerResolverInterface $controller_resolver, AccessArgumentsResolverInterface $arguments_resolver) {
     $this->controllerResolver = $controller_resolver;
+    $this->argumentsResolver = $arguments_resolver;
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
   public function access(Route $route, Request $request, AccountInterface $account) {
-    $access_controller = $route->getRequirement('_custom_access');
-
-    $controller = $this->controllerResolver->getControllerFromDefinition($access_controller);
-    $arguments = $this->controllerResolver->getArguments($request, $controller);
-
-    return call_user_func_array($controller, $arguments);
+    $callable = $this->controllerResolver->getControllerFromDefinition($route->getRequirement('_custom_access'));
+    $arguments = $this->argumentsResolver->getArguments($callable, $route, $request, $account);
+    return call_user_func_array($callable, $arguments);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Access/DefaultAccessCheck.php b/core/lib/Drupal/Core/Access/DefaultAccessCheck.php
index dc26067..268e940 100644
--- a/core/lib/Drupal/Core/Access/DefaultAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/DefaultAccessCheck.php
@@ -7,10 +7,8 @@
 
 namespace Drupal\Core\Access;
 
-use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Routing\Access\AccessInterface as RoutingAccessInterface;
 use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Allows access to routes to be controlled by an '_access' boolean parameter.
@@ -18,9 +16,14 @@
 class DefaultAccessCheck implements RoutingAccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route) {
     if ($route->getRequirement('_access') === 'TRUE') {
       return static::ALLOW;
     }
diff --git a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterAccessChecksPass.php b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterAccessChecksPass.php
index ae66851..69494af 100644
--- a/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterAccessChecksPass.php
+++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/RegisterAccessChecksPass.php
@@ -27,12 +27,16 @@ public function process(ContainerBuilder $container) {
     $access_manager = $container->getDefinition('access_manager');
     foreach ($container->findTaggedServiceIds('access_check') as $id => $attributes) {
       $applies = array();
+      $method = 'access';
       foreach ($attributes as $attribute) {
         if (isset($attribute['applies_to'])) {
           $applies[] = $attribute['applies_to'];
         }
+        if (isset($attribute['method'])) {
+          $method = $attribute['method'];
+        }
       }
-      $access_manager->addMethodCall('addCheckService', array($id, $applies));
+      $access_manager->addMethodCall('addCheckService', array($id, $method, $applies));
     }
   }
 }
diff --git a/core/lib/Drupal/Core/Entity/EntityAccessCheck.php b/core/lib/Drupal/Core/Entity/EntityAccessCheck.php
index 1e3b0ae..5c411ec 100644
--- a/core/lib/Drupal/Core/Entity/EntityAccessCheck.php
+++ b/core/lib/Drupal/Core/Entity/EntityAccessCheck.php
@@ -18,7 +18,7 @@
 class EntityAccessCheck implements AccessInterface {
 
   /**
-   * Implements \Drupal\Core\Access\AccessCheckInterface::access().
+   * Checks access.
    *
    * The value of the '_entity_access' key must be in the pattern
    * 'entity_type.operation.' The entity type must match the {entity_type}
@@ -29,6 +29,15 @@ class EntityAccessCheck implements AccessInterface {
    *   _entity_access: 'node.update'
    * @endcode
    * Available operations are 'view', 'update', 'create', and 'delete'.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
   public function access(Route $route, Request $request, AccountInterface $account) {
     // Split the entity type and the operation.
diff --git a/core/lib/Drupal/Core/Entity/EntityCreateAccessCheck.php b/core/lib/Drupal/Core/Entity/EntityCreateAccessCheck.php
index 1cf7d87..bdd117e 100644
--- a/core/lib/Drupal/Core/Entity/EntityCreateAccessCheck.php
+++ b/core/lib/Drupal/Core/Entity/EntityCreateAccessCheck.php
@@ -42,7 +42,16 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
   public function access(Route $route, Request $request, AccountInterface $account) {
     list($entity_type, $bundle) = explode(':', $route->getRequirement($this->requirementsKey) . ':');
diff --git a/core/lib/Drupal/Core/Routing/Access/AccessInterface.php b/core/lib/Drupal/Core/Routing/Access/AccessInterface.php
index 2d80c6d..077fbec 100644
--- a/core/lib/Drupal/Core/Routing/Access/AccessInterface.php
+++ b/core/lib/Drupal/Core/Routing/Access/AccessInterface.php
@@ -8,28 +8,12 @@
 namespace Drupal\Core\Routing\Access;
 
 use Drupal\Core\Access\AccessInterface as GenericAccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
 
 /**
  * An access check service determines access rules for particular routes.
  */
 interface AccessInterface extends GenericAccessInterface {
 
-  /**
-   * Checks for access to a route.
-   *
-   * @param \Symfony\Component\Routing\Route $route
-   *   The route to check against.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object.
-   * @param \Drupal\Core\Session\AccountInterface $account
-   *   The currently logged in account.
-   *
-   * @return bool|null
-   *   self::ALLOW, self::DENY, or self::KILL.
-   */
-  public function access(Route $route, Request $request, AccountInterface $account);
+  // @todo Remove this interface since it no longer defines any methods?
 
 }
diff --git a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php
index 75afddc..5b261fe 100644
--- a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php
+++ b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php
@@ -8,9 +8,6 @@
 namespace Drupal\Core\Theme;
 
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
 
 /**
  * Access check for a theme.
@@ -18,10 +15,15 @@
 class ThemeAccessCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param string $theme
+   *   The name of a theme.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    return $this->checkAccess($request->attributes->get('theme')) ? static::ALLOW : static::DENY;
+  public function access($theme) {
+    return $this->checkAccess($theme) ? static::ALLOW : static::DENY;
   }
 
   /**
diff --git a/core/modules/book/lib/Drupal/book/Access/BookNodeIsRemovableAccessCheck.php b/core/modules/book/lib/Drupal/book/Access/BookNodeIsRemovableAccessCheck.php
index 6a5385c..7ba29d0 100644
--- a/core/modules/book/lib/Drupal/book/Access/BookNodeIsRemovableAccessCheck.php
+++ b/core/modules/book/lib/Drupal/book/Access/BookNodeIsRemovableAccessCheck.php
@@ -9,9 +9,7 @@
 
 use Drupal\book\BookManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\node\NodeInterface;
 
 /**
  * Determines whether the requested node can be removed from its book.
@@ -36,14 +34,15 @@ public function __construct(BookManagerInterface $book_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Drupal\node\NodeInterface $node
+   *   The node requested to be removed from its book.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $node = $request->attributes->get('node');
-    if (!empty($node)) {
-      return $this->bookManager->checkNodeIsRemovable($node) ? static::ALLOW : static::DENY;
-    }
-    return static::DENY;
+  public function access(NodeInterface $node) {
+    return $this->bookManager->checkNodeIsRemovable($node) ? static::ALLOW : static::DENY;
   }
 
 }
diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigTranslationOverviewAccess.php b/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigTranslationOverviewAccess.php
index 1834416..c0320ab 100644
--- a/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigTranslationOverviewAccess.php
+++ b/core/modules/config_translation/lib/Drupal/config_translation/Access/ConfigTranslationOverviewAccess.php
@@ -43,7 +43,16 @@ public function __construct(ConfigMapperManagerInterface $config_mapper_manager)
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
   public function access(Route $route, Request $request, AccountInterface $account) {
     /** @var \Drupal\config_translation\ConfigMapperInterface $mapper */
diff --git a/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php
index 548d1fa..6c581f2 100644
--- a/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php
+++ b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php
@@ -11,8 +11,7 @@
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\user\UserDataInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\user\UserInterface;
 
 /**
  * Access check for contact_personal_page route.
@@ -47,10 +46,17 @@ public function __construct(ConfigFactoryInterface $config_factory, UserDataInte
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Drupal\user\UserInterface $user
+   *   The user being contacted.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $contact_account = $request->attributes->get('user');
+  public function access(UserInterface $user, AccountInterface $account) {
+    $contact_account = $user;
 
     // Anonymous users cannot have contact forms.
     if ($contact_account->isAnonymous()) {
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
index b9b4904..c223a35 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php
@@ -37,14 +37,29 @@ public function __construct(EntityManagerInterface $manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param string $source
+   *   (optional) For a create operation, the language code of the source.
+   * @param string $target
+   *   (optional) For a create operation, the language code of the translation.
+   * @param string $language
+   *   (optional) For an update or delete operation, the language code of the
+   *   translation being updated or deleted.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, Request $request, AccountInterface $account, $source = NULL, $target = NULL, $language = NULL) {
     $entity_type = $request->attributes->get('_entity_type_id');
     /** @var $entity \Drupal\Core\Entity\EntityInterface */
     if ($entity = $request->attributes->get($entity_type)) {
-      $route_requirements = $route->getRequirements();
-      $operation = $route_requirements['_access_content_translation_manage'];
+      $operation = $route->getRequirement('_access_content_translation_manage');
       $controller = content_translation_controller($entity_type, $account);
 
       // Load translation.
@@ -53,10 +68,8 @@ public function access(Route $route, Request $request, AccountInterface $account
 
       switch ($operation) {
         case 'create':
-          $source = language_load($request->attributes->get('source'));
-          $target = language_load($request->attributes->get('target'));
-          $source = !empty($source) ? $source : $entity->language();
-          $target = !empty($target) ? $target : \Drupal::languageManager()->getCurrentLanguage(Language::TYPE_CONTENT);
+          $source = language_load($source) ?: $entity->language();
+          $target = language_load($target) ?: \Drupal::languageManager()->getCurrentLanguage(Language::TYPE_CONTENT);
           return ($source->id != $target->id
             && isset($languages[$source->id])
             && isset($languages[$target->id])
@@ -66,8 +79,7 @@ public function access(Route $route, Request $request, AccountInterface $account
 
         case 'update':
         case 'delete':
-          $language = language_load($request->attributes->get('language'));
-          $language = !empty($language) ? $language : \Drupal::languageManager()->getCurrentLanguage(Language::TYPE_CONTENT);
+          $language = language_load($language) ?: \Drupal::languageManager()->getCurrentLanguage(Language::TYPE_CONTENT);
           return isset($languages[$language->id])
             && $language->id != $entity->getUntranslated()->language()->id
             && isset($translations[$language->id])
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
index bc30db8..659531e 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -36,9 +35,16 @@ public function __construct(EntityManagerInterface $manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Request $request, AccountInterface $account) {
     $entity_type = $request->attributes->get('_entity_type_id');
     if ($entity = $request->attributes->get($entity_type)) {
       // Get entity base info.
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
index 8b89d27..51731b6 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Routing/ContentTranslationRouteSubscriber.php
@@ -50,7 +50,6 @@ protected function alterRoutes(RouteCollection $collection) {
        $path,
         array(
           '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::overview',
-          'account' => 'NULL',
           '_entity_type_id' => $entity_type_id,
         ),
         array(
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
index e8d3acd..b2f797c 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
@@ -36,22 +36,33 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param string $form_mode_name
+   *   The form mode.
+   * @param string $bundle
+   *   The bundle.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, Request $request, AccountInterface $account, $form_mode_name = 'default', $bundle = NULL) {
     if ($entity_type_id = $route->getDefault('entity_type_id')) {
-      $form_mode = $request->attributes->get('form_mode_name');
-
-      if (!($bundle = $request->attributes->get('bundle'))) {
+      if (!isset($bundle)) {
         $entity_type = $this->entityManager->getDefinition($entity_type_id);
         $bundle = $request->attributes->get('_raw_variables')->get($entity_type->getBundleEntityType());
       }
 
       $visibility = FALSE;
-      if (!$form_mode || $form_mode == 'default') {
+      if ($form_mode_name == 'default') {
         $visibility = TRUE;
       }
-      elseif ($entity_display = $this->entityManager->getStorage('entity_form_display')->load($entity_type_id . '.' . $bundle . '.' . $form_mode)) {
+      elseif ($entity_display = $this->entityManager->getStorage('entity_form_display')->load($entity_type_id . '.' . $bundle . '.' . $form_mode_name)) {
         $visibility = $entity_display->status();
       }
 
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
index baa15f8..bd584e4 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
@@ -36,22 +36,33 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param string $view_mode_name
+   *   The view mode.
+   * @param string $bundle
+   *   The bundle.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, Request $request, AccountInterface $account, $view_mode_name = 'default', $bundle = NULL) {
     if ($entity_type_id = $route->getDefault('entity_type_id')) {
-      $view_mode = $request->attributes->get('view_mode_name');
-
-      if (!($bundle = $request->attributes->get('bundle'))) {
+      if (!isset($bundle)) {
         $entity_type = $this->entityManager->getDefinition($entity_type_id);
         $bundle = $request->attributes->get('_raw_variables')->get($entity_type->getBundleEntityType());
       }
 
       $visibility = FALSE;
-      if (!$view_mode || $view_mode == 'default') {
+      if ($view_mode_name == 'default') {
         $visibility = TRUE;
       }
-      elseif ($entity_display = $this->entityManager->getStorage('entity_view_display')->load($entity_type_id . '.' . $bundle . '.' . $view_mode)) {
+      elseif ($entity_display = $this->entityManager->getStorage('entity_view_display')->load($entity_type_id . '.' . $bundle . '.' . $view_mode_name)) {
         $visibility = $entity_display->status();
       }
 
diff --git a/core/modules/node/lib/Drupal/node/Access/NodeAddAccessCheck.php b/core/modules/node/lib/Drupal/node/Access/NodeAddAccessCheck.php
index 8d72223..43fbe4b 100644
--- a/core/modules/node/lib/Drupal/node/Access/NodeAddAccessCheck.php
+++ b/core/modules/node/lib/Drupal/node/Access/NodeAddAccessCheck.php
@@ -10,8 +10,7 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\node\NodeTypeInterface;
 
 /**
  * Determines access to for node add pages.
@@ -36,17 +35,24 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param \Drupal\node\NodeTypeInterface $node_type
+   *   The node type.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(AccountInterface $account, NodeTypeInterface $node_type = NULL) {
     $access_controller = $this->entityManager->getAccessController('node');
-    // If a node type is set on the request, just check that.
-    if ($request->attributes->has('node_type')) {
-      return $access_controller->createAccess($request->attributes->get('node_type')->type, $account) ? static::ALLOW : static::DENY;
+    // If checking whether a node of a particular type may be created.
+    if ($node_type) {
+      return $access_controller->createAccess($node_type->id(), $account) ? static::ALLOW : static::DENY;
     }
-    foreach (node_permissions_get_configured_types() as $type) {
-      if ($access_controller->createAccess($type->type, $account)) {
-        // Allow access if at least one type is permitted.
+    // If checking whether a node of any type may be created.
+    foreach (node_permissions_get_configured_types() as $node_type) {
+      if ($access_controller->createAccess($node_type->id(), $account)) {
         return static::ALLOW;
       }
     }
diff --git a/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php
index 9e60cae..1fb7f30 100644
--- a/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php
+++ b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php
@@ -12,7 +12,6 @@
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\node\NodeInterface;
-use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -63,21 +62,25 @@ public function __construct(EntityManagerInterface $entity_manager, Connection $
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param \Drupal\node\NodeInterface $node
+   *   The node.
+   * @param string $node_revision
+   *   The node revision.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    // If the route has a {node_revision} placeholder, load the node for that
-    // revision. Otherwise, try to use a {node} placeholder.
-    if ($request->attributes->has('node_revision')) {
-      $node = $this->nodeStorage->loadRevision($request->attributes->get('node_revision'));
-    }
-    elseif ($request->attributes->has('node')) {
-      $node = $request->attributes->get('node');
-    }
-    else {
-      return static::DENY;
+  public function access(Route $route, AccountInterface $account, NodeInterface $node = NULL, $node_revision = NULL) {
+    if ($node_revision) {
+      $node = $this->nodeStorage->loadRevision($node_revision);
     }
-    return $this->checkAccess($node, $account, $route->getRequirement('_access_node_revision')) ? static::ALLOW : static::DENY;
+    $operation = $route->getRequirement('_access_node_revision');
+    return ($node && $this->checkAccess($node, $account, $operation)) ? static::ALLOW : static::DENY;
   }
 
   /**
diff --git a/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityAccessCheck.php b/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityAccessCheck.php
index 535c74a..ce99272 100644
--- a/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityAccessCheck.php
+++ b/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityAccessCheck.php
@@ -10,9 +10,7 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Core\Entity\EntityInterface;
 
 /**
@@ -38,12 +36,19 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
+   *
+   * @todo Replace $request parameter with $entity once
+   *   https://drupal.org/node/1837388 is fixed.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    // @todo Request argument validation and object loading should happen
-    //   elsewhere in the request processing pipeline:
-    //   http://drupal.org/node/1798214.
+  public function access(Request $request, AccountInterface $account) {
     if (!$this->validateAndUpcastRequestAttributes($request)) {
       return static::KILL;
     }
@@ -60,6 +65,8 @@ protected function accessEditEntity(EntityInterface $entity, $account) {
 
   /**
    * Validates and upcasts request attributes.
+   *
+   * @todo Remove once https://drupal.org/node/1837388 is fixed.
    */
   protected function validateAndUpcastRequestAttributes(Request $request) {
     // Load the entity.
diff --git a/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityFieldAccessCheck.php b/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityFieldAccessCheck.php
index f8819ba..118fd8f 100644
--- a/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityFieldAccessCheck.php
+++ b/core/modules/quickedit/lib/Drupal/quickedit/Access/EditEntityFieldAccessCheck.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
 use Drupal\Core\Entity\EntityInterface;
 
@@ -37,17 +36,28 @@ public function __construct(EntityManagerInterface $entity_manager) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param string $field_name.
+   *   The field name.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
+   *
+   * @todo Replace $request parameter with $entity once
+   *   https://drupal.org/node/1837388 is fixed.
+   *
+   * @todo Use the $account argument.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    // @todo Request argument validation and object loading should happen
-    //   elsewhere in the request processing pipeline:
-    //   http://drupal.org/node/1798214.
+  public function access(Request $request, $field_name, AccountInterface $account) {
     if (!$this->validateAndUpcastRequestAttributes($request)) {
       return static::KILL;
     }
 
-    return $this->accessEditEntityField($request->attributes->get('entity'), $request->attributes->get('field_name'))  ? static::ALLOW : static::DENY;
+    return $this->accessEditEntityField($request->attributes->get('entity'), $field_name)  ? static::ALLOW : static::DENY;
   }
 
   /**
@@ -59,6 +69,8 @@ public function accessEditEntityField(EntityInterface $entity, $field_name) {
 
   /**
    * Validates and upcasts request attributes.
+   *
+   * @todo Remove once https://drupal.org/node/1837388 is fixed.
    */
   protected function validateAndUpcastRequestAttributes(Request $request) {
     // Load the entity.
diff --git a/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityAccessCheckTest.php b/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityAccessCheckTest.php
index c3f87da..6596ccb 100644
--- a/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityAccessCheckTest.php
+++ b/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityAccessCheckTest.php
@@ -8,7 +8,6 @@
 namespace Drupal\quickedit\Tests\Access;
 
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
 use Drupal\Core\Access\AccessCheckInterface;
 use Drupal\quickedit\Access\EditEntityAccessCheck;
 use Drupal\Tests\UnitTestCase;
@@ -103,7 +102,6 @@ public function providerTestAccess() {
    * @dataProvider providerTestAccess
    */
   public function testAccess(EntityInterface $entity, $expected_result) {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity' => 'TRUE'));
     $request = new Request();
 
     // Prepare the request to be valid.
@@ -111,7 +109,7 @@ public function testAccess(EntityInterface $entity, $expected_result) {
     $request->attributes->set('entity_type', 'test_entity');
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $access = $this->editAccessCheck->access($route, $request, $account);
+    $access = $this->editAccessCheck->access($request, $account);
     $this->assertSame($expected_result, $access);
   }
 
@@ -119,7 +117,6 @@ public function testAccess(EntityInterface $entity, $expected_result) {
    * Tests the access method with an undefined entity type.
    */
   public function testAccessWithUndefinedEntityType() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'non_valid');
 
@@ -129,14 +126,13 @@ public function testAccessWithUndefinedEntityType() {
       ->will($this->returnValue(NULL));
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, $account));
   }
 
   /**
    * Tests the access method with a non existing entity.
    */
   public function testAccessWithNotExistingEntity() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', 1);
@@ -152,7 +148,7 @@ public function testAccessWithNotExistingEntity() {
       ->will($this->returnValue(NULL));
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, $account));
   }
 
 }
diff --git a/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityFieldAccessCheckTest.php b/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityFieldAccessCheckTest.php
index 6895422..d1b0228 100644
--- a/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityFieldAccessCheckTest.php
+++ b/core/modules/quickedit/tests/Drupal/quickedit/Tests/Access/EditEntityFieldAccessCheckTest.php
@@ -8,7 +8,6 @@
 namespace Drupal\quickedit\Tests\Access;
 
 use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\Routing\Route;
 use Drupal\Core\Access\AccessCheckInterface;
 use Drupal\quickedit\Access\EditEntityFieldAccessCheck;
 use Drupal\Tests\UnitTestCase;
@@ -118,13 +117,13 @@ public function providerTestAccess() {
    * @dataProvider providerTestAccess
    */
   public function testAccess(EntityInterface $entity, FieldConfigInterface $field = NULL, $expected_result) {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
 
+    $field_name = 'valid';
     $entity_with_field = clone $entity;
     $entity_with_field->expects($this->any())
       ->method('get')
-      ->with('valid')
+      ->with($field_name)
       ->will($this->returnValue($field));
     $entity_with_field->expects($this->once())
       ->method('hasTranslation')
@@ -134,11 +133,11 @@ public function testAccess(EntityInterface $entity, FieldConfigInterface $field
     // Prepare the request to be valid.
     $request->attributes->set('entity_type', 'test_entity');
     $request->attributes->set('entity', $entity_with_field);
-    $request->attributes->set('field_name', 'valid');
+    $request->attributes->set('field_name', $field_name);
     $request->attributes->set('langcode', Language::LANGCODE_NOT_SPECIFIED);
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $access = $this->editAccessCheck->access($route, $request, $account);
+    $access = $this->editAccessCheck->access($request, $field_name, $account);
     $this->assertSame($expected_result, $access);
   }
 
@@ -146,7 +145,6 @@ public function testAccess(EntityInterface $entity, FieldConfigInterface $field
    * Tests the access method with an undefined entity type.
    */
   public function testAccessWithUndefinedEntityType() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'non_valid');
 
@@ -156,14 +154,13 @@ public function testAccessWithUndefinedEntityType() {
       ->will($this->returnValue(NULL));
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, NULL, $account));
   }
 
   /**
    * Tests the access method with a non existing entity.
    */
   public function testAccessWithNotExistingEntity() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', 1);
@@ -179,48 +176,47 @@ public function testAccessWithNotExistingEntity() {
       ->will($this->returnValue(NULL));
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, NULL, $account));
   }
 
   /**
    * Tests the access method with a forgotten passed field_name.
    */
   public function testAccessWithNotPassedFieldName() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', $this->createMockEntity());
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, NULL, $account));
   }
 
   /**
    * Tests the access method with a non existing field.
    */
   public function testAccessWithNonExistingField() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
+    $field_name = 'not_valid';
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', $this->createMockEntity());
-    $request->attributes->set('field_name', 'not_valid');
+    $request->attributes->set('field_name', $field_name);
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, $field_name, $account));
   }
 
   /**
    * Tests the access method with a forgotten passed language.
    */
   public function testAccessWithNotPassedLanguage() {
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
+    $field_name = 'valid';
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', $this->createMockEntity());
-    $request->attributes->set('field_name', 'valid');
+    $request->attributes->set('field_name', $field_name);
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, $field_name, $account));
   }
 
   /**
@@ -233,15 +229,15 @@ public function testAccessWithInvalidLanguage() {
       ->with('xx-lolspeak')
       ->will($this->returnValue(FALSE));
 
-    $route = new Route('/quickedit/form/test_entity/1/body/und/full', array(), array('_access_quickedit_entity_field' => 'TRUE'));
     $request = new Request();
+    $field_name = 'valid';
     $request->attributes->set('entity_type', 'entity_test');
     $request->attributes->set('entity', $entity);
-    $request->attributes->set('field_name', 'valid');
+    $request->attributes->set('field_name', $field_name);
     $request->attributes->set('langcode', 'xx-lolspeak');
 
     $account = $this->getMock('Drupal\Core\Session\AccountInterface');
-    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($route, $request, $account));
+    $this->assertSame(AccessCheckInterface::KILL, $this->editAccessCheck->access($request, $field_name, $account));
   }
 
   /**
diff --git a/core/modules/rest/lib/Drupal/rest/Access/CSRFAccessCheck.php b/core/modules/rest/lib/Drupal/rest/Access/CSRFAccessCheck.php
index 396b3a1..fcb5330 100644
--- a/core/modules/rest/lib/Drupal/rest/Access/CSRFAccessCheck.php
+++ b/core/modules/rest/lib/Drupal/rest/Access/CSRFAccessCheck.php
@@ -41,9 +41,16 @@ public function applies(Route $route) {
   }
 
   /**
-   * Implements AccessCheckInterface::access().
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Request $request, AccountInterface $account) {
     $method = $request->getMethod();
     $cookie = $request->attributes->get('_authentication_provider') == 'cookie';
 
diff --git a/core/modules/shortcut/shortcut.services.yml b/core/modules/shortcut/shortcut.services.yml
index a660594..dc8d30c 100644
--- a/core/modules/shortcut/shortcut.services.yml
+++ b/core/modules/shortcut/shortcut.services.yml
@@ -1,14 +1,4 @@
 services:
-  access_check.shortcut.link:
-    class: Drupal\shortcut\Access\LinkAccessCheck
-    tags:
-      - { name: access_check, applies_to: _access_shortcut_link }
-
-  access_check.shortcut.shortcut_set_edit:
-    class: Drupal\shortcut\Access\ShortcutSetEditAccessCheck
-    tags:
-      - { name: access_check, applies_to: _access_shortcut_set_edit }
-
   access_check.shortcut.shortcut_set_switch:
     class: Drupal\shortcut\Access\ShortcutSetSwitchAccessCheck
     tags:
diff --git a/core/modules/shortcut/src/Access/LinkAccessCheck.php b/core/modules/shortcut/src/Access/LinkAccessCheck.php
deleted file mode 100644
index b85fb9f..0000000
--- a/core/modules/shortcut/src/Access/LinkAccessCheck.php
+++ /dev/null
@@ -1,32 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\shortcut\Access\LinkAccessCheck.
- */
-
-namespace Drupal\shortcut\Access;
-
-use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Provides an access check for shortcut link delete routes.
- */
-class LinkAccessCheck implements AccessInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $menu_link = $request->attributes->get('menu_link');
-    $set_name = str_replace('shortcut-', '', $menu_link['menu_name']);
-    if ($shortcut_set = shortcut_set_load($set_name)) {
-      return shortcut_set_edit_access($shortcut_set) ? static::ALLOW : static::DENY;
-    }
-    return static::DENY;
-  }
-
-}
diff --git a/core/modules/shortcut/src/Access/ShortcutSetEditAccessCheck.php b/core/modules/shortcut/src/Access/ShortcutSetEditAccessCheck.php
deleted file mode 100644
index 21bbda8..0000000
--- a/core/modules/shortcut/src/Access/ShortcutSetEditAccessCheck.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\shortcut\Access\ShortcutSetEditAccessCheck.
- */
-
-namespace Drupal\shortcut\Access;
-
-use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
-
-/**
- * Provides an access check for shortcut link delete routes.
- */
-class ShortcutSetEditAccessCheck implements AccessInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $account = \Drupal::currentUser();
-    $shortcut_set = $request->attributes->get('shortcut_set');
-    // Sufficiently-privileged users can edit their currently displayed shortcut
-    // set, but not other sets. Shortcut administrators can edit any set.
-    if ($account->hasPermission('administer shortcuts')) {
-      return static::ALLOW;
-    }
-    if ($account->hasPermission('customize shortcut links')) {
-      return !isset($shortcut_set) || $shortcut_set == shortcut_current_displayed_set() ? static::ALLOW : static::DENY;
-    }
-    return static::DENY;
-  }
-
-}
diff --git a/core/modules/shortcut/src/Access/ShortcutSetSwitchAccessCheck.php b/core/modules/shortcut/src/Access/ShortcutSetSwitchAccessCheck.php
index 6d844ed..da2fa16 100644
--- a/core/modules/shortcut/src/Access/ShortcutSetSwitchAccessCheck.php
+++ b/core/modules/shortcut/src/Access/ShortcutSetSwitchAccessCheck.php
@@ -9,18 +9,24 @@
 
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\user\UserInterface;
 
 /**
- * Provides an access check for shortcut link delete routes.
+ * Checks access to switch a user's shortcut set.
  */
 class ShortcutSetSwitchAccessCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Drupal\user\UserInterface $user
+   *   The owner of the shortcut set.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(UserInterface $user, AccountInterface $account) {
     if ($account->hasPermission('administer shortcuts')) {
       // Administrators can switch anyone's shortcut set.
       return static::ALLOW;
@@ -31,8 +37,7 @@ public function access(Route $route, Request $request, AccountInterface $account
       return static::DENY;
     }
 
-    $user = $request->attributes->get('account');
-    if (!isset($user) || $user->id() == $account->id()) {
+    if ($user->id() == $account->id()) {
       // Users with the 'switch shortcut sets' permission can switch their own
       // shortcuts sets.
       return static::ALLOW;
diff --git a/core/modules/system/lib/Drupal/system/Access/CronAccessCheck.php b/core/modules/system/lib/Drupal/system/Access/CronAccessCheck.php
index ef094fd..02465f9 100644
--- a/core/modules/system/lib/Drupal/system/Access/CronAccessCheck.php
+++ b/core/modules/system/lib/Drupal/system/Access/CronAccessCheck.php
@@ -8,9 +8,6 @@
 namespace Drupal\system\Access;
 
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Access check for cron routes.
@@ -18,10 +15,14 @@
 class CronAccessCheck implements AccessInterface {
 
   /**
-   * Implements AccessCheckInterface::access().
+   * Checks access.
+   *
+   * @param string $key
+   *   The cron key.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $key = $request->attributes->get('key');
+  public function access($key) {
     if ($key != \Drupal::state()->get('system.cron_key')) {
       watchdog('cron', 'Cron could not run because an invalid key was used.', array(), WATCHDOG_NOTICE);
       return static::KILL;
diff --git a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/DefinedTestAccessCheck.php b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/DefinedTestAccessCheck.php
index 7aa50dc..c6b5a9f 100644
--- a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/DefinedTestAccessCheck.php
+++ b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/DefinedTestAccessCheck.php
@@ -8,8 +8,6 @@
 namespace Drupal\router_test\Access;
 
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -18,9 +16,14 @@
 class DefinedTestAccessCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route) {
     if ($route->getRequirement('_test_access') === 'TRUE') {
       return static::ALLOW;
     }
diff --git a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/TestAccessCheck.php b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/TestAccessCheck.php
index eda7560..495f859 100644
--- a/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/TestAccessCheck.php
+++ b/core/modules/system/tests/modules/router_test_directory/lib/Drupal/router_test/Access/TestAccessCheck.php
@@ -8,9 +8,6 @@
 namespace Drupal\router_test\Access;
 
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Access check for test routes.
@@ -18,9 +15,11 @@
 class TestAccessCheck implements AccessInterface {
 
   /**
-   * Implements AccessCheckInterface::access().
+   * Checks access.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access() {
     // No opinion, so other access checks should decide if access should be
     // allowed or not.
     return static::DENY;
diff --git a/core/modules/tracker/lib/Drupal/tracker/Access/ViewOwnTrackerAccessCheck.php b/core/modules/tracker/lib/Drupal/tracker/Access/ViewOwnTrackerAccessCheck.php
index a4c594e..a85926c 100644
--- a/core/modules/tracker/lib/Drupal/tracker/Access/ViewOwnTrackerAccessCheck.php
+++ b/core/modules/tracker/lib/Drupal/tracker/Access/ViewOwnTrackerAccessCheck.php
@@ -9,8 +9,7 @@
 
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
+use Drupal\user\UserInterface;
 
 /**
  * Access check for user tracker routes.
@@ -18,12 +17,16 @@
 class ViewOwnTrackerAccessCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   * @param \Drupal\user\UserInterface $user
+   *   The user whose tracker page is being accessed.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    // The user object from the User ID in the path.
-    $user = $request->attributes->get('user');
+  public function access(AccountInterface $account, UserInterface $user) {
     return ($user && $account->isAuthenticated() && ($user->id() == $account->id())) ? static::ALLOW : static::DENY;
   }
 }
-
diff --git a/core/modules/update/lib/Drupal/update/Access/UpdateManagerAccessCheck.php b/core/modules/update/lib/Drupal/update/Access/UpdateManagerAccessCheck.php
index 5fba57f..e11c540 100644
--- a/core/modules/update/lib/Drupal/update/Access/UpdateManagerAccessCheck.php
+++ b/core/modules/update/lib/Drupal/update/Access/UpdateManagerAccessCheck.php
@@ -8,10 +8,7 @@
 namespace Drupal\update\Access;
 
 use Drupal\Core\Routing\Access\AccessInterface;
-use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Site\Settings;
-use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Determines whether allow authorized operations is set.
@@ -36,9 +33,11 @@ public function __construct(Settings $settings) {
   }
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access() {
     return $this->settings->get('allow_authorize_operations', TRUE) ? static::ALLOW : static::DENY;
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php b/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php
index 01d7a6c..f680bcc 100644
--- a/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php
+++ b/core/modules/user/lib/Drupal/user/Access/LoginStatusCheck.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -18,9 +17,16 @@
 class LoginStatusCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Request $request, AccountInterface $account) {
     return ($request->attributes->get('_menu_admin') || $account->isAuthenticated()) ? static::ALLOW : static::DENY;
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Access/PermissionAccessCheck.php b/core/modules/user/lib/Drupal/user/Access/PermissionAccessCheck.php
index a159b1c..59af9c5 100644
--- a/core/modules/user/lib/Drupal/user/Access/PermissionAccessCheck.php
+++ b/core/modules/user/lib/Drupal/user/Access/PermissionAccessCheck.php
@@ -10,7 +10,6 @@
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
 use Symfony\Component\Routing\Route;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Determines access to routes based on permissions defined via hook_permission().
@@ -18,11 +17,17 @@
 class PermissionAccessCheck implements AccessInterface {
 
   /**
-   * Implements AccessCheckInterface::access().
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, AccountInterface $account) {
     $permission = $route->getRequirement('_permission');
-    // If the access check fails, return NULL to give other checks a chance.
     return $account->hasPermission($permission) ? static::ALLOW : static::DENY;
   }
 }
diff --git a/core/modules/user/lib/Drupal/user/Access/RegisterAccessCheck.php b/core/modules/user/lib/Drupal/user/Access/RegisterAccessCheck.php
index eff984b..3cc7568 100644
--- a/core/modules/user/lib/Drupal/user/Access/RegisterAccessCheck.php
+++ b/core/modules/user/lib/Drupal/user/Access/RegisterAccessCheck.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\Routing\Route;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -18,9 +17,16 @@
 class RegisterAccessCheck implements AccessInterface {
 
   /**
-   * Implements AccessCheckInterface::access().
+   * Checks access.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Request $request, AccountInterface $account) {
     return ($request->attributes->get('_menu_admin') || $account->isAnonymous()) && (\Drupal::config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) ? static::ALLOW : static::DENY;
   }
 }
diff --git a/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php b/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php
index e3ace16..aabfb76 100644
--- a/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php
+++ b/core/modules/user/lib/Drupal/user/Access/RoleAccessCheck.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -22,9 +21,16 @@
 class RoleAccessCheck implements AccessInterface {
 
   /**
-   * {@inheritdoc}
+   * Checks access.
+   *
+   * @param \Symfony\Component\Routing\Route $route
+   *   The route to check against.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
+  public function access(Route $route, AccountInterface $account) {
     // Requirements just allow strings, so this might be a comma separated list.
     $rid_string = $route->getRequirement('_role');
 
diff --git a/core/modules/views/lib/Drupal/views/ViewsAccessCheck.php b/core/modules/views/lib/Drupal/views/ViewsAccessCheck.php
index 8a81fb7..294fc9b 100644
--- a/core/modules/views/lib/Drupal/views/ViewsAccessCheck.php
+++ b/core/modules/views/lib/Drupal/views/ViewsAccessCheck.php
@@ -9,7 +9,6 @@
 
 use Drupal\Core\Access\AccessCheckInterface;
 use Drupal\Core\Session\AccountInterface;
-use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -27,12 +26,15 @@ public function applies(Route $route) {
   }
 
   /**
-   * Implements AccessCheckInterface::applies().
+   * Checks access.
+   *
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The currently logged in account.
+   *
+   * @return One of the constants from \Drupal\Core\Access\AccessInterface.
    */
-  public function access(Route $route, Request $request, AccountInterface $account) {
-    $access = $account->hasPermission('access all views');
-
-    return $access ? static::ALLOW : static::DENY;
+  public function access(AccountInterface $account) {
+    return $account->hasPermission('access all views') ? static::ALLOW : static::DENY;
   }
 
 }
diff --git a/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
index 0e830e2..77d93fe 100644
--- a/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/AccessManagerTest.php
@@ -76,6 +76,13 @@ class AccessManagerTest extends UnitTestCase {
    */
   protected $account;
 
+  /**
+   * The access arguments resolver.
+   *
+   * @var \Drupal\Core\Access\AccessArgumentsResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $argumentsResolver;
+
   public static function getInfo() {
     return array(
       'name' => 'Access manager tests',
@@ -122,8 +129,9 @@ protected function setUp() {
     $this->paramConverter = $this->getMock('Drupal\Core\ParamConverter\ParamConverterManagerInterface');
 
     $this->account = $this->getMock('Drupal\Core\Session\AccountInterface');
+    $this->argumentsResolver = $this->getMock('Drupal\Core\Access\AccessArgumentsResolverInterface');
 
-    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->account);
+    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $this->accessManager->setContainer($this->container);
   }
 
@@ -152,13 +160,13 @@ public function testSetChecks() {
    */
   public function testSetChecksWithDynamicAccessChecker() {
     // Setup the access manager.
-    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->account);
+    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $this->accessManager->setContainer($this->container);
 
     // Setup the dynamic access checker.
-    $access_check = $this->getMock('Drupal\Core\Access\AccessCheckInterface');
+    $access_check = $this->getMock('Drupal\Tests\Core\Access\TestAccessCheckInterface');
     $this->container->set('test_access', $access_check);
-    $this->accessManager->addCheckService('test_access');
+    $this->accessManager->addCheckService('test_access', 'access');
 
     $route = new Route('/test-path', array(), array('_foo' => '1', '_bar' => '1'));
     $route2 = new Route('/test-path', array(), array('_foo' => '1', '_bar' => '2'));
@@ -198,6 +206,11 @@ public function testCheck() {
     }
 
     $this->accessManager->setChecks($this->routeCollection);
+    $this->argumentsResolver->expects($this->any())
+      ->method('getArguments')
+      ->will($this->returnCallback(function ($callable, $route, $request, $account) {
+        return array($route);
+      }));
 
     $this->assertFalse($this->accessManager->check($this->routeCollection->get('test_route_1'), $request, $this->account));
     $this->assertTrue($this->accessManager->check($this->routeCollection->get('test_route_2'), $request, $this->account));
@@ -353,7 +366,7 @@ public function testCheckConjunctions($conjunction, $name, $condition_one, $cond
     $this->setupAccessChecker();
     $access_check = new DefinedTestAccessCheck();
     $this->container->register('test_access_defined', $access_check);
-    $this->accessManager->addCheckService('test_access_defined', array('_test_access'));
+    $this->accessManager->addCheckService('test_access_defined', 'access', array('_test_access'));
 
     $request = new Request();
 
@@ -366,6 +379,11 @@ public function testCheckConjunctions($conjunction, $name, $condition_one, $cond
     $options = $conjunction ? array('_access_mode' => $conjunction) : array();
     $route = new Route($name, array(), $requirements, $options);
     $route_collection->add($name, $route);
+    $this->argumentsResolver->expects($this->any())
+      ->method('getArguments')
+      ->will($this->returnCallback(function ($callable, $route, $request, $account) {
+        return array($route, $request, $account);
+      }));
 
     $this->accessManager->setChecks($route_collection);
     $this->assertSame($this->accessManager->check($route, $request, $this->account), $expected_access);
@@ -379,6 +397,11 @@ public function testCheckConjunctions($conjunction, $name, $condition_one, $cond
   public function testCheckNamedRoute() {
     $this->setupAccessChecker();
     $this->accessManager->setChecks($this->routeCollection);
+    $this->argumentsResolver->expects($this->any())
+      ->method('getArguments')
+      ->will($this->returnCallback(function ($callable, $route, $request, $account) {
+        return array($route, $request, $account);
+      }));
 
     // Tests the access with routes without parameters.
     $request = new Request();
@@ -444,23 +467,22 @@ public function testCheckNamedRouteWithUpcastedValues() {
       ->with('/test-route-1/example')
       ->will($this->returnValue($subrequest));
 
-    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->account);
+    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $this->accessManager->setContainer($this->container);
     $this->accessManager->setRequest(new Request());
 
-    $access_check = $this->getMock('Drupal\Core\Access\AccessCheckInterface');
+    $access_check = $this->getMock('Drupal\Tests\Core\Access\TestAccessCheckInterface');
     $access_check->expects($this->any())
       ->method('applies')
       ->will($this->returnValue(TRUE));
     $access_check->expects($this->any())
       ->method('access')
-      ->with($route, $subrequest)
       ->will($this->returnValue(AccessInterface::KILL));
 
     $subrequest->attributes->set('value', 'upcasted_value');
     $this->container->register('test_access', $access_check);
 
-    $this->accessManager->addCheckService('test_access');
+    $this->accessManager->addCheckService('test_access', 'access');
     $this->accessManager->setChecks($this->routeCollection);
 
     $this->assertFalse($this->accessManager->checkNamedRoute('test_route_1', array('value' => 'example'), $this->account));
@@ -504,23 +526,22 @@ public function testCheckNamedRouteWithDefaultValue() {
       ->with('/test-route-1/example')
       ->will($this->returnValue($subrequest));
 
-    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->account);
+    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $this->accessManager->setContainer($this->container);
     $this->accessManager->setRequest(new Request());
 
-    $access_check = $this->getMock('Drupal\Core\Access\AccessCheckInterface');
+    $access_check = $this->getMock('Drupal\Tests\Core\Access\TestAccessCheckInterface');
     $access_check->expects($this->any())
       ->method('applies')
       ->will($this->returnValue(TRUE));
     $access_check->expects($this->any())
       ->method('access')
-      ->with($route, $subrequest)
       ->will($this->returnValue(AccessInterface::KILL));
 
     $subrequest->attributes->set('value', 'upcasted_value');
     $this->container->register('test_access', $access_check);
 
-    $this->accessManager->addCheckService('test_access');
+    $this->accessManager->addCheckService('test_access', 'access');
     $this->accessManager->setChecks($this->routeCollection);
 
     $this->assertFalse($this->accessManager->checkNamedRoute('test_route_1', array(), $this->account));
@@ -566,21 +587,26 @@ public function testCheckException($return_value, $access_mode) {
     $route_provider->expects($this->any())
       ->method('getRouteByName')
       ->will($this->returnValue($route));
+    $this->argumentsResolver->expects($this->any())
+      ->method('getArguments')
+      ->will($this->returnCallback(function ($callable, $route, $request, $account) {
+        return array($route);
+      }));
 
     $request = new Request();
 
     $container = new ContainerBuilder();
 
     // Register a service that will return an incorrect value.
-    $access_check = $this->getMock('Drupal\Core\Routing\Access\AccessInterface');
+    $access_check = $this->getMock('Drupal\Tests\Core\Access\TestAccessCheckInterface');
     $access_check->expects($this->any())
       ->method('access')
       ->will($this->returnValue($return_value));
     $container->set('test_incorrect_value', $access_check);
 
-    $access_manager = new AccessManager($route_provider, $this->urlGenerator, $this->paramConverter);
+    $access_manager = new AccessManager($route_provider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $access_manager->setContainer($container);
-    $access_manager->addCheckService('test_incorrect_value');
+    $access_manager->addCheckService('test_incorrect_value', 'access');
 
     $access_manager->checkNamedRoute('test_incorrect_value', array(), $this->account, $request);
   }
@@ -633,11 +659,18 @@ protected static function convertAccessCheckInterfaceToString($constant) {
    * Adds a default access check service to the container and the access manager.
    */
   protected function setupAccessChecker() {
-    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->account);
+    $this->accessManager = new AccessManager($this->routeProvider, $this->urlGenerator, $this->paramConverter, $this->argumentsResolver);
     $this->accessManager->setContainer($this->container);
     $access_check = new DefaultAccessCheck();
     $this->container->register('test_access_default', $access_check);
-    $this->accessManager->addCheckService('test_access_default', array('_access'));
+    $this->accessManager->addCheckService('test_access_default', 'access', array('_access'));
   }
 
 }
+
+/**
+ * An interface with a defined access() method for mocking.
+ */
+interface TestAccessCheckInterface extends AccessCheckInterface {
+  public function access();
+}
diff --git a/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php
index 19a8bff..dca5620 100644
--- a/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php
+++ b/core/tests/Drupal/Tests/Core/Access/CustomAccessCheckTest.php
@@ -34,6 +34,13 @@ class CustomAccessCheckTest extends UnitTestCase {
    */
   protected $controllerResolver;
 
+  /**
+   * The mocked arguments resolver.
+   *
+   * @var \Drupal\Core\Access\AccessArgumentsResolverInterface|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $argumentsResolver;
+
   public static function getInfo() {
     return array(
       'name' => 'Custom access check',
@@ -49,7 +56,8 @@ protected function setUp() {
     parent::setUp();
 
     $this->controllerResolver = $this->getMock('Drupal\Core\Controller\ControllerResolverInterface');
-    $this->accessChecker = new CustomAccessCheck($this->controllerResolver);
+    $this->argumentsResolver = $this->getMock('Drupal\Core\Access\AccessArgumentsResolverInterface');
+    $this->accessChecker = new CustomAccessCheck($this->controllerResolver, $this->argumentsResolver);
   }
 
   /**
@@ -63,25 +71,25 @@ public function testAccess() {
       ->with('\Drupal\Tests\Core\Access\TestController::accessDeny')
       ->will($this->returnValue(array(new TestController(), 'accessDeny')));
 
-    $this->controllerResolver->expects($this->at(1))
+    $this->argumentsResolver->expects($this->at(0))
       ->method('getArguments')
       ->will($this->returnValue(array()));
 
-    $this->controllerResolver->expects($this->at(2))
+    $this->controllerResolver->expects($this->at(1))
       ->method('getControllerFromDefinition')
       ->with('\Drupal\Tests\Core\Access\TestController::accessAllow')
       ->will($this->returnValue(array(new TestController(), 'accessAllow')));
 
-    $this->controllerResolver->expects($this->at(3))
+    $this->argumentsResolver->expects($this->at(1))
       ->method('getArguments')
       ->will($this->returnValue(array()));
 
-    $this->controllerResolver->expects($this->at(4))
+    $this->controllerResolver->expects($this->at(2))
       ->method('getControllerFromDefinition')
       ->with('\Drupal\Tests\Core\Access\TestController::accessParameter')
       ->will($this->returnValue(array(new TestController(), 'accessParameter')));
 
-    $this->controllerResolver->expects($this->at(5))
+    $this->argumentsResolver->expects($this->at(2))
       ->method('getArguments')
       ->will($this->returnValue(array('parameter' => 'TRUE')));
 
diff --git a/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php
index 873ff0e..aec50c2 100644
--- a/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php
+++ b/core/tests/Drupal/Tests/Core/Route/RoleAccessCheckTest.php
@@ -8,13 +8,9 @@
 namespace Drupal\Tests\Core\Route;
 
 use Drupal\Core\Access\AccessCheckInterface;
-use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Session\UserSession;
 use Drupal\Tests\UnitTestCase;
 use Drupal\user\Access\RoleAccessCheck;
-use Symfony\Component\DependencyInjection\Container;
-use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\HttpKernelInterface;
 use Symfony\Component\Routing\Route;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -159,16 +155,14 @@ public function testRoleAccess($path, $grant_accounts, $deny_accounts) {
     $collection = $this->getTestRouteCollection();
 
     foreach ($grant_accounts as $account) {
-      $subrequest = Request::create($path, 'GET');
       $message = sprintf('Access granted for user with the roles %s on path: %s', implode(', ', $account->getRoles()), $path);
-      $this->assertSame(AccessCheckInterface::ALLOW, $role_access_check->access($collection->get($path), $subrequest, $account), $message);
+      $this->assertSame(AccessCheckInterface::ALLOW, $role_access_check->access($collection->get($path), $account), $message);
     }
 
     // Check all users which don't have access.
     foreach ($deny_accounts as $account) {
-      $subrequest = Request::create($path, 'GET');
       $message = sprintf('Access denied for user %s with the roles %s on path: %s', $account->id(), implode(', ', $account->getRoles()), $path);
-      $has_access = $role_access_check->access($collection->get($path), $subrequest, $account);
+      $has_access = $role_access_check->access($collection->get($path), $account);
       $this->assertSame(AccessCheckInterface::DENY, $has_access , $message);
     }
   }
