Index: authorize.php
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/authorize.php,v
retrieving revision 1.1
diff -u -p -r1.1 authorize.php
--- authorize.php	15 Oct 2009 21:19:30 -0000	1.1
+++ authorize.php	16 Oct 2009 05:48:41 -0000
@@ -96,8 +96,16 @@ if (authorize_access_allowed()) {
   // Load the code that drives the authorize process.
   require_once DRUPAL_ROOT . '/includes/authorize.inc';
 
-  // Initialize the URL path, but not via raising our bootstrap level.
-  drupal_path_initialize();
+  // For the sake of Batch API and a few other low-level functions, we need to
+  // initialize the URL path into $_GET['q']. However, we do not want to raise
+  // our bootstrap level, nor do we want to call drupal_initialize_path(),
+  // since that is assuming that modules are loaded and invoking hooks.
+  // However, all we really care is if we're in the middle of a batch, in which
+  // case $_GET['q'] will already be set, we just initialize it to an empty
+  // string if it's not already defined.
+  if (!isset($_GET['q'])) {
+    $_GET['q'] = '';
+  }
 
   if (isset($_SESSION['authorize_operation']['page_title'])) {
     drupal_set_title(check_plain($_SESSION['authorize_operation']['page_title']));
cvs diff: Diffing includes
Index: includes/bootstrap.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/includes/bootstrap.inc,v
retrieving revision 1.310
diff -u -p -r1.310 bootstrap.inc
--- includes/bootstrap.inc	16 Oct 2009 02:04:42 -0000	1.310
+++ includes/bootstrap.inc	16 Oct 2009 05:12:32 -0000
@@ -127,15 +127,10 @@ define('DRUPAL_BOOTSTRAP_PAGE_HEADER', 5
 define('DRUPAL_BOOTSTRAP_LANGUAGE', 6);
 
 /**
- * Eighth bootstrap phase: set $_GET['q'] to Drupal path of request.
- */
-define('DRUPAL_BOOTSTRAP_PATH', 7);
-
-/**
  * Final bootstrap phase: Drupal is fully loaded; validate and fix
  * input data.
  */
-define('DRUPAL_BOOTSTRAP_FULL', 8);
+define('DRUPAL_BOOTSTRAP_FULL', 7);
 
 /**
  * Role ID for anonymous users; should match what's in the "role" table.
@@ -1399,7 +1394,6 @@ function drupal_bootstrap($phase = NULL,
     DRUPAL_BOOTSTRAP_SESSION,
     DRUPAL_BOOTSTRAP_PAGE_HEADER,
     DRUPAL_BOOTSTRAP_LANGUAGE,
-    DRUPAL_BOOTSTRAP_PATH,
     DRUPAL_BOOTSTRAP_FULL,
   ));
   $completed_phase = &drupal_static(__FUNCTION__ . '_completed_phase', -1);
@@ -1535,12 +1529,6 @@ function _drupal_bootstrap($phase) {
       drupal_language_initialize();
       break;
 
-    case DRUPAL_BOOTSTRAP_PATH:
-      require_once DRUPAL_ROOT . '/includes/path.inc';
-      // Initialize $_GET['q'] prior to loading modules and invoking hook_init().
-      drupal_path_initialize();
-      break;
-
     case DRUPAL_BOOTSTRAP_FULL:
       require_once DRUPAL_ROOT . '/includes/common.inc';
       _drupal_bootstrap_full();
Index: includes/common.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/includes/common.inc,v
retrieving revision 1.1021
diff -u -p -r1.1021 common.inc
--- includes/common.inc	15 Oct 2009 21:19:30 -0000	1.1021
+++ includes/common.inc	16 Oct 2009 05:12:32 -0000
@@ -2357,6 +2357,7 @@ function url($path = NULL, array $option
     'https' => FALSE,
     'prefix' => ''
   );
+
   if (!isset($options['external'])) {
     // Return an external link if $path contains an allowed absolute URL.
     // Only call the slow filter_xss_bad_protocol if $path contains a ':' before
@@ -2365,10 +2366,12 @@ function url($path = NULL, array $option
     $options['external'] = ($colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path));
   }
 
-  // May need language dependent rewriting if language.inc is present.
-  if (function_exists('language_url_rewrite')) {
-    language_url_rewrite($path, $options);
-  }
+  // Preserve the original path before altering or aliasing.
+  $original_path = $path;
+
+  // Allow other modules to alter the outbound URL and options.
+  drupal_alter('url_outbound', $path, $options);
+
   if ($options['fragment']) {
     $options['fragment'] = '#' . $options['fragment'];
   }
@@ -2417,21 +2420,16 @@ function url($path = NULL, array $option
     }
   }
 
-  // Preserve the original path before aliasing.
-  $original_path = $path;
-
   // The special path '<front>' links to the default front page.
   if ($path == '<front>') {
     $path = '';
   }
   elseif (!empty($path) && !$options['alias']) {
     $language = isset($options['language']) && isset($options['language']->language) ? $options['language']->language : '';
-    $path = drupal_get_path_alias($path, $language);
-  }
-
-  if (function_exists('custom_url_rewrite_outbound')) {
-    // Modules may alter outbound links by reference.
-    custom_url_rewrite_outbound($path, $options, $original_path);
+    $alias = drupal_get_path_alias($original_path, $language);
+    if ($alias != $original_path) {
+      $path = $alias;
+    }
   }
 
   $base = $options['absolute'] ? $options['base_url'] . '/' : base_path();
@@ -4154,6 +4152,7 @@ function _drupal_bootstrap_full() {
     return;
   }
   $called = 1;
+  require_once DRUPAL_ROOT . '/includes/path.inc';
   require_once DRUPAL_ROOT . '/includes/theme.inc';
   require_once DRUPAL_ROOT . '/includes/pager.inc';
   require_once DRUPAL_ROOT . '/includes/menu.inc';
@@ -4187,6 +4186,8 @@ function _drupal_bootstrap_full() {
     ini_set('log_errors', 1);
     ini_set('error_log', file_directory_path() . '/error.log');
   }
+  // Initialize $_GET['q'] prior to invoking hook_init().
+  drupal_path_initialize();
   // Set a custom theme for the current page, if there is one. We need to run
   // this before invoking hook_init(), since any modules which initialize the
   // theme system will prevent a custom theme from being correctly set later.
@@ -6018,4 +6019,3 @@ function drupal_get_updaters() {
   }
   return $updaters;
 }
-
Index: includes/language.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/includes/language.inc,v
retrieving revision 1.21
diff -u -p -r1.21 language.inc
--- includes/language.inc	16 Oct 2009 02:04:42 -0000	1.21
+++ includes/language.inc	16 Oct 2009 05:12:32 -0000
@@ -325,47 +325,6 @@ function language_from_default() {
 }
 
 /**
- * Rewrite URLs allowing modules to hook in.
- *
- * @param $path
- *   The path to rewrite.
- * @param $options
- *   An associative array of additional options as in url().
- */
-function language_url_rewrite(&$path, &$options) {
-  // Only modify relative (insite) URLs.
-  if (!$options['external']) {
-    static $callbacks;
-
-    if (!isset($callbacks)) {
-      $callbacks = array();
-
-      foreach (language_types_configurable() as $type) {
-        // Get url rewriter callbacks only from enabled language providers.
-        $negotiation = variable_get("language_negotiation_$type", array());
-
-        foreach ($negotiation as $id => $provider) {
-          if (isset($provider['file'])) {
-            require_once DRUPAL_ROOT . '/' . $provider['file'];
-          }
-
-          // Avoid duplicate callback entries.
-          if (isset($provider['callbacks']['url_rewrite'])) {
-            $callbacks[$provider['callbacks']['url_rewrite']] = NULL;
-          }
-        }
-      }
-
-      $callbacks = array_keys($callbacks);
-    }
-
-    foreach ($callbacks as $callback) {
-      $callback($path, $options);
-    }
-  }
-}
-
-/**
  * Split the given path into prefix and actual path.
  *
  * Parse the given path and return the language object identified by the
Index: includes/path.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/includes/path.inc,v
retrieving revision 1.45
diff -u -p -r1.45 path.inc
--- includes/path.inc	15 Oct 2009 17:53:34 -0000	1.45
+++ includes/path.inc	16 Oct 2009 05:12:32 -0000
@@ -6,8 +6,8 @@
  * Functions to handle paths in Drupal, including path aliasing.
  *
  * These functions are not loaded for cached pages, but modules that need
- * to use them in hook_init() or hook exit() can make them available, by
- * executing "drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);".
+ * to use them in hook_boot() or hook exit() can make them available, by
+ * executing "drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);".
  */
 
 /**
@@ -205,13 +205,21 @@ function drupal_get_path_alias($path = N
  */
 function drupal_get_normal_path($path, $path_language = '') {
   $result = $path;
+
+  // Lookup the path alias first.
   if ($source = drupal_lookup_path('source', $path, $path_language)) {
     $result = $source;
   }
-  if (function_exists('custom_url_rewrite_inbound')) {
-    // Modules may alter the inbound request path by reference.
-    custom_url_rewrite_inbound($result, $path, $path_language);
+
+  // Allow other modules to alter the inbound URL. We cannot use drupal_alter()
+  // here because we need to run hook_url_inbound_alter() in the reverse order
+  // of hook_url_outbound_alter().
+  $result_copy = $result;
+  foreach (array_reverse(module_implements('url_inbound_alter')) as $module) {
+    $function = $module . '_url_inbound_alter';
+    $function($result, $result_copy, $path_language);
   }
+
   return $result;
 }
 
@@ -347,7 +355,7 @@ function drupal_match_path($path, $patte
  * This function is not available in hook_boot() so use $_GET['q'] instead.
  * However, be careful when doing that because in the case of Example #3
  * $_GET['q'] will contain "path/alias". If "node/306" is needed, calling
- * drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH) makes this function available.
+ * drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) makes this function available.
  *
  * @return
  *   The current Drupal URL path.
cvs diff: Diffing includes/database
cvs diff: Diffing includes/database/mysql
cvs diff: Diffing includes/database/pgsql
cvs diff: Diffing includes/database/sqlite
cvs diff: Diffing includes/filetransfer
cvs diff: Diffing modules/forum
Index: modules/forum/forum.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/forum/forum.module,v
retrieving revision 1.524
diff -u -p -r1.524 forum.module
--- modules/forum/forum.module	15 Oct 2009 12:44:36 -0000	1.524
+++ modules/forum/forum.module	16 Oct 2009 05:12:32 -0000
@@ -115,12 +115,6 @@ function forum_menu() {
     'parent' => 'admin/structure/forum',
     'file' => 'forum.admin.inc',
   );
-  $items['admin/structure/forum/edit/%taxonomy_term'] = array(
-    'page callback' => 'forum_form_main',
-    'access arguments' => array('administer forums'),
-    'type' => MENU_CALLBACK,
-    'file' => 'forum.admin.inc',
-  );
   $items['admin/structure/forum/edit/container/%taxonomy_term'] = array(
     'title' => 'Edit container',
     'page callback' => 'forum_form_main',
@@ -610,7 +604,7 @@ function forum_block_view_pre_render($el
  */
 function forum_form($node, $form_state) {
   $type = node_type_get_type($node);
-  
+
   if (!empty($node->nid)) {
     $forum_terms = $node->taxonomy_forums;
     // If editing, give option to leave shadows
@@ -626,10 +620,15 @@ function forum_form($node, $form_state) 
 }
 
 /**
- * Implement hook_term_path().
+ * Implement hook_url_outbound_alter().
  */
-function forum_term_path($term) {
-  return 'forum/' . $term->tid;
+function forum_url_outbound_alter(&$path, &$options) {
+  if (preg_match('!^taxonomy/term/(\d+)!', $path, $matches)) {
+    $term = taxonomy_term_load($matches[1]);
+    if ($term && $term->vocabulary_machine_name == 'forums') {
+      $path = 'forum/' . $matches[1];
+    }
+  }
 }
 
 /**
Index: modules/forum/forum.test
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/forum/forum.test,v
retrieving revision 1.34
diff -u -p -r1.34 forum.test
--- modules/forum/forum.test	11 Oct 2009 03:07:18 -0000	1.34
+++ modules/forum/forum.test	16 Oct 2009 05:12:32 -0000
@@ -204,7 +204,7 @@ class ForumTestCase extends DrupalWebTes
   function deleteForum($tid) {
     // Delete the forum.
     $this->drupalPost('admin/structure/forum/edit/forum/' . $tid, array(), t('Delete'));
-    $this->drupalPost(NULL, NULL, t('Delete'));
+    $this->drupalPost(NULL, array(), t('Delete'));
 
     // Assert that the forum no longer exists.
     $this->drupalGet('forum/' . $tid);
cvs diff: Diffing modules/locale
Index: modules/locale/locale.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/locale/locale.module,v
retrieving revision 1.264
diff -u -p -r1.264 locale.module
--- modules/locale/locale.module	16 Oct 2009 02:04:42 -0000	1.264
+++ modules/locale/locale.module	16 Oct 2009 05:12:32 -0000
@@ -1067,3 +1067,41 @@ function locale_date_format_reset_form_s
   $form_state['redirect'] = 'admin/config/regional/date-time/locale';
 }
 
+/**
+ * Implement hook_url_outbound_alter().
+ *
+ * Rewrite outbound URLs with language based prefixes.
+ */
+function locale_url_outbound_alter(&$path, &$options) {
+  // Only modify internal URLs.
+  if (!$options['external']) {
+    static $callbacks;
+
+    if (!isset($callbacks)) {
+      $callbacks = array();
+      include_once DRUPAL_ROOT . '/includes/language.inc';
+
+      foreach (language_types_configurable() as $type) {
+        // Get url rewriter callbacks only from enabled language providers.
+        $negotiation = variable_get("language_negotiation_$type", array());
+
+        foreach ($negotiation as $id => $provider) {
+          if (isset($provider['file'])) {
+            require_once DRUPAL_ROOT . '/' . $provider['file'];
+          }
+
+          // Avoid duplicate callback entries.
+          if (isset($provider['callbacks']['url_rewrite'])) {
+            $callbacks[$provider['callbacks']['url_rewrite']] = NULL;
+          }
+        }
+      }
+
+      $callbacks = array_keys($callbacks);
+    }
+
+    foreach ($callbacks as $callback) {
+      $callback($path, $options);
+    }
+  }
+}
cvs diff: Diffing modules/locale/tests
cvs diff: Diffing modules/locale/tests/translations
cvs diff: Diffing modules/path
Index: modules/path/path.admin.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/path/path.admin.inc,v
retrieving revision 1.34
diff -u -p -r1.34 path.admin.inc
--- modules/path/path.admin.inc	15 Oct 2009 17:53:34 -0000	1.34
+++ modules/path/path.admin.inc	16 Oct 2009 05:12:32 -0000
@@ -104,7 +104,7 @@ function path_admin_form($form, &$form_s
     '#default_value' => $path['source'],
     '#maxlength' => 255,
     '#size' => 45,
-    '#description' => t('Specify the existing path you wish to alias. For example: node/28, forum/1, taxonomy/term/1+2.'),
+    '#description' => t('Specify the existing path you wish to alias. For example: node/28, forum/1, taxonomy/term/1.'),
     '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='),
     '#required' => TRUE,
   );
@@ -149,7 +149,8 @@ function path_admin_form($form, &$form_s
  * Verify that a URL alias is valid
  */
 function path_admin_form_validate($form, &$form_state) {
-  $source = $form_state['values']['source'];
+  $source = &$form_state['values']['source'];
+  $source = drupal_get_normal_path($source);
   $alias = $form_state['values']['alias'];
   $pid = isset($form_state['values']['pid']) ? $form_state['values']['pid'] : 0;
   // Language is only set if locale module is enabled, otherwise save for all languages.
cvs diff: Diffing modules/simpletest
cvs diff: Diffing modules/simpletest/files
cvs diff: Diffing modules/simpletest/files/css_test_files
cvs diff: Diffing modules/simpletest/tests
Index: modules/simpletest/tests/path.test
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/simpletest/tests/path.test,v
retrieving revision 1.1
diff -u -p -r1.1 path.test
--- modules/simpletest/tests/path.test	11 Sep 2009 02:19:02 -0000	1.1
+++ modules/simpletest/tests/path.test	16 Oct 2009 05:12:33 -0000
@@ -126,3 +126,111 @@ class DrupalMatchPathTestCase extends Dr
     );
   }
 }
+
+/**
+ * Tests hook_url_alter functions.
+ */
+class UrlAlterFunctionalTest extends DrupalWebTestCase {
+  public static function getInfo() {
+    return array(
+      'name' => t('URL altering'),
+      'description' => t('Tests hook_url_inbound_alter() and hook_url_outbound_alter().'),
+      'group' => t('Path API'),
+    );
+  }
+
+  function setUp() {
+    parent::setUp('path', 'forum', 'url_alter_test');
+  }
+
+  /**
+   * Test that URL altering works and that it occurs in the correct order.
+   */
+  function testUrlAlter() {
+    $account = $this->drupalCreateUser(array('administer url aliases'));
+    $this->drupalLogin($account);
+
+    $uid = $account->uid;
+    $name = $account->name;
+
+    // Test a single altered path.
+    $this->assertUrlInboundAlter("user/$name", "user/$uid");
+    $this->assertUrlOutboundAlter("user/$uid", "user/$name");
+
+    // Test that a path always uses its alias.
+    path_save(array('source' => "user/$uid/test1", 'alias' => 'alias/test1'));
+    $this->assertUrlInboundAlter('alias/test1', "user/$uid/test1");
+    $this->assertUrlOutboundAlter("user/$uid/test1", 'alias/test1');
+
+    // Test that alias source paths are normalized in the interface.
+    $edit = array('source' => "user/$name/edit", 'alias' => 'alias/test2');
+    $this->drupalPost('admin/config/search/path/add', $edit, t('Create new alias'));
+    $this->assertText(t('The alias has been saved.'));
+
+    // Test that a path always uses its alias.
+    $this->assertUrlInboundAlter('alias/test2', "user/$uid/edit");
+    $this->assertUrlOutboundAlter("user/$uid/edit", 'alias/test2');
+
+    // Test a non-existant user is not altered.
+    $uid++;
+    $this->assertUrlInboundAlter("user/$uid", "user/$uid");
+    $this->assertUrlOutboundAlter("user/$uid", "user/$uid");
+
+    // Test that 'forum' is altered to 'community' correctly.
+    $this->assertUrlInboundAlter('community', 'forum');
+    $this->assertUrlOutboundAlter('forum', 'community');
+
+    // Add a forum to test url altering.
+    $forum_vid = db_query("SELECT vid FROM {taxonomy_vocabulary} WHERE module = 'forum'")->fetchField();
+    $tid = db_insert('taxonomy_term_data')
+      ->fields(array(
+        'name' => $this->randomName(),
+        'vid' => $forum_vid,
+      ))
+      ->execute();
+
+    // Test that a existing forum URL is altered.
+    $this->assertUrlInboundAlter("community/$tid", "forum/$tid");
+    $this->assertUrlOutboundAlter("taxonomy/term/$tid", "community/$tid");
+
+    // Test that a non-existant forum URL is not altered.
+    $tid++;
+    $this->assertUrlInboundAlter("taxonomy/term/$tid", "taxonomy/term/$tid");
+    $this->assertUrlOutboundAlter("taxonomy/term/$tid", "taxonomy/term/$tid");
+  }
+
+  /**
+   * Assert that an outbound path is altered to an expected value.
+   *
+   * @param $original
+   *   A string with the original path that is run through url().
+   * @param $final
+   *   A string with the expected result after url().
+   * @return
+   *   TRUE if $original was correctly altered to $final, FALSE otherwise.
+   */
+  protected function assertUrlOutboundAlter($original, $final) {
+    // Test outbound altering.
+    $result = url($original);
+    $base_path = base_path() . (variable_get('clean_url', '0') ? '' : '?q=');
+    $result = substr($result, strlen($base_path));
+    $this->assertIdentical($result, $final, t('Altered outbound URL %original, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result)));
+  }
+
+  /**
+   * Assert that a inbound path is altered to an expected value.
+   *
+   * @param $original
+   *   A string with the aliased or un-normal path that is run through
+   *   drupal_get_normal_path().
+   * @param $final
+   *   A string with the expected result after url().
+   * @return
+   *   TRUE if $original was correctly altered to $final, FALSE otherwise.
+   */
+  protected function assertUrlInboundAlter($original, $final) {
+    // Test inbound altering.
+    $result = drupal_get_normal_path($original);
+    $this->assertIdentical($result, $final, t('Altered inbound URL %origianl, expected %final, and got %result.', array('%original' => $original, '%final' => $final, '%result' => $result)));
+  }
+}
Index: modules/simpletest/tests/url_alter_test.info
===================================================================
RCS file: modules/simpletest/tests/url_alter_test.info
diff -N modules/simpletest/tests/url_alter_test.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/url_alter_test.info	16 Oct 2009 05:12:33 -0000
@@ -0,0 +1,9 @@
+; $Id$
+name = Url_alter tests
+description = A support modules for url_alter hook testing.
+core = 7.x
+package = Testing
+version = VERSION
+files[] = url_alter_test.module
+files[] = url_alter_test.install
+hidden = TRUE
Index: modules/simpletest/tests/url_alter_test.install
===================================================================
RCS file: modules/simpletest/tests/url_alter_test.install
diff -N modules/simpletest/tests/url_alter_test.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/url_alter_test.install	16 Oct 2009 05:12:33 -0000
@@ -0,0 +1,13 @@
+<?php
+// $Id$
+
+/**
+ * Impelement hook_install().
+ */
+function url_alter_test_install() {
+  // Set the weight of this module to one higher than forum.module.
+  db_update('system')
+    ->fields(array('weight' => 2))
+    ->condition('name', 'url_alter_test')
+    ->execute();
+}
Index: modules/simpletest/tests/url_alter_test.module
===================================================================
RCS file: modules/simpletest/tests/url_alter_test.module
diff -N modules/simpletest/tests/url_alter_test.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ modules/simpletest/tests/url_alter_test.module	16 Oct 2009 05:12:33 -0000
@@ -0,0 +1,43 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Module to help test hook_url_inbound_alter() and hook_url_outbound_alter().
+ */
+
+/**
+ * Implement hook_url_inbound_alter().
+ */
+function url_alter_test_url_inbound_alter(&$path, $original_path, $path_language) {
+  // Rewrite user/username to user/uid.
+  if (preg_match('!^user/([^/]+)(/.*)?!', $path, $matches)) {
+    if ($account = user_load_by_name($matches[1])) {
+      $matches += array(2 => '');
+      $path = 'user/' . $account->uid . $matches[2];
+    }
+  }
+
+  // Rewrite community/ to forum/.
+  if ($path == 'community' || strpos($path, 'community/') === 0) {
+    $path = 'forum' . substr($path, 9);
+  }
+}
+
+/**
+ * Implement hook_url_outbound_alter().
+ */
+function url_alter_test_url_outbound_alter(&$path, &$options) {
+  // Rewrite user/uid to user/username.
+  if (preg_match('!^user/([0-9]+)(/.*)?!', $path, $matches)) {
+    if ($account = user_load($matches[1])) {
+      $matches += array(2 => '');
+      $path = 'user/' . $account->name . $matches[2];
+    }
+  }
+
+  // Rewrite forum/ to community/.
+  if ($path == 'forum' || strpos($path, 'forum/') === 0) {
+    $path = 'community' . substr($path, 5);
+  }
+}
cvs diff: Diffing modules/statistics
Index: modules/statistics/statistics.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/statistics/statistics.module,v
retrieving revision 1.320
diff -u -p -r1.320 statistics.module
--- modules/statistics/statistics.module	5 Sep 2009 13:49:28 -0000	1.320
+++ modules/statistics/statistics.module	16 Oct 2009 05:12:33 -0000
@@ -45,7 +45,7 @@ function statistics_help($path, $arg) {
 function statistics_exit() {
   global $user;
 
-  drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH);
+  drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
 
   if (variable_get('statistics_count_content_views', 0)) {
     // We are counting content views.
cvs diff: Diffing modules/system
Index: modules/system/system.api.php
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/system/system.api.php,v
retrieving revision 1.92
diff -u -p -r1.92 system.api.php
--- modules/system/system.api.php	16 Oct 2009 03:47:14 -0000	1.92
+++ modules/system/system.api.php	16 Oct 2009 05:12:33 -0000
@@ -2654,5 +2654,59 @@ function hook_page_delivery_callback_alt
 }
 
 /**
+ * Alters inbound URL requests.
+ *
+ * @param $path
+ *   The path being constructed, which, if a path alias, has been resolved to a
+ *   Drupal path by the database, and which also may have been altered by other
+ *   modules before this one.
+ * @param $original_path
+ *   The original path, before being checked for path aliases or altered by the
+ *   modules.
+ * @param $path_language
+ *   The language of the path.
+ *
+ * @see drupal_get_normal_path()
+ */
+function hook_url_inbound_alter(&$path, $original_path, $path_language) {
+  // Create the path user/me/edit, which allows a user to edit their account.
+  if (preg_match('|^user/me/edit(/.*)?|', $path, $matches)) {
+    global $user;
+    $path = 'user/' . $user->uid . '/edit' . $matches[1];
+  }
+}
+
+/**
+ * Alters outbound URLs.
+ *
+ * @param $path
+ *   The outbound path to alter, not adjusted for path aliases yet. It won't be
+ *   adjusted for path aliases until all modules are finished altering it, thus
+ *   being consistent with hook_url_alter_inbound(), which adjusts for all path
+ *   aliases before allowing modules to alter it. This may have been altered by
+ *   other modules before this one.
+ * @param $options
+ *   A set of URL options for the URL so elements such as a fragment or a query
+ *   string can be added to the URL.
+ *
+ * @see url()
+ */
+function hook_url_outbound_alter(&$path, &$options) {
+  // Use an external RSS feed rather than the Drupal one.
+  if ($path == 'rss.xml') {
+    $path = 'http://example.com/rss.xml';
+    $options['external'] = TRUE;
+  }
+
+  // Instead of pointing to user/[uid]/edit, point to user/me/edit.
+  if (preg_match('|^user/([0-9]*)/edit(/.*)?|', $path, $matches)) {
+    global $user;
+    if ($user->uid == $matches[1]) {
+      $path = 'user/me/edit' . $matches[2];
+    }
+  }
+}
+
+/**
  * @} End of "addtogroup hooks".
  */
cvs diff: Diffing modules/taxonomy
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.523
diff -u -p -r1.523 taxonomy.module
--- modules/taxonomy/taxonomy.module	16 Oct 2009 03:21:23 -0000	1.523
+++ modules/taxonomy/taxonomy.module	16 Oct 2009 05:12:33 -0000
@@ -158,23 +158,6 @@ function taxonomy_theme() {
 }
 
 /**
- * For vocabularies not maintained by taxonomy.module, give the maintaining
- * module a chance to provide a path for terms in that vocabulary.
- *
- * @param $term
- *   A term object.
- * @return
- *   An internal Drupal path.
- */
-function taxonomy_term_path($term) {
-  $vocabulary = taxonomy_vocabulary_load($term->vid);
-  if ($vocabulary->module != 'taxonomy' && $path = module_invoke($vocabulary->module, 'term_path', $term)) {
-    return $path;
-  }
-  return 'taxonomy/term/' . $term->tid;
-}
-
-/**
  * Implement hook_menu().
  */
 function taxonomy_menu() {
@@ -1093,7 +1076,7 @@ function taxonomy_field_formatter_info()
  */
 function theme_field_formatter_taxonomy_term_link($variables) {
   $term = $variables['element']['#item']['taxonomy_term'];
-  return l($term->name, taxonomy_term_path($term));
+  return l($term->name, 'taxonomy/term/' . $term->tid, array('term' => $term));
 }
 
 /**
@@ -1494,4 +1477,3 @@ function taxonomy_taxonomy_term_delete($
 /**
  * @} End of "defgroup taxonomy indexing"
  */
-
Index: modules/taxonomy/taxonomy.pages.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/taxonomy/taxonomy.pages.inc,v
retrieving revision 1.40
diff -u -p -r1.40 taxonomy.pages.inc
--- modules/taxonomy/taxonomy.pages.inc	16 Oct 2009 03:21:23 -0000	1.40
+++ modules/taxonomy/taxonomy.pages.inc	16 Oct 2009 05:12:33 -0000
@@ -22,7 +22,7 @@ function taxonomy_term_page($term) {
   $breadcrumb = array();
   while ($parents = taxonomy_get_parents($current->tid)) {
     $current = array_shift($parents);
-    $breadcrumb[] = l($current->name, taxonomy_term_path($current));
+    $breadcrumb[] = l($current->name, 'taxonomy/term/' . $current->tid);
   }
   $breadcrumb[] = l(t('Home'), NULL);
   $breadcrumb = array_reverse($breadcrumb);
Index: modules/taxonomy/taxonomy.tokens.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/drupal/modules/taxonomy/taxonomy.tokens.inc,v
retrieving revision 1.2
diff -u -p -r1.2 taxonomy.tokens.inc
--- modules/taxonomy/taxonomy.tokens.inc	18 Sep 2009 00:04:23 -0000	1.2
+++ modules/taxonomy/taxonomy.tokens.inc	16 Oct 2009 05:12:33 -0000
@@ -119,7 +119,7 @@ function taxonomy_tokens($type, $tokens,
           break;
 
         case 'url':
-          $replacements[$original] = url(taxonomy_term_path($term), array('absolute' => TRUE));
+          $replacements[$original] = url('taxonomy/term/' . $term, array('absolute' => TRUE));
           break;
 
         case 'node-count':
