Index: modules/blogapi/blogapi.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/blogapi/blogapi.test,v
retrieving revision 1.16
diff -u -p -r1.16 blogapi.test
--- modules/blogapi/blogapi.test	17 Aug 2009 19:14:40 -0000	1.16
+++ modules/blogapi/blogapi.test	20 Aug 2009 00:37:42 -0000
@@ -146,8 +146,6 @@ class BlogAPITestCase extends DrupalWebT
     $vocabulary->name = $vocab;
     $vocabulary->description = $this->randomName();
     $vocabulary->machine_name = $this->randomName();
-    $vocabulary->help = '';
-    $vocabulary->nodes = array('blog' => 'blog');
     $vocabulary->weight = mt_rand(0, 10);
     taxonomy_vocabulary_save($vocabulary);
 
Index: modules/forum/forum.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.install,v
retrieving revision 1.32
diff -u -p -r1.32 forum.install
--- modules/forum/forum.install	13 Aug 2009 11:43:34 -0000	1.32
+++ modules/forum/forum.install	20 Aug 2009 00:37:43 -0000
@@ -102,7 +102,7 @@ function forum_schema() {
       ),
     ),
     'indexes' => array(
-      'nid' => array('nid'),
+      'forum_topic' => array('nid', 'tid'),
       'tid' => array('tid'),
     ),
     'primary key' => array('vid'),
@@ -114,3 +114,14 @@ function forum_schema() {
 
   return $schema;
 }
+
+/**
+ * Add new index to forum table.
+ */
+function forum_update_7000() {
+  $ret = array();
+  db_drop_index($ret, 'forum', 'nid');
+  db_add_index($ret, 'forum', 'forum_topic', array('nid', 'tid'));
+
+  return $ret;
+}
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.507
diff -u -p -r1.507 forum.module
--- modules/forum/forum.module	28 Jul 2009 10:41:20 -0000	1.507
+++ modules/forum/forum.module	20 Aug 2009 00:37:44 -0000
@@ -289,7 +289,7 @@ function forum_node_presave($node) {
           $node->tid = $term_id;
         }
       }
