Index: wp-includes/user.php
===================================================================
--- wp-includes/user.php	(revision 10943)
+++ wp-includes/user.php	(working copy)
@@ -367,6 +367,38 @@
 }
 
 /**
+ * Add meta data field to metadata of user
+ *
+ * @param int $user_id User ID
+ * @param string $meta_key Metadata key.
+ * @param mixed $meta_value Metadata value.
+ * @param bool $unique Optional, default is false. Whether the same key should not be added.
+ * @return bool True on successful update, false on failure.
+ */
+function add_usermeta( $user_id, $meta_key, $meta_value, $unique = false) {
+	global $wpdb;
+	if ( !is_numeric( $user_id ) )
+		return false;
+	$meta_key = preg_replace('|[^a-z0-9_]|i', '', $meta_key);
+
+	/** @todo Might need fix because usermeta data is assumed to be already escaped */
+	if ( is_string($meta_value) )
+		$meta_value = stripslashes($meta_value);
+	$meta_value = maybe_serialize($meta_value);
+
+	if ( $unique && $wpdb->get_var( $wpdb->prepare( "SELECT meta_key FROM $wpdb->usermeta WHERE meta_key = %s AND user_id = %d", $meta_key, $user_id ) ) )
+		return false;
+
+	$meta_value = maybe_serialize( stripslashes_deep($meta_value) );
+
+	$wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') );
+
+	wp_cache_delete($user_id, 'users');
+
+	return true;
+}
+
+/**
  * Update metadata of user.
  *
  * There is no need to serialize values, they will be serialized if it is
@@ -381,9 +413,10 @@
  * @param int $user_id User ID
  * @param string $meta_key Metadata key.
  * @param mixed $meta_value Metadata value.
+ * @param mixed $prev_value Optional. Previous value to check before removing.
  * @return bool True on successful update, false on failure.
  */
-function update_usermeta( $user_id, $meta_key, $meta_value ) {
+function update_usermeta( $user_id, $meta_key, $meta_value, $prev_value = '' ) {
 	global $wpdb;
 	if ( !is_numeric( $user_id ) )
 		return false;
@@ -398,13 +431,24 @@
 		return delete_usermeta($user_id, $meta_key);
 	}
 
-	$cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
-	if ( !$cur )
-		$wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') );
-	else if ( $cur->meta_value != $meta_value )
-		$wpdb->update($wpdb->usermeta, compact('meta_value'), compact('user_id', 'meta_key') );
-	else
-		return false;
+	if ( !empty( $prev_value ) ) {
+		$prev_value = maybe_serialize($prev_value);
+		$cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s AND meta_value = %s", $user_id, $meta_key, $prev_value ) );
+		if ( !$cur )
+			return false;
+		else if ( $cur->meta_value != $meta_value )
+			$wpdb->update($wpdb->usermeta, compact('meta_value'), array('user_id'=>$user_id, 'meta_key'=>$meta_key, 'meta_value'=>$prev_value) );
+		else
+			return false;
+	} else {
+		$cur = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->usermeta WHERE user_id = %d AND meta_key = %s", $user_id, $meta_key) );
+		if ( !$cur )
+			$wpdb->insert($wpdb->usermeta, compact('user_id', 'meta_key', 'meta_value') );
+		else if ( $cur->meta_value != $meta_value )
+			$wpdb->update($wpdb->usermeta, compact('meta_value'), compact('user_id', 'meta_key') );
+		else
+			return false;
+	}
 
 	wp_cache_delete($user_id, 'users');
 
