diff -u -F^f -r -x CVS -x .DS_Store -x file.inc -x menu.inc drupal-forum/database/database.mysql drupal-head/database/database.mysql
--- drupal-forum/database/database.mysql	Thu Aug 26 19:49:36 2004
+++ drupal-head/database/database.mysql	Sat Aug 28 23:54:03 2004
@@ -705,6 +705,7 @@
   hierarchy tinyint(3) unsigned NOT NULL default '0',
   multiple tinyint(3) unsigned NOT NULL default '0',
   required tinyint(3) unsigned NOT NULL default '0',
+  module varchar(255) NOT NULL default '',
   nodes longtext,
   weight tinyint(4) NOT NULL default '0',
   PRIMARY KEY  (vid)
diff -u -F^f -r -x CVS -x .DS_Store -x file.inc -x menu.inc drupal-forum/database/updates.inc drupal-head/database/updates.inc
--- drupal-forum/database/updates.inc	Thu Aug 26 19:49:36 2004
+++ drupal-head/database/updates.inc	Sun Aug 29 02:38:50 2004
@@ -81,7 +81,8 @@
   "2004-08-12" => "update_102",
   "2004-08-17" => "update_103",
   "2004-08-19" => "update_104",
-  "2004-08-22" => "update_105"  
+  "2004-08-22" => "update_105",
+  "2004-08-28" => "udpate_106"
 );
 
 function update_32() {
@@ -1584,6 +1585,19 @@ function update_105() {
   $ret[] = update_sql('UPDATE {node} n, {forum_conv_temp} t, {comments} c, {users} u SET n.comment_count = t.comment_count, n.last_comment_timestamp = c.timestamp, n.last_comment_name = IF(c.uid, u.name, c.name), n.last_comment_uid = c.uid WHERE t.cid = c.cid AND n.nid = t.nid AND c.uid = u.uid');
 
   $ret[] = update_sql("DROP TABLE {forum_conv_temp}");
+  
+  return $ret;
+}
+
+function update_106() {
+  $ret = array();
+  
+  $ret[] = update_sql("ALTER TABLE {vocabulary} ADD module varchar(255) NOT NULL default ''");
+  $ret[] = update_sql("UPDATE {vocabulary} SET module = 'taxonomy'");
+  $vid = variable_get('forum_nav_vocabulary', '');
+  if (!empty($vid)) {
+    $ret[] = update_sql("UDPATE {vocabulary} SET module = 'forum' WHERE vid = " . $vid);
+  }
   
   return $ret;
 }
diff -u -F^f -r -x CVS -x .DS_Store -x file.inc -x menu.inc drupal-forum/modules/forum.module drupal-head/modules/forum.module
--- drupal-forum/modules/forum.module	Thu Aug 26 19:49:36 2004
+++ drupal-head/modules/forum.module	Sun Aug 29 02:31:03 2004
@@ -21,8 +21,8 @@ function forum_help($section) {
       <p>All files in the icon directory are assumed to be images. You may use images of whatever size you wish, but it is recommended to use 15x15 or 16x16.</p>", array("%taxonomy" => url('admin/taxonomy/add/vocabulary'), '%taxo-terms' => url('admin/taxonomy'), '%forums' => url('admin/settings/forum'), '%permission' => url('admin/user/configure/permission')));
     case 'admin/modules#description':
       return t('Enable threaded discussions about general topics.');
-    case 'admin/settings/forum':
-      return t("Forums are threaded discussions based on the taxonomy system.  For the forums to work, the taxonomy module has to be installed and enabled.  When activated, a taxonomy vocabulary (eg. \"forums\") needs to be <a href=\"%created\">created</a> and bound to the node type \"forum topic\".", array('%created' => url('admin/taxonomy/add/vocabulary')));
+    case 'admin/forums':
+      return t("Forums are threaded discussions. More help text here!");
     case 'node/add/forum':
       return variable_get('forum_help', '');
     case 'node/add#forum':
@@ -50,54 +50,191 @@ function forum_access($op, $node) {
  * Implementation of hook_perm().
  */
 function forum_perm() {
-  return array('create forum topics');
+  return array('create forum topics', 'administer forums');
 }
 
-/**
- * Implementation of hook_settings().
- */
-function forum_settings() {
+function forum_admin() {
+  $op = $_POST['op'];
+  $edit = $_POST['edit'];
+  
+  if (empty($op)) {
+    $op = arg(2);
+  }
+  
+  switch ($op) {
+    case 'add':
+      if (arg(3) == 'forum') {
+        $output = forum_form_forum();
+      }
+      else if (arg(3) == 'container') {
+        $output = forum_form_container();
+      }
+      break;
+    case 'edit':
+      if (arg(3) == 'forum') {
+        $output = forum_form_forum(object2array(taxonomy_get_term(arg(4))));
+      }
+      else if (arg(3) == 'container') {
+        $output = forum_form_container(object2array(taxonomy_get_term(arg(4))));
+      }
+      break;
+    case t('Delete'):
+      if (!$edit['confirm']) {
+        $output = _forum_confirm_del($edit['tid']);
+        break;
+      }
+      else {
+        $edit['name'] = 0;
+      }
+    case t('Submit'):
+      $edit = taxonomy_save_term($edit);
+      if (arg(3) == 'container') {
+        $containers = variable_get('forum_containers', array());
+        $containers[] = $edit['tid'];
+        variable_set('forum_containers', $containers);
+      }
+      drupal_goto('admin/forums');
+    default:
+      $output = forum_overview();
+  }
+  
+  print theme('page', $output);
+}
 
-  if (module_exist('taxonomy')) {
-    $vocs[0] = '<'. t('none') .'>';
-    foreach (taxonomy_get_vocabularies('forum') as $vid => $voc) {
-      $vocs[$vid] = $voc->name;
-    }
+function _forum_confirm_del($tid) {
+  $term = taxonomy_get_term($tid);
+
+  $form .= form_hidden('confirm', 1);
+  $form .= form_hidden('tid', $tid);
+  $form .= form_submit(t('Delete'));
+  $form .= form_submit(t('Cancel'));
 
-    if ($voc) {
-      $group  = form_select(t('Forum vocabulary'), 'forum_nav_vocabulary', variable_get('forum_nav_vocabulary', ''), $vocs, t("The taxonomy vocabulary that will be used as the navigation tree.  The vocabulary's terms define the forums."));
-      $group .= _taxonomy_term_select(t('Containers'), 'forum_containers', variable_get('forum_containers', array()), variable_get('forum_nav_vocabulary', ''), t('You can choose forums which will not have topics, but will be just containers for other forums.  This lets you both group and nest forums.'), 1, '<'. t('none') .'>');
+  return form(form_item(t('Delete "%name"', array('%name' => $term->name)), $form, t('Deleteing a forum or container will delete all children as well.  Are you sure you want to delete?')));
+}
 
-      $output = form_group(t('Forum structure settings'), $group);
+function forum_form_container($edit = array()) {
+  $form = form_textfield(t('Container name'), 'name', $edit['name'], 50, 64, t('The name for this container.'), NULL, TRUE);
+  $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('A description of the container.'));
+  
+  $form .= _forum_parent_select($edit['tid'], t('Parent'), 'parent][');
+  $form .= form_weight(t('Weight'), 'weight', $edit['weight'], 10, t('In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top.'));
+  
+  $form .= form_hidden('vid', _forum_get_vid());
+  $form .= form_submit(t('Submit'));
+  if ($edit['tid']) {
+    $form .= form_submit(t('Delete'));
+    $form .= form_hidden('tid', $edit['tid']);
+  }
+  
+  return form($form);
+}
+
+function forum_form_forum($edit = array()) {
+  $form = form_textfield(t('Forum name'), 'name', $edit['name'], 50, 64, t('The name for this forum.'), NULL, TRUE);
+  $form .= form_textarea(t('Description'), 'description', $edit['description'], 60, 5, t('A description of the forum.'));
+
+  $form .= _forum_parent_select($edit['tid'], t('Parent'), 'parent][');
+  $form .= form_weight(t('Weight'), 'weight', $edit['weight'], 10, t('In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top.'));
+  
+  $form .= form_hidden('vid', _forum_get_vid());
+  $form .= form_submit(t('Submit'));
+  if ($edit['tid']) {
+    $form .= form_submit(t('Delete'));
+    $form .= form_hidden('tid', $edit['tid']);
+  }
+  
+  return form($form);
+}
 
-      $group  = form_textarea(t('Explanation or submission guidelines'), 'forum_help', variable_get('forum_help', ''), 70, 5, t('This text will be displayed at the top of the forum submission form.  Useful for helping or instructing your users.'));
-      $group .= form_textfield(t('Forum icon path'), 'forum_icon_path', variable_get('forum_icon_path', ''), 30, 255, t('The path to the forum icons.  Leave blank to disable icons.  Don\'t add a trailing slash.  Default icons are available in the "misc" directory.'));
-      $number = drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 10000));
-      $group .= form_select(t('Hot topic threshold'), 'forum_hot_topic', variable_get('forum_hot_topic', 15), $number, t('The number of posts a topic must have to be considered <strong>hot</strong>.'));
-      $number = drupal_map_assoc(array(10, 25, 50, 75, 100));
-      $group .= form_select(t('Topics per page'), 'forum_per_page', variable_get('forum_per_page', 25), $number, t('The default number of topics displayed per page; links to browse older messages are automatically being displayed.'));
-      $forder = array(1 => t('Date - newest first'), 2 => t('Date - oldest first'), 3 => t('Posts - most active first'), 4=> t('Posts - least active first'));
-      $group .= form_radios(t('Default order'), 'forum_order', variable_get('forum_order', '1'), $forder, t('The default display order for topics.'));
-      $output .= form_group(t('Forum viewing options'), $group);
+function _forum_parent_select($tid, $title, $name) {
 
-      $group = form_select(t('Number of topics in block'), 'forum_block_num', variable_get('forum_block_num', '5'), drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)), t('The number of topics to show in the "Forum topics" block.  To enable the block, go to the <a href="%block-administration">block administration</a> page.', array('%block-administration' => url('admin/block'))));
-      $output .= form_group(t('"Forum topic" block settings'), $group);
+  $parents = taxonomy_get_parents($tid);
+  $children = taxonomy_get_tree(_forum_get_vid, $tid);
+
+  // A term can't be the child of itself, nor of its children.
+  foreach ($children as $child) {
+    $exclude[] = $child->tid;
+  }
+  $exclude[] = $tid;
+
+  $tree = taxonomy_get_tree(_forum_get_vid());
+  $options[0] = '<'. t('root') .'>';
+  if ($tree) {
+    foreach ($tree as $term) {
+      if (!in_array($term->tid, $exclude)) {
+        $options[$term->tid] = _forum_depth($term->depth).$term->name;
+      }
     }
+  }  
+  
+  if (!$parents) {
+    $parents = 0;
   }
 
-  return $output;
+  return form_select($title, $name, $parents, $options, NULL, 0, FALSE, TRUE);
+}
+
+function forum_overview() {
+  $header = array(t('Name'), t('Type'), t('Operations'));
+  
+  $tree = taxonomy_get_tree(_forum_get_vid());
+  if ($tree) {
+    foreach ($tree as $term) {
+      if (in_array($term->tid, variable_get('forum_containers', array()))) { 
+        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, t('container'), l(t('edit'), "admin/forums/edit/container/$term->tid"));
+      }
+      else {
+        $rows[] = array(_forum_depth($term->depth) .' '. $term->name, t('forum'), l(t('edit'), "admin/forums/edit/forum/$term->tid"));
+      }   
+    }
+  }
+  
+  return theme('table', $header, $rows);
+}
+
+function _forum_depth($depth, $graphic = '--') {
+  for ($n = 0; $n < $depth; $n++) {
+    $result .= $graphic;
+  }
+  return $result;
 }
 
 /**
- * Implementation of hook_taxonomy().
+ * Returns the vocabulary id for forum navigation.
  */
