Index: wp-includes/category.php
===================================================================
--- wp-includes/category.php	(revision 5182)
+++ wp-includes/category.php	(working copy)
@@ -1,5 +1,8 @@
 <?php
 
+define('TAXONOMY_CATEGORY', 1);
+define('TAXONOMY_TAG', 2);
+
 function get_all_category_ids() {
 	global $wpdb;
 
@@ -78,7 +81,7 @@
 		else
 			$where .= ' AND category_count > 0';
 	} else {
-		$where .= ' AND ( tag_count = 0 OR ( tag_count != 0 AND ( link_count > 0 OR category_count > 0 ) ) ) ';
+		$where .= ' AND ( type & ' . TAXONOMY_CATEGORY . ' != 0 ) ';
 	}
 
 	
Index: wp-includes/version.php
===================================================================
--- wp-includes/version.php	(revision 5182)
+++ wp-includes/version.php	(working copy)
@@ -3,6 +3,6 @@
 // This holds the version number in a separate file so we can bump it without cluttering the SVN
 
 $wp_version = '2.2-bleeding';
-$wp_db_version = 4865;
+$wp_db_version = 5183;
 
 ?>
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 5182)
+++ wp-includes/post.php	(working copy)
@@ -787,7 +787,7 @@
 		if ( !$tag_slug = sanitize_title( $tag ) )
 			continue; // discard
 		if ( !$tag_id = category_exists( $tag ) )
-			$tag_id = wp_create_category( $tag );
+			$tag_id = wp_create_tag( $tag );
 		$tag_ids[] = $tag_id;
 	}
 
@@ -837,9 +837,9 @@
 	$all_affected_tags = array_unique( array_merge( $tag_ids, $old_tags ) );
 	foreach ( $all_affected_tags as $tag_id ) {
 		$count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status = 'publish' AND post_type = 'post' AND category_id = '$tag_id' AND rel_type = 'tag'" );
-		$wpdb->query( "UPDATE $wpdb->categories SET tag_count = '$count' WHERE cat_ID = '$tag_id'" );
+		$wpdb->query( "UPDATE $wpdb->categories SET tag_count = '$count', type = type | " . TAXONOMY_TAG . " WHERE cat_ID = '$tag_id'" );
 		if ( $count == 0 )
-			$wpdb->query( "UPDATE $wpdb->categories SET tag_count = '-1' WHERE cat_ID = '$tag_id'" );
+			$wpdb->query( "UPDATE $wpdb->categories SET type = type & ~". TAXONOMY_TAG . " WHERE cat_ID = '$tag_id'" );
 		clean_category_cache( $tag_id );
 		do_action( 'edit_category', $tag_id );
 		do_action( 'edit_tag', $tag_id );
@@ -876,7 +876,7 @@
 			$wpdb->query("
 				DELETE FROM $wpdb->post2cat
 				WHERE category_id = '$del'
-					AND post_id = '$post_ID'
+					AND post_id = '$post_ID' AND rel_type = 'category'
 				");
 		}
 	}
@@ -898,7 +898,7 @@
 	$all_affected_cats = array_unique(array_merge($post_categories, $old_categories));
 	foreach ( $all_affected_cats as $cat_id ) {
 		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->post2cat, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->post2cat.post_id AND post_status = 'publish' AND post_type = 'post' AND category_id = '$cat_id' AND rel_type = 'category'");
-		$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
+		$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count', type = type | " . TAXONOMY_CATEGORY . " WHERE cat_ID = '$cat_id'");
 		clean_category_cache($cat_id);
 		do_action('edit_category', $cat_id);
 	}
