Index: INSTALL.txt
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/INSTALL.txt,v
retrieving revision 1.4
diff -u -p -r1.4 INSTALL.txt
--- INSTALL.txt	24 Jun 2008 11:20:36 -0000	1.4
+++ INSTALL.txt	10 Nov 2009 00:24:09 -0000
@@ -22,8 +22,8 @@ replacement of Á with A) then you will 
 module, which can be found at http://drupal.org/project/transliteration
 
 Once you've installed and enabled the module, simply go to
-admin/build/path/pathauto and check the "Transliterate prior to creating alias"
-box and path aliases should now be transliterated automagically.
+admin/config/search/path/pathauto and check the "Transliterate prior to
+creating alias" box and path aliases should now be transliterated automagically.
 
 **Upgrading from previous versions:
 If you are upgrading from Pathauto 5.x-1.x to 5.x-2.x (or 6.x-2.x) then you 
Index: pathauto.admin.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.admin.inc,v
retrieving revision 1.20
diff -u -p -r1.20 pathauto.admin.inc
--- pathauto.admin.inc	13 Sep 2008 08:54:06 -0000	1.20
+++ pathauto.admin.inc	10 Nov 2009 00:24:09 -0000
@@ -14,15 +14,9 @@
  * @ingroup forms
  * @see system_settings_form()
  */
