diff --git a/modules/taxonomy/taxonomy.admin.inc b/modules/taxonomy/taxonomy.admin.inc
new file mode 100644
index 0000000000000000000000000000000000000000..91d47d89bc22b2fbc64de9ae1d28374ee1232112
--- /dev/null
+++ b/modules/taxonomy/taxonomy.admin.inc
@@ -0,0 +1,361 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Administrative page callbacks for the taxonomy module.
+ */
+
+/**
+ * List and manage vocabularies.
+ */
+function taxonomy_overview_vocabularies() {
+  $vocabularies = taxonomy_get_vocabularies();
+  $rows = array();
+  foreach ($vocabularies as $vocabulary) {
+    $types = array();
+    foreach ($vocabulary->nodes as $type) {
+      $node_type = node_get_types('name', $type);
+      $types[] = $node_type ? $node_type : $type;
+    }
+    $rows[] = array('name' => check_plain($vocabulary->name),
+      'type' => implode(', ', $types),
+      'edit' => l(t('edit vocabulary'), "admin/content/taxonomy/edit/vocabulary/$vocabulary->vid"),
+      'list' => l(t('list terms'), "admin/content/taxonomy/$vocabulary->vid"),
+      'add' => l(t('add terms'), "admin/content/taxonomy/$vocabulary->vid/add/term")
+    );
+  }
+  if (empty($rows)) {
+    $rows[] = array(array('data' => t('No categories available.'), 'colspan' => '5'));
+  }
+  $header = array(t('Name'), t('Type'), array('data' => t('Operations'), 'colspan' => '3'));
+
+  return theme('table', $header, $rows, array('id' => 'taxonomy'));
+}
+
+/**
+ * Display form for adding and editing vocabularies.
+ *
+ * @ingroup forms
+ * @see taxonomy_form_vocabulary_submit().
+ */
+function taxonomy_form_vocabulary(&$form_state, $edit = array()) {
+  $edit += array(
+    'name' => '',
+    'description' => '',
+    'help' => '',
+    'nodes' => array(),
+    'hierarchy' => 0,
+    'relations' => 0,
+    'tags' => 0,
+    'multiple' => 0,
+    'required' => 0,
+    'weight' => 0,
+  );
+  $form['name'] = array('#type' => 'textfield',
+    '#title' => t('Vocabulary name'),
+    '#default_value' => $edit['name'],
+    '#maxlength' => 255,
+    '#description' => t('The name for this vocabulary. Example: "Topic".'),
+    '#required' => TRUE,
+  );
+  $form['description'] = array('#type' => 'textarea',
+    '#title' => t('Description'),
+    '#default_value' => $edit['description'],
+    '#description' => t('Description of the vocabulary; can be used by modules.'),
+  );
+  $form['help'] = array('#type' => 'textfield',
+    '#title' => t('Help text'),
+    '#maxlength' => 255,
+    '#default_value' => $edit['help'],
+    '#description' => t('Instructions to present to the user when choosing a term.'),
+  );
+  $form['nodes'] = array('#type' => 'checkboxes',
+    '#title' => t('Content types'),
+    '#default_value' => $edit['nodes'],
+    '#options' => node_get_types('names'),
+    '#description' => t('A list of content types you would like to categorize using this vocabulary.'),
+  );
+  $form['hierarchy'] = array('#type' => 'radios',
+    '#title' => t('Hierarchy'),
+    '#default_value' => $edit['hierarchy'],
+    '#options' => array(t('Disabled'), t('Single'), t('Multiple')),
+    '#description' => t('Allows <a href="@help-url">a tree-like hierarchy</a> between terms of this vocabulary.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))),
+  );
+  $form['relations'] = array('#type' => 'checkbox',
+    '#title' => t('Related terms'),
+    '#default_value' => $edit['relations'],
+    '#description' => t('Allows <a href="@help-url">related terms</a> in this vocabulary.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))),
+  );
+  $form['tags'] = array('#type' => 'checkbox',
+    '#title' => t('Free tagging'),
+    '#default_value' => $edit['tags'],
+    '#description' => t('Content is categorized by typing terms instead of choosing from a list.'),
+  );
+  $form['multiple'] = array('#type' => 'checkbox',
+    '#title' => t('Multiple select'),
+    '#default_value' => $edit['multiple'],
+    '#description' => t('Allows nodes to have more than one term from this vocabulary (always true for free tagging).'),
+  );
+  $form['required'] = array('#type' => 'checkbox',
+    '#title' => t('Required'),
+    '#default_value' => $edit['required'],
+    '#description' => t('If enabled, every node <strong>must</strong> have at least one term in this vocabulary.'),
+  );
+  $form['weight'] = array('#type' => 'weight',
+    '#title' => t('Weight'),
+    '#default_value' => $edit['weight'],
+    '#description' => t('In listings, the heavier vocabularies will sink and the lighter vocabularies will be positioned nearer the top.'),
+  );
+
+  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
+  if (isset($edit['vid'])) {
+    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
+    $form['vid'] = array('#type' => 'value', '#value' => $edit['vid']);
+    $form['module'] = array('#type' => 'value', '#value' => $edit['module']);
+  }
+  return $form;
+}
+
+/**
+ * Accept the form submission for a vocabulary and save the results.
+ */
+function taxonomy_form_vocabulary_submit($form, &$form_state) {
+  // Fix up the nodes array to remove unchecked nodes.
+  $form_state['values']['nodes'] = array_filter($form_state['values']['nodes']);
+  switch (taxonomy_save_vocabulary($form_state['values'])) {
+    case SAVED_NEW:
+      drupal_set_message(t('Created new vocabulary %name.', array('%name' => $form_state['values']['name'])));
+      watchdog('taxonomy', 'Created new vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
+      break;
+    case SAVED_UPDATED:
+      drupal_set_message(t('Updated vocabulary %name.', array('%name' => $form_state['values']['name'])));
+      watchdog('taxonomy', 'Updated vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
+      break;
+  }
+
+  $form_state['vid'] = $form_state['values']['vid'];
+  $form_state['redirect'] = 'admin/content/taxonomy';
+  return;
+}
+
+/**
+ * Page to edit a vocabulary.
+ */
+function taxonomy_admin_vocabulary_edit($vocabulary) {
+  if ((isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) {
+    return drupal_get_form('taxonomy_vocabulary_confirm_delete', $vocabulary->vid);
+  }
+  return drupal_get_form('taxonomy_form_vocabulary', (array)$vocabulary);
+}
+
+/**
+ * Page to edit a vocabulary term.
+ */
+function taxonomy_admin_term_edit($tid) {
+  if ((isset($_POST['op']) && $_POST['op']) == t('Delete') || isset($_POST['confirm'])) {
+    return drupal_get_form('taxonomy_term_confirm_delete', $tid);
+  }
+  if ($term = (array)taxonomy_get_term($tid)) {
+    return drupal_get_form('taxonomy_form_term', taxonomy_vocabulary_load($term['vid']), $term);
+  }
+  return drupal_not_found();
+}
+
+/**
+ * Display a tree of all the terms in a vocabulary, with options to edit
+ * each one.
+ */
+function taxonomy_overview_terms($vocabulary) {
+  $destination = drupal_get_destination();
+
+  $header = array(t('Name'), t('Operations'));
+
+  drupal_set_title(check_plain($vocabulary->name));
+  $start_from      = isset($_GET['page']) ? $_GET['page'] : 0;
+  $total_entries   = 0;  // total count for pager
+  $page_increment  = 25; // number of tids per page
+  $displayed_count = 0;  // number of tids shown
+
+  $tree = taxonomy_get_tree($vocabulary->vid);
+  foreach ($tree as $term) {
+    $total_entries++; // we're counting all-totals, not displayed
+    if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count == $page_increment)) {
+      continue;
+    }
+    $rows[] = array(str_repeat('--', $term->depth) .' '. l($term->name, "taxonomy/term/$term->tid"), l(t('edit'), "admin/content/taxonomy/edit/term/$term->tid", array('query' => $destination)));
+    $displayed_count++; // we're counting tids displayed
+  }
+
+  if (empty($rows)) {
+    $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '2'));
+  }
+
+  $GLOBALS['pager_page_array'][] = $start_from;  // FIXME
+  $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME
+
+  if ($total_entries >= $page_increment) {
+    $rows[] = array(array('data' => theme('pager', NULL, $page_increment), 'colspan' => '2'));
+  }
+
+  return theme('table', $header, $rows, array('id' => 'taxonomy'));
+}
+
+/**
+ * Form function for the term edit form.
+ *
+ * @ingroup forms
+ * @see taxonomy_form_term_submit().
+ */
+function taxonomy_form_term(&$form_state, $vocabulary, $edit = array()) {
+  $edit += array(
+    'name' => '',
+    'description' => '',
+    'tid' => NULL,
+    'weight' => 0,
+  );
+  $form['name'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Term name'),
+    '#default_value' => $edit['name'],
+    '#maxlength' => 255,
+    '#description' => t('The name of this term.'),
+    '#required' => TRUE);
+
+  $form['description'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Description'),
+    '#default_value' => $edit['description'],
+    '#description' => t('A description of the term.'));
+
+  if ($vocabulary->hierarchy) {
+    $parent = array_keys(taxonomy_get_parents($edit['tid']));
+    $children = taxonomy_get_tree($vocabulary->vid, $edit['tid']);
+
+    // A term can't be the child of itself, nor of its children.
+    foreach ($children as $child) {
+      $exclude[] = $child->tid;
+    }
+    $exclude[] = $edit['tid'];
+
+    if ($vocabulary->hierarchy == 1) {
+      $form['parent'] = _taxonomy_term_select(t('Parent'), 'parent', $parent, $vocabulary->vid, l(t('Parent term'), 'admin/help/taxonomy', array('fragment' => 'parent')) .'.', 0, '<'. t('root') .'>', $exclude);
+    }
+    elseif ($vocabulary->hierarchy == 2) {
+      $form['parent'] = _taxonomy_term_select(t('Parents'), 'parent', $parent, $vocabulary->vid, l(t('Parent terms'), 'admin/help/taxonomy', array('fragment' => 'parent')) .'.', 1, '<'. t('root') .'>', $exclude);
+    }
+  }
+
+  if ($vocabulary->relations) {
+    $form['relations'] = _taxonomy_term_select(t('Related terms'), 'relations', array_keys(taxonomy_get_related($edit['tid'])), $vocabulary->vid, NULL, 1, '<'. t('none') .'>', array($edit['tid']));
+  }
+
+  $form['synonyms'] = array(
+    '#type' => 'textarea',
+    '#title' => t('Synonyms'),
+    '#default_value' => implode("\n", taxonomy_get_synonyms($edit['tid'])),
+    '#description' => t('<a href="@help-url">Synonyms</a> of this term, one synonym per line.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))));
+  $form['weight'] = array(
+    '#type' => 'weight',
+    '#title' => t('Weight'),
+    '#default_value' => $edit['weight'],
+    '#description' => t('In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top.'));
+  $form['vid'] = array(
+    '#type' => 'value',
+    '#value' => $vocabulary->vid);
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'));
+
+  if ($edit['tid']) {
+    $form['delete'] = array(
+      '#type' => 'submit',
+      '#value' => t('Delete'));
+    $form['tid'] = array(
+      '#type' => 'value',
+      '#value' => $edit['tid']);
+  }
+  else {
+    $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
+  }
+
+  return $form;
+}
+
+/**
+ * Accept the form submission for a taxonomy term and save the result.
+ */
+function taxonomy_form_term_submit($form, &$form_state) {
+  switch (taxonomy_save_term($form_state['values'])) {
+    case SAVED_NEW:
+      drupal_set_message(t('Created new term %term.', array('%term' => $form_state['values']['name'])));
+      watchdog('taxonomy', 'Created new term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
+      break;
+    case SAVED_UPDATED:
+      drupal_set_message(t('Updated term %term.', array('%term' => $form_state['values']['name'])));
+      watchdog('taxonomy', 'Updated term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
+      break;
+  }
+
+  $form_state['tid'] = $form_state['values']['tid'];
+  $form_state['redirect'] = 'admin/content/taxonomy';
+  return;
+}
+
+/**
+ * Form builder for the term delete form.
+ *
+ * @ingroup forms
+ * @see taxonomy_term_confirm_delete_submit().
+ */
+function taxonomy_term_confirm_delete(&$form_state, $tid) {
+  $term = taxonomy_get_term($tid);
+
+  $form['type'] = array('#type' => 'value', '#value' => 'term');
+  $form['name'] = array('#type' => 'value', '#value' => $term->name);
+  $form['tid'] = array('#type' => 'value', '#value' => $tid);
+  return confirm_form($form,
+                  t('Are you sure you want to delete the term %title?',
+                  array('%title' => $term->name)),
+                  'admin/content/taxonomy',
+                  t('Deleting a term will delete all its children if there are any. This action cannot be undone.'),
+                  t('Delete'),
+                  t('Cancel'));
+}
+
+function taxonomy_term_confirm_delete_submit($form, &$form_state) {
+  taxonomy_del_term($form_state['values']['tid']);
+  drupal_set_message(t('Deleted term %name.', array('%name' => $form_state['values']['name'])));
+  watchdog('taxonomy', 'Deleted term %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
+  $form_state['redirect'] = 'admin/content/taxonomy';
+  return;
+}
+
+/**
+ * Form builder for the vocabulary delete confirmation form.
+ *
+ * @ingroup forms
+ * @see taxonomy_vocabulary_confirm_delete_submit().
+ */
+function taxonomy_vocabulary_confirm_delete(&$form_state, $vid) {
+  $vocabulary = taxonomy_vocabulary_load($vid);
+
+  $form['type'] = array('#type' => 'value', '#value' => 'vocabulary');
+  $form['vid'] = array('#type' => 'value', '#value' => $vid);
+  $form['name'] = array('#type' => 'value', '#value' => $vocabulary->name);
+  return confirm_form($form,
+                  t('Are you sure you want to delete the vocabulary %title?',
+                  array('%title' => $vocabulary->name)),
+                  'admin/content/taxonomy',
+                  t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'),
+                  t('Delete'),
+                  t('Cancel'));
+}
+
+function taxonomy_vocabulary_confirm_delete_submit($form, &$form_state) {
+  $status = taxonomy_del_vocabulary($form_state['values']['vid']);
+  drupal_set_message(t('Deleted vocabulary %name.', array('%name' => $form_state['values']['name'])));
+  watchdog('taxonomy', 'Deleted vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
+  $form_state['redirect'] = 'admin/content/taxonomy';
+  return;
+}
diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module
index 0ef4122d69051629e8083b3e0771069b23f4769d..c7eaacc7c2e74fcf34091db991d0207b34cabdfc 100644
--- a/modules/taxonomy/taxonomy.module
+++ b/modules/taxonomy/taxonomy.module
@@ -87,6 +87,7 @@ function taxonomy_menu() {
     'description' => 'Create vocabularies and terms to categorize your content.',
     'page callback' => 'taxonomy_overview_vocabularies',
     'access arguments' => array('administer taxonomy'),
+    'file' => 'taxonomy.admin.inc',
   );
 
   $items['admin/content/taxonomy/list'] = array(
@@ -101,6 +102,7 @@ function taxonomy_menu() {
     'page arguments' => array('taxonomy_form_vocabulary'),
     'type' => MENU_LOCAL_TASK,
     'parent' => 'admin/content/taxonomy',
+    'file' => 'taxonomy.admin.inc',
   );
 
   $items['admin/content/taxonomy/edit/vocabulary/%taxonomy_vocabulary'] = array(
@@ -108,12 +110,14 @@ function taxonomy_menu() {
     'page callback' => 'taxonomy_admin_vocabulary_edit',
     'page arguments' => array(5),
     'type' => MENU_CALLBACK,
+    'file' => 'taxonomy.admin.inc',
   );
 
   $items['admin/content/taxonomy/edit/term'] = array(
     'title' => 'Edit term',
     'page callback' => 'taxonomy_admin_term_edit',
     'type' => MENU_CALLBACK,
+    'file' => 'taxonomy.admin.inc',
   );
 
   $items['taxonomy/term'] = array(
@@ -121,6 +125,7 @@ function taxonomy_menu() {
     'page callback' => 'taxonomy_term_page',
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
+    'file' => 'taxonomy.page.inc',
   );
 
   $items['taxonomy/autocomplete'] = array(
@@ -128,6 +133,7 @@ function taxonomy_menu() {
     'page callback' => 'taxonomy_autocomplete',
     'access arguments' => array('access content'),
     'type' => MENU_CALLBACK,
+    'file' => 'taxonomy.page.inc',
   );
   $items['admin/content/taxonomy/%taxonomy_vocabulary'] = array(
     'title' => 'List terms',
@@ -135,6 +141,7 @@ function taxonomy_menu() {
     'page arguments' => array(3),
     'access arguments' => array('administer taxonomy'),
     'type' => MENU_CALLBACK,
+    'file' => 'taxonomy.admin.inc',
   );
 
   $items['admin/content/taxonomy/%taxonomy_vocabulary/list'] = array(
@@ -149,180 +156,12 @@ function taxonomy_menu() {
     'page arguments' => array('taxonomy_form_term', 3),
     'type' => MENU_LOCAL_TASK,
     'parent' => 'admin/content/taxonomy/%taxonomy_vocabulary',
+    'file' => 'taxonomy.admin.inc',
   );
 
   return $items;
 }
 
-/**
- * List and manage vocabularies.
- */
-function taxonomy_overview_vocabularies() {
-  $vocabularies = taxonomy_get_vocabularies();
-  $rows = array();
-  foreach ($vocabularies as $vocabulary) {
-    $types = array();
-    foreach ($vocabulary->nodes as $type) {
-      $node_type = node_get_types('name', $type);
-      $types[] = $node_type ? $node_type : $type;
-    }
-    $rows[] = array('name' => check_plain($vocabulary->name),
-      'type' => implode(', ', $types),
-      'edit' => l(t('edit vocabulary'), "admin/content/taxonomy/edit/vocabulary/$vocabulary->vid"),
-      'list' => l(t('list terms'), "admin/content/taxonomy/$vocabulary->vid"),
-      'add' => l(t('add terms'), "admin/content/taxonomy/$vocabulary->vid/add/term")
-    );
-  }
-  if (empty($rows)) {
-    $rows[] = array(array('data' => t('No categories available.'), 'colspan' => '5'));
-  }
-  $header = array(t('Name'), t('Type'), array('data' => t('Operations'), 'colspan' => '3'));
-
-  return theme('table', $header, $rows, array('id' => 'taxonomy'));
-}
-
-/**
- * Display a tree of all the terms in a vocabulary, with options to edit
- * each one.
- */
-function taxonomy_overview_terms($vocabulary) {
-  $destination = drupal_get_destination();
-
-  $header = array(t('Name'), t('Operations'));
-
-  drupal_set_title(check_plain($vocabulary->name));
-  $start_from      = isset($_GET['page']) ? $_GET['page'] : 0;
-  $total_entries   = 0;  // total count for pager
-  $page_increment  = 25; // number of tids per page
-  $displayed_count = 0;  // number of tids shown
-
-  $tree = taxonomy_get_tree($vocabulary->vid);
-  foreach ($tree as $term) {
-    $total_entries++; // we're counting all-totals, not displayed
-    if (($start_from && ($start_from * $page_increment) >= $total_entries) || ($displayed_count == $page_increment)) {
-      continue;
-    }
-    $rows[] = array(str_repeat('--', $term->depth) .' '. l($term->name, "taxonomy/term/$term->tid"), l(t('edit'), "admin/content/taxonomy/edit/term/$term->tid", array('query' => $destination)));
-    $displayed_count++; // we're counting tids displayed
-  }
-
-  if (empty($rows)) {
-    $rows[] = array(array('data' => t('No terms available.'), 'colspan' => '2'));
-  }
-
-  $GLOBALS['pager_page_array'][] = $start_from;  // FIXME
-  $GLOBALS['pager_total'][] = intval($total_entries / $page_increment) + 1; // FIXME
-
-  if ($total_entries >= $page_increment) {
-    $rows[] = array(array('data' => theme('pager', NULL, $page_increment), 'colspan' => '2'));
-  }
-
-  return theme('table', $header, $rows, array('id' => 'taxonomy'));
-}
-
-/**
- * Display form for adding and editing vocabularies.
- */
-function taxonomy_form_vocabulary(&$form_state, $edit = array()) {
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'help' => '',
-    'nodes' => array(),
-    'hierarchy' => 0,
-    'relations' => 0,
-    'tags' => 0,
-    'multiple' => 0,
-    'required' => 0,
-    'weight' => 0,
-  );
-  $form['name'] = array('#type' => 'textfield',
-    '#title' => t('Vocabulary name'),
-    '#default_value' => $edit['name'],
-    '#maxlength' => 255,
-    '#description' => t('The name for this vocabulary. Example: "Topic".'),
-    '#required' => TRUE,
-  );
-  $form['description'] = array('#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $edit['description'],
-    '#description' => t('Description of the vocabulary; can be used by modules.'),
-  );
-  $form['help'] = array('#type' => 'textfield',
-    '#title' => t('Help text'),
-    '#maxlength' => 255,
-    '#default_value' => $edit['help'],
-    '#description' => t('Instructions to present to the user when choosing a term.'),
-  );
-  $form['nodes'] = array('#type' => 'checkboxes',
-    '#title' => t('Content types'),
-    '#default_value' => $edit['nodes'],
-    '#options' => node_get_types('names'),
-    '#description' => t('A list of content types you would like to categorize using this vocabulary.'),
-  );
-  $form['hierarchy'] = array('#type' => 'radios',
-    '#title' => t('Hierarchy'),
-    '#default_value' => $edit['hierarchy'],
-    '#options' => array(t('Disabled'), t('Single'), t('Multiple')),
-    '#description' => t('Allows <a href="@help-url">a tree-like hierarchy</a> between terms of this vocabulary.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))),
-  );
-  $form['relations'] = array('#type' => 'checkbox',
-    '#title' => t('Related terms'),
-    '#default_value' => $edit['relations'],
-    '#description' => t('Allows <a href="@help-url">related terms</a> in this vocabulary.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))),
-  );
-  $form['tags'] = array('#type' => 'checkbox',
-    '#title' => t('Free tagging'),
-    '#default_value' => $edit['tags'],
-    '#description' => t('Content is categorized by typing terms instead of choosing from a list.'),
-  );
-  $form['multiple'] = array('#type' => 'checkbox',
-    '#title' => t('Multiple select'),
-    '#default_value' => $edit['multiple'],
-    '#description' => t('Allows nodes to have more than one term from this vocabulary (always true for free tagging).'),
-  );
-  $form['required'] = array('#type' => 'checkbox',
-    '#title' => t('Required'),
-    '#default_value' => $edit['required'],
-    '#description' => t('If enabled, every node <strong>must</strong> have at least one term in this vocabulary.'),
-  );
-  $form['weight'] = array('#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
-    '#description' => t('In listings, the heavier vocabularies will sink and the lighter vocabularies will be positioned nearer the top.'),
-  );
-
-  $form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
-  if (isset($edit['vid'])) {
-    $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'));
-    $form['vid'] = array('#type' => 'value', '#value' => $edit['vid']);
-    $form['module'] = array('#type' => 'value', '#value' => $edit['module']);
-  }
-  return $form;
-}
-
-/**
- * Accept the form submission for a vocabulary and save the results.
- */
-function taxonomy_form_vocabulary_submit($form, &$form_state) {
-  // Fix up the nodes array to remove unchecked nodes.
-  $form_state['values']['nodes'] = array_filter($form_state['values']['nodes']);
-  switch (taxonomy_save_vocabulary($form_state['values'])) {
-    case SAVED_NEW:
-      drupal_set_message(t('Created new vocabulary %name.', array('%name' => $form_state['values']['name'])));
-      watchdog('taxonomy', 'Created new vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
-      break;
-    case SAVED_UPDATED:
-      drupal_set_message(t('Updated vocabulary %name.', array('%name' => $form_state['values']['name'])));
-      watchdog('taxonomy', 'Updated vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/vocabulary/'. $form_state['values']['vid']));
-      break;
-  }
-
-  $form_state['vid'] = $form_state['values']['vid'];
-  $form_state['redirect'] = 'admin/content/taxonomy';
-  return;
-}
-
 function taxonomy_save_vocabulary(&$edit) {
   $edit['nodes'] = empty($edit['nodes']) ? array() : $edit['nodes'];
 
@@ -378,124 +217,6 @@ function taxonomy_del_vocabulary($vid) {
   return SAVED_DELETED;
 }
 
-function taxonomy_vocabulary_confirm_delete(&$form_state, $vid) {
-  $vocabulary = taxonomy_vocabulary_load($vid);
-
-  $form['type'] = array('#type' => 'value', '#value' => 'vocabulary');
-  $form['vid'] = array('#type' => 'value', '#value' => $vid);
-  $form['name'] = array('#type' => 'value', '#value' => $vocabulary->name);
-  return confirm_form($form,
-                  t('Are you sure you want to delete the vocabulary %title?',
-                  array('%title' => $vocabulary->name)),
-                  'admin/content/taxonomy',
-                  t('Deleting a vocabulary will delete all the terms in it. This action cannot be undone.'),
-                  t('Delete'),
-                  t('Cancel'));
-}
-
-function taxonomy_vocabulary_confirm_delete_submit($form, &$form_state) {
-  $status = taxonomy_del_vocabulary($form_state['values']['vid']);
-  drupal_set_message(t('Deleted vocabulary %name.', array('%name' => $form_state['values']['name'])));
-  watchdog('taxonomy', 'Deleted vocabulary %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
-  $form_state['redirect'] = 'admin/content/taxonomy';
-  return;
-}
-
-function taxonomy_form_term(&$form_state, $vocabulary, $edit = array()) {
-  $edit += array(
-    'name' => '',
-    'description' => '',
-    'tid' => NULL,
-    'weight' => 0,
-  );
-  $form['name'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Term name'),
-    '#default_value' => $edit['name'],
-    '#maxlength' => 255,
-    '#description' => t('The name of this term.'),
-    '#required' => TRUE);
-
-  $form['description'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Description'),
-    '#default_value' => $edit['description'],
-    '#description' => t('A description of the term.'));
-
-  if ($vocabulary->hierarchy) {
-    $parent = array_keys(taxonomy_get_parents($edit['tid']));
-    $children = taxonomy_get_tree($vocabulary->vid, $edit['tid']);
-
-    // A term can't be the child of itself, nor of its children.
-    foreach ($children as $child) {
-      $exclude[] = $child->tid;
-    }
-    $exclude[] = $edit['tid'];
-
-    if ($vocabulary->hierarchy == 1) {
-      $form['parent'] = _taxonomy_term_select(t('Parent'), 'parent', $parent, $vocabulary->vid, l(t('Parent term'), 'admin/help/taxonomy', array('fragment' => 'parent')) .'.', 0, '<'. t('root') .'>', $exclude);
-    }
-    elseif ($vocabulary->hierarchy == 2) {
-      $form['parent'] = _taxonomy_term_select(t('Parents'), 'parent', $parent, $vocabulary->vid, l(t('Parent terms'), 'admin/help/taxonomy', array('fragment' => 'parent')) .'.', 1, '<'. t('root') .'>', $exclude);
-    }
-  }
-
-  if ($vocabulary->relations) {
-    $form['relations'] = _taxonomy_term_select(t('Related terms'), 'relations', array_keys(taxonomy_get_related($edit['tid'])), $vocabulary->vid, NULL, 1, '<'. t('none') .'>', array($edit['tid']));
-  }
-
-  $form['synonyms'] = array(
-    '#type' => 'textarea',
-    '#title' => t('Synonyms'),
-    '#default_value' => implode("\n", taxonomy_get_synonyms($edit['tid'])),
-    '#description' => t('<a href="@help-url">Synonyms</a> of this term, one synonym per line.', array('@help-url' => url('admin/help/taxonomy', array('absolute' => TRUE)))));
-  $form['weight'] = array(
-    '#type' => 'weight',
-    '#title' => t('Weight'),
-    '#default_value' => $edit['weight'],
-    '#description' => t('In listings, the heavier terms will sink and the lighter terms will be positioned nearer the top.'));
-  $form['vid'] = array(
-    '#type' => 'value',
-    '#value' => $vocabulary->vid);
-  $form['submit'] = array(
-    '#type' => 'submit',
-    '#value' => t('Save'));
-
-  if ($edit['tid']) {
-    $form['delete'] = array(
-      '#type' => 'submit',
-      '#value' => t('Delete'));
-    $form['tid'] = array(
-      '#type' => 'value',
-      '#value' => $edit['tid']);
-  }
-  else {
-    $form['destination'] = array('#type' => 'hidden', '#value' => $_GET['q']);
-  }
-
-  return $form;
-}
-
-/**
- * Accept the form submission for a taxonomy term and save the result.
- */
-function taxonomy_form_term_submit($form, &$form_state) {
-  switch (taxonomy_save_term($form_state['values'])) {
-    case SAVED_NEW:
-      drupal_set_message(t('Created new term %term.', array('%term' => $form_state['values']['name'])));
-      watchdog('taxonomy', 'Created new term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
-      break;
-    case SAVED_UPDATED:
-      drupal_set_message(t('Updated term %term.', array('%term' => $form_state['values']['name'])));
-      watchdog('taxonomy', 'Updated term %term.', array('%term' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/content/taxonomy/edit/term/'. $form_state['values']['tid']));
-      break;
-  }
-
-  $form_state['tid'] = $form_state['values']['tid'];
-  $form_state['redirect'] = 'admin/content/taxonomy';
-  return;
-}
-
 /**
  * Helper function for taxonomy_form_term_submit().
  *
@@ -614,29 +335,6 @@ function taxonomy_del_term($tid) {
   return SAVED_DELETED;
 }
 
-function taxonomy_term_confirm_delete(&$form_state, $tid) {
-  $term = taxonomy_get_term($tid);
-
-  $form['type'] = array('#type' => 'value', '#value' => 'term');
-  $form['name'] = array('#type' => 'value', '#value' => $term->name);
-  $form['tid'] = array('#type' => 'value', '#value' => $tid);
-  return confirm_form($form,
-                  t('Are you sure you want to delete the term %title?',
-                  array('%title' => $term->name)),
-                  'admin/content/taxonomy',
-                  t('Deleting a term will delete all its children if there are any. This action cannot be undone.'),
-                  t('Delete'),
-                  t('Cancel'));
-}
-
-function taxonomy_term_confirm_delete_submit($form, &$form_state) {
-  taxonomy_del_term($form_state['values']['tid']);
-  drupal_set_message(t('Deleted term %name.', array('%name' => $form_state['values']['name'])));
-  watchdog('taxonomy', 'Deleted term %name.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE);
-  $form_state['redirect'] = 'admin/content/taxonomy';
-  return;
-}
-
 /**
  * Generate a form element for selecting terms from a vocabulary.
  */
@@ -1376,93 +1074,6 @@ function taxonomy_terms_parse_string($str_tids) {
   return $terms;
 }
 
-
-/**
- * Menu callback; displays all nodes associated with a term.
- */
-function taxonomy_term_page($str_tids = '', $depth = 0, $op = 'page') {
-  $terms = taxonomy_terms_parse_string($str_tids);
-  if ($terms['operator'] != 'and' && $terms['operator'] != 'or') {
-    drupal_not_found();
-  }
-
-  if ($terms['tids']) {
-    $result = db_query(db_rewrite_sql('SELECT t.tid, t.name FROM {term_data} t WHERE t.tid IN (%s)', 't', 'tid'), implode(',', $terms['tids']));
-    $tids = array(); // we rebuild the $tids-array so it only contains terms the user has access to.
-    $names = array();
-    while ($term = db_fetch_object($result)) {
-      $tids[] = $term->tid;
-      $names[] = $term->name;
-    }
-
-    if ($names) {
-      $title = check_plain(implode(', ', $names));
-      drupal_set_title($title);
-
-      switch ($op) {
-        case 'page':
-          // Build breadcrumb based on first hierarchy of first term:
-          $current->tid = $tids[0];
-          $breadcrumbs = array(array('path' => $_GET['q'], 'title' => $names[0]));
-          while ($parents = taxonomy_get_parents($current->tid)) {
-            $current = array_shift($parents);
-            $breadcrumbs[] = array('path' => 'taxonomy/term/'. $current->tid, 'title' => $current->name);
-          }
-          $breadcrumbs = array_reverse($breadcrumbs);
-          menu_set_location($breadcrumbs);
-
-          $output = taxonomy_render_nodes(taxonomy_select_nodes($tids, $terms['operator'], $depth, TRUE));
-          drupal_add_feed(url('taxonomy/term/'. $str_tids .'/'. $depth .'/feed'), 'RSS - '. $title);
-          return $output;
-          break;
-
-        case 'feed':
-          $term = taxonomy_get_term($tids[0]);
-          $channel['link'] = url('taxonomy/term/'. $str_tids .'/'. $depth, array('absolute' => TRUE));
-          $channel['title'] = variable_get('site_name', 'Drupal') .' - '. $title;
-          $channel['description'] = $term->description;
-
-          $result = taxonomy_select_nodes($tids, $terms['operator'], $depth, FALSE);
-
-          while ($row = db_fetch_object($result)) {
-            $items[] = $row->nid;
-          }
-
-          node_feed($items, $channel);
-          break;
-        default:
-          drupal_not_found();
-      }
-    }
-    else {
-      drupal_not_found();
-    }
-  }
-}
-
-/**
- * Page to edit a vocabulary.
- */
-function taxonomy_admin_vocabulary_edit($vocabulary) {
-  if ((isset($_POST['op']) && $_POST['op'] == t('Delete')) || isset($_POST['confirm'])) {
-    return drupal_get_form('taxonomy_vocabulary_confirm_delete', $vocabulary->vid);
-  }
-  return drupal_get_form('taxonomy_form_vocabulary', (array)$vocabulary);
-}
-
-/**
- * Page to edit a vocabulary term.
- */
-function taxonomy_admin_term_edit($tid) {
-  if ((isset($_POST['op']) && $_POST['op']) == t('Delete') || isset($_POST['confirm'])) {
-    return drupal_get_form('taxonomy_term_confirm_delete', $tid);
-  }
-  if ($term = (array)taxonomy_get_term($tid)) {
-    return drupal_get_form('taxonomy_form_term', taxonomy_vocabulary_load($term['vid']), $term);
-  }
-  return drupal_not_found();
-}
-
 /**
  * Provides category information for RSS feeds.
  */
@@ -1501,34 +1112,6 @@ function _taxonomy_get_tid_from_term($term) {
   return $term->tid;
 }
 
-/**
- * Helper function for autocompletion
- */
-function taxonomy_autocomplete($vid, $string = '') {
-  // The user enters a comma-separated list of tags. We only autocomplete the last tag.
-  $array = drupal_explode_tags($string);
-
-  // Fetch last tag
-  $last_string = trim(array_pop($array));
-  $matches = array();
-  if ($last_string != '') {
-    $result = db_query_range(db_rewrite_sql("SELECT t.tid, t.name FROM {term_data} t WHERE t.vid = %d AND LOWER(t.name) LIKE LOWER('%%%s%%')", 't', 'tid'), $vid, $last_string, 0, 10);
-
-    $prefix = count($array) ? implode(', ', $array) .', ' : '';
-
-    while ($tag = db_fetch_object($result)) {
-      $n = $tag->name;
-      // Commas and quotes in terms are special cases, so encode 'em.
-      if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
-        $n = '"'. str_replace('"', '""', $tag->name) .'"';
-      }
-      $matches[$prefix . $n] = check_plain($tag->name);
-    }
-  }
-
-  drupal_json($matches);
-}
-
 /**
  * Implode a list of tags of a certain vocabulary into a string.
  */
diff --git a/modules/taxonomy/taxonomy.pages.inc b/modules/taxonomy/taxonomy.pages.inc
new file mode 100644
index 0000000000000000000000000000000000000000..ef4ceaed2234036e9e5af51a30c3e7306746255e
--- /dev/null
+++ b/modules/taxonomy/taxonomy.pages.inc
@@ -0,0 +1,98 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Administrative page callbacks for the taxonomy module.
+ */
+
+/**
+ * Menu callback; displays all nodes associated with a term.
+ */
+function taxonomy_term_page($str_tids = '', $depth = 0, $op = 'page') {
+  $terms = taxonomy_terms_parse_string($str_tids);
+  if ($terms['operator'] != 'and' && $terms['operator'] != 'or') {
+    drupal_not_found();
+  }
+
+  if ($terms['tids']) {
+    $result = db_query(db_rewrite_sql('SELECT t.tid, t.name FROM {term_data} t WHERE t.tid IN (%s)', 't', 'tid'), implode(',', $terms['tids']));
+    $tids = array(); // we rebuild the $tids-array so it only contains terms the user has access to.
+    $names = array();
+    while ($term = db_fetch_object($result)) {
+      $tids[] = $term->tid;
+      $names[] = $term->name;
+    }
+
+    if ($names) {
+      $title = check_plain(implode(', ', $names));
+      drupal_set_title($title);
+
+      switch ($op) {
+        case 'page':
+          // Build breadcrumb based on first hierarchy of first term:
+          $current->tid = $tids[0];
+          $breadcrumbs = array(array('path' => $_GET['q'], 'title' => $names[0]));
+          while ($parents = taxonomy_get_parents($current->tid)) {
+            $current = array_shift($parents);
+            $breadcrumbs[] = array('path' => 'taxonomy/term/'. $current->tid, 'title' => $current->name);
+          }
+          $breadcrumbs = array_reverse($breadcrumbs);
+          menu_set_location($breadcrumbs);
+
+          $output = taxonomy_render_nodes(taxonomy_select_nodes($tids, $terms['operator'], $depth, TRUE));
+          drupal_add_feed(url('taxonomy/term/'. $str_tids .'/'. $depth .'/feed'), 'RSS - '. $title);
+          return $output;
+          break;
+
+        case 'feed':
+          $term = taxonomy_get_term($tids[0]);
+          $channel['link'] = url('taxonomy/term/'. $str_tids .'/'. $depth, array('absolute' => TRUE));
+          $channel['title'] = variable_get('site_name', 'Drupal') .' - '. $title;
+          $channel['description'] = $term->description;
+
+          $result = taxonomy_select_nodes($tids, $terms['operator'], $depth, FALSE);
+
+          while ($row = db_fetch_object($result)) {
+            $items[] = $row->nid;
+          }
+
+          node_feed($items, $channel);
+          break;
+        default:
+          drupal_not_found();
+      }
+    }
+    else {
+      drupal_not_found();
+    }
+  }
+}
+
+/**
+ * Helper function for autocompletion
+ */
+function taxonomy_autocomplete($vid, $string = '') {
+  // The user enters a comma-separated list of tags. We only autocomplete the last tag.
+  $array = drupal_explode_tags($string);
+
+  // Fetch last tag
+  $last_string = trim(array_pop($array));
+  $matches = array();
+  if ($last_string != '') {
+    $result = db_query_range(db_rewrite_sql("SELECT t.tid, t.name FROM {term_data} t WHERE t.vid = %d AND LOWER(t.name) LIKE LOWER('%%%s%%')", 't', 'tid'), $vid, $last_string, 0, 10);
+
+    $prefix = count($array) ? implode(', ', $array) .', ' : '';
+
+    while ($tag = db_fetch_object($result)) {
+      $n = $tag->name;
+      // Commas and quotes in terms are special cases, so encode 'em.
+      if (strpos($tag->name, ',') !== FALSE || strpos($tag->name, '"') !== FALSE) {
+        $n = '"'. str_replace('"', '""', $tag->name) .'"';
+      }
+      $matches[$prefix . $n] = check_plain($tag->name);
+    }
+  }
+
+  drupal_json($matches);
+}