Index: modules/openid/openid.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/openid/openid.test,v
retrieving revision 1.31
diff -u -p -r1.31 openid.test
--- modules/openid/openid.test	22 Aug 2010 22:00:16 -0000	1.31
+++ modules/openid/openid.test	5 Oct 2010 03:59:04 -0000
@@ -20,6 +20,16 @@ abstract class OpenIDWebTestCase extends
     // Submit form to the OpenID Provider Endpoint.
     $this->drupalPost(NULL, array(), t('Send'));
   }
+
+  /**
+   * Parses the last sent e-mail and returns the one-time login link URL.
+   */
+  function getPasswordResetURLFromMail() {
+    $mails = $this->drupalGetMails();
+    $mail = end($mails);
+    preg_match('@.+user/reset/.+@', $mail['body'], $matches);
+    return $matches[0];
+  }
 }
 
 /**
@@ -126,7 +136,7 @@ class OpenIDFunctionalTestCase extends O
 
     // Test logging in via the login block on the front page.
     $this->submitLoginForm($identity);
-    $this->assertLink($this->web_user->name, 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
 
     $this->drupalLogout();
 
@@ -140,7 +150,7 @@ class OpenIDFunctionalTestCase extends O
     // Submit form to the OpenID Provider Endpoint.
     $this->drupalPost(NULL, array(), t('Send'));
 
-    $this->assertLink($this->web_user->name, 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
 
     // Verify user was redirected away from user/login to an accessible page.
     $this->assertResponse(200);
@@ -171,7 +181,7 @@ class OpenIDFunctionalTestCase extends O
     // Submit form to the OpenID Provider Endpoint.
     $this->drupalPost(NULL, array(), t('Send'));
 
-    $this->assertLink($this->web_user->name, 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
 
     // Verify user was redirected away from user/login to an accessible page.
     $this->assertText(t('Operating in maintenance mode.'));
@@ -316,6 +326,7 @@ class OpenIDRegistrationTestCase extends
     $this->submitLoginForm($identity);
     $this->assertRaw(t('Once you have verified your e-mail address, you may log in via OpenID.'), t('User was asked to verify e-mail address.'));
     $this->assertRaw(t('A welcome message with further instructions has been sent to your e-mail address.'), t('A welcome message was sent to the user.'));
+    $reset_url = $this->getPasswordResetURLFromMail();
 
     $user = user_load_by_name('john');
     $this->assertTrue($user, t('User was registered with right username.'));
@@ -326,14 +337,14 @@ class OpenIDRegistrationTestCase extends
     $this->assertRaw(t('You must validate your email address for this account before logging in via OpenID.'));
 
     // Follow the one-time login that was sent in the welcome e-mail.
-    $this->drupalGet(user_pass_reset_url($user));
+    $this->drupalGet($reset_url);
     $this->drupalPost(NULL, array(), t('Log in'));
 
     $this->drupalLogout();
 
     // Verify that the account was activated.
     $this->submitLoginForm($identity);
-    $this->assertLink('john', 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
   }
 
   /**
@@ -348,7 +359,7 @@ class OpenIDRegistrationTestCase extends
     // Use a User-supplied Identity that is the URL of an XRDS document.
     $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
     $this->submitLoginForm($identity);
-    $this->assertLink('john', 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
 
     $user = user_load_by_name('john');
     $this->assertTrue($user, t('User was registered with right username.'));
@@ -358,7 +369,7 @@ class OpenIDRegistrationTestCase extends
     $this->drupalLogout();
 
     $this->submitLoginForm($identity);
-    $this->assertLink('john', 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
   }
 
   /**
@@ -382,13 +393,14 @@ class OpenIDRegistrationTestCase extends
     $edit = array('name' => 'john', 'mail' => 'john@example.com');
     $this->drupalPost(NULL, $edit, t('Create new account'));
     $this->assertRaw(t('Once you have verified your e-mail address, you may log in via OpenID.'), t('User was asked to verify e-mail address.'));
+    $reset_url = $this->getPasswordResetURLFromMail();
 
     $user = user_load_by_name('john');
     $this->assertTrue($user, t('User was registered with right username.'));
     $this->assertFalse($user->data, t('No additional user info was saved.'));
 
     // Follow the one-time login that was sent in the welcome e-mail.
-    $this->drupalGet(user_pass_reset_url($user));
+    $this->drupalGet($reset_url);
     $this->drupalPost(NULL, array(), t('Log in'));
 
     // The user is taken to user/%uid/edit.
@@ -417,13 +429,14 @@ class OpenIDRegistrationTestCase extends
     $edit = array('name' => 'john', 'mail' => 'john@example.com');
     $this->drupalPost(NULL, $edit, t('Create new account'));
     $this->assertRaw(t('Once you have verified your e-mail address, you may log in via OpenID.'), t('User was asked to verify e-mail address.'));
+    $reset_url = $this->getPasswordResetURLFromMail();
 
     $user = user_load_by_name('john');
     $this->assertTrue($user, t('User was registered with right username.'));
     $this->assertFalse($user->data, t('No additional user info was saved.'));
 
     // Follow the one-time login that was sent in the welcome e-mail.
-    $this->drupalGet(user_pass_reset_url($user));
+    $this->drupalGet($reset_url);
     $this->drupalPost(NULL, array(), t('Log in'));
 
     // The user is taken to user/%uid/edit.
@@ -453,7 +466,7 @@ class OpenIDRegistrationTestCase extends
     // Use a User-supplied Identity that is the URL of an XRDS document.
     $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
     $this->submitLoginForm($identity);
-    $this->assertLink('john', 0, t('User was logged in.'));
+    $this->assertLink(t('Log out'), 0, t('User was logged in.'));
 
     $user = user_load_by_name('john');
     $this->assertTrue($user, t('User was registered with right username.'));
Index: modules/simpletest/tests/menu.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/menu.test,v
retrieving revision 1.36
diff -u -p -r1.36 menu.test
--- modules/simpletest/tests/menu.test	1 Oct 2010 15:24:18 -0000	1.36
+++ modules/simpletest/tests/menu.test	5 Oct 2010 02:49:58 -0000
@@ -872,19 +872,50 @@ class MenuBreadcrumbTestCase extends Dru
     // Verify breadcrumb on front page.
     $this->assertBreadcrumb('<front>', array());
 
+    // Verify breadcrumb on user pages (without menu link) for anonymous user.
     $trail = $home;
     $this->assertBreadcrumb('user', $trail, t('User account'));
     $this->assertBreadcrumb('user/' . $this->admin_user->uid, $trail, $this->admin_user->name);
 
+    // Verify breadcrumb on user pages (without menu link) for registered users.
     $this->drupalLogin($this->admin_user);
+    $trail = $home;
+    $this->assertBreadcrumb('user', $trail, $this->admin_user->name);
+    $this->assertBreadcrumb('user/' . $this->admin_user->uid, $trail, $this->admin_user->name);
+    $trail += array(
+      'user/' . $this->admin_user->uid => $this->admin_user->name,
+    );
+    $this->assertBreadcrumb('user/' . $this->admin_user->uid . '/edit', $trail, $this->admin_user->name);
+
+    // Create a second user to verify breadcrumb on user pages again.
+    $this->web_user = $this->drupalCreateUser(array(
+      'administer users',
+      'access user profiles',
+    ));
+    $this->drupalLogin($this->web_user);
+
+    // Verify correct breadcrumb and page title on another user's account pages
+    // (without menu link).
+    $trail = $home;
+    $this->assertBreadcrumb('user/' . $this->admin_user->uid, $trail, $this->admin_user->name);
     $trail += array(
       'user/' . $this->admin_user->uid => $this->admin_user->name,
     );
     $this->assertBreadcrumb('user/' . $this->admin_user->uid . '/edit', $trail, $this->admin_user->name);
 
+    // Verify correct breadcrumb and page title when viewing own user account
+    // pages (without menu link).
+    $trail = $home;
+    $this->assertBreadcrumb('user/' . $this->web_user->uid, $trail, $this->web_user->name);
+    $trail += array(
+      'user/' . $this->web_user->uid => $this->web_user->name,
+    );
+    $this->assertBreadcrumb('user/' . $this->web_user->uid . '/edit', $trail, $this->web_user->name);
+
     // Add a Navigation menu links for 'user' and $this->admin_user.
     // Although it may be faster to manage these links via low-level API
     // functions, there's a lot that can go wrong in doing so.
+    $this->drupalLogin($this->admin_user);
     $edit = array(
       'link_title' => 'User',
       'link_path' => 'user',
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1206
diff -u -p -r1.1206 user.module
--- modules/user/user.module	4 Oct 2010 14:54:10 -0000	1.1206
+++ modules/user/user.module	5 Oct 2010 02:49:58 -0000
@@ -1520,15 +1520,12 @@ function user_menu() {
   // Registration and login pages.
   $items['user'] = array(
     'title' => 'User account',
+    'title callback' => 'user_menu_title',
     'page callback' => 'user_page',
     'access callback' => TRUE,
-    // Edge-case: No menu links should be auto-generated for this and below
-    // items, which makes it a MENU_CALLBACK. However, this item's title is
-    // expected to appear on user login, register, and password pages, so we
-    // need to use MENU_VISIBLE_IN_BREADCRUMB to make
-    // menu_get_active_breadcrumb() account for it.
-    'type' => MENU_VISIBLE_IN_BREADCRUMB,
     'file' => 'user.pages.inc',
+    'weight' => -10,
+    'menu_name' => 'user-menu',
   );
 
   $items['user/login'] = array(
@@ -1568,6 +1565,11 @@ function user_menu() {
     'page callback' => 'user_logout',
     'weight' => 10,
     'menu_name' => 'user-menu',
+    // Ignore router path inheritance to make the Logout link appear on the
+    // top-level of the user menu by default. The forced parent link ID is only
+    // taken into account as long as the link has not been customized.
+    // @see menu_link_save()
+    'plid' => 0,
     'file' => 'user.pages.inc',
   );
 
@@ -1665,9 +1667,7 @@ function user_menu() {
     'weight' => -10,
   );
 
-  // Use %user_uid_only_optional here to avoid loading the full user for
-  // basic access checks.
-  $items['user/%user_uid_only_optional'] = array(
+  $items['user/%user'] = array(
     'title' => 'My account',
     'title callback' => 'user_page_title',
     'title arguments' => array(1),
@@ -1675,8 +1675,12 @@ function user_menu() {
     'page arguments' => array(1),
     'access callback' => 'user_view_access',
     'access arguments' => array(1),
-    'weight' => -10,
-    'menu_name' => 'user-menu',
+    // By assigning a different menu name, this item (and all registered child
+    // paths) are no longer considered as children of 'user'. When accessing the
+    // user account pages, the preferred menu link that is used to build the
+    // active trail (breadcrumb) will be found in this menu (unless there is
+    // more specific link), so the link to 'user' will not be in the breadcrumb.
+    'menu_name' => 'navigation',
   );
 
   $items['user/%user/view'] = array(
@@ -1867,24 +1871,19 @@ function user_uid_optional_to_arg($arg) 
 }
 
 /**
- * Returns $arg or the user ID of the current user if $arg is '%' or empty.
+ * Menu item title callback for the 'user' path.
  *
- * @todo rethink the naming of this in Drupal 8.
+ * Anonymous users should see "User account", but authenticated users are
+ * expected to see "My account".
  */
-function user_uid_only_optional_to_arg($arg) {
-  return user_uid_optional_to_arg($arg);
+function user_menu_title() {
+  return user_is_logged_in() ? t('My account') : t('User account');
 }
 
 /**
  * Menu item title callback - use the user name.
  */
-function user_page_title($uid) {
-  if ($GLOBALS['user']->uid == $uid) {
-    $account = $GLOBALS['user'];
-  }
-  else {
-    $account = user_load($uid);
-  }
+function user_page_title($account) {
   return is_object($account) ? format_username($account) : '';
 }
 
@@ -2359,10 +2358,9 @@ function user_delete_multiple(array $uid
 /**
  * Page callback wrapper for user_view().
  */
-function user_view_page($uid) {
+function user_view_page($account) {
   // An administrator may try to view a non-existent account,
   // so we give them a 404 (versus a 403 for non-admins).
-  $account = user_load($uid);
   return is_object($account) ? user_view($account) : MENU_NOT_FOUND;
 }
 
