Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.96
diff -u -p -r1.96 field.attach.inc
--- modules/field/field.attach.inc	3 Oct 2010 01:15:33 -0000	1.96
+++ modules/field/field.attach.inc	22 Oct 2010 09:25:53 -0000
@@ -539,7 +539,18 @@ function _field_invoke_get_instances($en
 function field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
   // If no language is provided use the default site language.
   $options = array('language' => field_valid_language($langcode));
-  $form += (array) _field_invoke_default('form', $entity_type, $entity, $form, $form_state, $options);
+  $sub_form = (array) _field_invoke_default('form', $entity_type, $entity, $form, $form_state);
+
+  // We can't use drupal_array_set_nested_value() because we need to merge
+  // $form and results of _field_invoke_default().
+  $ref = &$form;
+  foreach ($parents as $parent) {
+    $ref = &$ref[$parent];
+  }
+  if (!$ref) {
+    $ref = array();
+  }
+  $ref = array_merge($ref, $sub_form);
 
   // Add custom weight handling.
   list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity);
@@ -797,9 +808,10 @@ function field_attach_form_validate($ent
   catch (FieldValidationException $e) {
     // Pass field-level validation errors back to widgets for accurate error
     // flagging.
+    $parents = isset($form_state['field']['current_parents']) ? $form_state['field']['current_parents'] : array();
     foreach ($e->errors as $field_name => $field_errors) {
       foreach ($field_errors as $langcode => $language_errors) {
-        $form_state['field'][$field_name][$langcode]['errors'] = $language_errors;
+        drupal_array_set_nested_value($form_state['field'][$field_name][$langcode], array_merge($parents, array('errors')), $language_errors);
       }
     }
     _field_invoke_default('form_errors', $entity_type, $entity, $form, $form_state);
Index: modules/field/field.default.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.default.inc,v
retrieving revision 1.39
diff -u -p -r1.39 field.default.inc
--- modules/field/field.default.inc	4 Aug 2010 06:55:35 -0000	1.39
+++ modules/field/field.default.inc	22 Oct 2010 09:25:53 -0000
@@ -13,9 +13,12 @@
 
 function field_default_extract_form_values($entity_type, $entity, $field, $instance, $langcode, &$items, $form, &$form_state) {
   $field_name = $field['field_name'];
+  $parents = isset($form_state['field']['current_parents']) ? $form_state['field']['current_parents'] : array();
 
-  if (isset($form_state['values'][$field_name][$langcode])) {
-    $items = $form_state['values'][$field_name][$langcode];
+  $values_exists = FALSE;
+  $values = drupal_array_get_nested_value($form_state['values'], array_merge($parents, array($field_name, $langcode)), $values_exists);
+  if ($values_exists) {
+    $items = $values;
     // Remove the 'value' of the 'add more' button.
     unset($items['add_more']);
   }
Index: modules/field/field.form.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.form.inc,v
retrieving revision 1.51
diff -u -p -r1.51 field.form.inc
--- modules/field/field.form.inc	20 Oct 2010 01:31:06 -0000	1.51
+++ modules/field/field.form.inc	22 Oct 2010 09:25:53 -0000
@@ -16,6 +16,8 @@ function field_default_form($entity_type
     list($id, , ) = entity_extract_ids($entity_type, $entity);
   }
 
+  $parents = isset($form_state['field']['current_parents']) ? $form_state['field']['current_parents'] : array();
+
   $addition = array();
   $field_name = $field['field_name'];
   $addition[$field_name] = array();
@@ -101,6 +103,7 @@ function field_default_form($entity_type
   $elements['#after_build'][] = 'field_form_element_after_build';
   $elements['#field_name'] = $field_name;
   $elements['#language'] = $langcode;
+  $elements['#entity_parents'] = $parents;
 
   $addition[$field_name] += array(
     '#tree' => TRUE,
@@ -123,14 +126,18 @@ function field_default_form($entity_type
  */
 function field_multiple_value_form($field, $instance, $langcode, $items, &$form, &$form_state) {
   $field_name = $field['field_name'];
+  $parents = isset($form_state['field']['current_parents']) ? $form_state['field']['current_parents'] : array();
 
   // Determine the number of widgets to display.
   switch ($field['cardinality']) {
     case FIELD_CARDINALITY_UNLIMITED:
       $filled_items = _field_filter_items($field, $items);
-      $current_item_count = isset($form_state['field_item_count'][$field_name])
-                            ? $form_state['field_item_count'][$field_name]
-                            : count($items);
+      $key_exists = FALSE;
+      if (isset($form_state['field'][$field_name][$langcode])) {
+        $current_item_count = drupal_array_get_nested_value($form_state['field'][$field_name][$langcode], array_merge($parents, array('field_item_count')), $key_exists);
+      }
+      $current_item_count = $key_exists ? $current_item_count : count($items);
+
       // We always want at least one empty icon for the user to fill in.
       $max = ($current_item_count > count($filled_items))
               ? $current_item_count - 1
@@ -144,7 +151,8 @@ function field_multiple_value_form($fiel
 
   $title = check_plain(t($instance['label']));
   $description = field_filter_xss(t($instance['description']));
-  $wrapper_id = drupal_html_id($field_name . '-add-more-wrapper');
+  $prefix = count($parents) ? implode('_', $parents) . '_' : '';
+  $wrapper_id = drupal_html_id($prefix . $field_name . '-add-more-wrapper');
   $field_elements = array();
 
   $function = $instance['widget']['module'] . '_field_widget_form';
@@ -200,10 +208,10 @@ function field_multiple_value_form($fiel
       if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
         $field_elements['add_more'] = array(
           '#type' => 'submit',
-          '#name' => $field_name . '_add_more',
+          '#name' => $prefix . $field_name . '_add_more',
           '#value' => t('Add another item'),
           '#attributes' => array('class' => array('field-add-more-submit')),
-          '#limit_validation_errors' => array(array($field_name, $langcode)),
+          '#limit_validation_errors' => array(array_merge($parents, array($field_name, $langcode))),
           '#submit' => array('field_add_more_submit'),
           '#ajax' => array(
             'callback' => 'field_add_more_js',
@@ -214,6 +222,7 @@ function field_multiple_value_form($fiel
           // find the relevant field using those entries.
           '#field_name' => $field_name,
           '#language' => $langcode,
+          '#entity_parents' => $parents,
         );
       }
     }
@@ -310,7 +319,10 @@ function theme_field_multiple_value_form
 function field_form_element_after_build($element, &$form_state) {
   $field_name = $element['#field_name'];
   $langcode = $element['#language'];
-  $form_state['field'][$field_name][$langcode]['array_parents'] = $element['#array_parents'];
+  $parents = array_merge($element['#entity_parents'], array('array_parents'));
+  if (isset($form_state['field'][$field_name][$langcode])) {
+    drupal_array_set_nested_value($form_state['field'][$field_name][$langcode], $parents, $element['#array_parents']);
+  }
 
   return $element;
 }
@@ -320,7 +332,9 @@ function field_form_element_after_build(
  */
 function field_default_form_errors($entity_type, $entity, $field, $instance, $langcode, $items, $form, &$form_state) {
   $field_name = $field['field_name'];
-  $field_info = $form_state['field'][$field_name][$langcode];
+  $parents = isset($form_state['field']['current_parents']) ? $form_state['field']['current_parents'] : array();
+
+  $field_info = drupal_array_get_nested_value($form_state['field'][$field_name][$langcode], $parents);
 
   if (!empty($field_info['errors'])) {
     $function = $instance['widget']['module'] . '_field_widget_error';
@@ -363,8 +377,12 @@ function field_default_form_errors($enti
 function field_add_more_submit($form, &$form_state) {
   $field_name = $form_state['clicked_button']['#field_name'];
   $langcode = $form_state['clicked_button']['#language'];
-  if ($form_state['values'][$field_name . '_add_more']) {
-    $form_state['field_item_count'][$field_name] = count($form_state['values'][$field_name][$langcode]);
+  $parents = $form_state['clicked_button']['#entity_parents'];
+
+  $prefix = count($parents) ? implode('_', $parents) . '_' : '';
+  if ($form_state['values'][$prefix . $field_name . '_add_more']) {
+    $values = drupal_array_get_nested_value($form_state['values'], array_merge($parents, array($field_name, $langcode)));
+    drupal_array_set_nested_value($form_state['field'][$field_name][$langcode], array_merge($parents, array('field_item_count')), count($values));
   }
   $form_state['rebuild'] = TRUE;
 }
@@ -381,6 +399,7 @@ function field_add_more_js($form, $form_
   // Retrieve field information.
   $field_name = $form_state['clicked_button']['#field_name'];
   $langcode = $form_state['clicked_button']['#language'];
+  $parents = $form_state['clicked_button']['#entity_parents'];
   $field_info = $form_state['field'][$field_name][$langcode];
   $field = $field_info['field'];
 
@@ -390,8 +409,8 @@ function field_add_more_js($form, $form_
 
   // Navigate to the right element in the the form.
   $element = $form;
-
-  foreach ($field_info['array_parents'] as $key) {
+  $array_parents = drupal_array_get_nested_value($field_info, array_merge($parents, array('array_parents')));
+  foreach ($array_parents as $key) {
     $element = $element[$key];
   }
 
