Index: wp-includes/js/wp-ajax-js.php
===================================================================
--- wp-includes/js/wp-ajax-js.php	(revision 0)
+++ wp-includes/js/wp-ajax-js.php	(revision 0)
@@ -0,0 +1,74 @@
+<?php @require_once('../../wp-config.php'); cache_javascript_headers(); ?>
+var WPAjax = Class.create();
+Object.extend(WPAjax.prototype, Ajax.Request.prototype);
+Object.extend(WPAjax.prototype, {
+	WPComplete: false, // onComplete function
+	WPError: false, // onWPError function
+	initialize: function(url, responseEl) {
+		var tempObj = this;
+		this.transport = Ajax.getTransport();
+		if ( !this.transport )
+			return false;
+		this.setOptions( {
+			parameters: 'cookie=' + encodeURIComponent(document.cookie),
+			onComplete: function(transport) { // transport = XMLHttpRequest object
+				if ( tempObj.parseAjaxResponse() ) {
+					if ( 'function' == typeof tempObj.WPComplete )
+						tempObj.WPComplete(transport);
+				} else if ( 'function' == typeof tempObj.WPError ) // if response corresponds to an error (bad data, say, not 404)
+					tempObj.WPError(transport);
+			}
+		});
+		this.url = url;
+		this.getResponseElement(responseEl);
+	},
+	addArg: function(key, value) {
+		var a = $H(this.options.parameters.parseQuery());
+		a[encodeURIComponent(key)] = encodeURIComponent(value);
+		this.options.parameters = a.map(function(pair) {
+			return pair.join('=');
+		}).join('&');
+	},
+	getResponseElement: function(r) {
+		var p = $(r + '-p');
+		if ( !p ) {
+			new Insertion.Bottom(r, "<span id='" + r + "-p'></span>");
+			var p = $(r + '-p');
+		}
+		this.myResponseElement = p;
+	},
+	parseAjaxResponse: function() { // 1 = good, 0 = strange (bad data?), -1 = you lack permission
+		if ( this.transport.responseXML && typeof this.transport.responseXML == 'object' ) {
+			var err = this.transport.responseXML.getElementsByTagName('wp_error');
+			if ( err[0] ) {
+				var msg = $A(err).inject( '', function(a, b) { return a + '<p>' + b.firstChild.nodeValue + '</p>'; } );
+				this.myResponseElement.update('<div class="error">' + msg + '</div>');
+				return false;
+			}
+			return true;
+		}
+		var r = this.transport.responseText;
+		if ( isNaN(r) ) {
+			this.myResponseElement.update('<div class="error"><p>' + r + '</p></div>');
+			return false;
+		}
+		var r = parseInt(r,10);
+		if ( -1 == r ) {
+			this.myResponseElement.update("<div class='error'><p><?php _e("You don't have permission to do that."); ?></p></div>");
+			return false;
+		} else if ( 0 == r ) {
+			this.myResponseElement.update("<div class='error'><p><?php _e("Something strange happened.  Try refreshing the page."); ?></p></div>");
+			return false;
+		}
+		return true;
+	},
+	addOnComplete: function(f) {
+		if ( 'function' == typeof f ) { var of = this.WPComplete; this.WPComplete = function(t) { if ( of ) of(t); f(t); } }
+	},
+	addOnWPError: function(f) {
+		if ( 'function' == typeof f ) { var of = this.WPError; this.WPError = function(t) { if ( of ) of(t); f(t); } }
+	},
+	notInitialized: function() {
+		return this.transport ? false : true;
+	}
+});
Index: wp-includes/js/list-manipulation-js.php
===================================================================
--- wp-includes/js/list-manipulation-js.php	(revision 0)
+++ wp-includes/js/list-manipulation-js.php	(revision 0)
@@ -0,0 +1,252 @@
+<?php
+@require_once('../../wp-config.php');
+cache_javascript_headers();
+$handler =  get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php';
+?>
+addLoadEvent(function(){theList=new listMan();});
+function deleteSomething(what,id,message,obj){if(!obj)obj=theList;if(!message)message="<?php printf(__('Are you sure you want to delete this %s?'),"'+what+'"); ?>";if(confirm(message))return obj.ajaxDelete(what,id);else return false;}
+function dimSomething(what,id,dimClass,obj){if(!obj)obj=theList;return obj.ajaxDimmer(what,id,dimClass);}
+
+var listMan = Class.create();
+Object.extend(listMan.prototype, {
+	reg_color: '#FFFFFF',
+	alt_color: '#F1F1F1',
+	ajaxRespEl: 'ajax-response',
+	ajaxHandler: '<?php echo $handler; ?>',
+	inputData: '',
+	clearInputs: [],
+	showLink: true,
+	topAdder: false,
+	alt: 'alternate',
+	addComplete: null,
+	delComplete: null,
+	dimComplete: null,
+	dataStore: null,
+
+	initialize: function(theListId) {
+		this.theList = $(theListId ? theListId : 'the-list');
+		if ( !this.theList )
+			return false;
+		this.theList.cleanWhitespace();
+	},
+
+	// sends add-what and fields contained in where
+	// recieves html with top element having an id like what-#
+	ajaxAdder: function( what, where, update ) { // Do NOT wrap TR in TABLE TBODY
+		var ajaxAdd = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if ( ajaxAdd.notInitialized() )
+			return true;
+		ajaxAdd.options.parameters += '&action=' + ( update ? 'update-' : 'add-' ) + what + '&' + this.grabInputs(where) + this.inputData;
+		var tempObj=this;
+		ajaxAdd.addOnComplete( function(transport) {
+			var newItems = $A(transport.responseXML.getElementsByTagName(what));
+			if ( newItems ) {
+				newItems.each( function(i) {
+					var id = i.getAttribute('id');
+					var exists = $(what+'-'+id);
+					if ( exists )
+						tempObj.replaceListItem( exists, getNodeValue(i,'response_data'), update );
+					else
+						tempObj.addListItem( getNodeValue(i, 'response_data') );
+					if ( tempObj.showLink )
+						tempObj.showLink = id;
+				});
+			}
+			ajaxAdd.myResponseElement.update(tempObj.showLink ? ( "<div id='jumplink' class='updated fade'><p><a href='#" + what + '-' + tempObj.showLink + "'><?php _e('Jump to new item'); ?></a></p></div>" ) : '');
+			tempObj.clear();
+			if ( tempObj.addComplete && typeof tempObj.addComplete == 'function' )
+				tempObj.addComplete( what, where, update, transport );
+			tempObj.recolorList();
+		});
+		ajaxAdd.request(ajaxAdd.url);
+		return false;
+	},
+
+	// sends update-what and fields contained in where
+	// recieves html with top element having an id like what-#
+	ajaxUpdater: function( what, where ) { return this.ajaxAdder( what, where, true ); },
+
+	// sends delete-what and id#
+	ajaxDelete: function( what, id ) {
+		var ajaxDel = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if( ajaxDel.notInitialized() )
+			return true;
+		var tempObj = this;
+		var action = 'delete-' + what + '&id=' + id;
+		var idName = what.replace('-as-spam','') + '-' + id;
+		ajaxDel.addOnComplete( function(transport) {
+			ajaxDel.myResponseElement.update('');
+			tempObj.destore(action);
+			if( tempObj.delComplete && typeof tempObj.delComplete == 'function' )
+				tempObj.delComplete( what, id, transport );
+		});
+		ajaxDel.addOnWPError( function(transport) { tempObj.restore(action, true); });
+		ajaxDel.options.parameters += '&action=' + action + this.inputData;
+		ajaxDel.request(ajaxDel.url);
+		this.store(action, idName);
+		tempObj.removeListItem( idName );
+		return false;
+	},
+
+	// Toggles class nomes
+	// sends dim-what and id#
+	ajaxDimmer: function( what, id, dimClass ) {
+		ajaxDim = new WPAjax( this.ajaxHandler, this.ajaxRespEl );
+		if ( ajaxDim.notInitialized() )
+			return true;
+		var tempObj = this;
+		var action = 'dim-' + what + '&id=' + id;
+		var idName = what + '-' + id;
+		ajaxDim.addOnComplete( function(transport) {
+			ajaxDim.myResponseElement.update('');
+			tempObj.destore(action);
+			if ( tempObj.dimComplete && typeof tempObj.dimComplete == 'function' )
+				tempObj.dimComplete( what, id, dimClass, transport );
+		});
+		ajaxDim.addOnWPError( function(transport) { tempObj.restore(action, true); });
+		ajaxDim.options.parameters += '&action=' + action + this.inputData;
+		ajaxDim.request(ajaxDim.url);
+		this.store(action, idName);
+		this.dimItem( idName, dimClass );
+		return false;
+	},
+
+	addListItem: function( h ) {
+		new Insertion[this.topAdder ? 'Top' : 'Bottom'](this.theList,h);
+		this.theList.cleanWhitespace();
+		var id = this.topAdder ? this.theList.firstChild.id : this.theList.lastChild.id;
+		if ( this.alt )
+			if ( this.theList.childNodes.length % 2 )
+				$(id).addClassName(this.alt);
+		Fat.fade_element(id);
+	},
+
+	// only hides the element sa it can be put back again if necessary
+	removeListItem: function( id, noFade ) {
+		id = $(id);
+		if ( !noFade ) {
+			Fat.fade_element(id.id,null,700,'#FF3333');
+			var tempObj = this;
+			var func = function() { id.hide(); tempObj.recolorList(); }
+			setTimeout(func, 705);
+		} else {
+			id.hide();
+			this.recolorList();
+		}
+	},
+
+	replaceListItem: function( id, h, update ) {
+		id = $(id);
+		if ( !update ) {
+			id.remove();
+			this.addListItem( h );
+			return;
+		}
+		id.replace(h);
+		Fat.fade_element(id.id);
+	},
+
+	// toggles class
+	dimItem: function( id, dimClass, noFade ) {
+		id = $(id);
+		if ( id.hasClassName(dimClass) ) {
+			if ( !noFade )
+				Fat.fade_element(id.id,null,700,null);
+			id.removeClassName(dimClass);
+		} else {
+			if ( !noFade )
+				Fat.fade_element(id.id,null,700,'#FF3333');
+			id.addClassName(dimClass);
+		}
+	},
+
+	// store an element in case we need it later
+	store: function(action, id) {
+		if ( !this.dataStore )
+			this.dataStore = $H();
+		this.dataStore[action] = $(id).cloneNode(true);
+	},
+
+	// delete from store
+	destore: function(action) { delete(this.dataStore[action]); },
+
+	// restore element from store into existing (possibly hidden) element of same id
+	restore: function(action, error) {
+		var id = this.dataStore[action].id;
+		this.theList.replaceChild(this.dataStore[action], $(id));
+		delete(this.dataStore[action]);
+		if ( error ) {
+			func = function() { $(id).setStyle( { 'background-color': '#FF3333' } ); }
+			func(); setTimeout(func, 705); // Hit it twice in case it's still fading.
+		}
+	},
+
+	// Like Form.serialize, but excludes action and sets up clearInputs
+	grabInputs: function( where ) {
+		var elements = Form.getElements($(where));
+		var queryComponents = new Array();
+		for (var i = 0; i < elements.length; i++) {
+			if ( 'action' == elements[i].name )
+				continue;
+			if ( 'hidden' != elements[i].type && 'submit' != elements[i].type && 'button' != elements[i].type )
+				this.clearInputs.push(elements[i]);
+			var queryComponent = Form.Element.serialize(elements[i]);
+			if (queryComponent)
+				queryComponents.push(queryComponent);
+		}
+		return queryComponents.join('&');
+	},
+
+	// form.reset() can only do whole forms.  This can do subsections.
+	clear: function() {
+		this.clearInputs.each( function(i) {
+			if ( 'textarea' == i.tagName.toLowerCase() )
+				i.value = '';
+			else
+				switch ( i.type.toLowerCase() ) {
+					case 'password': case 'text':
+						i.value = '';
+						break;
+					case 'checkbox': case 'radio':
+						i.checked = false;
+						break;
+					case 'select': case 'select-one':
+						i.selectedIndex = null;
+						break;
+					case 'select-multiple':
+						for (var o = 0; o < i.length; o++) i.options[o].selected = false;
+						break;
+				}
+		});
+		this.clearInputs = [];
+	},
+
+	recolorList: function() {
+		if ( !this.alt )
+			return;
+		var alt = this.alt;
+		var listItems = $A(this.theList.childNodes).findAll( function(i) { return i.visible() } );
+		listItems.each( function(i,n) {
+			if ( n % 2 )
+				i.removeClassName(alt);
+			else
+				i.addClassName(alt);
+		});
+	}
+});
+
+//No submit unless code returns true.
+function killSubmit ( code, e ) {
+	e = e ? e : window.event;
+	if ( !e ) return;
+	var t = e.target ? e.target : e.srcElement;
+	if ( ( 'text' == t.type && e.keyCode == 13 ) || ( 'submit' == t.type && 'click' == e.type ) ) {
+		if ( ( 'string' == typeof code && !eval(code) ) || ( 'function' == typeof code && !code() ) ) {
+			e.returnValue = false; e.cancelBubble = true; return false;
+		}
+	}
+}
+//Pretty func adapted from ALA http://www.alistapart.com/articles/gettingstartedwithajax
+function getNodeValue(tree,el){try { var r = tree.getElementsByTagName(el)[0].firstChild.nodeValue; } catch(err) { var r = null; } return r; }
+//Generic but lame JS closure
+function encloseFunc(f){var a=arguments[1];return function(){return f(a);}}
Index: wp-includes/classes.php
===================================================================
--- wp-includes/classes.php	(revision 4165)
+++ wp-includes/classes.php	(working copy)
@@ -709,4 +709,67 @@
 	}
 }
 
