Index: bb-templates/style.css
===================================================================
--- bb-templates/style.css	(revision 629)
+++ bb-templates/style.css	(working copy)
@@ -169,7 +169,7 @@
 	padding-bottom: 10px;
 }
 
-#front-page #main h2, h2.post-form, #userlogin, #currentfavorites, #register {
+#front-page #main h2, #category-page #main h2, h2.post-form, #userlogin, #currentfavorites, #register {
 	color: #333;
 	border-bottom: 1px solid #ddd;
 	margin: 0 0 10px;
@@ -180,6 +180,27 @@
 
 .sticky { background: #a1d29a; }
 
+tr.category {
+	background-color: #4fad4f;
+	color: #ffffff;
+}
+tr.category td {
+	border-top: 1px solid #91d691;
+	border-bottom: 1px solid #176e17;
+}
+.category:hover {
+	background-color: #339a33 !important;
+}
+tr.category a {
+	color: #cdf6cd;
+}
+tr.category h3 {
+	display: inline;
+}
+tr.category p {
+	margin: 0.3em 0 0 0;
+}
+
 /* Topic Page
 =================================== */
 
@@ -196,11 +217,15 @@
 
 .infobox ul li { padding-bottom: 3px; }
 
+#topic-info {
+	float: left;
+	padding: 0 1em 0 0 ;
+}
+
 #topic-tags {
 	border-left: 1px solid #ccc;
 	float: right;
-	margin-top: -2em;
-	padding: 0 1em 1em;
+	padding: 0 0 0 1em ;
 }
 
 .nav {
Index: bb-templates/category.php
===================================================================
--- bb-templates/category.php	(revision 0)
+++ bb-templates/category.php	(revision 0)
@@ -0,0 +1,71 @@
+<?php bb_get_header(); ?>
+
+<h3 class="bbcrumb"><a href="<?php bb_option('uri'); ?>"><?php bb_option('name'); ?></a> &raquo; <?php category_name(); ?></h3>
+
+<?php if ( $topics || $stickies ) : ?>
+
+<h2><?php _e('Latest Discussions'); ?></h2>
+
+<table id="latest">
+<tr>
+	<th><?php _e('Topic'); ?> &#8212; <?php new_topic(); ?></th>
+	<th><?php _e('Posts'); ?></th>
+	<th><?php _e('Last Poster'); ?></th>
+	<th><?php _e('Freshness'); ?></th>
+</tr>
+
+<?php if ( $stickies ) : foreach ( $stickies as $topic ) : ?>
+<tr<?php topic_class(); ?>>
+	<td><?php _e('Sticky:'); ?> <big><a href="<?php topic_link(); ?>"><?php topic_title(); ?></a></big></td>
+	<td class="num"><?php topic_posts(); ?></td>
+	<td class="num"><?php topic_last_poster(); ?></td>
+	<td class="num"><small><?php topic_time(); ?></small></td>
+</tr>
+<?php endforeach; endif; ?>
+
+<?php if ( $topics ) : foreach ( $topics as $topic ) : ?>
+<tr<?php topic_class(); ?>>
+	<td><a href="<?php topic_link(); ?>"><?php topic_title(); ?></a></td>
+	<td class="num"><?php topic_posts(); ?></td>
+	<td class="num"><?php topic_last_poster(); ?></td>
+	<td class="num"><small><?php topic_time(); ?></small></td>
+</tr>
+<?php endforeach; endif; ?>
+</table>
+
+<?php endif; ?>
+
+<h2><?php _e('Forums'); ?></h2>
+
+<?php
+add_filter('get_forums_where', 'get_forums_where_in_category_filter', 1);
+$forums = get_forums();
+?>
+
+<p style="float:right;"><?php category_forums(); ?> <?php echo __ngettext('forum', 'forums', get_category_forums()); ?></p>
+
+<p><?php category_description(); ?></p>
+
+<?php if ( $forums ) : ?>
+
+<table style="clear:both;" id="forumlist">
+
+<tr>
+	<th><?php _e('Main Theme'); ?></th>
+	<th><?php _e('Topics'); ?></th>
+	<th><?php _e('Posts'); ?></th>
+</tr>
+
+<?php foreach ( $forums as $forum ) : ?>
+<tr<?php alt_class('forum'); ?>>
+	<td><a href="<?php forum_link(); ?>"><?php forum_name(); ?></a> &#8212; <small><?php forum_description(); ?></small></td>
+	<td class="num"><?php forum_topics(); ?></td>
+	<td class="num"><?php forum_posts(); ?></td>
+</tr>
+<?php endforeach; // forums ?>
+</table>
+<?php endif; // forums ?>
+
+<p><a href="<?php category_rss_link(); ?>"><?php _e('RSS feed for this category'); ?></a></p>
+
+<?php bb_get_footer(); ?>
Index: bb-templates/topic.php
===================================================================
--- bb-templates/topic.php	(revision 629)
+++ bb-templates/topic.php	(working copy)
@@ -1,11 +1,17 @@
 <?php bb_get_header(); ?>
 
-<h3 class="bbcrumb"><a href="<?php bb_option('uri'); ?>"><?php bb_option('name'); ?></a> &raquo; <a href="<?php forum_link(); ?>"><?php forum_name(); ?></a></h3>
+<h3 class="bbcrumb">
+	<a href="<?php bb_option('uri'); ?>"><?php bb_option('name'); ?></a> &raquo;
+<?php if ( $category ): ?>
+	<a href="<?php category_link(); ?>"><?php category_name(); ?></a> &raquo;
+<?php endif; ?>
+	<a href="<?php forum_link(); ?>"><?php forum_name(); ?></a>
+</h3>
 <div class="infobox">
+
+<div id="topic-info">
 <h2<?php topic_class( 'topictitle' ); ?>><?php topic_title(); ?></h2> <span id="topic_posts">(<?php topic_posts_link(); ?>)</span>
 
-<?php topic_tags(); ?>
-
 <ul class="topicmeta">
 	<li><?php printf(__('Started %1$s ago by %2$s'), get_topic_start_time(), get_topic_author()) ?></li>
 <?php if ( 1 < get_topic_posts() ) : ?>
@@ -15,6 +21,10 @@
 	<li<?php echo $class;?> id="favorite-toggle"><?php user_favorites_link() ?></li>
 <?php endif; do_action('topicmeta'); ?>
 </ul>
+</div>
+
+<?php topic_tags(); ?>
+
 <br clear="all" />
 </div>
 <?php do_action('under_title', ''); ?>
Index: bb-templates/forum.php
===================================================================
--- bb-templates/forum.php	(revision 629)
+++ bb-templates/forum.php	(working copy)
@@ -1,6 +1,12 @@
 <?php bb_get_header(); ?>
 
-<h3 class="bbcrumb"><a href="<?php bb_option('uri'); ?>"><?php bb_option('name'); ?></a> &raquo; <?php forum_name(); ?></h3>
+<h3 class="bbcrumb">
+	<a href="<?php bb_option('uri'); ?>"><?php bb_option('name'); ?></a> &raquo;
+<?php if ( $category ): ?>
+	<a href="<?php category_link(); ?>"><?php category_name(); ?></a> &raquo;
+<?php endif; ?>
+	<?php forum_name(); ?>
+</h3>
 
 <?php if ( $topics || $stickies ) : ?>
 
Index: bb-templates/front-page.php
===================================================================
--- bb-templates/front-page.php	(revision 629)
+++ bb-templates/front-page.php	(working copy)
@@ -40,24 +40,50 @@
 </table>
 <?php endif; ?>
 
+<?php if ( $categories ) : ?>
+
 <h2><?php _e('Forums'); ?></h2>
-<table id="forumlist">
 
+<table style="clear:both;" id="forumlist">
+
 <tr>
 	<th><?php _e('Main Theme'); ?></th>
 	<th><?php _e('Topics'); ?></th>
 	<th><?php _e('Posts'); ?></th>
 </tr>
 
+<?php foreach ( $categories as $category ) : ?>
+<?php
+add_filter('get_forums_where', 'get_forums_where_in_category_filter', 1);
+$forums = get_forums();
+?>
+<?php if ( $forums ) : ?>
+<tr class="category">
+	<td colspan="3">
+		<h3><a href="<?php category_link(); ?>"><?php category_name(); ?></a></h3> &#8212; <?php category_forums(); ?> <?php echo __ngettext('forum', 'forums', get_category_forums()); ?>
+<?php if ( get_category_description() ) : ?>
+		<p><small><?php category_description(); ?></small></p>
+<?php endif; ?>
+	</td>
+</tr>
+
+
 <?php foreach ( $forums as $forum ) : ?>
 <tr<?php alt_class('forum'); ?>>
 	<td><a href="<?php forum_link(); ?>"><?php forum_name(); ?></a> &#8212; <small><?php forum_description(); ?></small></td>
 	<td class="num"><?php forum_topics(); ?></td>
 	<td class="num"><?php forum_posts(); ?></td>
 </tr>
-<?php endforeach; ?>
+<?php endforeach; // forums ?>
+
+<?php endif; // forums ?>
+
+<?php endforeach; // catagories ?>
+
 </table>
 
+<?php endif; // catagories ?>
+
 <?php if ( $bb_current_user->ID ) : ?>
 <div id="viewdiv">
 <h2><?php _e('Views'); ?></h2>
Index: bb-includes/capabilities.php
===================================================================
--- bb-includes/capabilities.php	(revision 629)
+++ bb-includes/capabilities.php	(working copy)
@@ -37,6 +37,8 @@
 						'edit_users' => true,
 						'manage_tags' => true,		// Rename, Merge, Destroy
 						'edit_others_favorites' => true,
+						'manage_categories' => true,
+						'delete_categories' => true,
 						'manage_forums' => true,	// Add/Rename forum
 						'delete_forums' => true,	// Delete forum
 						'manage_topics' => true,	// Delete/Close/Stick
@@ -71,6 +73,8 @@
 						'edit_users' => true,			//+
 						'manage_tags' => true,			//+
 						'edit_others_favorites' => true,	//+
+						'manage_categories' => true,
+						'delete_categories' => true,
 						'manage_forums' => true,		//+
 						'delete_forums' => true,		//+
 						'manage_topics' => true,
@@ -404,6 +408,9 @@
 	case 'write_post':
 		$caps[] = 'write_posts';
 		break;
+	case 'delete_category':
+		$caps[] = 'delete_categories';
+		break;
 	case 'delete_forum':
 		$caps[] = 'delete_forums';
 		break;
Index: bb-includes/cache.php
===================================================================
--- bb-includes/cache.php	(revision 629)
+++ bb-includes/cache.php	(working copy)
@@ -137,17 +137,54 @@
 		return $posts;
 	}
 
