diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module
index a2f74a3..8bd0be3 100644
--- a/core/modules/rdf/rdf.module
+++ b/core/modules/rdf/rdf.module
@@ -675,29 +675,22 @@ function rdf_preprocess_username(&$variables) {
     $variables['attributes']['about'] = url('user/' . $variables['uid']);
   }
 
-  $attributes = array();
   // The typeof attribute specifies the RDF type(s) of this resource. They
   // are defined in the 'rdftype' property of the user RDF mapping.
   if (!empty($rdf_mapping['rdftype'])) {
-    $attributes['typeof'] = $rdf_mapping['rdftype'];
+    $variables['attributes']['typeof'] = $rdf_mapping['rdftype'];
   }
   // Annotate the username in RDFa. A property attribute is used with an empty
   // datatype attribute to ensure the username is parsed as a plain literal
   // in RDFa 1.0 and 1.1.
   if (!empty($rdf_mapping['name'])) {
-    $attributes['property'] = $rdf_mapping['name']['predicates'];
-    $attributes['datatype'] = '';
+    $variables['attributes']['property'] = $rdf_mapping['name']['predicates'];
+    $variables['attributes']['datatype'] = '';
   }
   // Add the homepage RDFa markup if present.
   if (!empty($variables['homepage']) && !empty($rdf_mapping['homepage'])) {
-    $attributes['rel'] = $rdf_mapping['homepage']['predicates'];
-  }
-  // The remaining attributes can have multiple values listed, with whitespace
-  // separating the values in the RDFa attributes
-  // (see http://www.w3.org/TR/rdfa-syntax/#rdfa-attributes).
-  // Therefore, merge rather than override so as not to clobber values set by
-  // earlier preprocess functions.
-  $variables['attributes'] = NestedArray::mergeDeep($variables['attributes'], $attributes);
+    $variables['attributes']['rel'] = $rdf_mapping['homepage']['predicates'];
+  }
 }
 
 /**
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index a59d8eb..443c4b9 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1499,19 +1499,9 @@ function hook_system_info_alter(&$info, $file, $type) {
  *     have inherent security risks across a variety of potential use cases
  *     (for example, the "administer filters" and "bypass node access"
  *     permissions provided by Drupal core). When set to TRUE, a standard
- *     warning message defined in user_admin_permissions() and output via
- *     theme_user_permission_description() will be associated with the
- *     permission and displayed with it on the permission administration page.
- *     Defaults to FALSE.
- *   - warning: (optional) A translated warning message to display for this
- *     permission on the permission administration page. This warning overrides
- *     the automatic warning generated by 'restrict access' being set to TRUE.
- *     This should rarely be used, since it is important for all permissions to
- *     have a clear, consistent security warning that is the same across the
- *     site. Use the 'description' key instead to provide any information that
- *     is specific to the permission you are defining.
- *
- * @see theme_user_permission_description()
+ *     warning message defined in user_admin_permissions() will be displayed
+ *     with the permission on the permission administration page. Defaults
+ *     to FALSE.
  */
 function hook_permission() {
   return array(
diff --git a/core/modules/user/templates/username.html.twig b/core/modules/user/templates/username.html.twig
new file mode 100644
index 0000000..35c64d3
--- /dev/null
+++ b/core/modules/user/templates/username.html.twig
@@ -0,0 +1,32 @@
+{#
+/**
+ * @file
+ * Default theme implementation for displaying a username.
+ *
+ * Available variables:
+ * - account: The full account information for the user.
+ * - name: The user's name, sanitized.
+ * - extra: Additional text to append to the user's name, sanitized.
+ * - link: The link fully generated by l() if link_path is set.
+ * - link_path: The path or URL of the user's profile page, home page,
+ *   or other desired page to link to for more information about the user.
+ * - link_options: Options to pass to the l() function's $options parameter if
+ *   linking the user's name to the user's page.
+ * - attributes: HTML attributes to be used if not linking to the user's page.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_username()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if link %}
+  {{- link -}}
+{% else %}
+  {#
+    Modules may have added important attributes so they must be included
+    in the output. Additional classes may be added as array elements like
+    {% set attributes.class = attributes.class|merge(["myclass"]) %}
+  #}
+  <span{{ attributes }}>{{ name }}{{ extra }}</span>
+{% endif %}
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 768bb96..1fb49e4 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -331,13 +331,23 @@ function user_admin_permissions($form, $form_state, $rid = NULL) {
         $perm_item += array(
           'description' => '',
           'restrict access' => FALSE,
-          'warning' => !empty($perm_item['restrict access']) ? t('Warning: Give to trusted roles only; this permission has security implications.') : '',
         );
         $options[$perm] = '';
+        // Show the permission description.
+        if (!$hide_descriptions) {
+          $description = $perm_item['description'];
+          // Append warning message.
+          if (!empty($perm_item['restrict access'])) {
+            $description .= ' <em class="permission-warning">' . t('Warning: Give to trusted roles only; this permission has security implications.') . '</em>';
+          }
+        }
+        else {
+          $description = '';
+        }
         $form['permission'][$perm] = array(
           '#type' => 'item',
           '#markup' => $perm_item['title'],
-          '#description' => theme('user_permission_description', array('permission_item' => $perm_item, 'hide' => $hide_descriptions)),
+          '#description' => trim($description),
         );
         foreach ($role_names as $rid => $name) {
           // Builds arrays for checked boxes for each role
@@ -428,37 +438,6 @@ function theme_user_admin_permissions($variables) {
 }
 
 /**
- * Returns HTML for an individual permission description.
- *
- * @param $variables
- *   An associative array containing:
- *   - permission_item: An associative array representing the permission whose
- *     description is being themed. Useful keys include:
- *     - description: The text of the permission description.
- *     - warning: A security-related warning message about the permission (if
- *       there is one).
- *   - hide: A boolean indicating whether or not the permission description was
- *     requested to be hidden rather than shown.
- *
- * @ingroup themeable
- */
-function theme_user_permission_description($variables) {
-  if (!$variables['hide']) {
-    $description = array();
-    $permission_item = $variables['permission_item'];
-    if (!empty($permission_item['description'])) {
-      $description[] = $permission_item['description'];
-    }
-    if (!empty($permission_item['warning'])) {
-      $description[] = '<em class="permission-warning">' . $permission_item['warning'] . '</em>';
-    }
-    if (!empty($description)) {
-      return implode(' ', $description);
-    }
-  }
-}
-
-/**
  * Form to re-order roles or add a new one.
  *
  * @ingroup forms
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 5afcfd9..ad26cf4 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -104,15 +104,9 @@ function user_theme() {
       'render element' => 'form',
       'file' => 'user.admin.inc',
     ),
-    'user_permission_description' => array(
-      'variables' => array('permission_item' => NULL, 'hide' => NULL),
-      'file' => 'user.admin.inc',
-    ),
-    'user_signature' => array(
-      'variables' => array('signature' => NULL),
-    ),
     'username' => array(
       'variables' => array('account' => NULL),
+      'template' => 'username',
     ),
   );
 }
@@ -730,9 +724,17 @@ function user_template_preprocess_default_variables_alter(&$variables) {
 }
 
 /**
- * Preprocesses variables for theme_username().
+ * Prepares variables for username templates.
+ *
+ * Default template: username.html.twig.
  *
- * Modules that make any changes to variables like 'name' or 'extra' must insure
+ * @param array $variables
+ *   An associative array containing:
+ *   - account: The user account to check access for
+ *     (Drupal\user\Plugin\Core\Entity\User).
+ *   - uid: The user uid number.
+ *
+ * Modules that make any changes to variables like 'name' or 'extra' must ensure
  * that the final string is safe to include directly in the output by using
  * check_plain() or filter_xss().
  *
@@ -785,7 +787,7 @@ function template_preprocess_username(&$variables) {
 }
 
 /**
- * Processes variables for theme_username().
+ * Processes variables for username templates.
  *
  * @see template_preprocess_username()
  */
@@ -805,44 +807,11 @@ function template_process_username(&$variables) {
     // \Drupal\Component\Utility\NestedArray::mergeDeep() for performance
     // reasons, since it is potentially called very often.
     $variables['link_options']['attributes'] = array_merge_recursive($variables['link_attributes'], $variables['attributes']);
+    $variables['link'] = l($variables['name'] . $variables['extra'], $variables['link_path'], $variables['link_options']);
   }
 }
 
 /**
- * Returns HTML for a username, potentially linked to the user's page.
- *
- * @param $variables
- *   An associative array containing:
- *   - account: The user object to format.
- *   - name: The user's name, sanitized.
- *   - extra: Additional text to append to the user's name, sanitized.
- *   - link_path: The path or URL of the user's profile page, home page, or
- *     other desired page to link to for more information about the user.
- *   - link_options: An array of options to pass to the l() function's $options
- *     parameter if linking the user's name to the user's page.
- *   - attributes: An array of attributes to instantiate the
- *     Drupal\Core\Template\Attribute class if not linking to the user's page.
- *
- * @see template_preprocess_username()
- * @see template_process_username()
- */
-function theme_username($variables) {
-  if (isset($variables['link_path'])) {
-    // We have a link path, so we should generate a link using l().
-    // Additional classes may be added as array elements like
-    // $variables['link_options']['attributes']['class'][] = 'myclass';
-    $output = l($variables['name'] . $variables['extra'], $variables['link_path'], $variables['link_options']);
-  }
-  else {
-    // Modules may have added important attributes so they must be included
-    // in the output. Additional classes may be added as array elements like
-    // $variables['attributes']['class'][] = 'myclass';
-    $output = '<span' . new Attribute($variables['attributes']) . '>' . $variables['name'] . $variables['extra'] . '</span>';
-  }
-  return $output;
-}
-
-/**
  * Determines if the current user is anonymous.
  *
  * @return bool
@@ -1720,8 +1689,8 @@ function user_view_page($account) {
  * - $page['content']['#user']:
  *   The user account of the profile being viewed.
  *
- * To theme user profiles, copy modules/user/user.tpl.php
- * to your theme directory, and edit it as instructed in that file's comments.
+ * To theme user profiles, copy modules/user/user.html.twig to your theme
+ * directory, and edit it as instructed in that file's comments.
  *
  * @param $account
  *   A user object.
@@ -2328,29 +2297,6 @@ function user_build_filter_query(SelectInterface $query) {
 }
 
 /**
- * Returns HTML for a user signature.
- *
- * @param $variables
- *   An associative array containing:
- *   - signature: The user's signature.
- *
- * @ingroup themeable
- */
-function theme_user_signature($variables) {
-  $signature = $variables['signature'];
-  $output = '';
-
-  if ($signature) {
-    $output .= '<div class="clear">';
-    $output .= '<div>—</div>';
-    $output .= $signature;
-    $output .= '</div>';
-  }
-
-  return $output;
-}
-
-/**
  * Get the language object preferred by the user. This user preference can
  * be set on the user account editing page, and is only available if there
  * are more than one languages enabled on the site. If the user did not
