Index: wp-admin/admin-ajax.php
===================================================================
--- wp-admin/admin-ajax.php	(revision 10220)
+++ wp-admin/admin-ajax.php	(working copy)
@@ -44,6 +44,11 @@
 		die('-1');
 
 	$s = $_GET['q']; // is this slashed already?
+	
+	if ( isset($_GET['tax']) )
+		$taxonomy = sanitize_title($_GET['tax']);
+	else
+		die('0');
 
 	if ( false !== strpos( $s, ',' ) ) {
 		$s = explode( ',', $s );
@@ -52,7 +57,9 @@
 	$s = trim( $s );
 	if ( strlen( $s ) < 2 )
 		die; // require 2 chars for matching
-	$results = $wpdb->get_col( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = 'post_tag' AND t.name LIKE ('%". $s . "%')" );
+
+	$results = $wpdb->get_col( "SELECT t.name FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = '$taxonomy' AND t.name LIKE ('%" . $s . "%')" );
+
 	echo join( $results, "\n" );
 	die;
 	break;
@@ -490,7 +497,12 @@
 	if ( !current_user_can( 'manage_categories' ) )
 		die('-1');
 
-	$tags = get_tags( array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ) );
+	if ( isset($_POST['tax']) )
+		$taxonomy = sanitize_title($_POST['tax']);
+	else
+		die('0');
+	
+	$tags = get_tags( array( 'number' => 45, 'orderby' => 'count', 'order' => 'DESC' ), $taxonomy );
 
 	if ( empty( $tags ) )
 		die( __('No tags found!') );
@@ -776,7 +788,6 @@
 	global $current_user;
 
 	$_POST['post_category'] = explode(",", $_POST['catslist']);
-	$_POST['tags_input'] = explode(",", $_POST['tags_input']);
 	if($_POST['post_type'] == 'page' || empty($_POST['post_category']))
 		unset($_POST['post_category']);
 
Index: wp-admin/css/colors-classic.css
===================================================================
--- wp-admin/css/colors-classic.css	(revision 10220)
+++ wp-admin/css/colors-classic.css	(working copy)
@@ -682,12 +682,12 @@
 	color: #448abd;
 }
 
-#tagchecklist span a,
+.tagchecklist span a,
 #bulk-titles div a {
 	background: url(../images/xit.gif) no-repeat;
 }
 
-#tagchecklist span a:hover,
+.tagchecklist span a:hover,
 #bulk-titles div a:hover {
 	background: url(../images/xit.gif) no-repeat -10px 0;
 }
@@ -1007,7 +1007,7 @@
 
 #timestampdiv input,
 #namediv input,
-#tagsdiv #the-tagcloud {
+#poststuff .inside .the-tagcloud {
 	border-color: #ddd;
 }
 
Index: wp-admin/css/colors-fresh.css
===================================================================
--- wp-admin/css/colors-fresh.css	(revision 10220)
+++ wp-admin/css/colors-fresh.css	(working copy)
@@ -682,12 +682,12 @@
 	color: #448abd;
 }
 
-#tagchecklist span a,
+.tagchecklist span a,
 #bulk-titles div a {
 	background: url(../images/xit.gif) no-repeat;
 }
 
-#tagchecklist span a:hover,
+.tagchecklist span a:hover,
 #bulk-titles div a:hover {
 	background: url(../images/xit.gif) no-repeat -10px 0;
 }
@@ -1007,7 +1007,7 @@
 
 #timestampdiv input,
 #namediv input,
-#tagsdiv #the-tagcloud {
+#poststuff .inside .the-tagcloud {
 	border-color: #ddd;
 }
 
Index: wp-admin/css/ie-rtl.css
===================================================================
--- wp-admin/css/ie-rtl.css	(revision 10220)
+++ wp-admin/css/ie-rtl.css	(working copy)
@@ -44,7 +44,7 @@
 	padding-right: 0;
 	padding-left: 1px;
 }
