diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/admin-ajax.php ./wp-admin/admin-ajax.php
--- wp-vanilla/wp-admin/admin-ajax.php	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-admin/admin-ajax.php	2008-12-30 03:36:13.444959922 +0100
@@ -927,6 +927,7 @@
 			$data['cat_ID'] = $id;
 			$data['cat_name'] = $_POST['name'];
 			$data['category_nicename'] = $_POST['slug'];
+			$data['category_flags'] = $_POST['flags'];
 			if ( isset($_POST['parent']) && (int) $_POST['parent'] > 0 )
 				$data['category_parent'] = $_POST['parent'];
 
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/categories.php ./wp-admin/categories.php
--- wp-vanilla/wp-admin/categories.php	2008-12-04 22:57:56.000000000 +0100
+++ ./wp-admin/categories.php	2008-12-30 03:52:00.895342220 +0100
@@ -277,6 +277,13 @@
     <p><?php _e('The description is not prominent by default, however some themes may show it.'); ?></p>
 </div>
 
+<div class="form-field">
+<div class="form-checkbox">
+	<span><input type="checkbox" id="category_hidden" name="category_flags" value="hidden" /><label for="category_hidden"><?php _e("Hide category and posts") ?></label></span>
+    <p><?php _e('If checked, the category is hidden from the category listing. Posts in this category are hidden from the entries feed, and from the previous and next post links.'); ?></p>
+</div>
+</div>
+
 <p class="submit"><input type="submit" class="button" name="submit" value="<?php _e('Add Category'); ?>" /></p>
 <?php do_action('edit_category_form', $category); ?>
 </form></div>
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/edit-category-form.php ./wp-admin/edit-category-form.php
--- wp-vanilla/wp-admin/edit-category-form.php	2008-12-09 10:07:36.000000000 +0100
+++ ./wp-admin/edit-category-form.php	2008-12-30 03:11:03.719156108 +0100
@@ -69,7 +69,15 @@
 			<td><textarea name="category_description" id="category_description" rows="5" cols="50" style="width: 97%;"><?php echo wp_specialchars($category->description); ?></textarea><br />
             <?php _e('The description is not prominent by default, however some themes may show it.'); ?></td>
 		</tr>
+		<tr class="form-field">
+			<th scope="row" valign="top"><label for="category_description"><?php _e('Flags') ?></label></th>
+			<td><span class="form-checkbox"><input type="checkbox" id="category_hidden" name="category_flags[]" value="hidden" <?php if ( is_category_flag_set($category, "hidden") ) { ?> checked <?php } ?>/><label for="category_hidden"><?php _e("Hide category and posts") ?></label></span><br />
+            <?php _e('If checked, the category is hidden from the category listing. Posts in this category are hidden from the entries feed, and from the previous and next post links.'); ?></td>
+
+		</tr>
 	</table>
+<?php // Always have empty flags ?>
+<input type="hidden" name="category_flags[]" value="" />
 <p class="submit"><input type="submit" class="button-primary" name="submit" value="<?php _e('Update Category'); ?>" /></p>
 <?php do_action('edit_category_form', $category); ?>
 </form>
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/includes/schema.php ./wp-admin/includes/schema.php
--- wp-vanilla/wp-admin/includes/schema.php	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-admin/includes/schema.php	2008-12-30 14:57:23.655457503 +0100
@@ -32,6 +32,7 @@
  name varchar(200) NOT NULL default '',
  slug varchar(200) NOT NULL default '',
  term_group bigint(10) NOT NULL default 0,
