diff --git a/includes/form.inc b/includes/form.inc
index a70e00039b2b4706361227165603e04e5da5ea4c..88aa8e70c89521446857a64fbbeb93ac91eab16b 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -17,7 +17,7 @@ function element_property($key) {
 }
 
 function element_properties($element) {
-  return array_filter(array_keys($element), 'element_property');
+  return array_filter(array_keys((array) $element), 'element_property');
 }
 
 /**
@@ -28,7 +28,7 @@ function element_child($key) {
 }
 
 function element_children($element) {
-  return array_filter(array_keys($element), 'element_child');
+  return array_filter(array_keys((array) $element), 'element_child');
 }
 
 /**
@@ -49,11 +49,15 @@ function drupal_get_form($form_id, &$form, $callback = NULL) {
   global $form_values, $form_execute;
   $form_values = array();
   $form_execute = FALSE;
+
   $form['#type'] = 'form';
   $form['#attributes']['class'] .= ' form-api';
   if (isset($form['#token'])) {
-    $form['form_token'] = array('#type' => 'hidden', '#value' => md5($_SERVER['REMOTE_ADDR'] . $form['#token'] . variable_get('drupal_private_key', '')));
+    $form['form_token'] = array('#type' => 'hidden', '#value' => md5($_SERVER['REMOTE_ADDR'] . $form['#token'] . variable_get('drupal_private_key',
+'')));
   }
+  $form['form_id'] = array('#type' => 'hidden', '#default_value' => $form_id);
+
   $form = array_merge(_element_info('form'), $form);
 
   foreach (module_implements('form_alter') as $module) {
@@ -61,15 +65,14 @@ function drupal_get_form($form_id, &$form, $callback = NULL) {
     $function($form);
   }
 
-  $function = $form_id . '_alter';
+  $function = $form_id . '_form_alter';
   if (function_exists($function)) {
     $function($form);
   }
 
-  if (!$form['#built']) {
-    $form = _form_builder($form);
-  }
-  if (!empty($_POST['edit'])) {
+  $form = _form_builder($form);
+
+  if (!empty($_POST['edit']) && (($form_values['form_id'] == $form_id) || ($form_values['form_id'] == $callback))) {
     drupal_validate_form($form_id, $form, $callback);
     if ($form_execute && !form_get_errors()) {
       drupal_execute_form($form_id, $form, $callback);
@@ -125,11 +128,13 @@ function drupal_execute_form($form_id, $form, $callback = NULL) {
   }
 }
 
-function _form_validate(&$elements) {
+function _form_validate($elements) {
 
   // Recurse through all children.
   foreach (element_children($elements) as $key) {
-    _form_validate($elements[$key]);
+    if (isset($elements[$key]) && $elements[$key]) {
+      _form_validate($elements[$key]);
+    }
   }
 
   /* Validate the current input */