-      $old_tid = db_query_range("SELECT t.tid FROM {taxonomy_term_node} t INNER JOIN {node} n ON t.vid = n.vid WHERE n.nid = :nid ORDER BY t.vid DESC", array(':nid' => $node->nid), 0, 1)->fetchField();
+      $old_tid = db_query_range("SELECT f.tid FROM {forum} f INNER JOIN {node} n ON f.vid = n.vid WHERE n.nid = :nid ORDER BY f.vid DESC", array(':nid' => $node->nid), 0, 1)->fetchField();
       if ($old_tid && isset($node->tid) && ($node->tid != $old_tid) && !empty($node->shadow)) {
         // A shadow copy needs to be created. Retain new term and add old term.
         $node->taxonomy[] = $old_tid;
@@ -439,7 +439,7 @@ function forum_taxonomy($op, $type, $ter
   if ($op == 'delete' && $term['vid'] == variable_get('forum_nav_vocabulary', 0)) {
     switch ($type) {
       case 'term':
-        $result = db_query('SELECT tn.nid FROM {taxonomy_term_node} tn WHERE tn.tid = :tid', array(':tid' => $term['tid']));
+        $result = db_query('SELECT f.nid FROM {forum} f WHERE f.tid = :tid', array(':tid' => $term['tid']));
         foreach ($result as $node) {
           // node_delete will also remove any association with non-forum vocabularies.
           node_delete($node->nid);
@@ -525,8 +525,8 @@ function forum_block_save($delta = '', $
 function forum_block_view($delta = '') {
   if (user_access('access content')) {
     $query = db_select('node', 'n');
-    $query->join('taxonomy_term_node', 'tn', 'tn.vid = n.vid');
-    $query->join('taxonomy_term_data', 'td', 'td.tid = tn.tid');
+    $query->join('forum', 'f', 'f.vid = n.vid');
+    $query->join('taxonomy_term_data', 'td', 'td.tid = f.tid');
     $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
     $query
       ->fields('n', array('nid', 'title'))
@@ -610,11 +610,11 @@ function forum_get_forums($tid = 0) {
   if (count($_forums)) {
     $query = db_select('node', 'n');
     $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
-    $query->join('taxonomy_term_node', 'r', 'n.vid = r.vid');
+    $query->join('forum', 'f', 'f.vid = f.vid');
     $query->addExpression('COUNT(n.nid)', 'topic_count');
     $query->addExpression('SUM(ncs.comment_count)', 'comment_count');
     $counts = $query
-      ->fields('r', array('tid'))
+      ->fields('f', array('tid'))
       ->condition('status', 1)
       ->groupBy('tid')
       ->addTag('node_access')
@@ -638,7 +638,7 @@ function forum_get_forums($tid = 0) {
 
     $query = db_select('node', 'n');
     $query->join('users', 'u1', 'n.uid = u1.uid');
-    $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid AND tn.tid = :tid', array(':tid' => $forum->tid));
+    $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $forum->tid));
     $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
     $query->join('users', 'u2', 'ncs.last_comment_uid = u2.uid');
     $query->addExpression('IF (ncs.last_comment_uid != 0, u2.name, ncs.last_comment_name)', 'last_comment_name');
@@ -672,7 +672,7 @@ function forum_get_forums($tid = 0) {
  */
 function _forum_topics_unread($term, $uid) {
   $query = db_select('node', 'n');
-  $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid AND tn.tid = :tid', array(':tid' => $term));
+  $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $term));
   $query->join('history', 'h', 'n.nid = h.nid AND h.uid = :uid', array(':uid' => $uid));
   $query->addExpression('COUNT(n.nid)', 'count');
   return $query
@@ -704,9 +704,8 @@ function forum_get_topics($tid, $sortby,
   $query = db_select('node_comment_statistics', 'ncs')->extend('PagerDefault')->extend('TableSort');
   $query->join('node', 'n', 'n.nid = ncs.nid');
   $query->join('users', 'cu', 'ncs.last_comment_uid = cu.uid');
-  $query->join('taxonomy_term_node', 'r', 'n.vid = r.vid AND r.tid = :tid', array(':tid' => $tid));
+  $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $tid));
   $query->join('users', 'u', 'n.uid = u.uid');
-  $query->join('forum', 'f', 'n.vid = f.vid');
   $query->addExpression('IF(ncs.last_comment_uid != 0, cu.name, ncs.last_comment_name)', 'last_comment_name');
   $query->addField('n', 'created', 'timestamp');
   $query->addField('n', 'comment', 'comment_mode');
@@ -715,7 +714,7 @@ function forum_get_topics($tid, $sortby,
   $query
     ->addTag('node_access')
     ->fields('n', array('nid', 'title', 'type', 'sticky'))
-    ->fields('r', array('tid'))
+    ->fields('f', array('tid'))
     ->fields('u', array('name', 'uid'))
     ->fields('ncs', array('last_comment_timestamp', 'last_comment_uid'))
     ->condition('n.status', 1)
@@ -725,7 +724,7 @@ function forum_get_topics($tid, $sortby,
     ->limit($forum_per_page);
 
   $count_query = db_select('node', 'n');
-  $count_query->join('taxonomy_term_node', 'r', 'n.vid = r.vid AND r.tid = :tid', array(':tid' => $tid));
+  $count_query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => $tid));
   $count_query->addExpression('COUNT(*)');
   $count_query
     ->condition('n.status', 1)
@@ -1023,7 +1022,7 @@ function template_preprocess_forum_topic
   // Get previous and next topic.
   $query = db_select('node', 'n');
   $query->join('node_comment_statistics', 'ncs', 'n.nid = ncs.nid');
-  $query->join('taxonomy_term_node', 'r', 'n.vid = r.vid AND r.tid = :tid', array(':tid' => isset($variables['node']->tid) ? $variables['node']->tid : 0));
+  $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', array(':tid' => isset($variables['node']->tid) ? $variables['node']->tid : 0));
 
   $order = _forum_get_topic_order(variable_get('forum_order', 1));
   $result = $query
Index: modules/forum/forum.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.test,v
retrieving revision 1.27
diff -u -p -r1.27 forum.test
--- modules/forum/forum.test	3 Aug 2009 03:04:33 -0000	1.27
+++ modules/forum/forum.test	20 Aug 2009 00:37:44 -0000
@@ -126,8 +126,7 @@ class ForumTestCase extends DrupalWebTes
     $edit = array(
       'name' => $title,
       'description' => $description,
-      'machine_name' => drupal_strtolower($this->randomName()),
-      'help' => '',
+      'machine_name' => drupal_strtolower(drupal_substr($this->randomName(), 3, 9)),
     );
 
     // Edit the vocabulary.
Index: modules/taxonomy/taxonomy.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.admin.inc,v
retrieving revision 1.64
diff -u -p -r1.64 taxonomy.admin.inc
--- modules/taxonomy/taxonomy.admin.inc	4 Aug 2009 06:50:07 -0000	1.64
+++ modules/taxonomy/taxonomy.admin.inc	20 Aug 2009 00:37:45 -0000
@@ -17,14 +17,8 @@ function taxonomy_overview_vocabularies(
   $vocabularies = taxonomy_get_vocabularies();
   $form = array('#tree' => TRUE);
   foreach ($vocabularies as $vocabulary) {
-    $types = array();
-    foreach ($vocabulary->nodes as $type) {
-      $node_type = node_type_get_name($type);
-      $types[] = $node_type ? check_plain($node_type) : check_plain($type);
-    }
     $form[$vocabulary->vid]['#vocabulary'] = $vocabulary;
     $form[$vocabulary->vid]['name'] = array('#markup' => check_plain($vocabulary->name));
-    $form[$vocabulary->vid]['types'] = array('#markup' => implode(', ', $types));
     $form[$vocabulary->vid]['weight'] = array('#type' => 'weight', '#delta' => 10, '#default_value' => $vocabulary->weight);
     $form[$vocabulary->vid]['edit'] = array('#markup' => l(t('edit vocabulary'), "admin/structure/taxonomy/$vocabulary->vid"));
     $form[$vocabulary->vid]['list'] = array('#markup' => l(t('list terms'), "admin/structure/taxonomy/$vocabulary->vid/list"));
@@ -71,7 +65,6 @@ function theme_taxonomy_overview_vocabul
 
       $row = array();
       $row[] = drupal_render($vocabulary['name']);
-      $row[] = drupal_render($vocabulary['types']);
       if (isset($vocabulary['weight'])) {
         $vocabulary['weight']['#attributes']['class'] = 'vocabulary-weight';
         $row[] = drupal_render($vocabulary['weight']);
@@ -87,7 +80,7 @@ function theme_taxonomy_overview_vocabul
     $rows[] = array(array('data' => t('No vocabularies available. <a href="@link">Add vocabulary</a>.', array('@link' => url('admin/structure/taxonomy/add'))), 'colspan' => '5'));
   }
 
-  $header = array(t('Vocabulary name'), t('Content types'));
+  $header = array(t('Vocabulary name'));
   if (isset($form['submit'])) {
     $header[] = t('Weight');
     drupal_add_tabledrag('taxonomy', 'order', 'sibling', 'vocabulary-weight');
@@ -111,12 +104,7 @@ function taxonomy_form_vocabulary(&$form
     'name' => '',
     'machine_name' => '',
     'description' => '',
-    'help' => '',
-    'nodes' => array(),
     'hierarchy' => 0,
-    'tags' => 0,
-    'multiple' => 0,
-    'required' => 0,
     'weight' => 0,
   );
   $form['#vocabulary'] = (object) $edit;
@@ -140,47 +128,11 @@ function taxonomy_form_vocabulary(&$form
     '#description' => t('The unique machine readable name for this vocabulary, used for theme templates, can only contain lowercase letters, numbers and underscores.'),
     '#required' => TRUE,
   );
-  $form['help'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Help text'),
-    '#maxlength' => 255,
-    '#default_value' => $edit['help'],
-    '#description' => t('Instructions to present to the user when selecting terms, e.g., <em>"Enter a comma separated list of words"</em>.'),
-  );
   $form['description'] = array(
     '#type' => 'textfield',
     '#title' => t('Description'),
     '#default_value' => $edit['description'],
   );
-  $form['nodes'] = array(
-    '#type' => 'checkboxes',
-    '#title' => t('Apply to content types'),
-    '#default_value' => $edit['nodes'],
-    '#options' => array_map('check_plain', node_type_get_names()),
-  );
-  $form['settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Settings'),
-    '#collapsible' => TRUE,
-  );
-  $form['settings']['tags'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Tags'),
-    '#default_value' => $edit['tags'],
-    '#description' => t('Terms are created by users when submitting posts by typing a comma separated list.'),
-  );
-  $form['settings']['multiple'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Multiple select'),
-    '#default_value' => $edit['multiple'],
-    '#description' => t('Allows posts to have more than one term from this vocabulary (always true for tags).'),
-  );
-  $form['settings']['required'] = array(
-    '#type' => 'checkbox',
-    '#title' => t('Required'),
-    '#default_value' => $edit['required'],
-    '#description' => t('At least one term in this vocabulary must be selected when submitting a post.'),
-  );
   // Set the hierarchy to "multiple parents" by default. This simplifies the
   // vocabulary form and standardizes the term form.
   $form['hierarchy'] = array(
@@ -231,8 +183,6 @@ function taxonomy_form_vocabulary_submit
     $form_state['confirm_delete'] = TRUE;
     return;
   }
-  // Fix up the nodes array to remove unchecked nodes.
-  $form_state['values']['nodes'] = array_filter($form_state['values']['nodes']);
   $vocabulary = (object) $form_state['values'];
   if ($vocabulary->machine_name != $old_vocabulary->machine_name) {
     field_attach_rename_bundle($old_vocabulary->machine_name, $vocabulary->machine_name);
@@ -293,106 +243,71 @@ function taxonomy_overview_terms(&$form_
   // An array of the terms to be displayed on this page.
   $current_page = array();
 
-  // Case for free tagging.
-  if ($vocabulary->tags) {
-    // We are not calling taxonomy_get_tree because that might fail with a big
-    // number of tags in the freetagging vocabulary.
-    $query = db_select('taxonomy_term_data', 't')->extend('PagerDefault');
-    $query->join('taxonomy_term_hierarchy', 'h', 't.tid = h.tid');
-    $query->addTag('term_access');
-    $query->condition('t.vid', $vocabulary->vid);
-
-    // Store count in total entries and use this as count query.
-    $count_query = db_select('taxonomy_term_data', 't');
-    $count_query->join('taxonomy_term_hierarchy', 'h', 't.tid = h.tid');
-    $count_query->addTag('term_access');
-    $count_query->condition('t.vid', $vocabulary->vid);
-    $count_query->addExpression('COUNT(t.tid)');
-    $total_entries = $count_query->execute();
-    $query->setCountQuery($count_query);
-
-    $result = $query
-      ->fields('t')
-      ->fields('h', array('parent'))
-      ->orderBy('weight')
-      ->orderBy('name')
-      ->limit($page_increment)
-      ->execute();
-
-    foreach ($result as $term) {
-      $key = 'tid:' . $term->tid . ':0';
-      $current_page[$key] = $term;
-      $page_entries++;
+  $term_deltas = array();
+  $tree = taxonomy_get_tree($vocabulary->vid);
+  $term = current($tree);
+  do {
+    // In case this tree is completely empty.
+    if (empty($term)) {
+      break;
     }
-  }
-  // Case for restricted vocabulary.
-  else {
-    $term_deltas = array();
-    $tree = taxonomy_get_tree($vocabulary->vid);
-    $term = current($tree);
-    do {
-      // In case this tree is completely empty.
-      if (empty($term)) {
-        break;
-      }
-      // Count entries before the current page.
-      if ($page && ($page * $page_increment) > $before_entries && !isset($back_peddle)) {
-        $before_entries++;
-        continue;
-      }
-      // Count entries after the current page.
-      elseif ($page_entries > $page_increment && isset($complete_tree)) {
-        $after_entries++;
-        continue;
-      }
-
-      // Do not let a term start the page that is not at the root.
-      if (isset($term->depth) && ($term->depth > 0) && !isset($back_peddle)) {
-        $back_peddle = 0;
-        while ($pterm = prev($tree)) {
-          $before_entries--;
-          $back_peddle++;
-          if ($pterm->depth == 0) {
-            prev($tree);
-            continue 2; // Jump back to the start of the root level parent.
-          }
-        }
-      }
-      $back_peddle = isset($back_peddle) ? $back_peddle : 0;
-
-      // Continue rendering the tree until we reach the a new root item.
-      if ($page_entries >= $page_increment + $back_peddle + 1 && $term->depth == 0 && $root_entries > 1) {
-        $complete_tree = TRUE;
-        // This new item at the root level is the first item on the next page.
-        $after_entries++;
-        continue;
-      }
-      if ($page_entries >= $page_increment + $back_peddle) {
-        $forward_peddle++;
-      }
-
-      // Finally, if we've gotten down this far, we're rendering a term on this page.
-      $page_entries++;
-      $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
-      $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];
-
-      // Keep track of the first term displayed on this page.
-      if ($page_entries == 1) {
-        $form['#first_tid'] = $term->tid;
-      }
-      // Keep a variable to make sure at least 2 root elements are displayed.
-      if ($term->parents[0] == 0) {
-        $root_entries++;
-      }
-      $current_page[$key] = $term;
-    } while ($term = next($tree));
-
-    // Because we didn't use a pager query, set the necessary pager variables.
-    $total_entries = $before_entries + $page_entries + $after_entries;
-    $pager_total_items[0] = $total_entries;
-    $pager_page_array[0] = $page;
-    $pager_total[0] = ceil($total_entries / $page_increment);
-  }
+    // Count entries before the current page.
+    if ($page && ($page * $page_increment) > $before_entries && !isset($back_peddle)) {
+      $before_entries++;
+      continue;
+    }
+    // Count entries after the current page.
+    elseif ($page_entries > $page_increment && isset($complete_tree)) {
+      $after_entries++;
+      continue;
+    }
+
+    // Do not let a term start the page that is not at the root.
+    if (isset($term->depth) && ($term->depth > 0) && !isset($back_peddle)) {
+      $back_peddle = 0;
+      while ($pterm = prev($tree)) {
+        $before_entries--;
+        $back_peddle++;
+        if ($pterm->depth == 0) {
+          prev($tree);
+          continue 2; // Jump back to the start of the root level parent.
+       }
+      }
+    }
+    $back_peddle = isset($back_peddle) ? $back_peddle : 0;
+
+    // Continue rendering the tree until we reach the a new root item.
+    if ($page_entries >= $page_increment + $back_peddle + 1 && $term->depth == 0 && $root_entries > 1) {
+      $complete_tree = TRUE;
+      // This new item at the root level is the first item on the next page.
+      $after_entries++;
+      continue;
+    }
+    if ($page_entries >= $page_increment + $back_peddle) {
+      $forward_peddle++;
+    }
+
+    // Finally, if we've gotten down this far, we're rendering a term on this page.
+    $page_entries++;
+    $term_deltas[$term->tid] = isset($term_deltas[$term->tid]) ? $term_deltas[$term->tid] + 1 : 0;
+    $key = 'tid:' . $term->tid . ':' . $term_deltas[$term->tid];
+
+    // Keep track of the first term displayed on this page.
+    if ($page_entries == 1) {
+      $form['#first_tid'] = $term->tid;
+    }
+    // Keep a variable to make sure at least 2 root elements are displayed.
+    if ($term->parents[0] == 0) {
+      $root_entries++;
+    }
+    $current_page[$key] = $term;
+  } while ($term = next($tree));
+
+  // Because we didn't use a pager query, set the necessary pager variables.
+  $total_entries = $before_entries + $page_entries + $after_entries;
+  $pager_total_items[0] = $total_entries;
+  $pager_page_array[0] = $page;
+  $pager_total[0] = ceil($total_entries / $page_increment);
 
   // If this form was already submitted once, it's probably hit a validation
   // error. Ensure the form is rebuilt in the same order as the user submitted.
@@ -420,7 +335,7 @@ function taxonomy_overview_terms(&$form_
     }
 
     $form[$key]['view'] = array('#markup' => l($term->name, "taxonomy/term/$term->tid"));
-    if (!$vocabulary->tags && $vocabulary->hierarchy < 2 && count($tree) > 1) {
+    if ($vocabulary->hierarchy < 2 && count($tree) > 1) {
       $form['#parent_fields'] = TRUE;
       $form[$key]['tid'] = array(
         '#type' => 'hidden',
@@ -447,7 +362,7 @@ function taxonomy_overview_terms(&$form_
   $form['#forward_peddle'] = $forward_peddle;
   $form['#empty_text'] = t('No terms available. <a href="@link">Add term</a>.', array('@link' => url('admin/structure/taxonomy/' . $vocabulary->vid . '/add')));
 
-  if (!$vocabulary->tags && $vocabulary->hierarchy < 2 && count($tree) > 1) {
+  if ($vocabulary->hierarchy < 2 && count($tree) > 1) {
     $form['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Save')
@@ -681,7 +596,6 @@ function taxonomy_form_term(&$form_state
   $form['#term'] = $edit;
   $form['#term']['parent'] = $parent;
   $form['#vocabulary'] = $vocabulary;
-  $form['#vocabulary']->nodes = drupal_map_assoc($vocabulary->nodes);
   $form['#builder_function'] = 'taxonomy_form_term_submit_builder';
 
   // Check for confirmation forms.
@@ -738,7 +652,7 @@ function taxonomy_form_term(&$form_state
     }
     $exclude[] = $edit['tid'];
 
-    $form['advanced']['parent'] = _taxonomy_term_select(t('Parents'), $parent, $vocabulary->vid, t('Parent terms') . '.', 1, '<' . t('root') . '>', $exclude);
+    $form['advanced']['parent'] = _taxonomy_term_select(t('Parents'), $parent, $vocabulary->vid, t('Parent terms') . '.', '<' . t('root') . '>', $exclude);
   }
   $form['advanced']['synonyms'] = array(
     '#type' => 'textarea',
@@ -805,7 +719,7 @@ function taxonomy_form_term_submit($form
     return;
   }
   // Rebuild the form to confirm enabling multiple parents.
-  elseif ($form_state['clicked_button']['#value'] == t('Save') && !$form['#vocabulary']->tags && count($form_state['values']['parent']) > 1 && $form['#vocabulary']->hierarchy < 2) {
+  elseif ($form_state['clicked_button']['#value'] == t('Save') && count($form_state['values']['parent']) > 1 && $form['#vocabulary']->hierarchy < 2) {
     $form_state['rebuild'] = TRUE;
     $form_state['confirm_parents'] = TRUE;
     return;
@@ -825,26 +739,24 @@ function taxonomy_form_term_submit($form
       break;
   }
 
-  if (!$form['#vocabulary']->tags) {
-    $current_parent_count = count($form_state['values']['parent']);
-    $previous_parent_count = count($form['#term']['parent']);
-    // Root doesn't count if it's the only parent.
-    if ($current_parent_count == 1 && isset($form_state['values']['parent'][0])) {
-      $current_parent_count = 0;
-      $form_state['values']['parent'] = array();
-    }
-
-    // If the number of parents has been reduced to one or none, do a check on the
-    // parents of every term in the vocabulary value.
-    if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) {
-      taxonomy_check_vocabulary_hierarchy($form['#vocabulary'], $form_state['values']);
-    }
-    // If we've increased the number of parents and this is a single or flat
-    // hierarchy, update the vocabulary immediately.
-    elseif ($current_parent_count > $previous_parent_count && $form['#vocabulary']->hierarchy < 2) {
-      $form['#vocabulary']->hierarchy = $current_parent_count == 1 ? 1 : 2;
-      taxonomy_vocabulary_save($form['#vocabulary']);
-    }
+  $current_parent_count = count($form_state['values']['parent']);
+  $previous_parent_count = count($form['#term']['parent']);
+  // Root doesn't count if it's the only parent.
+  if ($current_parent_count == 1 && isset($form_state['values']['parent'][0])) {
+    $current_parent_count = 0;
+    $form_state['values']['parent'] = array();
+  }
+
+  // If the number of parents has been reduced to one or none, do a check on the
+  // parents of every term in the vocabulary value.
+  if ($current_parent_count < $previous_parent_count && $current_parent_count < 2) {
+    taxonomy_check_vocabulary_hierarchy($form['#vocabulary'], $form_state['values']);
+  }
+  // If we've increased the number of parents and this is a single or flat
+  // hierarchy, update the vocabulary immediately.
+  elseif ($current_parent_count > $previous_parent_count && $form['#vocabulary']->hierarchy < 2) {
+    $form['#vocabulary']->hierarchy = $current_parent_count == 1 ? 1 : 2;
+    taxonomy_vocabulary_save($form['#vocabulary']);
   }
 
   $form_state['tid'] = $term->tid;
Index: modules/taxonomy/taxonomy.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.install,v
retrieving revision 1.21
diff -u -p -r1.21 taxonomy.install
--- modules/taxonomy/taxonomy.install	4 Aug 2009 06:50:07 -0000	1.21
+++ modules/taxonomy/taxonomy.install	20 Aug 2009 00:37:45 -0000
@@ -104,42 +104,6 @@ function taxonomy_schema() {
     'primary key' => array('tid', 'parent'),
   );
 
-  $schema['taxonomy_term_node'] = array(
-    'description' => 'Stores the relationship of terms to nodes.',
-    'fields' => array(
-      'nid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Primary Key: The {node}.nid of the node.',
-      ),
-      'vid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Primary Key: The {node}.vid of the node.',
-      ),
-      'tid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Primary Key: The {taxonomy_term_data}.tid of a term assigned to the node.',
-      ),
-    ),
-    'indexes' => array(
-      'vid' => array('vid'),
-      'nid' => array('nid'),
-    ),
-    'foreign keys' => array(
-      'nid' => array('node' => 'nid'),
-      'vid' => array('node' => 'vid'),
-      'tid' => array('taxonomy_term_data' => 'tid'),
-    ),
-    'primary key' => array('tid', 'vid'),
-  );
   $schema['taxonomy_term_synonym'] = array(
     'description' => 'Stores term synonyms.',
     'fields' => array(
@@ -202,13 +166,6 @@ function taxonomy_schema() {
         'size' => 'big',
         'description' => 'Description of the vocabulary.',
       ),
-      'help' => array(
-        'type' => 'varchar',
-        'length' => 255,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'Help text to display for the vocabulary.',
-      ),
       'relations' => array(
         'type' => 'int',
         'unsigned' => TRUE,
@@ -225,30 +182,6 @@ function taxonomy_schema() {
         'size' => 'tiny',
         'description' => 'The type of hierarchy allowed within the vocabulary. (0 = disabled, 1 = single, 2 = multiple)',
       ),
-      'multiple' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether or not multiple terms from this vocabulary may be assigned to a node. (0 = disabled, 1 = enabled)',
-      ),
-      'required' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether or not terms are required for nodes using this vocabulary. (0 = disabled, 1 = enabled)',
-      ),
-      'tags' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'size' => 'tiny',
-        'description' => 'Whether or not free tagging is enabled for the vocabulary. (0 = disabled, 1 = enabled)',
-      ),
       'module' => array(
         'type' => 'varchar',
         'length' => 255,
@@ -261,7 +194,7 @@ function taxonomy_schema() {
         'not null' => TRUE,
         'default' => 0,
         'size' => 'tiny',
-        'description' => 'The weight of the vocabulary in relation to other vocabularies.',
+        'description' => 'The weight of this vocabulary in relation to other vocabularies.',
       ),
     ),
     'primary key' => array('vid'),
@@ -270,33 +203,6 @@ function taxonomy_schema() {
     ),
   );
 
-  $schema['taxonomy_vocabulary_node_type'] = array(
-    'description' => 'Stores which node types vocabularies may be used with.',
-    'fields' => array(
-      'vid' => array(
-        'type' => 'int',
-        'unsigned' => TRUE,
-        'not null' => TRUE,
-        'default' => 0,
-        'description' => 'Primary Key: the {taxonomy_vocabulary}.vid of the vocabulary.',
-      ),
-      'type' => array(
-        'type' => 'varchar',
-        'length' => 32,
-        'not null' => TRUE,
-        'default' => '',
-        'description' => 'The {node}.type of the node type for which the vocabulary may be used.',
-      ),
-    ),
-    'primary key' => array('type', 'vid'),
-    'indexes' => array(
-      'vid' => array('vid'),
-    ),
-    'foreign keys' => array(
-      'vid' => array('taxonomy_vocabulary' => 'vid'),
-    ),
-  );
-
   return $schema;
 }
 
@@ -338,3 +244,79 @@ function taxonomy_update_7003() {
 
   return $ret;
 }
+
+/**
+ * Move taxonomy vocabulary associations for nodes to fields and field instances.
+ */
+function taxonomy_update_7005() {
+  $ret = array();
+  foreach (taxonomy_get_vocabularies() as $vocabulary) {
+    $field_name = 'taxonomy_vocabulary_' . $vocabulary->machine_name;
+    $field = array(
+      'field_name' => $field_name,
+      'type' => 'taxonomy_term',
+      'cardinality' => $vocabulary->multiple || $vocabulary->tags ? FIELD_CARDINALITY_UNLIMITED : 1,
+      'settings' => array(
+        'required' => $vocabulary->required ? TRUE : FALSE,
+        'allowed_values' => array(
+          array(
+            'vid' => $vocabulary->vid,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+    field_create_field($field);
+
+    foreach ($vocabulary->nodes as $bundle) {
+      $instance = array(
+        'label' => $vocabulary->name,
+        'field_name' => $field_name,
+        'bundle' => $bundle,
+        'description' => $vocabulary->help,
+        'widget' => array(
+          'type' => $vocabulary->tags ? 'taxonomy_autocomplete' : 'select',
+        ),
+      );
+      field_create_instance($instance);
+    }
+    // Migrate {term_node} data to the new field tables.
+    // Since we are upgrading from Drupal 6, we know that only
+    // field_sql_storage.module will be enabled.
+    $field = field_info_field($field['field_name']);
+    $data_table = _field_sql_storage_tablename($field);
+    $revision_table = _field_sql_storage_revision_tablename($field);
+    $etid = _field_sql_storage_etid('node');
+    $value_column = $field['field_name'] . '_value';
+    $columns = array('etid', 'entity_id', 'revision_id', 'bundle', 'delta', $value_column);
+
+    // Query and save data for the current revision.
+    $result = db_query('SELECT td.tid, tn.nid, td.weight, tn.vid FROM {taxonomy_term_data} td INNER JOIN {taxonomy_term_node} tn ON td.tid = tn.tid INNER JOIN {node} n WHERE tn.vid = n.vid AND td.vid = :vocabulary_id ORDER BY td.weight ASC', array(':vocabulary_id' => $vocabulary->vid));
+    $deltas = array();
+    foreach ($result as $record) {
+      // Start deltas from 0, and increment by one for each
+      //  term attached to a node.
+      $deltas[$record->nid] = isset($deltas[$record->nid]) ? ++$deltas[$record->nid] : 0;
+      $values = array($etid, $record->nid, $record->vid, $bundle, $deltas[$record->nid], $record->tid);
+      db_insert($data_table)->fields($columns)->values($values)->execute();
+    }
+
+    // Query and save data for all revisions.
+    $result = db_query('SELECT td.tid, tn.nid, td.weight, tn.vid FROM {taxonomy_term_data} td INNER JOIN {taxonomy_term_node} tn ON td.tid = tn.tid AND td.vid = :vocabulary_id ORDER BY td.weight ASC', array(':vocabulary_id' => $vocabulary->vid));
+    $deltas = array();
+    foreach ($result as $record) {
+      // Start deltas at 0, and increment by one for each term attached to a revision.
+      $deltas[$record->vid] = isset($deltas[$record->vid]) ? ++$deltas[$record->vid] : 0;
+      $values = array($etid, $record->nid, $record->vid, $bundle, $deltas[$record->vid], $record->tid);
+      db_insert($revision_table)->fields($columns)->values($values)->execute();
+    }
+  }
+
+  db_drop_table($ret, 'taxonomy_vocabulary_node_type');
+  $fields = array('help', 'multiple', 'required', 'tags');
+  foreach ($fields as $field) {
+    db_drop_field($ret, 'taxonomy_vocabulary', $field);
+  }
+
+  return $ret;
+}
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.497
diff -u -p -r1.497 taxonomy.module
--- modules/taxonomy/taxonomy.module	19 Aug 2009 13:31:13 -0000	1.497
+++ modules/taxonomy/taxonomy.module	20 Aug 2009 00:37:47 -0000
@@ -65,22 +65,53 @@ function taxonomy_field_build_modes($obj
 }
 
 /**
- * Implement hook_field_extra_fields().
+ * Return nodes attached to the default per-vocabulary fields.
+ *
+ * @param $term
+ *   The term object.
+ * @todo
+ *   Pager support.
+ * @todo
+ *   Order by node.created, node.sticky.
+ *
+ * @return
+ *   An array of nids matching the query.
  */
-function taxonomy_field_extra_fields($bundle) {
-  $extra = array();
-
-  if ($type = node_type_get_type($bundle)) {
-    if (taxonomy_get_vocabularies($bundle)) {
-      $extra['taxonomy'] = array(
-        'label' => t('Taxonomy'),
-        'description' => t('Taxonomy module element.'),
-        'weight' => -3,
-      );
+function taxonomy_select_nodes($term, $pager = FALSE, $order = array('n.sticky' => 'DESC', 'n.created' => 'DESC')) {
+  $field_info = field_info_field('taxonomy_vocabulary_' . $term->vocabulary_machine_name);
+  $conditions = array(array('value', $term->tid, '='), array('type', 'node', '='));
+  $result = reset(field_attach_query($field_info['id'], $conditions, FIELD_QUERY_NO_LIMIT));
+  $nids = $result ? array_keys($result) : $result;
+  if ($nids) {
+    $query = db_select('node', 'n');
+    $query->addTag('node_access');
+    $query->condition('n.status', 1);
+    if ($pager) {
+      $count_query = clone $query;
+      $count_query->addExpression('COUNT(n.nid)');
+
+      $query = $query
+        ->extend('PagerDefault')
+        ->limit(variable_get('default_nodes_main', 10));
+      $query->setCountQuery($count_query);
+    }
+    else {
+      $query->range(0, variable_get('feed_default_items', 10));
+    }
+    $query->condition('n.nid', $nids, 'IN');
+    $query->addField('n', 'nid');
+    foreach ($order as $field => $direction) {
+      $query->orderBy($field, $direction);
+      // ORDER BY fields need to be loaded too, assume they are in the form
+      // table_alias.name
+      list($table_alias, $name) = explode('.', $field);
+      $query->addField($table_alias, $name);
     }
+    return $query->execute()->fetchCol();
+  }
+  else {
+    return FALSE;
   }
-
-  return $extra;
 }
 
 /**
@@ -110,66 +141,6 @@ function taxonomy_theme() {
 }
 
 /**
- * Implement hook_node_view().
- */
-function taxonomy_node_view($node, $build_mode) {
-  if (empty($node->taxonomy)) {
-    return;
-  }
-
-  if ($build_mode == 'rss') {
-    // Provide category information for RSS feeds.
-    foreach ($node->taxonomy as $term) {
-      $node->rss_elements[] = array(
-        'key' => 'category',
-        'value' => $term->name,
-        'attributes' => array('domain' => url(taxonomy_term_path($term), array('absolute' => TRUE))),
-      );
-    }
-  }
-  else {
-    $links = array();
-
-    // If previewing, the terms must be converted to objects first.
-    if (!empty($node->in_preview)) {
-      $node->taxonomy = taxonomy_preview_terms($node);
-    }
-
-    foreach ($node->taxonomy as $term) {
-      // During preview the free tagging terms are in an array unlike the
-      // other terms which are objects. So we have to check if a $term
-      // is an object or not.
-      if (is_object($term)) {
-        $links['taxonomy_term_' . $term->tid] = array(
-          'title' => $term->name,
-          'href' => taxonomy_term_path($term),
-          'attributes' => array('rel' => 'tag', 'title' => strip_tags($term->description))
-        );
-      }
-      // Previewing free tagging terms; we don't link them because the
-      // term-page might not exist yet.
-      else {
-        foreach ($term as $free_typed) {
-          $typed_terms = drupal_explode_tags($free_typed);
-          foreach ($typed_terms as $typed_term) {
-            $links['taxonomy_preview_term_' . $typed_term] = array(
-              'title' => $typed_term,
-            );
-          }
-        }
-      }
-    }
-
-    $node->content['links']['terms'] = array(
-      '#theme' => 'links',
-      '#links' => $links,
-      '#attributes' => array('class' => 'links inline'),
-      '#sorted' => TRUE,
-    );
-  }
-}
-
-/**
  * For vocabularies not maintained by taxonomy.module, give the maintaining
  * module a chance to provide a path for terms in that vocabulary.
  *
@@ -250,13 +221,6 @@ function taxonomy_menu() {
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
   );
-  // TODO: remove with taxonomy_term_node_*
-  $items['taxonomy/autocomplete/legacy'] = array(
-    'title' => 'Autocomplete taxonomy',
-    'page callback' => 'taxonomy_autocomplete_legacy',
-    'access arguments' => array('access content'),
-    'type' => MENU_CALLBACK,
-  );
 
   $items['admin/structure/taxonomy/%taxonomy_vocabulary'] = array(
     'title' => 'Vocabulary', // this is replaced by callback
@@ -305,9 +269,6 @@ function taxonomy_admin_vocabulary_title
  * Save a vocabulary given a vocabulary object.
  */
 function taxonomy_vocabulary_save($vocabulary) {
-  if (empty($vocabulary->nodes)) {
-    $vocabulary->nodes = array();
-  }
 
   if (!empty($vocabulary->name)) {
     // Prevent leading and trailing spaces in vocabulary names.
@@ -320,38 +281,12 @@ function taxonomy_vocabulary_save($vocab
 
   if (!empty($vocabulary->vid) && !empty($vocabulary->name)) {
     $status = drupal_write_record('taxonomy_vocabulary', $vocabulary, 'vid');
-    db_delete('taxonomy_vocabulary_node_type')
-      ->condition('vid', $vocabulary->vid)
-      ->execute();
-
-    if (!empty($vocabulary->nodes)) {
-      $query = db_insert('taxonomy_vocabulary_node_type')
-        ->fields(array('vid', 'type'));
-      foreach ($vocabulary->nodes as $type => $selected) {
-        $query->values(array(
-          'vid' => $vocabulary->vid,
-          'type' => $type,
-        ));
-      }
-      $query->execute();
-    }
     module_invoke_all('taxonomy_vocabulary_update', $vocabulary);
   }
   elseif (empty($vocabulary->vid)) {
     $status = drupal_write_record('taxonomy_vocabulary', $vocabulary);
-
-    if (!empty($vocabulary->nodes)) {
-      $query = db_insert('taxonomy_vocabulary_node_type')
-        ->fields(array('vid', 'type'));
-      foreach ($vocabulary->nodes as $type => $selected) {
-        $query->values(array(
-          'vid' => $vocabulary->vid,
-          'type' => $type,
-        ));
-      }
-      $query->execute();
-    }
     field_attach_create_bundle($vocabulary->machine_name);
+    taxonomy_vocabulary_create_field($vocabulary);
     module_invoke_all('taxonomy_vocabulary_insert', $vocabulary);
   }
 
@@ -375,9 +310,6 @@ function taxonomy_vocabulary_delete($vid
   db_delete('taxonomy_vocabulary')
     ->condition('vid', $vid)
     ->execute();
-  db_delete('taxonomy_vocabulary_node_type')
-    ->condition('vid', $vid)
-    ->execute();
   $result = db_query('SELECT tid FROM {taxonomy_term_data} WHERE vid = :vid', array(':vid' => $vid))->fetchCol();
   foreach ($result as $tid) {
     taxonomy_term_delete($tid);
@@ -434,6 +366,31 @@ function taxonomy_check_vocabulary_hiera
 }
 
 /**
+ * Create a default field when a vocabulary is created.
+ *
+ * @param $vocabulary
+ *   A taxonomy vocabulary object.
+ */
+function taxonomy_vocabulary_create_field($vocabulary) {
+  $field = array(
+    'field_name' => 'taxonomy_vocabulary_' . $vocabulary->machine_name,
+    'type' => 'taxonomy_term',
+      // Set cardinality to unlimited so that select
+      // and autocomplete widgets behave as normal.
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'settings' => array(
+        'allowed_values' => array(
+          array(
+            'vid' => $vocabulary->vid,
+            'parent' => 0,
+          ),
+        ),
+      ),
+    );
+  field_create_field($field);
+}
+
+/**
  * Save a term object to the database.
  *
  * @param $term
@@ -472,6 +429,9 @@ function taxonomy_term_save($term) {
   if (!isset($term->parent) || empty($term->parent)) {
     $term->parent = array(0);
   }
+  if (!is_array($term->parent)) {
+    $term->parent = array($term->parent);
+  }
   $query = db_insert('taxonomy_term_hierarchy')
     ->fields(array('tid', 'parent'));
   if (is_array($term->parent)) {
@@ -492,12 +452,6 @@ function taxonomy_term_save($term) {
       }
     }
   }
-  else {
-    $query->values(array(
-     'tid' => $term->tid,
-     'parent' => $parent
-    ));
-  }
   $query->execute();
 
   db_delete('taxonomy_term_synonym')
@@ -558,9 +512,6 @@ function taxonomy_term_delete($tid) {
       db_delete('taxonomy_term_synonym')
         ->condition('tid', $tid)
         ->execute();
-      db_delete('taxonomy_term_node')
-        ->condition('tid', $tid)
-        ->execute();
 
       field_attach_delete('taxonomy_term', $term);
       _taxonomy_clean_field_cache($term);
@@ -608,26 +559,18 @@ function taxonomy_form($vid, $value = 0,
   $vocabulary = taxonomy_vocabulary_load($vid);
   $help = ($help) ? $help : filter_xss_admin($vocabulary->help);
 
-  if (!$vocabulary->multiple) {
-    $blank = ($vocabulary->required) ? t('- Please choose -') : t('- None selected -');
-  }
-  else {
-    $blank = ($vocabulary->required) ? 0 : t('- None -');
-  }
+  $blank = t('- Please choose -');
 
-  return _taxonomy_term_select(check_plain($vocabulary->name), $value, $vid, $help, intval($vocabulary->multiple), $blank);
+  return _taxonomy_term_select(check_plain($vocabulary->name), $value, $vid, $help, $blank);
 }
 
 /**
  * Generate a set of options for selecting a term from all vocabularies.
  */
-function taxonomy_form_all($free_tags = 0) {
+function taxonomy_form_all() {
   $vocabularies = taxonomy_get_vocabularies();
   $options = array();
   foreach ($vocabularies as $vid => $vocabulary) {
-    if ($vocabulary->tags && !$free_tags) {
-      continue;
-    }
     $tree = taxonomy_get_tree($vid);
     if ($tree && (count($tree) > 0)) {
       $options[$vocabulary->name] = array();
@@ -645,9 +588,8 @@ function taxonomy_form_all($free_tags = 
  * @param $type
  *   If set, return only those vocabularies associated with this node type.
  */
-function taxonomy_get_vocabularies($type = NULL) {
-  $conditions = !empty($type) ? array('type' => $type) : NULL;
-  return taxonomy_vocabulary_load_multiple(array(), $conditions);
+function taxonomy_get_vocabularies() {
+  return taxonomy_vocabulary_load_multiple(array(), array());
 }
 
 /**
@@ -666,331 +608,6 @@ function taxonomy_vocabulary_get_names()
 }
 
 /**
- * Implement hook_form_alter().
- * Generate a form for selecting terms to associate with a node.
- * We check for taxonomy_override_selector before loading the full
- * vocabulary, so contrib modules can intercept before hook_form_alter
- *  and provide scalable alternatives.
- */
-function taxonomy_form_alter(&$form, $form_state, $form_id) {
-  if (!variable_get('taxonomy_override_selector', FALSE) && !empty($form['#node_edit_form'])) {
-    $node = $form['#node'];
-
-    if (!isset($node->taxonomy)) {
-      $terms = empty($node->nid) ? array() : taxonomy_node_get_terms($node);
-    }
-    else {
-      // After preview the terms must be converted to objects.
-      if (isset($form_state['node_preview'])) {
-        $node->taxonomy = taxonomy_preview_terms($node);
-      }
-      $terms = $node->taxonomy;
-    }
-    $query = db_select('taxonomy_vocabulary', 'v');
-    $query->join('taxonomy_vocabulary_node_type', 'n', 'v.vid = n.vid');
-    $query->addTag('term_access');
-
-    $result = $query
-      ->fields('v')
-      ->condition('n.type', $node->type)
-      ->orderBy('v.weight')
-      ->orderBy('v.name')
-      ->execute();
-
-    foreach ($result as $vocabulary) {
-      if ($vocabulary->tags) {
-        if (isset($form_state['node_preview'])) {
-          // Typed string can be changed by the user before preview,
-          // so we just insert the tags directly as provided in the form.
-          $typed_string = $node->taxonomy['tags'][$vocabulary->vid];
-        }
-        else {
-          $typed_string = taxonomy_implode_tags($terms, $vocabulary->vid) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);
-        }
-        if ($vocabulary->help) {
-          $help = filter_xss_admin($vocabulary->help);
-        }
-        else {
-          $help = t('A comma-separated list of terms describing this content. Example: funny, bungee jumping, "Company, Inc."');
-        }
-        $form['taxonomy']['tags'][$vocabulary->vid] = array('#type' => 'textfield',
-          '#title' => $vocabulary->name,
-          '#description' => $help,
-          '#required' => $vocabulary->required,
-          '#default_value' => $typed_string,
-          '#autocomplete_path' => 'taxonomy/autocomplete/legacy/' . $vocabulary->vid,
-          '#weight' => $vocabulary->weight,
-          '#maxlength' => 1024,
-        );
-      }
-      else {
-        // Extract terms belonging to the vocabulary in question.
-        $default_terms = array();
-        foreach ($terms as $term) {
-          // Free tagging has no default terms and also no vid after preview.
-          if (isset($term->vid) && $term->vid == $vocabulary->vid) {
-            $default_terms[$term->tid] = $term;
-          }
-        }
-        $form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, array_keys($default_terms), filter_xss_admin($vocabulary->help));
-        $form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight;
-        $form['taxonomy'][$vocabulary->vid]['#required'] = $vocabulary->required;
-      }
-    }
-    if (!empty($form['taxonomy']) && is_array($form['taxonomy'])) {
-      if (count($form['taxonomy']) > 1) {
-        // Add fieldset only if form has more than 1 element.
-        $form['taxonomy'] += array(
-          '#type' => 'fieldset',
-          '#title' => t('Vocabularies'),
-          '#collapsible' => TRUE,
-          '#collapsed' => FALSE,
-        );
-      }
-      $form['taxonomy']['#weight'] = -3;
-      $form['taxonomy']['#tree'] = TRUE;
-    }
-  }
-}
-
-/**
- * Helper function to convert terms after a preview.
- *
- * After preview the tags are an array instead of proper objects. This function
- * converts them back to objects with the exception of 'free tagging' terms,
- * because new tags can be added by the user before preview and those do not
- * yet exist in the database. We therefore save those tags as a string so
- * we can fill the form again after the preview.
- */
-function taxonomy_preview_terms($node) {
-  $taxonomy = array();
-  if (isset($node->taxonomy)) {
-    foreach ($node->taxonomy as $key => $term) {
-      unset($node->taxonomy[$key]);
-      // A 'Multiple select' and a 'Free tagging' field returns an array.
-      if (is_array($term)) {
-        foreach ($term as $tid) {
-          if ($key == 'tags') {
-            // Free tagging; the values will be saved for later as strings
-            // instead of objects to fill the form again.
-            $taxonomy['tags'] = $term;
-          }
-          else {
-            $taxonomy[$tid] = taxonomy_term_load($tid);
-          }
-        }
-      }
-      // A 'Single select' field returns the term id.
-      elseif ($term) {
-        $taxonomy[$term] = taxonomy_term_load($term);
-      }
-    }
-  }
-  return $taxonomy;
-}
-
-/**
- * Find all terms associated with the given node, within one vocabulary.
- */
-function taxonomy_node_get_terms_by_vocabulary($node, $vid, $key = 'tid') {
-  $query = db_select('taxonomy_term_data', 't');
-  $query->join('taxonomy_term_node', 'r', 'r.tid = t.tid');
-  $query->addTag('term_access');
-
-  $result = $query
-    ->fields('t')
-    ->condition('t.vid', $vid)
-    ->condition('r.vid', $node->vid)
-    ->orderBy('weight')
-    ->execute();
-
-  $terms = array();
-  foreach ($result as $term) {
-    $terms[$term->$key] = $term;
-  }
-  return $terms;
-}
-
-/**
- * Find all term IDs associated with a set of nodes.
- *
- * @param $nodes
- *  An array of node objects.
- *
- * @return
- *  An array of term and node IDs ordered by vocabulary and term weight.
- */
-function taxonomy_get_tids_from_nodes($nodes) {
-  $node_vids = array();
-  foreach ($nodes as $node) {
-    $node_vids[] = $node->vid;
-  }
-  $query = db_select('taxonomy_term_node', 'r');
-  $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
-  $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
-  $query->addTag('term_access');
-
-  return $query
-    ->fields('r', array('tid', 'nid', 'vid'))
-    ->condition('r.vid', $node_vids, 'IN')
-    ->orderBy('v.weight')
-    ->orderBy('t.weight')
-    ->orderBy('t.name')
-    ->execute()
-    ->fetchAll();
-}
-
-/**
- * Find all terms associated with the given node, ordered by vocabulary and term weight.
- */
-function taxonomy_node_get_terms($node, $key = 'tid') {
-  $terms = &drupal_static(__FUNCTION__);
-
-  if (!isset($terms[$node->vid][$key])) {
-    $query = db_select('taxonomy_term_node', 'r');
-    $query->join('taxonomy_term_data', 't', 'r.tid = t.tid');
-    $query->join('taxonomy_vocabulary', 'v', 't.vid = v.vid');
-    $query->addTag('term_access');
-
-    $result = $query
-      ->fields('r', array('tid', 'nid', 'vid'))
-      ->condition('r.vid', $node->vid)
-      ->orderBy('v.weight')
-      ->orderBy('t.weight')
-      ->orderBy('t.name')
-      ->execute();
-    $terms[$node->vid][$key] = array();
-    foreach ($result as $term) {
-      $terms[$node->vid][$key][$term->$key] = $term;
-    }
-  }
-  return $terms[$node->vid][$key];
-}
-
-/**
- * Save term associations for a given node.
- */
-function taxonomy_node_save($node, $terms) {
-
-  taxonomy_node_delete_revision($node);
-
-  // Free tagging vocabularies do not send their tids in the form,
-  // so we'll detect them here and process them independently.
-  if (isset($terms['tags'])) {
-    $typed_input = $terms['tags'];
-    unset($terms['tags']);
-
-    foreach ($typed_input as $vid => $vid_value) {
-      $vocabulary = taxonomy_vocabulary_load($vid);
-      $typed_terms = drupal_explode_tags($vid_value);
-
-      $inserted = array();
-      foreach ($typed_terms as $typed_term) {
-        // See if the term exists in the chosen vocabulary
-        // and return the tid; otherwise, add a new record.
-        $possibilities = taxonomy_get_term_by_name($typed_term);
-        $typed_term_tid = NULL; // tid match, if any.
-        foreach ($possibilities as $possibility) {
-          if ($possibility->vid == $vid) {
-            $typed_term_tid = $possibility->tid;
-          }
-        }
-
-        if (!$typed_term_tid) {
-          $edit = array(
-            'vid' => $vid,
-            'name' => $typed_term,
-            'vocabulary_machine_name' => $vocabulary->machine_name,
-          );
-          $term = (object)$edit;
-          $status = taxonomy_term_save($term);
-          $typed_term_tid = $term->tid;
-        }
-
-        // Defend against duplicate, differently cased tags
-        if (!isset($inserted[$typed_term_tid])) {
-          db_insert('taxonomy_term_node')
-            ->fields(array(
-              'nid' => $node->nid,
-              'vid' => $node->vid,
-              'tid' => $typed_term_tid
-            ))
-            ->execute();
-          $inserted[$typed_term_tid] = TRUE;
-        }
-      }
-    }
-  }
-
-  if (is_array($terms) && !empty($terms)) {
-    $query = db_insert('taxonomy_term_node')
-      ->fields(array('nid', 'vid', 'tid'));
-
-    foreach ($terms as $term) {
-      if (is_array($term)) {
-        foreach ($term as $tid) {
-          if ($tid) {
-            $query->values(array(
-              'nid' => $node->nid,
-              'vid' => $node->vid,
-              'tid' => $tid,
-            ));
-          }
-        }
-      }
-      elseif (is_object($term)) {
-        $query->values(array(
-          'nid' => $node->nid,
-          'vid' => $node->vid,
-          'tid' => $term->tid,
-        ));
-      }
-      elseif ($term) {
-        $query->values(array(
-          'nid' => $node->nid,
-          'vid' => $node->vid,
-          'tid' => $term,
-        ));
-      }
-    }
-    $query->execute();
-  }
-}
-
-/**
- * Implement hook_node_type_insert().
- */
-function taxonomy_node_type_insert($info) {
-  drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implement hook_node_type_update().
- */
-function taxonomy_node_type_update($info) {
-  if (!empty($info->old_type) && $info->type != $info->old_type) {
-    db_update('taxonomy_vocabulary_node_type')
-      ->fields(array(
-        'type' => $info->type,
-      ))
-      ->condition('type', $info->old_type)
-      ->execute();
-  }
-  drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implement hook_node_type_delete().
- */
-function taxonomy_node_type_delete($info) {
-  db_delete('taxonomy_vocabulary_node_type')
-    ->condition('type', $info->type)
-    ->execute();
-
-  drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
  * Find all parents of a given term ID.
  */
 function taxonomy_get_parents($tid, $key = 'tid') {
@@ -1157,51 +774,6 @@ function taxonomy_get_synonym_root($syno
 }
 
 /**
- * Count the number of published nodes classified by a term.
- *
- * @param $tid
- *   The term ID
- * @param $type
- *   (Optional) The $node->type. If given, taxonomy_term_count_nodes only counts
- *   nodes of $type that are classified with the term $tid.
- *
- * @return
- *   An integer representing a number of nodes.
- *   Results are statically cached.
- */
-function taxonomy_term_count_nodes($tid, $type = NULL) {
-  $count = &drupal_static(__FUNCTION__, array());
-  // Reset the taxonomy tree when first called (or if reset).
-  if (empty($count)) {
-    drupal_static_reset('taxonomy_get_tree');
-  }
-  // If $type is NULL, change it to 0 to allow it to be used as an array key
-  // for the static cache.
-  $type = empty($type) ? 0 : $type;
-
-  if (!isset($count[$type][$tid])) {
-    $term = taxonomy_term_load($tid);
-    $tree = taxonomy_get_tree($term->vid, $tid, NULL);
-    $tids = array($tid);
-    foreach ($tree as $descendent) {
-      $tids[] = $descendent->tid;
-    }
-
-    $query = db_select('taxonomy_term_node', 't');
-    $query->addExpression('COUNT(DISTINCT(n.nid))', 'nid_count');
-    $query->join('node', 'n', 't.vid = n.vid');
-    $query->condition('t.tid', $tids, 'IN');
-    $query->condition('n.status', 1);
-    if (!is_numeric($type)) {
-      $query->condition('n.type', $type);
-    }
-    $query->addTag('term_access');
-    $count[$type][$tid] = $query->execute()->fetchField();
-  }
-  return $count[$type][$tid];
-}
-
-/**
  * Try to map a string to an existing term, as for glossary use.
  *
  * Provides a case-insensitive and trimmed mapping, to maximize the
@@ -1234,13 +806,6 @@ function taxonomy_get_term_by_name($name
  */
 function taxonomy_vocabulary_load_multiple($vids = array(), $conditions = array()) {
   $vocabulary_cache = &drupal_static(__FUNCTION__, array());
-  // Node type associations are not stored in the vocabulary table, so remove
-  // this from conditions into it's own variable.
-  if (isset($conditions['type'])) {
-    $type = $conditions['type'];
-    unset($conditions['type']);
-  }
-
   $vocabularies = array();
 
   // Create a new variable which is either a prepared version of the $vids
@@ -1265,15 +830,12 @@ function taxonomy_vocabulary_load_multip
   }
 
   // Remove any loaded terms from the array if they don't match $conditions.
-  if ($conditions || isset($type)) {
+  if ($conditions) {
     foreach ($vocabularies as $vocabulary) {
       $vocabulary_values = (array) $vocabulary;
       if (array_diff_assoc($conditions, $vocabulary_values)) {
         unset($vocabularies[$vocabulary->vid]);
       }
-      if (isset($type) && !in_array($type, $vocabulary->nodes)) {
-        unset($vocabularies[$vocabulary->vid]);
-      }
     }
   }
 
@@ -1281,20 +843,12 @@ function taxonomy_vocabulary_load_multip
   // we have $vids still to load, or if no $vids were passed.
   if ($vids || !$passed_vids) {
     $query = db_select('taxonomy_vocabulary', 'v');
-    $query->addField('n', 'type');
     $query
       ->fields('v')
       ->orderBy('v.weight')
       ->orderBy('v.name')
       ->addTag('vocabulary_access');
 
-    if (!empty($type)) {
-      $query->join('taxonomy_vocabulary_node_type', 'n', 'v.vid = n.vid AND n.type = :type', array(':type' => $type));
-    }
-    else {
-      $query->leftJoin('taxonomy_vocabulary_node_type', 'n', 'v.vid = n.vid');
-    }
-
     // If the $vids array is populated, add those to the query.
     if ($vids) {
       $query->condition('v.vid', $vids, 'IN');
@@ -1309,18 +863,7 @@ function taxonomy_vocabulary_load_multip
     $result = $query->execute();
 
     $queried_vocabularies = array();
-    $node_types = array();
     foreach ($result as $record) {
-      // If no node types are associated with a vocabulary, the LEFT JOIN will
-      // return a NULL value for type.
-      if (isset($record->type)) {
-        $node_types[$record->vid][$record->type] = $record->type;
-        unset($record->type);
-        $record->nodes = $node_types[$record->vid];
-      }
-      elseif (!isset($record->nodes)) {
-        $record->nodes = array();
-      }
       $queried_vocabularies[$record->vid] = $record;
     }
 
@@ -1382,13 +925,6 @@ function taxonomy_vocabulary_load($vid) 
 function taxonomy_term_load_multiple($tids = array(), $conditions = array()) {
   $term_cache = &drupal_static(__FUNCTION__, array());
 
-  // Node type associations are not stored in the taxonomy_term_data table, so
-  // remove this from conditions into it's own variable.
-  if (isset($conditions['type'])) {
-    $type = $conditions['type'];
-    unset($conditions['type']);
-  }
-
   $terms = array();
 
   // Create a new variable which is either a prepared version of the $tids
@@ -1444,10 +980,6 @@ function taxonomy_term_load_multiple($ti
       $query->condition('t.tid', $tids, 'IN');
     }
 
-    if (!empty($type)) {
-      $query->join('taxonomy_vocabulary_node_type', 'n', 't.vid = n.vid AND n.type = :type', array(':type' => $type));
-    }
-
     // If the conditions array is populated, add those to the query.
     if ($conditions) {
       // When name is passed as a condition use LIKE.
@@ -1535,7 +1067,7 @@ function taxonomy_term_load($tid) {
  * @see taxonomy_form()
  * @see taxonomy_form_term()
  */
-function _taxonomy_term_select($title, $value, $vocabulary_id, $description, $multiple, $blank, $exclude = array()) {
+function _taxonomy_term_select($title, $value, $vocabulary_id, $description, $blank, $exclude = array()) {
   $tree = taxonomy_get_tree($vocabulary_id);
   $options = array();
 
@@ -1557,8 +1089,6 @@ function _taxonomy_term_select($title, $
     '#default_value' => $value,
     '#options' => $options,
     '#description' => $description,
-    '#multiple' => $multiple,
-    '#size' => $multiple ? min(9, count($options)) : 0,
     '#weight' => -15,
     '#theme' => 'taxonomy_term_select',
   );
@@ -1575,186 +1105,6 @@ function theme_taxonomy_term_select($ele
 }
 
 /**
- * Finds all nodes that match selected taxonomy conditions.
- *
- * @param $tids
- *   An array of term IDs to match.
- * @param $operator
- *   How to interpret multiple IDs in the array. Can be "or" or "and".
- * @param $depth
- *   How many levels deep to traverse the taxonomy tree. Can be a non-negative
- *   integer or "all".
- * @param $pager
- *   Whether the nodes are to be used with a pager (the case on most Drupal
- *   pages) or not (in an XML feed, for example).
- * @param $order
- *   The order clause for the query that retrieve the nodes.
- *   It is important to specifc the table alias (n).
- *
- *   Example:
- *   array('table_alias.field_name' = 'DESC');
- * @return
- *   An array of node IDs.
- */
-function taxonomy_select_nodes($tids = array(), $operator = 'or', $depth = 0, $pager = TRUE, $order = array('n.sticky' => 'DESC', 'n.created' =>  'DESC')) {
-  if (count($tids) <= 0) {
-    return array();
-  }
-  // For each term ID, generate an array of descendant term IDs to the right depth.
-  $descendant_tids = array();
-  if ($depth === 'all') {
-    $depth = NULL;
-  }
-  $terms = taxonomy_term_load_multiple($tids);
-  foreach ($terms as $term) {
-    $tree = taxonomy_get_tree($term->vid, $term->tid, $depth);
-    $descendant_tids[] = array_merge(array($term->tid), array_map('_taxonomy_get_tid_from_term', $tree));
-  }
-
-  $query = db_select('node', 'n');
-  $query->addTag('node_access');
-  $query->condition('n.status', 1);
-
-  if ($operator == 'or') {
-      $args = call_user_func_array('array_merge', $descendant_tids);
-      $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid');
-      $query->condition('tn.tid', $args, 'IN');
-  }
-  else {
-    foreach ($descendant_tids as $tids) {
-      $alias = $query->join('taxonomy_term_node', 'tn', 'n.vid = tn.vid');
-      $query->condition($alias . '.tid', $tids, 'IN');
-    }
-  }
-
-  if ($pager) {
-    $count_query = clone $query;
-    $count_query->addExpression('COUNT(DISTINCT n.nid)');
-
-    $query = $query
-      ->extend('PagerDefault')
-      ->limit(variable_get('default_nodes_main', 10));
-    $query->setCountQuery($count_query);
-  }
-  else {
-    $query->range(0, variable_get('feed_default_items', 10));
-  }
-
-  $query->distinct(TRUE);
-  $query->addField('n', 'nid');
-  foreach ($order as $field => $direction) {
-    $query->orderBy($field, $direction);
-    // ORDER BY fields need to be loaded too, assume they are in the form table_alias.name
-    list($table_alias, $name) = explode('.', $field);
-    $query->addField($table_alias, $name);
-  }
-
-  return $query->execute()->fetchCol();
-}
-
-/**
- * Implement hook_node_load().
- */
-function taxonomy_node_load($nodes) {
-  // Get an array of tid, vid associations ordered by vocabulary and term
-  // weight.
-  $tids = taxonomy_get_tids_from_nodes($nodes);
-
-  // Extract the tids only from this array.
-  $term_ids = array();
-  foreach ($tids as $term) {
-    $term_ids[$term->tid] = $term->tid;
-  }
-
-  // Load the full term objects for these tids.
-  $terms = taxonomy_term_load_multiple($term_ids);
-  foreach ($tids as $term) {
-    $nodes[$term->nid]->taxonomy[$term->tid] = $terms[$term->tid];
-  }
-  foreach ($nodes as $node) {
-    if (!isset($nodes[$node->nid]->taxonomy)) {
-      $node->taxonomy = array();
-    }
-  }
-}
-
-/**
- * Implement hook_node_insert().
- */
-function taxonomy_node_insert($node) {
-  if (!empty($node->taxonomy)) {
-    taxonomy_node_save($node, $node->taxonomy);
-  }
-}
-
-/**
- * Implement hook_node_update().
- */
-function taxonomy_node_update($node) {
-  if (!empty($node->taxonomy)) {
-    taxonomy_node_save($node, $node->taxonomy);
-  }
-}
-
-/**
- * Implement hook_node_delete().
- *
- * Remove associations of a node to its terms.
- */
-function taxonomy_node_delete($node) {
-  db_delete('taxonomy_term_node')
-    ->condition('nid', $node->nid)
-    ->execute();
-  drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implement hook_node_delete_revision().
- *
- * Remove associations of a node to its terms.
- */
-function taxonomy_node_delete_revision($node) {
-  db_delete('taxonomy_term_node')
-    ->condition('vid', $node->vid)
-    ->execute();
-  drupal_static_reset('taxonomy_term_count_nodes');
-}
-
-/**
- * Implement hook_node_validate().
- *
- * Make sure incoming vids are free tagging enabled.
- */
-function taxonomy_node_validate($node, $form) {
-  if (!empty($node->taxonomy)) {
-    $terms = $node->taxonomy;
-    if (!empty($terms['tags'])) {
-      foreach ($terms['tags'] as $vid => $vid_value) {
-        $vocabulary = taxonomy_vocabulary_load($vid);
-        if (empty($vocabulary->tags)) {
-          // see form_get_error $key = implode('][', $element['#parents']);
-          // on why this is the key
-          form_set_error("taxonomy][tags][$vid", t('The %name vocabulary can not be modified in this way.', array('%name' => $vocabulary->name)));
-        }
-      }
-    }
-  }
-}
-
-/**
- * Implement hook_node_update_index().
- */
-function taxonomy_node_update_index($node) {
-  $output = array();
-  foreach ($node->taxonomy as $term) {
-    $output[] = $term->name;
-  }
-  if (count($output)) {
-    return '<strong>(' . implode(', ', $output) . ')</strong>';
-  }
-}
-
-/**
  * Implement hook_help().
  */
 function taxonomy_help($path, $arg) {
@@ -1775,9 +1125,6 @@ function taxonomy_help($path, $arg) {
       return $output;
     case 'admin/structure/taxonomy/%/list':
       $vocabulary = taxonomy_vocabulary_load($arg[3]);
-      if ($vocabulary->tags) {
-        return '<p>' . t('%capital_name is a free-tagging vocabulary. To change the name or description of a term, click the <em>edit</em> link next to the term.', array('%capital_name' => drupal_ucfirst($vocabulary->name))) . '</p>';
-      }
       switch ($vocabulary->hierarchy) {
         case 0:
           return '<p>' . t('%capital_name is a flat vocabulary. You may organize the terms in the %name vocabulary by using the handles on the left side of the table. To change the name or description of a term, click the <em>edit</em> link next to the term.', array('%capital_name' => drupal_ucfirst($vocabulary->name), '%name' => $vocabulary->name)) . '</p>';
Index: modules/taxonomy/taxonomy.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.pages.inc,v
retrieving revision 1.32
diff -u -p -r1.32 taxonomy.pages.inc
--- modules/taxonomy/taxonomy.pages.inc	18 Aug 2009 06:01:07 -0000	1.32
+++ modules/taxonomy/taxonomy.pages.inc	20 Aug 2009 00:37:47 -0000
@@ -40,8 +40,7 @@ function taxonomy_term_page($term) {
       '#suffix' => '</div>',
     );
   }
-
-  if ($nids = taxonomy_select_nodes(array($term->tid), NULL, TRUE)) {
+  if ($nids = taxonomy_select_nodes($term)) {
     $nodes = node_load_multiple($nids);
     $build += node_build_multiple($nodes);
     $build['pager'] = array(
@@ -71,7 +70,7 @@ function taxonomy_term_feed($term) {
   // Only display the description if we have a single term, to avoid clutter and confusion.
   // HTML will be removed from feed description, so no need to filter here.
   $channel['description'] = $term->description;
-  $nids = taxonomy_select_nodes(array($term->tid, NULL, NULL, FALSE));
+  $nids = taxonomy_select_nodes(array($term->tid, FALSE));
 
   node_feed($nids, $channel);
 }
@@ -90,56 +89,6 @@ function taxonomy_term_edit($term) {
 /**
  * Helper function for autocompletion
  */
-function taxonomy_autocomplete_legacy($vid = 0, $tags_typed = '') {
-  // The user enters a comma-separated list of tags. We only autocomplete the last tag.
-  $tags_typed = drupal_explode_tags($tags_typed);
-  $tag_last = drupal_strtolower(array_pop($tags_typed));
-
-  $matches = array();
-  if ($tag_last != '') {
-    $query = db_select('taxonomy_term_data', 't');
-    $query->addTag('term_access');
-    $query->leftJoin('taxonomy_term_synonym', 'ts', 't.tid = ts.tid');
-    // Don't select already entered terms.
-    if (count($tags_typed)) {
-      $query->condition('t.name', $tags_typed, 'NOT IN');
-    }
-    $tags_return = $query
-      ->fields('t', array('tid', 'name'))
-      ->condition('t.vid', $vid)
-      // Select rows that either match by term or synonym name.
-      ->condition(db_or()
-	    ->where("LOWER(t.name) LIKE :last_string", array(':last_string' => '%' . $tag_last . '%'))
-	    ->where("LOWER(ts.name) LIKE :last_string", array(':last_string' => '%' . $tag_last . '%'))
-      )
-      ->range(0, 10)
-      ->execute()
-      ->fetchAllKeyed();
-
-    $prefix = count($tags_typed) ? implode(', ', $tags_typed) . ', ' : '';
-
-    // We use two arrays to make sure synonym suggestions appear last.
-    $term_matches = $synonym_matches = array();
-    foreach ($tags_return as $tid => $name) {
-      $n = $name;
-      // Commas and quotes in terms are special cases, so encode 'em.
-      if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
-        $n = '"' . str_replace('"', '""', $name) . '"';
-      }
-      // Inform the user his query matched a synonym rather than a term.
-      if (strpos(drupal_strtolower($name), $tag_last) === FALSE) {
-        $name = t('Did you mean %suggestion', array('%suggestion' => $name));
-        $synonym_matches[$prefix . $n] = filter_xss($name);
-      }
-    }
-  }
-
-  drupal_json(array_merge($term_matches, $synonym_matches));
-}
-
-/**
- * Helper function for autocompletion
- */
 function taxonomy_autocomplete($field_name, $bundle, $tags_typed = '') {
   $instance = field_info_instance($field_name, $bundle);
   $field = field_info_field($field_name);
Index: modules/taxonomy/taxonomy.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.test,v
retrieving revision 1.43
diff -u -p -r1.43 taxonomy.test
--- modules/taxonomy/taxonomy.test	4 Aug 2009 06:50:07 -0000	1.43
+++ modules/taxonomy/taxonomy.test	20 Aug 2009 00:37:47 -0000
@@ -19,7 +19,8 @@ class TaxonomyWebTestCase extends Drupal
     $vocabulary = new stdClass();
     $vocabulary->name = $this->randomName();
     $vocabulary->description = $this->randomName();
-    $vocabulary->machine_name = drupal_strtolower($this->randomName());
+    // Field names are limited to 32 characters.
+    $vocabulary->machine_name = drupal_substr(drupal_strtolower($this->randomName()), 3, 9);
     $vocabulary->help = '';
     $vocabulary->nodes = array('article' => 'article');
     $vocabulary->weight = mt_rand(0, 10);
@@ -69,15 +70,10 @@ class TaxonomyVocabularyFunctionalTest e
     // Create a new vocabulary.
     $this->clickLink(t('Add vocabulary'));
     $edit = array();
-    $machine_name = drupal_strtolower($this->randomName());
+    $machine_name = drupal_strtolower(drupal_substr($this->randomName(), 3, 9));
     $edit['name'] = $this->randomName();
     $edit['description'] = $this->randomName();
     $edit['machine_name'] = $machine_name;
-    $edit['help'] = $this->randomName();
-    $edit['nodes[article]'] = 'article';
-    $edit['tags'] = 1;
-    $edit['multiple'] = 1;
-    $edit['required'] = 1;
     $this->drupalPost(NULL, $edit, t('Save'));
     $this->assertRaw(t('Created new vocabulary %name.', array('%name' => $edit['name'])), t('Vocabulary created successfully'));
 
@@ -153,8 +149,7 @@ class TaxonomyVocabularyFunctionalTest e
     // Create a vocabulary.
     $edit = array(
       'name' => $this->randomName(),
-      'machine_name' => drupal_strtolower($this->randomName()),
-      'nodes[article]' => 'article',
+      'machine_name' => drupal_strtolower(drupal_substr($this->randomName(), 3, 9)),
     );
     $this->drupalPost('admin/structure/taxonomy/add', $edit, t('Save'));
     $this->assertText(t('Created new vocabulary'), t('New vocabulary was created.'));
@@ -277,100 +272,22 @@ class TaxonomyVocabularyUnitTest extends
     // Fetch all of the vocabularies using taxonomy_get_vocabularies().
     // Confirm that the vocabularies are ordered by weight.
     $vocabularies = taxonomy_get_vocabularies();
-    $this->assertEqual(array_shift($vocabularies), $vocabulary1, t('Vocabulary was found in the vocabularies array.'));
-    $this->assertEqual(array_shift($vocabularies), $vocabulary2, t('Vocabulary was found in the vocabularies array.'));
-    $this->assertEqual(array_shift($vocabularies), $vocabulary3, t('Vocabulary was found in the vocabularies array.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, t('Vocabulary was found in the vocabularies array.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, t('Vocabulary was found in the vocabularies array.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, t('Vocabulary was found in the vocabularies array.'));
 
     // Fetch the vocabularies with taxonomy_vocabulary_load_multiple(), specifying IDs.
     // Ensure they are returned in the same order as the original array.
     $vocabularies = taxonomy_vocabulary_load_multiple(array($vocabulary3->vid, $vocabulary2->vid, $vocabulary1->vid));
-    $this->assertEqual(array_shift($vocabularies), $vocabulary3, t('Vocabulary loaded successfully by ID.'));
-    $this->assertEqual(array_shift($vocabularies), $vocabulary2, t('Vocabulary loaded successfully by ID.'));
-    $this->assertEqual(array_shift($vocabularies), $vocabulary1, t('Vocabulary loaded successfully by ID.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary3->vid, t('Vocabulary loaded successfully by ID.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary2->vid, t('Vocabulary loaded successfully by ID.'));
+    $this->assertEqual(array_shift($vocabularies)->vid, $vocabulary1->vid, t('Vocabulary loaded successfully by ID.'));
 
     // Fetch vocabulary 1 by name.
-    $this->assertTrue(current(taxonomy_vocabulary_load_multiple(array(), array('name' => $vocabulary1->name))) == $vocabulary1, t('Vocabulary loaded successfully by name.'));
+    $this->assertTrue(current(taxonomy_vocabulary_load_multiple(array(), array('name' => $vocabulary1->name)))->vid == $vocabulary1->vid, t('Vocabulary loaded successfully by name.'));
 
     // Fetch vocabulary 1 by name and ID.
-    $this->assertTrue(current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('name' => $vocabulary1->name))) == $vocabulary1, t('Vocabulary loaded successfully by name and ID.'));
-
-    // Fetch vocabulary 1 with specified node type.
-    drupal_static_reset('taxonomy_vocabulary_load_multiple');
-    $vocabulary_node_type = current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('type' => 'article')));
-    $this->assertEqual($vocabulary_node_type, $vocabulary1, t('Vocabulary with specified node type loaded successfully.'));
-  }
-}
-
-/**
- * Unit tests for taxonomy term functions.
- */
-class TaxonomyTermUnitTest extends TaxonomyWebTestCase {
-
-  public static function getInfo() {
-    return array(
-      'name' => 'Taxonomy term unit tests',
-      'description' => 'Unit tests for taxonomy term functions.',
-      'group' => 'Taxonomy',
-    );
-  }
-
-  /**
-   * Tests for taxonomy_term_count_nodes().
-   *
-   * Attach nodes to a hierarchical vocabulary and check they are counted
-   * correctly.
-   */
-  function testTaxonomyTermCountNodes() {
-    // Create a vocabulary with three terms.
-    $vocabulary = $this->createVocabulary();
-    $term1 = $this->createTerm($vocabulary);
-    $term2 = $this->createTerm($vocabulary);
-    $term3 = $this->createTerm($vocabulary);
-
-    // Attach term1 to a node.
-    $node1 = $this->drupalCreateNode(array('type' => 'page'));
-    $node1->taxonomy = array($term1->tid);
-    node_save($node1);
-    $this->assertEqual(taxonomy_term_count_nodes($term1->tid), 1, t('Term has one valid node association.'));
-
-    // Attach term2 to a node.
-    $node2 = $this->drupalCreateNode(array('type' => 'article'));
-    $node2->taxonomy = array($term2->tid);
-    node_save($node2);
-    $this->assertEqual(taxonomy_term_count_nodes($term2->tid), 1, t('Term has one valid node association.'));
-
-    // Confirm that term3 is not associated with any nodes.
-    $this->assertEqual(taxonomy_term_count_nodes($term3->tid), 0, t('Term is not associated with any nodes'));
-
-    // Set term3 as the parent of term1.
-    $term1->parent = array($term3->tid);
-    taxonomy_term_save($term1);
-
-    // Confirm that the term hierarchy is altered correctly.
-    $children = taxonomy_get_children($term3->tid);
-    $this->assertTrue(isset($children[$term1->tid]), t('Term 3 saved as parent of term 1'));
-
-    $this->assertEqual(count(taxonomy_get_tree($term3->vid, $term3->tid)), 1, t('Term 3 has one child term'));
-
-    // Confirm that term3's parental relationship with term1 leads to a
-    // node assocation being counted.
-    $this->assertEqual(taxonomy_term_count_nodes($term3->tid, NULL), 1, t('Term has one valid node association due to child term.'));
-
-    // Set term3 as the parent of term2.
-    $term2->parent = array($term3->tid);
-    taxonomy_term_save($term2);
-
-    // term3 should now have two node associations counted.
-    $this->assertEqual(taxonomy_term_count_nodes($term3->tid, NULL), 2, t('Term has two valid node associations due to child terms.'));
-
-    // Save node1 with both child taxonomy terms, this should still result
-    // in term3 having two node associations.
-    $node1->taxonomy = array($term1->tid, $term2->tid);
-    node_save($node1);
-    $this->assertEqual(taxonomy_term_count_nodes($term3->tid, NULL), 2, t('Term has two valid node associations.'));
-
-    // Confirm that the node type argument returns a single node association.
-    $this->assertEqual(taxonomy_term_count_nodes($term3->tid, 'page'), 1, t("Term is associated with one node of type 'page'."));
+    $this->assertTrue(current(taxonomy_vocabulary_load_multiple(array($vocabulary1->vid), array('name' => $vocabulary1->name)))->vid == $vocabulary1->vid, t('Vocabulary loaded successfully by name and ID.'));
   }
 }
 
@@ -392,6 +309,20 @@ class TaxonomyTermTestCase extends Taxon
     $this->admin_user = $this->drupalCreateUser(array('administer taxonomy', 'bypass node access'));
     $this->drupalLogin($this->admin_user);
     $this->vocabulary = $this->createVocabulary();
+
+    $this->instance = array(
+      'field_name' => 'taxonomy_vocabulary_' . $this->vocabulary->machine_name,
+      'bundle' => 'article',
+      'widget' => array(
+        'type' => 'options_select',
+      ),
+      'display' => array(
+        'full' => array(
+          'type' => 'taxonomy_term_link',
+        ),
+      ),
+    );
+    field_create_instance($this->instance);
   }
 
   /**
@@ -423,7 +354,7 @@ class TaxonomyTermTestCase extends Taxon
 
     // Edit $term2, setting $term1 as parent.
     $edit = array();
-    $edit['parent[]'] = $term1->tid;
+    $edit["parent"] = $term1->tid;
     $this->drupalPost('taxonomy/term/' . $term2->tid . '/edit', $edit, t('Save'));
 
     // Check the hierarchy.
@@ -454,7 +385,8 @@ class TaxonomyTermTestCase extends Taxon
     $edit = array();
     $edit['title'] = $this->randomName();
     $edit['body[0][value]'] = $this->randomName();
-    $edit['taxonomy[' . $this->vocabulary->vid . ']'] = $term1->tid;
+    $this->drupalGet('node/add/article');
+    $edit[$this->instance['field_name'] . '[value][]'] = array($term1->tid);
     $this->drupalPost('node/add/article', $edit, t('Save'));
 
     // Check that the term is displayed when the node is viewed.
@@ -463,19 +395,11 @@ class TaxonomyTermTestCase extends Taxon
     $this->assertText($term1->name, t('Term is displayed when viewing the node.'));
 
     // Edit the node with a different term.
-    $edit['taxonomy[' . $this->vocabulary->vid . ']'] = $term2->tid;
+    $edit[$this->instance['field_name'] . '[value][]'] = array($term2->tid);
     $this->drupalPost('node/' . $node->nid . '/edit', $edit, t('Save'));
 
     $this->drupalGet('node/' . $node->nid);
     $this->assertText($term2->name, t('Term is displayed when viewing the node.'));
-
-    // Delete node through browser.
-    $this->drupalPost('node/' . $node->nid . '/delete', array(), t('Delete'));
-    $this->drupalGet('node/' . $node->nid);
-    $this->assertNoText($term2->name, t('Checking if node exists'));
-    // Checking database fields.
-    $result = db_query('SELECT * FROM {taxonomy_term_node} WHERE nid = :nid', array(':nid' => $node->nid))->fetch();
-    $this->assertTrue(empty($result), t('Term/node relationships are no longer in the database table.'));
   }
 
   /**
@@ -483,8 +407,10 @@ class TaxonomyTermTestCase extends Taxon
    */
   function testNodeTermCreation() {
     // Enable tags in the vocabulary.
-    $this->vocabulary->tags = 1;
-    taxonomy_vocabulary_save($this->vocabulary);
+    $instance = $this->instance;
+    $instance['widget'] = array('type' => 'taxonomy_autocomplete');
+    $instance['bundle'] = 'page';
+    field_create_instance($instance);
     $terms = array(
       $this->randomName(),
       $this->randomName(),
@@ -492,12 +418,13 @@ class TaxonomyTermTestCase extends Taxon
     );
     $edit = array();
     $edit['title'] = $this->randomName();
+
     // Insert the terms in a comma separated list. Vocabulary 1 is a
     // free-tagging field created by the default profile.
-    $edit['taxonomy[tags][' . $this->vocabulary->vid . ']'] =  implode(', ', $terms);
+    $edit[$this->instance['field_name'] . '[value]'] =  implode(', ', $terms);
     $edit['body[0][value]'] = $this->randomName();
-    $this->drupalPost('node/add/article', $edit, t('Save'));
-    $this->assertRaw(t('@type %title has been created.', array('@type' => t('Article'), '%title' => $edit['title'])), t('The node was created successfully'));
+    $this->drupalPost('node/add/page', $edit, t('Save'));
+    $this->assertRaw(t('@type %title has been created.', array('@type' => t('Page'), '%title' => $edit['title'])), t('The node was created successfully'));
     foreach ($terms as $term) {
       $this->assertText($term, t('The term was saved and appears on the node page'));
     }
@@ -513,7 +440,7 @@ class TaxonomyTermTestCase extends Taxon
     );
     // Explicitly set the parents field to 'root', to ensure that
     // taxonomy_form_term_submit() handles the invalid term ID correctly.
-    $edit['parent[]'] = 0;
+    $edit['parent'] = 0;
 
     // Create the term to edit.
     $this->drupalPost('admin/structure/taxonomy/' . $this->vocabulary->vid . '/add', $edit, t('Save'));
Index: profiles/default/default.profile
===================================================================
RCS file: /cvs/drupal/drupal/profiles/default/default.profile,v
retrieving revision 1.62
diff -u -p -r1.62 default.profile
--- profiles/default/default.profile	3 Aug 2009 03:04:34 -0000	1.62
+++ profiles/default/default.profile	20 Aug 2009 00:37:48 -0000
@@ -181,21 +181,24 @@ function default_profile_site_setup(&$in
   // Create a default vocabulary named "Tags", enabled for the 'article' content type.
   $description = st('Use tags to group articles on similar topics into categories.');
   $help = st('Enter a comma-separated list of words to describe your content.');
-
-  $vid = db_insert('taxonomy_vocabulary')->fields(array(
+  $vocabulary = (object) array(
     'name' => 'Tags',
     'description' => $description,
     'machine_name' => 'tags',
     'help' => $help,
-    'relations' => 0,
-    'hierarchy' => 0,
-    'multiple' => 0,
-    'required' => 0,
-    'tags' => 1,
-    'module' => 'taxonomy',
     'weight' => 0,
-  ))->execute();
-  db_insert('taxonomy_vocabulary_node_type')->fields(array('vid' => $vid, 'type' => 'article'))->execute();
+  );
+  taxonomy_vocabulary_save($vocabulary);
+  $instance = array(
+    'field_name' => 'taxonomy_vocabulary_' . $vocabulary->machine_name,
+    'label' => $vocabulary->name,
+    'bundle' => 'article',
+    'description' => $vocabulary->help,
+    'widget' => array(
+      'type' => 'taxonomy_autocomplete',
+    ),
+  );
+  field_create_instance($instance);
 
   // Create a default role for site administrators.
   $rid = db_insert('role')->fields(array('name' => 'administrator'))->execute();