+ flags varchar(100) NOT NULL default '',
  PRIMARY KEY  (term_id),
  UNIQUE KEY slug (slug),
  KEY name (name)
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/includes/taxonomy.php ./wp-admin/includes/taxonomy.php
--- wp-vanilla/wp-admin/includes/taxonomy.php	2008-11-03 00:52:49.000000000 +0100
+++ ./wp-admin/includes/taxonomy.php	2008-12-30 03:21:26.330668132 +0100
@@ -108,7 +108,7 @@
  * @return unknown
  */
 function wp_insert_category($catarr, $wp_error = false) {
-	$cat_defaults = array('cat_ID' => 0, 'cat_name' => '', 'category_description' => '', 'category_nicename' => '', 'category_parent' => '');
+	$cat_defaults = array('cat_ID' => 0, 'cat_name' => '', 'category_description' => '', 'category_nicename' => '', 'category_parent' => '', 'category_flags' => '');
 	$catarr = wp_parse_args($catarr, $cat_defaults);
 	extract($catarr, EXTR_SKIP);
 
@@ -131,6 +131,7 @@
 	$description = $category_description;
 	$slug = $category_nicename;
 	$parent = $category_parent;
+        $flags = $category_flags;
 
 	$parent = (int) $parent;
 	if ( $parent < 0 )
@@ -139,7 +140,7 @@
 	if ( empty($parent) || !category_exists( $parent ) || ($cat_ID && cat_is_ancestor_of($cat_ID, $parent) ) )
 		$parent = 0;
 
-	$args = compact('name', 'slug', 'parent', 'description');
+	$args = compact('name', 'slug', 'parent', 'description', 'flags');
 
 	if ( $update )
 		$cat_ID = wp_update_term($cat_ID, 'category', $args);
@@ -170,6 +171,9 @@
 	if ( isset($catarr['category_parent']) && ($cat_ID == $catarr['category_parent']) )
 		return false;
 
+        if ( isset($catarr['category_flags']) )
+                $catarr['category_flags'] = join( ',', $catarr['category_flags'] );
+
 	// First, get all of the original fields
 	$category = get_category($cat_ID, ARRAY_A);
 
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/includes/template.php ./wp-admin/includes/template.php
--- wp-vanilla/wp-admin/includes/template.php	2008-12-10 23:22:30.000000000 +0100
+++ ./wp-admin/includes/template.php	2008-12-30 04:17:48.562614143 +0100
@@ -170,6 +170,7 @@
 				$output .= '<div class="hidden" id="inline_' . $qe_data->term_id . '">';
 				$output .= '<div class="name">' . $qe_data->name . '</div>';
 				$output .= '<div class="slug">' . $qe_data->slug . '</div>';
+				$output .= '<div class="flags">' . $qe_data->flags . '</div>';
 				$output .= '<div class="cat_parent">' . $qe_data->parent . '</div></div></td>';
 				break;
 			case 'description':
@@ -234,6 +235,11 @@
 
 <?php endif; // $type ?>
 
+			<label>
+				<span class="title"><?php _e( 'Flags' ); ?></span>
+				<span class="input-text-wrap"><input type="checkbox" name="flags[]" class="hidden-flag" value="hidden"   style="float: left"/><label for="hidden">Hidden</label></span>
+			</label>
+
 		</div></fieldset>
 
 <?php
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/js/inline-edit-tax.js ./wp-admin/js/inline-edit-tax.js
--- wp-vanilla/wp-admin/js/inline-edit-tax.js	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-admin/js/inline-edit-tax.js	2008-12-30 04:22:32.732119874 +0100
@@ -57,6 +57,15 @@
 
 		$(':input[name="name"]', editRow).val( $('.name', rowData).text() );
 		$(':input[name="slug"]', editRow).val( $('.slug', rowData).text() );
+                var flags = $( '.flags', rowData ).text();
+                flags = flags.split(',');
+                for ( var i = 0; i < flags.length; i++ ) {
+                        switch(flags[i]) {
+                                case 'hidden':
+                        		$(':input[class="hidden-flag"]', editRow).attr( 'checked', true );
+                                        break;
+                        }
+                }
 
 		// cat parents
 		var cat_parent = $('.cat_parent', rowData).text();
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-admin/wp-admin.css ./wp-admin/wp-admin.css
--- wp-vanilla/wp-admin/wp-admin.css	2008-12-10 10:26:23.000000000 +0100
+++ ./wp-admin/wp-admin.css	2008-12-30 03:12:33.689303228 +0100
@@ -1267,6 +1267,22 @@
 	font-size: 12px;
 }
 