-function forum_taxonomy($op, $type, $object) {
-  if ($type == 'vocabulary' && ($op == 'insert' || $op == 'update')) {
-    if (variable_get('forum_nav_vocabulary', '') == '' && in_array('forum', $object['nodes'])) {
-      // since none is already set, silently set this vocabulary as the navigation vocabulary
-      variable_set('forum_nav_vocabulary', $object['vid']);
-    }
+function _forum_get_vid() {
+  $vid = variable_get('forum_nav_vocabulary', '');
+  if (empty($vid)) {
+    $vocabulary = taxonomy_save_vocabulary(array('name' => 'Forums', 'multiple' => '0', 'required' => '1', 'hierarchy' => '1', 'relations' => '0', 'module' => 'forums', 'nodes' => array('forum')));
+    $vid = $vocabulary['vid'];
+    variable_set('forum_nav_vocabulary', $vid);
+  }
+  
+  return $vid;
+}
+
+/**
+ * Menu callback; present general forum configuration options
+ */
+function forum_configure() {
+  if ($_POST) {
+    system_settings_save();
   }
+  
+  $group  = form_textarea(t('Explanation or submission guidelines'), 'forum_help', variable_get('forum_help', ''), 70, 5, t('This text will be displayed at the top of the forum submission form.  Useful for helping or instructing your users.'));
+  $group .= form_textfield(t('Forum icon path'), 'forum_icon_path', variable_get('forum_icon_path', ''), 30, 255, t('The path to the forum icons.  Leave blank to disable icons.  Don\'t add a trailing slash.  Default icons are available in the "misc" directory.'));
+  $number = drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100, 10000));
+  $group .= form_select(t('Hot topic threshold'), 'forum_hot_topic', variable_get('forum_hot_topic', 15), $number, t('The number of posts a topic must have to be considered <strong>hot</strong>.'));
+  $number = drupal_map_assoc(array(10, 25, 50, 75, 100));
+  $group .= form_select(t('Topics per page'), 'forum_per_page', variable_get('forum_per_page', 25), $number, t('The default number of topics displayed per page; links to browse older messages are automatically being displayed.'));
+  $forder = array(1 => t('Date - newest first'), 2 => t('Date - oldest first'), 3 => t('Posts - most active first'), 4=> t('Posts - least active first'));
+  $group .= form_radios(t('Default order'), 'forum_order', variable_get('forum_order', '1'), $forder, t('The default display order for topics.'));
+  $output .= form_group(t('Forum viewing options'), $group);
+  
+  $group = form_select(t('Number of topics in block'), 'forum_block_num', variable_get('forum_block_num', '5'), drupal_map_assoc(array(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20)), t('The number of topics to show in the "Forum topics" block.  To enable the block, go to the <a href="%block-administration">block administration</a> page.', array('%block-administration' => url('admin/block'))));
+  $output .= form_group(t('"Forum topic" block settings'), $group);
+  
+  print theme('page', system_settings_form($output));      
 }
 
 /**
@@ -188,14 +325,34 @@ function forum_link($type, $node = 0, $m
  */
 function forum_menu() {
   $items = array();
-
+  
   $items[] = array('path' => 'node/add/forum', 'title' => t('forum topic'),
-    'access' => user_access('create forum topics'));
+    'access' => user_access('create forum topics'));  
+    
   $items[] = array('path' => 'forum', 'title' => t('forums'),
     'callback' => 'forum_page',
     'access' => user_access('access content'),
     'type' => MENU_CALLBACK);
