diff --git includes/form.inc includes/form.inc
index e9f0680..19bcc84 100644
--- includes/form.inc
+++ includes/form.inc
@@ -459,7 +459,20 @@ function form_state_keys_no_cache() {
  *   Any additional arguments are passed on to the functions called by
  *   drupal_form_submit(), including the unique form constructor function.
  *   For example, the node_edit form requires that a node object be passed
- *   in here when it is called.
+ *   in here when it is called. Arguments that need to be passed by reference
+ *   should not be included here, but rather placed directly in the $form_state
+ *   build info array so that the reference can be preserved. For example, a
+ *   form builder function with the following signature:
+ *   @code
+ *   function mymodule_form($form, &$form_state, &$object) {
+ *   }
+ *   @endcode
+ *   would be called via drupal_form_submit() as follows:
+ *   @code
+ *   $form_state['values'] = $my_form_values;
+ *   $form_state['build_info']['args'] = array(&$object);
+ *   drupal_form_submit('mymodule_form', $form_state);
+ *   @endcode
  * For example:
  * @code
  * // register a new user
diff --git includes/install.core.inc includes/install.core.inc
index eada5d1..5585cc7 100644
--- includes/install.core.inc
+++ includes/install.core.inc
@@ -1,5 +1,5 @@
 <?php
-// $Id: install.core.inc,v 1.11 2010-04-22 09:13:53 webchick Exp $
+// $Id: install.core.inc,v 1.10 2010-04-21 08:56:06 webchick Exp $
 
 /**
  * @file
@@ -406,8 +406,14 @@ function install_run_task($task, &$install_state) {
       // For non-interactive forms, submit the form programmatically with the
       // values taken from the installation state. Throw an exception if any
       // errors were encountered.
-      $form_state = array('values' => !empty($install_state['forms'][$function]) ? $install_state['forms'][$function] : array());
-      drupal_form_submit($function, $form_state, $install_state);
+      $form_state = array(
+        'values' => !empty($install_state['forms'][$function]) ? $install_state['forms'][$function] : array(),
+        // We need to pass $install_state by reference in order for forms to
+        // modify it, since the form API will use it in call_user_func_array(),
+        // which requires that referenced variables be passed explicitly.
+        'build_info' => array('args' => array(&$install_state)),
+      );
+      drupal_form_submit($function, $form_state);
       $errors = form_get_errors();
       if (!empty($errors)) {
         throw new Exception(implode("\n", $errors));
@@ -1392,7 +1398,7 @@ function install_import_locales(&$install_state) {
  * @return
  *   The form API definition for the site configuration form.
  */
-function install_configure_form($form, &$form_state, $install_state) {
+function install_configure_form($form, &$form_state, &$install_state) {
   if (variable_get('site_name', FALSE) || variable_get('site_mail', FALSE)) {
     // Site already configured: This should never happen, means re-running the
     // installer, possibly by an attacker after the 'install_task' variable got
@@ -1583,7 +1589,7 @@ function install_check_requirements($install_state) {
 /**
  * Forms API array definition for site configuration.
  */
-function _install_configure_form($form, &$form_state, $install_state) {
+function _install_configure_form($form, &$form_state, &$install_state) {
   include_once DRUPAL_ROOT . '/includes/locale.inc';
 
   $form['site_information'] = array(
