--- email_registration.module	2010-10-28 10:23:47.000000000 -0400
+++ email_registrationNew.module	2010-10-28 10:19:48.000000000 -0400
@@ -22,18 +22,9 @@ function email_registration_user($op, &$
       $names = array_filter($names);
 
       if (empty($names)) {
-        // Default implementation of name generation
+        // Default implementation of name generation - use name portion of email address
         $namenew = preg_replace('/@.*$/', '', $edit['mail']);
-        // Remove unwanted characters
-        $namenew = preg_replace('/[^a-zA-Z0-9.-]/', '', $namenew);
-
-        // if username generated from email record already exists, append underscore and number eg:(chris_123)
-        if (db_result(db_query("SELECT count(*) FROM {users} WHERE uid <> %d AND LOWER(name) = LOWER('%s')", $account->uid, $namenew)) > 0) {
-          // find the next number available to append to the name
-          $sql = "SELECT SUBSTRING_INDEX(name,'_',-1) FROM {users} WHERE name REGEXP '%s' ORDER BY CAST(SUBSTRING_INDEX(name,'_',-1) AS UNSIGNED) DESC LIMIT 1";
-          $nameidx = db_result(db_query($sql, '^'. $namenew .'_[0-9]+$'));
-          $namenew .= '_'. ($nameidx + 1);
-        }
+        $namenew = email_registration_unique_username($namenew, $account->uid);
       }
       else {
         // One would expect a single implementation of the hook, but if there
@@ -59,6 +50,49 @@ function email_registration_user($op, &$
 }
 
 /**
+ * Given a starting point for a Drupal username (e.g. the name portion of an email address) return
+ * a legal, unique Drupal username.
+ *
+ * @param $name
+ *   A name from which to base the final user name.  May contain illegal characters; these will be stripped.
+ *
+ * @param $uid
+ *   (optional) Uid to ignore when searching for unique user (e.g. if we update the username after the 
+ *   {users} row is inserted) 
+ *
+ * @return
+ *   A unique user name based on $name.
+ *
+ */
+function email_registration_unique_username($name, $uid = 0) {
+  // Strip illegal characters
+  $name = preg_replace('/[^\x{80}-\x{F7} a-zA-Z0-9@_.\'-]/', '', $name);
+  
+  // Strip leading and trailing spaces
+  $name = preg_replace('/^ +/', '', $name);
+  $name = preg_replace('/ +$/', '', $name);
+  
+  // Convert any other series of spaces to a single underscore
+  $name = preg_replace('/ +/', '_', $name);
+  
+  // If there's nothing left use a default
+  $name = ('' === $name) ? t('user') : $name;
+  
+  // Truncate to reasonable size
+  $name = (drupal_strlen($name) > (USERNAME_MAX_LENGTH - 10)) ? drupal_substr($name, 0, USERNAME_MAX_LENGTH - 11) : $name;
+  
+  // Iterate until we find a unique name
+  $i = 0;
+  do {
+    $newname = empty($i) ? $name : $name . '_' . $i;
+    $found = db_result(db_query_range("SELECT uid from {users} WHERE uid <> %d AND name = '%s'", $uid, $newname, 0, 1));
+    $i++;
+  } while ($found);
+  
+  return $newname;
+}
+
+/**
  * Implementation of hook_form_alter().
  *
  */