+class WP_Ajax_Response {
+	var $responses = array();
+
+	function WP_Ajax_Response( $args = '' ) {
+		if ( !empty($args) )
+			$this->add($args);
+	}
+
+	// a WP_Error object can be passed in 'id' or 'data'
+	function add( $args = '' ) {
+		if ( is_array($args) )
+			$r = &$args;
+		else
+			parse_str($args, $r);
+
+		$defaults = array('what' => 'object', 'action' => false, 'id' => '0', 'old_id' => false,
+				'data' => '', 'supplemental' => array());
+
+		$r = array_merge($defaults, $r);
+		extract($r);
+
+		if ( is_wp_error($id) ) {
+			$data = $id;
+			$id = 0;
+		}
+
+		$response = '';
+		if ( is_wp_error($data) )
+			foreach ( $data->get_error_codes() as $code )
+				$response .= "<wp_error code='$code'><![CDATA[" . $data->get_error_message($code) . "]]></wp_error>";
+		else
+			$response = "<response_data><![CDATA[$data]]></response_data>";
+
+		$s = '';
+		if ( (array) $supplemental )
+			foreach ( $supplemental as $k => $v )
+				$s .= "<$k><![CDATA[$v]]></$k>";
+
+		if ( false === $action )
+			$action = $_POST['action'];
+
+		$x = '';
+		$x .= "<response action='$action_$id'>"; // The action attribute in the xml output is formatted like a nonce action
+		$x .=	"<$what id='$id'" . ( false !== $old_id ? "old_id='$old_id'>" : '>' );
+		$x .=		$response;
+		$x .=		$s;
+		$x .=	"</$what>";
+		$x .= "</response>";
+
+		$this->responses[] = $x;
+		return $x;
+	}
+
+	function send() {
+		header('Content-type: text/xml');
+		echo "<?xml version='1.0' standalone='yes'?><wp_ajax>";
+		foreach ( $this->responses as $response )
+			echo $response;
+		echo '</wp_ajax>';
+		die();
+	}
+}
+
 ?>
Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php	(revision 4165)
+++ wp-includes/script-loader.php	(working copy)
@@ -19,9 +19,11 @@
 		$this->add( 'wp_tiny_mce', '/wp-includes/js/tinymce/tiny_mce_config.php', array('tiny_mce'), '04162006' );
 		$this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.5.0');
 		$this->add( 'autosave', '/wp-includes/js/autosave.js.php', array('prototype', 'sack'), '4107');
