Index: wp-includes/user.php
===================================================================
--- wp-includes/user.php	(revision 18586)
+++ wp-includes/user.php	(working copy)
@@ -254,20 +254,18 @@
 	if ( !empty( $deprecated ) )
 		_deprecated_argument( __FUNCTION__, '3.0' );
 
-	if ( empty($user) ) {
+	if ( empty( $user ) )
 		$user = wp_get_current_user();
-		$user = $user->ID;
-	}
+	else
+		$user = new WP_User( $user );
 
-	$user = get_userdata($user);
+	if ( ! isset( $user->ID ) )
+		return false;
 
-	// Keys used as object vars cannot have dashes.
-	$key = str_replace('-', '', $option);
-
-	if ( isset( $user->{$wpdb->prefix . $key} ) ) // Blog specific
-		$result = $user->{$wpdb->prefix . $key};
-	elseif ( isset( $user->{$key} ) ) // User specific and cross-blog
-		$result = $user->{$key};
+	if ( $user->has_prop( $wpdb->prefix . $option ) ) // Blog specific
+		$result = $user->get( $wpdb->prefix . $option );
+	elseif ( $user->has_prop( $option ) ) // User specific and cross-blog
+		$result = $user->get( $option );
 	else
 		$result = false;
 
@@ -680,13 +678,13 @@
 	}
 
 	if ( false === $blogs ) {
-		$user = get_userdata( (int) $id );
-		if ( !$user )
+		$userkeys = array_keys( get_user_meta( (int) $id ) );
+		if ( empty( $userkeys ) )
 			return false;
 
 		$blogs = $match = array();
-		$prefix_length = strlen($wpdb->base_prefix);
-		foreach ( (array) $user as $key => $value ) {
+		$prefix_length = strlen( $wpdb->base_prefix );
+		foreach ( $userkeys as $key ) {
 			if ( $prefix_length && substr($key, 0, $prefix_length) != $wpdb->base_prefix )
 				continue;
 			if ( substr($key, -12, 12) != 'capabilities' )
@@ -793,7 +791,7 @@
  * @return mixed Will be an array if $single is false. Will be value of meta data field if $single
  *  is true.
  */
-function get_user_meta($user_id, $key, $single = false) {
+function get_user_meta($user_id, $key = '', $single = false) {
 	return get_metadata('user', $user_id, $key, $single);
 }
 
@@ -1043,141 +1041,6 @@
 }
 
 /**
- * Add user meta data as properties to given user object.
- *
- * The finished user data is cached, but the cache is not used to fill in the
- * user data for the given object. Once the function has been used, the cache
- * should be used to retrieve user data. The intention is if the current data
- * had been cached already, there would be no need to call this function.
- *
- * @access private
- * @since 2.5.0
- * @uses $wpdb WordPress database object for queries
- *
- * @param object $user The user data object.
- */
-function _fill_user( &$user ) {
-	$metavalues = get_user_metavalues(array($user->ID));
-	_fill_single_user($user, $metavalues[$user->ID]);
-}
-
-/**
- * Perform the query to get the $metavalues array(s) needed by _fill_user and _fill_many_users
- *
- * @since 3.0.0
- * @param array $ids User ID numbers list.
- * @return array of arrays. The array is indexed by user_id, containing $metavalues object arrays.
- */
-function get_user_metavalues($ids) {
-	$objects = array();
-
-	$ids = array_map('intval', $ids);
-	foreach ( $ids as $id )
-		$objects[$id] = array();
-
-	$metas = update_meta_cache('user', $ids);
-
-	foreach ( $metas as $id => $meta ) {
-		foreach ( $meta as $key => $metavalues ) {
-			foreach ( $metavalues as $value ) {
-				$objects[$id][] = (object)array( 'user_id' => $id, 'meta_key' => $key, 'meta_value' => $value);
-			}
-		}
-	}
-
-	return $objects;
-}
-
-/**
- * Unserialize user metadata, fill $user object, then cache everything.
- *
- * @since 3.0.0
- * @param object $user The User object.
- * @param array $metavalues An array of objects provided by get_user_metavalues()
- */
-function _fill_single_user( &$user, &$metavalues ) {
-	global $wpdb;
-
-	foreach ( $metavalues as $meta ) {
-		$value = maybe_unserialize($meta->meta_value);
-		// Keys used as object vars cannot have dashes.
-		$key = str_replace('-', '', $meta->meta_key);
-		$user->{$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;
-
-	update_user_caches($user);
-}
-
-/**
- * Take an array of user objects, fill them with metas, and cache them.
- *
- * @since 3.0.0
- * @param array $users User objects
- */
-function _fill_many_users( &$users ) {
-	$ids = array();
-	foreach( $users as $user_object ) {
-		$ids[] = $user_object->ID;
-	}
-
-	$metas = get_user_metavalues($ids);
-
-	foreach ( $users as $user_object ) {
-		if ( isset($metas[$user_object->ID]) ) {
-			_fill_single_user($user_object, $metas[$user_object->ID]);
-		}
-	}
-}
-
-/**
- * Sanitize every user field.
- *
- * If the context is 'raw', then the user object or array will get minimal santization of the int fields.
- *
- * @since 2.3.0
- * @uses sanitize_user_field() Used to sanitize the fields.
- *
- * @param object|array $user The User Object or Array
- * @param string $context Optional, default is 'display'. How to sanitize user fields.
- * @return object|array The now sanitized User Object or Array (will be the same type as $user)
- */
-function sanitize_user_object($user, $context = 'display') {
-	if ( is_object($user) ) {
-		if ( !isset($user->ID) )
-			$user->ID = 0;
-		if ( isset($user->data) )
-			$vars = get_object_vars( $user->data );
-		else
-			$vars = get_object_vars($user);
-		foreach ( array_keys($vars) as $field ) {
-			if ( is_string($user->$field) || is_numeric($user->$field) )
-				$user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context);
-		}
-		$user->filter = $context;
-	} else {
-		if ( !isset($user['ID']) )
-			$user['ID'] = 0;
-		foreach ( array_keys($user) as $field )
-			$user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context);
-		$user['filter'] = $context;
-	}
-
-	return $user;
-}
-
-/**
  * Sanitize user field based on context.
  *
  * Possible context values are:  'raw', 'edit', 'db', 'display', 'attribute' and 'js'. The
@@ -1264,7 +1127,7 @@
  *
  * @param object $user User object to be cached
  */
-function update_user_caches(&$user) {
+function update_user_caches($user) {
 	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');
@@ -1279,7 +1142,7 @@
  * @param int $id User ID
  */
 function clean_user_cache($id) {
-	$user = new WP_User($id);
+	$user = WP_User::get_data_by( 'id', $id );
 
 	wp_cache_delete($id, 'users');
 	wp_cache_delete($user->user_login, 'userlogins');
@@ -1390,7 +1253,7 @@
 	if ( !empty($ID) ) {
 		$ID = (int) $ID;
 		$update = true;
-		$old_user_data = get_userdata($ID);
+		$old_user_data = WP_User::get_data_by( 'id', $ID );
 	} else {
 		$update = false;
 		// Hash the password
@@ -1548,7 +1411,7 @@
 	$ID = (int) $userdata['ID'];
 
 	// First, get all of the original fields
-	$user = get_userdata($ID);
+	$user = WP_User::get_data_by('id', $ID);
 
 	// Escape data pulled from DB.
 	$user = add_magic_quotes(get_object_vars($user));
Index: wp-includes/capabilities.php
===================================================================
--- wp-includes/capabilities.php	(revision 18586)
+++ wp-includes/capabilities.php	(working copy)
@@ -420,43 +420,110 @@
 	 */
 	var $filter = null;
 
+	private static $back_compat_keys = array(
+		'user_firstname' => 'first_name',
+		'user_lastname' => 'last_name',
+		'user_description' => 'description'
+	);
+
 	/**
-	 * Constructor - Sets up the object properties.
+	 * Constructor
 	 *
-	 * Retrieves the userdata and then assigns all of the data keys to direct
-	 * properties of the object. Calls {@link WP_User::_init_caps()} after
-	 * setting up the object's user data properties.
+	 * Retrieves the userdata and passes it to {@link WP_User::init()}.
 	 *
 	 * @since 2.0.0
 	 * @access public
 	 *
-	 * @param int|string $id User's ID or username
-	 * @param int $name Optional. User's username
+	 * @param int|string $id User's ID
+	 * @param string $name Optional. User's username
 	 * @param int $blog_id Optional Blog ID, defaults to current blog.
 	 * @return WP_User
 	 */
-	function __construct( $id, $name = '', $blog_id = '' ) {
-		if ( empty( $id ) && empty( $name ) )
-			return;
-
+	function __construct( $id = 0, $name = '', $blog_id = '' ) {
 		if ( ! is_numeric( $id ) ) {
 			$name = $id;
 			$id = 0;
 		}
 
-		if ( ! empty( $id ) )
-			$this->data = get_userdata( $id );
+		if ( $id )
+			$data = self::get_data_by( 'id', $id );
 		else
-			$this->data = get_user_by('login', $name );
+			$data = self::get_data_by( 'login', $name );
 
-		if ( empty( $this->data->ID ) )
-			return;
+		if ( $data )
+			$this->init( $data, $blog_id );
+	}
 
-		$this->ID = $this->data->ID;
+	/**
+	 * Sets up object properties, including capabilities.
+	 *
+	 * @param object $data User DB row object
+	 * @param int $blog_id Optional. The blog id to initialize for
+	 */
+	function init( $data, $blog_id = '' ) {
+		$this->data = $data;
+		$this->ID = (int) $data->ID;
+
 		$this->for_blog( $blog_id );
 	}
 
 	/**
+	 * Return only the main user fields
+	 *
+	 * @since 3.3.0
+	 *
+	 * @param string $field The field to query against: 'id', 'slug', 'email' or 'login'
+	 * @param string|int $value The field value
+	 */
+	static function get_data_by( $field, $value ) {
+		global $wpdb;
+
+		if ( 'id' == $field )
+			$value = absint( $value );
+		else
+			$value = trim( $value );
+
+		if ( !$value )
+			return false;
+
+		switch ( $field ) {
+			case 'id':
+				$user_id = $value;
+				$db_field = 'ID';
+				break;
+			case 'slug':
+				$user_id = wp_cache_get($value, 'userslugs');
+				$db_field = 'user_nicename';
+				break;
+			case 'email':
+				$user_id = wp_cache_get($value, 'useremail');
+				$db_field = 'user_email';
+				break;
+			case 'login':
+				$value = sanitize_user( $value );
+				$user_id = wp_cache_get($value, 'userlogins');
+				$db_field = 'user_login';
+				break;
+			default:
+				return false;
+		}
+
+		if ( false !== $user_id ) {
+			if ( $user = wp_cache_get( $user_id, 'users' ) )
+				return $user;
+		}
+
+		if ( !$user = $wpdb->get_row( $wpdb->prepare(
+			"SELECT * FROM $wpdb->users WHERE $db_field = %s", $value
+		) ) )
+			return false;
+
+		update_user_caches( $user );
+
+		return $user;
+	}
+
+	/**
 	 * Magic method for checking the existance of a certain custom field
 	 *
 	 * @since 3.3.0
@@ -466,7 +533,14 @@
 			_deprecated_argument( 'WP_User->id', '2.1', __( 'Use <code>WP_User->ID</code> instead.' ) );
 			$key = 'ID';
 		}
-		return isset( $this->data->$key );
+
+		if ( isset( $this->data->$key ) )
+			return true;
+
+		if ( isset( self::$back_compat_keys[ $key ] ) )
+			$key = self::$back_compat_keys[ $key ];
+
+		return metadata_exists( 'user', $this->ID, $key );
 	}
 
 	/**
@@ -480,7 +554,19 @@
 			return $this->ID;
 		}
 
-		return $this->data->$key;
+		if ( isset( $this->data->$key ) ) {
+			$value = $this->data->$key;
+		} else {
+			if ( isset( self::$back_compat_keys[ $key ] ) )
+				$key = self::$back_compat_keys[ $key ];
+			$value = get_user_meta( $this->ID, $key, true );
+		}
+
+		if ( $this->filter ) {
+			$value = sanitize_user_field( $key, $value, $this->ID, $this->filter );
+		}
+
+		return $value;
 	}
 
 	/**
@@ -499,6 +585,32 @@
 	}
 
 	/**
+	 * Retrieve the value of a property or meta key.
+	 *
+	 * Retrieves from the users and usermeta table.
+	 *
+	 * @since 3.3.0
+	 *
+	 * @param string $key Property
+	 */
+	function get( $key ) {
+		return $this->__get( $key );
+	}
+
+	/**
+	 * Determine whether a property or meta key is set
+	 *
+	 * Consults the users and usermeta tables.
+	 *
+	 * @since 3.3.0
+	 *
+	 * @param string $key Property
+	 */
+	function has_prop( $key ) {
+		return $this->__isset( $key );
+	}
+
+	/**
 	 * Set up capability object properties.
 	 *
 	 * Will set the value for the 'cap_key' property to current database table
@@ -519,7 +631,8 @@
 		else
 			$this->cap_key = $cap_key;
 
-		$this->caps = &$this->data->{$this->cap_key};
+		$this->caps = get_user_meta( $this->ID, $this->cap_key, true );
+
 		if ( ! is_array( $this->caps ) )
 			$this->caps = array();
 
@@ -662,7 +775,7 @@
 	 */
 	function update_user_level_from_caps() {
 		global $wpdb;
-		$this->user_level = array_reduce( array_keys( $this->allcaps ), array( &$this, 'level_reduction' ), 0 );
+		$this->user_level = array_reduce( array_keys( $this->allcaps ), array( $this, 'level_reduction' ), 0 );
 		update_user_meta( $this->ID, $wpdb->prefix . 'user_level', $this->user_level );
 	}
 
@@ -1066,7 +1179,7 @@
 	$args = array_slice( func_get_args(), 1 );
 	$args = array_merge( array( $capability ), $args );
 
-	return call_user_func_array( array( &$current_user, 'has_cap' ), $args );
+	return call_user_func_array( array( $current_user, 'has_cap' ), $args );
 }
 
 /**
Index: wp-includes/deprecated.php
===================================================================
--- wp-includes/deprecated.php	(revision 18586)
+++ wp-includes/deprecated.php	(working copy)
@@ -2627,13 +2627,13 @@
  */
 function wp_default_editor() {
 	_deprecated_function( __FUNCTION__, '3.3' );
-	
+
 	global $wp_editor;
 	if ( !is_a($wp_editor, 'WP_Editor') ) {
 		require_once( ABSPATH . WPINC . '/class-wp-editor.php' );
 		$wp_editor = new WP_Editor;
 	}
-	
+
 	return $wp_editor->wp_default_editor();
 }
 
@@ -2641,7 +2641,7 @@
  * Display editor: TinyMCE, HTML, or both.
  *
  * @since 2.1.0
- * @deprecated 3.3 
+ * @deprecated 3.3
  *
  * @param string $content Textarea content.
  * @param string $id Optional, default is 'content'. HTML ID attribute value.
@@ -2650,8 +2650,74 @@
  * @param int $tab_index Optional, not used
  */
 function the_editor($content, $id = 'content', $prev_id = 'title', $media_buttons = true, $tab_index = 2, $extended = true) {
-	
+
 	wp_editor( $content, $id, array( 'media_buttons' => $media_buttons ) );
 	return;
 }
 
+/**
+ * Perform the query to get the $metavalues array(s) needed by _fill_user and _fill_many_users
+ *
+ * @since 3.0.0
+ * @param array $ids User ID numbers list.
+ * @return array of arrays. The array is indexed by user_id, containing $metavalues object arrays.
+ */
+function get_user_metavalues($ids) {
+	_deprecated_function( __FUNCTION__, '3.3' );
+
+	$objects = array();
+
+	$ids = array_map('intval', $ids);
+	foreach ( $ids as $id )
+		$objects[$id] = array();
+
+	$metas = update_meta_cache('user', $ids);
+
+	foreach ( $metas as $id => $meta ) {
+		foreach ( $meta as $key => $metavalues ) {
+			foreach ( $metavalues as $value ) {
+				$objects[$id][] = (object)array( 'user_id' => $id, 'meta_key' => $key, 'meta_value' => $value);
+			}
+		}
+	}
+
+	return $objects;
+}
+
+/**
+ * Sanitize every user field.
+ *
+ * If the context is 'raw', then the user object or array will get minimal santization of the int fields.
+ *
+ * @since 2.3.0
+ * @deprecated 3.3.0
+ * @uses sanitize_user_field() Used to sanitize the fields.
+ *
+ * @param object|array $user The User Object or Array
+ * @param string $context Optional, default is 'display'. How to sanitize user fields.
+ * @return object|array The now sanitized User Object or Array (will be the same type as $user)
+ */
+function sanitize_user_object($user, $context = 'display') {
+	_deprecated_function( __FUNCTION__, '3.3' );
+
+	if ( is_object($user) ) {
+		if ( !isset($user->ID) )
+			$user->ID = 0;
+		if ( !is_a( $user, 'WP_User' ) ) {
+			$vars = get_object_vars($user);
+			foreach ( array_keys($vars) as $field ) {
+				if ( is_string($user->$field) || is_numeric($user->$field) )
+					$user->$field = sanitize_user_field($field, $user->$field, $user->ID, $context);
+			}
+		}
+		$user->filter = $context;
+	} else {
+		if ( !isset($user['ID']) )
+			$user['ID'] = 0;
+		foreach ( array_keys($user) as $field )
+			$user[$field] = sanitize_user_field($field, $user[$field], $user['ID'], $context);
+		$user['filter'] = $context;
+	}
+
+	return $user;
+}
Index: wp-includes/pluggable.php
===================================================================
--- wp-includes/pluggable.php	(revision 18586)
+++ wp-includes/pluggable.php	(working copy)
@@ -98,28 +98,32 @@
  * @since 0.71
  *
  * @param int $user_id User ID
- * @return bool|object False on failure, User DB row object
+ * @return bool|object False on failure, WP_User object on success
  */
 function get_userdata( $user_id ) {
-	global $wpdb;
+	return get_user_by( 'id', $user_id );
+}
+endif;
 
-	if ( ! is_numeric( $user_id ) )
-		return false;
+if ( !function_exists('get_user_by') ) :
+/**
+ * Retrieve user info by a given field
+ *
+ * @since 2.8.0
+ *
+ * @param string $field The field to retrieve the user with.  id | slug | email | login
+ * @param int|string $value A value for $field.  A user ID, slug, email address, or login name.
+ * @return bool|object False on failure, WP_User object on success
+ */
+function get_user_by( $field, $value ) {
+	$userdata = WP_User::get_data_by( $field, $value );
 
-	$user_id = absint( $user_id );
-	if ( ! $user_id )
+	if ( !$userdata )
 		return false;
 
-	$user = wp_cache_get( $user_id, 'users' );
+	$user = new WP_User;
+	$user->init( $userdata );
 
-	if ( $user )
-		return $user;
-
-	if ( ! $user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->users WHERE ID = %d LIMIT 1", $user_id ) ) )
-		return false;
-
-	_fill_user( $user );
-
 	return $user;
 }
 endif;
@@ -130,75 +134,32 @@
  *
  * @since 3.0.0
  *
- * @param array $users User ID numbers list
+ * @param array $user_ids User ID numbers list
  */
-function cache_users( $users ) {
+function cache_users( $user_ids ) {
 	global $wpdb;
 
 	$clean = array();
-	foreach($users as $id) {
+	foreach ( $user_ids as $id ) {
 		$id = (int) $id;
-		if (wp_cache_get($id, 'users')) {
-			// seems to be cached already
-		} else {
+		if ( !wp_cache_get( $id, 'users' ) ) {
 			$clean[] = $id;
 		}
 	}
 
-	if ( 0 == count($clean) )
+	if ( empty( $clean ) )
 		return;
 
-	$list = implode(',', $clean);
+	$list = implode( ',', $clean );
 
-	$results = $wpdb->get_results("SELECT * FROM $wpdb->users WHERE ID IN ($list)");
+	$users = $wpdb->get_results( "SELECT * FROM $wpdb->users WHERE ID IN ($list)" );
 
-	_fill_many_users($results);
-}
-endif;
-
-if ( !function_exists('get_user_by') ) :
-/**
- * Retrieve user info by a given field
- *
- * @since 2.8.0
- *
- * @param string $field The field to retrieve the user with.  id | slug | email | login
- * @param int|string $value A value for $field.  A user ID, slug, email address, or login name.
- * @return bool|object False on failure, User DB row object
- */
-function get_user_by($field, $value) {
-	global $wpdb;
-
-	switch ($field) {
-		case 'id':
-			return get_userdata($value);
-			break;
-		case 'slug':
-			$user_id = wp_cache_get($value, 'userslugs');
-			$field = 'user_nicename';
-			break;
-		case 'email':
-			$user_id = wp_cache_get($value, 'useremail');
-			$field = 'user_email';
-			break;
-		case 'login':
-			$value = sanitize_user( $value );
-			$user_id = wp_cache_get($value, 'userlogins');
-			$field = 'user_login';
-			break;
-		default:
-			return false;
+	$ids = array();
+	foreach ( $users as $user ) {
+		update_user_caches( $user );
+		$ids[] = $user->ID;
 	}
-
-	 if ( false !== $user_id )
-		return get_userdata($user_id);
-
-	if ( !$user = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->users WHERE $field = %s", $value) ) )
-		return false;
-
-	_fill_user($user);
-
-	return $user;
+	update_meta_cache( 'user', $ids );
 }
 endif;
 
Index: wp-includes/meta.php
===================================================================
--- wp-includes/meta.php	(revision 18586)
+++ wp-includes/meta.php	(working copy)
@@ -73,9 +73,6 @@
 	$mid = (int) $wpdb->insert_id;
 
 	wp_cache_delete($object_id, $meta_type . '_meta');
-	// users cache stores usermeta that must be cleared.
-	if ( 'user' == $meta_type )
-		clean_user_cache($object_id);
 
 	do_action( "added_{$meta_type}_meta", $mid, $object_id, $meta_key, $_meta_value );
 
@@ -149,21 +146,18 @@
 	}
 
 	do_action( "update_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
-	
+
 	if ( 'post' == $meta_type )
-		do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );	
+		do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 
 	$wpdb->update( $table, $data, $where );
 
 	wp_cache_delete($object_id, $meta_type . '_meta');
-	// users cache stores usermeta that must be cleared.
-	if ( 'user' == $meta_type )
-		clean_user_cache($object_id);
 
 	do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
-	
+
 	if ( 'post' == $meta_type )
-		do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );		
+		do_action( 'updated_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
 
 	return true;
 }
@@ -210,7 +204,7 @@
 
 	$_meta_value = $meta_value;
 	$meta_value = maybe_serialize( $meta_value );
-		
+
 	$query = $wpdb->prepare( "SELECT $id_column FROM $table WHERE meta_key = %s", $meta_key );
 
 	if ( !$delete_all )
@@ -227,7 +221,7 @@
 		$object_ids = $wpdb->get_col( $wpdb->prepare( "SELECT $type_column FROM $table WHERE meta_key = %s", $meta_key ) );
 
 	do_action( "delete_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
-	
+
 	if ( 'post' == $meta_type )
 		do_action( 'delete_postmeta', $meta_ids );
 
@@ -246,12 +240,8 @@
 		wp_cache_delete($object_id, $meta_type . '_meta');
 	}
 
-	// users cache stores usermeta that must be cleared.
-	if ( 'user' == $meta_type )
-		clean_user_cache($object_id);
+	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
 
-	do_action( "deleted_{$meta_type}_meta", $meta_ids, $object_id, $meta_key, $_meta_value );
-	
 	if ( 'post' == $meta_type )
 		do_action( 'deleted_postmeta', $meta_ids );
 
@@ -310,6 +300,40 @@
 }
 
 /**
+ * Determine if a meta key is set for a given object
+ *
+ * @since 3.3.0
+ *
+ * @param string $meta_type Type of object metadata is for (e.g., comment, post, or user)
+ * @param int $object_id ID of the object metadata is for
+ * @param string $meta_key Metadata key. 
+ * @return boolean true of the key is set, false if not.
+ */
+function metadata_exists( $meta_type, $object_id, $meta_key ) {
+	if ( ! $meta_type )
+		return false;
+
+	if ( ! $object_id = absint( $object_id ) )
+		return false;
+
+	$check = apply_filters( "get_{$meta_type}_metadata", null, $object_id, $meta_key, true );
+	if ( null !== $check )
+		return true;
+
+	$meta_cache = wp_cache_get( $object_id, $meta_type . '_meta' );
+
+	if ( !$meta_cache ) {
+		$meta_cache = update_meta_cache( $meta_type, array( $object_id ) );
+		$meta_cache = $meta_cache[$object_id];
+	}
+
+	if ( isset( $meta_cache[ $meta_key ] ) )
+		return true;
+
+	return false;
+}
+
+/**
  * Get meta data by meta ID
  *
  * @since 3.3.0
@@ -406,16 +430,12 @@
 
 		if ( 'post' == $meta_type )
 			do_action( 'update_postmeta', $meta_id, $object_id, $meta_key, $meta_value );
-		
+
 		// Run the update query, all fields in $data are %s, $where is a %d.
 		$result = (bool) $wpdb->update( $table, $data, $where, '%s', '%d' );
 
 		// Clear the caches.
 		wp_cache_delete($object_id, $meta_type . '_meta');
-		
-		// Users cache stores usermeta that must be cleared.
-		if ( 'user' == $meta_type )
-			clean_user_cache($object_id);
 
 		do_action( "updated_{$meta_type}_meta", $meta_id, $object_id, $meta_key, $_meta_value );
 
@@ -424,7 +444,7 @@
 
 		return $result;
 	}
-	
+
 	// And if the meta was not found.
 	return false;
 }
@@ -443,7 +463,7 @@
  */
 function delete_metadata_by_mid( $meta_type, $meta_id ) {
 	global $wpdb;
-	
+
 	// Make sure everything is valid.
 	if ( ! $meta_type )
 		return false;
@@ -453,7 +473,7 @@
 
 	if ( ! $table = _get_meta_table( $meta_type ) )
 		return false;
-	
+
 	// object and id columns
 	$column = esc_sql($meta_type . '_id');
 	$id_column = 'user' == $meta_type ? 'umeta_id' : 'meta_id';
@@ -473,10 +493,6 @@
 		// Clear the caches.
 		wp_cache_delete($object_id, $meta_type . '_meta');
 
-		// Users cache stores usermeta that must be cleared.
-		if ( 'user' == $meta_type )
-			clean_user_cache($object_id);
-
 		do_action( "deleted_{$meta_type}_meta", (array) $meta_id, $object_id, $meta->meta_key, $meta->meta_value );
 
 		if ( 'post' == $meta_type )
@@ -485,7 +501,7 @@
 		return $result;
 
 	}
-	
+
 	// Meta id was not found.
 	return false;
 }
@@ -818,7 +834,7 @@
 
 /**
  * Register meta key
- * 
+ *
  * @since 3.3.0
  *
  * @param string $meta_type Type of meta
Index: wp-admin/includes/class-wp-users-list-table.php
===================================================================
--- wp-admin/includes/class-wp-users-list-table.php	(revision 18586)
+++ wp-admin/includes/class-wp-users-list-table.php	(working copy)
@@ -219,7 +219,7 @@
 
 		if ( !( is_object( $user_object ) && is_a( $user_object, 'WP_User' ) ) )
 			$user_object = new WP_User( (int) $user_object );
-		$user_object = sanitize_user_object( $user_object, 'display' );
+		$user_object->filter = 'display';
 		$email = $user_object->user_email;
 
 		if ( $this->is_site_users )
Index: wp-admin/includes/user.php
===================================================================
--- wp-admin/includes/user.php	(revision 18586)
+++ wp-admin/includes/user.php	(working copy)
@@ -226,17 +226,8 @@
 function get_user_to_edit( $user_id ) {
 	$user = new WP_User( $user_id );
 
-	$user_contactmethods = _wp_get_user_contactmethods( $user );
-	foreach ($user_contactmethods as $method => $name) {
-		if ( empty( $user->{$method} ) )
-			$user->{$method} = '';
-	}
+	$user->filter = 'edit';
 
-	if ( empty($user->description) )
-		$user->description = '';
-
-	$user = sanitize_user_object($user, 'edit');
-
 	return $user;
 }
 
