Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.1021
diff -u -p -r1.1021 common.inc
--- includes/common.inc	15 Oct 2009 21:19:30 -0000	1.1021
+++ includes/common.inc	16 Oct 2009 04:23:33 -0000
@@ -4619,7 +4619,7 @@ function drupal_render(&$elements) {
   // Call the element's #theme function if it is set. Then any children of the
   // element have to be rendered there.
   if (isset($elements['#theme'])) {
-    $elements['#children'] = theme($elements['#theme'], $elements);
+    $elements['#children'] = theme($elements['#theme'], theme_get_variables_from_render_element($elements['#theme'], $elements));
   }
   // If #theme was not set and the element has children, render them now
   // using drupal_render_children().
@@ -4631,7 +4631,7 @@ function drupal_render(&$elements) {
   // children.
   if (isset($elements['#theme_wrappers'])) {
     foreach ($elements['#theme_wrappers'] as $theme_wrapper) {
-      $elements['#children'] = theme($theme_wrapper, $elements);
+      $elements['#children'] = theme($theme_wrapper, theme_get_variables_from_render_element($theme_wrapper, $elements));
     }
   }
 
@@ -4988,10 +4988,12 @@ function drupal_common_theme() {
     'html' => array(
       'arguments' => array('page' => NULL),
       'template' => 'html',
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
     ),
     'page' => array(
       'arguments' => array('page' => NULL),
       'template' => 'page',
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
     ),
     'region' => array(
       'arguments' => array('elements' => NULL),
@@ -5100,6 +5102,7 @@ function drupal_common_theme() {
     ),
     'menu_tree' => array(
       'arguments' => array('tree' => NULL),
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
     ),
     'menu_local_task' => array(
       'arguments' => array('element' => NULL),
Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.536
diff -u -p -r1.536 theme.inc
--- includes/theme.inc	15 Oct 2009 12:27:34 -0000	1.536
+++ includes/theme.inc	16 Oct 2009 04:23:33 -0000
@@ -37,6 +37,28 @@ define('MARK_UPDATED', 2);
  * @} End of "Content markers".
  */
 
+/**
+ * @name Render integration modes
+ * @{
+ * Markers used by theme_mark() and node_mark() to designate content.
+ * @see theme_mark(), node_mark()
+ */
+
+/**
+ * When calling theme() from drupal_render(), set the first theme hook argument
+ * to the element.
+ */
+define('THEME_SET_FIRST_ARGUMENT_TO_ELEMENT', 1);
+
+/**
+ * When calling theme() from drupal_render(), set each theme hook argument to
+ * the value of the element's correspondingly named property.
+ */
+define('THEME_SET_ARGUMENTS_TO_ELEMENT_PROPERTIES', 2);
+
+/**
+ * @} End of "Render integration modes".
+ */
 
 /**
  * An exception to throw when a theme function is requested that does not exist.
@@ -377,6 +399,10 @@ function _theme_process_registry(&$cache
       if (!isset($info['arguments']) && isset($cache[$hook])) {
         $result[$hook]['arguments'] = $cache[$hook]['arguments'];
       }
+      // Same for 'render integration'.
+      if (!isset($info['render integration']) && isset($cache[$hook]) && isset($cache[$hook]['render integration'])) {
+        $result[$hook]['render integration'] = $cache[$hook]['render integration'];
+      }
 
       // The following apply only to theming hooks implemented as templates.
       if (isset($info['template'])) {
@@ -516,13 +542,28 @@ function _theme_build_registry($theme, $
   // Let modules alter the registry.
   drupal_alter('theme_registry', $cache);
 
-  // Optimize the registry to not have empty arrays for functions.
+  // Final adjustments.
   foreach ($cache as $hook => $info) {
+    // Optimize the registry to not have empty arrays for functions.
     foreach (array('preprocess functions', 'process functions') as $phase) {
       if (empty($info[$phase])) {
         unset($cache[$hook][$phase]);
       }
     }
+    // Set a default render integration mode.
+    // @see drupal_render()
+    if (!isset($info['render integration']) && isset($info['arguments']) && ($n = count($info['arguments']))) {
+      $arg_keys = array_keys($info['arguments']);
+      if ($n > 1) {
+        $cache[$hook]['render integration'] = THEME_SET_ARGUMENTS_TO_ELEMENT_PROPERTIES;
+      }
+      elseif (in_array($arg_keys[0], array('element', 'elements', 'form'))) {
+        $cache[$hook]['render integration'] = THEME_SET_FIRST_ARGUMENT_TO_ELEMENT;
+      }
+      else {
+        $cache[$hook]['render integration'] = THEME_SET_ARGUMENTS_TO_ELEMENT_PROPERTIES;
+      }
+    }
   }
   return $cache;
 }
@@ -743,8 +784,6 @@ function list_themes($refresh = FALSE) {
  *   An associative array of variables to merge with defaults from the theme
  *   registry, pass to preprocess and process functions for modification, and
  *   finally, pass to the function or template implementing the theme hook.
- *   Alternatively, this can be a renderable array, in which case, its properties
- *   are mapped to variables expected by the theme hook implementations.
  *
  * @return
  *   An HTML string that generates the themed output.
@@ -784,28 +823,6 @@ function theme($hook, $variables = array
     }
   }
 
-  // If a renderable array is passed as $variables, then set $variables to
-  // what's expected by the theme hook. If the theme hook expects a single
-  // argument, set the renderable array as that argument. If the theme hook
-  // expects multiple arguments, set the properties of the renderable array as
-  // those arguments.
-  if (isset($variables['#theme']) || isset($variables['#theme_wrappers'])) {
-    $element = $variables;
-    $variables = array();
-    $n = count($info['arguments']);
-    if ($n == 1) {
-      $arg_keys = array_keys($info['arguments']);
-      $variables[$arg_keys[0]] = $element;
-    }
-    elseif ($n > 1) {
-      foreach ($info['arguments'] as $name => $default) {
-        if (isset($element["#$name"])) {
-          $variables[$name] = $element["#$name"];
-        }
-      }
-    }
-  }
-
   // Merge in argument defaults.
   if (!empty($info['arguments'])) {
     $variables += $info['arguments'];
@@ -906,6 +923,50 @@ function theme($hook, $variables = array
 }
 
 /**
+ * Convert a renderable element into a theme function variables array.
+ */
+function theme_get_variables_from_render_element($hook, $element) {
+  static $theme_registry = NULL;
+  if (!isset($theme_registry)) {
+    drupal_theme_initialize();
+    $theme_registry = theme_get_registry();
+  }
+  // If an array of hook candidates were passed, use the first one that has an
+  // implementation.
+  if (is_array($hook)) {
+    foreach ($hook as $candidate) {
+      if (isset($theme_registry[$candidate])) {
+        break;
+      }
+    }
+    $hook = $candidate;
+  }
+  $variables = array();
+  if (isset($theme_registry[$hook])) {
+    $info = $theme_registry[$hook];
+    if (isset($info['render integration']) && isset($info['arguments'])) {
+      $arg_keys = array_keys($info['arguments']);
+      switch ($info['render integration']) {
+        case THEME_SET_FIRST_ARGUMENT_TO_ELEMENT:
+          if (isset($arg_keys[0])) {
+            $variables[$arg_keys[0]] = $element;
+          }
+          break;
+
+        case THEME_SET_ARGUMENTS_TO_ELEMENT_PROPERTIES:
+          foreach ($arg_keys as $name) {
+            if (isset($element["#$name"])) {
+              $variables[$name] = $element["#$name"];
+            }
+          }
+          break;
+      }
+    }
+  }
+  return $variables;
+}
+
+/**
  * Determine and return which template file will generate the output.
  *
  * This helper allows the theme system to pick the template at runtime instead
@@ -998,6 +1059,7 @@ function drupal_find_theme_functions($ca
             $templates[$new_hook] = array(
               'function' => $match,
               'arguments' => $info['arguments'],
+              'render integration' => isset($info['render integration']) ? $info['render integration'] : NULL,
             );
           }
         }
@@ -1102,6 +1164,7 @@ function drupal_find_theme_templates($ca
             'template' => $file,
             'path' => dirname($files[$match]->uri),
             'arguments' => $info['arguments'],
+            'render integration' => isset($info['render integration']) ? $info['render integration'] : NULL,
           );
         }
       }
Index: modules/book/book.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/book/book.module,v
retrieving revision 1.519
diff -u -p -r1.519 book.module
--- modules/book/book.module	15 Oct 2009 14:07:26 -0000	1.519
+++ modules/book/book.module	16 Oct 2009 04:23:33 -0000
@@ -27,6 +27,7 @@ function book_theme() {
     ),
     'book_all_books_block' => array(
       'arguments' => array('book_menus' => array()),
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
       'template' => 'book-all-books-block',
     ),
     'book_node_export_html' => array(
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.787
diff -u -p -r1.787 comment.module
--- modules/comment/comment.module	15 Oct 2009 16:18:45 -0000	1.787
+++ modules/comment/comment.module	16 Oct 2009 04:23:34 -0000
@@ -147,6 +147,7 @@ function comment_theme() {
     'comment_wrapper' => array(
       'template' => 'comment-wrapper',
       'arguments' => array('content' => NULL),
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
     ),
   );
 }
Index: modules/simpletest/simpletest.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/simpletest.module,v
retrieving revision 1.77
diff -u -p -r1.77 simpletest.module
--- modules/simpletest/simpletest.module	9 Oct 2009 01:00:03 -0000	1.77
+++ modules/simpletest/simpletest.module	16 Oct 2009 04:23:34 -0000
@@ -76,6 +76,7 @@ function simpletest_theme() {
   return array(
     'simpletest_test_table' => array(
       'arguments' => array('table' => NULL),
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
       'file' => 'simpletest.pages.inc',
     ),
     'simpletest_result_summary' => array(
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.816
diff -u -p -r1.816 system.module
--- modules/system/system.module	15 Oct 2009 21:19:31 -0000	1.816
+++ modules/system/system.module	16 Oct 2009 04:23:34 -0000
@@ -180,6 +180,7 @@ function system_theme() {
     ),
     'status_report' => array(
       'arguments' => array('requirements' => NULL),
+      'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
       'file' => 'system.admin.inc',
     ),
     'admin_page' => array(
Index: modules/toolbar/toolbar.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/toolbar/toolbar.module,v
retrieving revision 1.13
diff -u -p -r1.13 toolbar.module
--- modules/toolbar/toolbar.module	15 Sep 2009 20:50:48 -0000	1.13
+++ modules/toolbar/toolbar.module	16 Oct 2009 04:23:34 -0000
@@ -24,6 +24,7 @@ function toolbar_permission() {
 function toolbar_theme($existing, $type, $theme, $path) {
   $items['toolbar'] = array(
     'arguments' => array('toolbar' => array()),
+    'render integration' => THEME_SET_FIRST_ARGUMENT_TO_ELEMENT,
     'template' => 'toolbar',
     'path' => drupal_get_path('module', 'toolbar'),
   );
Index: modules/update/update.report.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/update/update.report.inc,v
retrieving revision 1.26
diff -u -p -r1.26 update.report.inc
--- modules/update/update.report.inc	15 Oct 2009 21:19:31 -0000	1.26
+++ modules/update/update.report.inc	16 Oct 2009 04:23:34 -0000
@@ -199,7 +199,7 @@ function theme_update_report($variables)
             break;
             
           default:
-            $base_themes[] = theme('placeholder', $base_theme);
+            $base_themes[] = theme('placeholder', array('text' => $base_theme));
         }
       }
       $row .= t('Depends on: !basethemes', array('!basethemes' => implode(', ', $base_themes)));
