Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.302
diff -u -p -r1.302 bootstrap.inc
--- includes/bootstrap.inc	24 Aug 2009 00:14:18 -0000	1.302
+++ includes/bootstrap.inc	26 Aug 2009 19:13:57 -0000
@@ -167,20 +167,24 @@ define('LANGUAGE_NEGOTIATION_NONE', 0);
  * Path based negotiation with fallback to default language
  * if no defined path prefix identified.
  */
-define('LANGUAGE_NEGOTIATION_PATH_DEFAULT', 1);
+define('LANGUAGE_NEGOTIATION_URL_DEFAULT', 1);
 
 /**
  * Path based negotiation with fallback to user preferences
  * and browser language detection if no defined path prefix
  * identified.
  */
-define('LANGUAGE_NEGOTIATION_PATH', 2);
+define('LANGUAGE_NEGOTIATION_URL', 2);
 
 /**
- * Domain based negotiation with fallback to default language
- * if no language identified by domain.
+ * TODO
  */
-define('LANGUAGE_NEGOTIATION_DOMAIN', 3);
+define('LANGUAGE_NEGOTIATION_URL_PREFIX', 3);
+
+/**
+ * TODO
+ */
+define('LANGUAGE_NEGOTIATION_URL_DOMAIN', 4);
 
 /**
  * Language written left to right. Possible value of $language->direction.
@@ -1641,16 +1645,20 @@ function get_t() {
  *  Choose a language for the current page, based on site and user preferences.
  */
 function drupal_language_initialize() {
-  global $language, $user;
+  global $language, $ui_language, $user;
 
   // Ensure the language is correctly returned, even without multilanguage support.
   // Useful for eg. XML/HTML 'lang' attributes.
   if (variable_get('language_count', 1) == 1) {
-    $language = language_default();
+    $language = $ui_language = language_default();
   }
   else {
     include_once DRUPAL_ROOT . '/includes/language.inc';
-    $language = language_initialize();
+    $language = language_from_url();
+    if ($language->language == language_none()->language) {
+      $language = language_default();
+    }
+    $ui_language = language_ui_initialize();
   }
 }
 
