diff --git a/core/includes/ajax.inc b/core/includes/ajax.inc
index 8e024a8d3afc00789cdb017b197fa435b4b83edb..a94f068cc78f5d6f14846bb3fe5c36b793cd2abe 100644
--- a/core/includes/ajax.inc
+++ b/core/includes/ajax.inc
@@ -235,12 +235,14 @@ function ajax_render($commands = array()) {
   // during this request to be loaded by the page. We only want to send back
   // files that the page hasn't already loaded, so we implement simple diffing
   // logic using array_diff_key().
+  $request = Drupal::request();
   foreach (array('css', 'js') as $type) {
     // It is highly suspicious if $_POST['ajax_page_state'][$type] is empty,
     // since the base page ought to have at least one JS file and one CSS file
     // loaded. It probably indicates an error, and rather than making the page
     // reload all of the files, instead we return no new files.
-    if (empty($_POST['ajax_page_state'][$type])) {
+    $state = $request->request->get('ajax_page_state[' . $type . ']', FALSE, TRUE);
+    if ($state) {
       $items[$type] = array();
     }
     else {
@@ -259,7 +261,7 @@ function ajax_render($commands = array()) {
         }
       }
       // Ensure that the page doesn't reload what it already has.
-      $items[$type] = array_diff_key($items[$type], $_POST['ajax_page_state'][$type]);
+      $items[$type] = array_diff_key($items[$type], $state);
     }
   }
 
@@ -317,7 +319,8 @@ function ajax_render($commands = array()) {
 function ajax_get_form() {
   $form_state = form_state_defaults();
 
-  $form_build_id = $_POST['form_build_id'];
+  $request = Drupal::request();
+  $form_build_id = $request->request->get('form_build_id');
 
   // Get the form from the cache.
   $form = form_get_cache($form_build_id, $form_state);
@@ -342,7 +345,7 @@ function ajax_get_form() {
 
   // The form needs to be processed; prepare for that by setting a few internal
   // variables.
-  $form_state['input'] = $_POST;
+  $form_state['input'] = $request->request->all();
   $form_id = $form['#form_id'];
 
   return array($form, $form_state, $form_id, $form_build_id);
@@ -404,10 +407,10 @@ function ajax_form_callback() {
  * @see file_menu()
  */
 function ajax_base_page_theme() {
-  if (!empty($_POST['ajax_page_state']['theme']) && !empty($_POST['ajax_page_state']['theme_token'])) {
-    $theme = $_POST['ajax_page_state']['theme'];
-    $token = $_POST['ajax_page_state']['theme_token'];
-
+  $request = Drupal::request();
+  $theme = $request->request->get('ajax_page_state[theme]', NULL, TRUE);
+  $token = $request->request->get('ajax_page_state[theme_token]', NULL, TRUE);
+  if (!empty($theme) && !empty($token)) {
     // Prevent a request forgery from giving a person access to a theme they
     // shouldn't be otherwise allowed to see. However, since everyone is allowed
     // to see the default theme, token validation isn't required for that, and
diff --git a/core/includes/common.inc b/core/includes/common.inc
index a518afd882d0df3f3e90a0fe910d5501521ed977..03eaa399953131e2478c9fc5310bcfa79b4790fa 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -3989,7 +3989,8 @@ function show(&$element) {
  * @see drupal_render_cache_set()
  */
 function drupal_render_cache_get($elements) {
-  if (!in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) || !$cid = drupal_render_cid_create($elements)) {
+  $request = Drupal::request();
+  if (!$request->isMethodSafe() || !$cid = drupal_render_cid_create($elements)) {
     return FALSE;
   }
   $bin = isset($elements['#cache']['bin']) ? $elements['#cache']['bin'] : 'cache';
@@ -4021,7 +4022,8 @@ function drupal_render_cache_get($elements) {
  */
 function drupal_render_cache_set(&$markup, $elements) {
   // Create the cache ID for the element.
-  if (!in_array($_SERVER['REQUEST_METHOD'], array('GET', 'HEAD')) || !$cid = drupal_render_cid_create($elements)) {
+  $request = Drupal::request();
+  if (!$request->isMethodSafe() || !$cid = drupal_render_cid_create($elements)) {
     return FALSE;
   }
 
diff --git a/core/includes/errors.inc b/core/includes/errors.inc
index 3fe23b727cc564192bdd5dc8614d4e9164393b94..f44162db231b5ac8ed5de3c9192f7722da7011bf 100644
--- a/core/includes/errors.inc
+++ b/core/includes/errors.inc
@@ -222,7 +222,8 @@ function _drupal_log_error($error, $fatal = FALSE) {
     }
   }
 
-  if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') {
+  $request = Drupal::request();
+  if ($request->isXmlHttpRequest()) {
     if ($fatal) {
       if (error_displayable($error)) {
         // When called from JavaScript, simply output the error message.
diff --git a/core/includes/pager.inc b/core/includes/pager.inc
index cef12ac4c3a432698fc5fc29213514b343bac746..cb97b401b8037b04773c04e23473bc635a780840 100644
--- a/core/includes/pager.inc
+++ b/core/includes/pager.inc
@@ -26,7 +26,7 @@
  * @see pager_default_initialize()
  */
 function pager_find_page($element = 0) {
-  $page = isset($_GET['page']) ? $_GET['page'] : '';
+  $page = Drupal::request()->query->get('page', '');
   $page_array = explode(',', $page);
   if (!isset($page_array[$element])) {
     $page_array[$element] = 0;
@@ -136,7 +136,7 @@ function pager_default_initialize($total, $limit, $element = 0) {
 function pager_get_query_parameters() {
   $query = &drupal_static(__FUNCTION__);
   if (!isset($query)) {
-    $query = drupal_get_query_parameters($_GET, array('page'));
+    $query = drupal_get_query_parameters(Drupal::request()->query->all(), array('page'));
   }
   return $query;
 }
@@ -425,7 +425,7 @@ function pager_query_add_page(array $query, $element, $index) {
   // Determine the first result to display on the linked page.
   $page_new = pager_load_array($index, $element, $pager_page_array);
 
-  $page = isset($_GET['page']) ? $_GET['page'] : '';
+  $page = Drupal::request()->query->get('page', '');
   if ($new_page = implode(',', pager_load_array($page_new[$element], $element, explode(',', $page)))) {
     $query['page'] = $new_page;
   }
diff --git a/core/includes/tablesort.inc b/core/includes/tablesort.inc
index c42b1f4ea1203eb27e52f479b19b210a018ed8b5..82201e20f05751a8348900c8b29bd8861991dcc4 100644
--- a/core/includes/tablesort.inc
+++ b/core/includes/tablesort.inc
@@ -100,7 +100,7 @@ function tablesort_cell($cell, $header, $ts, $i) {
  *   page request except for those pertaining to table sorting.
  */
 function tablesort_get_query_parameters() {
-  return drupal_get_query_parameters($_GET, array('sort', 'order'));
+  return drupal_get_query_parameters(Drupal::request()->query->all(), array('sort', 'order'));
 }
 
 /**
@@ -115,7 +115,7 @@ function tablesort_get_query_parameters() {
  *   - "sql": The name of the database field to sort on.
  */
 function tablesort_get_order($headers) {
-  $order = isset($_GET['order']) ? $_GET['order'] : '';
+  $order = Drupal::request()->query->get('order', '');
   foreach ($headers as $header) {
     if (is_array($header)) {
       if (isset($header['data']) && $order == $header['data']) {
@@ -150,8 +150,9 @@ function tablesort_get_order($headers) {
  *   The current sort direction ("asc" or "desc").
  */
 function tablesort_get_sort($headers) {
-  if (isset($_GET['sort'])) {
-    return (strtolower($_GET['sort']) == 'desc') ? 'desc' : 'asc';
+  $sort = Drupal::request()->query->get('sort');
+  if (isset($sort)) {
+    return (strtolower($sort) == 'desc') ? 'desc' : 'asc';
   }
   // The user has not specified a sort. Use the default for the currently sorted
   // header if specified; otherwise use "asc".
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/TableSortExtenderUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/TableSortExtenderUnitTest.php
index c7cc2a9b8e60f35bfce2c5c34e86e14b941fcf31..241949fce4a4c30b449bd00386ed8cd10daafd21 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/TableSortExtenderUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/TableSortExtenderUnitTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\system\Tests\Common;
 
 use Drupal\simpletest\UnitTestBase;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Tests unicode handling features implemented in unicode.inc.
@@ -53,38 +54,42 @@ function testTableSortInit() {
     $headers = array('foo', 'bar', 'baz');
     // Reset $_GET to prevent parameters from Simpletest and Batch API ending
     // up in $ts['query'].
-    $_GET = array();
     $expected_ts = array(
       'name' => 'foo',
       'sql' => '',
       'sort' => 'asc',
       'query' => array(),
     );
+    $request = Request::createFromGlobals();
+    $request->query->replace(array());
+    \Drupal::getContainer()->set('request', $request);
     $ts = tablesort_init($headers);
     $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE)))));
     $this->assertEqual($ts, $expected_ts, 'Simple table headers sorted correctly.');
 
     // Test with simple table headers plus $_GET parameters that should _not_
     // override the default.
-
-    $_GET = array(
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
       // This should not override the table order because only complex
       // headers are overridable.
       'order' => 'bar',
-    );
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $ts = tablesort_init($headers);
     $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE)))));
     $this->assertEqual($ts, $expected_ts, 'Simple table headers plus non-overriding $_GET parameters sorted correctly.');
 
     // Test with simple table headers plus $_GET parameters that _should_
     // override the default.
-
-    $_GET = array(
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
       'sort' => 'DESC',
       // Add an unrelated parameter to ensure that tablesort will include
       // it in the links that it creates.
       'alpha' => 'beta',
-    );
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $expected_ts['sort'] = 'desc';
     $expected_ts['query'] = array('alpha' => 'beta');
     $ts = tablesort_init($headers);
@@ -108,9 +113,11 @@ function testTableSortInit() {
       ),
     );
     // Reset $_GET from previous assertion.
-    $_GET = array(
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
       'order' => '2',
-    );
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $ts = tablesort_init($headers);
     $expected_ts = array(
       'name' => '2',
@@ -123,12 +130,13 @@ function testTableSortInit() {
 
     // Test complex table headers plus $_GET parameters that should _not_
     // override the default.
-
-    $_GET = array(
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
       // This should not override the table order because this header does not
       // exist.
       'order' => 'bar',
-    );
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $ts = tablesort_init($headers);
     $expected_ts = array(
       'name' => '1',
@@ -138,18 +146,18 @@ function testTableSortInit() {
     );
     $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE)))));
     $this->assertEqual($ts, $expected_ts, 'Complex table headers plus non-overriding $_GET parameters sorted correctly.');
-    unset($_GET['sort'], $_GET['order'], $_GET['alpha']);
 
     // Test complex table headers plus $_GET parameters that _should_
     // override the default.
-
-    $_GET = array(
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
       'order' => '1',
       'sort' => 'ASC',
       // Add an unrelated parameter to ensure that tablesort will include
       // it in the links that it creates.
       'alpha' => 'beta',
-    );
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $expected_ts = array(
       'name' => '1',
       'sql' => 'one',
@@ -159,7 +167,5 @@ function testTableSortInit() {
     $ts = tablesort_init($headers);
     $this->verbose(strtr('$ts: <pre>!ts</pre>', array('!ts' => check_plain(var_export($ts, TRUE)))));
     $this->assertEqual($ts, $expected_ts, 'Complex table headers plus $_GET parameters sorted correctly.');
-    unset($_GET['sort'], $_GET['order'], $_GET['alpha']);
-
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/SelectPagerDefaultTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/SelectPagerDefaultTest.php
index 83f0640bf016d88a3219ac0e521279142478f482..79c93d210ab93bb2e9864f3a5b97fe217c922805 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Database/SelectPagerDefaultTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Database/SelectPagerDefaultTest.php
@@ -6,6 +6,7 @@
  */
 
 namespace Drupal\system\Tests\Database;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Tests the pager query select extender.
@@ -135,7 +136,12 @@ function testHavingPagerQuery() {
    * Confirms that every pager gets a valid, non-overlaping element ID.
    */
   function testElementNumbers() {
-    $_GET['page'] = '3, 2, 1, 0';
+
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
+      'page' => '3, 2, 1, 0',
+    ));
+    \Drupal::getContainer()->set('request', $request);
 
     $name = db_select('test', 't')
       ->extend('Drupal\Core\Database\Query\PagerSelectExtender')
@@ -168,6 +174,5 @@ function testElementNumbers() {
       ->fetchField();
     $this->assertEqual($name, 'John', 'Pager query #3 with a generated element ID returned the correct results.');
 
-    unset($_GET['page']);
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php
index 284526fe337bb55c70b2269e57e3015bf8d4b127..69851f9c87385c4bc74a69a7cd1b92e9fd64ed61 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityQueryTest.php
@@ -8,6 +8,7 @@
 namespace Drupal\system\Tests\Entity;
 
 use Drupal\Core\Language\Language;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Tests the basic Entity API.
@@ -348,7 +349,11 @@ function testSort() {
 
     // Test the pager by setting element #1 to page 2 with a page size of 4.
     // Results will be #8-12 from above.
-    $_GET['page'] = '0,2';
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
+      'page' => '0,2',
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $this->queryResults = $this->factory->get('entity_test_mulrev')
       ->sort("$figures.color")
       ->sort("$greetings.format")
@@ -375,8 +380,13 @@ protected function testTableSort() {
     // While ordering on bundles do not give us a definite order, we can still
     // assert that all entities from one bundle are after the other as the
     // order dictates.
-    $_GET['sort'] = 'asc';
-    $_GET['order'] = 'Type';
+    $request = Request::createFromGlobals();
+    $request->query->replace(array(
+      'sort' => 'asc',
+      'order' => 'Type',
+    ));
+    \Drupal::getContainer()->set('request', $request);
+
     $header = array(
       'id' => array('data' => 'Id', 'specifier' => 'id'),
       'type' => array('data' => 'Type', 'specifier' => 'type'),
@@ -386,7 +396,12 @@ protected function testTableSort() {
       ->tableSort($header)
       ->execute());
     $this->assertBundleOrder('asc');
-    $_GET['sort'] = 'desc';
+
+    $request->query->add(array(
+      'sort' => 'desc',
+    ));
+    \Drupal::getContainer()->set('request', $request);
+
     $header = array(
       'id' => array('data' => 'Id', 'specifier' => 'id'),
       'type' => array('data' => 'Type', 'specifier' => 'type'),
@@ -395,8 +410,12 @@ protected function testTableSort() {
       ->tableSort($header)
       ->execute());
     $this->assertBundleOrder('desc');
+
     // Ordering on ID is definite, however.
-    $_GET['order'] = 'Id';
+    $request->query->add(array(
+      'order' => 'Id',
+    ));
+    \Drupal::getContainer()->set('request', $request);
     $this->queryResults = $this->factory->get('entity_test_mulrev')
       ->tableSort($header)
       ->execute();