-
+    
+  $items[] = array('path' => 'admin/forums', 'title' => t('forums'),
+    'callback' => 'forum_admin',
+    'access' => user_access('administer forums'),
+    'type' => MENU_NORMAL_ITEM);
+    
+  $items[] = array('path' => 'admin/forums/list', 'title' => t('list'),
+    'access' => user_access('administer forums'),
+    'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
+  $items[] = array('path' => 'admin/forums/add/container', 'title' => t('add container'),
+    'access' => user_access('administer forums'),
+    'type' => MENU_LOCAL_TASK);
+  $items[] = array('path' => 'admin/forums/add/forum', 'title' => t('add forum'),
+    'access' => user_access('administer forums'),
+    'type' => MENU_LOCAL_TASK);
+  $items[] = array('path' => 'admin/forums/configure', 'title' => t('configure'),
+    'access' => user_access('administer forums'),
+    'callback' => 'forum_configure',
+    'type' => MENU_LOCAL_TASK);
+    
   return $items;
 }
 
diff -u -F^f -r -x CVS -x .DS_Store -x file.inc -x menu.inc drupal-forum/modules/taxonomy.module drupal-head/modules/taxonomy.module
--- drupal-forum/modules/taxonomy.module	Thu Aug 26 19:49:36 2004
+++ drupal-head/modules/taxonomy.module	Sat Aug 28 23:11:56 2004
@@ -118,7 +118,7 @@ function taxonomy_save_vocabulary($edit)
     $edit['nodes'] = array();
   }
 
