diff --git a/.htaccess b/.htaccess
index a69bdd4..725897e 100644
--- a/.htaccess
+++ b/.htaccess
@@ -109,7 +109,7 @@ DirectoryIndex index.php index.html index.htm
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_URI} !=/favicon.ico
-  RewriteRule ^ index.php [L]
+  RewriteRule ^(.*)$ index.php [L]
 
   # Rules to correctly serve gzip compressed CSS and JS files.
   # Requires both mod_rewrite and mod_headers to be enabled.
diff --git a/core/includes/batch.inc b/core/includes/batch.inc
index 83ddd30..0b07d8e 100644
--- a/core/includes/batch.inc
+++ b/core/includes/batch.inc
@@ -14,6 +14,8 @@
  * @see batch_get()
  */
 
+use \Symfony\Component\HttpFoundation\JsonResponse;
+
 /**
  * Loads a batch from the database.
  *
@@ -77,7 +79,7 @@ function _batch_page() {
 
     case 'do':
       // JavaScript-based progress page callback.
-      _batch_do();
+      $output = _batch_do();
       break;
 
     case 'do_nojs':
@@ -160,7 +162,7 @@ function _batch_do() {
   // Perform actual processing.
   list($percentage, $message) = _batch_process();
 
-  drupal_json_output(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
+  return new JsonResponse(array('status' => TRUE, 'percentage' => $percentage, 'message' => $message));
 }
 
 /**
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 12b1d80..d76ca4c 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -3,6 +3,7 @@
 use Drupal\Core\Database\Database;
 use Symfony\Component\ClassLoader\UniversalClassLoader;
 use Symfony\Component\ClassLoader\ApcUniversalClassLoader;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * @file
@@ -1511,6 +1512,27 @@ function request_uri() {
 }
 
 /**
+ * Returns the current global reuqest object.
+ *
+ * @todo Replace this function with a proper dependency injection container.
+ *
+ * @staticvar Request $request
+ * @param Request $new_request
+ *   The new request object to store. If you are not index.php, you probably
+ *   should not be using this parameter.
+ * @return Request
+ *   The current request object.
+ */
+function request(Request $new_request = NULL) {
+  static $request;
+
+  if ($new_request) {
+    $request = $new_request;
+  }
+  return $request;
+}
+
+/**
  * Logs an exception.
  *
  * This is a wrapper function for watchdog() which automatically decodes an
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 5ff6167..cd21512 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1,5 +1,7 @@
 <?php
 
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Drupal\Core\Database\Database;
 
 /**
@@ -711,7 +713,11 @@ function drupal_site_offline() {
  * bubble up to menu_execute_active_handler() should call drupal_not_found().
  */
 function drupal_not_found() {
-  drupal_deliver_page(MENU_NOT_FOUND);
+
+  throw new NotFoundHttpException();
+
+  // @todo Remove this line.
+  //drupal_deliver_page(MENU_NOT_FOUND);
 }
 
 /**
@@ -724,7 +730,11 @@ function drupal_not_found() {
  * drupal_access_denied().
  */
 function drupal_access_denied() {
-  drupal_deliver_page(MENU_ACCESS_DENIED);
+
+  throw new AccessDeniedHttpException();
+
+  // @todo Remove this line.
+  //drupal_deliver_page(MENU_ACCESS_DENIED);
 }
 
 /**
@@ -2246,31 +2256,20 @@ function url($path = NULL, array $options = array()) {
   $base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
   $prefix = empty($path) ? rtrim($options['prefix'], '/') : $options['prefix'];
 
-  // With Clean URLs.
-  if (!empty($GLOBALS['conf']['clean_url'])) {
-    $path = drupal_encode_path($prefix . $path);
-    if ($options['query']) {
-      return $base . $path . '?' . drupal_http_build_query($options['query']) . $options['fragment'];
-    }
-    else {
-      return $base . $path . $options['fragment'];
-    }
+  // If Clean URLs are not enabled, we need to prefix the script name onto
+  // the link.
+  // @todo: Make this dynamic based on the request object without using a global
+  // request object.
+  if (empty($GLOBALS['conf']['clean_url'])) {
+    $base .= 'index.php/';
+  }
+
+  $path = drupal_encode_path($prefix . $path);
+  if ($options['query']) {
+    return $base . $path . '?' . drupal_http_build_query($options['query']) . $options['fragment'];
   }
-  // Without Clean URLs.
   else {
-    $path = $prefix . $path;
-    $query = array();
-    if (!empty($path)) {
-      $query['q'] = $path;
-    }
-    if ($options['query']) {
-      // We do not use array_merge() here to prevent overriding $path via query
-      // parameters.
-      $query += $options['query'];
-    }
-    $query = $query ? ('?' . drupal_http_build_query($query)) : '';
-    $script = isset($options['script']) ? $options['script'] : '';
-    return $base . $script . $query . $options['fragment'];
+    return $base . $path . $options['fragment'];
   }
 }
 
@@ -5243,7 +5242,7 @@ function _drupal_bootstrap_full() {
  *
  * @see drupal_page_header()
  */