+		$this->add( 'wp-ajax', '/wp-includes/js/wp-ajax-js.php', array('prototype'), rand());
+		$this->add( 'listman', '/wp-includes/js/list-manipulation-js.php', array('wp-ajax', 'fat'), rand());
 		if ( is_admin() ) {
 			$this->add( 'dbx-admin-key', '/wp-admin/dbx-admin-key-js.php', array('dbx'), '3651' );
-			$this->add( 'listman', '/wp-admin/list-manipulation-js.php', array('sack', 'fat'), '4042' ); // Make changeset # the correct one
+			$this->add( 'listman-old', '/wp-admin/list-manipulation-js.php', array('sack', 'fat'), '4042' ); // Make changeset # the correct one
 			$this->add( 'ajaxcat', '/wp-admin/cat-js.php', array('listman'), '3684' );
 			$this->add( 'admin-categories', '/wp-admin/categories.js', array('listman'), '3684' );
 			$this->add( 'admin-custom-fields', '/wp-admin/custom-fields.js', array('listman'), '3733' );
Index: wp-admin/users.php
===================================================================
--- wp-admin/users.php	(revision 4165)
+++ wp-admin/users.php	(working copy)
@@ -490,12 +490,10 @@
 
 <?php if ( is_wp_error( $add_user_errors ) ) : ?>
 	<div class="error">
-		<ul>
 		<?php
 			foreach ( $add_user_errors->get_error_messages() as $message )
-				echo "$message<br />";
+				echo "<p>$message<p>";
 		?>
-		</ul>
 	</div>
 <?php endif; ?>
 <div id="ajax-response"></div>
Index: wp-admin/custom-fields.js
===================================================================
--- wp-admin/custom-fields.js	(revision 4165)
+++ wp-admin/custom-fields.js	(working copy)
@@ -1,8 +1,8 @@
-function customFieldsOnComplete() {
-	var pidEl = document.getElementById('post_ID');
+function customFieldsOnComplete( what, where, update, transport ) {
+	var pidEl = $('post_ID');
 	pidEl.name = 'post_ID';
-	pidEl.value = getNodeValue(theList.ajaxAdd.responseXML, 'postid');
-	var aEl = document.getElementById('hiddenaction')
+	pidEl.value = getNodeValue(transport.responseXML, 'postid');
+	var aEl = $('hiddenaction')
 	if ( aEl.value == 'post' ) aEl.value = 'postajaxpost';
 }
 addLoadEvent(customFieldsAddIn);
@@ -21,6 +21,6 @@
 		}
 	}
 
