diff --git a/core/core.services.yml b/core/core.services.yml
index 9fb9ebd25e268730359b68f9cd79f2090bb1722d..2e186aea1380ddf178987a3e306bfd2fca880b94 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -390,3 +390,6 @@ services:
     class: Drupal\system\Plugin\ImageToolkitInterface
     factory_method: getDefaultToolkit
     factory_service: image.toolkit.manager
+  token:
+    class: Drupal\Core\Utility\Token
+    arguments: ['@module_handler']
diff --git a/core/includes/common.inc b/core/includes/common.inc
index d4d9961510f35f8058b68046f5a10823d740ed32..4087a42083f79a972bcc84667c0c261c34308761 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4569,7 +4569,6 @@ function _drupal_bootstrap_code() {
   require_once DRUPAL_ROOT . '/core/includes/form.inc';
   require_once DRUPAL_ROOT . '/core/includes/mail.inc';
   require_once DRUPAL_ROOT . '/core/includes/ajax.inc';
-  require_once DRUPAL_ROOT . '/core/includes/token.inc';
   require_once DRUPAL_ROOT . '/core/includes/errors.inc';
   require_once DRUPAL_ROOT . '/core/includes/schema.inc';
   require_once DRUPAL_ROOT . '/core/includes/entity.inc';
diff --git a/core/includes/token.inc b/core/includes/token.inc
deleted file mode 100644
index c1f1c6ca780641ecb0a9d533e961adcd33032f41..0000000000000000000000000000000000000000
--- a/core/includes/token.inc
+++ /dev/null
@@ -1,265 +0,0 @@
-<?php
-
-/**
- * @file
- * Drupal placeholder/token replacement system.
- *
- * API functions for replacing placeholders in text with meaningful values.
- *
- * For example: When configuring automated emails, an administrator enters
- * standard text for the email. Variables like the title of a node and the date
- * the email was sent can be entered as placeholders like [node:title] and
- * [date:short]. When a Drupal module prepares to send the email, it can call
- * the token_replace() function, passing in the text. The token system will
- * scan the text for placeholder tokens, give other modules an opportunity to
- * replace them with meaningful text, then return the final product to the
- * original module.
- *
- * Tokens follow the form: [$type:$name], where $type is a general class of
- * tokens like 'node', 'user', or 'comment' and $name is the name of a given
- * placeholder. For example, [node:title] or [node:created:since].
- *
- * In addition to raw text containing placeholders, modules may pass in an array
- * of objects to be used when performing the replacement. The objects should be
- * keyed by the token type they correspond to. For example:
- *
- * @code
- * // Load a node and a user, then replace tokens in the text.
- * $text = 'On [date:short], [user:name] read [node:title].';
- * $node = node_load(1);
- * $user = user_load(1);
- *
- * // [date:...] tokens use the current date automatically.
- * $data = array('node' => $node, 'user' => $user);
- * return token_replace($text, $data);
- * @endcode
- *
- * Some tokens may be chained in the form of [$type:$pointer:$name], where $type
- * is a normal token type, $pointer is a reference to another token type, and
- * $name is the name of a given placeholder. For example, [node:author:mail]. In
- * that example, 'author' is a pointer to the 'user' account that created the
- * node, and 'mail' is a placeholder available for any 'user'.
- *
- * @see token_replace()
- * @see hook_tokens()
- * @see hook_token_info()
- */
-
-/**
- * Replaces all tokens in a given string with appropriate values.
- *
- * @param string $text
- *   A string potentially containing replaceable tokens.
- * @param array $data
- *   (optional) An array of keyed objects. For simple replacement scenarios
- *   'node', 'user', and others are common keys, with an accompanying node or
- *   user object being the value. Some token types, like 'site', do not require
- *   any explicit information from $data and can be replaced even if it is
- *   empty.
- * @param array $options
- *   (optional) A keyed array of settings and flags to control the token
- *   replacement process. Supported options are:
- *   - langcode: A language code to be used when generating locale-sensitive
- *     tokens.
- *   - callback: A callback function that will be used to post-process the
- *     array of token replacements after they are generated. For example, a
- *     module using tokens in a text-only email might provide a callback to
- *     strip HTML entities from token values before they are inserted into the
- *     final text.
- *   - clear: A boolean flag indicating that tokens should be removed from the
- *     final text if no replacement value can be generated.
- *   - sanitize: A boolean flag indicating that tokens should be sanitized for
- *     display to a web browser. Defaults to TRUE. Developers who set this
- *     option to FALSE assume responsibility for running filter_xss(),
- *     check_plain() or other appropriate scrubbing functions before displaying
- *     data to users.
- *
- * @return string
- *   Text with tokens replaced.
- */
-function token_replace($text, array $data = array(), array $options = array()) {
-  $text_tokens = token_scan($text);
-  if (empty($text_tokens)) {
-    return $text;
-  }
-
-  $replacements = array();
-  foreach ($text_tokens as $type => $tokens) {
-    $replacements += token_generate($type, $tokens, $data, $options);
-    if (!empty($options['clear'])) {
-      $replacements += array_fill_keys($tokens, '');
-    }
-  }
-
-  // Optionally alter the list of replacement values.
-  if (!empty($options['callback'])) {
-    $function = $options['callback'];
-    $function($replacements, $data, $options);
-  }
-
-  $tokens = array_keys($replacements);
-  $values = array_values($replacements);
-
-  return str_replace($tokens, $values, $text);
-}
-
-/**
- * Builds a list of all token-like patterns that appear in the text.
- *
- * @param string $text
- *   The text to be scanned for possible tokens.
- *
- * @return array
- *   An associative array of discovered tokens, grouped by type.
- */
-function token_scan($text) {
-  // Matches tokens with the following pattern: [$type:$name]
-  // $type and $name may not contain [ ] characters.
-  // $type may not contain : or whitespace characters, but $name may.
-  preg_match_all('/
-    \[             # [ - pattern start
-    ([^\s\[\]:]*)  # match $type not containing whitespace : [ or ]
-    :              # : - separator
-    ([^\[\]]*)     # match $name not containing [ or ]
-    \]             # ] - pattern end
-    /x', $text, $matches);
-
-  $types = $matches[1];
-  $tokens = $matches[2];
-
-  // Iterate through the matches, building an associative array containing
-  // $tokens grouped by $types, pointing to the version of the token found in
-  // the source text. For example, $results['node']['title'] = '[node:title]';
-  $results = array();
-  for ($i = 0; $i < count($tokens); $i++) {
-    $results[$types[$i]][$tokens[$i]] = $matches[0][$i];
-  }
-
-  return $results;
-}
-
-/**
- * Generates replacement values for a list of tokens.
- *
- * @param string $type
- *   The type of token being replaced. 'node', 'user', and 'date' are common.
- * @param array $tokens
- *   An array of tokens to be replaced, keyed by the literal text of the token
- *   as it appeared in the source text.
- * @param array $data
- *   (optional) An array of keyed objects. For simple replacement scenarios
- *   'node', 'user', and others are common keys, with an accompanying node or
- *   user object being the value. Some token types, like 'site', do not require
- *   any explicit information from $data and can be replaced even if it is
- *   empty.
- * @param array $options
- *   (optional) A keyed array of settings and flags to control the token
- *   replacement process. Supported options are:
- *   - langcode: A language code to be used when generating locale-sensitive
- *     tokens.
- *   - callback: A callback function that will be used to post-process the
- *     array of token replacements after they are generated. Can be used when
- *     modules require special formatting of token text, for example URL
- *     encoding or truncation to a specific length.
- *   - sanitize: A boolean flag indicating that tokens should be sanitized for
- *     display to a web browser. Developers who set this option to FALSE assume
- *     responsibility for running filter_xss(), check_plain() or other
- *     appropriate scrubbing functions before displaying data to users.
- *
- * @return array
- *   An associative array of replacement values, keyed by the original 'raw'
- *   tokens that were found in the source text. For example:
- *   $results['[node:title]'] = 'My new node';
- *
- * @see hook_tokens()
- * @see hook_tokens_alter()
- */
-function token_generate($type, array $tokens, array $data = array(), array $options = array()) {
-  $options += array('sanitize' => TRUE);
-  $replacements = module_invoke_all('tokens', $type, $tokens, $data, $options);
-
-  // Allow other modules to alter the replacements.
-  $context = array(
-    'type' => $type,
-    'tokens' => $tokens,
-    'data' => $data,
-    'options' => $options,
-  );
-  drupal_alter('tokens', $replacements, $context);
-
-  return $replacements;
-}
-
-/**
- * Returns a list of tokens that begin with a specific prefix.
- *
- * Used to extract a group of 'chained' tokens (such as [node:author:name])
- * from the full list of tokens found in text. For example:
- * @code
- *   $data = array(
- *     'author:name' => '[node:author:name]',
- *     'title'       => '[node:title]',
- *     'created'     => '[node:created]',
- *   );
- *   $results = token_find_with_prefix($data, 'author');
- *   $results == array('name' => '[node:author:name]');
- * @endcode
- *
- * @param array $tokens
- *   A keyed array of tokens, and their original raw form in the source text.
- * @param string $prefix
- *   A textual string to be matched at the beginning of the token.
- * @param string $delimiter
- *   (optional) A string containing the character that separates the prefix from
- *   the rest of the token. Defaults to ':'.
- *
- * @return array
- *   An associative array of discovered tokens, with the prefix and delimiter
- *   stripped from the key.
- */
-function token_find_with_prefix(array $tokens, $prefix, $delimiter = ':') {
-  $results = array();
-  foreach ($tokens as $token => $raw) {
-    $parts = explode($delimiter, $token, 2);
-    if (count($parts) == 2 && $parts[0] == $prefix) {
-      $results[$parts[1]] = $raw;
-    }
-  }
-  return $results;
-}
-
-/**
- * Returns metadata describing supported tokens.
- *
- * The metadata array contains token type, name, and description data as well
- * as an optional pointer indicating that the token chains to another set of
- * tokens.
- *
- * For example:
- * @code
- *   $data['types']['node'] = array(
- *     'name' => t('Nodes'),
- *     'description' => t('Tokens related to node objects.'),
- *   );
- *   $data['tokens']['node']['title'] = array(
- *     'name' => t('Title'),
- *     'description' => t('The title of the current node.'),
- *   );
- *   $data['tokens']['node']['author'] = array(
- *     'name' => t('Author'),
- *     'description' => t('The author of the current node.'),
- *     'type' => 'user',
- *   );
- * @endcode
- *
- * @return array
- *   An associative array of token information, grouped by token type.
- */
-function token_info() {
-  $data = &drupal_static(__FUNCTION__);
-  if (!isset($data)) {
-    $data = module_invoke_all('token_info');
-    drupal_alter('token_info', $data);
-  }
-  return $data;
-}
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index c9ab39ddb763ec28ad0d89bc10d27d3b3811b096..9be666927de6c2681c29695ff10446b0e0b71941 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -341,4 +341,14 @@ public static function typedData() {
     return static::$container->get('typed_data');
   }
 
+  /**
+   * Returns the token service.
+   *
+   * @return \Drupal\Core\Utility\Token
+   *   The token service.
+   */
+  public static function token() {
+    return static::$container->get('token');
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Utility/Token.php b/core/lib/Drupal/Core/Utility/Token.php
new file mode 100644
index 0000000000000000000000000000000000000000..29fef78a91cbb902514be3ae3d9b3665ed1566ac
--- /dev/null
+++ b/core/lib/Drupal/Core/Utility/Token.php
@@ -0,0 +1,309 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\Core\Utility\Token.
+ */
+
+namespace Drupal\Core\Utility;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+
+/**
+ * Drupal placeholder/token replacement system.
+ *
+ * API functions for replacing placeholders in text with meaningful values.
+ *
+ * For example: When configuring automated emails, an administrator enters
+ * standard text for the email. Variables like the title of a node and the date
+ * the email was sent can be entered as placeholders like [node:title] and
+ * [date:short]. When a Drupal module prepares to send the email, it can call
+ * the Token::replace() function, passing in the text. The token system will
+ * scan the text for placeholder tokens, give other modules an opportunity to
+ * replace them with meaningful text, then return the final product to the
+ * original module.
+ *
+ * Tokens follow the form: [$type:$name], where $type is a general class of
+ * tokens like 'node', 'user', or 'comment' and $name is the name of a given
+ * placeholder. For example, [node:title] or [node:created:since].
+ *
+ * In addition to raw text containing placeholders, modules may pass in an array
+ * of objects to be used when performing the replacement. The objects should be
+ * keyed by the token type they correspond to. For example:
+ *
+ * @code
+ * // Load a node and a user, then replace tokens in the text.
+ * $text = 'On [date:short], [user:name] read [node:title].';
+ * $node = node_load(1);
+ * $user = user_load(1);
+ *
+ * // [date:...] tokens use the current date automatically.
+ * $data = array('node' => $node, 'user' => $user);
+ * return Token::replace($text, $data);
+ * @endcode
+ *
+ * Some tokens may be chained in the form of [$type:$pointer:$name], where $type
+ * is a normal token type, $pointer is a reference to another token type, and
+ * $name is the name of a given placeholder. For example, [node:author:mail]. In
+ * that example, 'author' is a pointer to the 'user' account that created the
+ * node, and 'mail' is a placeholder available for any 'user'.
+ *
+ * @see Token::replace()
+ * @see hook_tokens()
+ * @see hook_token_info()
+ */
+class Token {
+
+  /**
+   * Token definitions.
+   *
+   * @var array|null
+   *   An array of token definitions, or NULL when the definitions are not set.
+   *
+   * @see self::setInfo()
+   * @see self::getInfo()
+   * @see self::resetInfo()
+   */
+  protected $tokenInfo;
+
+  /**
+   * The module handler service.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructor.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * Replaces all tokens in a given string with appropriate values.
+   *
+   * @param string $text
+   *   A string potentially containing replaceable tokens.
+   * @param array $data
+   *   (optional) An array of keyed objects. For simple replacement scenarios
+   *   'node', 'user', and others are common keys, with an accompanying node or
+   *   user object being the value. Some token types, like 'site', do not require
+   *   any explicit information from $data and can be replaced even if it is
+   *   empty.
+   * @param array $options
+   *   (optional) A keyed array of settings and flags to control the token
+   *   replacement process. Supported options are:
+   *   - langcode: A language code to be used when generating locale-sensitive
+   *     tokens.
+   *   - callback: A callback function that will be used to post-process the
+   *     array of token replacements after they are generated. For example, a
+   *     module using tokens in a text-only email might provide a callback to
+   *     strip HTML entities from token values before they are inserted into the
+   *     final text.
+   *   - clear: A boolean flag indicating that tokens should be removed from the
+   *     final text if no replacement value can be generated.
+   *   - sanitize: A boolean flag indicating that tokens should be sanitized for
+   *     display to a web browser. Defaults to TRUE. Developers who set this
+   *     option to FALSE assume responsibility for running filter_xss(),
+   *     check_plain() or other appropriate scrubbing functions before displaying
+   *     data to users.
+   *
+   * @return string
+   *   Text with tokens replaced.
+   */
+  public function replace($text, array $data = array(), array $options = array()) {
+    $text_tokens = $this->scan($text);
+    if (empty($text_tokens)) {
+      return $text;
+    }
+
+    $replacements = array();
+    foreach ($text_tokens as $type => $tokens) {
+      $replacements += $this->generate($type, $tokens, $data, $options);
+      if (!empty($options['clear'])) {
+        $replacements += array_fill_keys($tokens, '');
+      }
+    }
+
+    // Optionally alter the list of replacement values.
+    if (!empty($options['callback'])) {
+      $function = $options['callback'];
+      $function($replacements, $data, $options);
+    }
+
+    $tokens = array_keys($replacements);
+    $values = array_values($replacements);
+
+    return str_replace($tokens, $values, $text);
+  }
+
+  /**
+   * Builds a list of all token-like patterns that appear in the text.
+   *
+   * @param string $text
+   *   The text to be scanned for possible tokens.
+   *
+   * @return array
+   *   An associative array of discovered tokens, grouped by type.
+   */
+  public function scan($text) {
+    // Matches tokens with the following pattern: [$type:$name]
+    // $type and $name may not contain [ ] characters.
+    // $type may not contain : or whitespace characters, but $name may.
+    preg_match_all('/
+      \[             # [ - pattern start
+      ([^\s\[\]:]*)  # match $type not containing whitespace : [ or ]
+      :              # : - separator
+      ([^\[\]]*)     # match $name not containing [ or ]
+      \]             # ] - pattern end
+      /x', $text, $matches);
+
+    $types = $matches[1];
+    $tokens = $matches[2];
+
+    // Iterate through the matches, building an associative array containing
+    // $tokens grouped by $types, pointing to the version of the token found in
+    // the source text. For example, $results['node']['title'] = '[node:title]';
+    $results = array();
+    for ($i = 0; $i < count($tokens); $i++) {
+      $results[$types[$i]][$tokens[$i]] = $matches[0][$i];
+    }
+
+    return $results;
+  }
+
+  /**
+   * Generates replacement values for a list of tokens.
+   *
+   * @param string $type
+   *   The type of token being replaced. 'node', 'user', and 'date' are common.
+   * @param array $tokens
+   *   An array of tokens to be replaced, keyed by the literal text of the token
+   *   as it appeared in the source text.
+   * @param array $data
+   *   (optional) An array of keyed objects. For simple replacement scenarios
+   *   'node', 'user', and others are common keys, with an accompanying node or
+   *   user object being the value. Some token types, like 'site', do not require
+   *   any explicit information from $data and can be replaced even if it is
+   *   empty.
+   * @param array $options
+   *   (optional) A keyed array of settings and flags to control the token
+   *   replacement process. Supported options are:
+   *   - langcode: A language code to be used when generating locale-sensitive
+   *     tokens.
+   *   - callback: A callback function that will be used to post-process the
+   *     array of token replacements after they are generated. Can be used when
+   *     modules require special formatting of token text, for example URL
+   *     encoding or truncation to a specific length.
+   *   - sanitize: A boolean flag indicating that tokens should be sanitized for
+   *     display to a web browser. Developers who set this option to FALSE assume
+   *     responsibility for running filter_xss(), check_plain() or other
+   *     appropriate scrubbing functions before displaying data to users.
+   *
+   * @return array
+   *   An associative array of replacement values, keyed by the original 'raw'
+   *   tokens that were found in the source text. For example:
+   *   $results['[node:title]'] = 'My new node';
+   *
+   * @see hook_tokens()
+   * @see hook_tokens_alter()
+   */
+  public function generate($type, array $tokens, array $data = array(), array $options = array()) {
+    $options += array('sanitize' => TRUE);
+    $replacements = $this->moduleHandler->invokeAll('tokens', array($type, $tokens, $data, $options));
+
+    // Allow other modules to alter the replacements.
+    $context = array(
+      'type' => $type,
+      'tokens' => $tokens,
+      'data' => $data,
+      'options' => $options,
+    );
+    $this->moduleHandler->alter('tokens', $replacements, $context);
+
+    return $replacements;
+  }
+
+  /**
+   * Returns a list of tokens that begin with a specific prefix.
+   *
+   * Used to extract a group of 'chained' tokens (such as [node:author:name])
+   * from the full list of tokens found in text. For example:
+   * @code
+   *   $data = array(
+   *     'author:name' => '[node:author:name]',
+   *     'title'       => '[node:title]',
+   *     'created'     => '[node:created]',
+   *   );
+   *   $results = Token::findWithPrefix($data, 'author');
+   *   $results == array('name' => '[node:author:name]');
+   * @endcode
+   *
+   * @param array $tokens
+   *   A keyed array of tokens, and their original raw form in the source text.
+   * @param string $prefix
+   *   A textual string to be matched at the beginning of the token.
+   * @param string $delimiter
+   *   (optional) A string containing the character that separates the prefix from
+   *   the rest of the token. Defaults to ':'.
+   *
+   * @return array
+   *   An associative array of discovered tokens, with the prefix and delimiter
+   *   stripped from the key.
+   */
+  public function findWithPrefix(array $tokens, $prefix, $delimiter = ':') {
+    $results = array();
+    foreach ($tokens as $token => $raw) {
+      $parts = explode($delimiter, $token, 2);
+      if (count($parts) == 2 && $parts[0] == $prefix) {
+        $results[$parts[1]] = $raw;
+      }
+    }
+    return $results;
+  }
+
+  /**
+   * Returns metadata describing supported tokens.
+   *
+   * The metadata array contains token type, name, and description data as well
+   * as an optional pointer indicating that the token chains to another set of
+   * tokens.
+   *
+   * @return array
+   *   An associative array of token information, grouped by token type. The
+   *   array structure is identical to that of hook_token_info().
+   *
+   * @see hook_token_info()
+   */
+  public function getInfo() {
+    if (is_null($this->tokenInfo)) {
+      $this->tokenInfo = $this->moduleHandler->invokeAll('token_info');
+      $this->moduleHandler->alter('token_info', $this->tokenInfo);
+    }
+
+    return $this->tokenInfo;
+  }
+
+  /**
+   * Sets metadata describing supported tokens.
+   *
+   * @param array $tokens
+   *   Token metadata that has an identical structure to the return value of
+   *   hook_token_info().
+   *
+   * @see hook_token_info()
+   */
+  public function setInfo(array $tokens) {
+    $this->tokenInfo = $tokens;
+  }
+
+  /**
+   * Resets metadata describing supported tokens.
+   */
+  public function resetInfo() {
+    $this->tokenInfo = NULL;
+  }
+}
diff --git a/core/modules/action/action.module b/core/modules/action/action.module
index a4e259f2115888bff4bdfca6dd71485468dfa7cd..7ff568b0bb3d05d47205cec747a5cfe624af7719 100644
--- a/core/modules/action/action.module
+++ b/core/modules/action/action.module
@@ -564,11 +564,11 @@ function action_send_email_action_submit($form, $form_state) {
  * @param array $context
  *   Array with the following elements:
  *   - 'recipient': E-mail message recipient. This will be passed through
- *     token_replace().
+ *     \Drupal\Core\Utility\Token::replace().
  *   - 'subject': The subject of the message. This will be passed through
- *     token_replace().
+ *     \Drupal\Core\Utility\Token::replace().
  *   - 'message': The message to send. This will be passed through
- *     token_replace().
+ *     \Drupal\Core\Utility\Token::replace().
  *   - Other elements will be used as the data for token replacement.
  *
  * @ingroup actions
@@ -578,7 +578,7 @@ function action_send_email_action($entity, $context) {
     $context['node'] = $entity;
   }
 
-  $recipient = token_replace($context['recipient'], $context);
+  $recipient = Drupal::token()->replace($context['recipient'], $context);
 
   // If the recipient is a registered user with a language preference, use
   // the recipient's preferred language. Otherwise, use the system default
@@ -633,7 +633,7 @@ function action_message_action_submit($form, $form_state) {
  * @param array $context
  *   Array with the following elements:
  *   - 'message': The message to send. This will be passed through
- *     token_replace().
+ *     \Drupal\Core\Utility\Token::replace().
  *   - Other elements will be used as the data for token replacement in
  *     the message.
  *
@@ -644,7 +644,7 @@ function action_message_action(&$entity, $context = array()) {
     $context['node'] = $entity;
   }
 
-  $context['message'] = token_replace(filter_xss_admin($context['message']), $context);
+  $context['message'] = Drupal::token()->replace(filter_xss_admin($context['message']), $context);
   drupal_set_message($context['message']);
 }
 
@@ -685,11 +685,11 @@ function action_goto_action_submit($form, $form_state) {
  * @param array $context
  *   Array with the following elements:
  *   - 'url': URL to redirect to. This will be passed through
- *     token_replace().
+ *     \Drupal\Core\Utility\Token::replace().
  *   - Other elements will be used as the data for token replacement.
  *
  * @ingroup actions.
  */
 function action_goto_action($entity, $context) {
-  drupal_goto(token_replace($context['url'], $context));
+  drupal_goto(Drupal::token()->replace($context['url'], $context));
 }
diff --git a/core/modules/comment/comment.tokens.inc b/core/modules/comment/comment.tokens.inc
index 715b63d104075d22123f8272639464bfd433efcd..d938c27b6e61e827474fd7c5e220d4d0402caf84 100644
--- a/core/modules/comment/comment.tokens.inc
+++ b/core/modules/comment/comment.tokens.inc
@@ -103,6 +103,8 @@ function comment_token_info() {
  * Implements hook_tokens().
  */
 function comment_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   if (isset($options['langcode'])) {
     $url_options['language'] = language_load($options['langcode']);
@@ -198,25 +200,25 @@ function comment_tokens($type, $tokens, array $data = array(), array $options =
     }
 
     // Chained token relationships.
-    if ($node_tokens = token_find_with_prefix($tokens, 'node')) {
+    if ($node_tokens = $token_service->findwithPrefix($tokens, 'node')) {
       $node = $comment->nid->entity;
-      $replacements += token_generate('node', $node_tokens, array('node' => $node), $options);
+      $replacements += $token_service->generate('node', $node_tokens, array('node' => $node), $options);
     }
 
-    if ($date_tokens = token_find_with_prefix($tokens, 'created')) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $comment->created->value), $options);
+    if ($date_tokens = $token_service->findwithPrefix($tokens, 'created')) {
+      $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->created->value), $options);
     }
 
-    if ($date_tokens = token_find_with_prefix($tokens, 'changed')) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $comment->changed->value), $options);
+    if ($date_tokens = $token_service->findwithPrefix($tokens, 'changed')) {
+      $replacements += $token_service->generate('date', $date_tokens, array('date' => $comment->changed->value), $options);
     }
 
-    if (($parent_tokens = token_find_with_prefix($tokens, 'parent')) && $parent = $comment->pid->entity) {
-      $replacements += token_generate('comment', $parent_tokens, array('comment' => $parent), $options);
+    if (($parent_tokens = $token_service->findwithPrefix($tokens, 'parent')) && $parent = $comment->pid->entity) {
+      $replacements += $token_service->generate('comment', $parent_tokens, array('comment' => $parent), $options);
     }
 
-    if (($author_tokens = token_find_with_prefix($tokens, 'author')) && $account = $comment->uid->entity) {
-      $replacements += token_generate('user', $author_tokens, array('user' => $account), $options);
+    if (($author_tokens = $token_service->findwithPrefix($tokens, 'author')) && $account = $comment->uid->entity) {
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $account), $options);
     }
   }
   elseif ($type == 'node' & !empty($data['node'])) {
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
index 6bcc9923206300f4e7b1438b612897d3ece1760a..92be58f3a921ae9247a0b24734beee45a9ece3ff 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentTokenReplaceTest.php
@@ -23,6 +23,7 @@ public static function getInfo() {
    * Creates a comment, then tests the tokens generated from it.
    */
   function testCommentTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
     $url_options = array(
       'absolute' => TRUE,
@@ -72,7 +73,7 @@ function testCommentTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized comment token %token replaced.', array('%token' => $input)));
     }
 
@@ -88,7 +89,7 @@ function testCommentTokenReplacement() {
     $tests['[comment:author:name]'] = $this->admin_user->name;
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('comment' => $comment), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized comment token %token replaced.', array('%token' => $input)));
     }
 
@@ -101,7 +102,7 @@ function testCommentTokenReplacement() {
     $tests['[node:comment-count-new]'] = 2;
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Node comment token %token replaced.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
index ac6582eb38dd26437a9384b3d649e17bb31421f4..64c83a2d303691bdbba86ee04a5ffd34cf66c076 100644
--- a/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
+++ b/core/modules/field/lib/Drupal/field/Plugin/Type/Widget/WidgetBase.php
@@ -105,7 +105,7 @@ public function form(EntityInterface $entity, $langcode, array $items, array &$f
       $delta = isset($get_delta) ? $get_delta : 0;
       $element = array(
         '#title' => check_plain($instance['label']),
-        '#description' => field_filter_xss(token_replace($instance['description'])),
+        '#description' => field_filter_xss(\Drupal::token()->replace($instance['description'])),
       );
       $element = $this->formSingleElement($entity, $items, $delta, $langcode, $element, $form, $form_state);
 
@@ -196,7 +196,7 @@ protected function formMultipleElements(EntityInterface $entity, array $items, $
     $wrapper_id = drupal_html_id($id_prefix . '-add-more-wrapper');
 
     $title = check_plain($instance['label']);
-    $description = field_filter_xss(token_replace($instance['description']));
+    $description = field_filter_xss(\Drupal::token()->replace($instance['description']));
 
     $elements = array();
 
diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc
index e3a7d7ce38469b0b1619f3d22eccf39088618c5e..f3f2c0a5db6d1edf60b4e8db314448ce9ef4307e 100644
--- a/core/modules/file/file.field.inc
+++ b/core/modules/file/file.field.inc
@@ -352,18 +352,19 @@ function file_field_widget_upload_validators($field, $instance) {
  * @param $instance
  *   A field instance array.
  * @param $data
- *   An array of token objects to pass to token_replace().
+ *   An array of token objects to pass to
+ *   \Drupal\Core\Utility\Token::replace().
  *
  * @return
  *   A file directory URI with tokens replaced.
  *
- * @see token_replace()
+ * @see \Drupal\Core\Utility\Token::replace()
  */
 function file_field_widget_uri($field, $instance, $data = array()) {
   $destination = trim($instance['settings']['file_directory'], '/');
 
   // Replace tokens.
-  $destination = token_replace($destination, $data);
+  $destination = Drupal::token()->replace($destination, $data);
 
   return $field['settings']['uri_scheme'] . '://' . $destination;
 }
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
index d963b8918f0de1ee61ec0a08e841a5587cf976b4..c8612080c3208352197d08d663f5cc4c7638094e 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileFieldPathTest.php
@@ -60,7 +60,7 @@ function testUploadPath() {
     // Do token replacement using the same user which uploaded the file, not
     // the user running the test case.
     $data = array('user' => $this->admin_user);
-    $subdirectory = token_replace('[user:uid]/[user:name]', $data);
+    $subdirectory = \Drupal::token()->replace('[user:uid]/[user:name]', $data);
     $this->assertPathMatch('public://' . $subdirectory . '/' . $test_file->filename, $node_file->uri, t('The file %file was uploaded to the correct path with token replacements.', array('%file' => $node_file->uri)));
   }
 
diff --git a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
index 4d56b7b0814bda30d369b50e09797cf56a9e6763..36b32b16445184c53524e23bbb3ae2fc8a4f4245 100644
--- a/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
+++ b/core/modules/file/lib/Drupal/file/Tests/FileTokenReplaceTest.php
@@ -23,6 +23,7 @@ public static function getInfo() {
    * Creates a file, then tests the tokens generated from it.
    */
   function testFileTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
     $url_options = array(
       'absolute' => TRUE,
@@ -65,7 +66,7 @@ function testFileTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), t('No empty tokens generated.'));
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('file' => $file), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, t('Sanitized file token %token replaced.', array('%token' => $input)));
     }
 
@@ -76,7 +77,7 @@ function testFileTokenReplacement() {
     $tests['[file:size]'] = format_size($file->filesize);
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('file' => $file), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('file' => $file), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, t('Unsanitized file token %token replaced.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/link/link.module b/core/modules/link/link.module
index 064ad913358021f7bbcdb586e8f9a879b2dbd285..82824213e529ea0e445c6ac9456ea50abea539c1 100644
--- a/core/modules/link/link.module
+++ b/core/modules/link/link.module
@@ -362,7 +362,7 @@ function link_field_formatter_view(EntityInterface $entity, $field, $instance, $
     if (empty($settings['url_only']) && !empty($item['title'])) {
       // Unsanitizied token replacement here because $options['html'] is FALSE
       // by default in theme_link().
-      $link_title = token_replace($item['title'], array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
+      $link_title = Drupal::token()->replace($item['title'], array($entity->entityType() => $entity), array('sanitize' => FALSE, 'clear' => TRUE));
     }
 
     // Trim the link title to the desired length.
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
index d17de34eff62f15dd9842695bbd541029ee086b7..7a9e5f0762ac6f8e3e3be20c34ffc4952b8f9333 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTokenReplaceTest.php
@@ -23,6 +23,7 @@ public static function getInfo() {
    * Creates a node, then tests the tokens generated from it.
    */
   function testNodeTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
     $url_options = array(
       'absolute' => TRUE,
@@ -66,7 +67,7 @@ function testNodeTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized node token %token replaced.', array('%token' => $input)));
     }
 
@@ -78,7 +79,7 @@ function testNodeTokenReplacement() {
     $tests['[node:author:name]'] = user_format_name($account);
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized node token %token replaced.', array('%token' => $input)));
     }
 
@@ -99,7 +100,7 @@ function testNodeTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated for node without a summary.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('language' => $language_interface));
+      $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface));
       $this->assertEqual($output, $expected, format_string('Sanitized node token %token replaced for node without a summary.', array('%token' => $input)));
     }
 
@@ -107,7 +108,7 @@ function testNodeTokenReplacement() {
     $tests['[node:summary]'] = $node->body[$node->langcode][0]['value'];
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('node' => $node), array('language' => $language_interface, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized node token %token replaced for node without a summary.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/node/node.tokens.inc b/core/modules/node/node.tokens.inc
index c882450217afc71b2fcee950cec63ae3d8735c1c..d1c921130f49320e66f2e8986c63e4b5847ea41e 100644
--- a/core/modules/node/node.tokens.inc
+++ b/core/modules/node/node.tokens.inc
@@ -90,6 +90,8 @@ function node_token_info() {
  * Implements hook_tokens().
  */
 function node_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   if (isset($options['langcode'])) {
     $url_options['language'] = language_load($options['langcode']);
@@ -197,17 +199,17 @@ function node_tokens($type, $tokens, array $data = array(), array $options = arr
       }
     }
 
-    if ($author_tokens = token_find_with_prefix($tokens, 'author')) {
+    if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
       $author = user_load($node->uid);
-      $replacements += token_generate('user', $author_tokens, array('user' => $author), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options);
     }
 
-    if ($created_tokens = token_find_with_prefix($tokens, 'created')) {
-      $replacements += token_generate('date', $created_tokens, array('date' => $node->created), $options);
+    if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
+      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options);
     }
 
-    if ($changed_tokens = token_find_with_prefix($tokens, 'changed')) {
-      $replacements += token_generate('date', $changed_tokens, array('date' => $node->changed), $options);
+    if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) {
+      $replacements += $token_service->generate('date', $changed_tokens, array('date' => $node->changed), $options);
     }
   }
 
diff --git a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php
index fad28078df7d38b4961732795e1c7c7c669e8406..0a657468a18b9cdf7a982e12a75114c91c7e43be 100644
--- a/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php
+++ b/core/modules/statistics/lib/Drupal/statistics/Tests/StatisticsTokenReplaceTest.php
@@ -54,7 +54,7 @@ function testStatisticsTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
+      $output = \Drupal::token()->replace($input, array('node' => $node), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Statistics token %token replaced.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/statistics/statistics.tokens.inc b/core/modules/statistics/statistics.tokens.inc
index c2c8fc3cbc506a778b07425b6f6b9d50ceb379d9..27f628e50c69ed44019f36d3156feb8be96bd43d 100644
--- a/core/modules/statistics/statistics.tokens.inc
+++ b/core/modules/statistics/statistics.tokens.inc
@@ -32,6 +32,8 @@ function statistics_token_info() {
  * Implements hook_tokens().
  */
 function statistics_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   $replacements = array();
 
@@ -53,9 +55,9 @@ function statistics_tokens($type, $tokens, array $data = array(), array $options
       }
     }
 
-    if ($created_tokens = token_find_with_prefix($tokens, 'last-view')) {
+    if ($created_tokens = $token_service->findWithPrefix($tokens, 'last-view')) {
       $statistics = statistics_get($node->nid);
-      $replacements += token_generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options);
+      $replacements += $token_service->generate('date', $created_tokens, array('date' => $statistics['timestamp']), $options);
     }
   }
 
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
index 3859041980114b863f3ff92521b7c082ea5daf3d..e869c7108605806934cb26e5950a2a8f12bdc520 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/TokenReplaceTest.php
@@ -25,6 +25,8 @@ public static function getInfo() {
    * Creates a user and a node, then tests the tokens generated from them.
    */
   function testTokenReplacement() {
+    $token_service = \Drupal::token();
+
     // Create the initial objects.
     $account = $this->drupalCreateUser();
     $node = $this->drupalCreateNode(array('uid' => $account->uid));
@@ -47,34 +49,35 @@ function testTokenReplacement() {
     $target .= format_date(REQUEST_TIME, 'short', '', NULL, $language_interface->langcode);
 
     // Test that the clear parameter cleans out non-existent tokens.
-    $result = token_replace($source, array('node' => $node), array('langcode' => $language_interface->langcode, 'clear' => TRUE));
+    $result = $token_service->replace($source, array('node' => $node), array('langcode' => $language_interface->langcode, 'clear' => TRUE));
     $result = $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens cleared out.');
 
     // Test without using the clear parameter (non-existent token untouched).
     $target .= '[user:name]';
     $target .= '[bogus:token]';
-    $result = token_replace($source, array('node' => $node), array('langcode' => $language_interface->langcode));
+    $result = $token_service->replace($source, array('node' => $node), array('langcode' => $language_interface->langcode));
     $this->assertEqual($target, $result, 'Valid tokens replaced while invalid tokens ignored.');
 
-    // Check that the results of token_generate are sanitized properly. This does NOT
-    // test the cleanliness of every token -- just that the $sanitize flag is being
-    // passed properly through the call stack and being handled correctly by a 'known'
-    // token, [node:title].
+    // Check that the results of Token::generate are sanitized properly. This
+    // does NOT test the cleanliness of every token -- just that the $sanitize
+    // flag is being passed properly through the call stack and being handled
+    // correctly by a 'known' token, [node:title].
     $raw_tokens = array('title' => '[node:title]');
-    $generated = token_generate('node', $raw_tokens, array('node' => $node));
+    $generated = $token_service->generate('node', $raw_tokens, array('node' => $node));
     $this->assertEqual($generated['[node:title]'], check_plain($node->title), 'Token sanitized.');
 
-    $generated = token_generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
+    $generated = $token_service->generate('node', $raw_tokens, array('node' => $node), array('sanitize' => FALSE));
     $this->assertEqual($generated['[node:title]'], $node->title, 'Unsanitized token generated properly.');
 
     // Test token replacement when the string contains no tokens.
-    $this->assertEqual(token_replace('No tokens here.'), 'No tokens here.');
+    $this->assertEqual($token_service->replace('No tokens here.'), 'No tokens here.');
   }
 
   /**
    * Test whether token-replacement works in various contexts.
    */
   function testSystemTokenRecognition() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
 
     // Generate prefixes and suffixes for the token context.
@@ -95,7 +98,7 @@ function testSystemTokenRecognition() {
     foreach ($tests as $test) {
       $input = $test['prefix'] . '[site:name]' . $test['suffix'];
       $expected = $test['prefix'] . 'Drupal' . $test['suffix'];
-      $output = token_replace($input, array(), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode));
       $this->assertTrue($output == $expected, format_string('Token recognized in string %string', array('%string' => $input)));
     }
   }
@@ -104,6 +107,7 @@ function testSystemTokenRecognition() {
    * Tests the generation of all system site information tokens.
    */
   function testSystemSiteTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
     $url_options = array(
       'absolute' => TRUE,
@@ -129,7 +133,7 @@ function testSystemSiteTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array(), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized system site information token %token replaced.', array('%token' => $input)));
     }
 
@@ -138,7 +142,7 @@ function testSystemSiteTokenReplacement() {
     $tests['[site:slogan]'] = config('system.site')->get('slogan');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array(), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array(), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized system site information token %token replaced.', array('%token' => $input)));
     }
   }
@@ -147,6 +151,7 @@ function testSystemSiteTokenReplacement() {
    * Tests the generation of all system date tokens.
    */
   function testSystemDateTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
 
     // Set time to one hour before request.
@@ -165,7 +170,7 @@ function testSystemDateTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('date' => $date), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('date' => $date), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Date token %token replaced.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php b/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php
index fffe6ae73af552fd68a9095f7683be1500669a9f..ce29a08623773573bbb1c149e4a3800e7c73918d 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/TokenScanTest.php
@@ -31,7 +31,7 @@ function testTokenScan() {
     $text = 'First a [valid:simple], but dummy token, and a dummy [valid:token with: spaces].';
     $text .= 'Then a [not valid:token].';
     $text .= 'Last an existing token: [node:author:name].';
-    $token_wannabes = token_scan($text);
+    $token_wannabes = \Drupal::token()->scan($text);
 
     $this->assertTrue(isset($token_wannabes['valid']['simple']), 'A simple valid token has been matched.');
     $this->assertTrue(isset($token_wannabes['valid']['token with: spaces']), 'A valid token with space characters in the token name has been matched.');
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 13aa535ad89c47141323f6c84857568ce24cca3b..73ec88e7f64084e1daf775ca9fc225658e9351da 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -3166,11 +3166,12 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) {
 /**
  * Provide replacement values for placeholder tokens.
  *
- * This hook is invoked when someone calls token_replace(). That function first
- * scans the text for [type:token] patterns, and splits the needed tokens into
- * groups by type. Then hook_tokens() is invoked on each token-type group,
- * allowing your module to respond by providing replacement text for any of
- * the tokens in the group that your module knows how to process.
+ * This hook is invoked when someone calls
+ * \Drupal\Core\Utility\Token::replace(). That function first scans the text for
+ * [type:token] patterns, and splits the needed tokens into groups by type.
+ * Then hook_tokens() is invoked on each token-type group, allowing your module
+ * to respond by providing replacement text for any of the tokens in the group
+ * that your module knows how to process.
  *
  * A module implementing this hook should also implement hook_token_info() in
  * order to list its available tokens on editing screens.
@@ -3185,10 +3186,11 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) {
  *   original text.
  * @param $data
  *   (optional) An associative array of data objects to be used when generating
- *   replacement values, as supplied in the $data parameter to token_replace().
+ *   replacement values, as supplied in the $data parameter to
+ *   \Drupal\Core\Utility\Token::replace().
  * @param $options
  *   (optional) An associative array of options for token replacement; see
- *   token_replace() for possible values.
+ *   \Drupal\Core\Utility\Token::replace() for possible values.
  *
  * @return
  *   An associative array of replacement values, keyed by the raw [type:token]
@@ -3198,6 +3200,8 @@ function hook_url_outbound_alter(&$path, &$options, $original_path) {
  * @see hook_tokens_alter()
  */
 function hook_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   if (isset($options['langcode'])) {
     $url_options['language'] = language_load($options['langcode']);
@@ -3240,13 +3244,13 @@ function hook_tokens($type, $tokens, array $data = array(), array $options = arr
       }
     }
 
-    if ($author_tokens = token_find_with_prefix($tokens, 'author')) {
+    if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
       $author = user_load($node->uid);
-      $replacements += token_generate('user', $author_tokens, array('user' => $author), $options);
+      $replacements += $token_service->generate('user', $author_tokens, array('user' => $author), $options);
     }
 
-    if ($created_tokens = token_find_with_prefix($tokens, 'created')) {
-      $replacements += token_generate('date', $created_tokens, array('date' => $node->created), $options);
+    if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
+      $replacements += $token_service->generate('date', $created_tokens, array('date' => $node->created), $options);
     }
   }
 
@@ -3302,9 +3306,10 @@ function hook_tokens_alter(array &$replacements, array $context) {
  * provides a list of types and tokens to be displayed on text editing screens,
  * so that people editing text can see what their token options are.
  *
- * The actual token replacement is done by token_replace(), which invokes
- * hook_tokens(). Your module will need to implement that hook in order to
- * generate token replacements from the tokens defined here.
+ * The actual token replacement is done by
+ * \Drupal\Core\Utility\Token::replace(), which invokes hook_tokens(). Your
+ * module will need to implement that hook in order to generate token
+ * replacements from the tokens defined here.
  *
  * @return
  *   An associative array of available tokens and token types. The outer array
@@ -3313,12 +3318,13 @@ function hook_tokens_alter(array &$replacements, array $context) {
  *     an associative array with the following components:
  *     - name: The translated human-readable short name of the token type.
  *     - description: A translated longer description of the token type.
- *     - needs-data: The type of data that must be provided to token_replace()
- *       in the $data argument (i.e., the key name in $data) in order for tokens
- *       of this type to be used in the $text being processed. For instance, if
- *       the token needs a node object, 'needs-data' should be 'node', and to
- *       use this token in token_replace(), the caller needs to supply a node
- *       object as $data['node']. Some token data can also be supplied
+ *     - needs-data: The type of data that must be provided to
+ *       \Drupal\Core\Utility\Token::replace() in the $data argument (i.e., the
+ *       key name in $data) in order for tokens of this type to be used in the
+ *       $text being processed. For instance, if the token needs a node object,
+ *       'needs-data' should be 'node', and to use this token in
+ *       \Drupal\Core\Utility\Token::replace(), the caller needs to supply a
+ *       node object as $data['node']. Some token data can also be supplied
  *       indirectly; for instance, a node object in $data supplies a user object
  *       (the author of the node), allowing user tokens to be used when only
  *       a node data object is supplied.
@@ -3331,8 +3337,8 @@ function hook_tokens_alter(array &$replacements, array $context) {
  *     - type (optional): A 'needs-data' data type supplied by this token, which
  *       should match a 'needs-data' value from another token type. For example,
  *       the node author token provides a user object, which can then be used
- *       for token replacement data in token_replace() without having to supply
- *       a separate user object.
+ *       for token replacement data in \Drupal\Core\Utility\Token::replace()
+ *       without having to supply a separate user object.
  *
  * @see hook_token_info_alter()
  * @see hook_tokens()
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index ebe55483f238ec71bd4466098c48b7f92439f1f7..3b1205a0561431ea963c8bb445ab00cf84bdc13f 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -3591,10 +3591,12 @@ function system_cron() {
  * Implements hook_mail().
  */
 function system_mail($key, &$message, $params) {
+  $token_service = Drupal::token();
+
   $context = $params['context'];
 
-  $subject = token_replace($context['subject'], $context);
-  $body = token_replace($context['message'], $context);
+  $subject = $token_service->replace($context['subject'], $context);
+  $body = $token_service->replace($context['message'], $context);
 
   $message['subject'] .= str_replace(array("\r", "\n"), '', $subject);
   $message['body'][] = $body;
diff --git a/core/modules/system/system.tokens.inc b/core/modules/system/system.tokens.inc
index a5e7ad2d77ac90cd1ac2fc30cfa606843947eb52..241ed54d3ba819b38167e58978c7e5bdd0b78565 100644
--- a/core/modules/system/system.tokens.inc
+++ b/core/modules/system/system.tokens.inc
@@ -129,6 +129,8 @@ function system_token_info() {
  * Implements hook_tokens().
  */
 function system_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   if (isset($options['langcode'])) {
     $url_options['language'] = language_load($options['langcode']);
@@ -205,7 +207,7 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a
       }
     }
 
-    if ($created_tokens = token_find_with_prefix($tokens, 'custom')) {
+    if ($created_tokens = $token_service->findWithPrefix($tokens, 'custom')) {
       foreach ($created_tokens as $name => $original) {
         $replacements[$original] = format_date($date, 'custom', $name, NULL, $langcode);
       }
@@ -256,12 +258,12 @@ function system_tokens($type, $tokens, array $data = array(), array $options = a
       }
     }
 
-    if ($date_tokens = token_find_with_prefix($tokens, 'timestamp')) {
-      $replacements += token_generate('date', $date_tokens, array('date' => $file->timestamp), $options);
+    if ($date_tokens = $token_service->findWithPrefix($tokens, 'timestamp')) {
+      $replacements += $token_service->generate('date', $date_tokens, array('date' => $file->timestamp), $options);
     }
 
-    if (($owner_tokens = token_find_with_prefix($tokens, 'owner')) && $account = user_load($file->uid)) {
-      $replacements += token_generate('user', $owner_tokens, array('user' => $account), $options);
+    if (($owner_tokens = $token_service->findWithPrefix($tokens, 'owner')) && $account = user_load($file->uid)) {
+      $replacements += $token_service->generate('user', $owner_tokens, array('user' => $account), $options);
     }
   }
 
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
index ea731520132b6952beaae7093fe3505f9850337d..a792aad913d27986d049dd3f5b7c6adf7c15d3d4 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TokenReplaceTest.php
@@ -62,6 +62,7 @@ function setUp() {
    * Creates some terms and a node, then tests the tokens generated from them.
    */
   function testTaxonomyTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
 
     // Create two taxonomy terms.
@@ -91,7 +92,7 @@ function testTaxonomyTokenReplacement() {
     $tests['[term:vocabulary:name]'] = check_plain($this->vocabulary->name);
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('term' => $term1), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('term' => $term1), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input)));
     }
 
@@ -111,7 +112,7 @@ function testTaxonomyTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy term token %token replaced.', array('%token' => $input)));
     }
 
@@ -122,7 +123,7 @@ function testTaxonomyTokenReplacement() {
     $tests['[term:vocabulary:name]'] = $this->vocabulary->name;
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('term' => $term2), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy term token %token replaced.', array('%token' => $input)));
     }
 
@@ -138,7 +139,7 @@ function testTaxonomyTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized taxonomy vocabulary token %token replaced.', array('%token' => $input)));
     }
 
@@ -147,7 +148,7 @@ function testTaxonomyTokenReplacement() {
     $tests['[vocabulary:description]'] = $this->vocabulary->description;
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('vocabulary' => $this->vocabulary), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized taxonomy vocabulary token %token replaced.', array('%token' => $input)));
     }
   }
diff --git a/core/modules/taxonomy/taxonomy.tokens.inc b/core/modules/taxonomy/taxonomy.tokens.inc
index 34099cebe29b12a9808429248a0207815b2110b5..00819f6c798b1314f115017df14fa0749625a5d1 100644
--- a/core/modules/taxonomy/taxonomy.tokens.inc
+++ b/core/modules/taxonomy/taxonomy.tokens.inc
@@ -89,6 +89,8 @@ function taxonomy_token_info() {
  * Implements hook_tokens().
  */
 function taxonomy_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $replacements = array();
   $sanitize = !empty($options['sanitize']);
 
@@ -136,14 +138,14 @@ function taxonomy_tokens($type, $tokens, array $data = array(), array $options =
       }
     }
 
-    if ($vocabulary_tokens = token_find_with_prefix($tokens, 'vocabulary')) {
+    if ($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'vocabulary')) {
       $vocabulary = taxonomy_vocabulary_load($term->bundle());
-      $replacements += token_generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options);
+      $replacements += $token_service->generate('vocabulary', $vocabulary_tokens, array('vocabulary' => $vocabulary), $options);
     }
 
-    if (($vocabulary_tokens = token_find_with_prefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->tid)) {
+    if (($vocabulary_tokens = $token_service->findWithPrefix($tokens, 'parent')) && $parents = taxonomy_term_load_parents($term->tid)) {
       $parent = array_pop($parents);
-      $replacements += token_generate('term', $vocabulary_tokens, array('term' => $parent), $options);
+      $replacements += $token_service->generate('term', $vocabulary_tokens, array('term' => $parent), $options);
     }
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php
index d14e8267051a8397b095b120628e2e7b7c17d0be..e7fbec78e665675ba0268c1cd59ae5a938a7e9d7 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserTokenReplaceTest.php
@@ -42,6 +42,7 @@ public function setUp() {
    * Creates a user, then tests the tokens generated from it.
    */
   function testUserTokenReplacement() {
+    $token_service = \Drupal::token();
     $language_interface = language(LANGUAGE_TYPE_INTERFACE);
     $url_options = array(
       'absolute' => TRUE,
@@ -75,7 +76,7 @@ function testUserTokenReplacement() {
     $this->assertFalse(in_array(0, array_map('strlen', $tests)), 'No empty tokens generated.');
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode));
+      $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode));
       $this->assertEqual($output, $expected, format_string('Sanitized user token %token replaced.', array('%token' => $input)));
     }
 
@@ -85,7 +86,7 @@ function testUserTokenReplacement() {
     $tests['[current-user:name]'] = user_format_name($global_account);
 
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
+      $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'sanitize' => FALSE));
       $this->assertEqual($output, $expected, format_string('Unsanitized user token %token replaced.', array('%token' => $input)));
     }
 
@@ -97,7 +98,7 @@ function testUserTokenReplacement() {
     // Generate tokens with interface language.
     $link = url('user', array('absolute' => TRUE));
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
+      $output = $token_service->replace($input, array('user' => $account), array('langcode' => $language_interface->langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
       $this->assertTrue(strpos($output, $link) === 0, 'Generated URL is in interface language.');
     }
 
@@ -106,7 +107,7 @@ function testUserTokenReplacement() {
     $account->save();
     $link = url('user', array('language' => language_load($account->preferred_langcode), 'absolute' => TRUE));
     foreach ($tests as $input => $expected) {
-      $output = token_replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
+      $output = $token_service->replace($input, array('user' => $account), array('callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
       $this->assertTrue(strpos($output, $link) === 0, "Generated URL is in the user's preferred language.");
     }
 
@@ -114,7 +115,7 @@ function testUserTokenReplacement() {
     $link = url('user', array('language' => language_load('de'), 'absolute' => TRUE));
     foreach ($tests as $input => $expected) {
       foreach (array($user1, $user2) as $account) {
-        $output = token_replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
+        $output = $token_service->replace($input, array('user' => $account), array('langcode' => 'de', 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE));
         $this->assertTrue(strpos($output, $link) === 0, "Generated URL in in the requested language.");
       }
     }
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index ead593b87a4b21d83f7e518047c41ae3742e160f..eddc8c3d596e15d98ea082a4e8eec15a7c11ee59 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -1731,6 +1731,7 @@ function user_view_multiple($accounts, $view_mode = 'full', $langcode = NULL) {
  * Implements hook_mail().
  */
 function user_mail($key, &$message, $params) {
+  $token_service = Drupal::token();
   $langcode = $message['langcode'];
   $variables = array('user' => $params['account']);
 
@@ -1745,8 +1746,8 @@ function user_mail($key, &$message, $params) {
    // We do not sanitize the token replacement, since the output of this
    // replacement is intended for an e-mail message, not a web browser.
   $token_options = array('langcode' => $langcode, 'callback' => 'user_mail_tokens', 'sanitize' => FALSE, 'clear' => TRUE);
-  $message['subject'] .= token_replace($mail_config->get($key . '.subject'), $variables, $token_options);
-  $message['body'][] = token_replace($mail_config->get($key . '.body'), $variables, $token_options);
+  $message['subject'] .= $token_service->replace($mail_config->get($key . '.subject'), $variables, $token_options);
+  $message['body'][] = $token_service->replace($mail_config->get($key . '.body'), $variables, $token_options);
 
   // Return the previous config context.
   config_context_leave();
@@ -1755,8 +1756,9 @@ function user_mail($key, &$message, $params) {
 /**
  * Token callback to add unsafe tokens for user mails.
  *
- * This function is used by the token_replace() to set up some additional
- * tokens that can be used in email messages generated by user_mail().
+ * This function is used by \Drupal\Core\Utility\Token::replace() to set up
+ * some additional tokens that can be used in email messages generated by
+ * user_mail().
  *
  * @param $replacements
  *   An associative array variable containing mappings from token names to
@@ -1768,7 +1770,7 @@ function user_mail($key, &$message, $params) {
  *   - login: The account login name.
  *   - pass: The hashed account login password.
  * @param $options
- *   Unused parameter required by the token_replace() function.
+ *   Unused parameter required by \Drupal\Core\Utility\Token::replace().
  */
 function user_mail_tokens(&$replacements, $data, $options) {
   if (isset($data['user'])) {
diff --git a/core/modules/user/user.tokens.inc b/core/modules/user/user.tokens.inc
index bc37434aec27af803e136e25b50efa2aef55e845..185ad6e3a46f99edbad017b9ad8889f698309581 100644
--- a/core/modules/user/user.tokens.inc
+++ b/core/modules/user/user.tokens.inc
@@ -62,6 +62,8 @@ function user_token_info() {
  * Implements hook_tokens().
  */
 function user_tokens($type, $tokens, array $data = array(), array $options = array()) {
+
+  $token_service = Drupal::token();
   $url_options = array('absolute' => TRUE);
   if (isset($options['langcode'])) {
     $url_options['language'] = language_load($options['langcode']);
@@ -113,18 +115,18 @@ function user_tokens($type, $tokens, array $data = array(), array $options = arr
       }
     }
 
-    if ($login_tokens = token_find_with_prefix($tokens, 'last-login')) {
-      $replacements += token_generate('date', $login_tokens, array('date' => $account->login), $options);
+    if ($login_tokens = $token_service->findWithPrefix($tokens, 'last-login')) {
+      $replacements += $token_service->generate('date', $login_tokens, array('date' => $account->login), $options);
     }
 
-    if ($registered_tokens = token_find_with_prefix($tokens, 'created')) {
-      $replacements += token_generate('date', $registered_tokens, array('date' => $account->created), $options);
+    if ($registered_tokens = $token_service->findWithPrefix($tokens, 'created')) {
+      $replacements += $token_service->generate('date', $registered_tokens, array('date' => $account->created), $options);
     }
   }
 
   if ($type == 'current-user') {
     $account = user_load($GLOBALS['user']->uid);
-    $replacements += token_generate('user', $tokens, array('user' => $account), $options);
+    $replacements += $token_service->generate('user', $tokens, array('user' => $account), $options);
   }
 
   return $replacements;
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
index 8fa7034d2c89fa2a8e26834d9dc60d4766793221..2c360024277d5aa80df1cbfe17f843fa6f676378 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/PluginBase.php
@@ -251,13 +251,13 @@ public function usesOptions() {
    * @param string $string
    *   The string to preform the token replacement on.
    * @param array $options
-   *   An array of options, as passed to token_replace.
+   *   An array of options, as passed to \Drupal\Core\Utility\Token::replace().
    *
    * @return string
    *   The tokenized string.
    */
   public function globalTokenReplace($string = '', array $options = array()) {
-    return token_replace($string, array('view' => $this->view), $options);
+    return \Drupal::token()->replace($string, array('view' => $this->view), $options);
   }
 
   /**
@@ -274,7 +274,7 @@ public function globalTokenReplace($string = '', array $options = array()) {
    *   An array of available token replacement info or tokens, grouped by type.
    */
   public function getAvailableGlobalTokens($prepared = FALSE, array $types = array()) {
-    $info = token_info();
+    $info = \Drupal::token()->getInfo();
     // Site and view tokens should always be available.
     $types += array('site', 'view');
     $available = array_intersect_key($info['tokens'], array_flip($types));
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php
index 1ee08da333e1ed43d89a612db9db2e8f9b18ec6e..b8e5f6f45dbee46aefa56268e0c59126d7e6048f 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/AreaTest.php
@@ -151,7 +151,7 @@ public function testRenderAreaToken() {
     // Test we have the site:name token in the output.
     $output = $view->preview();
     $output = drupal_render($output);
-    $expected = token_replace('[site:name]');
+    $expected = \Drupal::token()->replace('[site:name]');
     $this->assertTrue(strpos($output, $expected) !== FALSE);
   }
 
diff --git a/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php b/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php
index dcf14333889053f931d63207c4e2d5d5f23fd97c..6bea0431e8614b08600607296d95475cb841209e 100644
--- a/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/TokenReplaceTest.php
@@ -38,6 +38,7 @@ function setUp() {
    * Tests core token replacements generated from a view.
    */
   function testTokenReplacement() {
+    $token_handler = \Drupal::token();
     $view = views_get_view('test_tokens');
     $view->setDisplay('page_1');
     $this->executeView($view);
@@ -57,7 +58,7 @@ function testTokenReplacement() {
     );
 
     foreach ($expected as $token => $expected_output) {
-      $output = token_replace($token, array('view' => $view));
+      $output = $token_handler->replace($token, array('view' => $view));
       $this->assertIdentical($output, $expected_output, format_string('Token %token replaced correctly.', array('%token' => $token)));
     }
   }
diff --git a/core/modules/views/views.tokens.inc b/core/modules/views/views.tokens.inc
index 9128744d20b5051b1059e2e1ddfb1d1c2c511eee..fc119b81658b152d0a8f25919a76af1d8896d56c 100644
--- a/core/modules/views/views.tokens.inc
+++ b/core/modules/views/views.tokens.inc
@@ -67,6 +67,8 @@ function views_token_info() {
  * Implements hook_tokens().
  */
 function views_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $token_service = Drupal::token();
+
   $url_options = array('absolute' => TRUE);
   if (isset($options['language'])) {
     $url_options['language'] = $options['language'];
@@ -127,9 +129,9 @@ function views_tokens($type, $tokens, array $data = array(), array $options = ar
     }
 
     // [view:url:*] nested tokens. This only works if Token module is installed.
-    if ($url_tokens = token_find_with_prefix($tokens, 'url')) {
+    if ($url_tokens = $token_service->findWithPrefix($tokens, 'url')) {
       if ($path = $view->getUrl()) {
-        $replacements += token_generate('url', $url_tokens, array('path' => $path), $options);
+        $replacements += $token_service->generate('url', $url_tokens, array('path' => $path), $options);
       }
     }
   }