diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 3e3853a..ee1092b 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -981,17 +981,18 @@ function variable_initialize($conf = array()) {
   else {
     // Cache miss. Avoid a stampede.
     $name = 'variable_init';
-    if (!lock()->acquire($name, 1)) {
+    $lock = Drupal::lock();
+    if (!$lock->acquire($name, 1)) {
       // Another request is building the variable cache.
       // Wait, then re-run this function.
-      lock()->wait($name);
+      $lock->wait($name);
       return variable_initialize($conf);
     }
     else {
       // Proceed with variable rebuild.
       $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
       cache('bootstrap')->set('variables', $variables);
-      lock()->release($name);
+      $lock->release($name);
     }
   }
 
@@ -2431,29 +2432,15 @@ function drupal_get_bootstrap_phase() {
 /**
  * Retrieves the Drupal Container to standardize object construction.
  *
- * The container is built by the kernel and passed in to this function which
- * stores it statically. The container always contains the services from
- * \Drupal\Core\CoreBundle, the bundles of enabled modules and any other
- * bundles defined in $GLOBALS['conf']['container_bundles'].
- *
- * @see Drupal\Core\DrupalKernel
- *
- * @param Symfony\Component\DependencyInjection\ContainerInterface $new_container
- *   (optional) A new container instance to replace the current.
+ * @deprecated This function has been replaced by the \Drupal class. Use that
+ *   instead.
  *
  * @return Symfony\Component\DependencyInjection\ContainerInterface|bool
  *   The instance of the ContainerInterface used to set up and maintain
  *   object instances or FALSE if none exist yet.
  */
-function drupal_container(ContainerInterface $new_container = NULL) {
-  // We do not use drupal_static() here because we do not have a mechanism by
-  // which to reinitialize the stored objects, so a drupal_static_reset() call
-  // would leave Drupal in a nonfunctional state.
-  static $container;
-  if (isset($new_container)) {
-    $container = $new_container;
-  }
-  return $container;
+function drupal_container() {
+  return Drupal::getContainer();
 }
 
 /**
@@ -3174,7 +3161,7 @@ function drupal_classloader($class_loader = NULL) {
     // ones that use PEAR-like class prefixes in a single array, but the Symfony
     // class loader requires them to be registered separately.
     $prefixes_and_namespaces = require DRUPAL_ROOT . '/core/vendor/composer/autoload_namespaces.php';
-    $prefixes = array();
+    $prefixes = array('Drupal' => DRUPAL_ROOT . '/core/lib');
     $namespaces = array();
     foreach ($prefixes_and_namespaces as $key => $path) {
       // If the key:
@@ -3547,10 +3534,13 @@ function drupal_check_memory_limit($required, $memory_limit = NULL) {
 /**
  * Get locking layer instance.
  *
+ * @deprecated Use Drupal::lock() instead, or even better have the lock service
+ *   injected into your object.
+ *
  * @return Drupal\Core\Lock\LockBackendInterface
  */
 function lock() {
-  return drupal_container()->get('lock');
+  return Drupal::lock();
 }
 
 /**
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index c4de9ee..2848d04 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -367,7 +367,7 @@ function install_begin_request(&$install_state) {
       ))
       ->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));
 
-    drupal_container($container);
+    Drupal::setContainer($container);
   }
 
   // Set up $language, so t() caller functions will still work.
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
new file mode 100644
index 0000000..dee7c9d
--- /dev/null
+++ b/core/lib/Drupal.php
@@ -0,0 +1,99 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal.
+ */
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Static Service Container wrapper.
+ *
+ * Generally, code in Drupal should accept its dependencies via either
+ * constructor injection or setter method injection. However, there are cases,
+ * particularly in legacy procedural code, where that is infeasible. This
+ * class acts as a unified global accessor to arbitrary services within the
+ * system in order to ease the transition from procedural code to injected OO
+ * code.
+ *
+ * The container is built by the kernel and passed in to this class which stores
+ * it statically. The container always contains the services from
+ * \Drupal\Core\CoreBundle, the bundles of enabled modules and any other bundles
+ * defined in $GLOBALS['conf']['container_bundles'].
+ *
+ * @see \Drupal\Core\DrupalKernel
+ *
+ * @deprecated
+ *   This class exists only to support legacy code that cannot be dependency
+ *   injected. If your code needs it, that means your code should be refactored
+ *   eventually. This class will be removed once enough of Drupal has been
+ *   migrated to be fully injected.
+ */
+class Drupal {
+
+  /**
+   * The currently active container object.
+   *
+   * @var \Symfony\Component\DependencyInjection\ContainerInterface
+   */
+  protected static $container;
+
+  /**
+   * Sets a new global container.
+   *
+   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
+   *   A new container instance to replace the current.
+   */
+  public static function setContainer(ContainerInterface $container) {
+    static::$container = $container;
+  }
+
+  /**
+   * Returns the currently active global container.
+   *
+   * @deprecated This method is only useful for the testing environment, and as
+   *   a BC shiv for drupal_container(). It should not be used otherwise.
+   *
+   * @return \Symfony\Component\DependencyInjection\ContainerInterface
+   */
+  public static function getContainer() {
+    return static::$container;
+  }
+
+  /**
+   * Retrieves a service from the container.
+   *
+   * Use this method if the desired service is not one of those with a dedicated
+   * accessor method below. If it is listed below, those methods are preferred
+   * as they can return useful type hints.
+   *
+   * @param string $id
+   *   The ID of the service to retrieve.
+   * @return mixed
+   *   The specified service.
+   */
+  public static function service($id) {
+    return static::$container->get($id);
+  }
+
+  /**
+   * Returns the current primary database.
+   *
+   * @return \Drupal\Core\Database\Connection
+   *   The current active database's master connection.
+   */
+  public static function database() {
+    return static::$container->get('database');
+  }
+
+  /**
+   * Returns the locking layer instance.
+   *
+   * @return \Drupal\Core\Lock\LockBackendInterface
+   */
+  public static function lock() {
+    return static::$container->get('lock');
+  }
+
+}
diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php
index d56f503..a159628 100644
--- a/core/lib/Drupal/Core/DrupalKernel.php
+++ b/core/lib/Drupal/Core/DrupalKernel.php
@@ -326,7 +326,7 @@ protected function initializeContainer() {
     // Set the class loader which was registered as a synthetic service.
     $this->container->set('class_loader', $this->classLoader);
 
-    drupal_container($this->container);
+    \Drupal::setContainer($this->container);
   }
 
   /**
diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc
index 931a47a..5ee9fb7 100644
--- a/core/modules/contact/contact.pages.inc
+++ b/core/modules/contact/contact.pages.inc
@@ -92,7 +92,7 @@ function contact_flood_control() {
   $config = config('contact.settings');
   $limit = $config->get('flood.limit');
   $interval = $config->get('flood.interval');
-  if (!drupal_container()->get('flood')->isAllowed('contact', $limit, $interval)) {
+  if (!Drupal::service('flood')->isAllowed('contact', $limit, $interval)) {
     drupal_set_message(t("You cannot send more than %limit messages in @interval. Try again later.", array(
       '%limit' => $limit,
       '@interval' => format_interval($interval),
diff --git a/core/modules/contact/lib/Drupal/contact/MessageFormController.php b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
index e536675..c4352cf 100644
--- a/core/modules/contact/lib/Drupal/contact/MessageFormController.php
+++ b/core/modules/contact/lib/Drupal/contact/MessageFormController.php
@@ -191,7 +191,7 @@ public function save(array $form, array &$form_state) {
       drupal_mail('contact', 'page_autoreply', $sender->mail, $language_interface->langcode, $params);
     }
 
-    drupal_container()->get('flood')->register('contact', config('contact.settings')->get('flood.interval'));
+    \Drupal::service('flood')->register('contact', config('contact.settings')->get('flood.interval'));
     if ($message->category) {
       watchdog('contact', '%sender-name (@sender-from) sent an e-mail regarding %category.', array(
         '%sender-name' => $sender->name,
diff --git a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
index fd5dd75..bdc98ef 100644
--- a/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
+++ b/core/modules/contact/lib/Drupal/contact/Tests/ContactSitewideTest.php
@@ -207,7 +207,7 @@ function testAutoReply() {
     // We are testing the auto-reply, so there should be one e-mail going to the sender.
     $captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email));
     $this->assertEqual(count($captured_emails), 1);
-    $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($foo_autoreply));
+    $this->assertEqual(trim($captured_emails[0]['body']), trim(drupal_html_to_text($foo_autoreply)));
 
     // Test the auto-reply for category 'bar'.
     $email = $this->randomName(32) . '@example.com';
@@ -216,7 +216,7 @@ function testAutoReply() {
     // Auto-reply for category 'bar' should result in one auto-reply e-mail to the sender.
     $captured_emails = $this->drupalGetMails(array('id' => 'contact_page_autoreply', 'to' => $email));
     $this->assertEqual(count($captured_emails), 1);
-    $this->assertEqual($captured_emails[0]['body'], drupal_html_to_text($bar_autoreply));
+    $this->assertEqual(trim($captured_emails[0]['body']), trim(drupal_html_to_text($bar_autoreply)));
 
     // Verify that no auto-reply is sent when the auto-reply field is left blank.
     $email = $this->randomName(32) . '@example.com';
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
index da6a65f..4d4c216 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/TestBase.php
@@ -894,7 +894,7 @@ protected function prepareEnvironment() {
 
     // Reset and create a new service container.
     $this->container = new ContainerBuilder();
-    drupal_container($this->container);
+    \Drupal::setContainer($this->container);
 
     // Unset globals.
     unset($GLOBALS['theme_key']);
@@ -1039,7 +1039,7 @@ protected function tearDown() {
     new Settings($this->originalSettings);
 
     // Restore original statics and globals.
-    drupal_container($this->originalContainer);
+    \Drupal::setContainer($this->originalContainer);
     $GLOBALS['config_directories'] = $this->originalConfigDirectories;
     if (isset($this->originalPrefix)) {
       drupal_valid_test_ua($this->originalPrefix);
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
index 083c968..6af396b 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/FloodTest.php
@@ -30,20 +30,21 @@ function testCleanUp() {
     $name = 'flood_test_cleanup';
 
     // Register expired event.
-    drupal_container()->get('flood')->register($name, $window_expired);
+    $flood = \Drupal::service('flood');
+    $flood->register($name, $window_expired);
     // Verify event is not allowed.
-    $this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
+    $this->assertFalse($flood->isAllowed($name, $threshold));
     // Run cron and verify event is now allowed.
     $this->cronRun();
-    $this->assertTrue(drupal_container()->get('flood')->isAllowed($name, $threshold));
+    $this->assertTrue($flood->isAllowed($name, $threshold));
 
     // Register unexpired event.
-    drupal_container()->get('flood')->register($name);
+    $flood->register($name);
     // Verify event is not allowed.
-    $this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
+    $this->assertFalse($flood->isAllowed($name, $threshold));
     // Run cron and verify event is still not allowed.
     $this->cronRun();
-    $this->assertFalse(drupal_container()->get('flood')->isAllowed($name, $threshold));
+    $this->assertFalse($flood->isAllowed($name, $threshold));
   }
 
   /**
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 1a659c5..f0b900c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3521,7 +3521,7 @@ function system_get_module_admin_tasks($module, $info) {
  */
 function system_cron() {
   // Cleanup the flood.
-  drupal_container()->get('flood')->garbageCollection();
+  Drupal::service('flood')->garbageCollection();
 
   $cache_bins = array_merge(module_invoke_all('cache_flush'), array('form', 'menu'));
   foreach ($cache_bins as $bin) {
diff --git a/core/modules/translation_entity/translation_entity.module b/core/modules/translation_entity/translation_entity.module
index ac00322..a413f0a 100644
--- a/core/modules/translation_entity/translation_entity.module
+++ b/core/modules/translation_entity/translation_entity.module
@@ -868,11 +868,21 @@ function translation_entity_field_info_alter(&$info) {
 function translation_entity_field_attach_presave(EntityInterface $entity) {
   if (translation_entity_enabled($entity->entityType(), $entity->bundle())) {
     $attributes = drupal_container()->get('request')->attributes;
-    drupal_container()->get('translation_entity.synchronizer')->synchronizeFields($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
+    translation_entity_synchronizer()->synchronizeFields($entity, $attributes->get('working_langcode'), $attributes->get('source_langcode'));
   }
 }
 
 /**
+ * Returns an instance of the field translation synchronizer service.
+ *
+ * @return \Drupal\translation_entity\FieldTranslationSynchronizerInterface
+ *   An object implementing the field translation synchronizer interface.
+ */
+function translation_entity_synchronizer() {
+  return Drupal::service('translation_entity.synchronizer');
+}
+
+/**
  * Implements hook_element_info_alter().
  */
 function translation_entity_element_info_alter(&$type) {
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 5635e16..250cc75 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1330,13 +1330,14 @@ function user_login_name_validate($form, &$form_state) {
 function user_login_authenticate_validate($form, &$form_state) {
   $password = trim($form_state['values']['pass']);
   $flood_config = config('user.flood');
+  $flood = Drupal::service('flood');
   if (!empty($form_state['values']['name']) && !empty($password)) {
     // Do not allow any login from the current user's IP if the limit has been
     // reached. Default is 50 failed attempts allowed in one hour. This is
     // independent of the per-user limit to catch attempts from one IP to log
     // in to many different user accounts.  We have a reasonably high limit
     // since there may be only one apparent IP for all users at an institution.
-    if (!drupal_container()->get('flood')->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
+    if (!$flood->isAllowed('user.failed_login_ip', $flood_config->get('ip_limit'), $flood_config->get('ip_window'))) {
       $form_state['flood_control_triggered'] = 'ip';
       return;
     }
@@ -1357,7 +1358,7 @@ function user_login_authenticate_validate($form, &$form_state) {
 
       // Don't allow login if the limit for this user has been reached.
       // Default is to allow 5 failed attempts every 6 hours.
-      if (!drupal_container()->get('flood')->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
+      if (!$flood->isAllowed('user.failed_login_user', $flood_config->get('user_limit'), $flood_config->get('user_window'), $identifier)) {
         $form_state['flood_control_triggered'] = 'user';
         return;
       }
@@ -1377,12 +1378,13 @@ function user_login_authenticate_validate($form, &$form_state) {
  */
 function user_login_final_validate($form, &$form_state) {
   $flood_config = config('user.flood');
+  $flood = Drupal::service('flood');
   if (empty($form_state['uid'])) {
     // Always register an IP-based failed login event.
-    drupal_container()->get('flood')->register('user.failed_login_ip', $flood_config->get('ip_window'));
+    $flood->register('user.failed_login_ip', $flood_config->get('ip_window'));
     // Register a per-user failed login event.
     if (isset($form_state['flood_control_user_identifier'])) {
-      drupal_container()->get('flood')->register('user.failed_login_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
+      $flood->register('user.failed_login_user', $flood_config->get('user_window'), $form_state['flood_control_user_identifier']);
     }
 
     if (isset($form_state['flood_control_triggered'])) {
@@ -1402,7 +1404,7 @@ function user_login_final_validate($form, &$form_state) {
   elseif (isset($form_state['flood_control_user_identifier'])) {
     // Clear past failures for this user so as not to block a user who might
     // log in and out more than once in an hour.
-    drupal_container()->get('flood')->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
+    $flood->clear('user.failed_login_user', $form_state['flood_control_user_identifier']);
   }
 }
 