+.form-field .form-checkbox input {
+	border-style: solid;
+	border-width: 1px;
+        margin-right: 2px;
+        width: 0px;
+        float: left;
+}
+
+.form-field .form-checkbox label {
+        font-size: 13px;
+}
+
+.form-field .form-checkbox span {
+        vertical-align: text-top
+}
+
 .form-field input,
 .form-field textarea {
 	border-style: solid;
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/category.php ./wp-includes/category.php
--- wp-vanilla/wp-includes/category.php	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-includes/category.php	2008-12-30 04:49:29.930777779 +0100
@@ -6,6 +6,30 @@
  */
 
 /**
+ * Retrieves all possible category flags.
+ *
+ * @since ???
+ * @link ???
+ *
+ * @return array List of all possible category flags.
+ */
+function get_all_category_flags() {
+        return array( 'hidden' );
+}
+
+/**
+ * Retrieves all possible category flags.
+ *
+ * @since ???
+ * @link ???
+ *
+ * @return array List of all possible category flags.
+ */
+function is_category_flag_set($cat, $flag) {
+        return in_array ( $flag, split( ',', $cat->flags ) );
+}
+
+/**
  * Retrieves all category IDs.
  *
  * @since 2.0.0
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/category-template.php ./wp-includes/category-template.php
--- wp-vanilla/wp-includes/category-template.php	2008-12-10 00:31:11.000000000 +0100
+++ ./wp-includes/category-template.php	2008-12-30 18:08:05.535459076 +0100
@@ -480,6 +480,14 @@
 
 	$categories = get_categories( $r );
 
+        $nonhidden_categories = array ();
+        foreach ( $categories as $category ) {
+            if ( is_category_flag_set($category, "hidden") )
+                continue;
+            array_push($nonhidden_categories, $category);
+        }
+        $categories = $nonhidden_categories;
+
 	$output = '';
 	if ( $title_li && 'list' == $style )
 			$output = '<li class="categories">' . $r['title_li'] . '<ul>';
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/feed-rss2.php ./wp-includes/feed-rss2.php
--- wp-vanilla/wp-includes/feed-rss2.php	2008-08-11 22:50:41.000000000 +0200
+++ ./wp-includes/feed-rss2.php	2008-12-30 05:09:02.851550598 +0100
@@ -31,7 +31,9 @@
 	<sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
 	<sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
 	<?php do_action('rss2_head'); ?>
-	<?php while( have_posts()) : the_post(); ?>
+	<?php while ( have_posts() ) : the_post(); ?>
+        <?php     if ( is_hidden_category() ) continue; ?>
+
 	<item>
 		<title><?php the_title_rss() ?></title>
 		<link><?php the_permalink_rss() ?></link>
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/link-template.php ./wp-includes/link-template.php
--- wp-vanilla/wp-includes/link-template.php	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-includes/link-template.php	2008-12-30 00:18:44.107239374 +0100
@@ -863,6 +863,23 @@
 	if( empty($post) || !is_single() || is_attachment() )
 		return null;
 
+        # Augment explicitly excluded categories with implicitly exluded categories.
+        $categories = get_categories();
+
+        $hidden_categories = array();
+        foreach ( $categories as $cat )
+        {
+             if ( in_array("hidden", split(",", $cat->flags)) )
+                array_push($hidden_categories, $cat->cat_ID);
+        }
+
+        if ( !empty($hidden_categories) )
+        {
+            if ( empty($excluded_categories) )
+                $excluded_categories .= join(' and ', $hidden_categories);
+            else
+                $excluded_categories .= ' and ' . join(' and ', $hidden_categories);
+        }
 	$current_post_date = $post->post_date;
 
 	$join = '';
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/query.php ./wp-includes/query.php
--- wp-vanilla/wp-includes/query.php	2008-12-09 19:03:31.000000000 +0100
+++ ./wp-includes/query.php	2008-12-30 05:09:34.741536601 +0100
@@ -173,6 +173,28 @@
 	return false;
 }
 
+
+/**
+ * Whether the current post is in a hidden category.
+ *
+ * @since ???
+ *
+ * @param 
+ * @return bool
+ */
+function is_hidden_category ()
+{
+        $categories = get_the_category();
+        $is_hidden = FALSE;
+        foreach ( $categories as $cat ) { 
+                 if ( is_category_flag_set($cat, "hidden") ) { 
+                         $is_hidden = TRUE; 
+                         break; 
+                 }
+        } 
+        return $is_hidden;
+}
+
 /**
  * Whether current page query contains a category name or given category name.
  *
diff -Naur -x wp-vanilla -x old-20081218 -x custom -x databalk -x '*~' -x wp-config.php -x awacs -x uploads -x '.#*' -x '#*' -x wp-content -x software wp-vanilla/wp-includes/taxonomy.php ./wp-includes/taxonomy.php
--- wp-vanilla/wp-includes/taxonomy.php	2008-12-10 00:31:11.000000000 +0100
+++ ./wp-includes/taxonomy.php	2008-12-30 03:21:38.785861825 +0100
@@ -1284,7 +1284,7 @@
 	if ( '' == trim($term) )
 		return new WP_Error('empty_term_name', __('A name is required for this term'));
 
-	$defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
+	$defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '', 'flags' => '');
 	$args = wp_parse_args($args, $defaults);
 	$args['name'] = $term;
 	$args['taxonomy'] = $taxonomy;
@@ -1294,6 +1294,7 @@
 	// expected_slashed ($name)
 	$name = stripslashes($name);
 	$description = stripslashes($description);
+        $flags = stripslashes($flags);
 
 	if ( empty($slug) )
 		$slug = sanitize_title($name);
@@ -1312,14 +1313,14 @@
 	}
 
 	if ( ! $term_id = is_term($slug) ) {
-		if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) )
+		if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group', 'flags' ) ) )
 			return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error);
 		$term_id = (int) $wpdb->insert_id;
 	} else if ( is_taxonomy_hierarchical($taxonomy) && !empty($parent) ) {
 		// If the taxonomy supports hierarchy and the term has a parent, make the slug unique
 		// by incorporating parent slugs.
 		$slug = wp_unique_term_slug($slug, (object) $args);
-		if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group' ) ) )
+		if ( false === $wpdb->insert( $wpdb->terms, compact( 'name', 'slug', 'term_group', 'flags' ) ) )
 			return new WP_Error('db_insert_error', __('Could not insert term into the database'), $wpdb->last_error);
 		$term_id = (int) $wpdb->insert_id;
 	}
@@ -1334,7 +1335,7 @@
 	if ( !empty($tt_id) )
 		return array('term_id' => $term_id, 'term_taxonomy_id' => $tt_id);
 
-	$wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent') + array( 'count' => 0 ) );
+	$wpdb->insert( $wpdb->term_taxonomy, compact( 'term_id', 'taxonomy', 'description', 'parent' ) + array( 'count' => 0 ) );
 	$tt_id = (int) $wpdb->insert_id;
 
 	do_action("create_term", $term_id, $tt_id);
@@ -1545,7 +1546,7 @@
 	// Merge old and new args with new args overwriting old ones.
 	$args = array_merge($term, $args);
 
-	$defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '');
+	$defaults = array( 'alias_of' => '', 'description' => '', 'parent' => 0, 'slug' => '', 'flags' => '');
 	$args = wp_parse_args($args, $defaults);
 	$args = sanitize_term($args, $taxonomy, 'db');
 	extract($args, EXTR_SKIP);
@@ -1553,6 +1554,7 @@
 	// expected_slashed ($name)
 	$name = stripslashes($name);
 	$description = stripslashes($description);
+        $flags = stripslashes($flags);
 
 	if ( '' == trim($name) )
 		return new WP_Error('empty_term_name', __('A name is required for this term'));
@@ -1586,7 +1588,7 @@
 			return new WP_Error('duplicate_term_slug', sprintf(__('The slug "%s" is already in use by another term'), $slug));
 	}
 
-	$wpdb->update($wpdb->terms, compact( 'name', 'slug', 'term_group' ), compact( 'term_id' ) );
+	$wpdb->update($wpdb->terms, compact( 'name', 'slug', 'term_group', 'flags' ), compact( 'term_id' ) );
 
 	if ( empty($slug) ) {
 		$slug = sanitize_title($name, $term_id);


