=== modified file 'includes/form.inc'
--- includes/form.inc	
+++ includes/form.inc	
@@ -111,8 +111,7 @@ function drupal_get_form($form_id, &$for
     $function($form_id, $form);
   }
 
-  form_builder($form_id, $form);
-
+  $form = form_builder($form_id, $form);
   if (!empty($_POST['edit']) && (($_POST['edit']['form_id'] == $form_id) || ($_POST['edit']['form_id'] == $callback))) {
     drupal_validate_form($form_id, $form, $callback);
     if ($form_submitted && !form_get_errors()) {
@@ -158,6 +157,17 @@ function drupal_get_form($form_id, &$for
 function drupal_validate_form($form_id, &$form, $callback = NULL) {
   global $form_values;
 
+  // we need a copy of form_values otherwise foreach falls into an infite loop
+  $copy = (array)$form_values;
+  // this loop breaks the references in form_values thus makes it impossible for 
+  // validate functions to modify the $form_values array
+  foreach ($copy as $k => $v) {
+    if ($k != '#ref') {
+      unset($form_values[$k]);
+      $form_values[$k] = $v;
+    }
+  }
+
   if (isset($form['#token'])) {
     if ($form_values['form_token'] != md5(session_id() . $form['#token'] . variable_get('drupal_private_key', ''))) {
       // setting this error will cause the form to fail validation
@@ -308,7 +318,7 @@ function form_error(&$element, $message 
  * @param $form
  *   An associative array containing the structure of the form.
  */
-function form_builder($form_id, &$form) {
+function form_builder($form_id, $form) {
   global $form_values;
   global $form_submitted;
   /* Use element defaults */
@@ -417,7 +427,7 @@ function form_builder($form_id, &$form) 
     if (!isset($form[$key]['#weight'])) {
       $form[$key]['#weight'] = $count/1000;
     }
-    form_builder($form_id, $form[$key]);
+    $form[$key] = form_builder($form_id, $form[$key]);
     $count++;
   }
 
@@ -426,6 +436,8 @@ function form_builder($form_id, &$form) 
     $form = $function($form, $form_values);
     $form['#after_build_done'] = TRUE;
   }
+
+  return $form;
 }
 
 /**
=== modified file 'modules/contact.module'
--- modules/contact.module	
+++ modules/contact.module	
@@ -184,6 +184,7 @@ function contact_admin_edit($cid = NULL)
   $form['cid'] = array('#type' => 'value',
     '#value' => $edit['cid'],
   );
+  $form['foo'] = array('#type' => 'textfield', '#default_value' => 'bar');
   $form['submit'] = array('#type' => 'submit',
     '#value' => t('Submit'),
   );
@@ -209,12 +210,14 @@ function contact_admin_edit_validate($fo
       }
     }
   }
+  $form_values['foo'] = "You should see 'bar' here not me.";
 }
 
 /**
  * Process the contact category edit page form submission.
  */
 function contact_admin_edit_submit($form_id, $form_values) {
+drupal_set_message($form_values['foo']);
   if ($form_values['selected']) {
     // Unselect all other contact categories.
     db_query('UPDATE {contact} SET selected = 0');
=== modified file 'modules/poll.module'
--- modules/poll.module	
+++ modules/poll.module	
@@ -133,7 +133,7 @@ function poll_form(&$node) {
 
   $form['choice']['choices'] = array('#type' => 'hidden', '#default_value' => max(2, count($node->choice) ? count($node->choice) : 5));
   $form['choice']['morechoices'] = array('#type' => 'checkbox', '#title' => t('Need more choices'), '#default_value' => 0, '#description' => t("If the amount of boxes above isn't enough, check this box and click the Preview button below to add some more."), '#weight' => 1);
-  form_builder('poll_node_form', $form['choice']);
+  $form['choice'] = form_builder('poll_node_form', $form['choice']);
   if ($form['choice']['morechoices']['#value']) {
     $form['choice']['morechoices']['#value'] = 0;
     $form['choice']['choices']['#value'] *= 2;
=== modified file 'modules/upload.module'
--- modules/upload.module	
+++ modules/upload.module	
@@ -640,7 +640,7 @@ function upload_js() {
   _upload_validate($node);
 
   $form = _upload_form($node);
-  form_builder('upload_js', $form);
+  $form = form_builder('upload_js', $form);
   $output = theme('status_messages') . form_render($form);
 
   // We send the updated file attachments form.