-function drupal_page_set_cache() {
+function drupal_page_set_cache($response_body) {
   global $base_root;
 
   if (drupal_page_is_cacheable()) {
@@ -5251,7 +5250,7 @@ function drupal_page_set_cache() {
       'cid' => $base_root . request_uri(),
       'data' => array(
         'path' => $_GET['q'],
-        'body' => ob_get_clean(),
+        'body' => $response_body,
         'title' => drupal_get_title(),
         'headers' => array(),
       ),
diff --git a/core/includes/file.inc b/core/includes/file.inc
index eaff634..fa6670d 100644
--- a/core/includes/file.inc
+++ b/core/includes/file.inc
@@ -5,6 +5,9 @@
  * API for handling file uploads and server file management.
  */
 
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpFoundation\StreamedResponse;
 use Drupal\Core\StreamWrapper\LocalStream;
 
 /**
@@ -2046,18 +2049,27 @@ function file_download() {
       $function = $module . '_file_download';
       $result = $function($uri);
       if ($result == -1) {
-        return drupal_access_denied();
+        throw new AccessDeniedHttpException();
       }
       if (isset($result) && is_array($result)) {
         $headers = array_merge($headers, $result);
       }
     }
     if (count($headers)) {
-      file_transfer($uri, $headers);
+      return new StreamedResponse(function() use ($uri) {
+        $scheme = file_uri_scheme($uri);
+        // Transfer file in 1024 byte chunks to save memory usage.
+        if ($scheme && file_stream_wrapper_valid_scheme($scheme) && $fd = fopen($uri, 'rb')) {
+          while (!feof($fd)) {
+            print fread($fd, 1024);
+          }
+          fclose($fd);
+        }
+      }, 200, $headers);
     }
-    return drupal_access_denied();
+    throw new AccessDeniedHttpException();
   }
-  return drupal_not_found();
+  throw new NotFoundHttpException();
 }
 
 
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 37b3281..e7bf3f8 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -3,6 +3,9 @@
 use Drupal\Core\Database\Database;
 use Drupal\Core\Database\Install\TaskException;
 
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+
 /**
  * @file
  * API functions for installing Drupal.
@@ -261,6 +264,14 @@ function install_begin_request(&$install_state) {
 
   drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
 
+  // A request object from the HTTPFoundation to tell us about the request.
+  $request = Request::createFromGlobals();
+
+  // Set the global $request object.  This is a temporary measure to
+  // keep legacy utility functions working.  It should be moved to a dependency
+  // injection container at some point.
+  request($request);
+
   // This must go after drupal_bootstrap(), which unsets globals!
   global $conf;
 
@@ -488,6 +499,15 @@ function install_run_task($task, &$install_state) {
     elseif ($current_batch == $function) {
       include_once DRUPAL_ROOT . '/core/includes/batch.inc';
       $output = _batch_page();
+      // Because Batch API now returns a JSON response for intermediary steps,
+      // but the installer doesn't handle Response objects yet, we will just
+      // send the output here and emulate the old model.
+      // @todo: Replace this when we refactor the installer to use a
+      // Request/Response workflow.
+      if ($output instanceof Response) {
+        $output->send();
+        $output = NULL;
+      }
       // The task is complete when we try to access the batch page and receive
       // FALSE in return, since this means we are at a URL where we are no
       // longer requesting a batch ID.
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index fecd158..9ccac08 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -3807,7 +3807,7 @@ function _menu_site_is_offline($check_only = FALSE) {
       // Ensure that the maintenance mode message is displayed only once
       // (allowing for page redirects) and specifically suppress its display on
       // the maintenance mode settings page.
-      if (!$check_only && $_GET['q'] != 'admin/config/development/maintenance') {
+      if (!$check_only && request()->attributes->get('system_path') != '/admin/config/development/maintenance') {
         if (user_access('administer site configuration')) {
           drupal_set_message(t('Operating in maintenance mode. <a href="@url">Go online.</a>', array('@url' => url('admin/config/development/maintenance'))), 'status', FALSE);
         }
diff --git a/core/lib/Drupal/Core/ContentNegotiation.php b/core/lib/Drupal/Core/ContentNegotiation.php
new file mode 100644
index 0000000..e19d950
--- /dev/null
+++ b/core/lib/Drupal/Core/ContentNegotiation.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\ContentNegotiation.
+ */
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * This class is a central library for content type negotiation.
+ *
+ * @todo Replace this class with a real content negotiation library based on
+ * mod_negotiation.  Development of that is a work in progress.
+ */
+class ContentNegotiation {
+
+  /**
+   * Returns the normalized type of a given request.
+   *
+   * The normalized type is a short, lowercase version of the format, such as
+   * "html" or "json" or "atom".
+   *
+   * @param Request $request
+   *   The request object from which to extract the content type.
+   */
+  public function getContentType(Request $request) {
+    $acceptable_content_types = $request->getAcceptableContentTypes();
+
+    // AJAX iframe uploads need special handling, because they contain a json
+    // response wrapped in <textarea>.
+    if ($request->get('ajax_iframe_upload', FALSE)) {
+      return 'iframeupload';
+    }
+
+    // AJAX calls need to be run through ajax rendering functions
+    elseif ($request->isXmlHttpRequest()) {
+      return 'ajax';
+    }
+
+    // JSON requests can be responded to using JsonResponse().
+    elseif (in_array('application/json', $acceptable_content_types)) {
+      return 'json';
+    }
+
+    // Do HTML last so that it always wins for */* formats.
+    elseif(in_array('text/html', $acceptable_content_types) || in_array('*/*', $acceptable_content_types)) {
+      return 'html';
+    }
+  }
+
+}
+
diff --git a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
index 2961aeb..f5e493d 100644
--- a/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
+++ b/core/lib/Drupal/Core/Database/Driver/mysql/Schema.php
@@ -140,13 +140,8 @@ class Schema extends DatabaseSchema {
   protected function createFieldSql($name, $spec) {
     $sql = "`" . $name . "` " . $spec['mysql_type'];
 
-    if (in_array($spec['mysql_type'], array('VARCHAR', 'CHAR', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT'))) {
-      if (isset($spec['length'])) {
-        $sql .= '(' . $spec['length'] . ')';
-      }
-      if (!empty($spec['binary'])) {
-        $sql .= ' BINARY';
-      }
+    if (in_array($spec['mysql_type'], array('VARCHAR', 'CHAR', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT', 'TEXT')) && isset($spec['length'])) {
+      $sql .= '(' . $spec['length'] . ')';
     }
     elseif (isset($spec['precision']) && isset($spec['scale'])) {
       $sql .= '(' . $spec['precision'] . ', ' . $spec['scale'] . ')';
diff --git a/core/lib/Drupal/Core/Database/Schema.php b/core/lib/Drupal/Core/Database/Schema.php
index 62e1327..9e2f22e 100644
--- a/core/lib/Drupal/Core/Database/Schema.php
+++ b/core/lib/Drupal/Core/Database/Schema.php
@@ -80,10 +80,6 @@ use Drupal\Core\Database\Query\PlaceholderInterface;
  *       the precision (total number of significant digits) and scale
  *       (decimal digits right of the decimal point). Both values are
  *       mandatory. Ignored for other field types.
- *     - 'binary': A boolean indicating that MySQL should force 'char',
- *       'varchar' or 'text' fields to use case-sensitive binary collation.
- *       This has no effect on other database types for which case sensitivity
- *       is already the default behavior.
  *     All parameters apart from 'type' are optional except that type
  *     'numeric' columns must specify 'precision' and 'scale', and type
  *     'varchar' must specify the 'length' parameter.
diff --git a/core/lib/Drupal/Core/Database/StatementEmpty.php b/core/lib/Drupal/Core/Database/StatementEmpty.php
index 4336fa1..84ccb6a 100644
--- a/core/lib/Drupal/Core/Database/StatementEmpty.php
+++ b/core/lib/Drupal/Core/Database/StatementEmpty.php
@@ -18,7 +18,7 @@ use Iterator;
  * database.  Calling code can then treat it the same as if it were an actual
  * result set that happens to contain no records.
  *
- * @see Drupal\search\SearchQuery
+ * @see SearchQuery
  */
 class StatementEmpty implements Iterator, StatementInterface {
 
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
new file mode 100644
index 0000000..26ff906
--- /dev/null
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -0,0 +1,88 @@
+<?php
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\DrupalKernel.
+ */
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\HttpKernel\HttpKernel;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\Event;
+use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
+use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
+use Symfony\Component\HttpKernel\EventListener\RouterListener;
+use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
+use Drupal\Core\EventSubscriber\ViewSubscriber;
+use Drupal\Core\EventSubscriber\AccessSubscriber;
+use Drupal\Core\EventSubscriber\PathSubscriber;
+use Drupal\Core\EventSubscriber\LegacyControllerSubscriber;
+use Drupal\Core\EventSubscriber\MaintenanceModeSubscriber;
+use Drupal\Core\EventSubscriber\RequestCloseSubscriber;
+
+use Exception;
+
+/**
+ * The DrupalKernel class is the core of Drupal itself.
+ */
+class DrupalKernel extends HttpKernel {
+
+    /**
+     * The event dispatcher used by this kernel.
+     *
+     * @var EventDispatcherInterface
+     */
+    protected $dispatcher;
+
+    /**
+     * The controller resolver that will extract the controller from a Request.
+     *
+     * @var ControllerResolverInterface
+     */
+    protected $resolver;
+
+
+    /**
+     * Constructor
+     *
+     * @param EventDispatcherInterface $dispatcher
+     *   An EventDispatcherInterface instance
+     * @param ControllerResolverInterface $resolver
+     *   A ControllerResolverInterface instance
+     */
+   public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver) {
+      parent::__construct($dispatcher, $resolver);
+      $this->dispatcher = $dispatcher;
+      $this->resolver = $resolver;
+
+      $context = new RequestContext();
+      $this->matcher = new UrlMatcher($context);
+      $this->dispatcher->addSubscriber(new RouterListener($this->matcher));
+
+      $negotiation = new ContentNegotiation();
+
+      // @todo Make this extensible rather than just hard coding some.
+      // @todo Add a subscriber to handle other things, too, like our Ajax
+      // replacement system.
+      $this->dispatcher->addSubscriber(new ViewSubscriber($negotiation));
+      $this->dispatcher->addSubscriber(new AccessSubscriber());
+      $this->dispatcher->addSubscriber(new MaintenanceModeSubscriber());
+      $this->dispatcher->addSubscriber(new PathSubscriber());
+      $this->dispatcher->addSubscriber(new LegacyControllerSubscriber());
+      $this->dispatcher->addSubscriber(new RequestCloseSubscriber());
+
+      // Some other form of error occured that wasn't handled by another kernel
+      // listener.  That could mean that it's a method/mime-type/error
+      // combination that is not accounted for, or some other type of error.
+      // Either way, treat it as a server-level error and return an HTTP 500.
+      // By default, this will be an HTML-type response because that's a decent
+      // best guess if we don't know otherwise.
+      $this->dispatcher->addSubscriber(new ExceptionListener(array(new ExceptionController($this, $negotiation), 'execute')));
+    }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/AccessSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/AccessSubscriber.php
new file mode 100644
index 0000000..04eac0a
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/AccessSubscriber.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\EventSubscriber\AccessSubscriber
+ */
+
+/**
+ * Access subscriber for controller requests.
+ */
+class AccessSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Verifies that the current user can access the requested path.
+   *
+   * @todo This is a total hack to keep our current access system working. It
+   * should be replaced with something robust and injected at some point.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelRequestAccessCheck(GetResponseEvent $event) {
+
+    $router_item = $event->getRequest()->attributes->get('drupal_menu_item');
+
+    if (isset($router_item['access']) && !$router_item['access']) {
+      throw new AccessDeniedHttpException();
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestAccessCheck', 30);
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php
new file mode 100644
index 0000000..cc4da15
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/LegacyControllerSubscriber.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\EventSubscriber\LegacyControllerSubscriber
+ */
+
+/**
+ * Access subscriber for controller requests.
+ */
+class LegacyControllerSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Wraps legacy controllers in a closure to handle old-style arguments.
+   *
+   * This is a backward compatibility layer only.  This is a rather ugly way
+   * to piggyback Drupal's existing menu router items onto the Symfony model,
+   * but it works for now.  If we did not do this, any menu router item with
+   * a variable number of arguments would fail to work.  This bypasses Symfony's
+   * controller argument handling entirely and lets the old-style approach work.
+   *
+   * @todo Convert Drupal to use the IETF-draft-RFC style {placeholders}. That
+   * will allow us to use the native Symfony conversion, including out-of-order
+   * argument mapping, name-based mapping, and with another listener
+   * auto-conversion of parameters to full objects.  That may necessitate not
+   * using func_get_args()-based controllers.  That is likely for the best,
+   * as those are quite hard to document anyway.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelControllerLegacy(FilterControllerEvent $event) {
+    $router_item = $event->getRequest()->attributes->get('drupal_menu_item');
+    $controller = $event->getController();
+
+    // This BC logic applies only to functions.  Otherwise, skip it.
+    if (is_string($controller) && function_exists($controller)) {
+      $new_controller = function() use ($router_item) {
+        return call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
+      };
+      $event->setController($new_controller);
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::CONTROLLER][] = array('onKernelControllerLegacy', 30);
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
new file mode 100644
index 0000000..2befe92
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @file
+ * Definition of Drupal\Core\EventSubscriber\MaintenanceModeSubscriber.
+ */
+
+/**
+ * Maintenance mode subscriber for controller requests.
+ */
+class MaintenanceModeSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Response with the maintenance page when the site is offline.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelRequestMaintenanceModeCheck(GetResponseEvent $event) {
+    // Check if the site is offline.
+    $status = _menu_site_is_offline() ? MENU_SITE_OFFLINE : MENU_SITE_ONLINE;
+
+    // Allow other modules to change the site status but not the path because
+    // that would not change the global variable. hook_url_inbound_alter() can
+    // be used to change the path. Code later will not use the $read_only_path
+    // variable.
+    $read_only_path = !empty($path) ? $path : $event->getRequest()->attributes->get('system_path');
+    drupal_alter('menu_site_status', $status, $read_only_path);
+
+    // Only continue if the site is online.
+    if ($status != MENU_SITE_ONLINE) {
+      // Deliver the 503 page.
+      drupal_maintenance_theme();
+      drupal_set_title(t('Site under maintenance'));
+      $content = theme('maintenance_page', array('content' => filter_xss_admin(variable_get('maintenance_mode_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))))));
+      $response = new Response('Service unavailable', 503);
+      $response->setContent($content);
+      $event->setResponse($response);
+    }
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestMaintenanceModeCheck', 40);
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
new file mode 100644
index 0000000..dc5059b
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/PathSubscriber.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\EventSubscriber\AccessSubscriber
+ */
+
+/**
+ * Access subscriber for controller requests.
+ */
+class PathSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Resolve the system path.
+   *
+   * @todo The path system should be objectified to remove the function calls
+   * in this method.
+   *
+   * @todo We're writing back to $_GET['q'] for temporary BC. All instances of
+   * $_GET['q'] should be removed and then this code eliminated.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelRequestPathResolve(GetResponseEvent $event) {
+
+    $request = $event->getRequest();
+
+    $path = ltrim($request->getPathInfo(), '/');
+
+    if (empty($path)) {
+      // @todo Temporary hack. Fix when configuration is injectable.
+      $path = variable_get('site_frontpage', 'user');
+    }
+    $system_path = drupal_get_normal_path($path);
+
+    $request->attributes->set('system_path', $system_path);
+
+    // @todo Remove this line.
+    // Drupal uses $_GET['q'] directly in over 100 places at present,
+    // including writing back to it at times. Those are all critical bugs,
+    // even by Drupal 7 standards, but as many of the places that it does so
+    // are slated to be rewritten anyway we will save time and include this
+    // temporary hack. Removal of this line is a critical, Drupal-release
+    // blocking bug.
+    $_GET['q'] = $system_path;
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestPathResolve', 100);
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/RequestCloseSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/RequestCloseSubscriber.php
new file mode 100644
index 0000000..91f768b
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/RequestCloseSubscriber.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\PostResponseEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\EventSubscriber\RequestCloseSubscriber;
+ */
+
+/**
+ * Subscriber for all responses.
+ */
+class RequestCloseSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Performs end of request tasks.
+   *
+   * @todo The body of this function has just been copied almost verbatim from
+   * drupal_page_footer(), with the exception of now passing the response
+   * content to drupal_page_set_cache(). There's probably a lot in here that
+   * needs to get removed/changed.
+   *
+   * @param PostResponseEvent $event
+   *   The Event to process.
+   */
+  public function onTerminate(PostResponseEvent $event) {
+
+    global $user;
+    module_invoke_all('exit');
+
+    // Commit the user session, if needed.
+    drupal_session_commit();
+    $response = $event->getResponse();
+    $config = config('system.performance');
+
+    if ($config->get('cache') && ($cache = drupal_page_set_cache($response->getContent()))) {
+      drupal_serve_page_from_cache($cache);
+    }
+    else {
+      ob_flush();
+    }
+
+    _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE);
+    drupal_cache_system_paths();
+    module_implements_write_cache();
+    system_run_automated_cron();
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::TERMINATE][] = array('onTerminate');
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php
new file mode 100644
index 0000000..647b641
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ViewSubscriber.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+use Drupal\Core\ContentNegotiation;
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\EventSubscriber\ViewSubscriber;
+ */
+
+/**
+ * Main subscriber for VIEW HTTP responses.
+ */
+class ViewSubscriber implements EventSubscriberInterface {
+
+  protected $negotiation;
+
+  public function __construct(ContentNegotiation $negotiation) {
+    $this->negotiation = $negotiation;
+  }
+
+  /**
+   * Processes a successful controller into an HTTP 200 response.
+   *
+   * Some controllers may not return a response object but simply the body of
+   * one.  The VIEW event is called in that case, to allow us to mutate that
+   * body into a Response object.  In particular we assume that the return
+   * from an JSON-type response is a JSON string, so just wrap it into a
+   * Response object.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onView(GetResponseEvent $event) {
+
+    $request = $event->getRequest();
+
+    $method = 'on' . $this->negotiation->getContentType($request);
+
+    if (method_exists($this, $method)) {
+      $event->setResponse($this->$method($event));
+    }
+    else {
+      $event->setResponse(new Response('Unsupported Media Type', 415));
+    }
+  }
+
+  public function onJson(GetResponseEvent $event) {
+    $page_callback_result = $event->getControllerResult();
+
+    //print_r($page_callback_result);
+
+    $response = new JsonResponse();
+    $response->setContent($page_callback_result);
+
+    return $response;
+  }
+
+  public function onAjax(GetResponseEvent $event) {
+    $page_callback_result = $event->getControllerResult();
+
+    // Construct the response content from the page callback result.
+    $commands = ajax_prepare_response($page_callback_result);
+    $json = ajax_render($commands);
+
+    // Build the actual response object.
+    $response = new JsonResponse();
+    $response->setContent($json);
+
+    return $response;
+  }
+
+  public function onIframeUpload(GetResponseEvent $event) {
+    $page_callback_result = $event->getControllerResult();
+
+    // Construct the response content from the page callback result.
+    $commands = ajax_prepare_response($page_callback_result);
+    $json = ajax_render($commands);
+
+    // Browser IFRAMEs expect HTML. Browser extensions, such as Linkification
+    // and Skype's Browser Highlighter, convert URLs, phone numbers, etc. into
+    // links. This corrupts the JSON response. Protect the integrity of the
+    // JSON data by making it the value of a textarea.
+    // @see http://malsup.com/jquery/form/#file-upload
+    // @see http://drupal.org/node/1009382
+    $html = '<textarea>' . $json . '</textarea>';
+
+    return new Response($html);
+  }
+
+  /**
+   * Processes a successful controller into an HTTP 200 response.
+   *
+   * Some controllers may not return a response object but simply the body of
+   * one.  The VIEW event is called in that case, to allow us to mutate that
+   * body into a Response object.  In particular we assume that the return
+   * from an HTML-type response is a render array from a legacy page callback
+   * and render it.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onHtml(GetResponseEvent $event) {
+    $page_callback_result = $event->getControllerResult();
+    return new Response(drupal_render_page($page_callback_result));
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::VIEW][] = array('onView');
+
+    return $events;
+  }
+}
diff --git a/core/lib/Drupal/Core/ExceptionController.php b/core/lib/Drupal/Core/ExceptionController.php
new file mode 100644
index 0000000..3e92e83
--- /dev/null
+++ b/core/lib/Drupal/Core/ExceptionController.php
@@ -0,0 +1,211 @@
+<?php
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\ExceptionController.
+ */
+
+namespace Drupal\Core;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpKernel\Controller\ControllerResolver;
+use Symfony\Component\HttpKernel\Exception\FlattenException;
+
+use Exception;
+
+/**
+ * This controller handles HTTP errors generated by the routing system.
+ */
+class ExceptionController {
+
+  /**
+   * The kernel that spawned this controller.
+   *
+   * We will use this to fire subrequests as needed.
+   *
+   * @var HttpKernelInterface
+   */
+  protected $kernel;
+
+  /**
+   * The
+   *
+   * @var ContentNegotiation
+   */
+  protected $negotiation;
+
+  /**
+   * Constructor
+   *
+   * @param HttpKernelInterface $kernel
+   *   The kernel that spawned this controller, so that it can be reused
+   *   for subrequests.
+   * @param ContentNegotiation $negotiation
+   *   The content negotiation library to use to determine the correct response
+   *   format.
+   */
+  public function __construct(HttpKernelInterface $kernel, ContentNegotiation $negotiation) {
+    $this->kernel = $kernel;
+    $this->negotiation = $negotiation;
+  }
+
+  /**
+   * Handles an exception on a request.
+   *
+   * @param FlattenException $exception
+   *   The flattened exception.
+   * @param Request $request
+   *   The request that generated the exception.
+   * @return \Symfony\Component\HttpFoundation\Response
+   *   A response object to be sent to the server.
+   */
+  public function execute(FlattenException $exception, Request $request) {
+
+    $method = 'on' . $exception->getStatusCode() . $this->negotiation->getContentType($request);
+
+    if (method_exists($this, $method)) {
+      return $this->$method($exception, $request);
+    }
+
+    return new Response('A fatal error occurred: ' . $exception->getMessage(), $exception->getStatusCode());
+
+  }
+
+  /**
+   * Processes a MethodNotAllowed exception into an HTTP 405 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on405Html(FlattenException $exception, Request $request) {
+    $event->setResponse(new Response('Method Not Allowed', 405));
+  }
+
+  /**
+   * Processes an AccessDenied exception into an HTTP 403 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on403Html(FlattenException $exception, Request $request) {
+    $system_path = $request->attributes->get('system_path');
+    watchdog('access denied', $system_path, NULL, WATCHDOG_WARNING);
+
+    $path = drupal_get_normal_path(variable_get('site_403', ''));
+    if ($path && $path != $system_path) {
+      // Keep old path for reference, and to allow forms to redirect to it.
+      if (!isset($_GET['destination'])) {
+        $_GET['destination'] = $system_path;
+      }
+
+      $subrequest = Request::create('/' . $path, 'get', array('destination' => $system_path), $request->cookies->all(), array(), $request->server->all());
+
+      $response = $this->kernel->handle($subrequest, DrupalKernel::SUB_REQUEST);
+      $response->setStatusCode(403, 'Access denied');
+    }
+    else {
+      $response = new Response('Access Denied', 403);
+
+      // @todo Replace this block with something cleaner.
+      $return = t('You are not authorized to access this page.');
+      drupal_set_title(t('Access denied'));
+      drupal_set_page_content($return);
+      $page = element_info('page');
+      $content = drupal_render_page($page);
+
+      $response->setContent($content);
+    }
+
+    return $response;
+  }
+
+  /**
+   * Processes a NotFound exception into an HTTP 403 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on404Html(FlattenException $exception, Request $request) {
+    watchdog('page not found', check_plain($_GET['q']), NULL, WATCHDOG_WARNING);
+
+    // Check for and return a fast 404 page if configured.
+    // @todo Inline this rather than using a function.
+    drupal_fast_404();
+
+    $system_path = $request->attributes->get('system_path');
+
+    // Keep old path for reference, and to allow forms to redirect to it.
+    if (!isset($_GET['destination'])) {
+      $_GET['destination'] = $system_path;
+    }
+
+    $path = drupal_get_normal_path(variable_get('site_404', ''));
+    if ($path && $path != $system_path) {
+      // @todo: Um, how do I specify an override URL again? Totally not clear.
+      // Do that and sub-call the kernel rather than using meah().
+      // @todo: The create() method expects a slash-prefixed path, but we
+      // store a normal system path in the site_404 variable.
+      $subrequest = Request::create('/' . $path, 'get', array(), $request->cookies->all(), array(), $request->server->all());
+
+      $response = $this->kernel->handle($subrequest, HttpKernelInterface::SUB_REQUEST);
+      $response->setStatusCode(404, 'Not Found');
+    }
+    else {
+      $response = new Response('Not Found', 404);
+
+      // @todo Replace this block with something cleaner.
+      $return = t('The requested page "@path" could not be found.', array('@path' => $request->getPathInfo()));
+      drupal_set_title(t('Page not found'));
+      drupal_set_page_content($return);
+      $page = element_info('page');
+      $content = drupal_render_page($page);
+
+      $response->setContent($content);
+    }
+
+    return $response;
+  }
+
+  /**
+   * Processes an AccessDenied exception into an HTTP 403 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on403Json(FlattenException $exception, Request $request) {
+    $response = new JsonResponse();
+    $response->setStatusCode(403, 'Access Denied');
+    return $response;
+  }
+
+  /**
+   * Processes a NotFound exception into an HTTP 404 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on404Json(FlattenException $exception, Request $request) {
+    $response = new JsonResponse();
+    $response->setStatusCode(404, 'Not Found');
+    return $response;
+  }
+
+  /**
+   * Processes a MethodNotAllowed exception into an HTTP 405 response.
+   *
+   * @param GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function on405Json(FlattenException $exception, Request $request) {
+    $response = new JsonResponse();
+    $response->setStatusCode(405, 'Method Not Allowed');
+    return $response;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/StreamWrapper/LocalStream.php b/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
index 0cd76e0..1b4abc9 100644
--- a/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
+++ b/core/lib/Drupal/Core/StreamWrapper/LocalStream.php
@@ -44,7 +44,7 @@ abstract class LocalStream implements StreamWrapperInterface {
 
   /**
    * Gets the path that the wrapper is responsible for.
-   * @TODO: Review this method name in D8 per http://drupal.org/node/701358
+   * @todo: Review this method name in D8 per http://drupal.org/node/701358
    *
    * @return string
    *   String specifying the path.
diff --git a/core/lib/Drupal/Core/Updater/Updater.php b/core/lib/Drupal/Core/Updater/Updater.php
index 2dca5ba..ad2213a 100644
--- a/core/lib/Drupal/Core/Updater/Updater.php
+++ b/core/lib/Drupal/Core/Updater/Updater.php
@@ -213,7 +213,7 @@ class Updater {
       $this->makeWorldReadable($filetransfer, $args['install_dir'] . '/' . $this->name);
 
       // Run the updates.
-      // @TODO: decide if we want to implement this.
+      // @todo: decide if we want to implement this.
       $this->postUpdate();
 
       // For now, just return a list of links of things to do.
@@ -252,7 +252,7 @@ class Updater {
       $this->makeWorldReadable($filetransfer, $args['install_dir'] . '/' . $this->name);
 
       // Potentially enable something?
-      // @TODO: decide if we want to implement this.
+      // @todo: decide if we want to implement this.
       $this->postInstall();
       // For now, just return a list of links of things to do.
       return $this->postInstallTasks();
diff --git a/core/lib/Drupal/Core/UrlMatcher.php b/core/lib/Drupal/Core/UrlMatcher.php
new file mode 100644
index 0000000..585fc45
--- /dev/null
+++ b/core/lib/Drupal/Core/UrlMatcher.php
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ *
+ * Definition of Drupal\Core\UrlMatcher.
+ */
+
+namespace Drupal\Core;
+
+use Symfony\Component\Routing\Exception\MethodNotAllowedException;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\Matcher\UrlMatcher as SymfonyUrlMatcher;
+use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * UrlMatcher matches URL based on a set of routes.
+ */
+class UrlMatcher extends SymfonyUrlMatcher {
+
+  /**
+   * The request context for this matcher.
+   *
+   * @var RequestContext
+   */
+  protected $context;
+
+  /**
+   * Constructor.
+   *
+   * @param RequestContext  $context
+   *   The request context object.
+   */
+  public function __construct(RequestContext $context) {
+    $this->context = $context;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * @api
+   */
+  public function match($pathinfo) {
+
+    $this->allow = array();
+
+    // Symfony uses a prefixing / but we don't yet.
+    $dpathinfo = ltrim($pathinfo, '/');
+
+    // Do our fancy frontpage logic.
+    if (empty($dpathinfo)) {
+      $dpathinfo = variable_get('site_frontpage', 'user');
+      $pathinfo = '/' . $dpathinfo;
+    }
+
+    if ($router_item = $this->matchDrupalItem($dpathinfo)) {
+      $ret = $this->convertDrupalItem($router_item);
+      // Stash the router item in the attributes while we're transitioning.
+      $ret['drupal_menu_item'] = $router_item;
+
+      // Most legacy controllers (aka page callbacks) are in a separate file,
+      // so we have to include that.
+      if ($router_item['include_file']) {
+        require_once DRUPAL_ROOT . '/' . $router_item['include_file'];
+      }
+
+      return $ret;
+    }
+
+    // This matcher doesn't differentiate by method, so don't bother with those
+    // exceptions.
+    throw new ResourceNotFoundException();
+  }
+
+  /**
+   * Get a drupal menu item.
+   *
+   * @todo Make this return multiple possible candidates for the resolver to
+   * consider.
+   *
+   * @param string $path
+   *   The path being looked up by
+   */
+  protected function matchDrupalItem($path) {
+    // For now we can just proxy our procedural method. At some point this will
+    // become more complicated because we'll need to get back candidates for a
+    // path and them resolve them based on things like method and scheme which
+    // we currently can't do.
+    return menu_get_item($path);
+  }
+
+  protected function convertDrupalItem($router_item) {
+    $route = array(
+      '_controller' => $router_item['page_callback']
+    );
+
+    // Place argument defaults on the route.
+    // @todo: For some reason drush test runs have a serialized page_arguments
+    // but HTTP requests are unserialized. Hack to get around this for now.
+    // This might be because page arguments aren't unserialized in
+    // menu_get_item() when the access is denied.
+    !is_array($router_item['page_arguments']) ? $page_arguments = unserialize($router_item['page_arguments']) : $page_arguments = $router_item['page_arguments'];
+    foreach ($page_arguments as $k => $v) {
+      $route[$k] = $v;
+    }
+    return $route;
+    return new Route($router_item['href'], $route);
+  }
+}
diff --git a/core/modules/aggregator/aggregator.admin.inc b/core/modules/aggregator/aggregator.admin.inc
index 09da1cf..ac868b4 100644
--- a/core/modules/aggregator/aggregator.admin.inc
+++ b/core/modules/aggregator/aggregator.admin.inc
@@ -401,11 +401,9 @@ function _aggregator_parse_opml($opml) {
  *   An object describing the feed to be refreshed.
  *
  * @see aggregator_menu()
+ * @see aggregator_admin_refresh_feed_access()
  */
 function aggregator_admin_refresh_feed($feed) {
-  if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'aggregator/update/' . $feed->fid)) {
-    return MENU_ACCESS_DENIED;
-  }
   aggregator_refresh($feed);
   drupal_goto('admin/config/services/aggregator');
 }
diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module
index 9a266ba..1997649 100644
--- a/core/modules/aggregator/aggregator.module
+++ b/core/modules/aggregator/aggregator.module
@@ -138,7 +138,8 @@ function aggregator_menu() {
     'title' => 'Update items',
     'page callback' => 'aggregator_admin_refresh_feed',
     'page arguments' => array(5),
-    'access arguments' => array('administer news feeds'),
+    'access callback' => 'aggregator_admin_refresh_feed_access',
+    'access arguments' => array(5),
     'file' => 'aggregator.admin.inc',
   );
   $items['admin/config/services/aggregator/list'] = array(
@@ -396,7 +397,6 @@ function aggregator_block_view($delta = '') {
   if (user_access('access news feeds')) {
     $block = array();
     list($type, $id) = explode('-', $delta);
-    $result = FALSE;
     switch ($type) {
       case 'feed':
         if ($feed = db_query('SELECT fid, title, block FROM {aggregator_feed} WHERE block <> 0 AND fid = :fid', array(':fid' => $id))->fetchObject()) {
@@ -414,12 +414,9 @@ function aggregator_block_view($delta = '') {
         }
         break;
     }
-
     $items = array();
-    if (!empty($result)) {
-      foreach ($result as $item) {
-        $items[] = theme('aggregator_block_item', array('item' => $item));
-      }
+    foreach ($result as $item) {
+      $items[] = theme('aggregator_block_item', array('item' => $item));
     }
 
     // Only display the block if there are items to show.
@@ -793,3 +790,23 @@ function aggregator_preprocess_block(&$variables) {
     $variables['attributes_array']['role'] = 'complementary';
   }
 }
+
+/**
+ * Access callback: Determines if feed refresh is accessible.
+ *
+ * @param $feed
+ *   An object describing the feed to be refreshed.
+ *
+ * @see aggregator_admin_refresh_feed()
+ * @see aggregator_menu()
+ */
+function aggregator_admin_refresh_feed_access($feed) {
+  if (!user_access('administer news feeds')) {
+    return FALSE;
+  }
+  $token = request()->query->get('token');
+  if (!isset($token) || !drupal_valid_token($token, 'aggregator/update/' . $feed->fid)) {
+    return FALSE;
+  }
+  return TRUE;
+}
diff --git a/core/modules/aggregator/aggregator.test b/core/modules/aggregator/aggregator.test
index 61ad16b..2149bed 100644
--- a/core/modules/aggregator/aggregator.test
+++ b/core/modules/aggregator/aggregator.test
@@ -887,16 +887,6 @@ class AggregatorRenderingTestCase extends AggregatorTestCase {
     $this->drupalGet($href);
     $correct_titles = $this->xpath('//h1[normalize-space(text())=:title]', array(':title' => $feed->title));
     $this->assertFalse(empty($correct_titles), t('Aggregator feed page is available and has the correct title.'));
-
-    // Set the number of news items to 0 to test that the block does not show
-    // up.
-    $feed->block = 0;
-    aggregator_save_feed((array) $feed);
-    // It is nescessary to flush the cache after saving the number of items.
-    drupal_flush_all_caches();
-    // Check that the block is no longer displayed.
-    $this->drupalGet('node');
-    $this->assertNoText(t($block['title']), 'Feed block is not displayed on the page when number of items is set to 0.');
   }
 
   /**
diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc
index d84b785..ed12872 100644
--- a/core/modules/comment/comment.admin.inc
+++ b/core/modules/comment/comment.admin.inc
@@ -258,13 +258,13 @@ function comment_confirm_delete_page($cid) {
   if ($comment = comment_load($cid)) {
     return drupal_get_form('comment_confirm_delete', $comment);
   }
-  return MENU_NOT_FOUND;
+  drupal_not_found();
 }
 
 /**
  * Form constructor for the confirmation form for comment deletion.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment that is about to be deleted.
  *
  * @ingroup forms
@@ -272,7 +272,7 @@ function comment_confirm_delete_page($cid) {
  * @see comment_confirm_delete_submit()
  * @see confirm_form()
  */
-function comment_confirm_delete($form, &$form_state, Comment $comment) {
+function comment_confirm_delete($form, &$form_state, $comment) {
   $form['#comment'] = $comment;
   // Always provide entity id in the same form key as in the entity edit form.
   $form['cid'] = array('#type' => 'value', '#value' => $comment->cid);
diff --git a/core/modules/comment/comment.api.php b/core/modules/comment/comment.api.php
index eb9f34d..f270aad 100644
--- a/core/modules/comment/comment.api.php
+++ b/core/modules/comment/comment.api.php
@@ -16,10 +16,10 @@
  * This hook is invoked from comment_save() before the comment is saved to the
  * database.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  */
-function hook_comment_presave(Comment $comment) {
+function hook_comment_presave($comment) {
   // Remove leading & trailing spaces from the comment subject.
   $comment->subject = trim($comment->subject);
 }
@@ -27,10 +27,10 @@ function hook_comment_presave(Comment $comment) {
 /**
  * Respond to creation of a new comment.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  */
-function hook_comment_insert(Comment $comment) {
+function hook_comment_insert($comment) {
   // Reindex the node when comments are added.
   search_touch_node($comment->nid);
 }
@@ -38,10 +38,10 @@ function hook_comment_insert(Comment $comment) {
 /**
  * Respond to updates to a comment.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  */
-function hook_comment_update(Comment $comment) {
+function hook_comment_update($comment) {
   // Reindex the node when comments are updated.
   search_touch_node($comment->nid);
 }
@@ -49,10 +49,10 @@ function hook_comment_update(Comment $comment) {
 /**
  * Act on comments being loaded from the database.
  *
- * @param array $comments
+ * @param $comments
  *  An array of comment objects indexed by cid.
  */
-function hook_comment_load(Comment $comments) {
+function hook_comment_load($comments) {
   $result = db_query('SELECT cid, foo FROM {mytable} WHERE cid IN (:cids)', array(':cids' => array_keys($comments)));
   foreach ($result as $record) {
     $comments[$record->cid]->foo = $record->foo;
@@ -62,7 +62,7 @@ function hook_comment_load(Comment $comments) {
 /**
  * Act on a comment that is being assembled before rendering.
  *
- * @param Comment $comment
+ * @param $comment
  *   Passes in the comment the action is being performed on.
  * @param $view_mode
  *   View mode, e.g. 'full', 'teaser'...
@@ -71,7 +71,7 @@ function hook_comment_load(Comment $comments) {
  *
  * @see hook_entity_view()
  */
-function hook_comment_view(Comment $comment, $view_mode, $langcode) {
+function hook_comment_view($comment, $view_mode, $langcode) {
   // how old is the comment
   $comment->time_ago = time() - $comment->changed;
 }
@@ -108,20 +108,20 @@ function hook_comment_view_alter(&$build) {
 /**
  * Respond to a comment being published by a moderator.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment the action is being performed on.
  */
-function hook_comment_publish(Comment $comment) {
+function hook_comment_publish($comment) {
   drupal_set_message(t('Comment: @subject has been published', array('@subject' => $comment->subject)));
 }
 
 /**
  * Respond to a comment being unpublished by a moderator.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment the action is being performed on.
  */
-function hook_comment_unpublish(Comment $comment) {
+function hook_comment_unpublish($comment) {
   drupal_set_message(t('Comment: @subject has been unpublished', array('@subject' => $comment->subject)));
 }
 
@@ -132,14 +132,14 @@ function hook_comment_unpublish(Comment $comment) {
  * field_attach_delete() is called and before the comment is actually removed
  * from the database.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object for the comment that is about to be deleted.
  *
  * @see hook_comment_delete()
  * @see comment_delete_multiple()
  * @see entity_delete_multiple()
  */
-function hook_comment_predelete(Comment $comment) {
+function hook_comment_predelete($comment) {
   // Delete a record associated with the comment in a custom table.
   db_delete('example_comment_table')
     ->condition('cid', $comment->cid)
@@ -153,14 +153,14 @@ function hook_comment_predelete(Comment $comment) {
  * field_attach_delete() has called and after the comment has been removed from
  * the database.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object for the comment that has been deleted.
  *
  * @see hook_comment_predelete()
  * @see comment_delete_multiple()
  * @see entity_delete_multiple()
  */
-function hook_comment_delete(Comment $comment) {
+function hook_comment_delete($comment) {
   drupal_set_message(t('Comment: @subject has been deleted', array('@subject' => $comment->subject)));
 }
 
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index a714419..2c28b35 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -164,7 +164,7 @@ function comment_node_type_load($name) {
 /**
  * Entity uri callback.
  */
-function comment_uri(Comment $comment) {
+function comment_uri($comment) {
   return array(
     'path' => 'comment/' . $comment->cid,
     'options' => array('fragment' => 'comment-' . $comment->cid),
@@ -275,7 +275,8 @@ function comment_menu() {
     'title' => 'Approve',
     'page callback' => 'comment_approve',
     'page arguments' => array(1),
-    'access arguments' => array('administer comments'),
+    'access callback' => 'comment_approve_access',
+    'access arguments' => array(1),
     'file' => 'comment.pages.inc',
     'weight' => 1,
   );
@@ -934,7 +935,7 @@ function comment_prepare_thread(&$comments) {
 /**
  * Generates an array for rendering a comment.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  * @param $node
  *   The node the comment is attached to.
@@ -947,7 +948,7 @@ function comment_prepare_thread(&$comments) {
  * @return
  *   An array as expected by drupal_render().
  */
-function comment_view(Comment $comment, $node, $view_mode = 'full', $langcode = NULL) {
+function comment_view($comment, $node, $view_mode = 'full', $langcode = NULL) {
   if (!isset($langcode)) {
     $langcode = $GLOBALS['language_content']->langcode;
   }
@@ -1004,7 +1005,7 @@ function comment_view(Comment $comment, $node, $view_mode = 'full', $langcode =
  * The content built for the comment (field values, comments, file attachments
  * or other comment components) will vary depending on the $view_mode parameter.
  *
- * @param Comment $comment
+ * @param $comment
  *   A comment object.
  * @param $node
  *   The node the comment is attached to.
@@ -1014,7 +1015,7 @@ function comment_view(Comment $comment, $node, $view_mode = 'full', $langcode =
  *   (optional) A language code to use for rendering. Defaults to the global
  *   content language of the current request.
  */
-function comment_build_content(Comment $comment, $node, $view_mode = 'full', $langcode = NULL) {
+function comment_build_content($comment, $node, $view_mode = 'full', $langcode = NULL) {
   if (!isset($langcode)) {
     $langcode = $GLOBALS['language_content']->langcode;
   }
@@ -1048,7 +1049,7 @@ function comment_build_content(Comment $comment, $node, $view_mode = 'full', $la
 /**
  * Adds reply, edit, delete, etc. links, depending on user permissions.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  * @param $node
  *   The node the comment is attached to.
@@ -1056,7 +1057,7 @@ function comment_build_content(Comment $comment, $node, $view_mode = 'full', $la
  * @return
  *   A structured array of links.
  */
-function comment_links(Comment $comment, $node) {
+function comment_links($comment, $node) {
   $links = array();
   if ($node->comment == COMMENT_NODE_OPEN) {
     if (user_access('administer comments') && user_access('post comments')) {
@@ -1450,13 +1451,13 @@ function comment_user_predelete($account) {
  * @param $op
  *   The operation that is to be performed on the comment. Only 'edit' is
  *   recognized now.
- * @param Comment $comment
+ * @param $comment
  *   The comment object.
  *
  * @return
  *   TRUE if the current user has acces to the comment, FALSE otherwise.
  */
-function comment_access($op, Comment $comment) {
+function comment_access($op, $comment) {
   global $user;
 
   if ($op == 'edit') {
@@ -1467,10 +1468,10 @@ function comment_access($op, Comment $comment) {
 /**
  * Accepts a submission of new or changed comment content.
  *
- * @param Comment $comment
+ * @param $comment
  *   A comment object.
  */
-function comment_save(Comment $comment) {
+function comment_save($comment) {
   $comment->save();
 }
 
@@ -1643,12 +1644,12 @@ function comment_get_display_page($cid, $node_type) {
 /**
  * Page callback: Displays the comment editing form.
  *
- * @param Comment $comment
+ * @param $comment
  *   The comment object representing the comment to be edited.
  *
  * @see comment_menu()
  */
-function comment_edit_page(Comment $comment) {
+function comment_edit_page($comment) {
   drupal_set_title(t('Edit comment %comment', array('%comment' => $comment->subject)), PASS_THROUGH);
   $node = node_load($comment->nid);
   return drupal_get_form("comment_node_{$node->type}_form", $comment);
@@ -1673,7 +1674,7 @@ function comment_forms() {
  * @see comment_form_build_preview()
  * @ingroup forms
  */
-function comment_form($form, &$form_state, Comment $comment) {
+function comment_form($form, &$form_state, $comment) {
   global $user, $language_content;
 
   // During initial form build, add the comment entity to the form state for
@@ -1887,11 +1888,9 @@ function comment_form_build_preview($form, &$form_state) {
 /**
  * Generates a comment preview.
  *
- * @param Comment $comment
- *
  * @see comment_form_build_preview()
  */
-function comment_preview(Comment $comment) {
+function comment_preview($comment) {
   global $user;
 
   drupal_set_title(t('Preview comment'), PASS_THROUGH);
@@ -1988,11 +1987,8 @@ function comment_form_validate($form, &$form_state) {
 
 /**
  * Prepare a comment for submission.
- *
- * @param Comment $comment
- *
  */
-function comment_submit(Comment $comment) {
+function comment_submit($comment) {
   if (empty($comment->date)) {
     $comment->date = 'now';
   }
@@ -2332,15 +2328,15 @@ function comment_action_info() {
 /**
  * Publishes a comment.
  *
- * @param Comment $comment
- *   (optional) A comment object to publish.
+ * @param $comment
+ *   An optional comment object.
  * @param array $context
  *   Array with components:
  *   - 'cid': Comment ID. Required if $comment is not given.
  *
  * @ingroup actions
  */
-function comment_publish_action(Comment $comment = NULL, $context = array()) {
+function comment_publish_action($comment, $context = array()) {
   if (isset($comment->subject)) {
     $subject = $comment->subject;
     $comment->status = COMMENT_PUBLISHED;
@@ -2359,15 +2355,15 @@ function comment_publish_action(Comment $comment = NULL, $context = array()) {
 /**
  * Unpublishes a comment.
  *
- * @param Comment|null $comment
- *   (optional) A comment object to unpublish.
+ * @param $comment
+ *   An optional comment object.
  * @param array $context
  *   Array with components:
  *   - 'cid': Comment ID. Required if $comment is not given.
  *
  * @ingroup actions
  */
-function comment_unpublish_action(Comment $comment = NULL, $context = array()) {
+function comment_unpublish_action($comment, $context = array()) {
   if (isset($comment->subject)) {
     $subject = $comment->subject;
     $comment->status = COMMENT_NOT_PUBLISHED;
@@ -2386,7 +2382,7 @@ function comment_unpublish_action(Comment $comment = NULL, $context = array()) {
 /**
  * Unpublishes a comment if it contains certain keywords.
  *
- * @param Comment $comment
+ * @param $comment
  *   Comment object to modify.
  * @param array $context
  *   Array with components:
@@ -2397,7 +2393,7 @@ function comment_unpublish_action(Comment $comment = NULL, $context = array()) {
  * @see comment_unpublish_by_keyword_action_form()
  * @see comment_unpublish_by_keyword_action_submit()
  */
-function comment_unpublish_by_keyword_action(Comment $comment, $context) {
+function comment_unpublish_by_keyword_action($comment, $context) {
   foreach ($context['keywords'] as $keyword) {
     $text = drupal_render($comment);
     if (strpos($text, $keyword) !== FALSE) {
@@ -2438,11 +2434,9 @@ function comment_unpublish_by_keyword_action_submit($form, $form_state) {
 /**
  * Saves a comment.
  *
- * @param Comment $comment
- *
  * @ingroup actions
  */
-function comment_save_action(Comment $comment) {
+function comment_save_action($comment) {
   comment_save($comment);
   cache_clear_all();
   watchdog('action', 'Saved comment %title', array('%title' => $comment->subject));
@@ -2522,3 +2516,23 @@ function comment_file_download_access($field, $entity_type, $entity) {
     return FALSE;
   }
 }
+
+/**
+ * Access callback: Determines if comment approval is accessible.
+ *
+ * @param $cid
+ *   A comment identifier.
+ *
+ * @see comment_approve()
+ * @see comment_menu()
+ */
+function comment_approve_access($cid) {
+  if (!user_access('administer comments')) {
+    return FALSE;
+  }
+  $token = request()->query->get('token');
+  if (!isset($token) || !drupal_valid_token($token, "comment/$cid/approve")) {
+    return FALSE;
+  }
+  return TRUE;
+}
diff --git a/core/modules/comment/comment.pages.inc b/core/modules/comment/comment.pages.inc
index 21fe465..c9cc96a 100644
--- a/core/modules/comment/comment.pages.inc
+++ b/core/modules/comment/comment.pages.inc
@@ -47,9 +47,12 @@ function comment_reply($node, $pid = NULL) {
     // $pid indicates that this is a reply to a comment.
     if ($pid) {
       if (user_access('access comments')) {
-        // Load the parent comment.
-        $comment = comment_load($pid);
-        if ($comment->status = COMMENT_PUBLISHED) {
+        // Load the comment whose cid = $pid
+        $comment = db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.signature_format, u.picture, u.data FROM {comment} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = :cid AND c.status = :status', array(
+          ':cid' => $pid,
+          ':status' => COMMENT_PUBLISHED,
+        ))->fetchObject();
+        if ($comment) {
           // If that comment exists, make sure that the current comment and the
           // parent comment both belong to the same parent node.
           if ($comment->nid != $node->nid) {
@@ -103,11 +106,9 @@ function comment_reply($node, $pid = NULL) {
  *   A comment identifier.
  *
  * @see comment_menu()
+ * @see comment_approve_access()
  */
 function comment_approve($cid) {
-  if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], "comment/$cid/approve")) {
-    return MENU_ACCESS_DENIED;
-  }
   if ($comment = comment_load($cid)) {
     $comment->status = COMMENT_PUBLISHED;
     comment_save($comment);
@@ -115,5 +116,5 @@ function comment_approve($cid) {
     drupal_set_message(t('Comment approved.'));
     drupal_goto('node/' . $comment->nid);
   }
-  return MENU_NOT_FOUND;
+  drupal_not_found();
 }
diff --git a/core/modules/comment/comment.test b/core/modules/comment/comment.test
index 259e420..9257513 100644
--- a/core/modules/comment/comment.test
+++ b/core/modules/comment/comment.test
@@ -96,7 +96,7 @@ class CommentHelperCase extends DrupalWebTestCase {
   /**
    * Checks current page for specified comment.
    *
-   * @param Comment $comment
+   * @param object $comment
    *   The comment object.
    * @param boolean $reply
    *   Boolean indicating whether the comment is a reply to another comment.
@@ -104,8 +104,8 @@ class CommentHelperCase extends DrupalWebTestCase {
    * @return boolean
    *   Boolean indicating whether the comment was found.
    */
-  function commentExists(Comment $comment = NULL, $reply = FALSE) {
-    if ($comment) {
+  function commentExists($comment, $reply = FALSE) {
+    if ($comment && is_object($comment)) {
       $regex = '/' . ($reply ? '<div class="indented">(.*?)' : '');
       $regex .= '<a id="comment-' . $comment->id . '"(.*?)'; // Comment anchor.
       $regex .= '<div(.*?)'; // Begin in comment div.
@@ -123,10 +123,10 @@ class CommentHelperCase extends DrupalWebTestCase {
   /**
    * Deletes a comment.
    *
-   * @param Comment $comment
+   * @param object $comment
    *   Comment to delete.
    */
-  function deleteComment(Comment $comment) {
+  function deleteComment($comment) {
     $this->drupalPost('comment/' . $comment->id . '/delete', array(), t('Delete'));
     $this->assertText(t('The comment and all its replies have been deleted.'), t('Comment deleted.'));
   }
diff --git a/core/modules/entity/entity.class.inc b/core/modules/entity/entity.class.inc
index 9136c58..2311af5 100644
--- a/core/modules/entity/entity.class.inc
+++ b/core/modules/entity/entity.class.inc
@@ -93,60 +93,6 @@ interface EntityInterface {
   public function uri();
 
   /**
-   * Returns the default language of a language-specific entity.
-   *
-   * @return
-   *   The language object of the entity's default language, or FALSE if the
-   *   entity is not language-specific.
-   *
-   * @see EntityInterface::translations()
-   */
-  public function language();
-
-  /**
-   * Returns the languages the entity is translated to.
-   *
-   * @return
-   *   An array of language objects, keyed by language codes.
-   *
-   * @see EntityInterface::language()
-   */
-  public function translations();
-
-  /**
-   * Returns the value of an entity property.
-   *
-   * @param $property_name
-   *   The name of the property to return; e.g., 'title'.
-   * @param $langcode
-   *   (optional) If the property is translatable, the language code of the
-   *   language that should be used for getting the property. If set to NULL,
-   *   the entity's default language is being used.
-   *
-   * @return
-   *   The property value, or NULL if it is not defined.
-   *
-   * @see EntityInterface::language()
-   */
-  public function get($property_name, $langcode = NULL);
-
-  /**
-   * Sets the value of an entity property.
-   *
-   * @param $property_name
-   *   The name of the property to set; e.g., 'title'.
-   * @param $value
-   *   The value to set, or NULL to unset the property.
-   * @param $langcode
-   *   (optional) If the property is translatable, the language code of the
-   *   language that should be used for getting the property. If set to
-   *   NULL, the entity's default language is being used.
-   *
-   * @see EntityInterface::language()
-   */
-  public function set($property_name, $value, $langcode = NULL);
-
-  /**
    * Saves an entity permanently.
    *
    * @return
@@ -193,13 +139,6 @@ interface EntityInterface {
 class Entity implements EntityInterface {
 
   /**
-   * The language code of the entity's default language.
-   *
-   * @var string
-   */
-  public $langcode = LANGUAGE_NOT_SPECIFIED;
-
-  /**
    * The entity type.
    *
    * @var string
@@ -308,92 +247,6 @@ class Entity implements EntityInterface {
   }
 
   /**
-   * Implements EntityInterface::language().
-   */
-  public function language() {
-    // @todo: Check for language.module instead, once Field API language
-    // handling depends upon it too.
-    return module_exists('locale') ? language_load($this->langcode) : FALSE;
-  }
-
-  /**
-   * Implements EntityInterface::translations().
-   */
-  public function translations() {
-    $languages = array();
-    $entity_info = $this->entityInfo();
-    if ($entity_info['fieldable'] && ($default_language = $this->language())) {
-      // Go through translatable properties and determine all languages for
-      // which translated values are available.
-      foreach (field_info_instances($this->entityType, $this->bundle()) as $field_name => $instance) {
-        $field = field_info_field($field_name);
-        if (field_is_translatable($this->entityType, $field) && isset($this->$field_name)) {
-          foreach ($this->$field_name as $langcode => $value)  {
-            $languages[$langcode] = TRUE;
-          }
-        }
-      }
-      // Remove the default language from the translations.
-      unset($languages[$default_language->langcode]);
-      $languages = array_intersect_key(language_list(), $languages);
-    }
-    return $languages;
-  }
-
-  /**
-   * Implements EntityInterface::get().
-   */
-  public function get($property_name, $langcode = NULL) {
-    // Handle fields.
-    $entity_info = $this->entityInfo();
-    if ($entity_info['fieldable'] && field_info_instance($this->entityType, $property_name, $this->bundle())) {
-      $field = field_info_field($property_name);
-      $langcode = $this->getFieldLangcode($field, $langcode);
-      return isset($this->{$property_name}[$langcode]) ? $this->{$property_name}[$langcode] : NULL;
-    }
-    else {
-      // Handle properties being not fields.
-      // @todo: Add support for translatable properties being not fields.
-      return isset($this->{$property_name}) ? $this->{$property_name} : NULL;
-    }
-  }
-
-  /**
-   * Implements EntityInterface::set().
-   */
-  public function set($property_name, $value, $langcode = NULL) {
-    // Handle fields.
-    $entity_info = $this->entityInfo();
-    if ($entity_info['fieldable'] && field_info_instance($this->entityType, $property_name, $this->bundle())) {
-      $field = field_info_field($property_name);
-      $langcode = $this->getFieldLangcode($field, $langcode);
-      $this->{$property_name}[$langcode] = $value;
-    }
-    else {
-      // Handle properties being not fields.
-      // @todo: Add support for translatable properties being not fields.
-      $this->{$property_name} = $value;
-    }
-  }
-
-  /**
-   * Determines the language code to use for accessing a field value in a certain language.
-   */
-  protected function getFieldLangcode($field, $langcode = NULL) {
-    // Only apply the given langcode if the entity is language-specific.
-    // Otherwise translatable fields are handled as non-translatable fields.
-    if (field_is_translatable($this->entityType, $field) && ($default_language = $this->language())) {
-      // For translatable fields the values in default language are stored using
-      // the language code of the default language.
-      return isset($langcode) ? $langcode : $default_language->langcode;
-    }
-    else {
-      // Non-translatable fields always use LANGUAGE_NOT_SPECIFIED.
-      return LANGUAGE_NOT_SPECIFIED;
-    }
-  }
-
-  /**
    * Implements EntityInterface::save().
    */
   public function save() {
diff --git a/core/modules/entity/tests/entity.test b/core/modules/entity/tests/entity.test
index 57600a3..35b6ab1 100644
--- a/core/modules/entity/tests/entity.test
+++ b/core/modules/entity/tests/entity.test
@@ -65,138 +65,6 @@ class EntityAPITestCase extends DrupalWebTestCase {
     $all = entity_test_load_multiple(FALSE);
     $this->assertTrue(empty($all), 'Deleted all entities.');
   }
-
-  /**
-   * Tests Entity getters/setters.
-   */
-  function testEntityGettersSetters() {
-    $entity = entity_create('entity_test', array('name' => 'test', 'uid' => NULL));
-    $this->assertNull($entity->get('uid'), 'Property is not set.');
-
-    $entity->set('uid', $GLOBALS['user']->uid);
-    $this->assertEqual($entity->uid, $GLOBALS['user']->uid, 'Property has been set.');
-
-    $value = $entity->get('uid');
-    $this->assertEqual($value, $entity->uid, 'Property has been retrieved.');
-
-    // Make sure setting/getting translations boils down to setting/getting the
-    // regular value as the entity and property are not translatable.
-    $entity->set('uid', NULL, 'en');
-    $this->assertNull($entity->uid, 'Language neutral property has been set.');
-
-    $value = $entity->get('uid', 'en');
-    $this->assertNull($value, 'Language neutral property has been retrieved.');
-  }
-}
-
-/**
- * Tests entity translation.
- */
-class EntityTranslationTestCase extends DrupalWebTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Entity Translation',
-      'description' => 'Tests entity translation functionality.',
-      'group' => 'Entity API',
-    );
-  }
-
-  function setUp() {
-    // Enable translations for the test entity type. We cannot use
-    // variable_set() here as variables are cleared by parent::setUp();
-    $GLOBALS['entity_test_translation'] = TRUE;
-    parent::setUp('entity_test', 'language', 'locale');
-
-    // Create a translatable test field.
-    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
-    $field = array(
-      'field_name' => $this->field_name,
-      'type' => 'text',
-      'cardinality' => 4,
-      'translatable' => TRUE,
-    );
-    field_create_field($field);
-    $this->field = field_read_field($this->field_name);
-
-    $instance = array(
-      'field_name' => $this->field_name,
-      'entity_type' => 'entity_test',
-      'bundle' => 'entity_test',
-    );
-    field_create_instance($instance);
-    $this->instance = field_read_instance('entity_test', $this->field_name, 'entity_test');
-
-    // Create test languages.
-    $this->langcodes = array();
-    for ($i = 0; $i < 3; ++$i) {
-      $language = (object) array(
-        'langcode' => 'l' . $i,
-        'name' => $this->randomString(),
-      );
-      $this->langcodes[$i] = $language->langcode;
-      language_save($language);
-    }
-  }
-
-  /**
-   * Tests language related methods of the Entity class.
-   */
-  function testEntityLanguageMethods() {
-    $entity = entity_create('entity_test', array(
-      'name' => 'test',
-      'uid' => $GLOBALS['user']->uid,
-    ));
-    $this->assertFalse($entity->language(), 'No entity language has been specified.');
-    $this->assertFalse($entity->translations(), 'No translations are available');
-
-    // Set the value in default language.
-    $entity->set($this->field_name, array(0 => array('value' => 'default value')));
-    // Get the value.
-    $value = $entity->get($this->field_name);
-    $this->assertEqual($value, array(0 => array('value' => 'default value')), 'Untranslated value retrieved.');
-
-    // Set the value in a certain language. As the entity is not
-    // language-specific it should use the default language and so ignore the
-    // specified language.
-    $entity->set($this->field_name, array(0 => array('value' => 'default value2')), $this->langcodes[1]);
-    $value = $entity->get($this->field_name);
-    $this->assertEqual($value, array(0 => array('value' => 'default value2')), 'Untranslated value updated.');
-    $this->assertFalse($entity->translations(), 'No translations are available');
-
-    // Test getting a field value using the default language for a not
-    // language-specific entity.
-    $value = $entity->get($this->field_name, $this->langcodes[1]);
-    $this->assertEqual($value, array(0 => array('value' => 'default value2')), 'Untranslated value retrieved.');
-
-    // Now, make the entity language-specific by assigning a language and test
-    // translating it.
-    $entity->langcode = $this->langcodes[0];
-    $entity->{$this->field_name} = array();
-    $this->assertEqual($entity->language(), language_load($this->langcodes[0]), 'Entity language retrieved.');
-    $this->assertFalse($entity->translations(), 'No translations are available');
-
-    // Set the value in default language.
-    $entity->set($this->field_name, array(0 => array('value' => 'default value')));
-    // Get the value.
-    $value = $entity->get($this->field_name);
-    $this->assertEqual($value, array(0 => array('value' => 'default value')), 'Untranslated value retrieved.');
-
-    // Set a translation.
-    $entity->set($this->field_name, array(0 => array('value' => 'translation 1')), $this->langcodes[1]);
-    $value = $entity->get($this->field_name, $this->langcodes[1]);
-    $this->assertEqual($value, array(0 => array('value' => 'translation 1')), 'Translated value set.');
-    // Make sure the untranslated value stays.
-    $value = $entity->get($this->field_name);
-    $this->assertEqual($value, array(0 => array('value' => 'default value')), 'Untranslated value stays.');
-
-    $translations[$this->langcodes[1]] = language_load($this->langcodes[1]);
-    $this->assertEqual($entity->translations(), $translations, 'Translations retrieved.');
-
-    // Try to get a not available translation.
-    $value = $entity->get($this->field_name, $this->langcodes[2]);
-    $this->assertNull($value, 'A translation that is not available is NULL.');
-  }
 }
 
 /**
diff --git a/core/modules/entity/tests/modules/entity_cache_test/entity_cache_test.info b/core/modules/entity/tests/entity_cache_test.info
similarity index 100%
rename from core/modules/entity/tests/modules/entity_cache_test/entity_cache_test.info
rename to core/modules/entity/tests/entity_cache_test.info
diff --git a/core/modules/entity/tests/modules/entity_cache_test/entity_cache_test.module b/core/modules/entity/tests/entity_cache_test.module
similarity index 100%
rename from core/modules/entity/tests/modules/entity_cache_test/entity_cache_test.module
rename to core/modules/entity/tests/entity_cache_test.module
diff --git a/core/modules/entity/tests/modules/entity_cache_test_dependency/entity_cache_test_dependency.info b/core/modules/entity/tests/entity_cache_test_dependency.info
similarity index 100%
rename from core/modules/entity/tests/modules/entity_cache_test_dependency/entity_cache_test_dependency.info
rename to core/modules/entity/tests/entity_cache_test_dependency.info
diff --git a/core/modules/entity/tests/modules/entity_cache_test_dependency/entity_cache_test_dependency.module b/core/modules/entity/tests/entity_cache_test_dependency.module
similarity index 100%
rename from core/modules/entity/tests/modules/entity_cache_test_dependency/entity_cache_test_dependency.module
rename to core/modules/entity/tests/entity_cache_test_dependency.module
diff --git a/core/modules/entity/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info b/core/modules/entity/tests/entity_crud_hook_test.info
similarity index 100%
rename from core/modules/entity/tests/modules/entity_crud_hook_test/entity_crud_hook_test.info
rename to core/modules/entity/tests/entity_crud_hook_test.info
diff --git a/core/modules/entity/tests/modules/entity_crud_hook_test/entity_crud_hook_test.module b/core/modules/entity/tests/entity_crud_hook_test.module
similarity index 100%
rename from core/modules/entity/tests/modules/entity_crud_hook_test/entity_crud_hook_test.module
rename to core/modules/entity/tests/entity_crud_hook_test.module
diff --git a/core/modules/entity/tests/modules/entity_test/entity_test.info b/core/modules/entity/tests/entity_test.info
similarity index 100%
rename from core/modules/entity/tests/modules/entity_test/entity_test.info
rename to core/modules/entity/tests/entity_test.info
diff --git a/core/modules/entity/tests/modules/entity_test/entity_test.install b/core/modules/entity/tests/entity_test.install
similarity index 88%
rename from core/modules/entity/tests/modules/entity_test/entity_test.install
rename to core/modules/entity/tests/entity_test.install
index c0c7703..ec2e5bd 100644
--- a/core/modules/entity/tests/modules/entity_test/entity_test.install
+++ b/core/modules/entity/tests/entity_test.install
@@ -57,13 +57,6 @@ function entity_test_schema() {
         'default' => NULL,
         'description' => "The {users}.uid of the associated user.",
       ),
-      'langcode' => array(
-        'description' => 'The {language}.langcode of the test entity.',
-        'type' => 'varchar',
-        'length' => 12,
-        'not null' => TRUE,
-        'default' => '',
-      ),
     ),
     'indexes' => array(
       'uid' => array('uid'),
diff --git a/core/modules/entity/tests/modules/entity_test/entity_test.module b/core/modules/entity/tests/entity_test.module
similarity index 73%
rename from core/modules/entity/tests/modules/entity_test/entity_test.module
rename to core/modules/entity/tests/entity_test.module
index f7dffa0..6034b06 100644
--- a/core/modules/entity/tests/modules/entity_test/entity_test.module
+++ b/core/modules/entity/tests/entity_test.module
@@ -9,21 +9,19 @@
  * Implements hook_entity_info().
  */
 function entity_test_entity_info() {
-  $items['entity_test'] = array(
-    'label' => t('Test entity'),
-    'entity class' => 'Entity',
-    'controller class' => 'EntityDatabaseStorageController',
-    'base table' => 'entity_test',
-    'fieldable' => TRUE,
-    'entity keys' => array(
-      'id' => 'id',
+  $return = array(
+    'entity_test' => array(
+      'label' => t('Test entity'),
+      'entity class' => 'Entity',
+      'controller class' => 'EntityDatabaseStorageController',
+      'base table' => 'entity_test',
+      'fieldable' => TRUE,
+      'entity keys' => array(
+        'id' => 'id',
+      ),
     ),
   );
-  // Optionally specify a translation handler for testing translations.
-  if (!empty($GLOBALS['entity_test_translation'])) {
-    $items['entity_test']['translation']['entity_test'] = TRUE;
-  }
-  return $items;
+  return $return;
 }
 
 /**
diff --git a/core/modules/node/node.module b/core/modules/node/node.module
index a59a5c7..b5ed7e8 100644
--- a/core/modules/node/node.module
+++ b/core/modules/node/node.module
@@ -1725,7 +1725,7 @@ function node_search_admin() {
  */
 function node_search_execute($keys = NULL, $conditions = NULL) {
   // Build matching conditions
-  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\SearchQuery')->extend('PagerDefault');
+  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
   $query->join('node', 'n', 'n.nid = i.sid');
   $query
     ->condition('n.status', 1)
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.info b/core/modules/node/tests/node_access_test.info
similarity index 100%
rename from core/modules/node/tests/modules/node_access_test/node_access_test.info
rename to core/modules/node/tests/node_access_test.info
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.install b/core/modules/node/tests/node_access_test.install
similarity index 100%
rename from core/modules/node/tests/modules/node_access_test/node_access_test.install
rename to core/modules/node/tests/node_access_test.install
diff --git a/core/modules/node/tests/modules/node_access_test/node_access_test.module b/core/modules/node/tests/node_access_test.module
similarity index 100%
rename from core/modules/node/tests/modules/node_access_test/node_access_test.module
rename to core/modules/node/tests/node_access_test.module
diff --git a/core/modules/node/tests/modules/node_test/node_test.info b/core/modules/node/tests/node_test.info
similarity index 100%
rename from core/modules/node/tests/modules/node_test/node_test.info
rename to core/modules/node/tests/node_test.info
diff --git a/core/modules/node/tests/modules/node_test/node_test.module b/core/modules/node/tests/node_test.module
similarity index 100%
rename from core/modules/node/tests/modules/node_test/node_test.module
rename to core/modules/node/tests/node_test.module
diff --git a/core/modules/node/tests/modules/node_test_exception/node_test_exception.info b/core/modules/node/tests/node_test_exception.info
similarity index 100%
rename from core/modules/node/tests/modules/node_test_exception/node_test_exception.info
rename to core/modules/node/tests/node_test_exception.info
diff --git a/core/modules/node/tests/modules/node_test_exception/node_test_exception.module b/core/modules/node/tests/node_test_exception.module
similarity index 100%
rename from core/modules/node/tests/modules/node_test_exception/node_test_exception.module
rename to core/modules/node/tests/node_test_exception.module
diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module
index 144c2ab..fdb19ab 100644
--- a/core/modules/overlay/overlay.module
+++ b/core/modules/overlay/overlay.module
@@ -5,6 +5,8 @@
  * Displays the Drupal administration interface in an overlay.
  */
 
+use Symfony\Component\HttpFoundation\Response;
+
 /**
  * Implements hook_help().
  */
@@ -19,7 +21,7 @@ function overlay_help($path, $arg) {
 }
 
 /**
- * Implements hook_menu().
+ * Implements hook_menu()
  */
 function overlay_menu() {
   $items['overlay-ajax/%'] = array(
@@ -32,7 +34,7 @@ function overlay_menu() {
   $items['overlay/dismiss-message'] = array(
     'title' => '',
     'page callback' => 'overlay_user_dismiss_message',
-    'access arguments' => array('access overlay'),
+    'access callback' => 'overlay_user_dismiss_message_access',
     'type' => MENU_CALLBACK,
   );
   return $items;
@@ -300,22 +302,41 @@ function overlay_page_alter(&$page) {
 
 /**
  * Menu callback; dismisses the overlay accessibility message for this user.
+ *
+ * @see overlay_user_dismiss_message_access()
+ * @see overlay_menu()
  */
 function overlay_user_dismiss_message() {
   global $user;
+  user_save(user_load($user->uid), array('data' => array('overlay_message_dismissed' => 1)));
+  drupal_set_message(t('The message has been dismissed. You can change your overlay settings at any time by visiting your profile page.'));
+  // Destination is normally given. Go to the user profile as a fallback.
+  drupal_goto('user/' . $user->uid . '/edit');
+}
+
+/**
+ * Access callback; determines access to dismiss the overlay accessibility message.
+ *
+ * @see overlay_user_dismiss_message()
+ * @see overlay_menu()
+ */
+function overlay_user_dismiss_message_access() {
+  global $user;
+  if (!user_access('access overlay')) {
+    return FALSE;
+  }
   // It's unlikely, but possible that "access overlay" permission is granted to
   // the anonymous role. In this case, we do not display the message to disable
-  // the overlay, so there is nothing to dismiss. Also, protect against
-  // cross-site request forgeries by validating a token.
-  if (empty($user->uid) || !isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'overlay')) {
-    return MENU_ACCESS_DENIED;
+  // the overlay, so there is nothing to dismiss.
+  if (empty($user->uid)) {
+    return FALSE;
   }
-  else {
-    user_save(user_load($user->uid), array('data' => array('overlay_message_dismissed' => 1)));
-    drupal_set_message(t('The message has been dismissed. You can change your overlay settings at any time by visiting your profile page.'));
-    // Destination is normally given. Go to the user profile as a fallback.
-    drupal_goto('user/' . $user->uid . '/edit');
+  // Protect against cross-site request forgeries by validating a token.
+  $token = request()->query->get('token');
+  if (!isset($token) || !drupal_valid_token($token, 'overlay')) {
+    return FALSE;
   }
+  return TRUE;
 }
 
 /**
@@ -667,7 +688,8 @@ function overlay_overlay_child_initialize() {
   // it to the same content rendered in overlay_exit(), at the end of the page
   // request. This allows us to check if anything actually did change, and, if
   // so, trigger an immediate Ajax refresh of the parent window.
-  if (!empty($_POST) || isset($_GET['token'])) {
+  $token = request()->query->get('token');
+  if (!empty($_POST) || isset($token)) {
     foreach (overlay_supplemental_regions() as $region) {
       overlay_store_rendered_content($region, overlay_render_region($region));
     }
@@ -979,5 +1001,5 @@ function overlay_trigger_refresh() {
  * @see Drupal.overlay.refreshRegions()
  */
 function overlay_ajax_render_region($region) {
-  print overlay_render_region($region);
+  return new Response(overlay_render_region($region));
 }
diff --git a/core/modules/search/search.api.php b/core/modules/search/search.api.php
index cf81922..534c1e8 100644
--- a/core/modules/search/search.api.php
+++ b/core/modules/search/search.api.php
@@ -162,10 +162,10 @@ function hook_search_admin() {
  *
  * If your module uses hook_update_index() and search_index() to index its
  * items, use table 'search_index' aliased to 'i' as the main table in your
- * query, with the 'Drupal\search\SearchQuery' extension. You can join to your
- * module's table using the 'i.sid' field, which will contain the $sid values
- * you provided to search_index(). Add the main keywords to the query by using
- * method searchExpression(). The functions search_expression_extract() and
+ * query, with the 'SearchQuery' extension. You can join to your module's table
+ * using the 'i.sid' field, which will contain the $sid values you provided to
+ * search_index(). Add the main keywords to the query by using method
+ * searchExpression(). The functions search_expression_extract() and
  * search_expression_insert() may also be helpful for adding custom search
  * parameters to the search expression.
  *
@@ -195,7 +195,7 @@ function hook_search_admin() {
  */
 function hook_search_execute($keys = NULL, $conditions = NULL) {
   // Build matching conditions
-  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('Drupal\search\SearchQuery')->extend('PagerDefault');
+  $query = db_select('search_index', 'i', array('target' => 'slave'))->extend('SearchQuery')->extend('PagerDefault');
   $query->join('node', 'n', 'n.nid = i.sid');
   $query
     ->condition('n.status', 1)
diff --git a/core/modules/search/lib/Drupal/search/SearchQuery.php b/core/modules/search/search.extender.inc
similarity index 99%
rename from core/modules/search/lib/Drupal/search/SearchQuery.php
rename to core/modules/search/search.extender.inc
index 95103a6..73f7836 100644
--- a/core/modules/search/lib/Drupal/search/SearchQuery.php
+++ b/core/modules/search/search.extender.inc
@@ -1,12 +1,5 @@
 <?php
 
-/**
- * @file
- * Definition of Drupal\search\SearchQuery.
- */
-
-namespace Drupal\search;
-
 use Drupal\Core\Database\Query\SelectExtender;
 use Drupal\Core\Database\StatementEmpty;
 
diff --git a/core/modules/search/search.info b/core/modules/search/search.info
index a5a019e..1d47c96 100644
--- a/core/modules/search/search.info
+++ b/core/modules/search/search.info
@@ -3,6 +3,7 @@ description = Enables site-wide keyword searching.
 package = Core
 version = VERSION
 core = 8.x
+files[] = search.extender.inc
 files[] = search.test
 configure = admin/config/search/settings
 stylesheets[all][] = search.theme.css
diff --git a/core/modules/search/search.test b/core/modules/search/search.test
index 8944475..8b67b0b 100644
--- a/core/modules/search/search.test
+++ b/core/modules/search/search.test
@@ -159,7 +159,7 @@ class SearchMatchTestCase extends SearchWebTestCase {
     );
     foreach ($queries as $query => $results) {
       $result = db_select('search_index', 'i')
-        ->extend('Drupal\search\SearchQuery')
+        ->extend('SearchQuery')
         ->searchExpression($query, SEARCH_TYPE)
         ->execute();
 
@@ -179,7 +179,7 @@ class SearchMatchTestCase extends SearchWebTestCase {
     );
     foreach ($queries as $query => $results) {
       $result = db_select('search_index', 'i')
-        ->extend('Drupal\search\SearchQuery')
+        ->extend('SearchQuery')
         ->searchExpression($query, SEARCH_TYPE_2)
         ->execute();
 
@@ -202,7 +202,7 @@ class SearchMatchTestCase extends SearchWebTestCase {
     );
     foreach ($queries as $query => $results) {
       $result = db_select('search_index', 'i')
-        ->extend('Drupal\search\SearchQuery')
+        ->extend('SearchQuery')
         ->searchExpression($query, SEARCH_TYPE_JPN)
         ->execute();
 
diff --git a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info b/core/modules/search/tests/search_embedded_form.info
similarity index 100%
rename from core/modules/search/tests/modules/search_embedded_form/search_embedded_form.info
rename to core/modules/search/tests/search_embedded_form.info
diff --git a/core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module b/core/modules/search/tests/search_embedded_form.module
similarity index 100%
rename from core/modules/search/tests/modules/search_embedded_form/search_embedded_form.module
rename to core/modules/search/tests/search_embedded_form.module
diff --git a/core/modules/search/tests/modules/search_extra_type/search_extra_type.info b/core/modules/search/tests/search_extra_type.info
similarity index 100%
rename from core/modules/search/tests/modules/search_extra_type/search_extra_type.info
rename to core/modules/search/tests/search_extra_type.info
diff --git a/core/modules/search/tests/modules/search_extra_type/search_extra_type.module b/core/modules/search/tests/search_extra_type.module
similarity index 100%
rename from core/modules/search/tests/modules/search_extra_type/search_extra_type.module
rename to core/modules/search/tests/search_extra_type.module
diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php
index 7163739..59eb239 100644
--- a/core/modules/simpletest/drupal_web_test_case.php
+++ b/core/modules/simpletest/drupal_web_test_case.php
@@ -1837,6 +1837,7 @@ class DrupalWebTestCase extends DrupalTestCase {
    * Retrieve a Drupal path or an absolute path and JSON decode the result.
    */
   protected function drupalGetAJAX($path, array $options = array(), array $headers = array()) {
+    $headers[] = 'X-Requested-With: XMLHttpRequest';
     return drupal_json_decode($this->drupalGet($path, $options, $headers));
   }
 
@@ -2044,6 +2045,7 @@ class DrupalWebTestCase extends DrupalTestCase {
     }
     $content = $this->content;
     $drupal_settings = $this->drupalSettings;
+    $headers[] = 'X-Requested-With: XMLHttpRequest';
 
     // Get the Ajax settings bound to the triggering element.
     if (!isset($ajax_settings)) {
diff --git a/core/modules/simpletest/simpletest.info b/core/modules/simpletest/simpletest.info
index 7797fc5..cf55121 100644
--- a/core/modules/simpletest/simpletest.info
+++ b/core/modules/simpletest/simpletest.info
@@ -6,3 +6,41 @@ core = 8.x
 files[] = simpletest.test
 files[] = drupal_web_test_case.php
 configure = admin/config/development/testing/settings
+
+; Tests in tests directory.
+files[] = tests/actions.test
+files[] = tests/ajax.test
+files[] = tests/batch.test
+files[] = tests/bootstrap.test
+files[] = tests/cache.test
+files[] = tests/common.test
+files[] = tests/database_test.test
+files[] = tests/error.test
+files[] = tests/file.test
+files[] = tests/filetransfer.test
+files[] = tests/form.test
+files[] = tests/graph.test
+files[] = tests/image.test
+files[] = tests/installer.test
+files[] = tests/lock.test
+files[] = tests/mail.test
+files[] = tests/menu.test
+files[] = tests/module.test
+files[] = tests/pager.test
+files[] = tests/password.test
+files[] = tests/path.test
+files[] = tests/queue.test
+files[] = tests/registry.test
+files[] = tests/schema.test
+files[] = tests/session.test
+files[] = tests/symfony.test
+files[] = tests/tablesort.test
+files[] = tests/theme.test
+files[] = tests/unicode.test
+files[] = tests/update.test
+files[] = tests/uuid.test
+files[] = tests/xmlrpc.test
+files[] = tests/upgrade/upgrade.test
+files[] = tests/upgrade/upgrade_bare.test
+files[] = tests/upgrade/upgrade_filled.test
+files[] = tests/upgrade/upgrade.language.test
diff --git a/core/modules/simpletest/simpletest.test b/core/modules/simpletest/simpletest.test
index 4cecbe6..55a48be 100644
--- a/core/modules/simpletest/simpletest.test
+++ b/core/modules/simpletest/simpletest.test
@@ -86,9 +86,9 @@ class SimpleTestFunctionalTest extends DrupalWebTestCase {
   function testUserAgentValidation() {
     if (!$this->inCURL()) {
       global $base_url;
-      $system_path = $base_url . '/' . drupal_get_path('module', 'system');
-      $HTTP_path = $system_path .'/tests/http.php?q=node';
-      $https_path = $system_path .'/tests/https.php?q=node';
+      $simpletest_path = $base_url . '/' . drupal_get_path('module', 'simpletest');
+      $HTTP_path = $simpletest_path .'/tests/http.php?q=node';
+      $https_path = $simpletest_path .'/tests/https.php?q=node';
       // Generate a valid simpletest User-Agent to pass validation.
       $this->assertTrue(preg_match('/simpletest\d+/', $this->databasePrefix, $matches), t('Database prefix contains simpletest prefix.'));
       $test_ua = drupal_generate_test_ua($matches[0]);
diff --git a/core/modules/system/tests/actions.test b/core/modules/simpletest/tests/actions.test
similarity index 100%
rename from core/modules/system/tests/actions.test
rename to core/modules/simpletest/tests/actions.test
diff --git a/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.info b/core/modules/simpletest/tests/actions_loop_test.info
similarity index 100%
rename from core/modules/system/tests/modules/actions_loop_test/actions_loop_test.info
rename to core/modules/simpletest/tests/actions_loop_test.info
diff --git a/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install b/core/modules/simpletest/tests/actions_loop_test.install
similarity index 100%
rename from core/modules/system/tests/modules/actions_loop_test/actions_loop_test.install
rename to core/modules/simpletest/tests/actions_loop_test.install
diff --git a/core/modules/system/tests/modules/actions_loop_test/actions_loop_test.module b/core/modules/simpletest/tests/actions_loop_test.module
similarity index 100%
rename from core/modules/system/tests/modules/actions_loop_test/actions_loop_test.module
rename to core/modules/simpletest/tests/actions_loop_test.module
diff --git a/core/modules/system/tests/ajax.test b/core/modules/simpletest/tests/ajax.test
similarity index 100%
rename from core/modules/system/tests/ajax.test
rename to core/modules/simpletest/tests/ajax.test
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info b/core/modules/simpletest/tests/ajax_forms_test.info
similarity index 100%
rename from core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.info
rename to core/modules/simpletest/tests/ajax_forms_test.info
diff --git a/core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module b/core/modules/simpletest/tests/ajax_forms_test.module
similarity index 100%
rename from core/modules/system/tests/modules/ajax_forms_test/ajax_forms_test.module
rename to core/modules/simpletest/tests/ajax_forms_test.module
diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.info b/core/modules/simpletest/tests/ajax_test.info
similarity index 100%
rename from core/modules/system/tests/modules/ajax_test/ajax_test.info
rename to core/modules/simpletest/tests/ajax_test.info
diff --git a/core/modules/system/tests/modules/ajax_test/ajax_test.module b/core/modules/simpletest/tests/ajax_test.module
similarity index 94%
rename from core/modules/system/tests/modules/ajax_test/ajax_test.module
rename to core/modules/simpletest/tests/ajax_test.module
index 27b3161..21be019 100644
--- a/core/modules/system/tests/modules/ajax_test/ajax_test.module
+++ b/core/modules/simpletest/tests/ajax_test.module
@@ -35,7 +35,7 @@ function ajax_test_menu() {
  * Implements hook_system_theme_info().
  */
 function ajax_test_system_theme_info() {
-  $themes['test_theme'] = drupal_get_path('module', 'system') . '/tests/themes/test_theme/test_theme.info';
+  $themes['test_theme'] = drupal_get_path('module', 'ajax_test') . '/themes/test_theme/test_theme.info';
   return $themes;
 }
 
diff --git a/core/modules/system/tests/batch.test b/core/modules/simpletest/tests/batch.test
similarity index 100%
rename from core/modules/system/tests/batch.test
rename to core/modules/simpletest/tests/batch.test
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc b/core/modules/simpletest/tests/batch_test.callbacks.inc
similarity index 100%
rename from core/modules/system/tests/modules/batch_test/batch_test.callbacks.inc
rename to core/modules/simpletest/tests/batch_test.callbacks.inc
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.info b/core/modules/simpletest/tests/batch_test.info
similarity index 100%
rename from core/modules/system/tests/modules/batch_test/batch_test.info
rename to core/modules/simpletest/tests/batch_test.info
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/simpletest/tests/batch_test.module
similarity index 100%
rename from core/modules/system/tests/modules/batch_test/batch_test.module
rename to core/modules/simpletest/tests/batch_test.module
diff --git a/core/modules/system/tests/bootstrap.test b/core/modules/simpletest/tests/bootstrap.test
similarity index 100%
rename from core/modules/system/tests/bootstrap.test
rename to core/modules/simpletest/tests/bootstrap.test
diff --git a/core/modules/system/tests/cache.test b/core/modules/simpletest/tests/cache.test
similarity index 100%
rename from core/modules/system/tests/cache.test
rename to core/modules/simpletest/tests/cache.test
diff --git a/core/modules/system/tests/common.test b/core/modules/simpletest/tests/common.test
similarity index 99%
rename from core/modules/system/tests/common.test
rename to core/modules/simpletest/tests/common.test
index dbb471e..12df48c 100644
--- a/core/modules/system/tests/common.test
+++ b/core/modules/simpletest/tests/common.test
@@ -615,14 +615,14 @@ class CommonCascadingStylesheetsTestCase extends DrupalWebTestCase {
     // Verify common_test.css in a STYLE media="all" tag.
     $elements = $this->xpath('//style[@media=:media and contains(text(), :filename)]', array(
       ':media' => 'all',
-      ':filename' => 'tests/modules/common_test/common_test.css',
+      ':filename' => 'tests/common_test.css',
     ));
     $this->assertTrue(count($elements), "Stylesheet with media 'all' in module .info file found.");
 
     // Verify common_test.print.css in a STYLE media="print" tag.
     $elements = $this->xpath('//style[@media=:media and contains(text(), :filename)]', array(
       ':media' => 'print',
-      ':filename' => 'tests/modules/common_test/common_test.print.css',
+      ':filename' => 'tests/common_test.print.css',
     ));
     $this->assertTrue(count($elements), "Stylesheet with media 'print' in module .info file found.");
   }
@@ -767,22 +767,23 @@ class CommonCascadingStylesheetsTestCase extends DrupalWebTestCase {
    */
   function testRenderOverride() {
     $system = drupal_get_path('module', 'system');
+    $simpletest = drupal_get_path('module', 'simpletest');
 
     drupal_add_css($system . '/system.base.css');
-    drupal_add_css($system . '/tests/system.base.css');
+    drupal_add_css($simpletest . '/tests/system.base.css');
 
     // The dummy stylesheet should be the only one included.
     $styles = drupal_get_css();
-    $this->assert(strpos($styles, $system . '/tests/system.base.css') !== FALSE, t('The overriding CSS file is output.'));
+    $this->assert(strpos($styles, $simpletest . '/tests/system.base.css') !== FALSE, t('The overriding CSS file is output.'));
     $this->assert(strpos($styles, $system . '/system.base.css') === FALSE, t('The overridden CSS file is not output.'));
 
-    drupal_add_css($system . '/tests/system.base.css');
+    drupal_add_css($simpletest . '/tests/system.base.css');
     drupal_add_css($system . '/system.base.css');
 
     // The standard stylesheet should be the only one included.
     $styles = drupal_get_css();
     $this->assert(strpos($styles, $system . '/system.base.css') !== FALSE, t('The overriding CSS file is output.'));
-    $this->assert(strpos($styles, $system . '/tests/system.base.css') === FALSE, t('The overridden CSS file is not output.'));
+    $this->assert(strpos($styles, $simpletest . '/tests/system.base.css') === FALSE, t('The overridden CSS file is not output.'));
   }
 
   /**
@@ -2315,7 +2316,7 @@ class CommonDrupalParseInfoFileTestCase extends DrupalUnitTestCase {
    * Parse an example .info file an verify the results.
    */
   function testParseInfoFile() {
-    $info_values = drupal_parse_info_file(drupal_get_path('module', 'system') . '/tests/common_test_info.txt');
+    $info_values = drupal_parse_info_file(drupal_get_path('module', 'simpletest') . '/tests/common_test_info.txt');
     $this->assertEqual($info_values['simple_string'], 'A simple string', t('Simple string value was parsed correctly.'), t('System'));
     $this->assertEqual($info_values['simple_constant'], WATCHDOG_INFO, t('Constant value was parsed correctly.'), t('System'));
     $this->assertEqual($info_values['double_colon'], 'dummyClassName::', t('Value containing double-colon was parsed correctly.'), t('System'));
@@ -2345,14 +2346,14 @@ class CommonDrupalSystemListingTestCase extends DrupalWebTestCase {
       // with Drupal core, the copy in the core modules directory takes
       // precedence.
       'drupal_system_listing_incompatible_test' => array(
-        'core/modules/system/tests/modules',
+        'core/modules/simpletest/tests',
         'profiles/testing/modules',
       ),
       // When both copies of the module are compatible with Drupal core, the
       // copy in the profile directory takes precedence.
       'drupal_system_listing_compatible_test' => array(
         'profiles/testing/modules',
-        'core/modules/system/tests/modules',
+        'core/modules/simpletest/tests',
       ),
     );
 
diff --git a/core/modules/system/tests/modules/common_test/common_test.css b/core/modules/simpletest/tests/common_test.css
similarity index 100%
rename from core/modules/system/tests/modules/common_test/common_test.css
rename to core/modules/simpletest/tests/common_test.css
diff --git a/core/modules/system/tests/modules/common_test/common_test.info b/core/modules/simpletest/tests/common_test.info
similarity index 100%
rename from core/modules/system/tests/modules/common_test/common_test.info
rename to core/modules/simpletest/tests/common_test.info
diff --git a/core/modules/system/tests/modules/common_test/common_test.module b/core/modules/simpletest/tests/common_test.module
similarity index 100%
rename from core/modules/system/tests/modules/common_test/common_test.module
rename to core/modules/simpletest/tests/common_test.module
diff --git a/core/modules/system/tests/modules/common_test/common_test.print.css b/core/modules/simpletest/tests/common_test.print.css
similarity index 100%
rename from core/modules/system/tests/modules/common_test/common_test.print.css
rename to core/modules/simpletest/tests/common_test.print.css
diff --git a/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info b/core/modules/simpletest/tests/common_test_cron_helper.info
similarity index 100%
rename from core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.info
rename to core/modules/simpletest/tests/common_test_cron_helper.info
diff --git a/core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.module b/core/modules/simpletest/tests/common_test_cron_helper.module
similarity index 100%
rename from core/modules/system/tests/modules/common_test_cron_helper/common_test_cron_helper.module
rename to core/modules/simpletest/tests/common_test_cron_helper.module
diff --git a/core/modules/system/tests/common_test_info.txt b/core/modules/simpletest/tests/common_test_info.txt
similarity index 100%
rename from core/modules/system/tests/common_test_info.txt
rename to core/modules/simpletest/tests/common_test_info.txt
diff --git a/core/modules/system/tests/modules/config_upgrade/config/config.test.xml b/core/modules/simpletest/tests/config_upgrade/config/config.test.xml
similarity index 100%
rename from core/modules/system/tests/modules/config_upgrade/config/config.test.xml
rename to core/modules/simpletest/tests/config_upgrade/config/config.test.xml
diff --git a/core/modules/system/tests/modules/config_upgrade/config_upgrade.info b/core/modules/simpletest/tests/config_upgrade/config_upgrade.info
similarity index 100%
rename from core/modules/system/tests/modules/config_upgrade/config_upgrade.info
rename to core/modules/simpletest/tests/config_upgrade/config_upgrade.info
diff --git a/core/modules/system/tests/modules/config_upgrade/config_upgrade.module b/core/modules/simpletest/tests/config_upgrade/config_upgrade.module
similarity index 100%
rename from core/modules/system/tests/modules/config_upgrade/config_upgrade.module
rename to core/modules/simpletest/tests/config_upgrade/config_upgrade.module
diff --git a/core/modules/system/tests/modules/database_test/database_test.info b/core/modules/simpletest/tests/database_test.info
similarity index 100%
rename from core/modules/system/tests/modules/database_test/database_test.info
rename to core/modules/simpletest/tests/database_test.info
diff --git a/core/modules/system/tests/modules/database_test/database_test.install b/core/modules/simpletest/tests/database_test.install
similarity index 99%
rename from core/modules/system/tests/modules/database_test/database_test.install
rename to core/modules/simpletest/tests/database_test.install
index 867d813..4dce2b1 100644
--- a/core/modules/system/tests/modules/database_test/database_test.install
+++ b/core/modules/simpletest/tests/database_test.install
@@ -28,7 +28,6 @@ function database_test_schema() {
         'length' => 255,
         'not null' => TRUE,
         'default' => '',
-        'binary' => TRUE,
       ),
       'age' => array(
         'description' => "The person's age",
diff --git a/core/modules/system/tests/modules/database_test/database_test.module b/core/modules/simpletest/tests/database_test.module
similarity index 100%
rename from core/modules/system/tests/modules/database_test/database_test.module
rename to core/modules/simpletest/tests/database_test.module
diff --git a/core/modules/system/tests/modules/database_test/database_test.test b/core/modules/simpletest/tests/database_test.test
similarity index 99%
rename from core/modules/system/tests/modules/database_test/database_test.test
rename to core/modules/simpletest/tests/database_test.test
index bec0c16..04181b3 100644
--- a/core/modules/system/tests/modules/database_test/database_test.test
+++ b/core/modules/simpletest/tests/database_test.test
@@ -3134,39 +3134,6 @@ class DatabaseBasicSyntaxTestCase extends DatabaseTestCase {
 }
 
 /**
- * Test case sensitivity handling.
- */
-class DatabaseCaseSensitivityTestCase extends DatabaseTestCase {
-  public static function getInfo() {
-    return array(
-      'name' => 'Case sensitivity',
-      'description' => 'Test handling case sensitive collation.',
-      'group' => 'Database',
-    );
-  }
-
-  /**
-   * Test BINARY collation in MySQL.
-   */
-  function testCaseSensitiveInsert() {
-    $num_records_before = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
-
-    $john = db_insert('test')
-      ->fields(array(
-        'name' => 'john', // <- A record already exists with name 'John'.
-        'age' => 2,
-        'job' => 'Baby',
-      ))
-      ->execute();
-
-    $num_records_after = db_query('SELECT COUNT(*) FROM {test}')->fetchField();
-    $this->assertIdentical($num_records_before + 1, (int) $num_records_after, t('Record inserts correctly.'));
-    $saved_age = db_query('SELECT age FROM {test} WHERE name = :name', array(':name' => 'john'))->fetchField();
-    $this->assertIdentical($saved_age, '2', t('Can retrieve after inserting.'));
-  }
-}
-
-/**
  * Test invalid data handling.
  */
 class DatabaseInvalidDataTestCase extends DatabaseTestCase {
diff --git a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info b/core/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
similarity index 100%
rename from core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
rename to core/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.info
diff --git a/core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module b/core/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module
similarity index 100%
rename from core/modules/system/tests/modules/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module
rename to core/modules/simpletest/tests/drupal_system_listing_compatible_test/drupal_system_listing_compatible_test.module
diff --git a/core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info b/core/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
similarity index 100%
rename from core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
rename to core/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.info
diff --git a/core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module b/core/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module
similarity index 100%
rename from core/modules/system/tests/modules/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module
rename to core/modules/simpletest/tests/drupal_system_listing_incompatible_test/drupal_system_listing_incompatible_test.module
diff --git a/core/modules/system/tests/error.test b/core/modules/simpletest/tests/error.test
similarity index 90%
rename from core/modules/system/tests/error.test
rename to core/modules/simpletest/tests/error.test
index ead3526..8c5a848 100644
--- a/core/modules/system/tests/error.test
+++ b/core/modules/simpletest/tests/error.test
@@ -24,19 +24,19 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
       '%type' => 'Notice',
       '!message' => 'Undefined variable: bananas',
       '%function' => 'error_test_generate_warnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => drupal_realpath('core/modules/simpletest/tests/error_test.module'),
     );
     $error_warning = array(
       '%type' => 'Warning',
       '!message' => 'Division by zero',
       '%function' => 'error_test_generate_warnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => drupal_realpath('core/modules/simpletest/tests/error_test.module'),
     );
     $error_user_notice = array(
       '%type' => 'User warning',
       '!message' => 'Drupal is awesome',
       '%function' => 'error_test_generate_warnings()',
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => drupal_realpath('core/modules/simpletest/tests/error_test.module'),
     );
 
     // Set error reporting to collect notices.
@@ -73,14 +73,14 @@ class DrupalErrorHandlerUnitTest extends DrupalWebTestCase {
       '!message' => 'Drupal is awesome',
       '%function' => 'error_test_trigger_exception()',
       '%line' => 57,
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => drupal_realpath('core/modules/simpletest/tests/error_test.module'),
     );
     $error_pdo_exception = array(
       '%type' => 'PDOException',
       '!message' => 'SELECT * FROM bananas_are_awesome',
       '%function' => 'error_test_trigger_pdo_exception()',
       '%line' => 65,
-      '%file' => drupal_get_path('module', 'error_test') . '/error_test.module',
+      '%file' => drupal_realpath('core/modules/simpletest/tests/error_test.module'),
     );
 
     $this->drupalGet('error-test/trigger-exception');
diff --git a/core/modules/system/tests/modules/error_test/error_test.info b/core/modules/simpletest/tests/error_test.info
similarity index 100%
rename from core/modules/system/tests/modules/error_test/error_test.info
rename to core/modules/simpletest/tests/error_test.info
diff --git a/core/modules/system/tests/modules/error_test/error_test.module b/core/modules/simpletest/tests/error_test.module
similarity index 100%
rename from core/modules/system/tests/modules/error_test/error_test.module
rename to core/modules/simpletest/tests/error_test.module
diff --git a/core/modules/system/tests/file.test b/core/modules/simpletest/tests/file.test
similarity index 99%
rename from core/modules/system/tests/file.test
rename to core/modules/simpletest/tests/file.test
index c5eced1..00bda25 100644
--- a/core/modules/system/tests/file.test
+++ b/core/modules/simpletest/tests/file.test
@@ -2423,7 +2423,7 @@ class FileDownloadTest extends FileTestCase {
 
     $this->checkUrl('public', '', $basename, $base_url . '/' . file_stream_wrapper_get_instance_by_scheme('public')->getDirectoryPath() . '/' . $basename_encoded);
     $this->checkUrl('private', '', $basename, $base_url . '/system/files/' . $basename_encoded);
-    $this->checkUrl('private', '', $basename, $base_url . '/?q=system/files/' . $basename_encoded, '0');
+    $this->checkUrl('private', '', $basename, $base_url . '/index.php/system/files/' . $basename_encoded, '0');
   }
 
   /**
diff --git a/core/modules/system/tests/modules/file_test/file_test.info b/core/modules/simpletest/tests/file_test.info
similarity index 100%
rename from core/modules/system/tests/modules/file_test/file_test.info
rename to core/modules/simpletest/tests/file_test.info
diff --git a/core/modules/system/tests/modules/file_test/file_test.module b/core/modules/simpletest/tests/file_test.module
similarity index 100%
rename from core/modules/system/tests/modules/file_test/file_test.module
rename to core/modules/simpletest/tests/file_test.module
diff --git a/core/modules/system/tests/filetransfer.test b/core/modules/simpletest/tests/filetransfer.test
similarity index 100%
rename from core/modules/system/tests/filetransfer.test
rename to core/modules/simpletest/tests/filetransfer.test
diff --git a/core/modules/system/tests/modules/filter_test/filter_test.info b/core/modules/simpletest/tests/filter_test.info
similarity index 100%
rename from core/modules/system/tests/modules/filter_test/filter_test.info
rename to core/modules/simpletest/tests/filter_test.info
diff --git a/core/modules/system/tests/modules/filter_test/filter_test.module b/core/modules/simpletest/tests/filter_test.module
similarity index 100%
rename from core/modules/system/tests/modules/filter_test/filter_test.module
rename to core/modules/simpletest/tests/filter_test.module
diff --git a/core/modules/system/tests/form.test b/core/modules/simpletest/tests/form.test
similarity index 100%
rename from core/modules/system/tests/form.test
rename to core/modules/simpletest/tests/form.test
diff --git a/core/modules/system/tests/modules/form_test/form_test.file.inc b/core/modules/simpletest/tests/form_test.file.inc
similarity index 100%
rename from core/modules/system/tests/modules/form_test/form_test.file.inc
rename to core/modules/simpletest/tests/form_test.file.inc
diff --git a/core/modules/system/tests/modules/form_test/form_test.info b/core/modules/simpletest/tests/form_test.info
similarity index 100%
rename from core/modules/system/tests/modules/form_test/form_test.info
rename to core/modules/simpletest/tests/form_test.info
diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/simpletest/tests/form_test.module
similarity index 99%
rename from core/modules/system/tests/modules/form_test/form_test.module
rename to core/modules/simpletest/tests/form_test.module
index a2a2815..01908b9 100644
--- a/core/modules/system/tests/modules/form_test/form_test.module
+++ b/core/modules/simpletest/tests/form_test.module
@@ -1972,7 +1972,7 @@ function form_test_load_include_custom($form, &$form_state) {
   // Specify the include file and enable form caching. That way the form is
   // cached when it is submitted, but needs to find the specified submit handler
   // in the include.
-  // Filename is a bit weird here: modules/system/tests/form_test.file.inc
+  // Filename is a bit weird here: modules/simpletest/tests/form_test.file.inc
   form_load_include($form_state, 'inc', 'form_test', 'form_test.file');
   $form_state['cache'] = TRUE;
   return $form;
diff --git a/core/modules/system/tests/http.php b/core/modules/simpletest/tests/http.php
similarity index 89%
rename from core/modules/system/tests/http.php
rename to core/modules/simpletest/tests/http.php
index 2481d16..91985a6 100644
--- a/core/modules/system/tests/http.php
+++ b/core/modules/simpletest/tests/http.php
@@ -12,7 +12,7 @@ $is_http_mock = !empty($_SERVER['HTTPS']);
 $_SERVER['HTTPS'] = NULL;
 ini_set('session.cookie_secure', FALSE);
 foreach ($_SERVER as $key => $value) {
-  $_SERVER[$key] = str_replace('core/modules/system/tests/http.php', 'index.php', $value);
+  $_SERVER[$key] = str_replace('core/modules/simpletest/tests/http.php', 'index.php', $value);
   $_SERVER[$key] = str_replace('https://', 'http://', $_SERVER[$key]);
 }
 
diff --git a/core/modules/system/tests/https.php b/core/modules/simpletest/tests/https.php
similarity index 89%
rename from core/modules/system/tests/https.php
rename to core/modules/simpletest/tests/https.php
index 3d07f0c..c342abc 100644
--- a/core/modules/system/tests/https.php
+++ b/core/modules/simpletest/tests/https.php
@@ -11,7 +11,7 @@ $is_https_mock = empty($_SERVER['HTTPS']);
 // Change to https.
 $_SERVER['HTTPS'] = 'on';
 foreach ($_SERVER as $key => $value) {
-  $_SERVER[$key] = str_replace('core/modules/system/tests/https.php', 'index.php', $value);
+  $_SERVER[$key] = str_replace('core/modules/simpletest/tests/https.php', 'index.php', $value);
   $_SERVER[$key] = str_replace('http://', 'https://', $_SERVER[$key]);
 }
 
diff --git a/core/modules/system/tests/image.test b/core/modules/simpletest/tests/image.test
similarity index 100%
rename from core/modules/system/tests/image.test
rename to core/modules/simpletest/tests/image.test
diff --git a/core/modules/system/tests/modules/image_test/image_test.info b/core/modules/simpletest/tests/image_test.info
similarity index 100%
rename from core/modules/system/tests/modules/image_test/image_test.info
rename to core/modules/simpletest/tests/image_test.info
diff --git a/core/modules/system/tests/modules/image_test/image_test.module b/core/modules/simpletest/tests/image_test.module
similarity index 100%
rename from core/modules/system/tests/modules/image_test/image_test.module
rename to core/modules/simpletest/tests/image_test.module
diff --git a/core/modules/system/tests/installer.test b/core/modules/simpletest/tests/installer.test
similarity index 100%
rename from core/modules/system/tests/installer.test
rename to core/modules/simpletest/tests/installer.test
diff --git a/core/modules/system/tests/lock.test b/core/modules/simpletest/tests/lock.test
similarity index 100%
rename from core/modules/system/tests/lock.test
rename to core/modules/simpletest/tests/lock.test
diff --git a/core/modules/system/tests/mail.test b/core/modules/simpletest/tests/mail.test
similarity index 100%
rename from core/modules/system/tests/mail.test
rename to core/modules/simpletest/tests/mail.test
diff --git a/core/modules/system/tests/menu.test b/core/modules/simpletest/tests/menu.test
similarity index 100%
rename from core/modules/system/tests/menu.test
rename to core/modules/simpletest/tests/menu.test
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.info b/core/modules/simpletest/tests/menu_test.info
similarity index 100%
rename from core/modules/system/tests/modules/menu_test/menu_test.info
rename to core/modules/simpletest/tests/menu_test.info
diff --git a/core/modules/system/tests/modules/menu_test/menu_test.module b/core/modules/simpletest/tests/menu_test.module
similarity index 100%
rename from core/modules/system/tests/modules/menu_test/menu_test.module
rename to core/modules/simpletest/tests/menu_test.module
diff --git a/core/modules/system/tests/module.test b/core/modules/simpletest/tests/module.test
similarity index 100%
rename from core/modules/system/tests/module.test
rename to core/modules/simpletest/tests/module.test
diff --git a/core/modules/system/tests/modules/module_autoload_test/lib/Drupal/module_autoload_test/SomeClass.php b/core/modules/simpletest/tests/module_autoload_test/lib/Drupal/module_autoload_test/SomeClass.php
similarity index 100%
rename from core/modules/system/tests/modules/module_autoload_test/lib/Drupal/module_autoload_test/SomeClass.php
rename to core/modules/simpletest/tests/module_autoload_test/lib/Drupal/module_autoload_test/SomeClass.php
diff --git a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info b/core/modules/simpletest/tests/module_autoload_test/module_autoload_test.info
similarity index 100%
rename from core/modules/system/tests/modules/module_autoload_test/module_autoload_test.info
rename to core/modules/simpletest/tests/module_autoload_test/module_autoload_test.info
diff --git a/core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module b/core/modules/simpletest/tests/module_autoload_test/module_autoload_test.module
similarity index 100%
rename from core/modules/system/tests/modules/module_autoload_test/module_autoload_test.module
rename to core/modules/simpletest/tests/module_autoload_test/module_autoload_test.module
diff --git a/core/modules/system/tests/modules/module_test/module_test.file.inc b/core/modules/simpletest/tests/module_test.file.inc
similarity index 100%
rename from core/modules/system/tests/modules/module_test/module_test.file.inc
rename to core/modules/simpletest/tests/module_test.file.inc
diff --git a/core/modules/system/tests/modules/module_test/module_test.info b/core/modules/simpletest/tests/module_test.info
similarity index 100%
rename from core/modules/system/tests/modules/module_test/module_test.info
rename to core/modules/simpletest/tests/module_test.info
diff --git a/core/modules/system/tests/modules/module_test/module_test.install b/core/modules/simpletest/tests/module_test.install
similarity index 100%
rename from core/modules/system/tests/modules/module_test/module_test.install
rename to core/modules/simpletest/tests/module_test.install
diff --git a/core/modules/system/tests/modules/module_test/module_test.module b/core/modules/simpletest/tests/module_test.module
similarity index 100%
rename from core/modules/system/tests/modules/module_test/module_test.module
rename to core/modules/simpletest/tests/module_test.module
diff --git a/core/modules/system/tests/pager.test b/core/modules/simpletest/tests/pager.test
similarity index 100%
rename from core/modules/system/tests/pager.test
rename to core/modules/simpletest/tests/pager.test
diff --git a/core/modules/system/tests/password.test b/core/modules/simpletest/tests/password.test
similarity index 100%
rename from core/modules/system/tests/password.test
rename to core/modules/simpletest/tests/password.test
diff --git a/core/modules/system/tests/path.test b/core/modules/simpletest/tests/path.test
similarity index 100%
rename from core/modules/system/tests/path.test
rename to core/modules/simpletest/tests/path.test
diff --git a/core/modules/system/tests/modules/path_test/path_test.info b/core/modules/simpletest/tests/path_test.info
similarity index 100%
rename from core/modules/system/tests/modules/path_test/path_test.info
rename to core/modules/simpletest/tests/path_test.info
diff --git a/core/modules/system/tests/modules/path_test/path_test.module b/core/modules/simpletest/tests/path_test.module
similarity index 100%
rename from core/modules/system/tests/modules/path_test/path_test.module
rename to core/modules/simpletest/tests/path_test.module
diff --git a/core/modules/system/tests/queue.test b/core/modules/simpletest/tests/queue.test
similarity index 100%
rename from core/modules/system/tests/queue.test
rename to core/modules/simpletest/tests/queue.test
diff --git a/core/modules/system/tests/registry.test b/core/modules/simpletest/tests/registry.test
similarity index 100%
rename from core/modules/system/tests/registry.test
rename to core/modules/simpletest/tests/registry.test
diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.info b/core/modules/simpletest/tests/requirements1_test.info
similarity index 100%
rename from core/modules/system/tests/modules/requirements1_test/requirements1_test.info
rename to core/modules/simpletest/tests/requirements1_test.info
diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.install b/core/modules/simpletest/tests/requirements1_test.install
similarity index 100%
rename from core/modules/system/tests/modules/requirements1_test/requirements1_test.install
rename to core/modules/simpletest/tests/requirements1_test.install
diff --git a/core/modules/system/tests/modules/requirements1_test/requirements1_test.module b/core/modules/simpletest/tests/requirements1_test.module
similarity index 100%
rename from core/modules/system/tests/modules/requirements1_test/requirements1_test.module
rename to core/modules/simpletest/tests/requirements1_test.module
diff --git a/core/modules/system/tests/modules/requirements2_test/requirements2_test.info b/core/modules/simpletest/tests/requirements2_test.info
similarity index 100%
rename from core/modules/system/tests/modules/requirements2_test/requirements2_test.info
rename to core/modules/simpletest/tests/requirements2_test.info
diff --git a/core/modules/system/tests/modules/requirements2_test/requirements2_test.module b/core/modules/simpletest/tests/requirements2_test.module
similarity index 100%
rename from core/modules/system/tests/modules/requirements2_test/requirements2_test.module
rename to core/modules/simpletest/tests/requirements2_test.module
diff --git a/core/modules/system/tests/schema.test b/core/modules/simpletest/tests/schema.test
similarity index 100%
rename from core/modules/system/tests/schema.test
rename to core/modules/simpletest/tests/schema.test
diff --git a/core/modules/system/tests/session.test b/core/modules/simpletest/tests/session.test
similarity index 99%
rename from core/modules/system/tests/session.test
rename to core/modules/simpletest/tests/session.test
index 017a8ba..6303ca5 100644
--- a/core/modules/system/tests/session.test
+++ b/core/modules/simpletest/tests/session.test
@@ -513,7 +513,7 @@ class SessionHttpsTestCase extends DrupalWebTestCase {
    */
   protected function httpsUrl($url) {
     global $base_url;
-    return $base_url . '/core/modules/system/tests/https.php?q=' . $url;
+    return $base_url . '/core/modules/simpletest/tests/https.php?q=' . $url;
   }
 
   /**
@@ -527,7 +527,7 @@ class SessionHttpsTestCase extends DrupalWebTestCase {
    */
   protected function httpUrl($url) {
     global $base_url;
-    return $base_url . '/core/modules/system/tests/http.php?q=' . $url;
+    return $base_url . '/core/modules/simpletest/tests/http.php?q=' . $url;
   }
 }
 
diff --git a/core/modules/system/tests/modules/session_test/session_test.info b/core/modules/simpletest/tests/session_test.info
similarity index 100%
rename from core/modules/system/tests/modules/session_test/session_test.info
rename to core/modules/simpletest/tests/session_test.info
diff --git a/core/modules/system/tests/modules/session_test/session_test.module b/core/modules/simpletest/tests/session_test.module
similarity index 100%
rename from core/modules/system/tests/modules/session_test/session_test.module
rename to core/modules/simpletest/tests/session_test.module
diff --git a/core/modules/system/tests/symfony.test b/core/modules/simpletest/tests/symfony.test
similarity index 100%
rename from core/modules/system/tests/symfony.test
rename to core/modules/simpletest/tests/symfony.test
diff --git a/core/modules/system/tests/system.base.css b/core/modules/simpletest/tests/system.base.css
similarity index 100%
rename from core/modules/system/tests/system.base.css
rename to core/modules/simpletest/tests/system.base.css
diff --git a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info b/core/modules/simpletest/tests/system_dependencies_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.info
rename to core/modules/simpletest/tests/system_dependencies_test.info
diff --git a/core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.module b/core/modules/simpletest/tests/system_dependencies_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_dependencies_test/system_dependencies_test.module
rename to core/modules/simpletest/tests/system_dependencies_test.module
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info b/core/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.info
rename to core/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.info
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.module b/core/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_core_version_dependencies_test/system_incompatible_core_version_dependencies_test.module
rename to core/modules/simpletest/tests/system_incompatible_core_version_dependencies_test.module
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info b/core/modules/simpletest/tests/system_incompatible_core_version_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.info
rename to core/modules/simpletest/tests/system_incompatible_core_version_test.info
diff --git a/core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.module b/core/modules/simpletest/tests/system_incompatible_core_version_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_core_version_test/system_incompatible_core_version_test.module
rename to core/modules/simpletest/tests/system_incompatible_core_version_test.module
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info b/core/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.info
rename to core/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.info
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.module b/core/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_module_version_dependencies_test/system_incompatible_module_version_dependencies_test.module
rename to core/modules/simpletest/tests/system_incompatible_module_version_dependencies_test.module
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info b/core/modules/simpletest/tests/system_incompatible_module_version_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.info
rename to core/modules/simpletest/tests/system_incompatible_module_version_test.info
diff --git a/core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.module b/core/modules/simpletest/tests/system_incompatible_module_version_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_incompatible_module_version_test/system_incompatible_module_version_test.module
rename to core/modules/simpletest/tests/system_incompatible_module_version_test.module
diff --git a/core/modules/system/tests/modules/system_test/system_test.info b/core/modules/simpletest/tests/system_test.info
similarity index 100%
rename from core/modules/system/tests/modules/system_test/system_test.info
rename to core/modules/simpletest/tests/system_test.info
diff --git a/core/modules/system/tests/modules/system_test/system_test.module b/core/modules/simpletest/tests/system_test.module
similarity index 100%
rename from core/modules/system/tests/modules/system_test/system_test.module
rename to core/modules/simpletest/tests/system_test.module
diff --git a/core/modules/system/tests/tablesort.test b/core/modules/simpletest/tests/tablesort.test
similarity index 100%
rename from core/modules/system/tests/tablesort.test
rename to core/modules/simpletest/tests/tablesort.test
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.info b/core/modules/simpletest/tests/taxonomy_test.info
similarity index 100%
rename from core/modules/system/tests/modules/taxonomy_test/taxonomy_test.info
rename to core/modules/simpletest/tests/taxonomy_test.info
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.install b/core/modules/simpletest/tests/taxonomy_test.install
similarity index 100%
rename from core/modules/system/tests/modules/taxonomy_test/taxonomy_test.install
rename to core/modules/simpletest/tests/taxonomy_test.install
diff --git a/core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module b/core/modules/simpletest/tests/taxonomy_test.module
similarity index 100%
rename from core/modules/system/tests/modules/taxonomy_test/taxonomy_test.module
rename to core/modules/simpletest/tests/taxonomy_test.module
diff --git a/core/modules/system/tests/theme.test b/core/modules/simpletest/tests/theme.test
similarity index 100%
rename from core/modules/system/tests/theme.test
rename to core/modules/simpletest/tests/theme.test
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.inc b/core/modules/simpletest/tests/theme_test.inc
similarity index 100%
rename from core/modules/system/tests/modules/theme_test/theme_test.inc
rename to core/modules/simpletest/tests/theme_test.inc
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.info b/core/modules/simpletest/tests/theme_test.info
similarity index 100%
rename from core/modules/system/tests/modules/theme_test/theme_test.info
rename to core/modules/simpletest/tests/theme_test.info
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.module b/core/modules/simpletest/tests/theme_test.module
similarity index 91%
rename from core/modules/system/tests/modules/theme_test/theme_test.module
rename to core/modules/simpletest/tests/theme_test.module
index f2cd4a0..f6065f2 100644
--- a/core/modules/system/tests/modules/theme_test/theme_test.module
+++ b/core/modules/simpletest/tests/theme_test.module
@@ -21,9 +21,9 @@ function theme_test_theme($existing, $type, $theme, $path) {
  * Implements hook_system_theme_info().
  */
 function theme_test_system_theme_info() {
-  $themes['test_theme'] = drupal_get_path('module', 'system') . '/tests/themes/test_theme/test_theme.info';
-  $themes['test_basetheme'] = drupal_get_path('module', 'system') . '/tests/themes/test_basetheme/test_basetheme.info';
-  $themes['test_subtheme'] = drupal_get_path('module', 'system') . '/tests/themes/test_subtheme/test_subtheme.info';
+  $themes['test_theme'] = drupal_get_path('module', 'theme_test') . '/themes/test_theme/test_theme.info';
+  $themes['test_basetheme'] = drupal_get_path('module', 'theme_test') . '/themes/test_basetheme/test_basetheme.info';
+  $themes['test_subtheme'] = drupal_get_path('module', 'theme_test') . '/themes/test_subtheme/test_subtheme.info';
   return $themes;
 }
 
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.template_test.tpl.php b/core/modules/simpletest/tests/theme_test.template_test.tpl.php
similarity index 100%
rename from core/modules/system/tests/modules/theme_test/theme_test.template_test.tpl.php
rename to core/modules/simpletest/tests/theme_test.template_test.tpl.php
diff --git a/core/modules/system/tests/themes/test_basetheme/test_basetheme.info b/core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info
similarity index 100%
rename from core/modules/system/tests/themes/test_basetheme/test_basetheme.info
rename to core/modules/simpletest/tests/themes/test_basetheme/test_basetheme.info
diff --git a/core/modules/system/tests/themes/test_subtheme/test_subtheme.info b/core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info
similarity index 100%
rename from core/modules/system/tests/themes/test_subtheme/test_subtheme.info
rename to core/modules/simpletest/tests/themes/test_subtheme/test_subtheme.info
diff --git a/core/modules/system/tests/themes/test_theme/template.php b/core/modules/simpletest/tests/themes/test_theme/template.php
similarity index 100%
rename from core/modules/system/tests/themes/test_theme/template.php
rename to core/modules/simpletest/tests/themes/test_theme/template.php
diff --git a/core/modules/system/tests/themes/test_theme/test_theme.info b/core/modules/simpletest/tests/themes/test_theme/test_theme.info
similarity index 100%
rename from core/modules/system/tests/themes/test_theme/test_theme.info
rename to core/modules/simpletest/tests/themes/test_theme/test_theme.info
diff --git a/core/modules/system/tests/themes/test_theme/theme_test.template_test.tpl.php b/core/modules/simpletest/tests/themes/test_theme/theme_test.template_test.tpl.php
similarity index 100%
rename from core/modules/system/tests/themes/test_theme/theme_test.template_test.tpl.php
rename to core/modules/simpletest/tests/themes/test_theme/theme_test.template_test.tpl.php
diff --git a/core/modules/system/tests/unicode.test b/core/modules/simpletest/tests/unicode.test
similarity index 100%
rename from core/modules/system/tests/unicode.test
rename to core/modules/simpletest/tests/unicode.test
diff --git a/core/modules/system/tests/update.test b/core/modules/simpletest/tests/update.test
similarity index 100%
rename from core/modules/system/tests/update.test
rename to core/modules/simpletest/tests/update.test
diff --git a/core/modules/system/tests/modules/update_script_test/update_script_test.info b/core/modules/simpletest/tests/update_script_test.info
similarity index 100%
rename from core/modules/system/tests/modules/update_script_test/update_script_test.info
rename to core/modules/simpletest/tests/update_script_test.info
diff --git a/core/modules/system/tests/modules/update_script_test/update_script_test.install b/core/modules/simpletest/tests/update_script_test.install
similarity index 100%
rename from core/modules/system/tests/modules/update_script_test/update_script_test.install
rename to core/modules/simpletest/tests/update_script_test.install
diff --git a/core/modules/system/tests/modules/update_script_test/update_script_test.module b/core/modules/simpletest/tests/update_script_test.module
similarity index 100%
rename from core/modules/system/tests/modules/update_script_test/update_script_test.module
rename to core/modules/simpletest/tests/update_script_test.module
diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.info b/core/modules/simpletest/tests/update_test_1.info
similarity index 100%
rename from core/modules/system/tests/modules/update_test_1/update_test_1.info
rename to core/modules/simpletest/tests/update_test_1.info
diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.install b/core/modules/simpletest/tests/update_test_1.install
similarity index 100%
rename from core/modules/system/tests/modules/update_test_1/update_test_1.install
rename to core/modules/simpletest/tests/update_test_1.install
diff --git a/core/modules/system/tests/modules/update_test_1/update_test_1.module b/core/modules/simpletest/tests/update_test_1.module
similarity index 100%
rename from core/modules/system/tests/modules/update_test_1/update_test_1.module
rename to core/modules/simpletest/tests/update_test_1.module
diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.info b/core/modules/simpletest/tests/update_test_2.info
similarity index 100%
rename from core/modules/system/tests/modules/update_test_2/update_test_2.info
rename to core/modules/simpletest/tests/update_test_2.info
diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.install b/core/modules/simpletest/tests/update_test_2.install
similarity index 100%
rename from core/modules/system/tests/modules/update_test_2/update_test_2.install
rename to core/modules/simpletest/tests/update_test_2.install
diff --git a/core/modules/system/tests/modules/update_test_2/update_test_2.module b/core/modules/simpletest/tests/update_test_2.module
similarity index 100%
rename from core/modules/system/tests/modules/update_test_2/update_test_2.module
rename to core/modules/simpletest/tests/update_test_2.module
diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.info b/core/modules/simpletest/tests/update_test_3.info
similarity index 100%
rename from core/modules/system/tests/modules/update_test_3/update_test_3.info
rename to core/modules/simpletest/tests/update_test_3.info
diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.install b/core/modules/simpletest/tests/update_test_3.install
similarity index 100%
rename from core/modules/system/tests/modules/update_test_3/update_test_3.install
rename to core/modules/simpletest/tests/update_test_3.install
diff --git a/core/modules/system/tests/modules/update_test_3/update_test_3.module b/core/modules/simpletest/tests/update_test_3.module
similarity index 100%
rename from core/modules/system/tests/modules/update_test_3/update_test_3.module
rename to core/modules/simpletest/tests/update_test_3.module
diff --git a/core/modules/system/tests/upgrade/drupal-7.bare.database.php.gz b/core/modules/simpletest/tests/upgrade/drupal-7.bare.database.php.gz
similarity index 100%
rename from core/modules/system/tests/upgrade/drupal-7.bare.database.php.gz
rename to core/modules/simpletest/tests/upgrade/drupal-7.bare.database.php.gz
diff --git a/core/modules/system/tests/upgrade/drupal-7.filled.database.php.gz b/core/modules/simpletest/tests/upgrade/drupal-7.filled.database.php.gz
similarity index 100%
rename from core/modules/system/tests/upgrade/drupal-7.filled.database.php.gz
rename to core/modules/simpletest/tests/upgrade/drupal-7.filled.database.php.gz
diff --git a/core/modules/system/tests/upgrade/drupal-7.language.database.php b/core/modules/simpletest/tests/upgrade/drupal-7.language.database.php
similarity index 100%
rename from core/modules/system/tests/upgrade/drupal-7.language.database.php
rename to core/modules/simpletest/tests/upgrade/drupal-7.language.database.php
diff --git a/core/modules/system/tests/upgrade/upgrade.language.test b/core/modules/simpletest/tests/upgrade/upgrade.language.test
similarity index 97%
rename from core/modules/system/tests/upgrade/upgrade.language.test
rename to core/modules/simpletest/tests/upgrade/upgrade.language.test
index e473c63..bcf73a1 100644
--- a/core/modules/system/tests/upgrade/upgrade.language.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade.language.test
@@ -22,8 +22,8 @@ class LanguageUpgradePathTestCase extends UpgradePathTestCase {
   public function setUp() {
     // Path to the database dump files.
     $this->databaseDumpFiles = array(
-      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.filled.database.php.gz',
-      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.language.database.php',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.database.php.gz',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.language.database.php',
     );
     parent::setUp();
   }
diff --git a/core/modules/system/tests/upgrade/upgrade.test b/core/modules/simpletest/tests/upgrade/upgrade.test
similarity index 100%
rename from core/modules/system/tests/upgrade/upgrade.test
rename to core/modules/simpletest/tests/upgrade/upgrade.test
diff --git a/core/modules/system/tests/upgrade/upgrade_bare.test b/core/modules/simpletest/tests/upgrade/upgrade_bare.test
similarity index 89%
rename from core/modules/system/tests/upgrade/upgrade_bare.test
rename to core/modules/simpletest/tests/upgrade/upgrade_bare.test
index 71553d3..f507aea 100644
--- a/core/modules/system/tests/upgrade/upgrade_bare.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade_bare.test
@@ -17,7 +17,7 @@ class BareUpgradePathTestCase extends UpgradePathTestCase {
   public function setUp() {
     // Path to the database dump.
     $this->databaseDumpFiles = array(
-      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.database.php.gz',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.database.php.gz',
     );
     parent::setUp();
   }
diff --git a/core/modules/system/tests/upgrade/upgrade_filled.test b/core/modules/simpletest/tests/upgrade/upgrade_filled.test
similarity index 87%
rename from core/modules/system/tests/upgrade/upgrade_filled.test
rename to core/modules/simpletest/tests/upgrade/upgrade_filled.test
index 947d830..9b17bda 100644
--- a/core/modules/system/tests/upgrade/upgrade_filled.test
+++ b/core/modules/simpletest/tests/upgrade/upgrade_filled.test
@@ -17,7 +17,7 @@ class FilledUpgradePathTestCase extends UpgradePathTestCase {
   public function setUp() {
     // Path to the database dump.
     $this->databaseDumpFiles = array(
-      drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.filled.database.php.gz',
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.database.php.gz',
     );
     parent::setUp();
   }
diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.info b/core/modules/simpletest/tests/url_alter_test.info
similarity index 100%
rename from core/modules/system/tests/modules/url_alter_test/url_alter_test.info
rename to core/modules/simpletest/tests/url_alter_test.info
diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.install b/core/modules/simpletest/tests/url_alter_test.install
similarity index 100%
rename from core/modules/system/tests/modules/url_alter_test/url_alter_test.install
rename to core/modules/simpletest/tests/url_alter_test.install
diff --git a/core/modules/system/tests/modules/url_alter_test/url_alter_test.module b/core/modules/simpletest/tests/url_alter_test.module
similarity index 100%
rename from core/modules/system/tests/modules/url_alter_test/url_alter_test.module
rename to core/modules/simpletest/tests/url_alter_test.module
diff --git a/core/modules/system/tests/uuid.test b/core/modules/simpletest/tests/uuid.test
similarity index 100%
rename from core/modules/system/tests/uuid.test
rename to core/modules/simpletest/tests/uuid.test
diff --git a/core/modules/system/tests/xmlrpc.test b/core/modules/simpletest/tests/xmlrpc.test
similarity index 100%
rename from core/modules/system/tests/xmlrpc.test
rename to core/modules/simpletest/tests/xmlrpc.test
diff --git a/core/modules/system/tests/modules/xmlrpc_test/xmlrpc_test.info b/core/modules/simpletest/tests/xmlrpc_test.info
similarity index 100%
rename from core/modules/system/tests/modules/xmlrpc_test/xmlrpc_test.info
rename to core/modules/simpletest/tests/xmlrpc_test.info
diff --git a/core/modules/system/tests/modules/xmlrpc_test/xmlrpc_test.module b/core/modules/simpletest/tests/xmlrpc_test.module
similarity index 100%
rename from core/modules/system/tests/modules/xmlrpc_test/xmlrpc_test.module
rename to core/modules/simpletest/tests/xmlrpc_test.module
diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc
index aac0c3d..34b3798 100644
--- a/core/modules/system/system.admin.inc
+++ b/core/modules/system/system.admin.inc
@@ -5,6 +5,8 @@
  * Admin page callbacks for the system module.
  */
 
+use Symfony\Component\HttpFoundation\Response;
+
 /**
  * Menu callback; Provide the administration overview page.
  */
@@ -2357,6 +2359,9 @@ function system_batch_page() {
   if ($output === FALSE) {
     drupal_access_denied();
   }
+  elseif ($output instanceof Response) {
+    return $output;
+  }
   elseif (isset($output)) {
     // Force a page without blocks or messages to
     // display a list of collected messages later.
diff --git a/core/modules/system/system.info b/core/modules/system/system.info
index 41495f3..f082cd5 100644
--- a/core/modules/system/system.info
+++ b/core/modules/system/system.info
@@ -6,40 +6,3 @@ core = 8.x
 files[] = system.test
 required = TRUE
 configure = admin/config/system
-
-; Tests in tests directory.
-files[] = tests/actions.test
-files[] = tests/ajax.test
-files[] = tests/batch.test
-files[] = tests/bootstrap.test
-files[] = tests/cache.test
-files[] = tests/common.test
-files[] = tests/database_test.test
-files[] = tests/error.test
-files[] = tests/file.test
-files[] = tests/filetransfer.test
-files[] = tests/form.test
-files[] = tests/image.test
-files[] = tests/installer.test
-files[] = tests/lock.test
-files[] = tests/mail.test
-files[] = tests/menu.test
-files[] = tests/module.test
-files[] = tests/pager.test
-files[] = tests/password.test
-files[] = tests/path.test
-files[] = tests/queue.test
-files[] = tests/registry.test
-files[] = tests/schema.test
-files[] = tests/session.test
-files[] = tests/symfony.test
-files[] = tests/tablesort.test
-files[] = tests/theme.test
-files[] = tests/unicode.test
-files[] = tests/update.test
-files[] = tests/uuid.test
-files[] = tests/xmlrpc.test
-files[] = tests/upgrade/upgrade.test
-files[] = tests/upgrade/upgrade_bare.test
-files[] = tests/upgrade/upgrade_filled.test
-files[] = tests/upgrade/upgrade.language.test
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index a3594b9..ccaac21 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -1983,8 +1983,11 @@ function system_add_module_assets() {
  * Implements hook_custom_theme().
  */
 function system_custom_theme() {
-  if (user_access('view the administration theme') && path_is_admin(current_path())) {
-    return variable_get('admin_theme');
+  if ($request = request()) {
+    $path = ltrim($request->getPathInfo(), '/');
+    if (user_access('view the administration theme') && path_is_admin($path)) {
+      return variable_get('admin_theme');
+    }
   }
 }
 
diff --git a/core/modules/taxonomy/taxonomy.test b/core/modules/taxonomy/taxonomy.test
index 65d6805..b3d0080 100644
--- a/core/modules/taxonomy/taxonomy.test
+++ b/core/modules/taxonomy/taxonomy.test
@@ -756,9 +756,8 @@ class TaxonomyTermTestCase extends TaxonomyWebTestCase {
     $path = 'taxonomy/autocomplete/taxonomy_';
     $path .= $this->vocabulary->machine_name . '/' . $input;
     // The result order is not guaranteed, so check each term separately.
-    $url = url($path, array('absolute' => TRUE));
-    $result = drupal_http_request($url);
-    $data = drupal_json_decode($result->data);
+    $result = $this->drupalGet($path);
+    $data = drupal_json_decode($result);
     $this->assertEqual($data[$first_term->name], check_plain($first_term->name), 'Autocomplete returned the first matching term');
     $this->assertEqual($data[$second_term->name], check_plain($second_term->name), 'Autocomplete returned the second matching term');
 
diff --git a/core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml b/core/modules/update/tests/aaa_update_test.1_0.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/aaa_update_test.1_0.xml
rename to core/modules/update/tests/aaa_update_test.1_0.xml
diff --git a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info b/core/modules/update/tests/aaa_update_test.info
similarity index 100%
rename from core/modules/update/tests/modules/aaa_update_test/aaa_update_test.info
rename to core/modules/update/tests/aaa_update_test.info
diff --git a/core/modules/update/tests/modules/aaa_update_test/aaa_update_test.module b/core/modules/update/tests/aaa_update_test.module
similarity index 100%
rename from core/modules/update/tests/modules/aaa_update_test/aaa_update_test.module
rename to core/modules/update/tests/aaa_update_test.module
diff --git a/core/modules/update/tests/modules/update_test/aaa_update_test.no-releases.xml b/core/modules/update/tests/aaa_update_test.no-releases.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/aaa_update_test.no-releases.xml
rename to core/modules/update/tests/aaa_update_test.no-releases.xml
diff --git a/core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml b/core/modules/update/tests/bbb_update_test.1_0.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/bbb_update_test.1_0.xml
rename to core/modules/update/tests/bbb_update_test.1_0.xml
diff --git a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info b/core/modules/update/tests/bbb_update_test.info
similarity index 100%
rename from core/modules/update/tests/modules/bbb_update_test/bbb_update_test.info
rename to core/modules/update/tests/bbb_update_test.info
diff --git a/core/modules/update/tests/modules/bbb_update_test/bbb_update_test.module b/core/modules/update/tests/bbb_update_test.module
similarity index 100%
rename from core/modules/update/tests/modules/bbb_update_test/bbb_update_test.module
rename to core/modules/update/tests/bbb_update_test.module
diff --git a/core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml b/core/modules/update/tests/ccc_update_test.1_0.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/ccc_update_test.1_0.xml
rename to core/modules/update/tests/ccc_update_test.1_0.xml
diff --git a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info b/core/modules/update/tests/ccc_update_test.info
similarity index 100%
rename from core/modules/update/tests/modules/ccc_update_test/ccc_update_test.info
rename to core/modules/update/tests/ccc_update_test.info
diff --git a/core/modules/update/tests/modules/ccc_update_test/ccc_update_test.module b/core/modules/update/tests/ccc_update_test.module
similarity index 100%
rename from core/modules/update/tests/modules/ccc_update_test/ccc_update_test.module
rename to core/modules/update/tests/ccc_update_test.module
diff --git a/core/modules/update/tests/modules/update_test/drupal.0.xml b/core/modules/update/tests/drupal.0.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/drupal.0.xml
rename to core/modules/update/tests/drupal.0.xml
diff --git a/core/modules/update/tests/modules/update_test/drupal.1.xml b/core/modules/update/tests/drupal.1.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/drupal.1.xml
rename to core/modules/update/tests/drupal.1.xml
diff --git a/core/modules/update/tests/modules/update_test/drupal.2-sec.xml b/core/modules/update/tests/drupal.2-sec.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/drupal.2-sec.xml
rename to core/modules/update/tests/drupal.2-sec.xml
diff --git a/core/modules/update/tests/modules/update_test/drupal.dev.xml b/core/modules/update/tests/drupal.dev.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/drupal.dev.xml
rename to core/modules/update/tests/drupal.dev.xml
diff --git a/core/modules/update/tests/modules/update_test/update_test.info b/core/modules/update/tests/update_test.info
similarity index 100%
rename from core/modules/update/tests/modules/update_test/update_test.info
rename to core/modules/update/tests/update_test.info
diff --git a/core/modules/update/tests/modules/update_test/update_test.module b/core/modules/update/tests/update_test.module
similarity index 97%
rename from core/modules/update/tests/modules/update_test/update_test.module
rename to core/modules/update/tests/update_test.module
index ff5aad5..312a6dd 100644
--- a/core/modules/update/tests/modules/update_test/update_test.module
+++ b/core/modules/update/tests/update_test.module
@@ -4,8 +4,8 @@
  * Implements hook_system_theme_info().
  */
 function update_test_system_theme_info() {
-  $themes['update_test_basetheme'] = drupal_get_path('module', 'update') . '/tests/themes/update_test_basetheme/update_test_basetheme.info';
-  $themes['update_test_subtheme'] = drupal_get_path('module', 'update') . '/tests/themes/update_test_subtheme/update_test_subtheme.info';
+  $themes['update_test_basetheme'] = drupal_get_path('module', 'update_test') . '/themes/update_test_basetheme/update_test_basetheme.info';
+  $themes['update_test_subtheme'] = drupal_get_path('module', 'update_test') . '/themes/update_test_subtheme/update_test_subtheme.info';
   return $themes;
 }
 
diff --git a/core/modules/update/tests/modules/update_test/update_test_basetheme.1_1-sec.xml b/core/modules/update/tests/update_test_basetheme.1_1-sec.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/update_test_basetheme.1_1-sec.xml
rename to core/modules/update/tests/update_test_basetheme.1_1-sec.xml
diff --git a/core/modules/update/tests/modules/update_test/update_test_subtheme.1_0.xml b/core/modules/update/tests/update_test_subtheme.1_0.xml
similarity index 100%
rename from core/modules/update/tests/modules/update_test/update_test_subtheme.1_0.xml
rename to core/modules/update/tests/update_test_subtheme.1_0.xml
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 3b1d9cb..92e7398 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -947,14 +947,11 @@ function user_account_form(&$form, &$form_state) {
     '#weight' => -10,
   );
 
-  // The mail field is NOT required if account originally had no mail set
-  // and the user performing the edit has 'administer users' permission.
-  // This allows users without e-mail address to be edited and deleted.
   $form['account']['mail'] = array(
     '#type' => 'email',
     '#title' => t('E-mail address'),
     '#description' => t('A valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail.'),
-    '#required' => !(empty($account->mail) && user_access('administer users')),
+    '#required' => TRUE,
     '#default_value' => (!$register ? $account->mail : ''),
   );
 
@@ -1136,7 +1133,7 @@ function user_account_form_validate($form, &$form_state) {
 
   $mail = $form_state['values']['mail'];
 
-  if (!empty($mail) && (bool) db_select('users')->fields('users', array('uid'))->condition('uid', $account->uid, '<>')->condition('mail', db_like($mail), 'LIKE')->range(0, 1)->execute()->fetchField()) {
+  if ((bool) db_select('users')->fields('users', array('uid'))->condition('uid', $account->uid, '<>')->condition('mail', db_like($mail), 'LIKE')->range(0, 1)->execute()->fetchField()) {
     // Format error message dependent on whether the user is logged in or not.
     if ($GLOBALS['user']->uid) {
       form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => $mail)));
@@ -2484,9 +2481,12 @@ function user_delete_multiple(array $uids) {
  * Page callback wrapper for user_view().
  */
 function user_view_page($account) {
+  if (is_object($account)) {
+    return user_view($account);
+  }
   // An administrator may try to view a non-existent account,
   // so we give them a 404 (versus a 403 for non-admins).
-  return is_object($account) ? user_view($account) : MENU_NOT_FOUND;
+  drupal_not_found();
 }
 
 /**
@@ -3797,19 +3797,14 @@ function user_register_submit($form, &$form_state) {
   }
   // No administrator approval required.
   elseif ($account->status || $notify) {
-    if (empty($account->mail) && $notify) {
-      drupal_set_message(t('The new user <a href="@url">%name</a> was created without an email address, so no welcome message was sent.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->name)));
+    $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
+    _user_mail_notify($op, $account);
+    if ($notify) {
+      drupal_set_message(t('A welcome message with further instructions has been e-mailed to the new user <a href="@url">%name</a>.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->name)));
     }
     else {
-      $op = $notify ? 'register_admin_created' : 'register_no_approval_required';
-      _user_mail_notify($op, $account);
-      if ($notify) {
-        drupal_set_message(t('A welcome message with further instructions has been e-mailed to the new user <a href="@url">%name</a>.', array('@url' => url($uri['path'], $uri['options']), '%name' => $account->name)));
-      }
-      else {
-        drupal_set_message(t('A welcome message with further instructions has been sent to your e-mail address.'));
-        $form_state['redirect'] = '';
-      }
+      drupal_set_message(t('A welcome message with further instructions has been sent to your e-mail address.'));
+      $form_state['redirect'] = '';
     }
   }
   // Administrator approval required.
diff --git a/core/modules/user/user.test b/core/modules/user/user.test
index 3a3a713..06fbc95 100644
--- a/core/modules/user/user.test
+++ b/core/modules/user/user.test
@@ -837,34 +837,6 @@ class UserCancelTestCase extends DrupalWebTestCase {
   }
 
   /**
-   * Tests deletion of a user account without an e-mail address.
-   */
-  function testUserWithoutEmailCancelByAdmin() {
-    variable_set('user_cancel_method', 'user_cancel_reassign');
-
-    // Create a regular user.
-    $account = $this->drupalCreateUser(array());
-    // This user has no e-mail address.
-    $edit = array('mail' => '');
-    $account = user_save($account, $edit);
-
-    // Create administrative user.
-    $admin_user = $this->drupalCreateUser(array('administer users'));
-    $this->drupalLogin($admin_user);
-
-    // Delete regular user without e-mail address.
-    $this->drupalGet('user/' . $account->uid . '/edit');
-    $this->drupalPost(NULL, NULL, t('Cancel account'));
-    $this->assertRaw(t('Are you sure you want to cancel the account %name?', array('%name' => $account->name)), t('Confirmation form to cancel account displayed.'));
-    $this->assertText(t('Select the method to cancel the account above.'), t('Allows to select account cancellation method.'));
-
-    // Confirm deletion.
-    $this->drupalPost(NULL, NULL, t('Cancel account'));
-    $this->assertRaw(t('%name has been deleted.', array('%name' => $account->name)), t('User deleted.'));
-    $this->assertFalse(user_load($account->uid), t('User is not found in the database.'));
-  }
-
-  /**
    * Create an administrative user and mass-delete other users.
    */
   function testMassUserCancelByAdmin() {
@@ -1814,22 +1786,6 @@ class UserEditTestCase extends DrupalWebTestCase {
     $this->drupalLogin($user1);
     $this->drupalLogout();
   }
-
-  /**
-   * Tests editing of a user account without an e-mail address.
-   */
-  function testUserWithoutEmailEdit() {
-    // Test that an admin can edit users without an e-mail address.
-    $admin = $this->drupalCreateUser(array('administer users'));
-    $this->drupalLogin($admin);
-    // Create a regular user.
-    $user1 = $this->drupalCreateUser(array());
-    // This user has no e-mail address.
-    $edit = array('mail' => '');
-    $user1 = user_save($user1, $edit);
-    $this->drupalPost("user/$user1->uid/edit", $edit, t('Save'));
-    $this->assertRaw(t("The changes have been saved."));
-  }
 }
 
 /**
diff --git a/core/update.php b/core/update.php
index 3d858a2..db9bd90 100644
--- a/core/update.php
+++ b/core/update.php
@@ -454,13 +454,15 @@ if (update_access_allowed()) {
     // update.php ops.
 
     case 'selection':
-      if (isset($_GET['token']) && $_GET['token'] == drupal_get_token('update')) {
+      $token = request()->query->get('token');
+      if (isset($token) && drupal_valid_token($token, 'update')) {
         $output = update_selection_page();
         break;
       }
 
     case 'Apply pending updates':
-      if (isset($_GET['token']) && $_GET['token'] == drupal_get_token('update')) {
+      $token = request()->query->get('token');
+      if (isset($token) && drupal_valid_token($token, 'update')) {
         // Generate absolute URLs for the batch processing (using $base_root),
         // since the batch API will pass them to url() which does not handle
         // update.php correctly by default.
diff --git a/index.php b/index.php
index b91fb1e..6ebb47f 100644
--- a/index.php
+++ b/index.php
@@ -11,11 +11,34 @@
  * See COPYRIGHT.txt and LICENSE.txt files in the "core" directory.
  */
 
+use Drupal\Core\DrupalKernel;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpKernel\Controller\ControllerResolver;
+
 /**
  * Root directory of Drupal installation.
  */
 define('DRUPAL_ROOT', getcwd());
-
+// Bootstrap the lowest level of what we need.
 require_once DRUPAL_ROOT . '/core/includes/bootstrap.inc';
+drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);
+
+// A request object from the HTTPFoundation to tell us about the request.
+$request = Request::createFromGlobals();
+
+// Set the global $request object.  This is a temporary measure to
+// keep legacy utility functions working.  It should be moved to a dependency
+// injection container at some point.
+request($request);
+
 drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
-menu_execute_active_handler();
+
+$dispatcher = new EventDispatcher();
+$resolver = new ControllerResolver();
+
+$kernel = new DrupalKernel($dispatcher, $resolver);
+$response = $kernel->handle($request);
+$response->prepare($request);
+$response->send();
+$kernel->terminate($request, $response);
