--- includes/common.inc	2009-12-07 09:46:59.000000000 +0100
+++ includes/common_new.inc	2009-12-10 13:20:55.000000000 +0100
@@ -3082,7 +3082,7 @@ function base_path() {
  * which on normal pages is up through the preprocess step of theme('html').
  * Adding a link will overwrite a prior link with the exact same 'rel' and
  * 'href' attributes.
- * 
+ *
  * @param $attributes
  *   Associative array of element attributes including 'href' and 'rel'.
  * @param $header
@@ -3482,7 +3482,7 @@ function drupal_load_stylesheet_content(
     $contents = preg_replace('{
       (?<=\\\\\*/)([^/\*]+/\*)([^\*/]+\*/)  # Add a backslash also at the end ie-mac hack comment, so the next pass will not touch it.
                                             # The added backshlash does not affect the effectiveness of the hack.
-      }x', '\1\\\\\2', $contents);    
+      }x', '\1\\\\\2', $contents);
     $contents = preg_replace('<
       \s*([@{}:;,]|\)\s|\s\()\s* |          # Remove whitespace around separators, but keep space around parentheses.
       /\*[^*\\\\]*\*+([^/*][^*]*\*+)*/ |    # Remove comments that are not CSS hacks.
@@ -3892,7 +3892,7 @@ function drupal_get_js($scope = 'header'
       case 'setting':
         $js_element = $element;
         $js_element['#value_prefix'] = $embed_prefix;
-        $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(call_user_func_array('array_merge_recursive', $item['data'])) . ");";
+        $js_element['#value'] = 'jQuery.extend(Drupal.settings, ' . drupal_json_encode(call_user_func_array('array_merge_recursive_distinct', $item['data'])) . ");";
         $js_element['#value_suffix'] = $embed_suffix;
         $output .= theme('html_tag', array('element' => $js_element));
         break;
@@ -6528,3 +6528,49 @@ function drupal_get_updaters() {
   }
   return $updaters;
 }
+
+/**
+ * array_merge_recursive does indeed merge arrays, but it converts values with duplicate
+ * keys to arrays rather than overwriting the value in the first array with the duplicate
+ * value in the second array, as array_merge does. I.e., with array_merge_recursive,
+ * this happens (documented behavior):
+ *
+ * array_merge_recursive(array('key' => 'org value'), array('key' => 'new value'));
+ *     => array('key' => array('org value', 'new value'));
+ *
+ * array_merge_recursive_distinct does not change the datatypes of the values in the arrays.
+ * Matching keys' values in the second array overwrite those in the first array, as is the
+ * case with array_merge, i.e.:
+ *
+ * array_merge_recursive_distinct(array('key' => 'org value'), array('key' => 'new value'));
+ *     => array('key' => array('new value'));
+ *
+ * Parameters are passed by reference, though only for performance reasons. They're not
+ * altered by this function.
+ *
+ * @param Initial array to merge.
+ * @param Variable list of arrays to recursively merge.
+ * @return array
+ * @author Daniel <daniel (at) danielsmedegaardbuus (dot) dk>
+ * @author Gabriel Sobrinho <gabriel (dot) sobrinho (at) gmail (dot) com>
+ */
+function array_merge_recursive_distinct() {
+  // Holds all the arrays passed
+  $params = & func_get_args();
+
+  // First array is used as the base
+  $merged = array_shift($params);
+
+  foreach ($params as $array) {
+    foreach ($array as $key => &$value) {
+      if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
+        $merged[$key] = array_merge_recursive_distinct($merged[$key], $value);
+      }
+      else {
+        $merged[$key] = $value;
+      }
+    }
+  }
+
+  return $merged;
+}
