Index: wp-includes/post.php
===================================================================
--- wp-includes/post.php	(revision 21356)
+++ wp-includes/post.php	(working copy)
@@ -27,6 +27,7 @@
 		'capability_type' => 'post',
 		'map_meta_cap' => true,
 		'hierarchical' => false,
+		'show_taxonomy_columns' => array( 'category', 'post_tag' ),
 		'rewrite' => false,
 		'query_var' => false,
 		'delete_with_user' => true,
@@ -977,7 +978,7 @@
 	$defaults = array(
 		'labels' => array(), 'description' => '', 'publicly_queryable' => null, 'exclude_from_search' => null,
 		'capability_type' => 'post', 'capabilities' => array(), 'map_meta_cap' => null,
-		'_builtin' => false, '_edit_link' => 'post.php?post=%d', 'hierarchical' => false,
+		'_builtin' => false, '_edit_link' => 'post.php?post=%d', 'hierarchical' => false, 'show_taxonomy_columns' => false,
 		'public' => false, 'rewrite' => true, 'has_archive' => false, 'query_var' => true,
 		'supports' => array(), 'register_meta_box_cb' => null,
 		'taxonomies' => array(), 'show_ui' => null, 'menu_position' => null, 'menu_icon' => null,
@@ -1285,6 +1286,9 @@
 	if ( !isset( $object->labels['all_items'] ) && isset( $object->labels['menu_name'] ) )
 		$object->labels['all_items'] = $object->labels['menu_name'];
 
+	if ( !isset( $object->labels['no_items'] ) && isset( $object->labels['menu_name'] ) )
+		$object->labels['no_items'] = 'No ' . $object->labels['menu_name'];
+
 	foreach ( $nohier_vs_hier_defaults as $key => $value )
 			$defaults[$key] = $object->hierarchical ? $value[1] : $value[0];
 
Index: wp-includes/taxonomy.php
===================================================================
--- wp-includes/taxonomy.php	(revision 21356)
+++ wp-includes/taxonomy.php	(working copy)
@@ -43,6 +43,9 @@
 
 	register_taxonomy( 'category', 'post', array(
 		'hierarchical' => true,
+		'labels' => array(
+			'no_items' => __( 'Uncategorized' ),
+		),
 		'query_var' => 'category_name',
 		'rewrite' => $rewrite['category'],
 		'public' => true,
@@ -416,6 +419,7 @@
 		'search_items' => array( __( 'Search Tags' ), __( 'Search Categories' ) ),
 		'popular_items' => array( __( 'Popular Tags' ), null ),
 		'all_items' => array( __( 'All Tags' ), __( 'All Categories' ) ),
+		'no_items' => array( __( 'No Tags' ), __( 'No Categories' ) ),
 		'parent_item' => array( null, __( 'Parent Category' ) ),
 		'parent_item_colon' => array( null, __( 'Parent Category:' ) ),
 		'edit_item' => array( __( 'Edit Tag' ), __( 'Edit Category' ) ),
Index: wp-admin/includes/class-wp-posts-list-table.php
===================================================================
--- wp-admin/includes/class-wp-posts-list-table.php	(revision 21356)
+++ wp-admin/includes/class-wp-posts-list-table.php	(working copy)
@@ -270,10 +270,10 @@
 			$posts_columns['author'] = __( 'Author' );
 
 		if ( empty( $post_type ) || is_object_in_taxonomy( $post_type, 'category' ) )
-			$posts_columns['categories'] = __( 'Categories' );
+			$posts_columns['category'] = __( 'Categories' );
 
 		if ( empty( $post_type ) || is_object_in_taxonomy( $post_type, 'post_tag' ) )
-			$posts_columns['tags'] = __( 'Tags' );
+			$posts_columns['post_tag'] = __( 'Tags' );
 
 		$post_status = !empty( $_REQUEST['post_status'] ) ? $_REQUEST['post_status'] : 'all';
 		if ( post_type_supports( $post_type, 'comments' ) && !in_array( $post_status, array( 'pending', 'draft', 'future' ) ) )
@@ -287,6 +287,30 @@
 			$posts_columns = apply_filters( 'manage_posts_columns', $posts_columns, $post_type );
 		$posts_columns = apply_filters( "manage_{$post_type}_posts_columns", $posts_columns );
 
+		if ( !empty( $post_type ) ) {
+			$post_type_object = get_post_type_object( $post_type );
+
+			if ( $post_type_object->show_taxonomy_columns ) {
+
+				if ( is_array( $post_type_object->show_taxonomy_columns ) )
+						$taxonomies = $post_type_object->show_taxonomy_columns;
+				else
+					$taxonomies = get_object_taxonomies( $screen->post_type );
+
+				if ( empty( $taxonomies ) )
+					return $posts_columns;
+
+				foreach ( $taxonomies as $registered_taxonomy ) {
+
+					if ( $registered_taxonomy == 'post_tag' || $registered_taxonomy == 'category' ) continue;
+
+					$taxonomy_object = get_taxonomy( $registered_taxonomy );
+					$posts_columns[$registered_taxonomy] = apply_filters( 'taxonomy_column_header', __( $taxonomy_object->label ), $post_type_object, $taxonomy_object );
+
+				}
+			}
+		}
+
 		return $posts_columns;
 	}
 
@@ -469,6 +493,12 @@
 		$edit_link = get_edit_post_link( $post->ID );
 		$title = _draft_or_post_title();
 		$post_type_object = get_post_type_object( $post->post_type );
+		if ( $post_type_object->show_taxonomy_columns ) {
+			if ( is_array( $post_type_object->show_taxonomy_columns ) )
+				$taxonomies_columns = $post_type_object->show_taxonomy_columns;
+			else
+				$taxonomies_columns = get_object_taxonomies( $post_type_object->name );
+		}
 		$can_edit_post = current_user_can( $post_type_object->cap->edit_post, $post->ID );
 
 		$alternate = 'alternate' == $alternate ? '' : 'alternate';
@@ -529,7 +559,6 @@
 				}
 				else {
 					$attributes = 'class="post-title page-title column-title"' . $style;
-					
 					$pad = str_repeat( '&#8212; ', $level );
 ?>
 			<td <?php echo $attributes ?>><strong><?php if ( $can_edit_post && $post->post_status != 'trash' ) { ?><a class="row-title" href="<?php echo $edit_link; ?>" title="<?php echo esc_attr( sprintf( __( 'Edit &#8220;%s&#8221;' ), $title ) ); ?>"><?php echo $pad; echo $title ?></a><?php } else { echo $pad; echo $title; }; _post_states( $post ); ?></strong>
@@ -603,46 +632,15 @@
 				echo '</td>';
 			break;
 
-			case 'categories':
-			?>
-			<td <?php echo $attributes ?>><?php
-				$categories = get_the_category();
-				if ( !empty( $categories ) ) {
-					$out = array();
-					foreach ( $categories as $c ) {
-						$out[] = sprintf( '<a href="%s">%s</a>',
-							esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'category_name' => $c->slug ), 'edit.php' ) ),
-							esc_html( sanitize_term_field( 'name', $c->name, $c->term_id, 'category', 'display' ) )
-						);
-					}
-					/* translators: used between list items, there is a space after the comma */
-					echo join( __( ', ' ), $out );
-				} else {
-					_e( 'Uncategorized' );
-				}
-			?></td>
-			<?php
-			break;
+			case ( is_array( $taxonomies_columns ) && in_array( $registered_taxonomy = $column_name, $taxonomies_columns ) ) :
 