+	function get_categories() {
+		global $bbdb;
+
+		$normal = true;
+		if ( '' != $where = apply_filters('get_categories_where', '') )
+			$normal = false;
+
+		if ( $this->use_cache && $normal && file_exists(BBPATH . 'bb-cache/bb_categories') )
+			return $this->read_cache(BBPATH . 'bb-cache/bb_categories');
+
+		$categories = $bbdb->get_results("SELECT * FROM $bbdb->categories $where ORDER BY category_order");
+		if ( $this->use_cache && $normal && $categories )
+			$this->write_cache(BBPATH . 'bb-cache/bb_categories', $categories);
+		return $categories;
+	}
+
+	function get_category( $category_id ) {
+		global $bbdb;
+		$category_id = (int) $category_id;
+
+		$normal = true;
+		if ( '' != $where = apply_filters('get_category_where', '') )
+			$normal = false;
+
+		if ( $this->use_cache && $normal && file_exists(BBPATH . 'bb-cache/bb_category-' . $category_id) )
+			return $this->read_cache(BBPATH . 'bb-cache/bb_category-' . $category_id);
+
+		$category = $bbdb->get_row("SELECT * FROM $bbdb->categories WHERE category_id = $category_id $where");
+		if ( $this->use_cache && $normal && $category )
+			$this->write_cache(BBPATH . 'bb-cache/bb_category-' . $category_id, $category);
+		return $category;
+	}
+
 	function get_forums() {
 		global $bbdb;
 
 		$normal = true;
+		if ( '' != $join = apply_filters('get_forums_join', '') )
+			$normal = false;
 		if ( '' != $where = apply_filters('get_forums_where', '') )
 			$normal = false;
+		if ( 'ORDER BY forum_order' != $orderby = apply_filters('get_forums_orderby', 'ORDER BY forum_order'))
+			$normal = false;
 
 		if ( $this->use_cache && $normal && file_exists(BBPATH . 'bb-cache/bb_forums') )
 			return $this->read_cache(BBPATH . 'bb-cache/bb_forums');
 
-		$forums = $bbdb->get_results("SELECT * FROM $bbdb->forums $where ORDER BY forum_order");
+		$forums = $bbdb->get_results("SELECT * FROM $bbdb->forums $join $where $orderby");
 		if ( $this->use_cache && $normal && $forums )
 			$this->write_cache(BBPATH . 'bb-cache/bb_forums', $forums);
 		return $forums;
Index: bb-includes/functions.php
===================================================================
--- bb-includes/functions.php	(revision 629)
+++ bb-includes/functions.php	(working copy)
@@ -1,5 +1,15 @@
 <?php
 
+function get_categories() {
+	global $bb_cache;
+	return apply_filters('get_categories',$bb_cache->get_categories());
+}
+
+function get_category( $id ) {
+	global $bb_cache;
+	return $bb_cache->get_category( $id );
+}
+
 function get_forums() {
 	global $bb_cache;
 	return apply_filters('get_forums',$bb_cache->get_forums());
@@ -82,7 +92,44 @@
 	else	return false;
 }
 
+function get_latest_category_topics( $category = 0, $page = 1, $exclude = '') {
+	global $bbdb, $bb_last_countable_query;
+	$category = (int) $category;
+	$page = (int) $page;
+	$where = 'WHERE topic_status = 0';
+	if ( $category )
+		$where .= " AND category_id = $category ";
+	if ( !empty( $exclude ) )
+		$where .= " AND category_id NOT IN ('$exclude') ";
+	if ( is_category() || is_view() )
+		$where .= " AND topic_sticky = 0 ";
+	$limit = bb_get_option('page_topics');
+	$where = apply_filters('get_latest_category_topics_where', $where);
+	if ( 1 < $page )
+		$limit = ($limit * ($page - 1)) . ", $limit";
+	$bb_last_countable_query = "SELECT * FROM $bbdb->topics LEFT JOIN $bbdb->forums ON " . $bbdb->forums . ".forum_id = " . $bbdb->topics . ".forum_id $where ORDER BY topic_time DESC LIMIT $limit";
+	if ( $topics = $bbdb->get_results($bb_last_countable_query) )
+		return bb_append_meta( $topics, 'topic' );
+	else
+		return false;
+}
 
+function get_sticky_category_topics( $category = 0, $display = 1 ) {
+	global $bbdb, $bb_last_countable_query;
+	if ( 1 != $display )
+		return false;
+	$category = (int) $category;
+	$where = 'WHERE topic_sticky <> 0 AND topic_status = 0';
+	if ( $category )
+		$where .= " AND category_id = $category ";
+	$where = apply_filters('get_sticky_category_topics_where', $where);
+	$bb_last_countable_query = "SELECT * FROM $bbdb->topics LEFT JOIN $bbdb->forums ON " . $bbdb->forums . ".forum_id = " . $bbdb->topics . ".forum_id $where ORDER BY topic_time DESC";
+	if ( $stickies = $bbdb->get_results($bb_last_countable_query) )
+		return bb_append_meta( $stickies, 'topic' );	
+	else	return false;
+}
+
+
 // Globalizes the result.
 function bb_get_first_post( $_topic = false, $author_cache = true ) {
 	global $topic, $bb_first_post_cache, $bb_post;
@@ -216,6 +263,36 @@
 	return;
 }
 
+function bb_move_category_forums( $from_category_id, $to_category_id ) {
+	global $bb_cache, $bbdb;
+	
+	$from_category_id = (int) $from_category_id ;
+	$to_category_id = (int) $to_category_id;
+	
+	add_filter('get_category_where', 'no_where'); // Just in case
+	
+	$from_category = get_category( $from_category_id );
+	if ( !$to_category = get_category( $to_category_id ) )
+		return false;
+
+	$bb_cache->flush_many( 'category', $from_category_id );
+	$bb_cache->flush_many( 'category', $to_category_id );
+	
+	$forums = $to_category->forums + ( $from_category ? $from_category->forums : 0 );
+	
+	$bbdb->query("UPDATE $bbdb->categories SET forums = '$forums' WHERE category_id = '$to_category_id'");
+	$bbdb->query("UPDATE $bbdb->categories SET forums = 0 WHERE category_id = '$from_category_id'");
+	$forum_ids = $bbdb->get_col("SELECT forum_id FROM $bbdb->forums WHERE category_id = '$from_category_id'");
+	$return = $bbdb->query("UPDATE $bbdb->forums SET category_id = '$to_category_id' WHERE category_id = '$from_category_id'");
+	if ( $forum_ids )
+		foreach ( $forum_ids as $forum_id ) {
+			$bb_cache->flush_one( 'forum', $forum_id );
+		}
+	$bb_cache->flush_one( 'category', $to_category_id );
+	$bb_cache->flush_many( 'category', $from_category_id );
+	return $return;
+}
+
 function bb_move_forum_topics( $from_forum_id, $to_forum_id ) {
 	global $bb_cache, $bbdb;
 	
@@ -272,6 +349,18 @@
 	return $bbdb->get_results("SELECT * FROM $bbdb->posts $where ORDER BY post_time DESC LIMIT $limit");
 }
 
+function get_latest_category_posts( $category_id, $limit = 0, $page = 1 ) {
+	global $bbdb;
+	$limit = (int) $limit;
+	$category_id = (int) $category_id;
+	if ( !$limit )
+		$limit = bb_get_option( 'page_topics' );
+	if ( 1 < $page )
+		$limit = ($limit * ($page - 1)) . ", $limit";
+	$where = apply_filters('get_latest_category_posts_where', "WHERE `" . $bbdb->forums . "`.category_id = '$category_id' AND post_status = 0");
+	return $bbdb->get_results("SELECT * FROM $bbdb->posts LEFT JOIN $bbdb->forums ON `" . $bbdb->forums . "`.forum_id = `" . $bbdb->posts . "`.forum_id $where ORDER BY post_time DESC LIMIT $limit");
+}
+
 function get_user_favorites( $user_id, $list = false ) {
 	global $bbdb, $page;
 	$user = bb_get_user( $user_id );
@@ -823,18 +912,70 @@
 
 
 
-function bb_new_forum( $name, $desc, $order = 0 ) {
+function bb_new_category( $name, $desc, $order = 0 ) {
 	global $bbdb, $bb_cache, $bb_current_user;
+	if ( !bb_current_user_can('manage_categories') )
+		return false;
+	if ( strlen($name) < 1 )
+		return false;
+	$bbdb->query("INSERT INTO $bbdb->categories (category_name, category_desc, category_order) VALUES ('$name', '$desc', '$order')");
+	$bb_cache->flush_one( 'categories' );
+	return $bbdb->insert_id;
+}
+
+function bb_update_category( $category_id, $name, $desc, $order = 0 ) {
+	global $bbdb, $bb_cache, $bb_current_user;
+	if ( !bb_current_user_can('manage_categories') )
+		return false;
+	if ( !$category_id = (int) $category_id )
+		return false;
+	$order = (int) $order;
+	if ( strlen($name) < 1 )
+		return false;
+	$bb_cache->flush_many( 'category', $category_id );
+	return $bbdb->query("UPDATE $bbdb->categories SET category_name = '$name', category_desc = '$desc', category_order = '$order' WHERE category_id = $category_id");
+}
+
+// When you delete a category, the underlying forums are given a category_id of 0
+function bb_delete_category( $category_id ) {
+	global $bbdb, $bb_cache;
+	if ( !bb_current_user_can( 'delete_category', $category_id ) )
+		return false;
+	if ( !$category_id = (int) $category_id )
+		return false;
+
+	$category = get_forum( $category_id );
+	
+	if ( $forum_ids = $bbdb->get_col("SELECT forum_id FROM $bbdb->forums WHERE category_id = '$category_id'") ) {
+		$_forum_ids = join(',', $forum_ids);
+		$bbdb->query("UPDATE $bbdb->forums SET category_id = 0 WHERE forum_id IN ($_forum_ids)");
+	}
+	
+	$return = $bbdb->query("DELETE FROM $bbdb->categories WHERE category_id = $category_id");
+
+	if ( $forum_ids )
+		foreach ( $forum_ids as $forum_id ) {
+			$bb_cache->flush_one( 'forum', $forum_id );
+		}
+
+	$bb_cache->flush_one( 'categories' );
+	return $return;
+}
+
+function bb_new_forum( $name, $desc, $order = 0, $category_id = 0 ) {
+	global $bbdb, $bb_cache, $bb_current_user;
 	if ( !bb_current_user_can('manage_forums') )
 		return false;
 	if ( strlen($name) < 1 )
 		return false;
-	$bbdb->query("INSERT INTO $bbdb->forums (forum_name, forum_desc, forum_order) VALUES ('$name', '$desc', '$order')");
+	$bbdb->query("INSERT INTO $bbdb->forums (category_id, forum_name, forum_desc, forum_order) VALUES ($category_id, '$name', '$desc', '$order')");
+	$bbdb->query("UPDATE $bbdb->categories SET forums = forums + 1 WHERE category_id = $category_id");
 	$bb_cache->flush_one( 'forums' );
+	$bb_cache->flush_many( 'category', $category_id );
 	return $bbdb->insert_id;
 }
 
-function bb_update_forum( $forum_id, $name, $desc, $order = 0 ) {
+function bb_update_forum( $forum_id, $name, $desc, $order = 0, $category_id = 0 ) {
 	global $bbdb, $bb_cache, $bb_current_user;
 	if ( !bb_current_user_can('manage_forums') )
 		return false;
@@ -843,8 +984,15 @@
 	$order = (int) $order;
 	if ( strlen($name) < 1 )
 		return false;
+	
+	$forum = get_forum( $forum_id );
+	
+	$return = $bbdb->query("UPDATE $bbdb->forums SET category_id = $category_id, forum_name = '$name', forum_desc = '$desc', forum_order = '$order' WHERE forum_id = $forum_id");
+	$bbdb->query("UPDATE $bbdb->categories SET forums = forums + 1 WHERE category_id = $category_id");
+	$bbdb->query("UPDATE $bbdb->categories SET forums = forums - 1 WHERE category_id = $forum->category_id");
 	$bb_cache->flush_many( 'forum', $forum_id );
-	return $bbdb->query("UPDATE $bbdb->forums SET forum_name = '$name', forum_desc = '$desc', forum_order = '$order' WHERE forum_id = $forum_id");
+	$bb_cache->flush_one( 'categories' );
+	return $return;
 }
 
 // When you delete a forum, you delete *everything*
@@ -855,6 +1003,8 @@
 	if ( !$forum_id = (int) $forum_id )
 		return false;
 
+	$forum = get_forum( $forum_id );
+	
 	if ( $topic_ids = $bbdb->get_col("SELECT topic_id FROM $bbdb->topics WHERE forum_id = '$forum_id'") ) {
 		$_topic_ids = join(',', $topic_ids);
 		$bbdb->query("DELETE FROM $bbdb->posts WHERE topic_id IN ($_topic_ids) AND topic_id != 0");
@@ -863,6 +1013,7 @@
 	}
 	
 	$return = $bbdb->query("DELETE FROM $bbdb->forums WHERE forum_id = $forum_id");
+	$bbdb->query("UPDATE $bbdb->categories SET forums = forums - 1 WHERE category_id = $forum->category_id");
 
 	if ( $topic_ids )
 		foreach ( $topic_ids as $topic_id ) {
@@ -871,6 +1022,7 @@
 		}
 
 	$bb_cache->flush_many( 'forum', $forum_id );
+	$bb_cache->flush_one( 'categories' );
 	return $return;
 }
 
@@ -1547,7 +1699,11 @@
 
 	do_action( 'pre_permalink', $permalink );
 
-	if ( is_forum() ) {
+	if ( is_category() ) {
+		global $category_id;
+		$category_id = $permalink;
+		$permalink = get_category_link( $permalink, $page );
+	} elseif ( is_forum() ) {
 		global $forum_id;
 		$forum_id = $permalink;
 		$permalink = get_forum_link( $permalink, $page );
Index: bb-includes/bozo.php
===================================================================
--- bb-includes/bozo.php	(revision 629)
+++ bb-includes/bozo.php	(working copy)
@@ -279,6 +279,7 @@
 
 add_action( 'pre_permalink', 'bozo_pre_permalink' );
 add_action( 'bb_index.php_pre_db', 'bozo_latest_filter' );
+add_action( 'bb_category.php_pre_db', 'bozo_latest_filter' );
 add_action( 'bb_forum.php_pre_db', 'bozo_latest_filter' );
 add_action( 'bb_topic.php_pre_db', 'bozo_topic_db_filter' );
 add_action( 'bb_profile.php_pre_db', 'bozo_profile_db_filter' );
Index: bb-includes/formatting-functions.php
===================================================================
--- bb-includes/formatting-functions.php	(revision 629)
+++ bb-includes/formatting-functions.php	(working copy)
@@ -154,7 +154,8 @@
 function closed_title( $title ) {
 	global $topic;
 	if ( '0' === $topic->topic_open )
-		return sprintf(__('[closed] %s'), $title);
+		//return sprintf(__('[closed] %s'), $title);
+		return '<img src="' . bb_get_option('uri') . 'my-templates/images/closed.png" alt="[' . __('[closed]') . ']" style="vertical-align:top; margin-right:0.3em; width:14px; height:14px; border-width:0;" />' . $title;
 	return $title;
 }
 
Index: bb-includes/template-functions.php
===================================================================
--- bb-includes/template-functions.php	(revision 629)
+++ bb-includes/template-functions.php	(working copy)
@@ -183,6 +183,9 @@
 	case 'index.php' :
 		return 'front-page';
 		break;
+	case 'category.php' :
+		return 'category-page';
+		break;
 	case 'forum.php' :
 		return 'forum-page';
 		break;
@@ -226,6 +229,13 @@
 		return false;
 }
 
+function is_category() {
+	if ( 'category-page' == get_bb_location() )
+		return true;
+	else
+		return false;
+}
+
 function is_forum() {
 	if ( 'forum-page' == get_bb_location() )
 		return true;
@@ -300,6 +310,8 @@
 		$title = get_topic_title(). ' &laquo; ';
 	if ( is_forum() )
 		$title = get_forum_name() . ' &laquo; ';
+	if ( is_category() )
+		$title = get_category_name() . ' &laquo; ';
 	if ( is_tag() )
 		$title = wp_specialchars( get_tag_name() ). ' &laquo; ' . __('Tags') . ' &laquo; ';
 	if ( is_bb_profile() )
@@ -319,6 +331,8 @@
 		$feed_link = '<link rel="alternate" type="application/rss+xml" title="' . __('Tag') . ': ' . wp_specialchars( get_tag_name(), 1 ) . '" href="' . get_tag_rss_link() . '" />';
 	elseif ( is_forum() )
 		$feed_link = '<link rel="alternate" type="application/rss+xml" title="' . __('Forum') . ': ' . wp_specialchars( get_forum_name(), 1) . '" href="' . get_forum_rss_link() . '" />';
+	elseif ( is_category() )
+		$feed_link = '<link rel="alternate" type="application/rss+xml" title="' . __('Category') . ': ' . wp_specialchars( get_category_name(), 1) . '" href="' . get_category_rss_link() . '" />';
 	elseif ( is_front() )
 		$feed_link = '<link rel="alternate" type="application/rss+xml" title="' . __('Recent Posts') . '" href="' . get_recent_rss_link() . '" />';
 	echo apply_filters('bb_feed_head', $feed_link);
@@ -332,6 +346,106 @@
 	return apply_filters( 'get_recent_rss_link', $link );
 }
 
+// CATEGORIES
+
+function get_forums_where_in_category_filter() {
+	global $category;
+	if ($category->category_id)
+		return 'WHERE category_id = ' . $category->category_id;
+	else	return NULL;
+}
+
+function get_forums_join_categories_filter() {
+	global $bbdb;
+	return 'LEFT JOIN `' . $bbdb->categories . '` ON `' . $bbdb->categories . '`.`category_id` = `' . $bbdb->forums . '`.`category_id`';
+}
+
+function get_forums_orderby_category_order_filter() {
+	return 'ORDER BY `category_order`, `forum_order`';
+}
+
+function category_id() {
+	echo apply_filters( 'category_id', get_category_id() );
+}
+
+function get_category_id() {
+	global $category;
+	return $category->category_id;
+}
+
+function category_link( $category_id = 0, $page = 1 ) {
+	echo apply_filters('category_link', get_category_link( $category_id, $page ), $category_id );
+}
+
+function get_category_link( $category_id = 0, $page = 1 ) {
+	global $category;
+
+	if ( $category_id )
+		$category = get_category( $category_id );
+	if ( bb_get_option( 'mod_rewrite' ) )
+		$link = bb_get_option( 'uri' ) . "category/$category->category_id" . ( 1 < $page ? "/page/$page" : '' );
+	else {
+		$args = array();
+		$link = bb_get_option( 'uri' ) . 'category.php';
+		$args['id'] = $category->category_id;
+		$args['page'] = 1 < $page ? $page : '';
+		$link = add_query_arg( $args, $link );
+	}
+
+	return apply_filters( 'get_category_link', $link, $category->category_id );
+}
+
+function category_name( $category_id = 0 ) {
+	echo apply_filters( 'category_name', get_category_name( $category_id ), $category_id );
+}
+
+function get_category_name( $category_id = 0 ) {
+	global $category;
+	if ( $category_id )
+		$category = get_category( $category_id );
+	return apply_filters( 'get_category_name', $category->category_name, $forum->category_id );
+}
+
+function category_description( $category_id = 0 ) {
+	echo apply_filters( 'category_description', get_category_description( $category_id ), $category_id );
+}
+
+function get_category_description( $category_id = 0 ) {
+	global $category;
+	if ( $category_id )
+		$category = get_forum( $category_id );
+	return apply_filters( 'get_category_description', $category->category_desc, $category->category_id );
+}
+
+function category_forums( $category_id = 0 ) {
+	echo apply_filters( 'category_forums', get_category_forums( $category_id ), $category_id );
+}
+
+function get_category_forums( $category_id = 0 ) {
+	global $category;
+	if ( $category_id )
+		$category = get_category( $category_id );
+	return apply_filters( 'get_category_forums', $category->forums, $category->category_id );
+}
+
+function category_rss_link( $category_id = 0 ) {
+	echo apply_filters('category_rss_link', get_category_rss_link( $category_id ) );
+}
+
+function get_category_rss_link( $category_id = 0 ) {
+	global $category;
+
+	if ( $category_id )
+		$category = get_category( $category_id );
+
+	if ( bb_get_option('mod_rewrite') )
+		$link = bb_get_option('uri') . "rss/category/$category->category_id";
+	else
+		$link = bb_get_option('uri') . "rss.php?category=$category->category_id";
+
+	return apply_filters( 'get_category_rss_link', $link, $category_id );
+}
+
 // FORUMS
 
 function forum_link( $forum_id = 0, $page = 1 ) {
@@ -744,9 +858,9 @@
 		$class[] = 'bozo';
 	if ( '0' === $topic->topic_open )
 		$class[] = 'closed';
-	if ( 1 == $topic->topic_sticky && is_forum() )
+	if ( 1 == $topic->topic_sticky && ( is_forum() || is_category() ) )
 		$class[] = 'sticky';
-	elseif ( 2 == $topic->topic_sticky && ( is_front() || is_forum() ) )
+	elseif ( 2 == $topic->topic_sticky && ( is_front() || is_forum() || is_category() ) )
 		$class[] = 'sticky super-sticky';
 	$class = apply_filters( 'topic_class', $class, $topic->topic_id );
 	$class = join(' ', $class);
@@ -760,7 +874,7 @@
 
 	if ( is_forum() || is_tag() )
 		$url = '#postform';
-	elseif ( is_front() )
+	elseif ( is_front() || is_category() )
 		$url = add_query_arg( 'new', '1', bb_get_option( 'uri' ) );
 	if ( !bb_is_user_logged_in() )
 		$url = add_query_arg( 're', urlencode($url), bb_get_option( 'uri' ) . 'bb-login.php' );
@@ -1333,13 +1447,29 @@
 
 function forum_dropdown() {
 	global $forum_id;
-	$forums = get_forums();
+	$categories = get_categories();
 	echo '<select name="forum_id" id="forum_id" tabindex="5">';
-
-	foreach ( $forums as $forum ) :
-		$selected = ( $forum_id == $forum->forum_id ) ? " selected='selected'" : '';
-		echo "<option value='$forum->forum_id'$selected>$forum->forum_name</option>";
-	endforeach;
+	if ($categories) :
+		global $category;
+		foreach ( $categories as $category ) :
+			add_filter('get_forums_where', 'get_forums_where_in_category_filter', 1);
+			$forums = get_forums();
+			if ( $forums ) :
+				echo "<optgroup label='$category->category_name'>";
+				foreach ( $forums as $forum ) :
+					$selected = ( $forum_id == $forum->forum_id ) ? " selected='selected'" : '';
+					echo "<option value='$forum->forum_id'$selected>$forum->forum_name</option>";
+				endforeach;
+				echo "</optgroup>";
+			endif;
+		endforeach;
+	else :
+		$forums = get_forums();
+		foreach ( $forums as $forum ) :
+			$selected = ( $forum_id == $forum->forum_id ) ? " selected='selected'" : '';
+			echo "<option value='$forum->forum_id'$selected>$forum->forum_name</option>";
+		endforeach;
+	endif;
 	echo '</select>';
 }
 
Index: bb-includes/db.php
===================================================================
--- bb-includes/db.php	(revision 629)
+++ bb-includes/db.php	(working copy)
@@ -17,6 +17,7 @@
 	var $queries;
 
 	// Our tables
+	var $categories;
 	var $forums;
 	var $posts;
 	var $topics;
Index: index.php
===================================================================
--- index.php	(revision 629)
+++ index.php	(working copy)
@@ -6,11 +6,23 @@
 do_action( 'bb_index.php_pre_db', '' );
 
 if ( isset($_GET['new']) && '1' == $_GET['new'] ) :
+	$categories = false;
 	$forums = false;
 elseif ( !$bb_db_override ) :
+	$categories = get_categories(); // Comment to hide categories
 	$forums = get_forums(); // Comment to hide forums
 	$topics = get_latest_topics();
 	$super_stickies = get_sticky_topics();
+	
+	if ( $forums && !$categories ) :
+		$categories = array(
+			0 => new stdClass()
+		);
+		$categories[0]->category_id = 0;
+		$categories[0]->category_name = __('Forums');
+		$categories[0]->category_desc = __('All available forums.');
+		$categories[0]->forums = $forums ? count($forums) : 0;
+	endif;
 endif;
 
 do_action( 'bb_index.php', '' );
Index: rss.php
===================================================================
--- rss.php	(revision 629)
+++ rss.php	(working copy)
@@ -22,6 +22,11 @@
 elseif ( 'forum' == get_path() )
 	$forum_id = (int) get_path(2);
 
+elseif ( isset($_GET['category']) )
+	$category_id = (int) $_GET['category'];
+elseif ( 'category' == get_path() )
+	$category_id = (int) get_path(2);
+
 $bb_db_override = false;
 do_action( 'bb_rss.php_pre_db', '' );
 
@@ -48,6 +53,10 @@
 	if ( !$posts = get_latest_forum_posts( $forum_id ) )
 		die();
 	$title = wp_specialchars( bb_get_option( 'name' ) ) . ' ' . __('Forum') . ': ' . get_forum_name( $forum_id );
+} elseif ( isset($category_id) ) {
+	if ( !$posts = get_latest_category_posts( $category_id ) )
+		die();
+	$title = wp_specialchars( bb_get_option( 'name' ) ) . ' ' . __('Category') . ': ' . get_category_name( $category_id );
 } else {
 	if ( !$posts = get_latest_posts( 35 ) )
 		die();
Index: category.php
===================================================================
--- category.php	(revision 0)
+++ category.php	(revision 0)
@@ -0,0 +1,28 @@
+<?php
+
+require_once('./bb-load.php');
+
+$category_id = 0;
+
+bb_repermalink();
+
+if ( !$category )
+	bb_die(__('Category not found.'));
+
+$bb_db_override = false;
+do_action( 'bb_category.php_pre_db', $category_id );
+
+if ( !$bb_db_override ) :
+	add_filter('get_forums_where', 'get_forums_where_in_category_filter', 1);
+	$forums   = get_forums();
+	$topics   = get_latest_category_topics( $category_id, $page );
+	$stickies = get_sticky_category_topics( $category_id, $page );
+endif;
+
+do_action( 'bb_category.php', $category_id );
+
+if (file_exists( BBPATH . 'my-templates/category.php' ))
+	require( BBPATH . 'my-templates/category.php' );
+else	require( BBPATH . 'bb-templates/category.php' );
+
+?>
Index: topic.php
===================================================================
--- topic.php	(revision 629)
+++ topic.php	(working copy)
@@ -20,6 +20,7 @@
 if ( !$bb_db_override ) :
 	$posts = get_thread( $topic_id, $page );
 	$forum = get_forum ( $topic->forum_id );
+	$category = get_category( $forum->category_id );
 
 	$tags  = get_topic_tags ( $topic_id );
 	if ( $bb_current_user && $tags ) {
Index: bb-settings.php
===================================================================
--- bb-settings.php	(revision 629)
+++ bb-settings.php	(working copy)
@@ -60,6 +60,7 @@
 	require( BBPATH . BBINC . '/db.php');
 }
 
+$bbdb->categories = $bb_table_prefix . 'categories';
 $bbdb->forums    = $bb_table_prefix . 'forums';
 $bbdb->posts     = $bb_table_prefix . 'posts';
 $bbdb->topics    = $bb_table_prefix . 'topics';
Index: bb-admin/bb-do-counts.php
===================================================================
--- bb-admin/bb-do-counts.php	(revision 629)
+++ bb-admin/bb-do-counts.php	(working copy)
@@ -70,6 +70,19 @@
 	echo "\n\t</li>\n";
 endif;
 
+if ( isset($_POST['categories']) && 1 == $_POST['categories'] ):
+	echo "\t<li>\n";
+	if ( $categories = (array) $bbdb->get_col("SELECT category_id, COUNT(forum_id) FROM $bbdb->forums GROUP BY category_id") ) :
+		echo "\t\t" . __('Counting category forums...') . "<br />\n";
+		$counts = (array) $bbdb->get_col('', 1);
+		foreach ($categories as $t => $i)
+			$bbdb->query("UPDATE $bbdb->categories SET forums = '{$counts[$t]}' WHERE category_id = $i");
+		unset($topics, $t, $i, $counts);
+	endif;
+	echo "\t\t" . __('Done counting category forums.');
+	echo "\n\t</li>\n";
+endif;
+
 if ( isset($_POST['topics-replied']) && 1 == $_POST['topics-replied'] ) :
 	echo "\t<li>\n";
 	if ( $users = (array) $bbdb->get_col("SELECT ID FROM $bbdb->users") ) :
Index: bb-admin/bb-category.php
===================================================================
--- bb-admin/bb-category.php	(revision 0)
+++ bb-admin/bb-category.php	(revision 0)
@@ -0,0 +1,62 @@
+<?php
+require_once('admin.php');
+
+if ( !bb_current_user_can('manage_categories') )
+	bb_die(__("You don't have the authority to mess with the categories."));
+
+if ( !isset($_POST['action']) )
+	wp_redirect( bb_get_option( 'uri' ) . 'bb-admin/content-categories.php' );
+
+$sent_from = wp_get_referer();
+
+switch ( $_POST['action'] ) :
+case 'add' :
+	if ( !isset($_POST['category']) || '' === $_POST['category'] )
+		bb_die(__('Bad category name.  Go back and try again.'));
+
+	bb_check_admin_referer( 'add-category' );
+
+	$category_name = $_POST['category'];
+	$category_desc = $_POST['category-desc'];
+	$category_order = ( '' === $_POST['category-order'] ) ? 0 : (int) $_POST['category-order'];
+	if ( false !== bb_new_category( $category_name, $category_desc, $category_order ) ) :
+		wp_redirect( $sent_from );
+		exit;
+	else :
+		bb_die(__('The category was not added'));
+	endif;
+	break;
+case 'update' :
+	bb_check_admin_referer( 'update-category' );
+
+	if ( !$categories = get_categories() )
+		bb_die(__('No categories to update!'));
+	foreach ( $categories as $category ) :
+		if ( isset($_POST['name-' . $category->category_id]) && '' !== $_POST['name-' . $category->category_id] )
+			bb_update_category( $category->category_id, $_POST['name-' . $category->category_id], $_POST['desc-' . $category->category_id], $_POST['order-' . $category->category_id]);
+	endforeach;
+	wp_redirect( $sent_from );
+	exit;
+	break;
+case 'delete' :
+	bb_check_admin_referer( 'delete-category' );
+
+	$category_id = (int) $_POST['category_id'];
+	$move_forums_category = (int) $_POST['move_forums_category'];
+
+	if ( !bb_current_user_can( 'delete_category', $forum_id ) )
+		bb_die(__("You don't have the authority to kill off the categories."));
+
+	if ( isset($_POST['move_forums']) && $_POST['move_forums'] != 'delete' )
+		bb_move_category_forums( $category_id, $move_forums_category );
+
+	if ( !bb_delete_category( $category_id ) )
+		bb_die( __('Error occured while trying to delete category') );
+
+	foreach ( array('action', 'id') as $arg )
+		$sent_from = remove_query_arg( $arg, $sent_from );
+	wp_redirect( add_query_arg( 'message', 'deleted', $sent_from ) );
+	exit;
+	break;
+endswitch;
+?>
Index: bb-admin/rewrite-rules.php
===================================================================
--- bb-admin/rewrite-rules.php	(revision 629)
+++ bb-admin/rewrite-rules.php	(working copy)
@@ -14,6 +14,7 @@
 RewriteEngine On
 RewriteBase <?php bb_option( 'path' ); ?>
 
+RewriteRule ^category/([0-9]+)$ <?php bb_option( 'path' ); ?>category.php?id=$1 [L,QSA]
 RewriteRule ^forum/([0-9]+)/page/([0-9]+)$ <?php bb_option( 'path' ); ?>forum.php?id=$1&page=$2 [L,QSA]
 RewriteRule ^forum/([0-9]+)$ <?php bb_option( 'path' ); ?>forum.php?id=$1 [L,QSA]
 RewriteRule ^topic/([0-9]+)/page/([0-9]+)$ <?php bb_option( 'path' ); ?>topic.php?id=$1&page=$2 [L,QSA]
@@ -28,6 +29,7 @@
 RewriteRule ^view/([a-z-]+)/page/([0-9]+)$ <?php bb_option( 'path' ); ?>view.php?view=$1&page=$2 [L,QSA]
 RewriteRule ^view/([a-z-]+)$ <?php bb_option( 'path' ); ?>view.php?view=$1 [L,QSA]
 RewriteRule ^rss/$ <?php bb_option( 'path' ); ?>rss.php [L,QSA]
+RewriteRule ^rss/category/([0-9]+)$ <?php bb_option( 'path' ); ?>rss.php?category=$1 [L,QSA]
 RewriteRule ^rss/forum/([0-9]+)$ <?php bb_option( 'path' ); ?>rss.php?forum=$1 [L,QSA]
 RewriteRule ^rss/topic/([0-9]+)$ <?php bb_option( 'path' ); ?>rss.php?topic=$1 [L,QSA]
 RewriteRule ^rss/tags/([a-z]+)$ <?php bb_option( 'path' ); ?>rss.php?tag=$1 [L,QSA]
Index: bb-admin/content-forums.php
===================================================================
--- bb-admin/content-forums.php	(revision 629)
+++ bb-admin/content-forums.php	(working copy)
@@ -1,6 +1,8 @@
 <?php
 require_once('admin.php');
 
+add_filter( 'get_forums_join', 'get_forums_join_categories_filter', 1 );
+add_filter( 'get_forums_orderby', 'get_forums_orderby_category_order_filter', 1 );
 $forums = get_forums();
 $forums_count = $forums ? count($forums) : 0;
 
@@ -12,6 +14,8 @@
 }
 
 bb_get_admin_header();
+
+$categories = get_categories();
 ?>
 
 <h2><?php _e('Forum Management'); ?></h2>
@@ -79,6 +83,17 @@
 		 <tr><th scope="row"><?php _e('Position:'); ?></th>
 		     <td><input type="text" name="forum-order" id="forum-order" tabindex="12" maxlength="10" /></td>
 		 </tr>
+<?php if ($categories) : ?>
+		 <tr><th scope="row"><?php _e('Category:'); ?></th>
+		     <td>
+				<select name="forum-category" tabindex="<?php echo $t++; ?>">
+<?php foreach ( $categories as $category ) : ?>
+					<option value="<?php echo $category->category_id; ?>"><?php category_name(); ?></option>
+<?php endforeach; ?>
+				</select>
+		     </td>
+		 </tr>
+<?php endif; ?>
 		</table>
 		<p class="submit alignleft"><input name="Submit" type="submit" value="<?php _e('Add Forum'); ?>" tabindex="13" /><input type="hidden" name="action" value="add" /></p>
 	</fieldset> 
@@ -92,6 +107,9 @@
 		 <tr><th><?php _e('Name'); ?></th>
 		     <th><?php _e('Description'); ?></th>
 		     <th><?php _e('Position'); ?></th>
+<?php if ($categories) : ?>
+		     <th><?php _e('Category'); ?></th>
+<?php endif; ?>
 <?php if ( bb_current_user_can( 'delete_forums' ) && 1 < $forums_count ) : ?>
 		     <th><?php _e('Action'); ?></th>
 <?php endif; ?>
@@ -100,6 +118,24 @@
 		 <tr><td><input type="text" name="name-<?php forum_id(); ?>"  value="<?php echo wp_specialchars( get_forum_name(), 1 ); ?>" tabindex="<?php echo $t++; ?>" /></td>
 		     <td><input type="text" name="desc-<?php forum_id(); ?>"  value="<?php echo wp_specialchars( get_forum_description(), 1 ); ?>" tabindex="<?php echo $t++; ?>" /></td>
 		     <td><input type="text" name="order-<?php forum_id(); ?>" value="<?php echo $forum->forum_order; ?>" maxlength="10" tabindex="<?php echo $t++; ?>" /></td>
+<?php if ($categories) : ?>
+		     <td>
+				<select name="category-<?php forum_id(); ?>" tabindex="<?php echo $t++; ?>">
+<?php if ( !$forum->category_id ) : ?>
+					<option value=""><?php _e('No category!!!'); ?></option>
+<?php endif; ?>
+<?php foreach ( $categories as $category ) : ?>
+<?php
+if ($forum->category_id == $category->category_id) {
+	$category_selected = ' selected="selected"';
+} else
+	$category_selected = '';
+?>
+					<option value="<?php echo $category->category_id; ?>"<?php echo $category_selected; ?>><?php category_name(); ?></option>
+<?php endforeach; ?>
+				</select>
+			</td>
+<?php endif; ?>
 <?php if ( bb_current_user_can( 'delete_forums' ) && 1 < $forums_count ) : ?>
 		     <td><?php if ( bb_current_user_can( 'delete_forum', $forum->forum_id ) ) : ?><a class="delete" href="<?php bb_option('uri'); ?>bb-admin/content-forums.php?action=delete&id=<?php forum_id();?>"><?php _e('Delete'); ?></a><?php endif; ?></td>
 <?php endif; ?>
Index: bb-admin/content-categories.php
===================================================================
--- bb-admin/content-categories.php	(revision 0)
+++ bb-admin/content-categories.php	(revision 0)
@@ -0,0 +1,121 @@
+<?php
+require_once('admin.php');
+
+$categories = get_categories();
+$categories_count = $categories ? count($categories) : 0;
+
+if ( 'delete' == $_GET['action'] ) {
+	$category_to_delete = (int) $_GET['id'];
+	$deleted_category = get_category( $category_to_delete );
+	if ( !$deleted_category || $categories_count < 1 || !bb_current_user_can( 'delete_category', $category_to_delete ) )
+		wp_redirect( add_query_arg( array('action' => false, 'id' => false) ) );
+}
+?>
+
+<?php bb_get_admin_header(); ?>
+
+<h2><?php _e('Category Management'); ?></h2>
+<?php  if ( 'delete' == $_GET['action'] ) : ?>
+<div class="ays narrow">
+	<p><big><?php printf(__('Are you sure you want to delete the "<strong>%s</strong>" category?'), $deleted_category->category_name); ?></big></p>
+	<p>This category contains</p>
+	<ul>
+		<li><?php printf(__ngettext('%d forum', '%d forums', $deleted_category->forums), $deleted_category->forums); ?></li>
+	</ul>
+
+	<form method="post" id="delete-category" action="<?php bb_option('uri'); ?>bb-admin/bb-category.php">
+<?php if ( $categories_count > 1 ) : ?>
+		<p>
+			<label for="move-forums-delete"><input type="radio" name="move_forums" id="move-forums-delete" value="delete" /> <?php _e('Forums will not be assigned to a category.'); ?></label><br />
+			<label for="move-forums-move"><input type="radio" name="move_forums" id="move-forums-move" value="move" checked="checked" /> <?php _e('Move forums from this category into'); ?></label>
+			<?php $categories = get_categories(); ?>
+			<select name="move_forums_category" id="move-topics-forum">
+				<?php foreach ($categories as $category ) : ?>
+					<?php if ($category->category_id != $deleted_category->category_id) : ?>
+
+						<option value="<?php category_id(); ?>"><?php category_name(); ?></option>
+					<?php endif; ?>
+				<?php endforeach; ?>
+			</select>
+		</p>
+<?php else : ?>
+		<p>
+			<input type="hidden" name="move_forums" id="move-forums-delete" value="delete" /> <?php _e('Forums will not be assigned to a category.'); ?>
+		</p>
+<?php endif; ?>
+		<p class="submit alignright">
+			<input class="delete" name="Submit" type="submit" value="<?php _e('Delete category &raquo;'); ?>" tabindex="10" />
+			<input type="hidden" name="action" value="delete" />
+			<input type="hidden" name="category_id" value="<?php echo $deleted_category->category_id; ?>" />
+		</p>
+		<?php bb_nonce_field( 'delete-categories' ); ?>
+	</form>
+	<form method="get" action="<?php bb_option('uri'); ?>bb-admin/bb-category.php">
+		<p class="submit alignleft">
+			<input type="submit" value="<?php _e('&laquo; Go back'); ?>" tabindex="10" />
+		</p>
+	</form>
+</div>
+<?php else: // action ?>
+<?php if ( isset($_GET['message']) ) : ?>
+<div class="updated">
+	<p>
+<?php
+switch ( $_GET['message'] ) :
+case 'deleted' :
+	printf(__('Category deleted.  You should have bbPress <a href="%s">recount your site information</a>.'), bb_get_option( 'uri' ) . 'bb-admin/site.php');
+	break;
+endswitch;
+?>
+	</p>
+</div>
+<?php endif; ?>
+<form method="post" id="add-category" action="<?php bb_option('uri'); ?>bb-admin/bb-category.php">
+	<h3><?php _e('Add category'); ?></h3>
+	<fieldset>
+		<table>
+		 <tr><th scope="row"><?php _e('Category Name:'); ?></th>
+		     <td><input type="text" name="category" id="category" tabindex="10" /></td>
+		 </tr>
+		 <tr><th scope="row"><?php _e('Category Description:'); ?></th>
+		     <td><input type="text" name="category-desc" id="category-desc" tabindex="11" /></td>
+		 </tr>
+		 <tr><th scope="row"><?php _e('Position:'); ?></th>
+		     <td><input type="text" name="category-order" id="category-order" tabindex="12" maxlength="10" /></td>
+		 </tr>
+		</table>
+		<p class="submit alignleft"><input name="Submit" type="submit" value="<?php _e('Add Category'); ?>" tabindex="13" /><input type="hidden" name="action" value="add" /></p>
+	</fieldset> 
+	<?php bb_nonce_field( 'add-category' ); ?>
+</form>
+<?php if ( $categories ) : ?>
+<form method="post" id="update-categories" action="<?php bb_option('uri'); ?>bb-admin/bb-category.php">
+	<h3><?php _e('Update category information'); ?></h3>
+	<fieldset>
+		<table>
+		 <tr><th><?php _e('Name'); ?></th>
+		     <th><?php _e('Description'); ?></th>
+		     <th><?php _e('Position'); ?></th>
+<?php if ( bb_current_user_can( 'delete_categories' ) ) : ?>
+		     <th><?php _e('Action'); ?></th>
+<?php endif; ?>
+		 </tr>
+<?php $t = 20; foreach ( $categories as $category ) : ?>
+		 <tr><td><input type="text" name="name-<?php category_id(); ?>"  value="<?php echo wp_specialchars( get_category_name(), 1 ); ?>" tabindex="<?php echo $t++; ?>" /></td>
+		     <td><input type="text" name="desc-<?php category_id(); ?>"  value="<?php echo wp_specialchars( get_category_description(), 1 ); ?>" tabindex="<?php echo $t++; ?>" /></td>
+		     <td><input type="text" name="order-<?php category_id(); ?>" value="<?php echo $category->category_order; ?>" maxlength="10" tabindex="<?php echo $t++; ?>" /></td>
+<?php if ( bb_current_user_can( 'delete_categories' ) ) : ?>
+		     <td><?php if ( bb_current_user_can( 'delete_category', $category->category_id ) ) : ?><a class="delete" href="<?php bb_option('uri'); ?>bb-admin/content-categories.php?action=delete&id=<?php category_id();?>"><?php _e('Delete'); ?></a><?php endif; ?></td>
+<?php endif; ?>
+		 </tr>
+<?php endforeach; ?>
+		</table>
+	<p class="submit alignleft"><input name="Submit" type="submit" value="<?php _e('Update'); ?>" tabindex="<?php echo $t; ?>" /><input type="hidden" name="action" value="update" /></p>
+	</fieldset>
+	<?php bb_nonce_field( 'update-categories' ); ?>
+</form>
+<?php endif; ?>
+
+<?php endif; // action ?>
+
+<?php bb_get_admin_footer(); ?>
Index: bb-admin/admin-functions.php
===================================================================
--- bb-admin/admin-functions.php	(revision 629)
+++ bb-admin/admin-functions.php	(working copy)
@@ -27,6 +27,7 @@
 	$bb_submenu['content.php'][5] = array(__('Topics'), 'moderate', 'content.php');
 	$bb_submenu['content.php'][10] = array(__('Posts'), 'moderate', 'content-posts.php');
 	$bb_submenu['content.php'][15] = array(__('Forums'), 'moderate', 'content-forums.php');
+	$bb_submenu['content.php'][20] = array(__('Categories'), 'moderate', 'content-categories.php');
 
 	$bb_submenu['site.php'][5] = array(__('Recount'), 'recount', 'site.php');
 
@@ -160,6 +161,7 @@
 	$recount_list[25] = array('topic-tag-count', __('Count tags for every topic'));
 	$recount_list[30] = array('tags-tag-count', __('Count topics for every tag'));
 	$recount_list[35] = array('zap-tags', __('DELETE tags with no topics.  Only functions if the above checked'));
+	$recount_list[40] = array('categories', __('Count forums in every category'));
 	do_action('bb_recount_list');
 	ksort($recount_list);
 	return $recount_list;
Index: bb-admin/bb-forum.php
===================================================================
--- bb-admin/bb-forum.php	(revision 629)
+++ bb-admin/bb-forum.php	(working copy)
@@ -19,7 +19,8 @@
 	$forum_name = $_POST['forum'];
 	$forum_desc = $_POST['forum-desc'];
 	$forum_order = ( '' === $_POST['forum-order'] ) ? 0 : (int) $_POST['forum-order'];
-	if ( false !== bb_new_forum( $forum_name, $forum_desc, $forum_order ) ) :
+	$forum_category = $_POST['forum-category'];
+	if ( false !== bb_new_forum( $forum_name, $forum_desc, $forum_order, $forum_category ) ) :
 		wp_redirect( $sent_from );
 		exit;
 	else :
@@ -33,7 +34,7 @@
 		bb_die(__('No forums to update!'));
 	foreach ( $forums as $forum ) :
 		if ( isset($_POST['name-' . $forum->forum_id]) && '' !== $_POST['name-' . $forum->forum_id] )
-			bb_update_forum( $forum->forum_id, $_POST['name-' . $forum->forum_id], $_POST['desc-' . $forum->forum_id], $_POST['order-' . $forum->forum_id]);
+			bb_update_forum( $forum->forum_id, $_POST['name-' . $forum->forum_id], $_POST['desc-' . $forum->forum_id], $_POST['order-' . $forum->forum_id], $_POST['category-' . $forum->forum_id]);
 	endforeach;
 	wp_redirect( $sent_from );
 	exit;
Index: bb-admin/upgrade-schema.php
===================================================================
--- bb-admin/upgrade-schema.php	(revision 629)
+++ bb-admin/upgrade-schema.php	(working copy)
@@ -2,14 +2,24 @@
 require_once('../bb-load.php');
 set_time_limit(600);
 
-$bb_queries = "CREATE TABLE $bbdb->forums (
+$bb_queries = "CREATE TABLE $bbdb->categories (
+  category_id int(10) NOT NULL auto_increment,
+  category_name varchar(150)  NOT NULL default '',
+  category_desc text  NOT NULL,
+  category_order int(10) NOT NULL default '0',
+  forums bigint(20) NOT NULL default '0',
+  PRIMARY KEY  (category_id)
+);
+CREATE TABLE $bbdb->forums (
   forum_id int(10) NOT NULL auto_increment,
+  category_id int(10) NOT NULL default '0',
   forum_name varchar(150)  NOT NULL default '',
   forum_desc text  NOT NULL,
   forum_order int(10) NOT NULL default '0',
   topics bigint(20) NOT NULL default '0',
   posts bigint(20) NOT NULL default '0',
   PRIMARY KEY  (forum_id)
+  KEY category_id (category_id),
 );
 CREATE TABLE $bbdb->posts (
   post_id bigint(20) NOT NULL auto_increment,
Index: forum.php
===================================================================
--- forum.php	(revision 629)
+++ forum.php	(working copy)
@@ -13,6 +13,7 @@
 do_action( 'bb_forum.php_pre_db', $forum_id );
 
 if ( !$bb_db_override ) :
+	$category = get_category( $forum->category_id );
 	$topics   = get_latest_topics( $forum_id, $page );
 	$stickies = get_sticky_topics( $forum_id, $page );
 endif;