-	document.getElementById('metakeyinput').onkeypress = function(e) {return killSubmit('theList.inputData+="&id="+document.getElementById("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
-	document.getElementById('updatemetasub').onclick = function(e) {return killSubmit('theList.inputData+="&id="+document.getElementById("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
+	$('metakeyinput').onkeypress = function(e) {return killSubmit('theList.inputData+="&id="+$("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
+	$('updatemetasub').onclick = function(e) {return killSubmit('theList.inputData+="&id="+$("post_ID").value;theList.ajaxAdder("meta", "newmeta");', e); };
 }
Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 4165)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -5,7 +5,6 @@
 
 define('DOING_AJAX', true);
 
-
 check_ajax_referer();
 if ( !is_user_logged_in() )
 	die('-1');
@@ -13,19 +12,17 @@
 function get_out_now() { exit; }
 add_action( 'shutdown', 'get_out_now', -1 );
 
-function wp_ajax_echo_meta( $pid, $mid, $key, $value ) {
+function wp_ajax_meta_row( $pid, $mid, $key, $value ) {
 	$value = wp_specialchars($value, true);
 	$key_js = addslashes(wp_specialchars($key, 'double'));
 	$key = wp_specialchars($key, true);
-	$r  = "<meta><id>$mid</id><postid>$pid</postid><newitem><![CDATA[<table><tbody>";
 	$r .= "<tr id='meta-$mid'><td valign='top'>";
 	$r .= "<input name='meta[$mid][key]' tabindex='6' onkeypress='return killSubmit(\"theList.ajaxUpdater(&#039;meta&#039;,&#039;meta-$mid&#039;);\",event);' type='text' size='20' value='$key' />";
 	$r .= "</td><td><textarea name='meta[$mid][value]' tabindex='6' rows='2' cols='30'>$value</textarea></td><td align='center'>";
 	$r .= "<input name='updatemeta' type='button' class='updatemeta' tabindex='6' value='Update' onclick='return theList.ajaxUpdater(&#039;meta&#039;,&#039;meta-$mid&#039;);' /><br />";
 	$r .= "<input name='deletemeta[$mid]' type='submit' onclick=\"return deleteSomething( 'meta', $mid, '";
 	$r .= sprintf(__("You are about to delete the &quot;%s&quot; custom field on this post.\\n&quot;OK&quot; to delete, &quot;Cancel&quot; to stop."), $key_js);
-	$r .= "' );\" class='deletemeta' tabindex='6' value='Delete' />";
-	$r .= "</td></tr></tbody></table>]]></newitem></meta>";
+	$r .= "' );\" class='deletemeta' tabindex='6' value='Delete' /></td></tr>";
 	return $r;
 }
 
@@ -113,7 +110,7 @@
 	if ( !current_user_can( 'manage_categories' ) )
 		die('-1');
 	$names = explode(',', $_POST['newcat']);
-	$r = "<?xml version='1.0' standalone='yes'?><ajaxresponse>";
+	$x = new WP_Ajax_Response();
 	foreach ( $names as $cat_name ) {
 		$cat_name = trim($cat_name);
 		if ( !$category_nicename = sanitize_title($cat_name) )
@@ -121,14 +118,13 @@
 		if ( !$cat_id = category_exists( $cat_name ) )
 			$cat_id = wp_create_category( $cat_name );
 		$cat_name = wp_specialchars(stripslashes($cat_name));
-		$r .= "<category><id>$cat_id</id><newitem><![CDATA[";
-		$r .= "<li id='category-$cat_id'><label for='in-category-$cat_id' class='selectit'>";
-		$r .= "<input value='$cat_id' type='checkbox' checked='checked' name='post_category[]' id='in-category-$cat_id'/> $cat_name</label></li>";
-		$r .= "]]></newitem></category>";
+		$x->add( array(
+			'what' => 'category',
+			'id' => $cat_id,
+			'data' => "<li id='category-$cat_id'><label for='in-category-$cat_id' class='selectit'><input value='$cat_id' type='checkbox' checked='checked' name='post_category[]' id='in-category-$cat_id'/> $cat_name</label></li>"
+		) );
 	}
-	$r .= '</ajaxresponse>';
-	header('Content-type: text/xml');
-	die($r);
+	$x->send();
 	break;
 case 'add-cat' : // From Manage->Categories
 	if ( !current_user_can( 'manage_categories' ) )
@@ -147,12 +143,13 @@
 	}
 	$cat_full_name = wp_specialchars( $cat_full_name, 1 );
 
-	$r  = "<?xml version='1.0' standalone='yes'?><ajaxresponse>";
-	$r .= "<cat><id>$cat->cat_ID</id><name>$cat_full_name</name><newitem><![CDATA[<table><tbody>";
-	$r .= _cat_row( $cat, $level, $cat_full_name );
-	$r .= "</tbody></table>]]></newitem></cat></ajaxresponse>";
-	header('Content-type: text/xml');
-	die($r);
+	$x = new WP_Ajax_Response( array(
+		'what' => 'cat',
+		'id' => $cat->cat_ID,
+		'data' => _cat_row( $cat, $level, $cat_full_name ),
+		'supplemental' => array('name' => $cat_full_name)
+	) );
+	$x->send();
 	break;
 case 'add-meta' :
 	if ( !current_user_can( 'edit_post', $id ) )
@@ -171,11 +168,13 @@
 	$value = $meta->meta_value;
 	$pid = (int) $meta->post_id;
 
-	$r = "<?xml version='1.0' standalone='yes'?><ajaxresponse>";
-	$r .= wp_ajax_echo_meta( $pid, $mid, $key, $value );
-	$r .= '</ajaxresponse>';
-	header('Content-type: text/xml');
-	die($r);
+	$x = new WP_Ajax_Response( array(
+		'what' => 'meta',
+		'id' => $mid,
+		'data' => wp_ajax_meta_row( $pid, $mid, $key, $value ),
+		'supplemental' => array('postid' => $pid)
+	) );
+	$x->send();
 	break;
 case 'update-meta' :
 	$mid = (int) array_pop(array_keys($_POST['meta']));
@@ -185,33 +184,36 @@
 		die('0');
 	if ( !current_user_can( 'edit_post', $meta->post_id ) )
 		die('-1');
-	$r = "<?xml version='1.0' standalone='yes'?><ajaxresponse>";
 	if ( $u = update_meta( $mid, $key, $value ) ) {
 		$key = stripslashes($key);
 		$value = stripslashes($value);
-		$r .= wp_ajax_echo_meta( $meta->post_id, $mid, $key, $value );
+		$x = new WP_Ajax_Response( array(
+			'what' => 'meta',
+			'id' => $mid,
+			'data' => wp_ajax_meta_row( $meta->post_id, $mid, $key, $value ),
+			'supplemental' => array('postid' => $meta->post_id)
+		) );
+		$x->send();
 	}
-	$r .= '</ajaxresponse>';
-	header('Content-type: text/xml');
-	die($r);
+	die('0');
 	break;
 case 'add-user' :
 	if ( !current_user_can('edit_users') )
 		die('-1');
 	require_once(ABSPATH . WPINC . '/registration.php');
-	$user_id = add_user();
-	if ( is_wp_error( $user_id ) ) {
+	if ( !$user_id = add_user() )
+		die('0');
+	elseif ( is_wp_error( $user_id ) ) {
 		foreach( $user_id->get_error_messages() as $message )
-			echo "$message<br />";
-	exit;
-	} elseif ( !$user_id ) {
-		die('0');
+			echo "<p>$message<p>";
+		exit;
 	}
-	$r  = "<?xml version='1.0' standalone='yes'?><ajaxresponse><user><id>$user_id</id><newitem><![CDATA[<table><tbody>";
-	$r .= user_row( $user_id );
-	$r .= "</tbody></table>]]></newitem></user></ajaxresponse>";
-	header('Content-type: text/xml');
-	die($r);
+	$x = new WP_Ajax_Response( array(
+		'what' => 'user',
+		'id' => $user_id,
+		'data' => user_row( $user_id )
+	) );
+	$x->send();
 	break;
 case 'autosave' :
 	$_POST['post_content'] = $_POST['content'];
Index: wp-admin/categories.js
===================================================================
--- wp-admin/categories.js	(revision 4165)
+++ wp-admin/categories.js	(working copy)
@@ -1,9 +1,9 @@
 addLoadEvent(function() {
 	if (!theList.theList) return false;
 	document.forms.addcat.submit.onclick = function(e) {return killSubmit('theList.ajaxAdder("cat", "addcat");', e); };
-	theList.addComplete = function(what, where, update) {
-		var name = getNodeValue(theList.ajaxAdd.responseXML, 'name');
-		var id = getNodeValue(theList.ajaxAdd.responseXML, 'id');
+	theList.addComplete = function(what, where, update, transport) {
+		var name = getNodeValue(transport.responseXML, 'name');
+		var id = transport.responseXML.getElementsByTagName(what)[0].getAttribute('id');
 		var options = document.forms['addcat'].category_parent.options;
 		options[options.length] = new Option(name, id);
 	};
Index: wp-admin/cat-js.php
===================================================================
--- wp-admin/cat-js.php	(revision 4165)
+++ wp-admin/cat-js.php	(working copy)
@@ -5,31 +5,10 @@
 addLoadEvent(function(){catList=new listMan('categorychecklist');catList.ajaxRespEl='jaxcat';catList.topAdder=1;catList.alt=0;catList.showLink=0;});
 addLoadEvent(newCatAddIn);
 function newCatAddIn() {
-	if ( !document.getElementById('jaxcat') ) return false;
-	var ajaxcat = document.createElement('span');
-	ajaxcat.id = 'ajaxcat';
-
-	newcat = document.createElement('input');
-	newcat.type = 'text';
-	newcat.name = 'newcat';
-	newcat.id = 'newcat';
-	newcat.size = '16';
-	newcat.setAttribute('autocomplete', 'off');
-	newcat.onkeypress = function(e) { return killSubmit("catList.ajaxAdder('category','categorydiv');", e); };
-
-	var newcatSub = document.createElement('input');
-	newcatSub.type = 'button';
-	newcatSub.name = 'Button';
-	newcatSub.id = 'catadd';
-	newcatSub.value = 'Add';
-	newcatSub.onclick = function() { catList.ajaxAdder('category', 'categorydiv'); };
-
-	ajaxcat.appendChild(newcat);
-	ajaxcat.appendChild(newcatSub);
-	document.getElementById('jaxcat').appendChild(ajaxcat);
-
-	howto = document.createElement('span');
-	howto.innerHTML = "<?php _e('Separate multiple categories with commas.'); ?>";
-	howto.id = 'howto';
-	ajaxcat.appendChild(howto);
+	var jaxcat = $('jaxcat');
+	if ( !jaxcat )
+		return false;
+	jaxcat.update('<span id="ajaxcat"><input type="text" name="newcat" id="newcat" size="16" autocomplete="off"/><input type="button" name="Button" id="catadd" value="Add"/><span id="howto"><?php _e('Separate multiple categories with commas.'); ?></span></span>');
+	$('newcat').onkeypress = function(e) { return killSubmit("catList.ajaxAdder('category','jaxcat');", e); };
+	$('catadd').onclick = function() { catList.ajaxAdder('category', 'jaxcat'); };
 }