-function pathauto_admin_settings() {
+function pathauto_admin_settings($form) {
   _pathauto_include();
 
-  // Make sure they have token
-  if (!function_exists('token_get_list')) {
-    drupal_set_message(t('It appears that the <a href="@token_link">Token module</a> is not installed. Please ensure that you have it installed so that Pathauto can work properly. You may need to disable Pathauto and re-enable it to get Token enabled.', array('@token_link' => 'http://drupal.org/project/token')), 'error');
-    return;
-  }
-
   // Default words to ignore
   $ignore_words = array(
     'a', 'an', 'as', 'at', 'before', 'but', 'by', 'for', 'from', 'is', 'in',
@@ -122,7 +116,7 @@ function pathauto_admin_settings() {
   $transliteration_help = t('When a pattern includes certain characters (such as those with accents) should Pathauto attempt to transliterate them into the ASCII-96 alphabet? Transliteration is handled by the Transliteration module.');
   if (!module_exists('transliteration')) {
     $disable_transliteration = TRUE;
-    $transliteration_help .= ' <strong>'. t("This option is disabled on your site because the Transliteration module either isn't installed, or isn't installed properly.") .'</strong>';
+    $transliteration_help .= ' <strong>' . t("This option is disabled on your site because the Transliteration module either isn't installed, or isn't installed properly.") . '</strong>';
     // Make sure we don't try to use Transliteration if it isn't available
     variable_set('pathauto_transliterate', FALSE);
   }
@@ -160,10 +154,10 @@ function pathauto_admin_settings() {
 
   $punctuation = pathauto_punctuation_chars();
   foreach ($punctuation as $name => $details) {
-    $form['punctuation']['pathauto_punctuation_'. $name ] = array(
+    $form['punctuation']['pathauto_punctuation_' . $name ] = array(
       '#type' => 'select',
       '#title' => $details['name'],
-      '#default_value' => variable_get('pathauto_punctuation_'. $name, PATHAUTO_PUNCTUATION_REMOVE),
+      '#default_value' => variable_get('pathauto_punctuation_' . $name, PATHAUTO_PUNCTUATION_REMOVE),
       '#options' => array(
         PATHAUTO_PUNCTUATION_REMOVE => t('Remove'),
         PATHAUTO_PUNCTUATION_REPLACE => t('Replace by separator'),
@@ -184,7 +178,7 @@ function pathauto_admin_settings() {
     $patterndefault = $settings->patterndefault;
     $groupheader = $settings->groupheader;
     $supportsfeeds = isset($settings->supportsfeeds) ? $settings->supportsfeeds : NULL;
-    variable_set('pathauto_'. $module .'_supportsfeeds', $supportsfeeds);
+    variable_set('pathauto_' . $module . '_supportsfeeds', $supportsfeeds);
 
     $form[$module] = array(
       '#type' => 'fieldset',
@@ -196,7 +190,7 @@ function pathauto_admin_settings() {
     $group_weight++;
 
     // Prompt for the default pattern for this module
-    $variable = 'pathauto_'. $module .'_pattern';
+    $variable = 'pathauto_' . $module . '_pattern';
     $description = '';
     if (!count($_POST)) {
       $error = _pathauto_check_pattern(variable_get($variable, $patterndefault), $settings->token_type);
@@ -218,7 +212,7 @@ function pathauto_admin_settings() {
     // them up here
     if (isset($settings->patternitems)) {
       foreach ($settings->patternitems as $itemname => $itemlabel) {
-        $variable = 'pathauto_'. $module .'_'. $itemname .'_pattern';
+        $variable = 'pathauto_' . $module . '_' . $itemname . '_pattern';
         $description = '';
         if (!count($_POST)) {
           $error = _pathauto_check_pattern(variable_get($variable, $patterndefault), $settings->token_type);
@@ -240,9 +234,9 @@ function pathauto_admin_settings() {
     // Display the user documentation of placeholders supported by
     // this module, as a description on the last pattern
     $doc = "<dl>\n";
-    foreach ($settings->placeholders as $name => $description) {
-      $doc .= '<dt>'. $name .'</dt>';
-      $doc .= '<dd>'. $description .'</dd>';
+    foreach ($settings->tokens as $name => $description) {
+      $doc .= '<dt>' . $name . '</dt>';
+      $doc .= '<dd>' . $description . '</dd>';
     }
     $doc .= "</dl>\n";
     $form[$module]['token_help'] = array(
@@ -250,18 +244,17 @@ function pathauto_admin_settings() {
       '#type' => 'fieldset',
       '#collapsible' => TRUE,
       '#collapsed' => TRUE,
-      '#description' => t('Use -raw replacements for text to avoid problems with HTML entities.'),
     );
     $form[$module]['token_help']['help'] = array(
-      '#value' => $doc,
+      '#markup' => $doc,
     );
 
     // If the module supports bulk updates, offer the update action here
     if ($settings->bulkname) {
-      $variable = 'pathauto_'. $module .'_bulkupdate';
+      $variable = 'pathauto_' . $module . '_bulkupdate';
       if (variable_get($variable, FALSE)) {
         variable_set($variable, FALSE);
-        $function = $module .'_pathauto_bulkupdate';
+        $function = $module . '_pathauto_bulkupdate';
         call_user_func($function);
       }
       $form[$module][$variable] = array(
@@ -274,7 +267,7 @@ function pathauto_admin_settings() {
 
     // If the module supports feeds, offer to generate aliases for them
     if ($supportsfeeds) {
-      $variable = 'pathauto_'. $module .'_applytofeeds';
+      $variable = 'pathauto_' . $module . '_applytofeeds';
       $current = variable_get($variable, $supportsfeeds);
       // This checks for the old style from 2.0 and earlier. TODO: At some point we can drop that.
       if (is_numeric($current)) {
@@ -308,8 +301,7 @@ function pathauto_admin_settings() {
 /**
  * Helper function for pathauto_admin_settings().
  *
- * See if they are using all -raw tokens available
- * and if all the tokens are valid in the given context.
+ * See if all the tokens are valid in the given context.
  *
  * @param $pattern
  *   A string containing the pattern to be tested.
@@ -322,40 +314,25 @@ function pathauto_admin_settings() {
  */
 function _pathauto_check_pattern($pattern, $type) {
   // Hold items we've warned about so we only warn once per token
-  static $warned;
+  $warned = &drupal_static(__FUNCTION__);
   $return = FALSE;
 
   // Build up a set of all tokens in a format that's easy to search
-  $all_tokens = array();
-  $tokens = token_get_list($type);
-  foreach ($tokens as $actual_tokens) {
-    foreach (array_keys($actual_tokens) as $token) {
-      $all_tokens[$token] = $token;
-    }
-  }
+  $tokens = token_info();
+  $tokens = $tokens['tokens'][$type];
 
   // Now, search the pattern and evaluate its contents.
   $matches = array();
   if (preg_match_all('/\[[a-zA-z_\-]+?\]/i', $pattern, $matches)) {
     // Loop over each found token.
     foreach ($matches[0] as $id => $token) {
-      $token = str_replace('[', '', str_replace(']', '', $token));
+      $test = str_replace('[', '', str_replace(']', '', $token));
+      $test = drupal_substr($test, strpos($test, $type . ':'));
       // Check if the token is even valid in this context.
-      if (!array_key_exists($token, $all_tokens)) {
-        drupal_set_message(t('You are using the token [%token] which is not valid within the scope of tokens where you are using it.', array('%token' => $token)), 'error');
+      if (!array_key_exists($test, $tokens)) {
+        drupal_set_message(t('You are using the token [%token] which is not valid within the scope of tokens where you are using it.', array('%token' => $type . ':' . $test)), 'error');
         $return[] = $token;
       }
-      // Check if there is a raw companion that they should be using.
-      elseif (!preg_match('/\-raw/i', $token)) {
-        $raw_token = $token .'-raw';
-        if (array_key_exists($raw_token, $all_tokens)) {
-          if (!isset($warned) || !array_key_exists($token, $warned)) {
-            drupal_set_message(t('You are using the token [%token] which has a -raw companion available [%raw_token]. For Pathauto patterns you should use the -raw version of tokens unless you really know what you are doing. See the <a href="@pathauto-help">Pathauto help</a> for more details.', array('%token' => $token, '%raw_token' => $raw_token, '@pathauto-help' => url('admin/help/pathauto'))), 'error');
-            $warned[$token] = $token;
-          }
-          $return[] = $token;
-        }
-      }
     }
   }
 
@@ -381,7 +358,7 @@ function pathauto_admin_settings_validat
   $punctuation = pathauto_punctuation_chars();
   foreach ($punctuation as $name => $details) {
     if ($details['value'] == $separator) {
-      $action = $form_state['values']['pathauto_punctuation_'. $name];
+      $action = $form_state['values']['pathauto_punctuation_' . $name];
       if ($action == PATHAUTO_PUNCTUATION_REMOVE) {
         drupal_set_message(t('You have configured the @name to be the separator and to be removed when encountered in strings. This can cause problems with your patterns and especially with the catpath and termpath patterns. You should probably set the action for @name to be "replace by separator".', array('@name' => $details['name'])), 'error');
       }
@@ -392,7 +369,7 @@ function pathauto_admin_settings_validat
 /**
  * Menu callback; select certain alias types to delete.
  */
-function pathauto_admin_delete() {
+function pathauto_admin_delete($form) {
   /* TODO:
    1) all - DONE
    2) all node aliases - DONE
@@ -405,7 +382,6 @@ function pathauto_admin_delete() {
    10) where dst like 'pattern' - DON'T DO
   */
 
-  $form = array();
   $form['delete'] = array(
     '#type' => 'fieldset',
     '#title' => t('Choose aliases to delete'),
@@ -414,7 +390,7 @@ function pathauto_admin_delete() {
   );
 
   // First we do the "all" case
-  $total_count = db_result(db_query('SELECT count(1) FROM {url_alias}'));
+  $total_count = db_query('SELECT count(1) FROM {url_alias}')->fetchField();
   $form['delete']['all_aliases'] = array(
     '#type' => 'checkbox',
     '#title' => t('All aliases'),
@@ -425,7 +401,7 @@ function pathauto_admin_delete() {
   // Next, iterate over an array of objects/alias types which can be deleted and provide checkboxes
   $objects = module_invoke_all('path_alias_types');
   foreach ($objects as $internal_name => $label) {
-    $count = db_result(db_query("SELECT count(1) FROM {url_alias} WHERE src LIKE '%s%%'", $internal_name));
+    $count = db_query("SELECT count(1) FROM {url_alias} WHERE source LIKE :src", array(':src' => "$internal_name%"))->fetchField();
     $form['delete'][$internal_name] = array(
       '#type' => 'checkbox',
       '#title' => $label, // This label is sent through t() in the hard coded function where it is defined
@@ -435,7 +411,7 @@ function pathauto_admin_delete() {
   }
 
   // Warn them and give a button that shows we mean business
-  $form['warning'] = array('#value' => '<p>'. t('<strong>Note:</strong> there is no confirmation. Be sure of your action before clicking the "Delete aliases now!" button.<br />You may want to make a backup of the database and/or the url_alias table prior to using this feature.') .'</p>');
+  $form['warning'] = array('#value' => '<p>' . t('<strong>Note:</strong> there is no confirmation. Be sure of your action before clicking the "Delete aliases now!" button.<br />You may want to make a backup of the database and/or the url_alias table prior to using this feature.') . '</p>');
   $form['buttons']['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Delete aliases now!'),
@@ -456,12 +432,12 @@ function pathauto_admin_delete_submit($f
       }
       $objects = module_invoke_all('path_alias_types');
       if (array_key_exists($key, $objects)) {
-        db_query("DELETE FROM {url_alias} WHERE src LIKE '%s%%'", $key);
+        db_query("DELETE FROM {url_alias} WHERE source LIKE :src", array(':src' => "$key%"));
         drupal_set_message(t('All of your %type path aliases have been deleted.', array('%type' => $objects[$key])));
       }
     }
   }
-  $form_state['redirect'] = 'admin/build/path/delete_bulk';
+  $form_state['redirect'] = 'admin/config/search/path/delete_bulk';
 }
 
 /**
@@ -486,6 +462,6 @@ function _pathauto_warn_wysiwygs() {
     }
   }
   if ($wysiwyg_problem) {
-    return '<strong> '. t('You appear to be using a "WYSIWYG" editor which can cause problems if that editor runs on the Pathauto administrative settings page. Please be sure to disable these editors for all text boxes on this page. See the "WYSIWYG Conflicts" section of the README.txt file for more information.') .'</strong>';
+    return '<strong> ' . t('You appear to be using a "WYSIWYG" editor which can cause problems if that editor runs on the Pathauto administrative settings page. Please be sure to disable these editors for all text boxes on this page. See the "WYSIWYG Conflicts" section of the README.txt file for more information.') . '</strong>';
   }
 }
Index: pathauto.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.inc,v
retrieving revision 1.54
diff -u -p -r1.54 pathauto.inc
--- pathauto.inc	22 Oct 2009 00:11:35 -0000	1.54
+++ pathauto.inc	10 Nov 2009 00:24:09 -0000
@@ -75,54 +75,54 @@ define('PATHAUTO_PUNCTUATION_DO_NOTHING'
  * Copied from search.module's PREG_CLASS_SEARCH_EXCLUDE.
  */
 define('PREG_CLASS_ALNUM',
-'\x{0}-\x{2f}\x{3a}-\x{40}\x{5b}-\x{60}\x{7b}-\x{bf}\x{d7}\x{f7}\x{2b0}-'.
-'\x{385}\x{387}\x{3f6}\x{482}-\x{489}\x{559}-\x{55f}\x{589}-\x{5c7}\x{5f3}-'.
-'\x{61f}\x{640}\x{64b}-\x{65e}\x{66a}-\x{66d}\x{670}\x{6d4}\x{6d6}-\x{6ed}'.
-'\x{6fd}\x{6fe}\x{700}-\x{70f}\x{711}\x{730}-\x{74a}\x{7a6}-\x{7b0}\x{901}-'.
-'\x{903}\x{93c}\x{93e}-\x{94d}\x{951}-\x{954}\x{962}-\x{965}\x{970}\x{981}-'.
-'\x{983}\x{9bc}\x{9be}-\x{9cd}\x{9d7}\x{9e2}\x{9e3}\x{9f2}-\x{a03}\x{a3c}-'.
-'\x{a4d}\x{a70}\x{a71}\x{a81}-\x{a83}\x{abc}\x{abe}-\x{acd}\x{ae2}\x{ae3}'.
-'\x{af1}-\x{b03}\x{b3c}\x{b3e}-\x{b57}\x{b70}\x{b82}\x{bbe}-\x{bd7}\x{bf0}-'.
-'\x{c03}\x{c3e}-\x{c56}\x{c82}\x{c83}\x{cbc}\x{cbe}-\x{cd6}\x{d02}\x{d03}'.
-'\x{d3e}-\x{d57}\x{d82}\x{d83}\x{dca}-\x{df4}\x{e31}\x{e34}-\x{e3f}\x{e46}-'.
-'\x{e4f}\x{e5a}\x{e5b}\x{eb1}\x{eb4}-\x{ebc}\x{ec6}-\x{ecd}\x{f01}-\x{f1f}'.
-'\x{f2a}-\x{f3f}\x{f71}-\x{f87}\x{f90}-\x{fd1}\x{102c}-\x{1039}\x{104a}-'.
-'\x{104f}\x{1056}-\x{1059}\x{10fb}\x{10fc}\x{135f}-\x{137c}\x{1390}-\x{1399}'.
-'\x{166d}\x{166e}\x{1680}\x{169b}\x{169c}\x{16eb}-\x{16f0}\x{1712}-\x{1714}'.
-'\x{1732}-\x{1736}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17db}\x{17dd}'.
-'\x{17f0}-\x{180e}\x{1843}\x{18a9}\x{1920}-\x{1945}\x{19b0}-\x{19c0}\x{19c8}'.
-'\x{19c9}\x{19de}-\x{19ff}\x{1a17}-\x{1a1f}\x{1d2c}-\x{1d61}\x{1d78}\x{1d9b}-'.
-'\x{1dc3}\x{1fbd}\x{1fbf}-\x{1fc1}\x{1fcd}-\x{1fcf}\x{1fdd}-\x{1fdf}\x{1fed}-'.
-'\x{1fef}\x{1ffd}-\x{2070}\x{2074}-\x{207e}\x{2080}-\x{2101}\x{2103}-\x{2106}'.
-'\x{2108}\x{2109}\x{2114}\x{2116}-\x{2118}\x{211e}-\x{2123}\x{2125}\x{2127}'.
-'\x{2129}\x{212e}\x{2132}\x{213a}\x{213b}\x{2140}-\x{2144}\x{214a}-\x{2b13}'.
-'\x{2ce5}-\x{2cff}\x{2d6f}\x{2e00}-\x{3005}\x{3007}-\x{303b}\x{303d}-\x{303f}'.
-'\x{3099}-\x{309e}\x{30a0}\x{30fb}-\x{30fe}\x{3190}-\x{319f}\x{31c0}-\x{31cf}'.
-'\x{3200}-\x{33ff}\x{4dc0}-\x{4dff}\x{a015}\x{a490}-\x{a716}\x{a802}\x{a806}'.
-'\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}\x{fd3f}'.
-'\x{fdfc}-\x{fe6b}\x{feff}-\x{ff0f}\x{ff1a}-\x{ff20}\x{ff3b}-\x{ff40}\x{ff5b}-'.
+'\x{0}-\x{2f}\x{3a}-\x{40}\x{5b}-\x{60}\x{7b}-\x{bf}\x{d7}\x{f7}\x{2b0}-' .
+'\x{385}\x{387}\x{3f6}\x{482}-\x{489}\x{559}-\x{55f}\x{589}-\x{5c7}\x{5f3}-' .
+'\x{61f}\x{640}\x{64b}-\x{65e}\x{66a}-\x{66d}\x{670}\x{6d4}\x{6d6}-\x{6ed}' .
+'\x{6fd}\x{6fe}\x{700}-\x{70f}\x{711}\x{730}-\x{74a}\x{7a6}-\x{7b0}\x{901}-' .
+'\x{903}\x{93c}\x{93e}-\x{94d}\x{951}-\x{954}\x{962}-\x{965}\x{970}\x{981}-' .
+'\x{983}\x{9bc}\x{9be}-\x{9cd}\x{9d7}\x{9e2}\x{9e3}\x{9f2}-\x{a03}\x{a3c}-' .
+'\x{a4d}\x{a70}\x{a71}\x{a81}-\x{a83}\x{abc}\x{abe}-\x{acd}\x{ae2}\x{ae3}' .
+'\x{af1}-\x{b03}\x{b3c}\x{b3e}-\x{b57}\x{b70}\x{b82}\x{bbe}-\x{bd7}\x{bf0}-' .
+'\x{c03}\x{c3e}-\x{c56}\x{c82}\x{c83}\x{cbc}\x{cbe}-\x{cd6}\x{d02}\x{d03}' .
+'\x{d3e}-\x{d57}\x{d82}\x{d83}\x{dca}-\x{df4}\x{e31}\x{e34}-\x{e3f}\x{e46}-' .
+'\x{e4f}\x{e5a}\x{e5b}\x{eb1}\x{eb4}-\x{ebc}\x{ec6}-\x{ecd}\x{f01}-\x{f1f}' .
+'\x{f2a}-\x{f3f}\x{f71}-\x{f87}\x{f90}-\x{fd1}\x{102c}-\x{1039}\x{104a}-' .
+'\x{104f}\x{1056}-\x{1059}\x{10fb}\x{10fc}\x{135f}-\x{137c}\x{1390}-\x{1399}' .
+'\x{166d}\x{166e}\x{1680}\x{169b}\x{169c}\x{16eb}-\x{16f0}\x{1712}-\x{1714}' .
+'\x{1732}-\x{1736}\x{1752}\x{1753}\x{1772}\x{1773}\x{17b4}-\x{17db}\x{17dd}' .
+'\x{17f0}-\x{180e}\x{1843}\x{18a9}\x{1920}-\x{1945}\x{19b0}-\x{19c0}\x{19c8}' .
+'\x{19c9}\x{19de}-\x{19ff}\x{1a17}-\x{1a1f}\x{1d2c}-\x{1d61}\x{1d78}\x{1d9b}-' .
+'\x{1dc3}\x{1fbd}\x{1fbf}-\x{1fc1}\x{1fcd}-\x{1fcf}\x{1fdd}-\x{1fdf}\x{1fed}-' .
+'\x{1fef}\x{1ffd}-\x{2070}\x{2074}-\x{207e}\x{2080}-\x{2101}\x{2103}-\x{2106}' .
+'\x{2108}\x{2109}\x{2114}\x{2116}-\x{2118}\x{211e}-\x{2123}\x{2125}\x{2127}' .
+'\x{2129}\x{212e}\x{2132}\x{213a}\x{213b}\x{2140}-\x{2144}\x{214a}-\x{2b13}' .
+'\x{2ce5}-\x{2cff}\x{2d6f}\x{2e00}-\x{3005}\x{3007}-\x{303b}\x{303d}-\x{303f}' .
+'\x{3099}-\x{309e}\x{30a0}\x{30fb}-\x{30fe}\x{3190}-\x{319f}\x{31c0}-\x{31cf}' .
+'\x{3200}-\x{33ff}\x{4dc0}-\x{4dff}\x{a015}\x{a490}-\x{a716}\x{a802}\x{a806}' .
+'\x{a80b}\x{a823}-\x{a82b}\x{d800}-\x{f8ff}\x{fb1e}\x{fb29}\x{fd3e}\x{fd3f}' .
+'\x{fdfc}-\x{fe6b}\x{feff}-\x{ff0f}\x{ff1a}-\x{ff20}\x{ff3b}-\x{ff40}\x{ff5b}-' .
 '\x{ff65}\x{ff70}\x{ff9e}\x{ff9f}\x{ffe0}-\x{fffd}');
 
 /**
  * Check to see if there is already an alias pointing to a different item.
  *
  * @param $alias
- *   A string alias (i.e. dst).
- * @param $src
+ *   A string alias.
+ * @param $source
  *   A string that is the internal path.
  * @param $language
  *   A string indicating the path's language.
  * @return
  *   TRUE if an alias exists, FALSE if not.
  */
-function _pathauto_alias_exists($alias, $src, $language = '') {
-  $alias_pid = db_result(db_query_range("SELECT pid FROM {url_alias} WHERE dst = '%s' AND src <> '%s' AND language = '%s'", array($alias, $src, $language), 0, 1));
+function _pathauto_alias_exists($alias, $source, $language = '') {
+  $alias_pid = db_query_range("SELECT pid FROM {url_alias} WHERE alias = :alias AND source <> :source AND language = :lang", 0, 1, array(':alias' => $alias, ':source' => $source, ':lang' => $language))->fetchColumn();
   if (function_exists('path_redirect_delete')) {
     // Delete from path_redirect the exact same alias to the same node.
-    path_redirect_delete(array('path' => $alias, 'redirect' => $src));
+    path_redirect_delete(array('path' => $alias, 'redirect' => $source));
 
     // If there still is this alias used in path_redirect, then create a different alias
-    $redirect_rid = db_result(db_query_range("SELECT rid FROM {path_redirect} WHERE path = '%s'", $alias, 0, 1));
+    $redirect_rid = db_query_range("SELECT rid FROM {path_redirect} WHERE path = :path", 0, 1, array(':path' => $alias))->fetchColumn();
   }
   if ($alias_pid || !empty($redirect_rid)) {
     return TRUE;
@@ -142,13 +142,13 @@ function _pathauto_alias_exists($alias, 
  *   An array with the keys "pid" and "old_alias" containing
  *   the "pid" and old "alias", respectively, of the old alias.
  */
-function _pathauto_existing_alias_data($src) {
+function _pathauto_existing_alias_data($source) {
   $output = array(
     'pid' => '',
     'old_alias' => ''
   );
-  $result = db_query("SELECT pid, dst FROM {url_alias} WHERE src='%s'", $src);
-  if ($data = db_fetch_object($result)) {
+  $result = db_query("SELECT pid, alias FROM {url_alias} WHERE source = :source", array(':source' => $source));
+  if ($data = $result->fetchObject()) {
     // The item is already aliased, check what to do...
     switch (variable_get('pathauto_update_action', PATHAUTO_UPDATE_ACTION_DELETE)) {
       // Replace old alias - remember the pid to update
@@ -157,7 +157,7 @@ function _pathauto_existing_alias_data($
         $output['pid'] = $data->pid;
       // Add new alias in addition to old one
       case PATHAUTO_UPDATE_ACTION_LEAVE:
-        $output['old_alias'] = $data->dst;
+        $output['old_alias'] = $data->alias;
         break;
       // Do nothing
       case PATHAUTO_UPDATE_ACTION_NO_NEW:
@@ -193,7 +193,7 @@ function pathauto_cleanstring($string, $
   $output = $string;
   $punctuation = pathauto_punctuation_chars();
   foreach ($punctuation as $name => $details) {
-    $action = variable_get('pathauto_punctuation_'. $name, PATHAUTO_PUNCTUATION_REMOVE);
+    $action = variable_get('pathauto_punctuation_' . $name, PATHAUTO_PUNCTUATION_REMOVE);
     if ($action != PATHAUTO_PUNCTUATION_DO_NOTHING) {
       // Slightly tricky inline if which either replaces with the separator or nothing
       $output = str_replace($details['value'], ($action ? $separator : ''), $output);
@@ -222,7 +222,7 @@ function pathauto_cleanstring($string, $
   }
 
   // Get rid of words that are on the ignore list
-  $ignore_re = '\b'. preg_replace('/,/', '\b|\b', variable_get('pathauto_ignore_words', $ignore_words)) .'\b';
+  $ignore_re = '\b' . preg_replace('/,/', '\b|\b', variable_get('pathauto_ignore_words', $ignore_words)) . '\b';
 
   if (function_exists('mb_eregi_replace')) {
     $output = mb_eregi_replace($ignore_re, '', $output);
@@ -237,11 +237,11 @@ function pathauto_cleanstring($string, $
   // In preparation for pattern matching,
   // escape the separator if and only if it is not alphanumeric.
   if (isset($separator)) {
-    if (preg_match('/^[^'. PREG_CLASS_ALNUM .']+$/uD', $separator)) {
+    if (preg_match('/^[^' . PREG_CLASS_ALNUM . ']+$/uD', $separator)) {
       $seppattern = $separator;
     }
     else {
-      $seppattern = '\\'. $separator;
+      $seppattern = '\\' . $separator;
     }
     // Trim any leading or trailing separators.
     $output = preg_replace("/^$seppattern+|$seppattern+$/", '', $output);
@@ -273,22 +273,22 @@ function pathauto_cleanstring($string, $
  * @param $op
  *   Operation being performed on the content being aliased
  *   ('insert', 'update', 'return', or 'bulkupdate').
- * @param $placeholders
- *   An array whose keys consist of the translated placeholders
- *   which appear in patterns (e.g., t('[title]')) and values are the
- *   actual values to be substituted into the pattern (e.g., $node->title).
- * @param $src
+ * @param $source
  *   The "real" URI of the content to be aliased (e.g., "node/$node->nid").
+ * @param $data
+ *   An associative array of objects needed to apply the alias' pattern, keyed
+ *   by their type.  Example: array('term' => $term, 'vocabulary' => $vocabulary).
  * @param $type
  *   For modules which provided pattern items in hook_pathauto(),
  *   the relevant identifier for the specific item to be aliased
  *   (e.g., $node->type).
  * @param $language
  *   A string specify the path's language.
+ *
  * @return
  *   The alias that was created.
  */
-function pathauto_create_alias($module, $op, $placeholders, $src, $entity_id, $type = NULL, $language = '') {
+function pathauto_create_alias($module, $op, $source, $data, $type = NULL, $language = '') {
   if (($op != 'bulkupdate') and variable_get('pathauto_verbose', FALSE) && user_access('notify of path changes')) {
     $verbose = TRUE;
   }
@@ -298,28 +298,28 @@ function pathauto_create_alias($module, 
 
   // Retrieve and apply the pattern for this content type
   if (!empty($type)) {
-    $pattern = trim(variable_get('pathauto_'. $module .'_'. $type .'_'. $language .'_pattern', ''));
+    $pattern = trim(variable_get('pathauto_' . $module . '_' . $type . '_' . $language . '_pattern', ''));
     if (empty($pattern)) {
-      $pattern = trim(variable_get('pathauto_'. $module .'_'. $type .'_pattern', ''));
+      $pattern = trim(variable_get('pathauto_' . $module . '_' . $type . '_pattern', ''));
     }
   }
   if (empty($pattern)) {
-    $pattern = trim(variable_get('pathauto_'. $module .'_pattern', ''));
+    $pattern = trim(variable_get('pathauto_' . $module . '_pattern', ''));
   }
   // No pattern? Do nothing (otherwise we may blow away existing aliases...)
   if (empty($pattern)) {
     return '';
   }
 
-  if ($module == 'taxonomy') {
+  if ($module == 'taxonomy' && isset($data['term'])) {
     // Get proper path for term.
-    $term_path = taxonomy_term_path(taxonomy_get_term($entity_id));
-    if ($term_path != $src) {
+    $term_path = 'taxonomy/term/' . $data['term']->tid;
+    if ($term_path != $source) {
       // 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($source);
+      _pathauto_set_alias($source, $term_path, $update_data['pid'], FALSE, $update_data['old_alias'], $language);
       // Set $src as proper path.
-      $src = $term_path;
+      $source = $term_path;
     }
   }
 
@@ -331,13 +331,13 @@ function pathauto_create_alias($module, 
       // Do nothing
       return '';
     }
-    $update_data = _pathauto_existing_alias_data($src);
+    $update_data = _pathauto_existing_alias_data($source);
     $pid = $update_data['pid'];
     $old_alias = $update_data['old_alias'];
   }
 
-  // Replace the placeholders with the values provided by the module.
-  $alias = str_replace($placeholders['tokens'], $placeholders['values'], $pattern);
+  // Replace any tokens in the pattern.  Uses callback option to clean replacements. No sanitization.
+  $alias = token_replace($pattern, $data, array('sanitize' => FALSE, 'callback' => 'pathauto_clean_token_values', 'language' => (object)array('language' => $language)));
 
   // Two or more slashes should be collapsed into one
   $alias = preg_replace('/\/+/', '/', $alias);
@@ -353,9 +353,9 @@ function pathauto_create_alias($module, 
   $alias = _pathauto_truncate_chars($alias, $maxlength, $separator);
 
   // If the alias already exists, generate a new, hopefully unique, variant
-  if (_pathauto_alias_exists($alias, $src, $language)) {
+  if (_pathauto_alias_exists($alias, $source, $language)) {
     $original_alias = $alias;
-    for ($i = 0; _pathauto_alias_exists(drupal_substr($alias, 0, $maxlength - strlen($i)) . $separator . $i, $src, $language); $i++) {
+    for ($i = 0; _pathauto_alias_exists(drupal_substr($alias, 0, $maxlength - drupal_strlen($i)) . $separator . $i, $source, $language); $i++) {
     }
     // Make room for the sequence number
     $alias = drupal_substr($alias, 0, $maxlength - drupal_strlen($i));
@@ -374,21 +374,22 @@ function pathauto_create_alias($module, 
 
   // 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($source, $alias, $pid, $verbose, $old_alias, $language);
 
   // Also create a related feed alias if requested, and if supported
   // by the module
-  if (drupal_strlen(variable_get('pathauto_'. $module .'_applytofeeds', ''))) {
-    $feedappend = variable_get('pathauto_'. $module .'_applytofeeds', '');
+  if (drupal_strlen(variable_get('pathauto_' . $module . '_applytofeeds', ''))) {
+    $feedappend = variable_get('pathauto_' . $module . '_applytofeeds', '');
 
     // 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);
+    if (($module == 'taxonomy' || $module == 'forum') && isset($data['term'])) {
+      $tid = $data['term']->tid;
+      $update_data = _pathauto_existing_alias_data("taxonomy/term/$tid/$feedappend");
+      _pathauto_set_alias("taxonomy/term/$tid/$feedappend", "$alias/feed", $update_data['pid'], $verbose, $update_data['old_alias'], $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);
+      $update_data = _pathauto_existing_alias_data("$source/$feedappend");
+      _pathauto_set_alias("$source/$feedappend", "$alias/feed", $update_data['pid'], $verbose, $update_data['old_alias'], $language);
     }
   }
 
@@ -416,9 +417,9 @@ function _pathauto_path_is_callback($pat
 /**
  * Private function for Pathauto to create an alias.
  *
- * @param $src
+ * @param $source
  *   The internal path.
- * @param $dst
+ * @param $alias
  *   The visible externally used path.
  * @param $pid
  *   If the item is currently aliased, the pid for that item.
@@ -429,90 +430,71 @@ function _pathauto_path_is_callback($pat
  * @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($source, $alias, $pid = NULL, $verbose = FALSE, $old_alias = NULL, $language = '') {
   // Alert users that an existing callback cannot be overridden automatically
-  if (_pathauto_path_is_callback($dst)) {
+  if (_pathauto_path_is_callback($alias)) {
     if ($verbose && user_access('notify of path changes')) {
-      drupal_set_message(t('Ignoring alias %dst due to existing path conflict.', array('%dst' => $dst)));
+      drupal_set_message(t('Ignoring alias %alias due to existing path conflict.', array('%alias' => $alias)));
     }
     return;
   }
   // Alert users if they are trying to create an alias that is the same as the internal path
-  if ($src == $dst) {
+  if ($source == $alias) {
     if ($verbose && user_access('notify of path changes')) {
-      drupal_set_message(t('Ignoring alias %dst because it is the same as the internal path.', array('%dst' => $dst)));
+      drupal_set_message(t('Ignoring alias %alias because it is the same as the internal path.', array('%alias' => $alias)));
     }
     return;
   }
 
   // Skip replacing the current alias with an identical alias
-  if ($old_alias != $dst) {
-    path_set_alias($src, $dst, $pid, $language);
+  if ($old_alias != $alias) {
+    $path = array('source' => $source, 'alias' => $alias, 'pid' => $pid, 'language' => $language);
+    path_save($path);
 
     if (variable_get('pathauto_update_action', PATHAUTO_UPDATE_ACTION_DELETE) == PATHAUTO_UPDATE_ACTION_REDIRECT
         && function_exists('path_redirect_save')) {
       if (!empty($old_alias)) {
         $redirect = array(
           'path' => $old_alias,
-          'redirect' => $src,
+          'redirect' => $source,
         );
         path_redirect_save($redirect);
       }
     }
     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)));
+        drupal_set_message(t('Created new alias %alias for %source, replacing %old_alias. %old_alias now redirects to %alias.', array('%alias' => $alias, '%source' => $source, '%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)));
+        drupal_set_message(t('Created new alias %alias for %source, replacing %old_alias.', array('%alias' => $alias, '%source' => $source, '%old_alias' => $old_alias)));
       }
       else {
-        drupal_set_message(t('Created new alias %dst for %src.', array('%dst' => $dst, '%src' => $src)));
+        drupal_set_message(t('Created new alias %alias for %source.', array('%alias' => $alias, '%source' => $source)));
       }
     }
   }
 }
 
 /**
- * Generalized function to get tokens across all Pathauto types.
- *
- * @param $object
- *   A user, node, or category object.
- * @return
- *   Tokens for that object formatted in the way that
- *   Pathauto expects to see them.
- */
-function pathauto_get_placeholders($type, $object) {
-  if (function_exists('token_get_values')) {
-    $full = token_get_values($type, $object, TRUE);
-    $tokens = token_prepare_tokens($full->tokens);
-    $values = pathauto_clean_token_values($full);
-    return array('tokens' => $tokens, 'values' => $values);
-  }
-  // TODO at some point try removing this and see if install profiles have problems again.
-  watchdog('Pathauto', 'It appears that you have installed Pathauto, which depends on Token, but Token is either not installed or not installed properly.');
-  return array('tokens' => array(), 'values' => array());
-}
-
-/**
  * Clean tokens so they are URL friendly.
  *
- * @param $full
- *   An array of token values that need to be "cleaned" for use in the URL.
- * @return
- *   An array of the cleaned tokens.
+ * @param $replacements
+ *   An array of token replacements that need to be "cleaned" for use in the URL.
+ * @param $data
+ *   An array of objects used to generate the replacements.
+ * @param $options
+ *   An array of options used to generate the replacements.
  */
-function pathauto_clean_token_values($full) {
-  foreach ($full->values as $key => $value) {
+function pathauto_clean_token_values(&$replacements, $data = array(), $options = array()) {
+  foreach ($replacements as $token => $value) {
     // If it's a "path" or "url friendly" token don't remove the "/" character
-    if (drupal_substr($full->tokens[$key], -4, 4) === 'path' || drupal_substr($full->tokens[$key], -8, 8) === 'path-raw' || drupal_substr($full->tokens[$key], -5, 5) === 'alias') {
-      $full->values[$key] = pathauto_cleanstring($value, FALSE);
+    if (drupal_substr($token, -5, 4) === 'path' || drupal_substr($token, -6, 5) === 'alias') {
+      $replacements[$token] = pathauto_cleanstring($value, FALSE);
     }
     else {
-      $full->values[$key] = pathauto_cleanstring($value);
+      $replacements[$token] = pathauto_cleanstring($value);
     }
   }
-  return $full->values;
 }
 
 /**
@@ -582,7 +564,7 @@ function _pathauto_truncate_chars($strin
   if (drupal_strlen($string) > $length) {
     $string = drupal_substr($string, 0, $length + 1); // leave one more character
     if ($last_break = strrpos($string, $separator)) { // space exists AND is not on position 0
-      $string = substr($string, 0, $last_break);
+      $string = drupal_substr($string, 0, $last_break);
     }
     else {
       $string = drupal_substr($string, 0, $length);
Index: pathauto.info
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.info,v
retrieving revision 1.5
diff -u -p -r1.5 pathauto.info
--- pathauto.info	21 Mar 2009 00:24:28 -0000	1.5
+++ pathauto.info	10 Nov 2009 00:24:09 -0000
@@ -2,6 +2,14 @@
 name = Pathauto
 description = Provides a mechanism for modules to automatically generate aliases for the content they manage.
 dependencies[] = path
-dependencies[] = token
 suggests[] = path_redirect
-core = 6.x
+core = 7.x
+
+files[] = pathauto.admin.inc
+files[] = pathauto.inc
+files[] = pathauto.module
+files[] = pathauto_node.inc
+files[] = pathauto_taxonomy.inc
+files[] = pathauto_user.inc
+files[] = pathauto.install
+files[] = tests/pathauto.test
Index: pathauto.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.install,v
retrieving revision 1.14
diff -u -p -r1.14 pathauto.install
--- pathauto.install	17 Oct 2009 17:36:58 -0000	1.14
+++ pathauto.install	10 Nov 2009 00:24:09 -0000
@@ -9,14 +9,14 @@
  */
 
 /**
- * Implementation of hook_install().
+ * Implement hook_install().
  */
 function pathauto_install() {
   // Check to see if taxonomy module is enabled before we set those variables
   if (module_exists('taxonomy')) {
     variable_set('pathauto_modulelist', array('node', 'user', 'taxonomy'));
     variable_set('pathauto_taxonomy_supportsfeeds', '0/feed');
-    variable_set('pathauto_taxonomy_pattern', 'category/[vocab-raw]/[catpath-raw]');
+    variable_set('pathauto_taxonomy_pattern', 'category/[vocabulary:name]/[term:catpath]');
     variable_set('pathauto_taxonomy_bulkupdate', FALSE);
     variable_set('pathauto_taxonomy_applytofeeds', FALSE);
     variable_set('pathauto_taxonomy_2_pattern', '');
@@ -36,13 +36,13 @@ function pathauto_install() {
   variable_set('pathauto_node_forum_pattern', '');
   variable_set('pathauto_node_image_pattern', '');
   variable_set('pathauto_node_page_pattern', '');
-  variable_set('pathauto_node_pattern', 'content/[title-raw]');
+  variable_set('pathauto_node_pattern', 'content/[node:title]');
   variable_set('pathauto_node_story_pattern', '');
   variable_set('pathauto_punctuation_quotes', 0);
   variable_set('pathauto_separator', '-');
   variable_set('pathauto_update_action', '2');
   variable_set('pathauto_user_bulkupdate', FALSE);
-  variable_set('pathauto_user_pattern', 'users/[user-raw]');
+  variable_set('pathauto_user_pattern', 'users/[user:name]');
   variable_set('pathauto_user_supportsfeeds', NULL);
   variable_set('pathauto_verbose', FALSE);
   variable_set('pathauto_node_applytofeeds', '');
@@ -58,7 +58,7 @@ function pathauto_install() {
 }
 
 /**
- * Implementation of hook_uninstall().
+ * Implement hook_uninstall().
  */
 function pathauto_uninstall() {
   // Delete all the pathauto variables and then clear the variable cache
Index: pathauto.js
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.js,v
retrieving revision 1.5
diff -u -p -r1.5 pathauto.js
--- pathauto.js	18 Apr 2009 17:09:15 -0000	1.5
+++ pathauto.js	10 Nov 2009 00:24:09 -0000
@@ -1,23 +1,30 @@
 // $Id: pathauto.js,v 1.5 2009/04/18 17:09:15 freso Exp $
-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);
-    }
-    $("#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');
-      }
-      else {
-        // Auto-alias unchecked; enable input.
-        $("#edit-path").removeAttr("disabled");
-        $("#edit-path")[0].focus();
-        $("#edit-path-wrapper > div[class=description]").slideDown('fast');
+(function ($) {
+
+Drupal.behaviors.pathauto = {
+  attach: function(context, settings) {
+    $("#edit-path-pathauto-perform-alias", context).once("pathauto", function () {
+      var path_input = $("#edit-path-alias", context);
+      if ($(this, context).size() && $(this, context).attr("checked")) {
+        // Disable input and hide its description.
+        path_input.attr("disabled", "disabled");
+        path_input.parent().find("div.description", context).hide(0);
       }
+      $(this, context).bind("click", function() {
+        if ($(this, context).attr("checked")) {
+          // Auto-alias checked; disable input.
+          path_input.attr("disabled", "disabled");
+          path_input.parent().find("div.description", context).slideUp('fast');
+        }
+        else {
+          // Auto-alias unchecked; enable input.
+          path_input.removeAttr("disabled");
+          path_input[0].focus();
+          path_input.parent().find("div.description", context).slideDown('fast');
+        }
+      });
     });
-  });
-}
+  }
+};
+
+})(jQuery);
Index: pathauto.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto.module,v
retrieving revision 1.126
diff -u -p -r1.126 pathauto.module
--- pathauto.module	17 Oct 2009 17:45:10 -0000	1.126
+++ pathauto.module	10 Nov 2009 00:24:09 -0000
@@ -19,31 +19,39 @@
  */
 
 /**
- * Implementation of hook_help().
+ * Implement hook_help().
  */
 function pathauto_help($path, $arg) {
   switch ($path) {
     case 'admin/help#pathauto':
-      $output = '<p>'. t('Provides a mechanism for modules to automatically generate aliases for the content they manage.') .'</p>';
-      $output .= '<h2>'. t('Settings') .'</h2>';
-      $output .= '<p>'. t('The <strong>maximum alias length</strong> and <strong>maximum component length</strong> values default to 100 and have a limit of 128 from Pathauto. This length is limited by the length of the "dst" column of the url_alias database table. The default database schema for this column is 128. If you set a length that is equal to that of the one set in the "dst" column it will cause problems in situations where the system needs to append additional words to the aliased URL. For example, URLs generated for feeds will have "/feed" added to the end. You should enter a value that is the length of the "dst" column minus the length of any strings that might get added to the end of the URL. The length of strings that might get added to the end of your URLs depends on which modules you have enabled and on your Pathauto settings. The recommended and default value is 100.') .'</p>';
-      $output .= '<p>'. t('<strong>Raw tokens</strong>: In Pathauto it is appropriate to use the -raw form of tokens. Paths are sent through a filtering system which ensures that raw user content is filtered. Failure to use -raw tokens can cause problems with the Pathauto punctuation filtering system.') .'</p>';
+      $output = '<p>' . t('Provides a mechanism for modules to automatically generate aliases for the content they manage.') . '</p>';
+      $output .= '<h2>' . t('Settings') . '</h2>';
+      $output .= '<p>' . t('The <strong>maximum alias length</strong> and <strong>maximum component length</strong> values default to 100 and have a limit of 128 from Pathauto. This length is limited by the length of the "alias" column of the url_alias database table. The default database schema for this column is 128. If you set a length that is equal to that of the one set in the "alias" column it will cause problems in situations where the system needs to append additional words to the aliased URL. For example, URLs generated for feeds will have "/feed" added to the end. You should enter a value that is the length of the "alias" column minus the length of any strings that might get added to the end of the URL. The length of strings that might get added to the end of your URLs depends on which modules you have enabled and on your Pathauto settings. The recommended and default value is 100.') . '</p>';
       return $output;
   }
 }
 
 /**
- * Implementation of hook_perm().
+ * Implement hook_permission().
  */
-function pathauto_perm() {
-  return array('administer pathauto', 'notify of path changes');
+function pathauto_permission() {
+  return array(
+    'administer pathauto' => array(
+      'title' => t('Administer pathauto'),
+      'description' => t('PLACEHOLDER'),
+    ),
+    'notify of path changes' => array(
+      'title' => t('Notify of Path Changes'),
+      'description' => t('PLACEHOILDER'),
+    ),
+  );
 }
 
 /**
- * Implementation of hook_menu().
+ * Implement hook_menu().
  */
 function pathauto_menu() {
-  $items['admin/build/path/pathauto'] = array(
+  $items['admin/config/search/path/pathauto'] = array(
     'title' => 'Automated alias settings',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('pathauto_admin_settings'),
@@ -54,12 +62,13 @@ function pathauto_menu() {
     'file' => 'pathauto.admin.inc',
   );
 
-  $items['admin/build/path/delete_bulk'] = array(
+  $items['admin/config/search/path/delete_bulk'] = array(
     'title' => 'Delete aliases',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('pathauto_admin_delete'),
     'access arguments' => array('administer url aliases'),
     'type' => MENU_LOCAL_TASK,
+    'weight' => 11,
     'file' => 'pathauto.admin.inc',
   );
 
@@ -77,99 +86,119 @@ function _pathauto_include() {
 }
 
 /**
- * Implementation of hook_token_values() for Pathauto specific tokens.
+ * Implement hook_tokens() for Pathauto specific tokens.
  */
-function pathauto_token_values($type, $object = NULL) {
+function pathauto_tokens($type, $tokens, array $data = array(), array $options = array()) {
+  $replacements = array();
   if (module_exists('taxonomy')) {
-    if ($type == 'taxonomy' || $type == 'node' || $type == 'all') {
+    if ($type == 'term' || $type == 'node') {
       _pathauto_include();
-      switch ($type) {
-        case 'node':
-          // Get the bookpathalias token
-          $values['bookpathalias'] = '';
-          // We're on a node and it's a book and it has a parent? Get the book path alias.
-          if (module_exists('book') && !empty($object->book['menu_name'])) {
-            for ($i = 1; $i < 10; $i++) {
-              $second_child = $i + 2;
-              if ($object->book["p$second_child"] === 0) {
-                $parent_node = db_result(db_query('SELECT link_path FROM {menu_links} WHERE mlid = %d', $object->book["p$i"]));
-                break;
-              }
-            }
-            $values['bookpathalias'] = drupal_get_path_alias($parent_node);
-          }
-
+      $sanitize = !empty($options['sanitize']);
+      $separator = variable_get('pathauto_separator', '-');
+      $catpath = $alias = '';
+
+      if (($type == 'node' && !empty($data['node'])) || ($type == 'term' && !empty($data['term']))) {
+        if ($type == 'node') {
+          $node = $data['node'];
           // Get taxonomy related data.
-          $vid = db_result(db_query_range("SELECT t.vid FROM {term_node} r INNER JOIN {term_data} t ON r.tid = t.tid INNER JOIN {vocabulary} v ON t.vid = v.vid WHERE r.vid = %d ORDER BY v.weight, t.weight, t.name", $object->vid, 0, 1));
-          $category = db_fetch_object(db_query_range("SELECT t.tid, t.name FROM {term_data} t INNER JOIN {term_node} r ON r.tid = t.tid WHERE t.vid = %d AND r.nid = %d ORDER BY weight", $vid, $object->nid, 0, 1));
-          $category->vid = $vid;
-          // In the realm of nodes these are terms, in the realm of Taxonomy, cats
-          $label = 'term';
-
-        case 'taxonomy':
-        default:
-          if (!isset($category)) {
-            $category = $object;
-          }
-          if (!isset($label)) {
-            $label = 'cat';
+          $vid = db_query_range("SELECT t.vid FROM {taxonomy_index} i INNER JOIN {taxonomy_term_data} t ON i.tid = t.tid INNER JOIN {taxonomy_vocabulary} v ON t.vid = v.vid WHERE i.nid = :nid ORDER BY v.weight, t.weight, t.name", 0, 1, array(':nid' => $node->nid))->fetchColumn();
+          $term = db_query_range("SELECT t.tid, t.name FROM {taxonomy_term_data} t INNER JOIN {taxonomy_index} i ON i.tid = t.tid WHERE t.vid = :vid AND i.nid = :nid ORDER BY weight", 0, 1, array(':vid' => $vid, ':nid' => $node->nid))->fetchObject();
+          $term->vid = $vid;
+        }
+        elseif ($type == 'term') {
+          $term = $data['term'];
+        }
+
+        if (isset($term->tid)) {
+          $parents = taxonomy_get_parents_all($term->tid);
+          array_shift($parents);
+          foreach ($parents as $parent) {
+            // Replace any '/' characters in individual terms which might create confusing URLs
+            $catpath = '/' . pathauto_cleanstring(check_plain(preg_replace('/\//', '', $parent->name))) . $catpath;
           }
-          if (isset($category->tid)) {
-            $separator = variable_get('pathauto_separator', '-');
-            $parents = taxonomy_get_parents_all($category->tid);
-            array_shift($parents);
-            $catpath = '';
-            $catpath_raw = '';
-            foreach ($parents as $parent) {
-              // Replace any / characters in individual terms which might create confusing URLs
-              $catpath = pathauto_cleanstring(check_plain(preg_replace('/\//', '', $parent->name))) .'/'. $catpath;
-              $catpath_raw = pathauto_cleanstring(preg_replace('/\//', '', $parent->name)) .'/'. $catpath_raw;
-            }
-            $values[$label .'path'] = $catpath .'/'. check_plain($category->name);
-            $values[$label .'path-raw'] = $catpath_raw .'/'. $category->name;
-            $values[$label .'alias'] = drupal_get_path_alias('taxonomy/term/'. $category->tid);
-            if (!strncasecmp($values[$label .'alias'], 'taxonomy', 8)) {
-              $values[$label .'alias'] = check_plain($category->name);
-            }
+
+          $catpath = $catpath . '/' . check_plain($term->name);
+          $alias = drupal_get_path_alias('taxonomy/term/' . $term->tid);
+          if (!strncasecmp($alias, 'taxonomy', 8)) {
+            $alias = check_plain($term->name);
           }
-          else { // Provide some defaults if they aren't set.
-            $values[$label .'path'] = '';
-            $values[$label .'path-raw'] = '';
-            $values[$label .'alias'] = '';
+        }
+
+        foreach ($tokens as $name => $original) {
+          switch ($name) {
+            case 'bookpathalias':
+              if (module_exists('book') && !empty($node->book['menu_name'])) {
+                for ($i = 1; $i < 10; $i++) {
+                  $second_child = $i + 2;
+                  if ($node->book["p$second_child"] === 0) {
+                    $parent_node = db_query('SELECT link_path FROM {menu_links} WHERE mlid = :mlid', array(':mlid' => $node->book["p$i"]))->fetchObject();
+                    break;
+                  }
+                }
+                $replacements[$original] = drupal_get_path_alias($parent_node);
+              }
+              else {
+                $replacements[$original] = '';
+              }
+              break;
+
+            case 'termpath':
+            case 'catpath':
+              $replacements[$original] = $catpath;
+              break;
+
+            case 'termalias':
+            case 'catalias':
+              $replacements[$original] = $alias;
+              break;
           }
+        }
       }
-      return $values;
     }
   }
+  return $replacements;
 }
 
 /**
- * Implementation of hook_token_list() for Pathauto specific tokens.
+ * Implement hook_token_info() for Pathauto specific tokens.
  */
-function pathauto_token_list($type = 'all') {
+function pathauto_token_info() {
   $tokens = array();
+
   if (module_exists('taxonomy')) {
-    if ($type == 'taxonomy' || $type == 'all') {
-      $tokens['taxonomy']['catpath'] = t('As [cat], but including its supercategories separated by /.');
-      $tokens['taxonomy']['catpath-raw'] = t('As [cat-raw], but including its supercategories separated by /. WARNING - raw user input.');
-      $tokens['taxonomy']['catalias'] = t('URL alias for the term.');
-    }
-    if ($type == 'node' || $type == 'all') {
-      $tokens['node']['termpath'] = t('As [term], but including its supercategories separated by /.');
-      $tokens['node']['termpath-raw'] = t('As [term-raw], but including its supercategories separated by /. WARNING - raw user input.');
-      $tokens['node']['termalias'] = t('URL alias for the term.');
-    }
-  }
-  if (module_exists('book')) {
-    if ($type == 'node' || $type == 'all') {
-      $tokens['node']['bookpathalias'] = t('URL alias for the parent book.');
+    $tokens['term']['catpath'] = array(
+      'name' => t("Node's Term Path"),
+      'description' => t('As [cat], but including its supercategories separated by /.'),
+    );
+    $tokens['term']['catalias'] = array(
+      'name' => t("Node's Term Alias"),
+      'description' => t('URL alias for the term.'),
+    );
+
+    $tokens['node']['termpath'] = array(
+      'name' => t('Term Path'),
+      'description' => t('As [term], but including its supercategories separated by /.'),
+    );
+    $tokens['node']['termalias'] = array(
+      'name' => t('Term Alias'),
+      'description' => t('URL alias for the term.'),
+    );
+
+    if (module_exists('book')) {
+      $tokens['node']['bookpathalias'] = array(
+        'name' => t('Book Path Alias'),
+        'description' => t('URL alias for the parent book.'),
+      );
     }
   }
-  return $tokens;
+
+  return array(
+    'tokens' => $tokens,
+  );
 }
 
 /**
- * Implementation of hook_path_alias_types().
+ * Implement hook_path_alias_types().
  *
  * Used primarily by the bulk delete form.
  */
@@ -194,77 +223,95 @@ function pathauto_path_alias_types() {
 // Some node related functions.
 
 /**
- * Implementation of hook_nodeapi().
+ * Implement hook_node_presave().
  */
-function pathauto_nodeapi(&$node, $op, $teaser, $page) {
+function pathauto_node_presave($node) {
   if (module_exists('path')) {
-    switch ($op) {
-      case 'presave':
-        // About to be saved (before insert/update)
-        if (!empty($node->pathauto_perform_alias) && isset($node->old_alias)
-            && $node->path == '' && $node->old_alias != '') {
-          /**
-           * There was an old alias, but when pathauto_perform_alias was checked
-           * the javascript disabled the textbox which led to an empty value being
-           * submitted. Restoring the old path-value here prevents the Path module
-           * from deleting any old alias before Pathauto gets control.
-           */
-          $node->path = $node->old_alias;
-        }
-        break;
-      case 'insert':
-      case 'update':
-        _pathauto_include();
-        // Get the specific pattern or the default
-        if (variable_get('language_content_type_'. $node->type, 0)) {
-          $pattern = trim(variable_get('pathauto_node_'. $node->type .'_'. $node->language .'_pattern', FALSE));
-        }
-        if (empty($pattern)) {
-          $pattern = trim(variable_get('pathauto_node_'. $node->type .'_pattern', FALSE));
-          if (empty($pattern)) {
-            $pattern = trim(variable_get('pathauto_node_pattern', FALSE));
-          }
-        }
-        // Only do work if there's a pattern
-        if ($pattern) {
-          // 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);
-            $src = "node/$node->nid";
-            $alias = pathauto_create_alias('node', $op, $placeholders, $src, $node->nid, $node->type, $node->language);
-          }
-        }
-        break;
-      case 'delete':
-        path_set_alias('node/'. $node->nid);
-        path_set_alias('node/'. $node->nid .'/feed');
-        break;
-      default:
-        break;
+    // About to be saved (before insert/update)
+    if (!empty($node->path['pathauto_perform_alias']) && isset($node->path['old_alias'])
+        && $node->path['alias'] == '' && $node->path['old_alias'] != '') {
+      /**
+       * There was an old alias, but when pathauto_perform_alias was checked
+       * the javascript disabled the textbox which led to an empty value being
+       * submitted. Restoring the old path-value here prevents the Path module
+       * from deleting any old alias before Pathauto gets control.
+       */
+      $node->path['alias'] = $node->path['old_alias'];
+    }
+  }
+}
+
+/**
+ * Implement hook_node_insert().
+ */
+function pathauto_node_insert($node) {
+  _pathauto_node_insert_update($node, 'insert');
+}
+
+/**
+ * Implement hook_node_update().
+ */
+function pathauto_node_update($node) {
+  _pathauto_node_insert_update($node, 'update');
+}
+
+/**
+ * Internal helper for node insert/update duplicate functionality.
+ */
+function _pathauto_node_insert_update($node, $op) {
+  if (module_exists('path')) {
+    _pathauto_include();
+    // Get the specific pattern or the default
+    if (variable_get('language_content_type_' . $node->type, 0)) {
+      $pattern = trim(variable_get('pathauto_node_' . $node->type . '_' . $node->language . '_pattern', FALSE));
     }
+    if (empty($pattern)) {
+      $pattern = trim(variable_get('pathauto_node_' . $node->type . '_pattern', FALSE));
+      if (empty($pattern)) {
+        $pattern = trim(variable_get('pathauto_node_pattern', FALSE));
+      }
+    }
+    // Only do work if there's a pattern
+    if ($pattern) {
+      // Only create an alias if the checkbox was not provided or if the checkbox was provided and is checked
+      if (!isset($node->path['pathauto_perform_alias']) || $node->path['pathauto_perform_alias']) {
+        $source = "node/$node->nid";
+        $alias = pathauto_create_alias('node', $op, $source, array('node' => $node), $node->type, $node->language);
+      }
+    }
+  }
+}
+
+/**
+ * Implement hook_node_delete().
+ */
+function pathauto_node_delete($node) {
+  if (module_exists('path')) {
+    path_delete(array('source' => 'node/' . $node->nid));
+    path_delete(array('source' => 'node/' . $node->nid . '/feed'));
   }
 }
 
 /**
- * Implementation of hook_form_alter().
+ * Implement hook_form_alter().
  *
  * This allows alias creators to override Pathauto and specify their
  * own aliases (Pathauto will be invisible to other users). Inserted
  * into the path module's fieldset in the node form.
  */
-function pathauto_form_alter(&$form, $form_state, $form_id) {
-  // Process only node forms.
-  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
+function pathauto_form_alter(&$form, &$form_state, $form_id) {
+  // Only do this for node forms
+  if (!empty($form['#node_edit_form'])) {
     $node = $form['#node'];
     $pattern = FALSE;
 
     // Find if there is an automatic alias pattern for this node type.
     if (isset($form['language'])) {
       $language = isset($form['language']['#value']) ? $form['language']['#value'] : $form['language']['#default_value'];
-      $pattern = trim(variable_get('pathauto_node_'. $form['type']['#value'] .'_'. $language .'_pattern', ''));
+      $pattern = trim(variable_get('pathauto_node_' . $form['type']['#value'] . '_' . $language . '_pattern', ''));
     }
     if (!$pattern) {
-      $pattern = trim(variable_get('pathauto_node_'. $form['type']['#value'] .'_pattern', ''));
+      $pattern = trim(variable_get('pathauto_node_' . $form['type']['#value'] . '_pattern', ''));
       if (!$pattern) {
         $pattern = trim(variable_get('pathauto_node_pattern', ''));
       }
@@ -278,9 +325,9 @@ function pathauto_form_alter(&$form, $fo
           // alias that would be genereted by pathauto. If they are the same,
           // then keep the automatic alias enabled.
           _pathauto_include();
-          $placeholders = pathauto_get_placeholders('node', $node);
-          $pathauto_alias = pathauto_create_alias('node', 'return', $placeholders, "node/{$node->nid}", $node->nid, $node->type, $node->language);
-          $node->pathauto_perform_alias = isset($node->path) && $node->path == $pathauto_alias;
+          $path = path_load(array('source' => 'node/' . $node->nid));
+          $pathauto_alias = pathauto_create_alias('node', 'return', "node/{$node->nid}", array('node' => $node), $node->type, $node->language);
+          $node->pathauto_perform_alias = !empty($path['alias']) && $path['alias'] == $pathauto_alias;
         }
         else {
           // If this is a new node, enable the automatic alias.
@@ -290,7 +337,7 @@ function pathauto_form_alter(&$form, $fo
 
       // Add JavaScript that will disable the path textfield when the automatic
       // alias checkbox is checked.
-      drupal_add_js(drupal_get_path('module', 'pathauto') .'/pathauto.js');
+      drupal_add_js(drupal_get_path('module', 'pathauto') . '/pathauto.js');
 
       $form['path']['pathauto_perform_alias'] = array(
         '#type' => 'checkbox',
@@ -301,19 +348,19 @@ function pathauto_form_alter(&$form, $fo
       );
 
       if (user_access('administer pathauto')) {
-        $form['path']['pathauto_perform_alias']['#description'] .= ' '. t('To control the format of the generated aliases, see the <a href="@pathauto">automated alias settings</a>.', array('@pathauto' => url('admin/build/path/pathauto')));
+        $form['path']['pathauto_perform_alias']['#description'] .= ' ' . t('To control the format of the generated aliases, see the <a href="@pathauto">automated alias settings</a>.', array('@pathauto' => url('admin/config/search/path/pathauto')));
       }
 
-      if ($node->pathauto_perform_alias && !empty($node->old_alias) && empty($node->path)) {
-        $form['path']['path']['#default_value'] = $node->old_alias;
-        $node->path = $node->old_alias;
+      if ($node->pathauto_perform_alias && !empty($node->old_alias) && empty($path['alias'])) {
+        $form['path']['alias']['#default_value'] = $node->old_alias;
+        $path['alias'] = $node->old_alias;
       }
 
       // For Pathauto to remember the old alias and prevent the Path-module from deleteing it when Pathauto wants to preserve it
-      if (isset($node->path)) {
+      if (!empty($path['alias'])) {
         $form['path']['old_alias'] = array(
           '#type' => 'value',
-          '#value' => $node->path,
+          '#value' => $path['alias'],
         );
       }
     }
@@ -321,7 +368,7 @@ function pathauto_form_alter(&$form, $fo
 }
 
 /**
- * Implementation of hook_node_operations().
+ * Implement hook_node_operations().
  */
 function pathauto_node_operations() {
   $operations = array(
@@ -341,10 +388,9 @@ function pathauto_node_operations() {
  */
 function pathauto_node_operations_update($nodes) {
   _pathauto_include();
-  foreach ($nodes as $nid) {
-    $node = node_load($nid);
-    $placeholders = pathauto_get_placeholders('node', $node);
-    pathauto_create_alias('node', 'bulkupdate', $placeholders, "node/$node->nid", $node->nid, $node->type);
+  $nodes = node_load_multiple($nodes);
+  foreach ($nodes as $node) {
+    pathauto_create_alias('node', 'bulkupdate', "node/$node->nid", array('node' => $node), $node->type);
   }
 }
 
@@ -352,100 +398,123 @@ function pathauto_node_operations_update
 // Taxonomy related functions.
 
 /**
- * Implementation of hook_taxonomy().
+ * Implement hook_taxonomy_term_insert().
  */
-function pathauto_taxonomy($op, $type, $object = NULL) {
-  switch ($type) {
-    case 'term':
-      switch ($op) {
-        case 'insert':
-        case 'update':
-          _pathauto_include();
-          // Use the category info to automatically create an alias
-          $category = (object) $object;
-          if ($category->name) {
-            $count = _taxonomy_pathauto_alias($category, $op);
-          }
+function pathauto_taxonomy_term_insert($term) {
+  // taxonomy.tokens.inc expects a description
+  if (!isset($term->description)) {
+    $term->description = NULL;
+  }
+  _pathauto_taxonomy_term_insert_update($term, 'insert');
+}
 
-          // For all children generate new alias (important if [catpath] used)
-          foreach (taxonomy_get_tree($category->vid, $category->tid) as $subcategory) {
-            $count = _taxonomy_pathauto_alias($subcategory, $op);
-          }
+/**
+ * Implement hook_taxonomy_term_update().
+ */
+function pathauto_taxonomy_term_update($term) {
+  _pathauto_taxonomy_term_insert_update($term, 'update');
+}
 
-          break;
-        case 'delete':
-          // If the category is deleted, remove the path aliases
-          $category = (object) $object;
-          path_set_alias('taxonomy/term/'. $category->tid);
-          path_set_alias(taxonomy_term_path($category));
-          path_set_alias('forum/'. $category->tid);
-          path_set_alias('taxonomy/term/'. $category->tid .'/0/feed');
-          break;
-        default:
-          break;
-      }
-      break;
-    default:
-      break;
+/**
+ * Internal helper for taxonomy term insert/update duplicate functionality
+ */
+function _pathauto_taxonomy_term_insert_update($term, $op) {
+  _pathauto_include();
+  if ($term->name) {
+    $count = _taxonomy_pathauto_alias($term, $op);
+  }
+
+  // For all children generate new alias (important if [catpath] used)
+  foreach (taxonomy_get_tree($term->vid, $term->tid) as $subterm) {
+    $count = _taxonomy_pathauto_alias($subterm, $op);
   }
 }
 
+/**
+ * Implement hook_taxonomy_term_delete().
+ */
+function pathauto_taxonomy_term_delete($term) {
+  path_delete(array('source' => 'taxonomy/term/' . $term->tid));
+  path_delete(array('source' => 'forum/' . $term->tid));
+  path_delete(array('source' => 'taxonomy/term/' . $term->tid . '/0/feed'));
+}
+
 //==============================================================================
-// User related functions.
+// User related functions. For users, trackers, and blogs.
 
 /**
- * Implementation of hook_user() for users, trackers, and blogs.
+ * Implement hook_user_insert().
  */
-function pathauto_user($op, &$edit, &$user, $category = FALSE) {
-  switch ($op) {
-    case 'insert':
-    case 'update':
-      _pathauto_include();
-      // Use the username to automatically create an alias
-      $pathauto_user = (object) array_merge((array) $user, $edit);
-      if ($user->name) {
-        $placeholders = pathauto_get_placeholders('user', $pathauto_user);
-        $src = 'user/'. $user->uid;
-        $alias = pathauto_create_alias('user', $op, $placeholders, $src, $user->uid);
-
-        if (module_exists('blog')) {
-          $new_user = drupal_clone($user);
-          if ($category == 'account') {
-            $new_user->roles = isset($edit['roles']) ? $edit['roles'] : array();
-            $new_user->roles[DRUPAL_AUTHENTICATED_RID] = t('authenticated user'); // Add this back
-          }
-          if (user_access('create blog entries', $new_user)) {
-            $src = 'blog/'. $user->uid;
-            $alias = pathauto_create_alias('blog', $op, $placeholders, $src, $user->uid);
-          }
-          else {
-            path_set_alias('blog/'. $user->uid);
-            path_set_alias('blog/'. $user->uid .'/feed');
-          }
-        }
-        if (module_exists('tracker')) {
-          $src = 'user/'. $user->uid .'/track';
-          $alias = pathauto_create_alias('tracker', $op, $placeholders, $src, $user->uid);
-        }
-        if (module_exists('contact')) {
-          $src = 'user/'. $user->uid .'/contact';
-          $alias = pathauto_create_alias('contact', $op, $placeholders, $src, $user->uid);
-        }
+function pathauto_user_insert(&$edit, $account, $category) {
+  _pathauto_user_insert_update($edit, $account, $category, 'insert');
+}
+
+/**
+ * Implement hook_user_update().
+ */
+function pathauto_user_update(&$edit, $account, $category) {
+  _pathauto_user_insert_update($edit, $account, $category, 'update');
+}
+
+/**
+ * Internal helper for user insert/update duplicate functionality.
+ */
+function _pathauto_user_insert_update(&$edit, $account, $category, $op) {
+  _pathauto_include();
+  // Use the username to automatically create an alias
+  $pathauto_user = (object) array_merge((array) $account, $edit);
+  if ($pathauto_user->name) {
+    $source = 'user/' . $pathauto_user->uid;
+    $alias = pathauto_create_alias('user', $op, $source, array('user' => $pathauto_user));
+
+    if (module_exists('blog')) {
+      $new_user = clone $pathauto_user;
+      if ($category == 'account') {
+        $new_user->roles = isset($edit['roles']) ? $edit['roles'] : array();
+        $new_user->roles[DRUPAL_AUTHENTICATED_RID] = t('authenticated user'); // Add this back
+      }
+      if (user_access('create blog entries', $new_user)) {
+        $source = 'blog/' . $new_user->uid;
+        $alias = pathauto_create_alias('blog', $op, $source, array('user' => $new_user));
       }
+      else {
+        path_delete(array('source' => 'blog/' . $new_user->uid));
+        path_delete(array('source' => 'blog/' . $new_user->uid . '/feed'));
+      }
+    }
+    if (module_exists('tracker')) {
+      $source = 'user/' . $new_user->uid . '/track';
+      $alias = pathauto_create_alias('tracker', $op, $source, array('user' => $new_user));
+    }
+    if (module_exists('contact')) {
+      $source = 'user/' . $new_user->uid . '/contact';
+      $alias = pathauto_create_alias('contact', $op, $source, array('user' => $new_user));
+    }
+  }
+}
+
+/**
+ * Implement hook_user_delete().
+ */
+function pathauto_user_cancel($edit, $account, $method) {
+  switch ($method) {
+    case 'user_cancel_block':
+    case 'user_cancel_block_unpublish':
+      // Don't remove aliases because the user may become active again later.
       break;
-    case 'delete':
-      // If the user is deleted, remove the path aliases
-      $user = (object) $user;
-      path_set_alias('user/'. $user->uid);
+
+    case 'user_cancel_reassign':
+    case 'user_cancel_delete':
+      // Remove the users's path aliases
+      $user = (object) $account;
+      path_delete(array('source' => 'user/' . $user->uid));
 
       // They may have enabled these modules and/or feeds when the user was created, so let's try to delete all of them
-      path_set_alias('blog/'. $user->uid);
-      path_set_alias('blog/'. $user->uid .'/feed');
-      path_set_alias('user/'. $user->uid .'/track');
-      path_set_alias('user/'. $user->uid .'/track/feed');
-      path_set_alias('user/'. $user->uid .'/contact');
-      break;
-    default:
+      path_delete(array('source' => 'blog/' . $user->uid));
+      path_delete(array('source' => 'blog/' . $user->uid . '/feed'));
+      path_delete(array('source' => 'user/' . $user->uid . '/track'));
+      path_delete(array('source' => 'user/' . $user->uid . '/track/feed'));
+      path_delete(array('source' => 'user/' . $user->uid . '/contact'));
       break;
   }
 }
Index: pathauto_node.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto_node.inc,v
retrieving revision 1.48
diff -u -p -r1.48 pathauto_node.inc
--- pathauto_node.inc	28 Jun 2008 15:41:15 -0000	1.48
+++ pathauto_node.inc	10 Nov 2009 00:24:09 -0000
@@ -9,7 +9,7 @@
  */
 
 /**
- * Implementation of hook_pathauto().
+ * Implement hook_pathauto().
  */
 function node_pathauto($op) {
   switch ($op) {
@@ -19,17 +19,13 @@ function node_pathauto($op) {
       $settings['token_type'] = 'node';
       $settings['groupheader'] = t('Node path settings');
       $settings['patterndescr'] = t('Default path pattern (applies to all node types with blank patterns below)');
-      $settings['patterndefault'] = t('content/[title-raw]');
+      $settings['patterndefault'] = t('content/[node:title]');
       $settings['bulkname'] = t('Bulk generate aliases for nodes that are not aliased');
       $settings['bulkdescr'] = t('Generate aliases for all existing nodes which do not already have aliases.');
 
-      $patterns = token_get_list('node');
-      foreach ($patterns as $type => $pattern_set) {
-        if ($type != 'global') {
-          foreach ($pattern_set as $pattern => $description) {
-            $settings['placeholders']['['. $pattern .']'] = $description;
-          }
-        }
+      $tokens = token_info();
+      foreach ($tokens['tokens']['node'] as $key => $info) {
+        $settings['tokens']["[node:$key]"] = $info['description'];
       }
       $settings['supportsfeeds'] = 'feed';
 
@@ -39,15 +35,15 @@ function node_pathauto($op) {
       else {
         $languages = array();
       }
-      foreach (node_get_types('names') as $node_type => $node_name) {
-        if (variable_get('language_content_type_'. $node_type, 0) && count($languages)) {
+      foreach (node_type_get_names() as $node_type => $node_name) {
+        if (variable_get('language_content_type_' . $node_type, 0) && count($languages)) {
           $settings['patternitems'][$node_type] = t('Default path pattern for @node_type (applies to all @node_type node types with blank patterns below)', array('@node_type' => $node_name));
           foreach ($languages as $lang_code => $lang_name) {
             if (!empty($lang_code)) {
-              $settings['patternitems'][$node_type .'_'. $lang_code] = t('Pattern for all @node_type paths in @language', array('@node_type' => $node_name, '@language' => $lang_name));
+              $settings['patternitems'][$node_type . '_' . $lang_code] = t('Pattern for all @node_type paths in @language', array('@node_type' => $node_name, '@language' => $lang_name));
             }
             else {
-              $settings['patternitems'][$node_type .'_'. $lang_code] = t('Pattern for all language neutral @node_type paths', array('@node_type' => $node_name));
+              $settings['patternitems'][$node_type . '_' . $lang_code] = t('Pattern for all language neutral @node_type paths', array('@node_type' => $node_name));
             }
           }
         }
@@ -70,7 +66,7 @@ function node_pathauto_bulkupdate() {
 
   // If there's a default pattern we assume all types might be updated.
   if (trim(variable_get('pathauto_node_pattern', ''))) {
-    $pattern_types = array_keys(node_get_types('names'));
+    $pattern_types = array_keys(node_type_get_types());
   }
   else {
     // Check first for a node specific pattern...
@@ -78,15 +74,15 @@ function node_pathauto_bulkupdate() {
     if (module_exists('locale')) {
       $languages = array('' => t('Language neutral')) + locale_language_list('name');
     }
-    foreach (array_keys(node_get_types('names')) as $type) {
-      if (trim(variable_get('pathauto_node_'. $type .'_pattern', ''))) {
+    foreach (array_keys(node_type_get_types()) as $type) {
+      if (trim(variable_get('pathauto_node_' . $type . '_pattern', ''))) {
         $pattern_types[$type] = $type;
         continue;
       }
       // ...then for a node-language pattern.
-      if (variable_get('language_content_type_'. $type, 0) && $languages) {
+      if (variable_get('language_content_type_' . $type, 0) && $languages) {
         foreach ($languages as $lang_code => $lang_name) {
-          if (trim(variable_get('pathauto_node_'. $type .'_'. $lang_code .'_pattern', ''))) {
+          if (trim(variable_get('pathauto_node_' . $type . '_' . $lang_code . '_pattern', ''))) {
             $pattern_types[$type] = $type;
             continue 2;
           }
@@ -97,22 +93,22 @@ function node_pathauto_bulkupdate() {
 
   $count = 0;
   if (count($pattern_types)) {
-    $query = "SELECT n.nid, n.vid, n.type, n.title, n.uid, n.created, n.language, alias.src, alias.dst FROM {node} n LEFT JOIN {url_alias} alias ON CONCAT('node/', CAST(n.nid AS CHAR)) = alias.src WHERE alias.src IS NULL AND n.type IN (". db_placeholders($pattern_types, 'varchar') .')';
-    $result = db_query_range($query, $pattern_types, 0, variable_get('pathauto_max_bulk_update', 50));
+    // @TODO We could rewrite this section to use node_load_multiple
+    $query = "SELECT n.nid, n.vid, n.type, n.title, n.uid, n.created, n.language, ua.source, ua.alias FROM {node} n LEFT JOIN {url_alias} ua ON CONCAT('node/', CAST(n.nid AS CHAR)) = ua.source WHERE ua.source IS NULL AND n.type IN (:pattern_types)";
+    $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50), array(':pattern_types' => $pattern_types));
 
-    $placeholders = array();
-    while ($node_ref = db_fetch_object($result)) {
+    foreach ($result as $node_ref) {
       $node = node_load($node_ref->nid, NULL, TRUE);
-      $node->src = $node_ref->src;
-      $node->dst = $node_ref->dst;
+      $node->source = $node_ref->source;
+      $node->alias = $node_ref->alias;
       if (module_exists('taxonomy')) {
         // Must populate the terms for the node here for the category
         // placeholders to work
-        $node->taxonomy = array_keys(taxonomy_node_get_terms($node));
+        // @TODO Find the Drupal 7 alternative for this if necessary
+        //$node->taxonomy = array_keys(taxonomy_node_get_terms($node));
       }
-      $placeholders = pathauto_get_placeholders('node', $node);
-      $src = "node/$node->nid";
-      if (pathauto_create_alias('node', 'bulkupdate', $placeholders, $src, $node->nid, $node->type, $node->language)) {
+      $source = "node/$node->nid";
+      if (pathauto_create_alias('node', 'bulkupdate', $source, array('node' => $node), $node->type, $node->language)) {
         $count++;
       }
     }
Index: pathauto_taxonomy.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto_taxonomy.inc,v
retrieving revision 1.41
diff -u -p -r1.41 pathauto_taxonomy.inc
--- pathauto_taxonomy.inc	28 Aug 2008 16:14:06 -0000	1.41
+++ pathauto_taxonomy.inc	10 Nov 2009 00:24:09 -0000
@@ -9,24 +9,24 @@
  */
 
 /**
- * Implementation of hook_pathauto() for taxonomy module.
+ * Implement hook_pathauto() for taxonomy module.
  */
 function taxonomy_pathauto($op) {
   switch ($op) {
     case 'settings':
       $settings = array();
       $settings['module'] = 'taxonomy';
-      $settings['token_type'] = 'taxonomy';
+      $settings['token_type'] = 'term';
       $settings['groupheader'] = t('Taxonomy term path settings');
       $settings['patterndescr'] = t('Default path pattern (applies to all vocabularies with blank patterns below)');
-      $settings['patterndefault'] = t('category/[vocab-raw]/[catpath-raw]');
-      $patterns = token_get_list('taxonomy');
-      foreach ($patterns as $type => $pattern_set) {
-        if ($type != 'global') {
-          foreach ($pattern_set as $pattern => $description) {
-            $settings['placeholders']['['. $pattern .']'] = $description;
-          }
-        }
+      $settings['patterndefault'] = t('category/[vocabulary:name]/[term:catpath]');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['term'] as $key => $info) {
+        $settings['tokens']["[term:$key]"] = $info['description'];
+      }
+      foreach ($tokens['tokens']['vocabulary'] as $key => $info) {
+        $settings['tokens']["[vocabulary:$key]"] = $info['description'];
       }
       $settings['supportsfeeds'] = '0/feed';
       $settings['bulkname'] = t('Bulk generate aliases for terms that are not aliased');
@@ -54,39 +54,47 @@ function taxonomy_pathauto($op) {
  * Generate aliases for all categories without aliases.
  */
 function taxonomy_pathauto_bulkupdate() {
-  // From all node types, only attempt to update those with patterns
-  $pattern_vids = array();
+  // Initialize db_or().
+  $pattern_or = db_or();
+
+  // From all vocabularies, only attempt to update those with patterns.
   foreach (taxonomy_get_vocabularies() as $vid => $info) {
-    $pattern = trim(variable_get('pathauto_taxonomy_'. $vid .'_pattern', ''));
+    $pattern = trim(variable_get('pathauto_taxonomy_' . $vid . '_pattern', ''));
 
     // If it's not set, check the default
-    // TODO - if there's a default we shouldn't do this crazy where statement because all vocabs get aliases
-    // TODO - special casing to exclude the forum vid (and the images vid and...?)
+    // TODO - If there's a default we shouldn't do this crazy where statement because all vocabularies get aliases.
+    // TODO - Special casing to exclude the forum vid (and the images vid and...?).
     if (empty($pattern)) {
       $pattern = trim(variable_get('pathauto_taxonomy_pattern', ''));
     }
     if (!empty($pattern)) {
-      $pattern_vids[] = $vid;
-      if (empty($vid_where)) {
-        $vid_where = " AND (vid = '%s' ";
-      }
-      else {
-        $vid_where .= " OR vid = '%s'";
-      }
+      $pattern_or->condition('vid', $vid);
     }
   }
-  $vid_where .= ')';
 
-  // Exclude the forums and join all the args into one array so they can be passed to db_query
-  $forum_vid[] = variable_get('forum_nav_vocabulary', '');
-  $query_args = array_merge($forum_vid, $pattern_vids);
-  $query = "SELECT tid, vid, name, src, dst FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('taxonomy/term/', CAST(tid AS CHAR)) = src WHERE src IS NULL AND vid <> %d ". $vid_where;
-  $result = db_query_range($query, $query_args, 0, variable_get('pathauto_max_bulk_update', 50));
+  // Set up the query object.
+  $query = db_select('taxonomy_term_data', 'td');
+  $query->leftJoin('url_alias', 'ua', "CONCAT('taxonomy/term/', CAST(tid AS CHAR)) = source");
+  $query->fields('td', array('tid', 'vid', 'name'));
+  $query->fields('ua', array('source', 'alias'));
+  $query->isNull('source');
+
+  // Exclude the forums.
+  $query->condition('vid', variable_get('forum_nav_vocabulary', ''), '<>');
+
+  // Add $pattern_or condition to query.
+  $query->condition($pattern_or);
+
+  // Add range to query.
+  $query->range(0, variable_get('pathauto_max_bulk_update', 50));
+
+  // Execute query.
+  $result = $query->execute();
 
   $count = 0;
   $placeholders = array();
-  while ($category = db_fetch_object($result)) {
-    $count += _taxonomy_pathauto_alias($category, 'bulkupdate');
+  foreach ($result as $term) {
+    $count += _taxonomy_pathauto_alias($term, 'bulkupdate');
   }
 
   drupal_set_message(format_plural($count,
@@ -100,22 +108,22 @@ function taxonomy_pathauto_bulkupdate() 
  * @param $category
  *   A taxonomy object.
  */
-function _taxonomy_pathauto_alias($category, $op) {
+function _taxonomy_pathauto_alias($term, $op) {
   $count = 0;
-
-  $placeholders = pathauto_get_placeholders('taxonomy', $category);
+  $term = taxonomy_term_load($term->tid);
+  $vocabulary = taxonomy_vocabulary_load($term->vid);
 
   $forum_vid = variable_get('forum_nav_vocabulary', '');
   // If we're in a forum vocabulary, also create a forum container, forum, or forum topic alias.
-  if (module_exists('forum') && $forum_vid == (int)$category->vid) {
-    $src = 'forum/'. $category->tid;
-    if (pathauto_create_alias('forum', $op, $placeholders, $src, $category->tid, $category->vid)) {
+  if (module_exists('forum') && $forum_vid == (int)$term->vid) {
+    $source = 'forum/' . $term->tid;
+    if (pathauto_create_alias('forum', $op, $source, array('term' => $term, 'vocabulary' => $vocabulary), $term->vid)) {
       $count++;
     }
   }
   else {
-    $src = taxonomy_term_path($category);
-    if (pathauto_create_alias('taxonomy', $op, $placeholders, $src, $category->tid, $category->vid)) {
+    $source = 'taxonomy/term/' . $term->tid;
+    if (pathauto_create_alias('taxonomy', $op, $source, array('term' => $term, 'vocabulary' => $vocabulary), $term->vid)) {
       $count++;
     }
   }
@@ -123,28 +131,29 @@ function _taxonomy_pathauto_alias($categ
 }
 
 /**
- * Implementation of hook_pathauto() for forum module.
+ * Implement hook_pathauto() for forum module.
  */
 function forum_pathauto($op) {
   switch ($op) {
     case 'settings':
       $settings = array();
       $settings['module'] = 'forum';
-      $settings['token_type'] = 'taxonomy';
+      $settings['token_type'] = 'term';
       $settings['groupheader'] = t('Forum path settings');
       $settings['patterndescr'] = t('Pattern for forums and forum containers');
-      $settings['patterndefault'] = t('[vocab-raw]/[catpath-raw]');
-      $patterns = token_get_list('taxonomy');
-      foreach ($patterns as $type => $pattern_set) {
-        if ($type != 'global') {
-          foreach ($pattern_set as $pattern => $description) {
-            $settings['placeholders']['['. $pattern .']'] = $description;
-          }
-        }
+      $settings['patterndefault'] = t('[vocabulary:name]/[term:catpath]');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['term'] as $key => $info) {
+        $settings['tokens']["[term:$key]"] = $info['description'];
+      }
+      foreach ($tokens['tokens']['vocabulary'] as $key => $info) {
+        $settings['tokens']["[vocabulary:$key]"] = $info['description'];
       }
       $settings['supportsfeeds'] = '0/feed';
       $settings['bulkname'] = t('Bulk generate forum paths');
       $settings['bulkdescr'] = t('Generate aliases for all existing forums and forum containers which do not already have aliases.');
+
       return (object) $settings;
     default:
       break;
@@ -155,14 +164,24 @@ function forum_pathauto($op) {
  * Generate aliases for all forums and forum containers without aliases.
  */
 function forum_pathauto_bulkupdate() {
-  $forum_vid = variable_get('forum_nav_vocabulary', '');
-  $query = "SELECT tid, vid, name, src, dst FROM {term_data} LEFT JOIN {url_alias} ON CONCAT('forum/', CAST(tid AS CHAR)) = src WHERE vid = %d AND src IS NULL";
-  $result = db_query_range($query, $forum_vid, 0, variable_get('pathauto_max_bulk_update', 50));
+  // Set up the query object and limit it to the forum vocabulary.
+  $query = db_select('taxonomy_term_data', 'td');
+  $query->leftJoin('url_alias', 'ua', "CONCAT('forum/', CAST(tid AS CHAR)) = source");
+  $query->condition('vid', variable_get('forum_nav_vocabulary', ''));
+  $query->fields('td', array('tid', 'vid', 'name'));
+  $query->fields('ua', array('source', 'alias'));
+  $query->isNull('source');
+
+  // Add range to query.
+  $query->range(0, variable_get('pathauto_max_bulk_update', 50));
+
+  // Execute query.
+  $result = $query->execute();
 
   $count = 0;
   $placeholders = array();
-  while ($category = db_fetch_object($result)) {
-    $count = _taxonomy_pathauto_alias($category, 'bulkupdate') + $count;
+  foreach ($result as $term) {
+    $count += _taxonomy_pathauto_alias($term, 'bulkupdate');
   }
 
   drupal_set_message(format_plural($count,
Index: pathauto_user.inc
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/pathauto_user.inc,v
retrieving revision 1.31
diff -u -p -r1.31 pathauto_user.inc
--- pathauto_user.inc	11 Jul 2008 20:01:22 -0000	1.31
+++ pathauto_user.inc	10 Nov 2009 00:24:09 -0000
@@ -9,7 +9,7 @@
  */
 
 /**
- * Implementation of hook_pathauto() for user aliases.
+ * Implement hook_pathauto() for user aliases.
  */
 function user_pathauto($op) {
   switch ($op) {
@@ -19,14 +19,11 @@ function user_pathauto($op) {
       $settings['token_type'] = 'user';
       $settings['groupheader'] = t('User path settings');
       $settings['patterndescr'] = t('Pattern for user account page paths');
-      $settings['patterndefault'] = t('users/[user-raw]');
-      $patterns = token_get_list('user');
-      foreach ($patterns as $type => $pattern_set) {
-        if ($type != 'global') {
-          foreach ($pattern_set as $pattern => $description) {
-            $settings['placeholders']['['. $pattern .']'] = $description;
-          }
-        }
+      $settings['patterndefault'] = t('users/[user:name]');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['user'] as $key => $info) {
+        $settings['tokens']["[user:$key]"] = $info['description'];
       }
 
       $settings['bulkname'] = t('Bulk generate aliases for users that are not aliased');
@@ -38,7 +35,7 @@ function user_pathauto($op) {
 }
 
 /**
- * Implementation of hook_pathauto() for blog aliases.
+ * Implement hook_pathauto() for blog aliases.
  */
 function blog_pathauto($op) {
   switch ($op) {
@@ -48,11 +45,13 @@ function blog_pathauto($op) {
       $settings['token_type'] = 'user';
       $settings['groupheader'] = t('Blog path settings');
       $settings['patterndescr'] = t('Pattern for blog page paths');
-      $settings['patterndefault'] = t('blogs/[user-raw]');
-      $patterns = token_get_list('user');
-      foreach ($patterns['user'] as $pattern => $description) {
-        $settings['placeholders']['['. $pattern .']'] = $description;
+      $settings['patterndefault'] = t('blogs/[user:name]');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['user'] as $key => $info) {
+        $settings['tokens']["[user:$key]"] = $info['description'];
       }
+
       $settings['supportsfeeds'] = 'feed';
       $settings['bulkname'] = t('Bulk generate aliases for blogs that are not aliased');
       $settings['bulkdescr'] = t('Generate aliases for all existing blog pages which do not already have aliases.');
@@ -63,7 +62,7 @@ function blog_pathauto($op) {
 }
 
 /**
- * Implementation of hook_pathauto() for user-tracker aliases.
+ * Implement hook_pathauto() for user-tracker aliases.
  */
 function tracker_pathauto($op) {
   switch ($op) {
@@ -73,11 +72,13 @@ function tracker_pathauto($op) {
       $settings['token_type'] = 'user';
       $settings['groupheader'] = t('User-tracker path settings');
       $settings['patterndescr'] = t('Pattern for user-tracker page paths');
-      $settings['patterndefault'] = t('users/[user-raw]/track');
-      $patterns = token_get_list('user');
-      foreach ($patterns['user'] as $pattern => $description) {
-        $settings['placeholders']['['. $pattern .']'] = $description;
+      $settings['patterndefault'] = t('users/[user:name]/track');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['user'] as $key => $info) {
+        $settings['tokens']["[user:$key]"] = $info['description'];
       }
+
       $settings['supportsfeeds'] = 'feed';
       $settings['bulkname'] = t('Bulk generate aliases for user-tracker paths that are not aliased');
       $settings['bulkdescr'] = t('Generate aliases for all existing user-tracker pages which do not already have aliases.');
@@ -88,7 +89,7 @@ function tracker_pathauto($op) {
 }
 
 /**
- * Implementation of hook_pathauto() for contact form aliases.
+ * Implement hook_pathauto() for contact form aliases.
  */
 function contact_pathauto($op) {
   switch ($op) {
@@ -98,11 +99,13 @@ function contact_pathauto($op) {
       $settings['token_type'] = 'user';
       $settings['groupheader'] = t('User contact form path settings');
       $settings['patterndescr'] = t('Pattern for the user contact form paths');
-      $settings['patterndefault'] = t('users/[user-raw]/contact');
-      $patterns = token_get_list('user');
-      foreach ($patterns['user'] as $pattern => $description) {
-        $settings['placeholders']['['. $pattern .']'] = $description;
+      $settings['patterndefault'] = t('users/[user:name]/contact');
+
+      $tokens = token_info();
+      foreach ($tokens['tokens']['user'] as $key => $info) {
+        $settings['tokens']["[user:$key]"] = $info['description'];
       }
+
       $settings['bulkname'] = t('Bulk generate aliases for user contact form paths that are not aliased');
       $settings['bulkdescr'] = t('Generate aliases for all existing user contact form pages which do not already have aliases.');
       return (object) $settings;
@@ -115,15 +118,14 @@ function contact_pathauto($op) {
  * Bulk generate aliases for all users without aliases.
  */
 function user_pathauto_bulkupdate() {
-  $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT('user/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL";
+  $query = "SELECT uid, name, source, alias FROM {users} LEFT JOIN {url_alias} ON CONCAT('user/', CAST(uid AS CHAR)) = source WHERE uid > 0 AND source IS NULL";
   $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50));
 
   $count = 0;
   $placeholders = array();
-  while ($user = db_fetch_object($result)) {
-    $placeholders = pathauto_get_placeholders('user', $user);
-    $src = 'user/'. $user->uid;
-    if (pathauto_create_alias('user', 'bulkupdate', $placeholders, $src, $user->uid)) {
+  foreach ($result as $user) {
+    $source = 'user/' . $user->uid;
+    if (pathauto_create_alias('user', 'bulkupdate', $source, array('user' => $user))) {
       $count++;
     }
   }
@@ -137,15 +139,13 @@ function user_pathauto_bulkupdate() {
  * Bulk generate aliases for all blogs without aliases.
  */
 function blog_pathauto_bulkupdate() {
-  $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT('blog/', CAST(uid AS CHAR)) = src WHERE uid > 0 AND src IS NULL";
+  $query = "SELECT uid, name, source, alias FROM {users} LEFT JOIN {url_alias} ON CONCAT('blog/', CAST(uid AS CHAR)) = source WHERE uid > 0 AND source IS NULL";
   $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50));
 
   $count = 0;
-  $placeholders = array();
-  while ($user = db_fetch_object($result)) {
-    $placeholders = pathauto_get_placeholders('user', $user);
-    $src = 'blog/'. $user->uid;
-    if (pathauto_create_alias('blog', 'bulkupdate', $placeholders, $src, $user->uid)) {
+  foreach ($result as $user) {
+    $source = 'blog/' . $user->uid;
+    if (pathauto_create_alias('blog', 'bulkupdate', $source, array('user' => $user))) {
       $count++;
     }
   }
@@ -161,15 +161,13 @@ function blog_pathauto_bulkupdate() {
 function tracker_pathauto_bulkupdate() {
   // We do the double CONCAT because Pgsql8.1 doesn't support more than three arguments to CONCAT
   // Hopefully some day we can remove that.
-  $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/track') = src WHERE uid > 0 AND src IS NULL";
+  $query = "SELECT uid, name, source, alias FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/track') = source WHERE uid > 0 AND source IS NULL";
   $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50));
 
   $count = 0;
-  $placeholders = array();
-  while ($user = db_fetch_object($result)) {
-    $placeholders = pathauto_get_placeholders('user', $user);
-    $src = 'user/'. $user->uid .'/track';
-    if (pathauto_create_alias('tracker', 'bulkupdate', $placeholders, $src, $user->uid)) {
+  foreach ($result as $user) {
+    $source = 'user/' . $user->uid . '/track';
+    if (pathauto_create_alias('tracker', 'bulkupdate', $source, array('user' => $user))) {
       $count++;
     }
   }
@@ -183,15 +181,13 @@ function tracker_pathauto_bulkupdate() {
  * Bulk generate aliases for all users without aliases
  */
 function contact_pathauto_bulkupdate() {
-  $query = "SELECT uid, name, src, dst FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/contact') = src WHERE uid > 0 AND src IS NULL";
+  $query = "SELECT uid, name, source, alias FROM {users} LEFT JOIN {url_alias} ON CONCAT(CONCAT('user/', CAST(uid AS CHAR)), '/contact') = source WHERE uid > 0 AND source IS NULL";
   $result = db_query_range($query, 0, variable_get('pathauto_max_bulk_update', 50));
 
   $count = 0;
-  $placeholders = array();
-  while ($user = db_fetch_object($result)) {
-    $placeholders = pathauto_get_placeholders('user', $user);
-    $src = 'user/'. $user->uid .'/contact';
-    if (pathauto_create_alias('contact', 'bulkupdate', $placeholders, $src, $user->uid)) {
+  foreach ($result as $user) {
+    $source = 'user/' . $user->uid . '/contact';
+    if (pathauto_create_alias('contact', 'bulkupdate', $source, array('user' => $user))) {
       $count++;
     }
   }
Index: tests/pathauto.test
===================================================================
RCS file: /cvs/drupal/contributions/modules/pathauto/tests/pathauto.test,v
retrieving revision 1.5
diff -u -p -r1.5 pathauto.test
--- tests/pathauto.test	20 Oct 2009 18:02:18 -0000	1.5
+++ tests/pathauto.test	10 Nov 2009 00:24:09 -0000
@@ -18,10 +18,10 @@ class PathautoTestCase extends DrupalWeb
   /**
    * Implementation of getInfo().
    */
-  function getInfo() {
+  public static function getInfo() {
     return array(
-      'name' => t('Pathauto basic tests'),
-      'description' => t('Test basic pathauto functionality.'),
+      'name' => 'Pathauto basic tests',
+      'description' => 'Test basic pathauto functionality.',
       'group' => 'Pathauto',
     );
   }
@@ -30,19 +30,19 @@ class PathautoTestCase extends DrupalWeb
    * Implementation of setUp().
    */
   function setUp() {
-    parent::setUp('path', 'token', 'pathauto');
+    parent::setUp('path', 'pathauto');
 
     $this->content_type = $this->drupalCreateContentType();
     $this->web_user = $this->drupalCreateUser(array(
       'administer pathauto',
-      'create '. $this->content_type->type .' content',
-      'edit own '. $this->content_type->type .' content',
+      'create ' . $this->content_type->type . ' content',
+      'edit own ' . $this->content_type->type . ' content',
       'administer url aliases',
       'create url aliases',
     ));
 
     // Set pathauto settings we assume to be as-is in this test.
-    variable_set('pathauto_node_'. $this->content_type->type .'_pattern', 'content/[title-raw]');
+    variable_set('pathauto_node_' . $this->content_type->type . '_pattern', 'content/[node:title]');
     variable_set('pathauto_separator', '-');
     variable_set('pathauto_case', '1'); // lowercase
     variable_set('pathauto_max_length', '100');
@@ -51,7 +51,6 @@ class PathautoTestCase extends DrupalWeb
 
     $this->assertTrue(module_exists('pathauto'), t('Pathauto module is loaded.'));
     $this->assertTrue(module_exists('path'), t('Path module is loaded.'));
-    $this->assertTrue(module_exists('token'), t('Token module is loaded.'));
   }
 
   /**
@@ -60,31 +59,34 @@ class PathautoTestCase extends DrupalWeb
   function testPathautoFunctionalTest() {
     $this->drupalLogin($this->web_user);
 
-    $this->drupalGet('admin/build/path/pathauto');
+    $this->drupalGet('admin/config/search/path/pathauto');
     $this->assertRaw(t('General settings'), 'Settings page displayed.', 'Functionality test');
 
     // Create node for testing.
     $random_title = $this->randomName(10); // this contains _
-    $expected_alias = 'content/simpletest-title-'. strtolower($random_title);
+    $expected_alias = 'content/simpletest-title-' . strtolower($random_title);
+    $langcode = FIELD_LANGUAGE_NONE;
     // Extra characters at the beginning and end of the title tests that extra separator characters are removed.
     $edit = array(
-      'title' => ' Simpletest title '. $random_title .' [',
-      'body'  => 'Simpletest body '. $this->randomName(10),
+      "title[$langcode][0][value]" => ' Simpletest title ' . $random_title . ' [',
+      "body[$langcode][0][value]"  => 'Simpletest body ' . $this->randomName(10),
     );
+    $title = $edit["title[$langcode][0][value]"];
 
-    $this->drupalPost('node/add/'. str_replace('_', '-', $this->content_type->type), $edit, 'Save');
-    $this->assertRaw(t('@type %title has been created.', array('@type' => $this->content_type->name, '%title' => $edit['title'])), 'Test node submitted.', 'Functionality test');
+    $this->drupalPost('node/add/' . str_replace('_', '-', $this->content_type->type), $edit, 'Save');
+    $this->assertRaw(t('@type %title has been created.', array('@type' => $this->content_type->name, '%title' => $title)), 'Test node submitted.', 'Functionality test');
 
     // Look for alias generated in the form.
-    $node = node_load(array('title' => $edit['title']));
-    $this->drupalGet('node/'. $node->nid .'/edit');
+    $nodes = node_load_multiple(array(), array('title' => $title));
+    $node = reset($nodes);
+    $this->drupalGet('node/' . $node->nid . '/edit');
 
-    $this->assertPattern('!<input[^>]+name="path"[^>]+value="'. $expected_alias .'"!', 'Proper automated alias generated.', 'Functionality test');
+    $this->assertPattern('!<input[^>]+name="path\[alias\]"[^>]+value="' . $expected_alias . '"!', 'Proper automated alias generated.', 'Functionality test');
     // Look for checkbox.
-    $this->assertPattern('!<input[^>]+name="pathauto_perform_alias"[^>]+checked="checked"!', 'Automated alias turned on.', 'Functionality test');
+    $this->assertPattern('!<input[^>]+name="path\[pathauto_perform_alias\]"[^>]+checked="checked"!', 'Automated alias turned on.', 'Functionality test');
 
     // Check whether the alias actually works.
     $this->drupalGet($expected_alias);
-    $this->assertRaw($edit['title'], 'Node accessible through alias.', 'Functionality test');
+    $this->assertRaw($title, 'Node accessible through alias.', 'Functionality test');
   }
 }
