Index: includes/form.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/form.inc,v
retrieving revision 1.456
diff -u -p -r1.456 form.inc
--- includes/form.inc	28 Apr 2010 16:11:22 -0000	1.456
+++ includes/form.inc	29 Apr 2010 03:08:42 -0000
@@ -1293,6 +1293,12 @@ function form_builder($form_id, $element
   foreach (element_children($element) as $key) {
     // Don't squash an existing tree value.
     if (!isset($element[$key]['#tree'])) {
+      // #tree explicitly set to NULL should result in $key not being added to
+      // #parents of self or children, and not changing how #tree cascades to
+      // children. Don't squash existing parents value.
+      if (array_key_exists('#tree', $element[$key]) && !isset($element[$key]['#parents'])) {
+        $element[$key]['#parents'] = $element['#parents'];
+      }
       $element[$key]['#tree'] = $element['#tree'];
     }
 
Index: modules/simpletest/tests/form.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v
retrieving revision 1.50
diff -u -p -r1.50 form.test
--- modules/simpletest/tests/form.test	28 Apr 2010 16:11:22 -0000	1.50
+++ modules/simpletest/tests/form.test	29 Apr 2010 03:08:44 -0000
@@ -1053,7 +1053,6 @@ class FormsClickedButtonTestCase extends
   }
 }
 
-
 /**
  * Tests rebuilding of arbitrary forms by altering them.
  */
@@ -1118,3 +1117,29 @@ class FormsArbitraryRebuildTestCase exte
     $this->assertFieldByName('mail', 'bar@example.com', 'Entered mail address has been kept.');
   }
 }
+
+/**
+ * Tests the #tree property.
+ */
+class FormsTreeValueTestCase extends DrupalWebTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Form values tree',
+      'description' => 'Tests using the tree property to build the form values.',
+      'group' => 'Form API',
+    );
+  }
+
+  function setUp() {
+    parent::setUp('form_test');
+  }
+
+  /**
+   * Tests the tree value form to make sure the value is under the right parent.
+   */
+  function testTreeValues() {
+    $this->drupalPost('form-test/tree-values', array(), t('Save'));
+    $this->assertText('Value is in A:C:D.');
+  }
+}
Index: modules/simpletest/tests/form_test.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form_test.module,v
retrieving revision 1.39
diff -u -p -r1.39 form_test.module
--- modules/simpletest/tests/form_test.module	28 Apr 2010 16:11:22 -0000	1.39
+++ modules/simpletest/tests/form_test.module	29 Apr 2010 03:08:44 -0000
@@ -145,6 +145,14 @@ function form_test_menu() {
     );
   }
 
+  $items['form-test/tree-values'] = array(
+    'title' => 'Tree values test',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('form_test_tree_values'),
+    'access callback' => TRUE,
+    'type' => MENU_CALLBACK,
+  );
+
   return $items;
 }
 
@@ -1135,3 +1143,44 @@ function form_test_two_instances() {
   $return['node_form_2'] = drupal_get_form('page_node_form', $node2);
   return $return;
 }
+
+/**
+ * Form constructor for the #tree property test form.
+ */
+function form_test_tree_values($form, $form_state) {
+  $form['a'] = array(
+    '#title' => 'A',
+    '#type' => 'fieldset',
+    '#tree' => TRUE,
+  );
+  $form['a']['b'] = array(
+    '#title' => 'A:B',
+    '#type' => 'fieldset',
+    // Exclude 'b' from #parents of child elements without forcing the child
+    // elements out of the tree entirely.
+    '#tree' => NULL,
+  );
+  $form['a']['b']['c'] = array(
+    '#title' => 'A:B:C',
+    '#type' => 'fieldset',
+  );
+  $form['a']['b']['c']['d'] = array(
+    '#title' => 'A:B:C:D',
+    '#type' => 'textfield',
+    '#default_value' => 'DEFAULT',
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save'),
+  );
+  return $form;
+}
+
+/**
+ * Submit callback for the #tree property test form.
+ */
+function form_test_tree_values_submit($form, $form_state) {
+  if ($form_state['values']['a']['c']['d'] == 'DEFAULT') {
+    drupal_set_message('Value is in A:C:D.');
+  }
+}
