=== modified file 'includes/form.inc'
--- includes/form.inc	
+++ includes/form.inc	
@@ -215,6 +215,16 @@ function drupal_prepare_form($form_id, &
     $function = $module .'_form_alter';
     $function($form_id, $form);
   }
+  if (isset($form['#base'])) {
+    foreach (module_implements('form_alter_'. $form['#base']) as $module) {
+      $function = $module .'_form_alter_'. $form['#base'];
+      $function($form_id, $form);
+    }
+  }
+  foreach (module_implements('form_alter_'. $form_id) as $module) {
+    $function = $module .'_form_alter_'. $form_id;
+    $function($form_id, $form);
+  }
 
   $form = form_builder($form_id, $form);
 }
=== modified file 'modules/comment/comment.module'
--- modules/comment/comment.module	
+++ modules/comment/comment.module	
@@ -268,35 +268,32 @@ function comment_link($type, $node = NUL
   return $links;
 }
 
-function comment_form_alter($form_id, &$form) {
-  if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
-    $form['workflow']['comment'] = array(
-      '#type' => 'radios',
-      '#title' => t('Default comment setting'),
-      '#default_value' => variable_get('comment_'. $form['identity']['type']['#default_value'], COMMENT_NODE_READ_WRITE),
-      '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
-      '#description' => t('Users with the <em>administer comments</em> permission will be able to override this setting.'),
-    );
-  }
-  elseif (isset($form['type'])) {
-    if ($form['type']['#value'] .'_node_form' == $form_id) {
-      $node = $form['#node'];
-      $form['comment_settings'] = array(
-        '#type' => 'fieldset',
-        '#access' => user_access('administer comments'),
-        '#title' => t('Comment settings'),
-        '#collapsible' => TRUE,
-        '#collapsed' => TRUE,
-        '#weight' => 30,
-      );
-      $form['comment_settings']['comment'] = array(
-        '#type' => 'radios',
-        '#parents' => array('comment'),
-        '#default_value' => $node->comment,
-        '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
-      );
-    }
-  }
+function comment_form_alter_node_type_form($form_id, &$form) {
+  $form['workflow']['comment'] = array(
+    '#type' => 'radios',
+    '#title' => t('Default comment setting'),
+    '#default_value' => variable_get('comment_'. $form['identity']['type']['#default_value'], COMMENT_NODE_READ_WRITE),
+    '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
+    '#description' => t('Users with the <em>administer comments</em> permission will be able to override this setting.'),
+  );
+}
+
+function comment_form_alter_node_form($form_id, &$form) {
+  $node = $form['#node'];
+  $form['comment_settings'] = array(
+    '#type' => 'fieldset',
+    '#access' => user_access('administer comments'),
+    '#title' => t('Comment settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#weight' => 30,
+  );
+  $form['comment_settings']['comment'] = array(
+    '#type' => 'radios',
+    '#parents' => array('comment'),
+    '#default_value' => $node->comment,
+    '#options' => array(t('Disabled'), t('Read only'), t('Read/Write')),
+  );
 }
 
 /**
=== modified file 'modules/forum/forum.module'
--- modules/forum/forum.module	
+++ modules/forum/forum.module	
@@ -214,24 +214,22 @@ function forum_admin_settings() {
 /**
  * Implementation of hook_form_alter().
  */
-function forum_form_alter($form_id, &$form) {
+function forum_form_alter_taxonomy_form_vocabulary($form_id, &$form) {
   // hide critical options from forum vocabulary
-  if ($form_id == 'taxonomy_form_vocabulary') {
-    if ($form['vid']['#value'] == _forum_get_vid()) {
-      $form['help_forum_vocab'] = array(
-        '#value' => t('This is the designated forum vocabulary. Some of the normal vocabulary options have been removed.'),
-        '#weight' => -1,
-      );
-      $form['nodes']['forum'] = array('#type' => 'checkbox', '#value' => 1, '#title' => t('forum topic'), '#attributes' => array('disabled' => '' ), '#description' => t('forum topic is affixed to the forum vocabulary.'));
-      $form['hierarchy'] = array('#type' => 'value', '#value' => 1);
-      unset($form['relations']);
-      unset($form['tags']);
-      unset($form['multiple']);
-      $form['required'] = array('#type' => 'value', '#value' => 1);
-    }
-    else {
-      unset($form['nodes']['forum']);
-    }
+  if ($form['vid']['#value'] == _forum_get_vid()) {
+    $form['help_forum_vocab'] = array(
+      '#value' => t('This is the designated forum vocabulary. Some of the normal vocabulary options have been removed.'),
+      '#weight' => -1,
+    );
+    $form['nodes']['forum'] = array('#type' => 'checkbox', '#value' => 1, '#title' => t('forum topic'), '#attributes' => array('disabled' => '' ), '#description' => t('forum topic is affixed to the forum vocabulary.'));
+    $form['hierarchy'] = array('#type' => 'value', '#value' => 1);
+    unset($form['relations']);
+    unset($form['tags']);
+    unset($form['multiple']);
+    $form['required'] = array('#type' => 'value', '#value' => 1);
+  }
+  else {
+    unset($form['nodes']['forum']);
   }
 }
 
=== modified file 'modules/menu/menu.module'
--- modules/menu/menu.module	
+++ modules/menu/menu.module	
@@ -186,78 +186,76 @@ function menu_perm() {
  * Implementation of hook_form_alter().
  * Add menu item fields to the node form.
  */
-function menu_form_alter($form_id, &$form) {
-  if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
-    $edit = isset($_POST['edit']) ? $_POST['edit'] : '';
-    $edit['nid'] = $form['nid']['#value'];
-
-    $item = array();
-    if ($edit['nid'] > 0) {
-      $item = db_fetch_array(db_query("SELECT * FROM {menu} WHERE path = 'node/%d'", $edit['nid']));
-      if (isset($edit['menu']) && is_array($edit['menu'])) {
-        $item = !is_array($item) ? $edit['menu'] : (($_POST['op'] == t('Preview')) ? array_merge($item, $edit['menu']) : array_merge($edit['menu'], $item));
-      }
+function menu_form_alter_node_form($form_id, &$form) {
+  $edit = isset($_POST['edit']) ? $_POST['edit'] : '';
+  $edit['nid'] = $form['nid']['#value'];
+
+  $item = array();
+  if ($edit['nid'] > 0) {
+    $item = db_fetch_array(db_query("SELECT * FROM {menu} WHERE path = 'node/%d'", $edit['nid']));
+    if (isset($edit['menu']) && is_array($edit['menu'])) {
+      $item = !is_array($item) ? $edit['menu'] : (($_POST['op'] == t('Preview')) ? array_merge($item, $edit['menu']) : array_merge($edit['menu'], $item));
     }
+  }
 
-    $form['menu'] = array('#type' => 'fieldset',
-      '#title' => t('Menu settings'),
-      '#access' => user_access('administer menu'),
-      '#collapsible' => TRUE,
-      '#collapsed' => empty($item['title']),
-      '#tree' => TRUE,
-      '#weight' => 30,
-    );
+  $form['menu'] = array('#type' => 'fieldset',
+    '#title' => t('Menu settings'),
+    '#access' => user_access('administer menu'),
+    '#collapsible' => TRUE,
+    '#collapsed' => empty($item['title']),
+    '#tree' => TRUE,
+    '#weight' => 30,
+  );
 
-    $form['menu']['title'] = array('#type' => 'textfield',
-      '#title' => t('Title'),
-      '#default_value' => $item['title'],
-      '#description' => t('The name to display for this link.'),
-    );
+  $form['menu']['title'] = array('#type' => 'textfield',
+    '#title' => t('Title'),
+    '#default_value' => $item['title'],
+    '#description' => t('The name to display for this link.'),
+  );
 
-    $form['menu']['description'] = array('#type' => 'textfield',
-      '#title' => t('Description'),
-      '#default_value' => $item['description'],
-      '#description' => t('The description displayed when hovering over a menu item.'),
-    );
+  $form['menu']['description'] = array('#type' => 'textfield',
+    '#title' => t('Description'),
+    '#default_value' => $item['description'],
+    '#description' => t('The description displayed when hovering over a menu item.'),
+  );
 
-    // Generate a list of possible parents.
-    $options = menu_parent_options($item['mid'], variable_get('menu_parent_items', 0));
+  // Generate a list of possible parents.
+  $options = menu_parent_options($item['mid'], variable_get('menu_parent_items', 0));
 
-    $form['menu']['pid'] = array('#type' => 'select',
-      '#title' => t('Parent item'),
-      '#default_value' => $item['pid'],
-      '#options' => $options,
-    );
+  $form['menu']['pid'] = array('#type' => 'select',
+    '#title' => t('Parent item'),
+    '#default_value' => $item['pid'],
+    '#options' => $options,
+  );
 
-    $form['menu']['path'] = array('#type' => 'hidden',
-      '#value' => $item['path'],
-    );
+  $form['menu']['path'] = array('#type' => 'hidden',
+    '#value' => $item['path'],
+  );
 
-    $form['menu']['weight'] = array('#type' => 'weight',
-      '#title' => t('Weight'),
-      '#default_value' => $item['weight'],
-      '#delta' => 10,
-      '#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
-    );
+  $form['menu']['weight'] = array('#type' => 'weight',
+    '#title' => t('Weight'),
+    '#default_value' => $item['weight'],
+    '#delta' => 10,
+    '#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
+  );
 
-    $form['menu']['mid'] = array('#type' => 'hidden',
-      '#value' => $item['mid'] ? $item['mid'] : 0,
-    );
+  $form['menu']['mid'] = array('#type' => 'hidden',
+    '#value' => $item['mid'] ? $item['mid'] : 0,
+  );
 
-    $form['menu']['type'] = array('#type' => 'hidden',
-      '#value' => $item['type'] ? $item['type'] : MENU_CUSTOM_ITEM,
+  $form['menu']['type'] = array('#type' => 'hidden',
+    '#value' => $item['type'] ? $item['type'] : MENU_CUSTOM_ITEM,
+  );
+
+  if ($item['mid'] > 0) {
+    $form['menu']['delete'] = array('#type' => 'checkbox',
+      '#title' => t('Check to delete this menu item.'),
+      '#default_value' => $item['delete'],
     );
 
-    if ($item['mid'] > 0) {
-      $form['menu']['delete'] = array('#type' => 'checkbox',
-        '#title' => t('Check to delete this menu item.'),
-        '#default_value' => $item['delete'],
-      );
-
-      $form['menu']['advanced'] = array('#type' => 'item',
-        '#value' => t('You may also <a href="@edit">edit the advanced settings</a> for this menu item.', array('@edit' => url("admin/build/menu/item/edit/{$item['mid']}"))),
-      );
-    }
+    $form['menu']['advanced'] = array('#type' => 'item',
+      '#value' => t('You may also <a href="@edit">edit the advanced settings</a> for this menu item.', array('@edit' => url("admin/build/menu/item/edit/{$item['mid']}"))),
+    );
   }
 }
 
=== modified file 'modules/node/node.module'
--- modules/node/node.module	
+++ modules/node/node.module	
@@ -2383,9 +2383,9 @@ function node_update_index() {
 /**
  * Implementation of hook_form_alter().
  */
-function node_form_alter($form_id, &$form) {
+function node_form_alter_search_form($form_id, &$form) {
   // Advanced node search form
-  if ($form_id == 'search_form' && arg(1) == 'node' && user_access('use advanced search')) {
+  if (arg(1) == 'node' && user_access('use advanced search')) {
     // Keyword boxes:
     $form['advanced'] = array(
       '#type' => 'fieldset',
=== modified file 'modules/path/path.module'
--- modules/path/path.module	
+++ modules/path/path.module	
@@ -255,30 +255,28 @@ function path_nodeapi(&$node, $op, $arg)
  * Implementation of hook_form_alter().
  */
 function path_form_alter($form_id, &$form) {
-  if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
-    $path = $form['#node']->path;
-    $form['path'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('URL path settings'),
-      '#collapsible' => TRUE,
-      '#collapsed' => empty($path),
-      '#access' => user_access('create url aliases'),
-      '#weight' => 30,
-    );
-    $form['path']['path'] = array(
-      '#type' => 'textfield',
-      '#default_value' => $path,
-      '#maxlength' => 250,
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-      '#description' => t('Optionally specify an alternative URL by which this node can be accessed. For example, type "about" when writing an about page. Use a relative path and don\'t add a trailing slash or the URL alias won\'t work.'),
+  $path = $form['#node']->path;
+  $form['path'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('URL path settings'),
+    '#collapsible' => TRUE,
+    '#collapsed' => empty($path),
+    '#access' => user_access('create url aliases'),
+    '#weight' => 30,
+  );
+  $form['path']['path'] = array(
+    '#type' => 'textfield',
+    '#default_value' => $path,
+    '#maxlength' => 250,
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('Optionally specify an alternative URL by which this node can be accessed. For example, type "about" when writing an about page. Use a relative path and don\'t add a trailing slash or the URL alias won\'t work.'),
+  );
+  if ($path) {
+    $form['path']['pid'] = array(
+      '#type' => 'value',
+      '#value' => db_result(db_query("SELECT pid FROM {url_alias} WHERE dst = '%s'", $path))
     );
-    if ($path) {
-      $form['path']['pid'] = array(
-        '#type' => 'value',
-        '#value' => db_result(db_query("SELECT pid FROM {url_alias} WHERE dst = '%s'", $path))
-      );
-    }
   }
 }
 
=== modified file 'modules/taxonomy/taxonomy.module'
--- modules/taxonomy/taxonomy.module	
+++ modules/taxonomy/taxonomy.module	
@@ -599,74 +599,72 @@ function taxonomy_get_vocabularies($type
 /**
  * Generate a form for selecting terms to associate with a node.
  */
-function taxonomy_form_alter($form_id, &$form) {
-  if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
-    $node = $form['#node'];
-
-    if (!isset($node->taxonomy)) {
-      if ($node->nid) {
-        $terms = taxonomy_node_get_terms($node->nid);
-      }
-      else {
-        $terms = array();
-      }
+function taxonomy_form_alter_node_form($form_id, &$form) {
+  $node = $form['#node'];
+
+  if (!isset($node->taxonomy)) {
+    if ($node->nid) {
+      $terms = taxonomy_node_get_terms($node->nid);
     }
     else {
-      $terms = $node->taxonomy;
+      $terms = array();
     }
+  }
+  else {
+    $terms = $node->taxonomy;
+  }
 
-    $c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node->type);
-
-    while ($vocabulary = db_fetch_object($c)) {
-      if ($vocabulary->tags) {
-        $typed_terms = array();
-        foreach ($terms as $term) {
-          // Extract terms belonging to the vocabulary in question.
-          if ($term->vid == $vocabulary->vid) {
+  $c = db_query(db_rewrite_sql("SELECT v.* FROM {vocabulary} v INNER JOIN {vocabulary_node_types} n ON v.vid = n.vid WHERE n.type = '%s' ORDER BY v.weight, v.name", 'v', 'vid'), $node->type);
 
-            // Commas and quotes in terms are special cases, so encode 'em.
-            if (preg_match('/,/', $term->name) || preg_match('/"/', $term->name)) {
-              $term->name = '"'.preg_replace('/"/', '""', $term->name).'"';
-            }
+  while ($vocabulary = db_fetch_object($c)) {
+    if ($vocabulary->tags) {
+      $typed_terms = array();
+      foreach ($terms as $term) {
+        // Extract terms belonging to the vocabulary in question.
+        if ($term->vid == $vocabulary->vid) {
 
-            $typed_terms[] = $term->name;
+          // Commas and quotes in terms are special cases, so encode 'em.
+          if (preg_match('/,/', $term->name) || preg_match('/"/', $term->name)) {
+            $term->name = '"'.preg_replace('/"/', '""', $term->name).'"';
           }
-        }
-        $typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);
 
-        if ($vocabulary->help) {
-          $help = $vocabulary->help;
+          $typed_terms[] = $term->name;
         }
-        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/'. $vocabulary->vid,
-          '#weight' => $vocabulary->weight,
-          '#maxlength' => 255,
-        );
+      }
+      $typed_string = implode(', ', $typed_terms) . (array_key_exists('tags', $terms) ? $terms['tags'][$vocabulary->vid] : NULL);
+
+      if ($vocabulary->help) {
+        $help = $vocabulary->help;
       }
       else {
-        // Extract terms belonging to the vocabulary in question.
-        $default_terms = array();
-        foreach ($terms as $term) {
-          if ($term->vid == $vocabulary->vid) {
-            $default_terms[$term->tid] = $term;
-          }
-        }
-        $form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, array_keys($default_terms), $vocabulary->help);
-        $form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight;
-        $form['taxonomy'][$vocabulary->vid]['#required'] = $vocabulary->required;
+        $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/'. $vocabulary->vid,
+        '#weight' => $vocabulary->weight,
+        '#maxlength' => 255,
+      );
     }
-    if (isset($form['taxonomy'])) {
-      $form['taxonomy'] += array('#type' => 'fieldset', '#title' => t('Categories'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#tree' => TRUE, '#weight' => -3);
+    else {
+      // Extract terms belonging to the vocabulary in question.
+      $default_terms = array();
+      foreach ($terms as $term) {
+        if ($term->vid == $vocabulary->vid) {
+          $default_terms[$term->tid] = $term;
+        }
+      }
+      $form['taxonomy'][$vocabulary->vid] = taxonomy_form($vocabulary->vid, array_keys($default_terms), $vocabulary->help);
+      $form['taxonomy'][$vocabulary->vid]['#weight'] = $vocabulary->weight;
+      $form['taxonomy'][$vocabulary->vid]['#required'] = $vocabulary->required;
     }
   }
+  if (isset($form['taxonomy'])) {
+    $form['taxonomy'] += array('#type' => 'fieldset', '#title' => t('Categories'), '#collapsible' => TRUE, '#collapsed' => FALSE, '#tree' => TRUE, '#weight' => -3);
+  }
 }
 
 /**
=== modified file 'modules/upload/upload.module'
--- modules/upload/upload.module	
+++ modules/upload/upload.module	
@@ -348,43 +348,41 @@ function _upload_prepare(&$node) {
   }
 }
 
-function upload_form_alter($form_id, &$form) {
-  if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
-    $form['workflow']['upload'] = array(
-      '#type' => 'radios',
-      '#title' => t('Attachments'),
-      '#default_value' => variable_get('upload_'. $form['identity']['type']['#default_value'], 1),
-      '#options' => array(t('Disabled'), t('Enabled')),
+function upload_form_alter_node_type_form($form_id, &$form) {
+  $form['workflow']['upload'] = array(
+    '#type' => 'radios',
+    '#title' => t('Attachments'),
+    '#default_value' => variable_get('upload_'. $form['identity']['type']['#default_value'], 1),
+    '#options' => array(t('Disabled'), t('Enabled')),
+  );
+}
+
+function upload_form_alter_node_type_form($form_id, &$form) {
+  $node = $form['#node'];
+  if (variable_get("upload_$node->type", TRUE)) {
+    drupal_add_js('misc/progress.js');
+    drupal_add_js('misc/upload.js');
+
+    // Attachments fieldset
+    $form['attachments'] = array(
+      '#type' => 'fieldset',
+      '#access' => user_access('upload files'),
+      '#title' => t('File attachments'),
+      '#collapsible' => TRUE,
+      '#collapsed' => empty($node->files),
+      '#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
+      '#prefix' => '<div class="attachments">',
+      '#suffix' => '</div>',
+      '#weight' => 30,
     );
-  }
 
-  if (isset($form['type'])) {
-    $node = $form['#node'];
-    if ($form['type']['#value'] .'_node_form' == $form_id && variable_get("upload_$node->type", TRUE)) {
-      drupal_add_js('misc/progress.js');
-      drupal_add_js('misc/upload.js');
-
-      // Attachments fieldset
-      $form['attachments'] = array(
-        '#type' => 'fieldset',
-        '#access' => user_access('upload files'),
-        '#title' => t('File attachments'),
-        '#collapsible' => TRUE,
-        '#collapsed' => empty($node->files),
-        '#description' => t('Changes made to the attachments are not permanent until you save this post. The first "listed" file will be included in RSS feeds.'),
-        '#prefix' => '<div class="attachments">',
-        '#suffix' => '</div>',
-        '#weight' => 30,
-      );
-
-      // Wrapper for fieldset contents (used by upload JS).
-      $form['attachments']['wrapper'] = array(
-        '#prefix' => '<div id="attach-wrapper">',
-        '#suffix' => '</div>',
-      );
-      $form['attachments']['wrapper'] += _upload_form($node);
-      $form['#attributes']['enctype'] = 'multipart/form-data';
-    }
+    // Wrapper for fieldset contents (used by upload JS).
+    $form['attachments']['wrapper'] = array(
+      '#prefix' => '<div id="attach-wrapper">',
+      '#suffix' => '</div>',
+    );
+    $form['attachments']['wrapper'] += _upload_form($node);
+    $form['#attributes']['enctype'] = 'multipart/form-data';
   }
 }
 
