--- pathauto.inc.orig	2009-02-17 12:42:58.000000000 +0100
+++ pathauto.inc	2009-02-24 11:15:33.000000000 +0100
@@ -82,31 +82,31 @@
 }
 
 /**
- * Returns old alias and pid if there is already an alias
- * pointing to a different item.
+ * Returns old aliases and pids if there are already aliases for this path.
  *
  * @param $src
  *   A string that is the internal path.
  * @return
- *   An array with the keys "pid" and "old_alias" containing
- *   the "pid" and old "alias", respectively, of the old alias.
+ *   An array with the keys "pids" and "old_aliases" containing
+ *   the pids and pathes, respectively, of all old aliases.
  */
 function _pathauto_existing_alias_data($src) {
   $output = array(
-    'pid' => '',
-    'old_alias' => ''
+    'pids' => array(),
+    'old_aliases' => array()
   );
   $result = db_query("SELECT pid, dst FROM {url_alias} WHERE src='%s'", $src);
-  if ($data = db_fetch_object($result)) {
+  while ($data = db_fetch_object($result)) {
     // The item is already aliased, check what to do...
     switch (variable_get('pathauto_update_action', 2)) {
-      // Replace old alias - remember the pid to update
+      // Replace old alias - remember the pids to update/remove
       case 2:
       case 3:
-        $output['pid'] = $data->pid;
+        $output['pids'][] = $data->pid;
       // Add new alias in addition to old one
       case 1:
-        $output['old_alias'] = $data->dst;
+        // Collect all existing aliases.
+        $output['old_aliases'][] = $data->dst;
         break;
       // Do nothing
       case 0:
@@ -265,23 +265,23 @@
     if ($term_path != $src) {
       // Quietly alias 'taxonomy/term/[tid]' with proper path for term.
       $update_data = _pathauto_existing_alias_data($src);
-      _pathauto_set_alias($src, $term_path, $module, $entity_id, $update_data['pid'], FALSE, $update_data['old_alias'], $language);
+      _pathauto_set_alias($src, $term_path, $module, $entity_id, $update_data['pids'], FALSE, $update_data['old_aliases'], $language);
       // Set $src as proper path.
       $src = $term_path;
     }
   }
 
   // Special handling when updating an item which is already aliased.
-  $pid = NULL;
-  $old_alias = NULL;
+  $pids = array();
+  $old_aliases = array();
   if ($op == 'update' or $op == 'bulkupdate') {
     if (variable_get('pathauto_update_action', 2) == 0) {
       // Do nothing
       return '';
     }
     $update_data = _pathauto_existing_alias_data($src);
-    $pid = $update_data['pid'];
-    $old_alias = $update_data['old_alias'];
+    $pids = $update_data['pids'];
+    $old_aliases = $update_data['old_aliases'];
   }
 
   // Replace the placeholders with the values provided by the module,
@@ -317,9 +317,9 @@
     }
   }
 
-  // If $pid is NULL, a new alias is created - otherwise, the existing
-  // alias for the designated src is replaced
-  _pathauto_set_alias($src, $alias, $module, $entity_id, $pid, $verbose, $old_alias, $language);
+  // If $pids is array(), a new alias is created - otherwise, existings
+  // aliases for the designated src are replaced
+  _pathauto_set_alias($src, $alias, $module, $entity_id, $pids, $verbose, $old_aliases, $language);
 
   // Also create a related feed alias if requested, and if supported
   // by the module
@@ -329,11 +329,11 @@
     // For forums and taxonomies, the src doesn't always form the base of the rss feed (ie. image galleries)
     if ($module == 'taxonomy' || $module == 'forum') {
       $update_data = _pathauto_existing_alias_data("taxonomy/term/$entity_id/$feedappend");
-      _pathauto_set_alias("taxonomy/term/$entity_id/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias'], $language);
+      _pathauto_set_alias("taxonomy/term/$entity_id/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pids'], $verbose, $update_data['old_aliases'], $language);
     }
     else {
       $update_data = _pathauto_existing_alias_data("$src/$feedappend");
-      _pathauto_set_alias("$src/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias'], $language);
+      _pathauto_set_alias("$src/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pids'], $verbose, $update_data['old_aliases'], $language);
     }
   }
 
@@ -365,16 +365,18 @@
  *   The internal path.
  * @param $dst
  *   The visible externally used path.
- * @param $pid
- *   If the item is currently aliased, the pid for that item.
+ * @param $pids
+ *   If the item is currently aliased, a single pid or an array of pids for that item
+ *   several aliases exist.
  * @param $verbose
  *   If the admin has enabled verbose, should be TRUE. Else FALSE or NULL.
- * @param $old_alias
- *   If the item is currently aliased, the existing alias for that item.
+ * @param $old_aliases
+ *   If the item is currently aliased, one or an array of all existing aliases
+ *   aliases for that item.
  * @param $language
  *   The path's language.
  */
-function _pathauto_set_alias($src, $dst, $entity_type, $entity_id, $pid = NULL, $verbose = FALSE, $old_alias = NULL, $language = '') {
+function _pathauto_set_alias($src, $dst, $entity_type, $entity_id, $pids = array(), $verbose = FALSE, $old_aliases = array(), $language = '') {
   // Alert users that an existing callback cannot be overridden automatically
   if (_pathauto_path_is_callback($dst)) {
     if ($verbose && user_access('notify of path changes')) {
@@ -389,13 +391,29 @@
     }
     return;
   }
+  // Backwards compability if users pass only one pid or one old_alias
+  if (is_numeric($pids)) $pids = array($pids);
+  if (is_string($old_aliases)) $old_aliases = array($old_aliases);
 
   // Skip replacing the current alias with an identical alias
-  if ($old_alias != $dst) {
-    path_set_alias($src, $dst, $pid, $language);
+  $key = array_search($dst, $old_aliases);
+  if ($key === FALSE) path_set_alias($src, $dst, NULL, $language);
 
-    if (variable_get('pathauto_update_action', 2) == 3 && function_exists('path_redirect_save')) {
-      if (!empty($old_alias)) {
+  if (variable_get('pathauto_update_action', 2) == 2) {
+    // Remove all existing aliases, only keep the same as the new one.
+    foreach ($old_aliases as $old_key => $old_alias) {
+      if ($key !== $old_key) {
+        path_set_alias(NULL, NULL, $pids[$old_key]);
+        $deleted = TRUE;
+      }
+    }
+  }
+
+  // Remove existing paths and create redirections for them.
+  if (variable_get('pathauto_update_action', 2) == 3 && function_exists('path_redirect_save')) {
+    foreach ($old_aliases as $old_key => $old_alias) {
+      if ($key !== $old_key) {
+        path_set_alias(NULL, NULL, $pids[$old_key]);
         $save['path'] = $old_alias;
         $save['redirect'] = $src;
         $save['type'] = 301; //moved permanently
@@ -403,15 +421,20 @@
         $redirect = TRUE;
       }
     }
-    if ($verbose && user_access('notify of path changes')) {
-      if (!empty($redirect)) {
-        drupal_set_message(t('Created new alias %dst for %src, replacing %old_alias. %old_alias now redirects to %dst', array('%dst' => $dst, '%src' => $src, '%old_alias' => $old_alias)));
-      }
-      elseif ($pid) {
-        drupal_set_message(t('Created new alias %dst for %src, replacing %old_alias', array('%dst' => $dst, '%src' => $src, '%old_alias' => $old_alias)));
-      }
-      else {
-        drupal_set_message(t('Created new alias %dst for %src', array('%dst' => $dst, '%src' => $src)));
+  }
+
+  if ($verbose && user_access('notify of path changes')) {
+    if ($key === FALSE) drupal_set_message(t("Created new alias %dst for %src", array('%dst' => $dst, '%src' => $src)));
+    
+    if ($old_aliases) {
+      foreach ($old_aliases as $old_key => $old_alias) {
+        if ($key === $old_key) continue; // This alias has has not been altered.
+        if (!empty($redirect)) {
+          drupal_set_message(t('Existing alias %old_alias for %src now redirects to %dst', array('%dst' => $dst, '%src' => $src, '%old_alias' => $old_alias)));
+        }
+        elseif (!empty($deleted)) {
+          drupal_set_message(t('Existing alias %old_alias for %src has been removed', array('%src' => $src, '%old_alias' => $old_alias)));
+        }
       }
     }
   }
