diff --git a/core/modules/language/language.negotiation.inc b/core/modules/language/language.negotiation.inc
index 8bf45a6..babd9ec 100644
--- a/core/modules/language/language.negotiation.inc
+++ b/core/modules/language/language.negotiation.inc
@@ -410,11 +410,12 @@ function language_switcher_session($type, $path) {
       'attributes' => array('class' => array('language-link')),
       'query'      => $query,
     );
-    if ($language_query != $langcode) {
-      $links[$langcode]['query'][$param] = $langcode;
+    if ($langcode == $language_query) {
+      $links[$langcode]['attributes']['class'][] = 'session-active';
     }
-    else {
-      $links[$langcode]['attributes']['class'][] = ' session-active';
+    // Always set the language query parameter. It will be removed if necessary
+    // in locale_language_url_rewrite_session().
+    $links[$langcode]['query'][$param] = $langcode;
     }
   }
 
@@ -554,17 +555,29 @@ function language_negotiation_url_domains_save(array $domains) {
  * Rewrite URLs for the Session language negotiation method.
  */
 function language_url_rewrite_session(&$path, &$options) {
-  static $query_rewrite, $query_param, $query_value;
+  static $drupal_static_fast;
+  global $user;
+
+  if (!isset($drupal_static_fast)) {
+    $drupal_static_fast['static'] = &drupal_static(__FUNCTION__, array());
+  }
+
+  $cache = &$drupal_static_fast['static']['cache'];
+  $default = &$drupal_static_fast['static']['default'];
+  $query_rewrite = &$drupal_static_fast['static']['query_rewrite'];
+  $query_param = &$drupal_static_fast['static']['query_param'];
+  $query_value = &$drupal_static_fast['static']['query_value'];
 
   // The following values are not supposed to change during a single page
   // request processing.
   if (!isset($query_rewrite)) {
-    global $user;
     if (!$user->uid) {
       $languages = language_list();
+      $cache = variable_get('cache', 0);
+      $default = language_default()->language;
       $query_param = check_plain(config('language.negotiation')->get('session.parameter'));
       $query_value = isset($_GET[$query_param]) ? check_plain($_GET[$query_param]) : NULL;
-      $query_rewrite = isset($languages[$query_value]) && language_negotiation_method_enabled(LANGUAGE_NEGOTIATION_SESSION);
+      $query_rewrite = isset($languages[$query_value]);
     }
     else {
       $query_rewrite = FALSE;
@@ -582,4 +595,10 @@ function language_url_rewrite_session(&$path, &$options) {
       $options['query'][$query_param] = $query_value;
     }
   }
+
+  // To avoid page cache duplicates, remove the language query if the default
+  // language is set.
+  if (!$user->uid && $cache && isset($options['query'][$query_param]) && $options['query'][$query_param] == $default) {
+    unset($options['query'][$query_param]);
+  }
 }