-#tagchecklist span a {
+.tagchecklist span a {
 	margin: 4px -9px 0 0;
 }
 .widefat th input {
Index: wp-admin/css/ie.css
===================================================================
--- wp-admin/css/ie.css	(revision 10220)
+++ wp-admin/css/ie.css	(working copy)
@@ -245,7 +245,7 @@
 li.widget-list-control-item h4,
 .widget-sortable,
 .widget-control-actions,
-#tagchecklist,
+.tagchecklist,
 #col-container,
 #col-left,
 #col-right {
@@ -296,12 +296,12 @@
 	padding-right: 1px;
 }
 
-#tagchecklist span, #tagchecklist span a {
+.tagchecklist span, .tagchecklist span a {
 	display: inline-block;
 	display: block;
 }
 
-#tagchecklist span a {
+.tagchecklist span a {
 	margin: 4px 0 0 -9px;
 }
 
Index: wp-admin/edit-form-advanced.php
===================================================================
--- wp-admin/edit-form-advanced.php	(revision 10220)
+++ wp-admin/edit-form-advanced.php	(working copy)
@@ -263,15 +263,38 @@
  *
  * @param object $post
  */
-function post_tags_meta_box($post) {
+function post_tags_meta_box($post, $box) {
+	$tax_name = substr($box['id'], 8); 
+	$taxonomy = get_taxonomy($tax_name);
+	$helps    = attribute_escape($taxonomy->helps);
 ?>
-<p id="jaxtag"><label class="hidden" for="newtag"><?php _e('Tags'); ?></label><input type="text" name="tags_input" class="tags-input" id="tags-input" size="40" tabindex="3" value="<?php echo get_tags_to_edit( $post->ID ); ?>" /></p>
-<div id="tagchecklist"></div>
-<p id="tagcloud-link" class="hide-if-no-js"><a href='#'><?php _e( 'Choose from the most popular tags' ); ?></a></p>
+<div class="tagsdiv" id="<?php echo $tax_name; ?>"> 
+	<p class="jaxtag">
+		<label class="hidden" for="newtag"><?php _e( $box['title'] ); ?></label>
+		<input type="hidden" name="<?php echo "tax_input[$tax_name]"; ?>" class="the-tags" id="tax-input[<?php echo $tax_name; ?>]" value="<?php echo get_tags_to_edit( $post->ID, $tax_name ); ?>" /> 
+	 
+	<span class="ajaxtag" style="display:none;">
+		<input type="text" name="newtag[<?php echo $tax_name; ?>]" class="newtag form-input-tip" size="16" autocomplete="off" value="<?php _e('Add new tag'); ?>" />
+		<input type="button" class="button tagadd" value="<?php _e('Add'); ?>" tabindex="3" />
+	</span>
+	<?php echo $helps ? "<div class='howto'>$helps</div>" : ''; ?>
+	</p> 
+	<div class="tagchecklist"></div> 
+</div> 
+<p class="tagcloud-link hide-if-no-js"><a href="#titlediv" class="tagcloud-link" id="link-<?php echo $tax_name; ?>"><?php printf( __('Choose from the most used tags in %s'), $box['title'] ); ?></a></p>
 <?php
 }
-add_meta_box('tagsdiv', __('Tags'), 'post_tags_meta_box', 'post', 'side', 'core');
 
+// all tag-style post taxonomies 
+foreach ( get_object_taxonomies('post') as $tax_name ) { 
+	if ( !is_taxonomy_hierarchical($tax_name) ) { 
+		$taxonomy = get_taxonomy($tax_name);
+		$label = isset($taxonomy->label) ? attribute_escape($taxonomy->label) : $tax_name;
+
+		add_meta_box('tagsdiv-' . $tax_name, $label, 'post_tags_meta_box', 'post', 'side', 'core'); 
+	} 
+} 
+
 /**
  * Display post categories form fields.
  *
Index: wp-admin/includes/taxonomy.php
===================================================================
--- wp-admin/includes/taxonomy.php	(revision 10220)
+++ wp-admin/includes/taxonomy.php	(working copy)
@@ -194,21 +194,25 @@
  * @param unknown_type $post_id
  * @return unknown
  */
-function get_tags_to_edit( $post_id ) {
+function get_tags_to_edit( $post_id, $taxonomy = 'post_tag' ) {
 	$post_id = (int) $post_id;
 	if ( !$post_id )
 		return false;
 
-	$tags = wp_get_post_tags($post_id);
+	$tags = wp_get_post_tags($post_id, array(), $taxonomy);
 
 	if ( !$tags )
 		return false;
 
+	if ( is_wp_error($tags) )
+		return show_message($tags);
+	
 	foreach ( $tags as $tag )
 		$tag_names[] = $tag->name;
 	$tags_to_edit = join( ',', $tag_names );
 	$tags_to_edit = attribute_escape( $tags_to_edit );
-	$tags_to_edit = apply_filters( 'tags_to_edit', $tags_to_edit );
+	$tags_to_edit = apply_filters( 'tags_to_edit', $tags_to_edit, $taxonomy );
+
 	return $tags_to_edit;
 }
 
@@ -220,8 +224,8 @@
  * @param unknown_type $tag_name
  * @return unknown
  */
-function tag_exists($tag_name) {
-	return is_term($tag_name, 'post_tag');
+function tag_exists($tag_name, $taxonomy = 'post_tag') {
+	return is_term($tag_name, $taxonomy);
 }
 
 /**
@@ -232,11 +236,9 @@
  * @param unknown_type $tag_name
  * @return unknown
  */
-function wp_create_tag($tag_name) {
-	if ( $id = tag_exists($tag_name) )
+function wp_create_tag($tag_name, $taxonomy = 'post_tag') {
+	if ( $id = tag_exists($tag_name, $taxonomy) )
 		return $id;
 
-	return wp_insert_term($tag_name, 'post_tag');
+	return wp_insert_term($tag_name, $taxonomy);
 }
-
-?>
Index: wp-admin/includes/template.php
===================================================================
--- wp-admin/includes/template.php	(revision 10220)
+++ wp-admin/includes/template.php	(working copy)
@@ -2695,7 +2695,7 @@
  * @param string $context The context within the page where the boxes should show ('normal', 'advanced').
  * @param string $priority The priority within the context where the boxes should show ('high', 'low').
  */
-function add_meta_box($id, $title, $callback, $page, $context = 'advanced', $priority = 'default') {
+function add_meta_box($id, $title, $callback, $page, $context = 'advanced', $priority = 'default', $callback_args=null) {
 	global $wp_meta_boxes;
 
 	if ( !isset($wp_meta_boxes) )
@@ -2729,6 +2729,7 @@
 		} elseif ( 'sorted' == $priority ) {
 			$title = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['title'];
 			$callback = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['callback'];
+			$callback_args = $wp_meta_boxes[$page][$a_context][$a_priority][$id]['args'];
 		}
 		// An id can be in only one priority and one context
 		if ( $priority != $a_priority || $context != $a_context )
@@ -2742,7 +2743,7 @@
 	if ( !isset($wp_meta_boxes[$page][$context][$priority]) )
 		$wp_meta_boxes[$page][$context][$priority] = array();
 
-	$wp_meta_boxes[$page][$context][$priority][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback);
+	$wp_meta_boxes[$page][$context][$priority][$id] = array('id' => $id, 'title' => $title, 'callback' => $callback, 'args' => $callback_args);
 }
 
 /**
Index: wp-admin/js/post.js
===================================================================
--- wp-admin/js/post.js	(revision 10220)
+++ wp-admin/js/post.js	(working copy)
@@ -1,95 +1,146 @@
 // this file contains all the scripts used in the post/edit page
 
+// return an array with any duplicate, whitespace or values removed
+function array_unique_noempty(a) {
+	var out = [];
+	jQuery.each( a, function(key, val) {
+		val = jQuery.trim(val);
+		if ( val && jQuery.inArray(val, out) == -1 )
+			out.push(val);
+		} );
+	return out;
+}
+
 function new_tag_remove_tag() {
 	var id = jQuery( this ).attr( 'id' );
-	var num = id.substr( 10 );
-	var current_tags = jQuery( '#tags-input' ).val().split(',');
+	var num = id.split('-check-num-')[1];
+	var taxbox = jQuery(this).parents('.tagsdiv');
+	var current_tags = taxbox.find( '.the-tags' ).val().split(',');
 	delete current_tags[num];
 	var new_tags = [];
-	jQuery.each( current_tags, function( key, val ) {
-		if ( val && !val.match(/^\s+$/) && '' != val ) {
-			new_tags = new_tags.concat( val );
+
+	jQuery.each( current_tags, function(key, val) {
+		val = jQuery.trim(val);
+		if ( val ) {
+			new_tags.push(val);
 		}
 	});
-	jQuery( '#tags-input' ).val( new_tags.join( ',' ).replace( /\s*,+\s*/, ',' ).replace( /,+/, ',' ).replace( /,+\s+,+/, ',' ).replace( /,+\s*$/, '' ).replace( /^\s*,+/, '' ) );
-	tag_update_quickclicks();
-	jQuery('#newtag').focus();
+
+	taxbox.find('.the-tags').val( new_tags.join(',').replace(/\s*,+\s*/, ',').replace(/,+/, ',').replace(/,+\s+,+/, ',').replace(/,+\s*$/, '').replace(/^\s*,+/, '') );
+
+	tag_update_quickclicks(taxbox);
 	return false;
 }
 
-function tag_update_quickclicks() {
-	if ( jQuery( '#tags-input' ).length == 0 )
+function tag_update_quickclicks(taxbox) {
+	if ( jQuery(taxbox).find('.the-tags').length == 0 )
 		return;
-	var current_tags = jQuery( '#tags-input' ).val().split(',');
-	jQuery( '#tagchecklist' ).empty();
+
+	var current_tags = jQuery(taxbox).find('.the-tags').val().split(',');
+	jQuery(taxbox).find('.tagchecklist').empty();
 	shown = false;
-//	jQuery.merge( current_tags, current_tags ); // this doesn't work anymore, need something to array_unique
+
 	jQuery.each( current_tags, function( key, val ) {
-		val = val.replace( /^\s+/, '' ).replace( /\s+$/, '' ); // trim
+		val = jQuery.trim(val);
 		if ( !val.match(/^\s+$/) && '' != val ) {
-			txt = '<span><a id="tag-check-' + key + '" class="ntdelbutton">X</a>&nbsp;' + val + '</span> ';
-			jQuery( '#tagchecklist' ).append( txt );
-			jQuery( '#tag-check-' + key ).click( new_tag_remove_tag );
-			shown = true;
+			var button_id = jQuery(taxbox).attr('id') + '-check-num-' + key;
+ 			txt = '<span><a id="' + button_id + '" class="ntdelbutton">X</a>&nbsp;' + val + '</span> ';
+ 			jQuery(taxbox).find('.tagchecklist').append(txt);
+ 			jQuery( '#' + button_id ).click( new_tag_remove_tag );
 		}
 	});
 	if ( shown )
-		jQuery( '#tagchecklist' ).prepend( '<strong>'+postL10n.tagsUsed+'</strong><br />' );
+		jQuery(taxbox).find('.tagchecklist').prepend('<strong>'+postL10n.tagsUsed+'</strong><br />');
 }
 
-function tag_flush_to_text(e,a) {
+function tag_flush_to_text(id, a) {
 	a = a || false;
-	var text = a ? jQuery(a).text() : jQuery('#newtag').val();
-	var newtags = jQuery('#tags-input').val();
+	var taxbox = jQuery('#'+id);
+	var text = a ? jQuery(a).text() : taxbox.find('input.newtag').val();
 
-	var t = text.replace( /\s*([^,]+).*/, '$1,' );
-	newtags += ','
-
-	if ( newtags.indexOf(t) != -1 )
+	// is the input box empty (i.e. showing the 'Add new tag' tip)?
+	if ( taxbox.find('input.newtag').hasClass('form-input-tip') && ! a )
 		return false;
 
-	newtags += text;
+	var tags = taxbox.find('.the-tags').val();
+	var newtags = tags ? tags + ',' + text : text;
 
 	// massage
-	newtags = newtags.replace( /\s+,+\s*/g, ',' ).replace( /,+/g, ',' ).replace( /,+\s+,+/g, ',' ).replace( /,+\s*$/g, '' ).replace( /^\s*,+/g, '' );
-	jQuery('#tags-input').val( newtags );
-	tag_update_quickclicks();
-	if ( ! a ) {
-		jQuery('#newtag').val('');
-		jQuery('#newtag').focus();
-	}
+	newtags = newtags.replace(/\s+,+\s*/g, ',').replace(/,+/g, ',').replace(/,+\s+,+/g, ',').replace(/,+\s*$/g, '').replace(/^\s*,+/g, '');
+	newtags = array_unique_noempty(newtags.split(',')).join(',');
+	taxbox.find('.the-tags').val(newtags);
+	tag_update_quickclicks(taxbox);
+	
+	if ( ! a )
+		taxbox.find('input.newtag').val('').focus();
+
 	return false;
 }
 
 function tag_save_on_publish() {
-	if ( jQuery('#newtag').val() != postL10n.addTag )
-		tag_flush_to_text();
+	jQuery('.tagsdiv').each( function(i) {
+		if ( !jQuery(this).find('input.newtag').hasClass('form-input-tip') )
+        	tag_flush_to_text(jQuery(this).parents('.tagsdiv').attr('id'));
+		} );
 }
 
 function tag_press_key( e ) {
-	if ( 13 == e.keyCode ) {
-		tag_flush_to_text();
+	if ( 13 == e.which ) {
+		tag_flush_to_text(jQuery(e.target).parents('.tagsdiv').attr('id'));
 		return false;
 	}
 };
 
+function tag_init() {
+
+	jQuery('.ajaxtag').show();
+    jQuery('.tagsdiv').each( function(i) {
+        tag_update_quickclicks(this);
+    } );
+
+    // add the quickadd form
+    jQuery('.ajaxtag input.tagadd').click(function(){tag_flush_to_text(jQuery(this).parents('.tagsdiv').attr('id'));});
+    jQuery('.ajaxtag input.newtag').focus(function() {
+        if ( this.value == postL10n.addTag ) {
+            jQuery(this).val( '' ).removeClass( 'form-input-tip' );
+        }
+    });
+
+    jQuery('.ajaxtag input.newtag').blur(function() {
+        if ( this.value == '' ) {
+            jQuery(this).val( postL10n.addTag ).addClass( 'form-input-tip' );
+        }
+    });
+
+    // auto-save tags on post save/publish
+    jQuery('#publish').click( tag_save_on_publish );
+    jQuery('#save-post').click( tag_save_on_publish );
+
+    // catch the enter key
+    jQuery('.ajaxtag input.newtag').keypress( tag_press_key );
+}
+
 (function($){
 	tagCloud = {
 		init : function() {
-			$('#tagcloud-link').click(function(){tagCloud.get(); $(this).unbind().click(function(){return false;}); return false;});
+			$('.tagcloud-link').click(function(){tagCloud.get($(this).attr('id')); $(this).unbind().click(function(){return false;}); return false;});
 		},
 
-		get : function() {
-			$.post('admin-ajax.php', {'action':'get-tagcloud'}, function(r, stat) {
+		get : function(id) {
+			tax = id.substr(id.indexOf('-')+1);
+
+			$.post('admin-ajax.php', {'action':'get-tagcloud','tax':tax}, function(r, stat) {
 				if ( 0 == r || 'success' != stat )
 					r = wpAjax.broken;
 
-				r = '<p id="the-tagcloud">'+r+'</p>';
-				$('#tagcloud-link').after($(r));
-				$('#the-tagcloud a').click(function(){
-					tag_flush_to_text(0,this);
+				r = $('<p id="tagcloud-'+tax+'" class="the-tagcloud">'+r+'</p>');
+				$('a', r).click(function(){
+					var id = $(this).parents('p').attr('id');
+					tag_flush_to_text(id.substr(id.indexOf('-')+1), this);
 					return false;
 				});
+
+				$('#'+id).after(r);
 			});
 		}
 	}
@@ -107,29 +158,16 @@
 	// Editable slugs
 	make_slugedit_clickable();
 
-	jQuery('#tags-input').hide();
-	tag_update_quickclicks();
-	// add the quickadd form
-	jQuery('#jaxtag').prepend('<span id="ajaxtag"><input type="text" name="newtag" id="newtag" class="form-input-tip" size="16" autocomplete="off" value="'+postL10n.addTag+'" /><input type="button" class="button" id="tagadd" value="' + postL10n.add + '" tabindex="3" /><input type="hidden"/><input type="hidden"/><span class="howto">'+postL10n.separate+'</span></span>');
-	jQuery('#tagadd').click( tag_flush_to_text );
-	jQuery('#newtag').focus(function() {
-		if ( this.value == postL10n.addTag )
-			jQuery(this).val( '' ).removeClass( 'form-input-tip' );
-	});
-	jQuery('#newtag').blur(function() {
-		if ( this.value == '' )
-			jQuery(this).val( postL10n.addTag ).addClass( 'form-input-tip' );
-	});
+	// prepare the tag UI
+	tag_init();
 
-	// auto-save tags on post save/publish
-	jQuery('#publish').click( tag_save_on_publish );
-	jQuery('#save-post').click( tag_save_on_publish );
-
 	jQuery('#title').blur( function() { if ( (jQuery("#post_ID").val() > 0) || (jQuery("#title").val().length == 0) ) return; autosave(); } );
 
 	// auto-suggest stuff
-	jQuery('#newtag').suggest( 'admin-ajax.php?action=ajax-tag-search', { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } );
-	jQuery('#newtag').keypress( tag_press_key );
+	jQuery('.newtag').each(function(){
+		var tax = $(this).parents('div.tagsdiv').attr('id');
+		$(this).suggest( 'admin-ajax.php?action=ajax-tag-search&tax='+tax, { delay: 500, minchars: 2, multiple: true, multipleSep: ", " } );
+	});
 
 	// category tabs
 	var categoryTabs =jQuery('#category-tabs').tabs();
Index: wp-admin/rtl.css
===================================================================
--- wp-admin/rtl.css	(revision 10220)
+++ wp-admin/rtl.css	(working copy)
@@ -211,7 +211,7 @@
 #normal-sortables .postbox .submit {
 	float: left;
 }
-#post-body #tagsdiv #newtag {
+#post-body .tagsdiv #newtag {
 	margin-right: 0;
 	margin-left: 5px;
 }
@@ -221,18 +221,18 @@
 #comment-status-radio input {
 	margin: 2px 0 5px 3px;
 }
-#tagchecklist {
+.tagchecklist {
 	margin-left: 0;
 	margin-right: 10px;
 }
-#tagchecklist strong {
+.tagchecklist strong {
 	margin-left: 0;
 	margin-right: -8px;
 }
-#tagchecklist span {
+.tagchecklist span {
 	float: right;
 }
-#tagchecklist span a {
+.tagchecklist span a {
 	margin: 6px -9px 0 0;
 	float: right;
 }
Index: wp-admin/wp-admin.css
===================================================================
--- wp-admin/wp-admin.css	(revision 10220)
+++ wp-admin/wp-admin.css	(working copy)
@@ -1355,7 +1355,7 @@
 	display: none;
 }
 
-#post-body #tagsdiv #newtag {
+#post-body .tagsdiv #newtag {
 	margin-right: 5px;
 	width: 16em;
 }
@@ -1364,7 +1364,7 @@
 	width: 94%
 }
 
-#side-info-column #tagsdiv #newtag {
+#side-info-column .tagsdiv #newtag {
 	width: 68%;
 }
 
@@ -1421,18 +1421,18 @@
 	padding: 5px 0;
 }
 
-#tagchecklist {
+.tagchecklist {
 	margin-left: 10px;
 	font-size: 12px;
 	overflow: auto;
 }
 
-#tagchecklist strong {
+.tagchecklist strong {
 	margin-left: -8px;
 	position: absolute;
 }
 
-#tagchecklist span {
+.tagchecklist span {
 	margin-right: 25px;
 	display: block;
 	float: left;
@@ -1442,7 +1442,7 @@
 	cursor: default;
 }
 
-#tagchecklist span a {
+.tagchecklist span a {
 	margin: 6px 0pt 0pt -9px;
 	cursor: pointer;
 	width: 10px;
@@ -2830,8 +2830,8 @@
 	margin-top: 8px;
 }
 
-#tagsdiv #the-tagcloud {
-	margin: 5px 5px 10px;
+#poststuff .inside .the-tagcloud {
+	margin: 5px 0 10px;
 	padding: 8px;
 	border-width: 1px;
 	border-style: solid;
Index: wp-includes/category.php
===================================================================
--- wp-includes/category.php	(revision 10220)
+++ wp-includes/category.php	(working copy)
@@ -274,15 +274,15 @@
  * @param string|array $args Tag arguments to use when retrieving tags.
  * @return array List of tags.
  */
-function &get_tags( $args = '' ) {
-	$tags = get_terms( 'post_tag', $args );
+function &get_tags( $args = '', $taxonomy = 'post_tag' ) {
+	$tags = get_terms( $taxonomy, $args );
 
 	if ( empty( $tags ) ) {
 		$return = array();
 		return $return;
 	}
 
-	$tags = apply_filters( 'get_tags', $tags, $args );
+	$tags = apply_filters( 'get_tags', $tags, $args, $taxonomy );
 	return $tags;
 }
 
Index: wp-includes/js/autosave.js
===================================================================
--- wp-includes/js/autosave.js	(revision 10220)
+++ wp-includes/js/autosave.js	(working copy)
@@ -130,10 +130,14 @@
 		post_ID:  jQuery("#post_ID").val() || 0,
 		post_title: jQuery("#title").val() || "",
 		autosavenonce: jQuery('#autosavenonce').val(),
-		tags_input: jQuery("#tags-input").val() || "",
+		//tags_input: jQuery("#tags-input").val() || "",
 		post_type: jQuery('#post_type').val() || "",
 		autosave: 1
 	};
+	
+	jQuery('.tags-input').each( function() {
+		post_data[this.name] = this.value;
+	} );
 
 	// We always send the ajax request in order to keep the post lock fresh.
 	// This (bool) tells whether or not to write the post to the DB during the ajax request.
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 10220)
+++ wp-includes/post.php	(working copy)
@@ -1205,13 +1205,13 @@
  * @param array $args Optional. Overwrite the defaults
  * @return array List of post tags.
  */
-function wp_get_post_tags( $post_id = 0, $args = array() ) {
+function wp_get_post_tags( $post_id = 0, $args = array(), $taxonomy = 'post_tag' ) {
 	$post_id = (int) $post_id;
 
 	$defaults = array('fields' => 'all');
 	$args = wp_parse_args( $args, $defaults );
 
-	$tags = wp_get_object_terms($post_id, 'post_tag', $args);
+	$tags = wp_get_object_terms($post_id, $taxonomy, $args);
 
 	return $tags;
 }
@@ -1498,7 +1498,15 @@
 	}
 
 	wp_set_post_categories( $post_ID, $post_category );
-	wp_set_post_tags( $post_ID, $tags_input );
+	// old-style tags_input
+	if ( !empty($tags_input) )
+		wp_set_post_tags( $post_ID, $tags_input );
+	// new-style support for all tag-like taxonomies
+	if ( !empty($tax_input) ) {
+		foreach ( $tax_input as $taxonomy => $tags ) {
+			wp_set_post_tax( $post_ID, $tags, $taxonomy );			
+		}
+	}
 
 	$current_guid = get_post_field( 'guid', $post_ID );
 
@@ -1685,7 +1693,10 @@
  * @return bool|null Will return false if $post_id is not an integer or is 0. Will return null otherwise
  */
 function wp_set_post_tags( $post_id = 0, $tags = '', $append = false ) {
+	return wp_set_post_tax( $post_id, $tags, 'post_tag', $append);
+}
 
+function wp_set_post_tax( $post_id = 0, $tags = '', $taxonomy = 'post_tag', $append = false ) {
 	$post_id = (int) $post_id;
 
 	if ( !$post_id )
@@ -1693,8 +1704,9 @@
 
 	if ( empty($tags) )
 		$tags = array();
-	$tags = (is_array($tags)) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
-	wp_set_object_terms($post_id, $tags, 'post_tag', $append);
+
+	$tags = is_array($tags) ? $tags : explode( ',', trim($tags, " \n\t\r\0\x0B,") );
+	wp_set_object_terms($post_id, $tags, $taxonomy, $append);
 }
 
 /**
Index: wp-includes/script-loader.php
===================================================================
--- wp-includes/script-loader.php	(revision 10220)
+++ wp-includes/script-loader.php	(working copy)
@@ -77,7 +77,7 @@
 		'l10n_print_after' => 'try{convertEntities(wpAjax);}catch(e){};'
 	) );
 
-	$scripts->add( 'autosave', '/wp-includes/js/autosave.js', array('schedule', 'wp-ajax-response'), '20081210' );
+	$scripts->add( 'autosave', '/wp-includes/js/autosave.js', array('schedule', 'wp-ajax-response'), '20081217' );
 
 	$scripts->add( 'wp-lists', '/wp-includes/js/wp-lists.js', array('wp-ajax-response'), '20081210' );
 	$scripts->localize( 'wp-lists', 'wpListL10n', array(
@@ -179,7 +179,7 @@
 			'cancel' => __('Cancel'),
 			'l10n_print_after' => 'try{convertEntities(slugL10n);}catch(e){};'
 		) );
-		$scripts->add( 'post', '/wp-admin/js/post.js', array('suggest', 'jquery-ui-tabs', 'wp-lists', 'postbox', 'slug'), '20081210' );
+		$scripts->add( 'post', '/wp-admin/js/post.js', array('suggest', 'jquery-ui-tabs', 'wp-lists', 'postbox', 'slug'), '20081217' );
 		$scripts->localize( 'post', 'postL10n', array(
 			'tagsUsed' =>  __('Tags used on this post:'),
 			'add' => attribute_escape(__('Add')),
Index: wp-includes/taxonomy.php
===================================================================
--- wp-includes/taxonomy.php	(revision 10220)
+++ wp-includes/taxonomy.php	(working copy)
@@ -17,8 +17,8 @@
  * @global array $wp_taxonomies
  */
 $wp_taxonomies = array();
-$wp_taxonomies['category'] = (object) array('name' => 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count');
-$wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count');
+$wp_taxonomies['category'] = (object) array('name' => 'category', 'object_type' => 'post', 'hierarchical' => true, 'update_count_callback' => '_update_post_term_count', 'label' => __('Categories'));
+$wp_taxonomies['post_tag'] = (object) array('name' => 'post_tag', 'object_type' => 'post', 'hierarchical' => false, 'update_count_callback' => '_update_post_term_count', 'label' => __('Post Tags'));
 $wp_taxonomies['link_category'] = (object) array('name' => 'link_category', 'object_type' => 'link', 'hierarchical' => false);
 
 /**