-  $data = array('name' => $edit['name'], 'nodes' => implode(',', $edit['nodes']), 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight']);
+  $data = array('name' => $edit['name'], 'nodes' => implode(',', $edit['nodes']), 'description' => $edit['description'], 'help' => $edit['help'], 'multiple' => $edit['multiple'], 'required' => $edit['required'], 'hierarchy' => $edit['hierarchy'], 'relations' => $edit['relations'], 'weight' => $edit['weight'], 'module' => isset($edit['module']) ? $edit['module'] : 'taxonomy');
   if ($edit['vid'] && $edit['name']) {
     db_query('UPDATE {vocabulary} SET '. _taxonomy_prepare_update($data) .' WHERE vid = %d', $edit['vid']);
     module_invoke_all('taxonomy', 'update', 'vocabulary', $edit);
@@ -304,21 +304,23 @@ function taxonomy_overview() {
   $vocabularies = taxonomy_get_vocabularies();
 
   foreach ($vocabularies as $vocabulary) {
-    $links = array();
-    $types = array();
-    foreach(explode(',', $vocabulary->nodes) as $type) {
-      $types[] = node_invoke($type, 'node_name');
-    }
-    $rows[] = array($vocabulary->name, array('data' => implode(', ', $types), 'align' => 'center'), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
-
-    $tree = taxonomy_get_tree($vocabulary->vid);
-    if ($tree) {
-      unset($data);
-      foreach ($tree as $term) {
-        $data .= _taxonomy_depth($term->depth) .' '. $term->name .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
+    if ($vocabulary->module == 'taxonomy') {
+      $links = array();
+      $types = array();
+      foreach(explode(',', $vocabulary->nodes) as $type) {
+        $types[] = node_invoke($type, 'node_name');
       }
-      $rows[] = array(array('data' => $data, 'colspan' => 5));
-    }
+      $rows[] = array($vocabulary->name, array('data' => implode(', ', $types), 'align' => 'center'), l(t('edit vocabulary'), "admin/taxonomy/edit/vocabulary/$vocabulary->vid"), l(t('add term'), "admin/taxonomy/add/term/$vocabulary->vid"), l(t('preview form'), "admin/taxonomy/preview/vocabulary/$vocabulary->vid"));
+  
+      $tree = taxonomy_get_tree($vocabulary->vid);
+      if ($tree) {
+        unset($data);
+        foreach ($tree as $term) {
+          $data .= _taxonomy_depth($term->depth) .' '. $term->name .' ('. l(t('edit term'), "admin/taxonomy/edit/term/$term->tid") .')<br />';
+        }
+        $rows[] = array(array('data' => $data, 'colspan' => 5));
+      }
+    }      
   }
 
   return theme('table', $header, $rows);
Only in drupal-head/themes: dawnsedge