-			case 'tags':
-			?>
-			<td <?php echo $attributes ?>><?php
-				$tags = get_the_tags( $post->ID );
-				if ( !empty( $tags ) ) {
-					$out = array();
-					foreach ( $tags as $c ) {
-						$out[] = sprintf( '<a href="%s">%s</a>',
-							esc_url( add_query_arg( array( 'post_type' => $post->post_type, 'tag' => $c->slug ), 'edit.php' ) ),
-							esc_html( sanitize_term_field( 'name', $c->name, $c->term_id, 'tag', 'display' ) )
-						);
-					}
-					/* translators: used between list items, there is a space after the comma */
-					echo join( __( ', ' ), $out );
-				} else {
-					_e( 'No Tags' );
-				}
-			?></td>
-			<?php
+			$defaults = array(
+				'taxonomy' => $registered_taxonomy,
+				'attributes' => $attributes,
+			);
+			$args = apply_filters( 'taxonomy_column_args', $defaults, $post_type_object, $registered_taxonomy  );
+
+			$this->taxonomy_column( $args );
 			break;
 
 			case 'comments':
@@ -679,8 +677,8 @@
 			?></td>
 			<?php
 			break;
+			}
 		}
-	}
 	?>
 		</tr>
 	<?php
@@ -688,6 +686,45 @@
 	}
 
 	/**
+	 * Creates internal taxonomy columns as well as registered taxonomies
+	 *
+	 * @since 3.5.0
+	 */
+	function taxonomy_column( $atts = array() ) {
+		global $post;
+
+		$defaults = array(
+			'taxonomy' => 'category',
+			'attributes' => '',
+			'empty' => '',
+		);
+		$args = wp_parse_args( (array) $atts, $defaults );
+		extract( $args, EXTR_SKIP );
+
+		$attributes = !empty( $attributes ) ? $attributes : 'class="column-'. $taxonomy .'"';
+		$taxonomy_object = get_taxonomy( $taxonomy );
+
+		?>
+		<td <?php echo $attributes ?>><?php
+			$terms = get_the_terms( $post->ID, $taxonomy );
+			if ( !empty( $terms ) ) {
+				$out = array();
+				foreach ( $terms as $t ) {
+					$out[] = sprintf( '<a href="%s">%s</a>',
+						esc_url( add_query_arg( array( 'post_type' => $post->post_type, $taxonomy_object->query_var => $t->slug ), 'edit.php' ) ),
+						esc_html( sanitize_term_field( 'name', $t->name, $t->term_id, $taxonomy, 'display' ) )
+					);
+				}
+				/* translators: used between list items, there is a space after the comma */
+				echo join( __( ', ' ), $out );
+			} else {
+				echo $taxonomy_object->labels->no_items;
+			}
+		?></td>
+		<?php
+	}
+
+	/**
 	 * Outputs the hidden row displayed when inline editing
 	 *
 	 * @since 3.1.0
Index: wp-admin/css/wp-admin.dev.css
===================================================================
--- wp-admin/css/wp-admin.dev.css	(revision 21357)
+++ wp-admin/css/wp-admin.dev.css	(working copy)
@@ -2350,8 +2350,8 @@
 
 .fixed .column-response,
 .fixed .column-author,
-.fixed .column-categories,
-.fixed .column-tags,
+.fixed .column-category,
+.fixed .column-post_tag,
 .fixed .column-rel,
 .fixed .column-role {
 	width: 15%;
