Index: wp-includes/pluggable.php
===================================================================
--- wp-includes/pluggable.php	(revision 6341)
+++ wp-includes/pluggable.php	(working copy)
@@ -60,43 +60,25 @@
 if ( !function_exists('get_userdata') ) :
 function get_userdata( $user_id ) {
 	global $wpdb;
+
 	$user_id = abs(intval($user_id));
 	if ( $user_id == 0 )
 		return false;
 
 	$user = wp_cache_get($user_id, 'users');
 
-	if ( $user )
+	if ( '0' === $user )
+		return false;
+	else if ( $user )
 		return $user;
 
-	if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id)) )
+	if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id)) ) {
+		wp_cache_add($user_id, 0, 'users');
 		return false;
+	}
 
-	$wpdb->hide_errors();
-	$metavalues = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user_id));
-	$wpdb->show_errors();
+	_fill_user($user);
 
-	if ($metavalues) {
-		foreach ( $metavalues as $meta ) {
-			$value = maybe_unserialize($meta->meta_value);
-			$user->{$meta->meta_key} = $value;
-
-			// We need to set user_level from meta, not row
-			if ( $wpdb->prefix . 'user_level' == $meta->meta_key )
-				$user->user_level = $meta->meta_value;
-		} // end foreach
-	} //end if
-
-	// For backwards compat.
-	if ( isset($user->first_name) )
-		$user->user_firstname = $user->first_name;
-	if ( isset($user->last_name) )
-		$user->user_lastname = $user->last_name;
-	if ( isset($user->description) )
-		$user->user_description = $user->description;
-
-	wp_cache_add($user_id, $user, 'users');
-	wp_cache_add($user->user_login, $user_id, 'userlogins');
 	return $user;
 }
 endif;
@@ -116,19 +98,54 @@
 		return false;
 
 	$user_id = wp_cache_get($user_login, 'userlogins');
-	$userdata = wp_cache_get($user_id, 'users');
+	if ( '0' === $user_id )
+		return false;
 
-	if ( $userdata )
-		return $userdata;
+	$user = false;
+	if ( false !== $user_id )
+		$user = wp_cache_get($user_id, 'users');
 
-	if ( !$user_ID = $wpdb->get_var($wpdb->prepare("SELECT ID FROM $wpdb->users WHERE user_login = %s", $user_login)) )
+	if ( false !== $user )
+		return $user;
+
+	if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_login = %s", $user_login)) ) {
+		wp_cache_add($user_login, 0, 'userlogins');
 		return false;
+	}
 
-	$user = get_userdata($user_ID);
+	_fill_user($user);
+
 	return $user;
 }
 endif;
 
+if ( !function_exists('get_user_by_email') ) :
+function get_user_by_email($email) {
+	global $wpdb;
+
+	$user_id = wp_cache_get($email, 'useremail');
+
+	if ( '0' === $user_id )
+		return false;
+
+	$user = false;
+	if ( false !== $user_id )
+		$user = wp_cache_get($user_id, 'users');
+
+	if ( false !== $user )
+		return $user;
+
+	if ( !$user = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->users WHERE user_email = %s", $email)) ) {
+		wp_cache_add($email, 0, 'useremail');
+		return false;
+	}
+
+	_fill_user($user);
+
+	return $user;
+}
+endif;
+
 if ( !function_exists( 'wp_mail' ) ) :
 function wp_mail( $to, $subject, $message, $headers = '' ) {
 	// Compact the input, apply the filters, and extract them back out
Index: wp-includes/registration.php
===================================================================
--- wp-includes/registration.php	(revision 6341)
+++ wp-includes/registration.php	(working copy)
@@ -6,7 +6,7 @@
  * @return mixed The user's ID on success, and null on failure.
  */
 function username_exists( $username ) {
-	if ( $user = get_userdatabylogin( sanitize_user( $username ) ) ) {
+	if ( $user = get_userdatabylogin( $username ) ) {
 		return $user->ID;
 	} else {
 		return null;
@@ -20,8 +20,10 @@
  * @return mixed The user's ID on success, and false on failure.
  */
 function email_exists( $email ) {
-	global $wpdb;
-	return $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->users WHERE user_email = %s", $email) );
+	if ( $user = get_user_by_email($email) )
+		return $user->ID;
+
+	return false;
 }
 
 /**
Index: wp-includes/user.php
===================================================================
--- wp-includes/user.php	(revision 6341)
+++ wp-includes/user.php	(working copy)
@@ -78,7 +78,6 @@
 
 	$user = get_userdata($user_id);
 	wp_cache_delete($user_id, 'users');
-	wp_cache_delete($user->user_login, 'userlogins');
 
 	return true;
 }
@@ -142,7 +141,6 @@
 
 	$user = get_userdata($user_id);
 	wp_cache_delete($user_id, 'users');
-	wp_cache_delete($user->user_login, 'userlogins');
 
 	return true;
 }
@@ -238,4 +236,35 @@
 	return $output;
 }
 
+function _fill_user( &$user ) {
+	global $wpdb;
+
+	$wpdb->hide_errors();
+	$metavalues = $wpdb->get_results($wpdb->prepare("SELECT meta_key, meta_value FROM $wpdb->usermeta WHERE user_id = %d", $user->ID));
+	$wpdb->show_errors();
+
+	if ( $metavalues ) {
+		foreach ( $metavalues as $meta ) {
+			$value = maybe_unserialize($meta->meta_value);
+			$user->{$meta->meta_key} = $value;
+		}
+	}
+
+	$level = $wpdb->prefix . 'user_level';
+	if ( isset( $user->{$level} ) )
+		$user->user_level = $user->{$level};
+
+	// For backwards compat.
+	if ( isset($user->first_name) )
+		$user->user_firstname = $user->first_name;
+	if ( isset($user->last_name) )
+		$user->user_lastname = $user->last_name;
+	if ( isset($user->description) )
+		$user->user_description = $user->description;
+
+	wp_cache_add($user->ID, $user, 'users');
+	wp_cache_add($user->user_login, $user->ID, 'userlogins');
+	wp_cache_add($user->user_email, $user->ID, 'useremail');
+}
+
 ?>
Index: wp-admin/includes/user.php
===================================================================
--- wp-admin/includes/user.php	(revision 6341)
+++ wp-admin/includes/user.php	(working copy)
@@ -272,6 +272,7 @@
 
 	wp_cache_delete($id, 'users');
 	wp_cache_delete($user->user_login, 'userlogins');
+	wp_cache_delete($user->user_email, 'useremail');
 
 	return true;
 }

