Index: wp-includes/category.php
===================================================================
--- wp-includes/category.php	(revision 4871)
+++ wp-includes/category.php	(working copy)
@@ -23,11 +23,18 @@
 		'hide_empty' => true, 'include_last_update_time' => false, 'hierarchical' => 1, 'exclude' => '', 'include' => '',
 		'number' => '', 'pad_counts' => false);
 	$r = array_merge($defaults, $r);
-	if ( 'count' == $r['orderby'] )
-		$r['orderby'] = 'category_count';
-	else
+	if ( 'count' == $r['orderby'] ) {
+		if ( 'link' == $type )
+			$r['orderby'] = 'link_count';
+		else if ( 'post' == $type )
+			$r['orderby'] = 'category_count';
+		else
+			$r['orderby'] = 'tagged_count';
+	} else
 		$r['orderby'] = "cat_" . $r['orderby'];  // restricts order by to cat_ID and cat_name fields
 	$r['number'] = (int) $r['number'];
+	if ( 'tag' == $type )
+		$r['hierarchical'] = 0;
 	extract($r);
 
 	$key = md5( serialize( $r ) );
@@ -75,8 +82,10 @@
 	if ( $hide_empty && !$hierarchical ) {
 		if ( 'link' == $type )
 			$where .= ' AND link_count > 0';
+		else if ( 'post' == $type )
+			$where .= ' AND category_count > 0';
 		else
-			$where .= ' AND category_count > 0';
+			$where .= ' AND tagged_count > 0';
 	}
 
 	if ( !empty($number) )
@@ -276,10 +285,14 @@
 		$results = $wpdb->get_results("SELECT post_id, category_id FROM $wpdb->post2cat LEFT JOIN $wpdb->posts ON post_id = ID WHERE category_id IN (".join(',', $cat_IDs).") AND post_type = 'post' AND post_status = 'publish'");
 		foreach ( $results as $row )
 			++$cat_items[$row->category_id][$row->post_id];
-	} else {
+	} else if ( $type == 'link' ) {
 		$results = $wpdb->get_results("SELECT $wpdb->link2cat.link_id, category_id FROM $wpdb->link2cat LEFT JOIN $wpdb->links USING (link_id) WHERE category_id IN (".join(',', $cat_IDs).") AND link_visible = 'Y'");
 		foreach ( $results as $row )
 			++$cat_items[$row->category_id][$row->link_id];
+	} else {
+		$results = $wpdb->get_results("SELECT post_id, category_id FROM $wpdb->post2tag LEFT JOIN $wpdb->posts ON post_id = ID WHERE category_id IN (".join(',', $cat_IDs).") AND post_type = 'post' AND post_status = 'publish'");
+		foreach ( $results as $row )
+			++$cat_items[$row->category_id][$row->post_id];
 	}
 
 	// Touch every ancestor's lookup row for each post in each category
@@ -293,7 +306,7 @@
 		}
 	}
 
-	// Transfer the touched cells 
+	// Transfer the touched cells   // TAGFIX
 	foreach ( (array) $cat_items as $id => $items )
 		if ( isset($cats[$id]) )
 			$cats[$id]->{'link' == $type ? 'link_count' : 'category_count'} = count($items);
Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 4871)
+++ wp-includes/post.php	(working copy)
@@ -453,6 +453,14 @@
 	return array_unique($cat_ids);
 }
 
+function wp_get_post_tags($post_id = 0) {
+	$cats = &get_the_tags($post_id);
+	$cat_ids = array();
+	foreach ( $cats as $cat )
+		$cat_ids[] = (int) $cat->cat_ID;
+	return array_unique($cat_ids);
+}
+
 function wp_get_recent_posts($num = 10) {
 	global $wpdb;
 
@@ -761,18 +769,23 @@
 	return wp_update_post(array('post_status' => 'publish', 'ID' => $post_id, 'no_filter' => true));
 }
 