@@ -1701,6 +1709,25 @@ function language_default($property = NU
 }
 
 /**
+ * Language neutral content language.
+ */
+function language_none() {
+  return (object) array(
+    'language' => 'zxx',
+    'name' => '',
+    'native' => '',
+    'direction' => 0,
+    'enabled' => 1,
+    'plurals' => '',
+    'formula' => '',
+    'domain' => '',
+    'prefix' => '',
+    'weight' => 0,
+    'javascript' => '',
+  );
+}
+
+/**
  * If Drupal is behind a reverse proxy, we use the X-Forwarded-For header
  * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address of
  * the proxy server, and not the client's. If Drupal is run in a cluster
Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.977
diff -u -p -r1.977 common.inc
--- includes/common.inc	26 Aug 2009 15:00:17 -0000	1.977
+++ includes/common.inc	26 Aug 2009 19:13:57 -0000
@@ -1193,12 +1193,12 @@ function fix_gpc_magic() {
  *   The translated string.
  */
 function t($string, array $args = array(), array $options = array()) {
-  global $language;
+  global $ui_language;
   static $custom_strings;
 
   // Merge in default.
   if (empty($options['langcode'])) {
-    $options['langcode'] = isset($language->language) ? $language->language : 'en';
+    $options['langcode'] = isset($ui_language->language) ? $ui_language->language : 'en';
   }
   if (empty($options['context'])) {
     $options['context'] = '';
@@ -1220,7 +1220,7 @@ function t($string, array $args = array(
   // framework if the locale module is enabled in the parent site (we cannot
   // unload functions in PHP).
   elseif (function_exists('locale') && $options['langcode'] != 'en') {
-    $string = locale($string, $options['context'], $options['langcode']);
+    $string = locale($old_string = $string, $options['context'], $options['langcode']);
   }
   if (empty($args)) {
     return $string;
Index: includes/language.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/language.inc,v
retrieving revision 1.19
diff -u -p -r1.19 language.inc
--- includes/language.inc	1 Feb 2009 16:45:53 -0000	1.19
+++ includes/language.inc	26 Aug 2009 20:16:13 -0000
@@ -7,58 +7,44 @@
  */
 
 /**
- *  Choose a language for the page, based on language negotiation settings.
+ *  Choose a language for the interface, based on language negotiation settings.
  */
-function language_initialize() {
+function language_ui_initialize() {
   global $user;
 
+  // User preference, if allowed.
+  if ($user->uid && !variable_get('language_negotiation_user_override', TRUE)) {
+    return language_from_user();
+  }
+
   // Configured presentation language mode.
   $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
-  // Get a list of enabled languages.
-  $languages = language_list('enabled');
-  $languages = $languages[1];
-
   switch ($mode) {
     case LANGUAGE_NEGOTIATION_NONE:
       return language_default();
 
-    case LANGUAGE_NEGOTIATION_DOMAIN:
-      foreach ($languages as $language) {
-        $host = parse_url($language->domain, PHP_URL_HOST);
-        if ($host && ($_SERVER['HTTP_HOST'] == $host)) {
-          return $language;
-        }
-      }
-      return language_default();
-
-    case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
-    case LANGUAGE_NEGOTIATION_PATH:
-      // $_GET['q'] might not be available at this time, because
-      // path initialization runs after the language bootstrap phase.
-      $args = isset($_GET['q']) ? explode('/', $_GET['q']) : array();
-      $prefix = array_shift($args);
-      // Search prefix within enabled languages.
-      foreach ($languages as $language) {
-        if (!empty($language->prefix) && $language->prefix == $prefix) {
-          // Rebuild $GET['q'] with the language removed.
-          $_GET['q'] = implode('/', $args);
-          return $language;
-        }
+    case LANGUAGE_NEGOTIATION_URL_DEFAULT:
+    case LANGUAGE_NEGOTIATION_URL:
+      $language = language_from_url();
+      // If the URL language is defined we can use it.
+      if ($language->language != language_none()->language) {
+        return $language;
       }
-      if ($mode == LANGUAGE_NEGOTIATION_PATH_DEFAULT) {
-        // If we did not found the language by prefix, choose the default.
+      if ($mode == LANGUAGE_NEGOTIATION_URL_DEFAULT) {
+        // If we did not found the language by URL, choose the default.
         return language_default();
       }
+      else if ($user->uid) {
+        // Fall back to the user preferred language.
+        return language_from_user();
+      }
       break;
   }
 
-  // User language.
-  if ($user->uid && isset($languages[$user->language])) {
-    return $languages[$user->language];
-  }
-
-  // Browser accept-language parsing.
-  if ($language = language_from_browser()) {
+  // Browser accept-language parsing: only if cache is disabled, otherwise
+  // we would cache a user-specific preference.
+  $cache_mode = variable_get('cache');
+  if ($cache_mode == CACHE_DISABLED && $language = language_from_browser()) {
     return $language;
   }
 
@@ -67,6 +53,61 @@ function language_initialize() {
 }
 
 /**
+ * Identify language via URL prefix or domain.
+ */
+function language_from_url() {
+  $url_language = &drupal_static(__FUNCTION__);
+
+  if (!isset($url_language)) {
+    $url_language = language_none();
+  
+    switch (variable_get('language_negotiation_url', LANGUAGE_NEGOTIATION_URL_PREFIX)) {
+      case LANGUAGE_NEGOTIATION_URL_PREFIX:
+        // $_GET['q'] might not be available at this time, because
+        // path initialization runs after the language bootstrap phase.
+        list($language, $_GET['q']) = language_split_prefix(isset($_GET['q']) ? $_GET['q'] : NULL);
+        if ($language !== FALSE) {
+          $url_language = $language;
+        }
+        break;
+  
+      case LANGUAGE_NEGOTIATION_URL_DOMAIN:
+        $languages = language_list('enabled');
+        $languages = $languages[1];
+        foreach ($languages as $language) {
+          $host = parse_url($language->domain, PHP_URL_HOST);
+          if ($host && ($_SERVER['HTTP_HOST'] == $host)) {
+            $url_language = $language;
+            break;
+          }
+        }
+        break;
+    }
+  }
+
+  return $url_language;
+}
+
+/**
+ * TODO
+ * @param $path
+ * @return unknown_type
+ */
+function language_split_prefix($path) {
+  $languages = language_list('enabled');
+  $args = empty($path) ? array() : explode('/', $path);
+  $prefix = array_shift($args);
+  // Search prefix within enabled languages.
+  foreach ($languages[1] as $language) {
+    if (!empty($language->prefix) && $language->prefix == $prefix) {
+      // Rebuild $path with the language removed.
+      return array($language, implode('/', $args));
+    }
+  }
+  return array(FALSE, $path);
+}
+
+/**
  * Identify language from the Accept-language HTTP header we got.
  */
 function language_from_browser() {
@@ -99,6 +140,28 @@ function language_from_browser() {
 }
 
 /**
+ * Identify language from the user preferences.
+ */
+function language_from_user() {
+  $languages = language_list('enabled');
+  $languages = $languages[1];
+
+  // Request parameter.
+  if (isset($_GET['ui_language']) && isset($languages[$langcode = $_GET['ui_language']])) {
+    return $_SESSION['ui_language'] = $languages[$langcode];
+  }
+  // Session parameter.
+  if (isset($_SESSION['ui_language'])) {
+    return $_SESSION['ui_language'];
+  }
+  // User preference.
+  global $user;
+  if (isset($languages[$user->language])) {
+    return $languages[$user->language];
+  }
+}
+
+/**
  * Rewrite URLs with language based prefix. Parameters are the same
  * as those of the url() function.
  */
@@ -113,13 +176,8 @@ function language_url_rewrite(&$path, &$
       $options['language'] = $language;
     }
 
-    switch (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE)) {
-      case LANGUAGE_NEGOTIATION_NONE:
-        // No language dependent path allowed in this mode.
-        unset($options['language']);
-        break;
-
-      case LANGUAGE_NEGOTIATION_DOMAIN:
+    switch (variable_get('language_negotiation_url', LANGUAGE_NEGOTIATION_URL_PREFIX)) {
+      case LANGUAGE_NEGOTIATION_URL_DOMAIN:
         if ($options['language']->domain) {
           // Ask for an absolute URL with our modified base_url.
           $options['absolute'] = TRUE;
@@ -127,14 +185,7 @@ function language_url_rewrite(&$path, &$
         }
         break;
 
-      case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
-        $default = language_default();
-        if ($options['language']->language == $default->language) {
-          break;
-        }
-        // Intentionally no break here.
-
-      case LANGUAGE_NEGOTIATION_PATH:
+      case LANGUAGE_NEGOTIATION_URL_PREFIX:
         if (!empty($options['language']->prefix)) {
           $options['prefix'] = $options['language']->prefix . '/';
         }
Index: includes/locale.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/locale.inc,v
retrieving revision 1.226
diff -u -p -r1.226 locale.inc
--- includes/locale.inc	22 Aug 2009 14:34:17 -0000	1.226
+++ includes/locale.inc	26 Aug 2009 19:13:57 -0000
@@ -477,15 +477,30 @@ function locale_languages_delete_form_su
  */
 function locale_languages_configure_form() {
   $form['language_negotiation'] = array(
-    '#title' => t('Language negotiation'),
+    '#title' => t('Interface language negotiation'),
     '#type' => 'radios',
     '#options' => array(
       LANGUAGE_NEGOTIATION_NONE => t('None.'),
-      LANGUAGE_NEGOTIATION_PATH_DEFAULT => t('Path prefix only.'),
-      LANGUAGE_NEGOTIATION_PATH => t('Path prefix with language fallback.'),
-      LANGUAGE_NEGOTIATION_DOMAIN => t('Domain name only.')),
+      LANGUAGE_NEGOTIATION_URL_DEFAULT => t('URL only.'),
+      LANGUAGE_NEGOTIATION_URL => t('URL with language fallback.'),
+    ),
     '#default_value' => variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE),
-    '#description' => t("Select the mechanism used to determine your site's presentation language. <strong>Modifying this setting may break all incoming URLs and should be used with caution in a production environment.</strong>")
+    '#description' => t("Select the mechanism used to determine your site's presentation language.")
+  );
+  $form['language_negotiation_user_override'] = array(
+    '#title' => t('Override user preferences'),
+    '#type' => 'checkbox',
+    '#default_value' => variable_get('language_negotiation_user_override', TRUE),
+  );
+  $form['language_negotiation_url'] = array(
+    '#title' => t('Content language negotiation'),
+    '#type' => 'radios',
+    '#options' => array(
+      LANGUAGE_NEGOTIATION_URL_PREFIX => t('URL Prefix.'),
+      LANGUAGE_NEGOTIATION_URL_DOMAIN => t('URL Domain.'),
+    ),
+    '#default_value' => variable_get('language_negotiation_url', LANGUAGE_NEGOTIATION_URL_PREFIX),
+    '#description' => t("Select which part of the URL will determine the content language.<br/><strong>Modifying this setting may break all incoming URLs and should be used with caution in a production environment.</strong>")
   );
   $form['submit'] = array(
     '#type' => 'submit',
@@ -499,6 +514,8 @@ function locale_languages_configure_form
  */
 function locale_languages_configure_form_submit($form, &$form_state) {
   variable_set('language_negotiation', $form_state['values']['language_negotiation']);
+  variable_set('language_negotiation_user_override', $form_state['values']['language_negotiation_user_override']);
+  variable_set('language_negotiation_url', $form_state['values']['language_negotiation_url']);
   drupal_set_message(t('Language negotiation configuration saved.'));
   $form_state['redirect'] = 'admin/config/regional/language';
   return;
Index: modules/locale/locale.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v
retrieving revision 1.256
diff -u -p -r1.256 locale.module
--- modules/locale/locale.module	24 Aug 2009 00:14:20 -0000	1.256
+++ modules/locale/locale.module	26 Aug 2009 19:13:58 -0000
@@ -265,13 +265,13 @@ function locale_language_selector_form($
   );
 
   // Get language negotiation settings.
-  $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE);
+  $mode = !variable_get('language_negotiation_user_override', TRUE);
   $form['locale']['language'] = array(
     '#type' => (count($names) <= 5 ? 'radios' : 'select'),
     '#title' => t('Language'),
     '#default_value' => $user_preferred_language->language,
     '#options' => $names,
-    '#description' => ($mode == LANGUAGE_NEGOTIATION_PATH) ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."),
+    '#description' => $mode ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."),
   );
   return $form;
 }
@@ -646,7 +646,7 @@ function locale_block_list() {
  * web addresses, so we can actually link to other language versions.
  */
 function locale_block_view($delta = '') {
-  if (variable_get('language_count', 1) > 1 && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) {
+  if (variable_get('language_count', 1) > 1) {
     $path = drupal_is_front_page() ? '<front>' : $_GET['q'];
     $languages = language_list('enabled');
     $links = array();
Index: modules/locale/locale.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/locale/locale.test,v
retrieving revision 1.39
diff -u -p -r1.39 locale.test
--- modules/locale/locale.test	22 Aug 2009 00:58:53 -0000	1.39
+++ modules/locale/locale.test	26 Aug 2009 20:19:29 -0000
@@ -91,7 +91,8 @@ class LocaleConfigurationTest extends Dr
     // Ensure we can't delete the default language.
     $path = 'admin/config/regional/language/delete/' . $langcode;
     $this->drupalGet($path);
-    $this->assertEqual($this->getUrl(), url('admin/config/regional/language', array('absolute' => TRUE)), t('Correct page redirection.'));
+    $url = url('admin/config/regional/language', array('absolute' => TRUE, 'prefix' => $langcode . '/'));
+    $this->assertEqual($this->getUrl(), $url, t('Correct page redirection.'));
     $this->assertText(t('The default language cannot be deleted.'), t('Failed to delete the default language.'));
 
     // Check if we can disable a language.
@@ -933,7 +934,7 @@ class LocaleUninstallFunctionalTest exte
     $this->assertEqual($language->language, $this->ui_language, t('Current language: %lang', array('%lang' => $language->language)));
 
     // Change language negotiation options.
-    variable_set('language_negotiation', LANGUAGE_NEGOTIATION_PATH_DEFAULT);
+    variable_set('language_negotiation', LANGUAGE_NEGOTIATION_URL_DEFAULT);
 
     // Enable multilingual workflow option for articles.
     variable_set('language_content_type_article', 1);
@@ -1060,13 +1061,6 @@ class LanguageSwitchingFunctionalTest ex
     );
     $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
 
-    // Set language negotiation.
-    $edit = array(
-      'language_negotiation' => LANGUAGE_NEGOTIATION_PATH_DEFAULT,
-    );
-    $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
-    $this->assertEqual($this->getUrl(), url('admin/config/regional/language', array('absolute' => TRUE)), t('Correct page redirection.'));
-
     // Assert that the language switching block is displayed on the frontpage.
     $this->drupalGet('');
     $this->assertText(t('Languages'), t('Language switcher block found.'));
@@ -1244,7 +1238,7 @@ class LocalePathFunctionalTest extends D
 
     // Set language negotiation.
     $edit = array(
-      'language_negotiation' => LANGUAGE_NEGOTIATION_PATH_DEFAULT,
+      'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
     );
     $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 
@@ -1354,7 +1348,7 @@ class LocaleContentFunctionalTest extend
 
     // Set language negotiation.
     $edit = array(
-      'language_negotiation' => LANGUAGE_NEGOTIATION_PATH_DEFAULT,
+      'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
     );
     $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
 
@@ -1411,6 +1405,7 @@ class LocaleContentFunctionalTest extend
 
 
 /**
+ * TODO
  * Test UI language negotiation
  * 1. LANGUAGE_NEGOTIATION_PATH_DEFAULT
  *    UI Language base on URL prefix, browser language preference has no
@@ -1435,10 +1430,10 @@ class LocaleContentFunctionalTest extend
  *        http://example.cn/admin/config
  *          UI language in Chinese
  */
-class UILanguageNegotiationTest extends DrupalWebTestCase {
+class LanguageNegotiationTest extends DrupalWebTestCase {
   public static function getInfo() {
     return array(
-      'name' => 'UI language negotiation',
+      'name' => 'Language negotiation',
       'description' => 'Test UI language switching by url path prefix and domain.',
       'group' => 'Locale',
     );
@@ -1451,9 +1446,9 @@ class UILanguageNegotiationTest extends 
   /**
    * Tests for language switching by URL path.
    */
-  function testUILanguageNegotiation() {
-    $admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
-    $this->drupalLogin($admin_user);
+  function testLanguageNegotiation() {
+    $this->admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
+    $this->drupalLogin($this->admin_user);
 
     // A few languages to switch to.
     // This one is unknown, should get the default lang version.
@@ -1475,9 +1470,9 @@ class UILanguageNegotiationTest extends 
     locale_add_language($language_browser_fallback);
     locale_add_language($language);
 
-    // We will look for this string in the admin/config screen to see if the
+    // We will look for this string in the default node page to see if the
     // corresponding translated string is shown.
-    $default_string = 'Configure languages for content and the user interface';
+    $default_string = 'Welcome to Drupal';
 
     // Set the default language in order for the translated string to be registered
     // into database when seen by t(). Without doing this, our target string
@@ -1495,7 +1490,7 @@ class UILanguageNegotiationTest extends 
     $language_browser_fallback_string = "In $language_browser_fallback In $language_browser_fallback In $language_browser_fallback";
     $language_string = "In $language In $language In $language";
     // Do a translate search of our target string.
-    $edit = array( 'string' => $default_string);
+    $edit = array('string' => 'Welcome to @site-name');
     $this->drupalPost('admin/config/regional/translate/translate', $edit, t('Filter'));
     // Should find the string and now click edit to post translated string.
     $this->clickLink('edit');
@@ -1508,43 +1503,45 @@ class UILanguageNegotiationTest extends 
     $tests = array(
       // Default, browser preference should have no influence.
       array(
-        'language_negotiation' => LANGUAGE_NEGOTIATION_PATH_DEFAULT,
-        'path' => 'admin/config',
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
+        'path' => 'node',
         'expect' => $default_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_PATH_DEFAULT: no language prefix, UI language is default and not the browser language preference setting is used.',
+        'message' => 'LANGUAGE_NEGOTIATION_URL_DEFAULT: no language prefix, UI language is default and not the browser language preference setting is used.',
       ),
       // Language prefix.
       array(
-        'language_negotiation' => LANGUAGE_NEGOTIATION_PATH_DEFAULT,
-        'path' => "$language/admin/config",
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
+        'path' => "$language/node",
         'expect' => $language_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_PATH_DEFAULT: with language prefix, UI language is switched based on path prefix',
+        'message' => 'LANGUAGE_NEGOTIATION_URL_DEFAULT: with language prefix, UI language is switched based on path prefix',
       ),
-      // Default, go by browser preference.
+      // Default, anonymous, go by browser preference.
       array(
-        'language_negotiation' => LANGUAGE_NEGOTIATION_PATH,
-        'path' => 'admin/config',
+        'anonymous' => TRUE,
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL,
+        'path' => 'node',
         'expect' => $language_browser_fallback_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_PATH: no language prefix, UI language is determined by browser language preference',
+        'message' => 'LANGUAGE_NEGOTIATION_URL: no language prefix, anoymous user, UI language is determined by browser language preference',
       ),
       // Prefix, switch to the language.
       array(
-        'language_negotiation' => LANGUAGE_NEGOTIATION_PATH,
-        'path' => "$language/admin/config",
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL,
+        'path' => "$language/node",
         'expect' => $language_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_PATH: with langage prefix, UI language is based on path prefix',
+        'message' => 'LANGUAGE_NEGOTIATION_URL: with langage prefix, UI language is based on path prefix',
       ),
-      // Default, browser language preference is not one of site's lang.
+      // Default, anonymous, browser language preference is not one of site's lang.
       array(
-        'language_negotiation' => LANGUAGE_NEGOTIATION_PATH,
-        'path' => 'admin/config',
+        'anonymous' => TRUE,
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL,
+        'path' => 'node',
         'expect' => $default_string,
         'http_header' => $http_header_blah,
-        'message' => 'LANGUAGE_NEGOTIATION_PATH: no language prefix and browser language preference set to unknown language should use default language',
+        'message' => 'LANGUAGE_NEGOTIATION_URL: no language prefix and browser language preference set to unknown language should use default language',
       ),
     );
 
@@ -1553,7 +1550,7 @@ class UILanguageNegotiationTest extends 
     }
 
     // Unknown language prefix should return 404.
-    foreach(array(LANGUAGE_NEGOTIATION_PATH_DEFAULT, LANGUAGE_NEGOTIATION_PATH) as $negotiation) {
+    foreach(array(LANGUAGE_NEGOTIATION_URL_DEFAULT, LANGUAGE_NEGOTIATION_URL) as $negotiation) {
       variable_set('language_negotiation', $negotiation);
       $this->drupalGet("$language_unknown/admin/config", array(), $http_header_browser_fallback);
       $this->assertResponse(404, "Unknown language path prefix should return 404, code = $negotiation");
@@ -1564,24 +1561,27 @@ class UILanguageNegotiationTest extends 
     $edit = array('prefix' => '', 'domain' => "http://$language_domain");
     $this->drupalPost("admin/config/regional/language/edit/$language", $edit, t('Save language'));
     // Set the site to use domain language negotiation.
-    variable_set('language_negotiation', LANGUAGE_NEGOTIATION_DOMAIN);
 
     $tests = array(
       // Default domain, browser preference should have no influence.
       array(
-        'path' => 'admin/config',
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
+        'language_negotiation_url' => LANGUAGE_NEGOTIATION_URL_DOMAIN,
+        'path' => 'node',
         'expect' => $default_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_DOMAIN: default domain should get default language',
+        'message' => 'LANGUAGE_NEGOTIATION_URL_DOMAIN: default domain should get default language',
       ),
       // Language domain specific URL, we set the $_SERVER['HTTP_HOST'] in
       // locale_test.module hook_boot() to simulate this.
       array(
+        'language_negotiation' => LANGUAGE_NEGOTIATION_URL_DEFAULT,
+        'language_negotiation_url' => LANGUAGE_NEGOTIATION_URL_DOMAIN,
         'locale_test_domain' => $language_domain,
-        'path' => 'admin/config',
+        'path' => 'node',
         'expect' => $language_string,
         'http_header' => $http_header_browser_fallback,
-        'message' => 'LANGUAGE_NEGOTIATION_DOMAIN: domain example.cn should switch to Chinese',
+        'message' => 'LANGUAGE_NEGOTIATION_URL_DOMAIN: domain example.cn should switch to Chinese',
       ),
     );
 
@@ -1591,13 +1591,23 @@ class UILanguageNegotiationTest extends 
   }
 
   private function runTest($test) {
+    if (!empty($test['anonymous'])) {
+      $this->drupalLogout();
+    }
     if (!empty($test['language_negotiation'])) {
       variable_set('language_negotiation', $test['language_negotiation']);
     }
+    if (!empty($test['language_negotiation_url'])) {
+      variable_set('language_negotiation_url', $test['language_negotiation_url']);
+    }
     if (!empty($test['locale_test_domain'])) {
       variable_set('locale_test_domain', $test['locale_test_domain']);
     }
     $this->drupalGet($test['path'], array(), $test['http_header']);
     $this->assertText($test['expect'], $test['message']);
+    $this->assertTrue(TRUE, print_r($this->plainTextContent, TRUE));
+    if (!empty($test['anonymous'])) {
+      $this->drupalLogin($this->admin_user);
+    }
   }
 }
Index: modules/path/path.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/path/path.test,v
retrieving revision 1.19
diff -u -p -r1.19 path.test
--- modules/path/path.test	22 Aug 2009 00:58:54 -0000	1.19
+++ modules/path/path.test	26 Aug 2009 20:21:51 -0000
@@ -183,7 +183,8 @@ class PathLanguageTestCase extends Drupa
     drupal_static_reset('language_list');
 
     // Set language negotiation to "Path prefix with fallback".
-    variable_set('language_negotiation', LANGUAGE_NEGOTIATION_PATH);
+    variable_set('language_negotiation', LANGUAGE_NEGOTIATION_URL);
+    variable_set('language_negotiation_url', LANGUAGE_NEGOTIATION_URL_PREFIX);
 
     // Force inclusion of language.inc.
     drupal_language_initialize();
Index: modules/simpletest/drupal_web_test_case.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/drupal_web_test_case.php,v
retrieving revision 1.144
diff -u -p -r1.144 drupal_web_test_case.php
--- modules/simpletest/drupal_web_test_case.php	24 Aug 2009 00:14:21 -0000	1.144
+++ modules/simpletest/drupal_web_test_case.php	26 Aug 2009 20:20:01 -0000
@@ -1804,6 +1804,9 @@ class DrupalWebTestCase extends DrupalTe
       $n = strlen($base_path);
       if (substr($path, 0, $n) == $base_path) {
         $path = substr($path, $n);
+        if (function_exists('language_url_rewrite')) {
+          list(, $path) = language_split_prefix($path);
+        }
       }
       if (isset($parts['query'])) {
         $options['query'] = $parts['query'];