Index: wp-admin/admin-functions.php
===================================================================
--- wp-admin/admin-functions.php	(revision 5182)
+++ wp-admin/admin-functions.php	(working copy)
@@ -647,7 +647,7 @@
 
 function return_categories_list( $parent = 0 ) {
 	global $wpdb;
-	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( ( link_count = 0 AND tag_count = 0 ) OR category_count != 0 OR ( link_count = 0 AND category_count = 0 AND tag_count = 0 ) ) ORDER BY category_count DESC" );
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( type & " . TAXONOMY_CATEGORY . " != 0 ) AND ( link_count = 0 OR category_count != 0 ) ORDER BY category_count DESC" );
 }
 
 function sort_cats( $cat1, $cat2 ) {
@@ -744,7 +744,7 @@
 
 function return_link_categories_list( $parent = 0 ) {
 	global $wpdb;
-	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( ( category_count = 0 AND tag_count = 0 ) OR link_count != 0 OR ( link_count = 0 AND category_count = 0 AND tag_count = 0 ) ) ORDER BY link_count DESC" );
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( type & " . TAXONOMY_CATEGORY . " != 0 ) AND ( category_count = 0 OR link_count != 0 ) ORDER BY link_count DESC" );
 }
 
 function get_nested_link_categories( $default = 0, $parent = 0 ) {
Index: wp-admin/admin-db.php
===================================================================
--- wp-admin/admin-db.php	(revision 5182)
+++ wp-admin/admin-db.php	(working copy)
@@ -121,15 +121,23 @@
 	else
 		$links_private = 0;
 
+	if ( empty($type) )
+		$type = TAXONOMY_CATEGORY;
+
 	// Let's check if we have this category already, if so just do an update
-	if ( $cat_ID = category_exists( $category_nicename ) )
+	if ( $cat_ID = category_exists( $category_nicename ) ) {
 		$update = true;
+		$category = get_category($cat_ID);
+		// If inserting a category that already exists, OR in the new type rather
+		// than replacing the entire value.
+		$type = $category->type | $type;
+	}
 
 	if (!$update) {
-		$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_description, category_parent, links_private, posts_private) VALUES ('0', '$cat_name', '$category_nicename', '$category_description', '$category_parent', '$links_private', '$posts_private')");
+		$wpdb->query("INSERT INTO $wpdb->categories (cat_ID, cat_name, category_nicename, category_description, category_parent, links_private, posts_private, type) VALUES ('0', '$cat_name', '$category_nicename', '$category_description', '$category_parent', '$links_private', '$posts_private', '$type')");
 		$cat_ID = (int) $wpdb->insert_id;
 	} else {
-		$wpdb->query ("UPDATE $wpdb->categories SET cat_name = '$cat_name', category_nicename = '$category_nicename', category_description = '$category_description', category_parent = '$category_parent', links_private = '$links_private', posts_private = '$posts_private' WHERE cat_ID = '$cat_ID'");
+		$wpdb->query ("UPDATE $wpdb->categories SET cat_name = '$cat_name', category_nicename = '$category_nicename', category_description = '$category_description', category_parent = '$category_parent', links_private = '$links_private', posts_private = '$posts_private', type = '$type' WHERE cat_ID = '$cat_ID'");
 	}
 
 	if ( $category_nicename == '' ) {
@@ -195,15 +203,18 @@
 
 	$parent = $category->category_parent;
 
-	// Delete the category
-	if ( !$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'") )
-		return 0;
-
+	// Delete the category if it is not also a tag.
+	if ( 0 == ($category->type & TAXONOMY_TAG) ) {
+		if ( !$wpdb->query("DELETE FROM $wpdb->categories WHERE cat_ID = '$cat_ID'") )
+			return 0;
+	} else {
+		$wpdb->query("UPDATE $wpdb->categories SET type = type & ~" . TAXONOMY_CATEGORY . " WHERE cat_ID = '$cat_ID'");
+	}
 	// Update children to point to new parent
 	$wpdb->query("UPDATE $wpdb->categories SET category_parent = '$parent' WHERE category_parent = '$cat_ID'");
 
 	// Only set posts and links to the default category if they're not in another category already
-	$posts = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE category_id='$cat_ID'");
+	$posts = $wpdb->get_col("SELECT post_id FROM $wpdb->post2cat WHERE category_id='$cat_ID' AND rel_type = 'category'");
 	foreach ( (array) $posts as $post_id ) {
 		$cats = wp_get_post_categories($post_id);
 		if ( 1 == count($cats) )
@@ -257,6 +268,11 @@
 	return (int) $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE category_nicename = '$category_nicename'");
 }
 
+function wp_create_tag($tag_name) {
+	$tag_array = array('cat_name' => $tag_name, 'type' => TAXONOMY_TAG);
+	return wp_insert_category($tag_array);
+}
+
 function wp_delete_user($id, $reassign = 'novalue') {
 	global $wpdb;
 
Index: wp-admin/upgrade-schema.php
===================================================================
--- wp-admin/upgrade-schema.php	(revision 5182)
+++ wp-admin/upgrade-schema.php	(working copy)
@@ -21,6 +21,7 @@
   tag_count bigint(20) NOT NULL default '0',
   posts_private tinyint(1) NOT NULL default '0',
   links_private tinyint(1) NOT NULL default '0',
+  type tinyint NOT NULL default '1',
   PRIMARY KEY  (cat_ID),
   KEY category_nicename (category_nicename)
 ) $charset_collate;

