Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1222
diff -u -p -r1.1222 common.inc
--- includes/common.inc	17 Sep 2010 14:53:21 -0000	1.1222
+++ includes/common.inc	18 Sep 2010 00:37:55 -0000
@@ -5476,8 +5476,12 @@ function element_sort_by_title($a, $b) {
 
 /**
  * Retrieve the default properties for the defined element type.
+ *
+ * @param $element
+ *   (optional) A new element array to (intelligently) merge the default element
+ *   type properties into.
  */
-function element_info($type) {
+function element_info($type, array $element = NULL) {
   // Use the advanced drupal_static() pattern, since this is called very often.
   static $drupal_static_fast;
   if (!isset($drupal_static_fast)) {
@@ -5494,6 +5498,34 @@ function element_info($type) {
     drupal_alter('element_info', $cache);
   }
 
+  // Intelligently merge default element properties into the optionally passed
+  // new element.
+  if (isset($element)) {
+    if (!isset($cache[$type])) {
+      return $element;
+    }
+    // Prepend custom values defined in $element to default element type info.
+    // Most often, the custom values are expected to take effect prior to the
+    // default values.
+    foreach (array('#process', '#pre_render', '#theme_wrappers') as $property) {
+      if (isset($cache[$type][$property])) {
+        $element += array($property => array());
+        $element[$property] = array_merge($element[$property], $cache[$type][$property]);
+      }
+    }
+    // Merge values in $element into default element type info. Custom scalar
+    // values override the default values, while array values are merged.
+    foreach (array('#attributes') as $property) {
+      if (isset($cache[$type][$property])) {
+        $element += array($property => array());
+        $element[$property] = array_merge($cache[$type][$property], $element[$property]);
+      }
+    }
+    // Add other default element properties, if undefined in $element.
+    $element += $cache[$type];
+    return $element;
+  }
+
   return isset($cache[$type]) ? $cache[$type] : array();
 }
 