@@ -209,26 +214,15 @@ function form_error(&$element, $message) {
  * This function also automatically assigns the value property from the $edit array, provided the
  * element doesn't already have an assigned value.
  */
-function _form_builder($form, $parents = array(), $multiple = FALSE) {
+function _form_builder($form) {
   global $form_values;
   global $form_execute;
-
-  if ($form['#built'] == TRUE) {
-    return $form;
-  }
-  $form['#built'] = TRUE;
-
-  $form['#parents'] = ($form['#parents']) ? $form['#parents'] : $parents;
   /* Use element defaults */
   if ((!empty($form['#type'])) && ($info = _element_info($form['#type']))) {
     $form += $info;
   }
 
   if ($form['#input']) {
-    if (!$form['#tree']) {
-      $form['#parents'] = array(array_pop($form['#parents']));
-    }
-
     $form['#name'] = ($form['#name']) ? $form['#name'] : 'edit[' . implode('][', $form['#parents']) . ']';
     $form['#id'] =  ($form['#id']) ? $form['#id'] : 'edit-' . implode('-', $form['#parents']);
 
@@ -240,7 +234,7 @@ function _form_builder($form, $parents = array(), $multiple = FALSE) {
       $ref =& $ref[$parent];
     }
     if (!isset($form['#value'])) {
-      $form['#value'] = $posted ? $edit : $form['#default_value'];
+      $form['#value'] = ($posted && isset($edit)) ? $edit : $form['#default_value'];
     }
     if (isset($form['#execute'])) {
       if ($_POST[$form['#name']] == $form['#value']) {
@@ -260,13 +254,31 @@ function _form_builder($form, $parents = array(), $multiple = FALSE) {
   // Recurse through all child elements.
   $count  = 0;
   foreach (element_children($form) as $key) {
+    // don't squash an existing tree value
     $form[$key]['#tree'] = (isset($form[$key]['#tree'])) ? $form[$key]['#tree'] : $form['#tree'];
+
+    if ($form[$key]['#tree']) {
+      //continue tree
+      $parents = (array) $form['#parents'];
+      array_push($parents, $key);
+    }
+    else {
+      $parents = array($key);
+    }
+
+    // don't squash existing parents value
+    $form[$key]['#parents'] = (isset($form[$key]['#parents'])) ? $form[$key]['#parents'] : $parents;
+
     # Assign a decimal placeholder weight, to preserve original array order
-    $form[$key]['#weight'] = $form[$key]['#weight'] ? $form[$key]['#weight'] : $count/10;
-    $form[$key] = _form_builder($form[$key], array_merge($form['#parents'], array($key)));
+    $form[$key]['#weight'] = $form[$key]['#weight'] ? $form[$key]['#weight'] : $count/1000;
+    $form[$key] = _form_builder($form[$key]);
     $count++;
   }
 
+  if (function_exists($form['#post_process']) && !$form['#post_processed']) {
+    $form = call_user_func($form['#post_process'], $form_id, $form, $form_values, $form['#parents']);
+    $form['#post_processed'] = TRUE;
+  }
 
   return $form;
 }
@@ -334,11 +346,14 @@ function _form_sort($a, $b) {
  */
 function _element_info($type, $refresh = null) {
   static $cache;
+
+  $parents = array();
   $basic_defaults = array(
     '#description' => NULL,
     '#attributes' => array(),
     '#required' => FALSE,
-    '#tree' => FALSE
+    '#tree' => FALSE,
+    '#parents' => $parents
   );
   if ($refresh || !is_array($cache)) {
     $cache = array();
@@ -385,7 +400,7 @@ function theme_select($element) {
       $select .= '<option value="'. $key .'"'. (is_array($element['#value']) ? (in_array($key, $element['#value']) ? ' selected="selected"' : '') : ($element['#value'] == $key ? ' selected="selected"' : '')) .'>'. check_plain($choice) .'</option>';
     }
   }
-  return theme('form_element', $element['#title'], '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . ($element['#extra'] ? ' '. $element['#extra'] : '') .' id="' . $element['#id'] .'">'. $select .'</select>', $element['#description'], $element['#name'], $element['#required'], form_get_error($element));
+  return theme('form_element', $element['#title'], '<select name="'. $element['#name'] .''. ($element['#multiple'] ? '[]' : '') .'"'. ($element['#multiple'] ? ' multiple="multiple" ' : '') . drupal_attributes($element['#attributes']) .' id="' . $element['#id'] .'">'. $select .'</select>', $element['#description'], $element['#id'], $element['#required'], form_get_error($element));
 }
 
 /**
@@ -499,7 +514,7 @@ function expand_date($element) {
         $options = drupal_map_assoc(range(1900, 2050));
         break;
     }
-    $element[$type] = array('#type' => 'radio', '#value' => $element['#value'][$type], '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#options' => $options,  '#tree' => TRUE);
+    $element[$type] = array('#type' => 'select', '#value' => $element['#value'][$type], '#attributes' => $element['#attributes'], '#parents' => $element['#parents'], '#options' => $options,  '#tree' => TRUE);
   }
 
   return $element;
@@ -518,7 +533,6 @@ function expand_radios($element) {
       }
     }
   }
-
   return $element;
 }
 
@@ -582,13 +596,14 @@ function theme_checkboxes($element) {
 
 function expand_checkboxes($element) {
   $value = is_array($element['#value']) ? $element['#value'] : array();
+  $element['#tree'] = TRUE;
   if (count($element['#options']) > 0) {
     if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
       $element['#default_value'] = array();
     }
     foreach ($element['#options'] as $key => $choice) {
       if (!isset($element[$key])) {
-        $element[$key] = array('#type' => 'checkbox', '#processed' => TRUE, '#title' => $choice, '#tree' => TRUE, '#default_value' => in_array($key, $value), '#attributes' => $element['#attributes']);
+        $element[$key] = array('#type' => 'checkbox', '#processed' => TRUE, '#title' => $choice, '#default_value' => in_array($key, $value), '#attributes' => $element['#attributes']);
       }
     }
   }
@@ -765,5 +780,3 @@ function form_clean_id($id = NULL) {
 /**
  * @} End of "defgroup form".
  */
-
-?>
diff --git a/modules/node.module b/modules/node.module
index 1d6ca752aa8233cddfb7b9161a00d4b61f67b757..a318e5d6d77ca50f15bffb9b1a2c40a3bb15893a 100644
--- a/modules/node.module
+++ b/modules/node.module
@@ -1508,15 +1508,6 @@ function node_validate($node) {
   }
 
   if (user_access('administer nodes')) {
-    // Set up default values, if required.
-    if (!isset($node->created)) {
-      $node->created = time();
-    }
-
-    if (!isset($node->date)) {
-      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
-    }
-
     // Validate the "authored by" field.
     if (empty($node->name)) {
       // The use of empty() is mandatory in the context of usernames
@@ -1574,15 +1565,32 @@ function node_validate_title($node, $message = NULL) {
   }
 }
 
+function node_form_validate($form_id, $edit) {
+  node_validate($edit);
+}
+
+function node_object_prepare(&$node) {
+  if (user_access('administer nodes')) {
+    // Set up default values, if required.
+    if (!isset($node->created)) {
+      $node->created = time();
+    }
+
+    if (!isset($node->date)) {
+      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+    }
+  }
+  node_invoke($node, 'prepare');
+  node_invoke_nodeapi($node, 'prepare');
+}
+
 /**
  * Generate the node editing form.
  */
 function node_form($node) {
   $op = isset($_POST['op']) ? $_POST['op'] : '';
 
-  if (!isset($node) || !isset($node->validated) || !$node->validated) {
-    $node = node_validate($node);
-  }
+  node_object_prepare($node);
 
   // Set the id of the top-level form tag
   $form['#attributes']['id'] = 'node-form';
@@ -1598,10 +1606,6 @@ function node_form($node) {
   $form['changed'] = array('#type' => 'value', '#value' => $node->changed);
   $form['type']    = array('#type' => 'value', '#value' => $node->type);
 
-  if ($op == t('Preview')) {
-    $form['node_preview'] = array('#value' => node_preview(array2object($_POST['edit'])), '#weight' => -100);
-  }
-
   // Get the node-specific bits.
   // We can't use node_invoke() because $param must be passed by reference.
   $function = node_get_base($node) .'_form';
@@ -1649,20 +1653,23 @@ function node_form($node) {
   // Add the buttons.
   $form['preview'] = array('#type' => 'button', '#value' => t('Preview'), '#weight' => 19);
 
-  if ($node->type) {
-    if (!form_get_errors()) {
-      if ($_POST['op'] == t('Preview')|| !variable_get('node_preview', 0)) {
-
-      }
-    }
-  }
   $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'), '#weight' => 20);
   if ($node->nid && node_access('delete', $node)) {
     $form['delete'] = array('#type' => 'button', '#value' => t('Delete'), '#weight' => 21);
   }
+
+  if ($op == t('Preview')) {
+    $form['#post_process'] = 'node_form_add_preview';
+  }
+
   return drupal_get_form($node->type . '_node_form', $form, 'node_form');
 }
 
+function node_form_add_preview($form_id, $form, $edit) {
+  $form['node_preview'] = array('#value' => node_preview(node_validate($edit)), '#weight' => -100);
+  return $form;
+}
+
 function theme_node_form($form) {
   $output = '<div class="node-form">';
   if (isset($form['node_preview'])) {
@@ -1733,10 +1740,6 @@ function node_add($type) {
  * Generate a node preview.
  */
 function node_preview($node) {
-  if (!isset($node) || !isset($node->validated) || !$node->validated) {
-    $node = node_validate($node);
-  }
-
   if (node_access('create', $node) || node_access('update', $node)) {
     // Load the user's name when needed:
     if (isset($node->name)) {
@@ -1919,8 +1922,6 @@ function node_page_default() {
  * Menu callback; dispatches control to the appropriate operation handler.
  */
 function node_page() {
-  $edit = $_POST['edit'];
-
   $op = arg(1);
 
   if (is_numeric($op)) {
diff --git a/modules/node/node.module b/modules/node/node.module
index 1d6ca752aa8233cddfb7b9161a00d4b61f67b757..a318e5d6d77ca50f15bffb9b1a2c40a3bb15893a 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1508,15 +1508,6 @@ function node_validate($node) {
   }
 
   if (user_access('administer nodes')) {
-    // Set up default values, if required.
-    if (!isset($node->created)) {
-      $node->created = time();
-    }
-
-    if (!isset($node->date)) {
-      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
-    }
-
     // Validate the "authored by" field.
     if (empty($node->name)) {
       // The use of empty() is mandatory in the context of usernames
@@ -1574,15 +1565,32 @@ function node_validate_title($node, $message = NULL) {
   }
 }
 
+function node_form_validate($form_id, $edit) {
+  node_validate($edit);
+}
+
+function node_object_prepare(&$node) {
+  if (user_access('administer nodes')) {
+    // Set up default values, if required.
+    if (!isset($node->created)) {
+      $node->created = time();
+    }
+
+    if (!isset($node->date)) {
+      $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
+    }
+  }
+  node_invoke($node, 'prepare');
+  node_invoke_nodeapi($node, 'prepare');
+}
+
 /**
  * Generate the node editing form.
  */
 function node_form($node) {
   $op = isset($_POST['op']) ? $_POST['op'] : '';
 
-  if (!isset($node) || !isset($node->validated) || !$node->validated) {
-    $node = node_validate($node);
-  }
+  node_object_prepare($node);
 
   // Set the id of the top-level form tag
   $form['#attributes']['id'] = 'node-form';
@@ -1598,10 +1606,6 @@ function node_form($node) {
   $form['changed'] = array('#type' => 'value', '#value' => $node->changed);
   $form['type']    = array('#type' => 'value', '#value' => $node->type);
 
-  if ($op == t('Preview')) {
-    $form['node_preview'] = array('#value' => node_preview(array2object($_POST['edit'])), '#weight' => -100);
-  }
-
   // Get the node-specific bits.
   // We can't use node_invoke() because $param must be passed by reference.
   $function = node_get_base($node) .'_form';
@@ -1649,20 +1653,23 @@ function node_form($node) {
   // Add the buttons.
   $form['preview'] = array('#type' => 'button', '#value' => t('Preview'), '#weight' => 19);
 
-  if ($node->type) {
-    if (!form_get_errors()) {
-      if ($_POST['op'] == t('Preview')|| !variable_get('node_preview', 0)) {
-
-      }
-    }
-  }
   $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'), '#weight' => 20);
   if ($node->nid && node_access('delete', $node)) {
     $form['delete'] = array('#type' => 'button', '#value' => t('Delete'), '#weight' => 21);
   }
+
+  if ($op == t('Preview')) {
+    $form['#post_process'] = 'node_form_add_preview';
+  }
+
   return drupal_get_form($node->type . '_node_form', $form, 'node_form');
 }
 
+function node_form_add_preview($form_id, $form, $edit) {
+  $form['node_preview'] = array('#value' => node_preview(node_validate($edit)), '#weight' => -100);
+  return $form;
+}
+
 function theme_node_form($form) {
   $output = '<div class="node-form">';
   if (isset($form['node_preview'])) {
@@ -1733,10 +1740,6 @@ function node_add($type) {
  * Generate a node preview.
  */
 function node_preview($node) {
-  if (!isset($node) || !isset($node->validated) || !$node->validated) {
-    $node = node_validate($node);
-  }
-
   if (node_access('create', $node) || node_access('update', $node)) {
     // Load the user's name when needed:
     if (isset($node->name)) {
@@ -1919,8 +1922,6 @@ function node_page_default() {
  * Menu callback; dispatches control to the appropriate operation handler.
  */
 function node_page() {
-  $edit = $_POST['edit'];
-
   $op = arg(1);
 
   if (is_numeric($op)) {
diff --git a/modules/system.module b/modules/system.module
index bd0b89d821bcf1ffbb11aae3ad462173be33f819..1a7bf9d95ae1e3d58c853ed875284dc2da21373b 100644
--- a/modules/system.module
+++ b/modules/system.module
@@ -682,6 +682,24 @@ function system_settings_form($form_id, $form) {
   return drupal_get_form($form_id, $form, 'system_settings_form');
 }
 
+function system_theme_settings_execute($form_id, $values) {
+  $op = isset($_POST['op']) ? $_POST['op'] : '';
+  $key = $values['var'];
+
+  if ($op == t('Reset to defaults')) {
+    variable_del($key);
+  }
+  else {
+    variable_set($key, $values);
+  }
+  if ($op == t('Reset to defaults')) {
+    drupal_set_message(t('The configuration options have been reset to their default values.'));
+  }
+  else {
+    drupal_set_message(t('The configuration options have been saved.'));
+  }
+}
+
 /**
  * Execute the system_settings_form.
  *
@@ -1065,7 +1083,7 @@ function system_theme_settings($key = '') {
     $disabled['toggle_search'] = true;
   }
 
-  $form['theme_settings'] = array('#type' => 'fieldset', '#title' => t('Toggle display'), '#description' => t('Enable or disable the display of certain page elements.'), '#tree' => TRUE);
+  $form['theme_settings'] = array('#type' => 'fieldset', '#title' => t('Toggle display'), '#description' => t('Enable or disable the display of certain page elements.'));
   foreach ($toggles as $name => $title) {
     if ((!$key) || in_array($name, $features)) {
       // disable search box if search.module is disabled
diff --git a/modules/system/system.module b/modules/system/system.module
index bd0b89d821bcf1ffbb11aae3ad462173be33f819..1a7bf9d95ae1e3d58c853ed875284dc2da21373b 100644
--- a/modules/system/system.module
+++ b/modules/system/system.module
@@ -682,6 +682,24 @@ function system_settings_form($form_id, $form) {
   return drupal_get_form($form_id, $form, 'system_settings_form');
 }
 
+function system_theme_settings_execute($form_id, $values) {
+  $op = isset($_POST['op']) ? $_POST['op'] : '';
+  $key = $values['var'];
+
+  if ($op == t('Reset to defaults')) {
+    variable_del($key);
+  }
+  else {
+    variable_set($key, $values);
+  }
+  if ($op == t('Reset to defaults')) {
+    drupal_set_message(t('The configuration options have been reset to their default values.'));
+  }
+  else {
+    drupal_set_message(t('The configuration options have been saved.'));
+  }
+}
+
 /**
  * Execute the system_settings_form.
  *
@@ -1065,7 +1083,7 @@ function system_theme_settings($key = '') {
     $disabled['toggle_search'] = true;
   }
 
-  $form['theme_settings'] = array('#type' => 'fieldset', '#title' => t('Toggle display'), '#description' => t('Enable or disable the display of certain page elements.'), '#tree' => TRUE);
+  $form['theme_settings'] = array('#type' => 'fieldset', '#title' => t('Toggle display'), '#description' => t('Enable or disable the display of certain page elements.'));
   foreach ($toggles as $name => $title) {
     if ((!$key) || in_array($name, $features)) {
       // disable search box if search.module is disabled