-function wp_set_post_categories($post_ID = 0, $post_categories = array()) {
+function _set_post_categories($type = 'cat', $post_ID = 0, $post_categories = array()) {
 	global $wpdb;
-	// If $post_categories isn't already an array, make it one:
-	if (!is_array($post_categories) || 0 == count($post_categories) || empty($post_categories))
-		$post_categories = array(get_option('default_category'));
 
 	$post_categories = array_unique($post_categories);
 
+	if ( 'cat' == $type ) {
+		$table = 'post2cat';
+		$counter = 'category_count';
+	} else {
+		$table = 'post2tag';
+		$counter = 'tagged_count';
+	}
+
 	// First the old categories
 	$old_categories = $wpdb->get_col("
 		SELECT category_id
-		FROM $wpdb->post2cat
+		FROM $wpdb->$table
 		WHERE post_id = $post_ID");
 
 	if (!$old_categories) {
@@ -787,7 +800,7 @@
 	if ($delete_cats) {
 		foreach ($delete_cats as $del) {
 			$wpdb->query("
-				DELETE FROM $wpdb->post2cat
+				DELETE FROM $wpdb->$table
 				WHERE category_id = $del
 					AND post_id = $post_ID
 				");
@@ -801,7 +814,7 @@
 		foreach ($add_cats as $new_cat) {
 			if ( !empty($new_cat) )
 				$wpdb->query("
-					INSERT INTO $wpdb->post2cat (post_id, category_id) 
+					INSERT INTO $wpdb->$table (post_id, category_id) 
 					VALUES ($post_ID, $new_cat)");
 		}
 	}
@@ -809,13 +822,30 @@
 	// Update category counts.
 	$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'");
-		$wpdb->query("UPDATE $wpdb->categories SET category_count = '$count' WHERE cat_ID = '$cat_id'");
+		$count = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->$table, $wpdb->posts WHERE $wpdb->posts.ID=$wpdb->$table.post_id AND post_status = 'publish' AND post_type = 'post' AND category_id = '$cat_id'");
+		$wpdb->query("UPDATE $wpdb->categories SET $counter = '$count' WHERE cat_ID = '$cat_id'");
 		clean_category_cache($cat_id);
 		do_action('edit_category', $cat_id);
 	}
-}	// wp_set_post_categories()
+}
 
+function wp_set_post_categories($post_ID = 0, $post_categories = array()) {
+	// If $post_categories isn't already an array, make it one:
+	if (!is_array($post_categories) || 0 == count($post_categories) || empty($post_categories))
+		$post_categories = array(get_option('default_category'));
+
+	return _set_post_categories($post_ID, $post_categories);
+}
+
+function wp_set_post_tags($post_ID = 0, $post_tags = array()) {
+	global $wpdb;
+	// If $post_categories isn't already an array, make it one:
+	if (!is_array($post_tags) || 0 == count($post_tags) || empty($post_tags))
+		$post_tags = array();
+
+	return _set_post_categories($post_ID, $post_tags);
+}
+
 //
 // Trackback and ping functions
 //
Index: wp-admin/admin-functions.php
===================================================================
--- wp-admin/admin-functions.php	(revision 4871)
+++ wp-admin/admin-functions.php	(working copy)
@@ -635,7 +635,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 OR category_count != 0 OR ( link_count = 0 AND category_count = 0 ) ) ORDER BY category_count DESC" );
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( link_count = 0 OR category_count != 0 OR tagged_count = 0 OR ( link_count = 0 AND category_count = 0 AND tagged_count = 0 ) ) ORDER BY category_count DESC" );
 }
 
 function sort_cats( $cat1, $cat2 ) {
@@ -709,7 +709,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  OR link_count != 0 OR ( link_count = 0 AND category_count = 0 ) ) ORDER BY link_count DESC" );
+	return $wpdb->get_col( "SELECT cat_ID FROM $wpdb->categories WHERE category_parent = $parent AND ( category_count = 0  OR link_count != 0 OR tagged_count = 0 OR ( link_count = 0 AND category_count = 0 AND tagged_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 4871)
+++ wp-admin/admin-db.php	(working copy)
@@ -248,6 +248,30 @@
 	return $wpdb->get_var("SELECT cat_ID FROM $wpdb->categories WHERE category_nicename = '$category_nicename'");
 }
 
+function wp_create_tag($tag_name) {
+	return wp_create_tag($tag_name);
+}
+
+function wp_create_tags($tags, $post_id = '') {
+	$cat_ids = array ();
+	foreach ($tags as $tag) {
+		if ($id = tag_exists($tag))
+			$tag_ids[] = $id;
+		else
+			if ($id = wp_create_tag($tag))
+				$tag_ids[] = $id;
+	}
+
+	if ($post_id)
+		wp_set_post_tags($post_id, $tag_ids);
+
+	return $tag_ids;
+}
+
+function tag_exists($tag_name) {
+	return category_exists($tag_name);
+}
+
 function wp_delete_user($id, $reassign = 'novalue') {
 	global $wpdb;
 
Index: wp-admin/upgrade-schema.php
===================================================================
--- wp-admin/upgrade-schema.php	(revision 4871)
+++ wp-admin/upgrade-schema.php	(working copy)
@@ -18,6 +18,7 @@
   category_parent bigint(20) NOT NULL default '0',
   category_count bigint(20) NOT NULL default '0',
   link_count bigint(20) NOT NULL default '0',
+  tagged_count bigint(20) NOT NULL default '0',
   posts_private tinyint(1) NOT NULL default '0',
   links_private tinyint(1) NOT NULL default '0',
   PRIMARY KEY  (cat_ID),
@@ -91,6 +92,13 @@
   PRIMARY KEY  (rel_id),
   KEY post_id (post_id,category_id)
 ) $charset_collate;
+CREATE TABLE $wpdb->post2tag (
+  rel_id bigint(20) NOT NULL auto_increment,
+  post_id bigint(20) NOT NULL default '0',
+  tag_id bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (rel_id),
+  KEY post_id (post_id,tag_id)
+) $charset_collate;
 CREATE TABLE $wpdb->postmeta (
   meta_id bigint(20) NOT NULL auto_increment,
   post_id bigint(20) NOT NULL default '0',

