diff --git a/modules/user/user.module b/modules/user/user.module
index 358b4cec569251786225b18fafab97602f4afbd4..92a55bcf47254eaee95a77999aa62e1a27df805b 100644
--- a/modules/user/user.module
+++ b/modules/user/user.module
@@ -417,6 +417,9 @@ function user_save($account, $edit = array(), $category = 'account') {
       // Avoid overwriting an existing password with a blank password.
       unset($edit['pass']);
     }
+    if (isset($edit['mail'])) {
+      $edit['mail'] = trim($edit['mail']);
+    }
 
     // Load the stored entity, if any.
     if (!empty($account->uid) && !isset($account->original)) {
@@ -562,9 +565,6 @@ function user_save($account, $edit = array(), $category = 'account') {
       if (!isset($edit['created'])) {
         $edit['created'] = REQUEST_TIME;
       }
-      if (isset($edit['mail'])) {
-        $edit['mail'] = trim($edit['mail']);
-      }
       $success = drupal_write_record('users', $edit);
       if ($success === FALSE) {
         // On a failed INSERT some other existing user's uid may be returned.
@@ -655,7 +655,6 @@ function user_validate_name($name) {
  *   If the address is valid, nothing is returned.
  */
 function user_validate_mail($mail) {
-  $mail = trim($mail);
   if (!$mail) {
     return t('You must enter an e-mail address.');
   }
@@ -1203,6 +1202,11 @@ function user_account_form_validate($form, &$form_state) {
       }
     }
 
+    // Trim whitespace from mail, to prevent confusing 'e-mail not valid'
+    // warnings often caused by cutting and pasting.
+    $mail = trim($form_state['values']['mail']);
+    form_set_value($form['account']['mail'], $mail, $form_state);
+
     // Validate the e-mail address, and check if it is taken by an existing user.
     if ($error = user_validate_mail($form_state['values']['mail'])) {
       form_set_error('mail', $error);
diff --git a/modules/user/user.test b/modules/user/user.test
index 3c453a8b07eb3fdfe24cc8e5303d2757faf273c1..6ecbfac771c244edbe27ce72f4fca2b3a1e95e0a 100644
--- a/modules/user/user.test
+++ b/modules/user/user.test
@@ -108,6 +108,31 @@ class UserRegistrationTestCase extends DrupalWebTestCase {
     $this->assertText(t('Member for'), t('User can log in after administrator approval.'));
   }
 
+  function testRegistrationEmailDuplicates() {
+    // Don't require e-mail verification.
+    variable_set('user_email_verification', FALSE);
+
+    // Allow registration by site visitors without administrator approval.
+    variable_set('user_register', USER_REGISTER_VISITORS);
+
+    // Set up a user to check for duplicates.
+    $duplicate_user = $this->drupalCreateUser();
+
+    $edit = array();
+    $edit['name'] = $this->randomName();
+    $edit['mail'] = $duplicate_user->mail;
+
+    // Attempt to create a new account using an existing e-mail address.
+    $this->drupalPost('user/register', $edit, t('Create new account'));
+    $this->assertText(t('The e-mail address @email is already registered.', array('@email' => $duplicate_user->mail)), t('Supplying an exact duplicate email address displays an error message'));
+
+    // Attempt to bypass duplicate email registration validation by adding spaces.
+    $edit['mail'] = '   ' . $duplicate_user->mail . '   ';
+
+    $this->drupalPost('user/register', $edit, t('Create new account'));
+    $this->assertText(t('The e-mail address @email is already registered.', array('@email' => $duplicate_user->mail)), t('Supplying a duplicate email address with added whitespace displays an error message'));
+  }
+
   function testRegistrationDefaultValues() {
     // Allow registration by site visitors without administrator approval.
     variable_set('user_register', USER_REGISTER_VISITORS);