Index: pathauto.inc
===================================================================
--- pathauto.inc	(revision 51)
+++ pathauto.inc	(working copy)
@@ -74,9 +74,11 @@
  * 
  * @param string $src
  *   A string that is the internal path
+ * @param $update_action
+ *   The most relevant update action mode (0,1,2,3) for the given item 
  * 
  */
-function _pathauto_existing_alias_data ($src) {
+function _pathauto_existing_alias_data($src, $update_action) {
   $output = array(
     'pid' => '',
     'old_alias' => ''
@@ -84,8 +86,9 @@
   $result = db_query("SELECT pid, dst FROM {url_alias} WHERE src='%s'", $src);
   if ($data = db_fetch_object($result)) {
     // The item is already aliased, check what to do...
-    switch (variable_get('pathauto_update_action', 2)) {
+    switch ($update_action) {
       // Replace old alias - remember the pid to update
+      case 0:
       case 2:
       case 3:
         $output['pid'] = $data->pid;
@@ -94,7 +97,6 @@
         $output['old_alias'] = $data->dst;
         break;
       // Do nothing
-      case 0:
       default:
         break;
     }
@@ -103,6 +105,42 @@
 }
 
 /**
+ * Determine the most relevant update action mode (0,1,2,3) for a given item
+ *
+ * @param $module
+ *   The name of the module (e.g., 'node')
+ * @param $type
+ *   For modules which provided patternitems in hook_pathauto(),
+ *   the relevant identifier for the specific item to be aliased (e.g.,
+ *   $node->type)
+ * @param $debug
+ *   Should verbose debugging be displayed
+ * @return
+ *   The most relevant update action mode (0,1,2,3) for the given item
+ */
+function _pathauto_update_action($module, $type = NULL, $debug) {
+  $update_action = 'default';
+  if ($type) {
+    $update_variable = 'pathauto_'. $module .'_'. $type .'_update_action';
+    $update_action = variable_get($update_variable, 'default');
+    $debug_output = t('Pathauto update_action=%update_action based on "%update_variable"', array('%update_action' => $update_action, '%update_variable' => $update_variable));
+  }
+  if ($update_action == 'default') {
+    $update_variable = 'pathauto_'. $module .'_update_action';
+    $update_action = variable_get($update_variable, 'default');
+    $debug_output = t('Pathauto update_action=%update_action based on "%update_variable"', array('%update_action' => $update_action, '%update_variable' => $update_variable));
+  }
+  if ($update_action == 'default') {
+    $update_action = variable_get('pathauto_update_action', 2);
+    $debug_output = '';
+  }
+  if ($debug) {
+    drupal_set_message($debug_output);
+  }
+  return $update_action;
+}
+
+/**
  * Clean up a string value provided by a module, resulting in a
  * string containing only alphanumerics and separators
  * @param $string
@@ -240,14 +278,25 @@
   if (!trim($pattern)) {
     return '';
   }
+  
+  // Let's only show update action mode debugging when pathauto_update_action_debug set
+  if ($verbose && variable_get('pathauto_update_action_debug', FALSE)) {
+    $update_debug = TRUE;
+  }
+  else {
+    $update_debug = FALSE;
+  }
+  
+  // Set the most relevant update action mode for this item
+  $update_action = _pathauto_update_action($module, $type, $update_debug);
 
   if ($module == 'taxonomy') {
     // Get proper path for term.
     $term_path = taxonomy_term_path(taxonomy_get_term($entity_id));
     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);
+      $update_data = _pathauto_existing_alias_data($src, $update_action);
+      _pathauto_set_alias($src, $term_path, $module, $entity_id, $update_data['pid'], FALSE, $update_data['old_alias'], $language, $update_action);
       // Set $src as proper path.
       $src = $term_path;
     }
@@ -257,13 +306,24 @@
   $pid = NULL;
   $old_alias = NULL;
   if ($op == 'update' or $op == 'bulkupdate') {
-    if (variable_get('pathauto_update_action', 2) == 0) {
+    // Let's gather any exiting alias information
+    $update_data = _pathauto_existing_alias_data($src, $update_action);
+    $pid = $update_data['pid'];
+    $old_alias = $update_data['old_alias'];
+    // Special case for update action mode 0 for 'nodes' that have an exiting alias.  The only
+    // way we make it here is if the user has specifically asked for a new automatic alias to be made.
+    // In which case we replace the old one.
+    if ($module == 'node' && $op == 'update' && $update_action == '0' && !empty($pid)) {
+      $update_action = 2;
+      if ($update_debug) {
+        drupal_set_message(t('Pathauto update_action=2 now, due to user request for new automatic alias'));
+      }
+    }
+    // Otherwise if we are in update action mode 0 and there is already an alias for this item, we return.
+    if ($update_action == 0 && !empty($pid)) {
       // Do nothing
       return '';
     }
-    $update_data = _pathauto_existing_alias_data($src);
-    $pid = $update_data['pid'];
-    $old_alias = $update_data['old_alias'];
   }
 
   // Replace the placeholders with the values provided by the module,
@@ -295,7 +355,7 @@
 
   // 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);
+  _pathauto_set_alias($src, $alias, $module, $entity_id, $pid, $verbose, $old_alias, $language, $update_action);
 
   // Also create a related feed alias if requested, and if supported
   // by the module
@@ -304,12 +364,12 @@
     
     // 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);
+      $update_data = _pathauto_existing_alias_data("taxonomy/term/$entity_id/$feedappend", $update_action); 
+      _pathauto_set_alias("taxonomy/term/$entity_id/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias'], $language, $update_action);
     }
     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);
+      $update_data = _pathauto_existing_alias_data("$src/$feedappend", $update_action);
+      _pathauto_set_alias("$src/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias'], $language, $update_action);
     }
   }
 
@@ -349,8 +409,10 @@
  *   If the item is currently aliased, the existing alias for that item.
  * @param $language
  *   The path's language.
+ * @param $update_action
+ *   The relevant update action mode (0,1,2,3) for this item
  */
-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, $pid = NULL, $verbose = FALSE, $old_alias = NULL, $language = '', $update_action) {
   // Alert users that an existing callback cannot be overridden automatically
   if (_pathauto_path_is_callback($dst)) {
     if ($verbose and user_access('notify of path changes')) {
@@ -370,7 +432,7 @@
   if ($old_alias != $dst) {
     path_set_alias($src, $dst, $pid, $language);
 
-    if (variable_get('pathauto_update_action', 2) == 3 && function_exists('path_redirect_save')) {
+    if ( $update_action == 3 && function_exists('path_redirect_save')) {
       if (isset($old_alias) && strlen($old_alias)) {
         $save['path'] = $old_alias;
         $save['redirect'] = $src;
Index: pathauto.js
===================================================================
--- pathauto.js	(revision 17)
+++ pathauto.js	(working copy)
@@ -2,21 +2,18 @@
 if (Drupal.jsEnabled) {
   $(document).ready(function() {
     if ($("#edit-pathauto-perform-alias").size() && $("#edit-pathauto-perform-alias").attr("checked")) {
-      // Disable input and hide its description.
-      $("#edit-path").attr("disabled","disabled");
-      $("#edit-path-wrapper > div.description").hide(0);
+      // Auto-alias is checked so manual path input is hidden
+      $("#edit-path-wrapper").hide(0);
     }
     $("#edit-pathauto-perform-alias").bind("click", function() {
       if ($("#edit-pathauto-perform-alias").attr("checked")) {
-        // Auto-alias checked; disable input.
-        $("#edit-path").attr("disabled","disabled");
-        $("#edit-path-wrapper > div[@class=description]").slideUp('fast');
+        // Auto-alias has been checked; let's hide manual path input.
+        $("#edit-path-wrapper").slideUp('fast');
       }
       else {
-        // Auto-alias unchecked; enable input.
-        $("#edit-path").removeAttr("disabled");
+        // Auto-alias has been unchecked; Let's reveal manual path input and give it focus.
+        $("#edit-path-wrapper").slideDown('fast');
         $("#edit-path")[0].focus();
-        $("#edit-path-wrapper > div[@class=description]").slideDown('fast');
       }
     });
   });
Index: pathauto.module
===================================================================
--- pathauto.module	(revision 51)
+++ pathauto.module	(working copy)
@@ -145,7 +145,7 @@
   $form["general"]["pathauto_update_action"] = array('#type' => 'radios',
     '#title' => t('Update action'), '#default_value' => variable_get('pathauto_update_action', 2),
     '#options' => $actions,
-    '#description' => t('What should pathauto do when updating an existing content item which already has an alias?'));
+    '#description' => t('What should pathauto do when updating an existing item which already has an alias?'));
 
   $disable_transliteration = TRUE;
   $disable_text = "";
@@ -589,6 +589,12 @@
         }
         // Only do work if there's a pattern
         if ($pattern) {
+          // Return on the special case of no checkbox and update_action=0 (don't update) w/ an existing alias
+          if (!isset($node->pathauto_perform_alias)
+              && _pathauto_update_action('node', $node->type, FALSE) == 0
+              && !empty($node->path)) {
+            break;
+          }
           // Only create an alias if the checkbox was not provided or if the checkbox was provided and is checked
           if (!isset($node->pathauto_perform_alias) || $node->pathauto_perform_alias) {
             $placeholders = pathauto_get_placeholders('node', $node);
@@ -624,19 +630,49 @@
     }
     // If there is a pattern AND the user is allowed to create aliases AND the path textbox is present on this form
     if ($pattern && user_access('create url aliases') && isset($form['path']['path'])) {
-      $output = t('An alias will be generated for you. If you wish to create your own alias below, untick this option.');
+      
+      // Let's gather the most relavate update action mode for this node type in case an alias exists already
+      $update_action = _pathauto_update_action('node', $form['type']['#value'], FALSE);
+      
+      // If update_action = 0 (don't change) and there is an existing alias
+      // then we untick "Automatic alias", otherwise it's ticked.
+      if ( $update_action == 0 && !empty($form['path']['path']['#default_value'])) {
+        $automatic_alias = FALSE;
+        $output = t('<em>A URL path alias already exists for this content as shown below.</em> You may edit this URL path alias directly if desired, or tick the option above to have a new URL path alias automatically generated that will <em>replace</em> the existing entry.');
+      }
+      else {
+        $automatic_alias = TRUE;
+        if (empty($form['path']['path']['#default_value'])) {
+          $output = t('This option will automatically generate a URL path alias for this content.  If you wish to manually create your own URL path alias, untick this option and enter it below.');
+        }
+        else {
+          $output = t('<em>A URL path alias already exists for this content.</em> ');
+          switch ($update_action) {
+            case 1:
+              $output .= t('If this option is ticked, a new URL path alias may be created in <em>addition to</em> the exiting alias.  If unticked, you will have manual control of the existing URL path alias below.');
+              break;
+            case 2:
+              $output .= t('If this option is ticked, a new URL path alias may be created that will <em>replace</em> the exiting alias.  If unticked, you will have manual control of the existing URL path alias below.');
+              break;
+            case 3:
+              $output .= t('If this option is ticked, a new URL path alias may be created that will <em>replace</em> the exiting alias and a <em>redirect<em> will be created from the old alias. If unticked, you will have manual control of the existing URL path alias below.');
+              break;  
+          }
+        }
+      }
+      
       if (user_access('administer pathauto')) {
-        $output .= t(' To control the format of the generated aliases, see the <a href="@pathauto">Pathauto settings</a>.', array('@pathauto' => url('admin/settings/pathauto')));
+        $output .= t(' To control the format of the automatically generated URL path aliases, see the <a href="@pathauto">Pathauto settings</a>.', array('@pathauto' => url('admin/settings/pathauto')));
       }
 
       drupal_add_js(drupal_get_path('module', 'pathauto') .'/pathauto.js');
       $form['path']['#collapsed'] = FALSE;
 
       $form['path']['pathauto_perform_alias'] = array('#type' => 'checkbox',
-        '#title' => t('Automatic alias'),
-        '#default_value' => TRUE,
+        '#title' => t('Automatic URL alias'),
+        '#default_value' => $automatic_alias,
         '#description' => $output,
-        '#weight' => 0
+        '#weight' => -10
       );
 
       //For Pathauto to remember the old alias and prevent the Path-module from deleteing it when Pathauto wants to preserve it
Index: README.txt
===================================================================
--- README.txt	(revision 32)
+++ README.txt	(working copy)
@@ -54,6 +54,49 @@
 used. But if the default pattern is also blank, Pathauto will be disabled 
 for that node type.
 
+** Creating more specific "alias update" actions
+When Pathauto is asked to alias an item that already has an existing alias, it must make a decision on what to do with this existing alias.  Currently there is *one* global setting for this behavior in the Pathauto admin.  It's in the "General Settings" section and is labeled "Update action".
+
+However, more specific control is available by setting additional system variables by hand. For example you can tell Pathauto to not overwrite existing aliases to "page" type nodes, but to always replace "story" type nodes aliases with updated ones.
+
+The current "global default" update action variable, as set in the Pathauto admin, is named 'pathauto_update_action' and must have a value of 0,1,2 or 3 (if Path redirect is installed). These numbers correspond to the following:
+
+0 - Do nothing. Leave the old alias intact.
+1 - Create a new alias. Leave the existing alias functioning.
+2 - Create a new alias. Delete the old alias.
+3 - Create a new alias. Redirect from old alias. (w/ Path Redirect)
+
+However, Pathauto will look for other additional variables,  with the following naming schema, in the following order. The first found will be used:
+
+1. pathauto_*module*_*type*_update_action = (default,0,1,2,3)
+2. pathauto_*module*_update_action = (default,0,1,2,3)
+3. pathauto_update_action = (0,1,2,3)
+
+*module* is the name of the module Pathauto is working with (ie. node, user, etc)
+
+*type* is a more specific item from *module* that can have its own path construction settings. (ie. "page" and "story" are two default *types* for the node *module*)
+
+Values 0,1,2 and 3 have the same actions as listed above. The "default" value is a 'non-value' placeholder for a forthcoming administration patch. Thus it won't really be used when setting variables by hand.
+
+Thus, as an example, if the following variables are set:
+
+pathauto_update_action = 2 (replace)
+pathauto_node_update_action = 1 (add alias)
+pathauto_node_page_update_action = 0 (leave alone)
+pathauto_node_story_update_action = 3 (new with redirect)
+
+We would have the following behavior:
+
+-> "story" type nodes would have existing aliases replaced with new ones and redirects created from the old aliases.
+-> "page" type nodes would have existing aliases "left alone".
+-> All other node types would have aliases "added" to the existing ones.
+-> All other items would have aliases "replaced" with new ones.
+
+To see additional debugging information for update action settings you can set "pathauto_update_action_debug" = 1 and enable "Verbose" in the Pathauto admin.
+
+A forthcoming patch will be made available that implements an administration section for functionality into the Pathauto admin.  When available the URL will be included here.
+
+
 ** Bulk Updates Must be Run Multiple Times:
 As of 5.x-2.x Pathauto now performs bulk updates in a manner which is more 
 likely to succeed on large sites.  The drawback is that it needs to be run 
@@ -75,6 +118,8 @@
 
 Matt England added the tracker support.
 
+James Pooton added support for creating more specific "alias update" actions
+
 Other suggestions and patches contributed by the Drupal community.
 
 Current maintainer: Greg Knaddison (greg AT knaddison DOT com)
