diff --git includes/theme.inc includes/theme.inc
index 9c646a0..527b4e6 100644
--- includes/theme.inc
+++ includes/theme.inc
@@ -1855,53 +1855,91 @@ function theme_more_link($url, $title) {
 }
 
 /**
- * Format a username.
+ * Preprocess variables for theme_username().
  *
- * @param $object
- *   The user object to format, usually returned from user_load().
- * @return
- *   A string containing an HTML link to the user's page if the passed object
- *   suggests that this is a site user. Otherwise, only the username is returned.
+ * @see theme_username().
  */
-function theme_username($object) {
-
-  if ($object->uid && $object->name) {
-    // Shorten the name when it is too long or it will break many tables.
-    if (drupal_strlen($object->name) > 20) {
-      $name = drupal_substr($object->name, 0, 15) . '...';
-    }
-    else {
-      $name = $object->name;
+function template_preprocess_username(&$variables) {
+  $account = $variables['object'];
+  // Create a new empty object to populate with standardized data.
+  $variables['object'] = new stdClass;
+  // Keep a reference to the original data.
+  $variables['object']->account = $account;
+  $variables['object']->extra = '';
+  if (empty($account->uid)) {
+    $variables['object']->uid = 0;
+    if (theme_get_setting('toggle_comment_user_verification')) {
+      $variables['object']->extra = ' (' . t('not verified') . ')';
     }
+  }
+  else {
+    $variables['object']->uid = $account->uid;
+  }
+  if (empty($account->name)) {
+    $variables['object']->name = variable_get('anonymous', t('Anonymous'));
+  }
+  else {
+    $variables['object']->name = $account->name;
+  }
 
-    if (user_access('access user profiles')) {
-      $output = l($name, 'user/' . $object->uid, array('attributes' => array('title' => t('View user profile.'))));
-    }
-    else {
-      $output = check_plain($name);
-    }
+  $variables['object']->profile_access = user_access('access user profiles');
+  // Link-specific attributes.
+  if ($variables['object']->uid && $variables['object']->profile_access) {
+    // We are linking to a local user.
+    $variables['object']->link_attributes = array('title' => t('View user profile.'));
+    $variables['object']->link_path = 'user/' . $variables['object']->uid;
   }
-  elseif ($object->name) {
-    // Sometimes modules display content composed by people who are
-    // not registered members of the site (e.g. mailing list or news
-    // aggregator modules). This clause enables modules to display
-    // the true author of the content.
-    if (!empty($object->homepage)) {
-      $output = l($object->name, $object->homepage, array('attributes' => array('rel' => 'nofollow')));
-    }
-    else {
-      $output = check_plain($object->name);
-    }
+  elseif (!empty($account->homepage)) {
+    $variables['object']->link_attributes = array('rel' => 'nofollow');
+    $variables['object']->link_path = $account->homepage;
+    $variables['object']->homepage = $account->homepage;
+  }
+  // Other attributes.
+  $variables['object']->attributes = array('class' => array('username'));
+  // Shorten the string if needed.
+  if (drupal_strlen($variables['object']->name) > 20) {
+    $variables['object']->name = drupal_substr($variables['object']->name, 0, 15) . '...';
+  }
+}
 
-    if (theme_get_setting('toggle_comment_user_verification')) {
-      $output .= ' (' . t('not verified') . ')';
-    }
+/**
+ * Process variables for theme_username().
+ *
+ * @see theme_username().
+ */
+function template_process_username(&$variables) {
+  if (isset($variables['object']->link_path)) {
+    $options['attributes'] = $variables['object']->link_attributes + $variables['object']->attributes;
+    $variables['object']->safe_output = l($variables['object']->name . $variables['object']->extra, $variables['object']->link_path, $options);
+    $variables['object']->is_link = TRUE;
   }
   else {
-    $output = check_plain(variable_get('anonymous', t('Anonymous')));
+    $variables['object']->safe_output = '<span' . drupal_attributes($variables['object']->attributes) . '>' . check_plain($variables['object']->name . $variables['object']->extra) . '</span>';
+    $variables['object']->is_link = FALSE;
   }
+  // Make sure these are safe in case they are printed in the theme function.
+  $variables['object']->safe_name = check_plain($variables['object']->name);
+  $variables['object']->safe_extra = check_plain($variables['object']->extra);
+}
 
-  return $output;
+/**
+ * Format a username.
+ *
+ * @param $object
+ *   The user object to format, which has been processed to provide safe and
+ *   standarized elements. The object keys 'safe_output', 'safe_name', and
+ *   'safe_extra' are safe strings that can be used directly.  If
+ *   $object->is_link is TRUE, then $object->safe_output is a link.
+ *
+ * @return
+ *   A string containing an HTML link to the user's page if the passed object
+ *   suggests that this is a site user. Otherwise, only the username is returned.
+ *
+ * @see template_preprocess_username()
+ * @see template_process_username()
+ */
+function theme_username($object) {
+  return $object->safe_output;
 }
 
 /**
