? .cache
? .settings
Index: modules/field/field.api.php
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.api.php,v
retrieving revision 1.53
diff -u -p -r1.53 field.api.php
--- modules/field/field.api.php	12 Dec 2009 20:16:03 -0000	1.53
+++ modules/field/field.api.php	13 Dec 2009 01:26:16 -0000
@@ -621,15 +621,16 @@ function hook_field_widget_info_alter(&$
  * contains the base form element properties derived from the field
  * configuration.
  *
- * Field API will set the weight, field name and delta values for each
- * form element. If there are multiple values for this field, the
- * Field API will call this function as many times as needed.
+ * @todo note about $form_state['storage']['field_info']
+ *
+ * Field API will set the weight, field name and delta values for each form
+ * element. If there are multiple values for this field, the Field API will
+ * call this function as many times as needed.
  *
  * @param $form
  *   The entire form array.
  * @param $form_state
- *   The form_state, $form_state['values'][$field['field_name']]
- *   holds the field's form values.
+ *   An associative array containing the current state of the form.
  * @param $field
  *   The field structure.
  * @param $instance
@@ -645,6 +646,7 @@ function hook_field_widget_info_alter(&$
  *   - #object_type: The name of the object the field is attached to.
  *   - #bundle: The name of the field bundle the field is contained in.
  *   - #field_name: The name of the field.
+ *   - #language: The language the field is being edited in.
  *   - #columns: A list of field storage columns of the field.
  *   - #title: The sanitized element label for the field instance, ready for
  *     output.
@@ -655,7 +657,6 @@ function hook_field_widget_info_alter(&$
  *     required.
  *   - #delta: The order of this item in the array of subelements; see $delta
  *     above.
- *
  * @return
  *   The form elements for a single widget for this field.
  */
@@ -680,8 +681,12 @@ function hook_field_widget(&$form, &$for
  *   - 'error': the error code. Complex widgets might need to report different
  *     errors to different form elements inside the widget.
  *   - 'message': the human readable message to be displayed.
+ * @param $form
+ *   The form array.
+ * @param $form_state
+ *   An associative array containing the current state of the form.
  */
-function hook_field_widget_error($element, $error) {
+function hook_field_widget_error($element, $error, $form, &$form_state) {
   form_error($element['value'], $error['message']);
 }
 
Index: modules/field/field.attach.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.attach.inc,v
retrieving revision 1.62
diff -u -p -r1.62 field.attach.inc
--- modules/field/field.attach.inc	12 Dec 2009 20:16:03 -0000	1.62
+++ modules/field/field.attach.inc	13 Dec 2009 01:26:16 -0000
@@ -414,21 +414,10 @@ function _field_invoke_multiple_default(
  *   is provided the default site language will be used.
  * @return
  *   The form elements are added by reference at the top level of the $form
- *   parameter. Sample structure:
+ *   parameter. Processing information is added by reference in
+ *   $form_state['storage']['field_info'].
+ *   Sample structure for $form:
  *   @code
- *   array(
- *     '#fields' => array(
- *       // One sub-array per field appearing in the form, keyed by field name.
- *       'field_foo' => array (
- *         'field' => the field definition structure,
- *         'instance' => the field instance definition structure,
- *         'form_path' => an array of keys indicating the path to the field
- *           element within the full $form structure, used by the 'add more
- *           values' AHAH button. Any 3rd party module using form_alter() to
- *           modify the structure of the form should update this entry as well.
- *       ),
- *     ),
- *
  *     // One sub-array per field appearing in the form, keyed by field name.
  *     // The structure of the array differs slightly depending on whether the
  *     // widget is 'single-value' (provides the input for one field value,
@@ -436,12 +425,12 @@ function _field_invoke_multiple_default(
  *     // needed, or 'multiple-values' (one single widget allows the input of
  *     // several values, e.g checkboxes, select box...).
  *     // The sub-array is nested into a $langcode key where $langcode has the
- *     // same value of the $langcode parameter above. This allow us to match
- *     // the field data structure ($field_name[$langcode][$delta][$column]).
+ *     // same value of the $langcode parameter above.
  *     // The '#language' key holds the same value of $langcode and it is used
  *     // to access the field sub-array when $langcode is unknown.
  *     'field_foo' => array(
  *       '#tree' => TRUE,
+ *       '#field_name' => the name of the field
  *       '#language' => $langcode,
  *       $langcode => array(
  *         '#field_name' => the name of the field,
@@ -481,6 +470,26 @@ function _field_invoke_multiple_default(
  *     ),
  *   )
  *   @endcode
+ *
+ *   Sample structure for $form_state['storage']['field_info']: @todo
+ *   @code
+ *   array(
+ *       // One sub-array per field appearing in the form, keyed by field name.
+ *       'field_foo' => array (
+ *         // One sub-array per language the field is being edited in.
+ *         // @todo compare with above.
+ *         'xxz' => array (
+ *           'field' => the field definition structure,
+ *           'instance' => the field instance definition structure,
+ *           'parents' => @todo
+ *           'array_parents' => @todo an array of keys indicating the path to the field
+ *             element within the full $form structure, used by the 'add more
+ *             values' AHAH button.
+ *           'errors' => @todo
+ *         ),
+ *       ),
+ *     ),
+ *
  */
 function field_attach_form($obj_type, $object, &$form, &$form_state, $langcode = NULL) {
   // If no language is provided use the default site language.
@@ -743,7 +752,12 @@ function field_attach_form_validate($obj
   catch (FieldValidationException $e) {
     // Pass field-level validation errors back to widgets for accurate error
     // flagging.
-    _field_invoke_default('form_errors', $obj_type, $object, $form, $e->errors);
+    foreach ($e->errors as $field_name => $field_errors) {
+      foreach ($field_errors as $langcode => $language_errors) {
+        $form_state['storage']['field_info'][$field_name][$langcode]['errors'] = $language_errors;
+      }
+    }
+    _field_invoke_default('form_errors', $obj_type, $object, $form, $form_state);
   }
 }
 
Index: modules/field/field.form.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/field.form.inc,v
retrieving revision 1.36
diff -u -p -r1.36 field.form.inc
--- modules/field/field.form.inc	1 Dec 2009 03:07:33 -0000	1.36
+++ modules/field/field.form.inc	13 Dec 2009 01:26:16 -0000
@@ -17,16 +17,16 @@ function field_default_form($obj_type, $
   }
 
   $field_name = $field['field_name'];
+  $addition[$field_name] = array();
 
-  // Put field information at the top of the form, so that it can be easily
-  // retrieved.
-  // Note : widgets and other form handling code should *always* fetch field
-  // and instance information from $form['#fields'] rather than from
-  // field_info_field(). This lets us build forms for 'variants' of a field,
-  // for instance on admin screens.
-  $form['#fields'][$field_name] = array(
+  // Store field information in $form_state['storage'].
+  $form_state['storage']['field_info'][$field_name][$langcode] = array(
     'field' => $field,
     'instance' => $instance,
+    // This entry will be populated at form build time.
+    'array_parents' => array(),
+    // This entry will be populated at form validation time.
+    'errors' => array(),
   );
 
   // Populate widgets with default values when creating a new object.
@@ -34,13 +34,13 @@ function field_default_form($obj_type, $
     $items = field_get_default_value($obj_type, $object, $field, $instance, $langcode);
   }
 
-  $field_elements = array();
-
+  // Collect widget elements.
+  $elements = array();
   if (field_access('edit', $field, $obj_type, $object)) {
     // If field module handles multiple values for this form element, and we
     // are displaying an individual element, process the multiple value form.
     if (!isset($get_delta) && field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
-      $field_elements = field_multiple_value_form($field, $instance, $langcode, $items, $form, $form_state);
+      $elements = field_multiple_value_form($field, $instance, $langcode, $items, $form, $form_state);
     }
     // If the widget is handling multiple values (e.g Options), or if we are
     // displaying an individual element, just get a single form element and
@@ -53,6 +53,7 @@ function field_default_form($obj_type, $
           '#object_type' => $instance['object_type'],
           '#bundle' => $instance['bundle'],
           '#field_name' => $field_name,
+          '#language' => $langcode,
           '#columns' => array_keys($field['columns']),
           '#title' => check_plain(t($instance['label'])),
           '#description' => field_filter_xss($instance['description']),
@@ -67,23 +68,17 @@ function field_default_form($obj_type, $
           // assumptions about how the field is structured, just merge in the
           // returned element.
           if (field_behaviors_widget('multiple values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
-            $field_elements[$delta] = $element;
+            $elements[$delta] = $element;
           }
           else {
-            $field_elements = $element;
+            $elements = $element;
           }
         }
       }
     }
   }
 
-  if ($field_elements) {
-    // Add the field form element as a child keyed by language code to match
-    // the field data structure:
-    // $object->{$field_name}[$langcode][$delta][$column].
-    // The '#language' key can be used to access the field's form element
-    // when $langcode is unknown. The #weight property is inherited from the
-    // field's form element.
+  if ($elements) {
     // Also aid in theming of field widgets by rendering a classified
     // container.
     $addition[$field_name] = array(
@@ -95,29 +90,32 @@ function field_default_form($obj_type, $
           'field-widget-' . drupal_html_class($instance['widget']['type']),
         ),
       ),
-      '#tree' => TRUE,
       '#weight' => $instance['widget']['weight'],
-      '#language' => $langcode,
-      $langcode => $field_elements,
     );
   }
   else {
     // The field is not accessible, or the widget did not return anything. Make
     // sure the items are available in the submitted form values.
     foreach ($items as $delta => $item) {
-      $field_elements[$delta] = array(
+      $elements[$delta] = array(
         '#type' => 'value',
         '#value' => $item,
       );
     }
-    $addition[$field_name] = array(
-      '#tree' => TRUE,
-      '#language' => $langcode,
-      $langcode => $field_elements,
-    );
   }
 
-  $form['#fields'][$field_name]['form_path'] = array($field_name);
+  // @todo A word of explanation.
+  $elements['#after_build'][] = 'field_form_element_after_build';
+  $elements['#field_name'] = $field_name;
+  $elements['#language'] = $langcode;
+
+  $addition[$field_name] += array(
+    '#tree' => TRUE,
+    // The '#language' key can be used to access the field's form element
+    // when $langcode is unknown.
+    '#language' => $langcode,
+    $langcode => $elements,
+  );
 
   return $addition;
 }
@@ -158,7 +156,7 @@ function field_multiple_value_form($fiel
 
   $title = check_plain(t($instance['label']));
   $description = field_filter_xss(t($instance['description']));
-  $wrapper_id = drupal_html_class($field_name) . '-wrapper';
+  $wrapper_id = drupal_html_class($field_name) . '-add-more-wrapper';
   $field_elements = array();
 
   $function = $instance['widget']['module'] . '_field_widget';
@@ -169,6 +167,7 @@ function field_multiple_value_form($fiel
         '#object_type' => $instance['object_type'],
         '#bundle' => $instance['bundle'],
         '#field_name' => $field_name,
+        '#language' => $langcode,
         '#columns' => array_keys($field['columns']),
         // For multiple fields, title and description are handled by the wrapping table.
         '#title' => $multiple ? '' : $title,
@@ -304,36 +303,54 @@ function theme_field_multiple_value_form
   return $output;
 }
 
+/**
+ * Stores information about the built form structure in the form storage.
+ *
+ * The 'array_parents' array is used to assign validation errors to actual form
+ * elements, and to identify the form element to return in the AJAX 'add more'
+ * button handler.
+ * @see field_default_form_errors()
+ * @see field_add_more_js()
+ */
+function field_form_element_after_build($element, &$form_state) {
+  $field_name = $element['#field_name'];
+  $langcode = $element['#language'];
+  $form_state['storage']['field_info'][$field_name][$langcode]['array_parents'] = $element['#array_parents'];
+
+  return $element;
+}
 
 /**
  * Transfer field-level validation errors to widgets.
  */
-function field_default_form_errors($obj_type, $object, $field, $instance, $langcode, $items, $form, $errors) {
+function field_default_form_errors($obj_type, $object, $field, $instance, $langcode, $items, $form, &$form_state) {
   $field_name = $field['field_name'];
-  if (!empty($errors[$field_name][$langcode])) {
+  $field_info = $form_state['storage']['field_info'][$field_name][$langcode];
+  // @todo Should we test isset($form_state['storage']['field_info'][$field_name][$langcode]) ?
+
+  if (!empty($field_info['errors'])) {
     $function = $instance['widget']['module'] . '_field_widget_error';
     $function_exists = function_exists($function);
 
     // Walk the form down to where the widget lives.
-    $form_path = $form['#fields'][$field_name]['form_path'];
     $element = $form;
-    foreach ($form_path as $key) {
+    foreach ($field_info['array_parents'] as $key) {
       $element = $element[$key];
     }
 
     $multiple_widget = field_behaviors_widget('multiple values', $instance) != FIELD_BEHAVIOR_DEFAULT;
-    foreach ($errors[$field_name][$langcode] as $delta => $delta_errors) {
+    foreach ($field_info['errors'] as $delta => $delta_errors) {
       // For multiple single-value widgets, pass errors by delta.
       // For a multiple-value widget, all errors are passed to the main widget.
-      $error_element = $multiple_widget ? $element[$langcode] : $element[$langcode][$delta];
+      $error_element = $multiple_widget ? $element : $element[$delta];
       foreach ($delta_errors as $error) {
         if ($function_exists) {
-          $function($error_element, $error);
+          $function($error_element, $error, $form, $form_state);
         }
         else {
           // Make sure that errors are reported (even incorrectly flagged) if
           // the widget module fails to implement hook_field_widget_error().
-          form_error($error_element, $error['error']);
+          form_error($error_element, $error['error'], $form, $form_state);
         }
       }
     }
@@ -365,22 +382,25 @@ function field_add_more_submit($form, &$
 function field_add_more_js($form, $form_state) {
   // Retrieve field information.
   $field_name = $form_state['clicked_button']['#field_name'];
-  $field = $form['#fields'][$field_name]['field'];
+  $langcode = $form_state['clicked_button']['#language'];
+  $field_info = $form_state['storage']['field_info'][$field_name][$langcode];
+  $field = $field_info['field'];
+
   if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
     ajax_render(array());
   }
-  // Navigate to the right part of the form.
-  $form_path = $form['#fields'][$field_name]['form_path'];
-  $field_form = $form;
-  foreach ($form_path as $key) {
-    $field_form = $field_form[$key];
+
+  // Navigate to the right element in the the form.
+  $element = $form;
+
+  foreach ($field_info['array_parents'] as $key) {
+    $element = $element[$key];
   }
 
   // Add a DIV around the new field to receive the AJAX effect.
-  $langcode = $field_form['#language'];
-  $delta = $field_form[$langcode]['#max_delta'];
-  $field_form[$langcode][$delta]['#prefix'] = '<div class="ajax-new-content">' . (isset($field_form[$langcode][$delta]['#prefix']) ? $field_form[$langcode][$delta]['#prefix'] : '');
-  $field_form[$langcode][$delta]['#suffix'] = (isset($field_form[$langcode][$delta]['#suffix']) ? $field_form[$langcode][$delta]['#suffix'] : '') . '</div>';
+  $delta = $element['#max_delta'];
+  $element[$delta]['#prefix'] = '<div class="ajax-new-content">' . (isset($element[$delta]['#prefix']) ? $element[$delta]['#prefix'] : '');
+  $element[$delta]['#suffix'] = (isset($element[$delta]['#suffix']) ? $element[$delta]['#suffix'] : '') . '</div>';
 
-  return drupal_render($field_form);
+  return $element;
 }
Index: modules/field/modules/number/number.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/number/number.module,v
retrieving revision 1.31
diff -u -p -r1.31 number.module
--- modules/field/modules/number/number.module	12 Dec 2009 20:16:03 -0000	1.31
+++ modules/field/modules/number/number.module	13 Dec 2009 01:26:16 -0000
@@ -324,8 +324,8 @@ function number_field_widget(&$form, &$f
  * FAPI validation of an individual number element.
  */
 function number_field_widget_validate($element, &$form_state) {
-  $field = $form_state['complete form']['#fields'][$element['#field_name']]['field'];
-  $instance = $form_state['complete form']['#fields'][$element['#field_name']]['instance'];
+  $field = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['field'];
+  $instance = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['instance'];
 
   $type = $element['#number_type'];
   $value = $element['#value'];
@@ -360,6 +360,6 @@ function number_field_widget_validate($e
 /**
  * Implements hook_field_widget_error().
  */
-function number_field_widget_error($element, $error) {
+function number_field_widget_error($element, $error, $form, &$form_state) {
   form_error($element['value'], $error['message']);
 }
Index: modules/field/modules/options/options.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/options/options.module,v
retrieving revision 1.19
diff -u -p -r1.19 options.module
--- modules/field/modules/options/options.module	4 Dec 2009 16:49:46 -0000	1.19
+++ modules/field/modules/options/options.module	13 Dec 2009 01:26:16 -0000
@@ -115,8 +115,8 @@ function options_field_widget(&$form, &$
  * Form element validation handler for options element.
  */
 function options_field_widget_validate($element, &$form_state) {
-  $field = $form_state['complete form']['#fields'][$element['#field_name']]['field'];
-  $instance = $form_state['complete form']['#fields'][$element['#field_name']]['instance'];
+  $field = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['field'];
+  $instance = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['instance'];
 
   // Transpose selections from field => delta to delta => field, turning
   // multiple selected options into multiple parent elements.
@@ -252,7 +252,7 @@ function options_array_transpose($array)
 /**
  * Implements hook_field_widget_error().
  */
-function options_field_widget_error($element, $error) {
+function options_field_widget_error($element, $error, $form, &$form_state) {
   form_error($element, $error['message']);
 }
 
Index: modules/field/modules/text/text.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/text/text.module,v
retrieving revision 1.42
diff -u -p -r1.42 text.module
--- modules/field/modules/text/text.module	12 Dec 2009 20:16:03 -0000	1.42
+++ modules/field/modules/text/text.module	13 Dec 2009 01:26:16 -0000
@@ -553,7 +553,7 @@ function text_field_widget(&$form, &$for
 /**
  * Implements hook_field_widget_error().
  */
-function text_field_widget_error($element, $error) {
+function text_field_widget_error($element, $error, $form, &$form_state) {
   switch ($error['error']) {
     case 'text_summary_max_length':
       $error_element = $element[$element['#columns'][1]];
Index: modules/field/tests/field.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/tests/field.test,v
retrieving revision 1.7
diff -u -p -r1.7 field.test
--- modules/field/tests/field.test	11 Dec 2009 16:49:40 -0000	1.7
+++ modules/field/tests/field.test	13 Dec 2009 01:26:17 -0000
@@ -1112,6 +1112,9 @@ class FieldAttachOtherTestCase extends F
     $values[1]['value'] = 0;
 
     $langcode = LANGUAGE_NONE;
+    // Pretend the form has been built.
+    drupal_prepare_form('field_test_entity_form', $form, $form_state);
+    $form = form_builder('field_test_entity_form', $form, $form_state);
     $form_state['values'] = array($this->field_name => array($langcode => $values));
     field_attach_submit($entity_type, $entity, $form, $form_state);
 
Index: modules/field/tests/field_test.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/tests/field_test.field.inc,v
retrieving revision 1.4
diff -u -p -r1.4 field_test.field.inc
--- modules/field/tests/field_test.field.inc	12 Dec 2009 20:16:03 -0000	1.4
+++ modules/field/tests/field_test.field.inc	13 Dec 2009 01:26:17 -0000
@@ -169,7 +169,7 @@ function field_test_field_widget(&$form,
 /**
  * Implements hook_field_widget_error().
  */
-function field_test_field_widget_error($element, $error) {
+function field_test_field_widget_error($element, $error, $form, &$form_state) {
   form_error($element['value'], $error['message']);
 }
 
Index: modules/field_ui/field_ui.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.admin.inc,v
retrieving revision 1.31
diff -u -p -r1.31 field_ui.admin.inc
--- modules/field_ui/field_ui.admin.inc	2 Dec 2009 19:26:22 -0000	1.31
+++ modules/field_ui/field_ui.admin.inc	13 Dec 2009 01:26:17 -0000
@@ -1204,6 +1204,7 @@ function field_ui_default_value_widget($
     '#collapsible' => FALSE,
     '#tree' => TRUE,
     '#description' => t('The default value for this field, used when creating new content.'),
+    '#parents' => array(),
   );
 
   // Insert the widget.
@@ -1213,10 +1214,6 @@ function field_ui_default_value_widget($
   // @todo Allow multiple values (requires more work on 'add more' JS handler).
   $element += field_default_form(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state, 0);
 
-  // Adjust 'form_path' to reflect the actual location of the widget in the
-  // form structure.
-  $form['#fields'][$field_name]['form_path'] = array('instance', 'default_value_widget', $field_name);
-
   return $element;
 }
 
@@ -1225,25 +1222,22 @@ function field_ui_default_value_widget($
  */
 function field_ui_field_edit_form_validate($form, &$form_state) {
   $instance = $form_state['values']['instance'];
+  $field_name = $instance['field_name'];
+  $field = field_info_field($field_name);
 
   // Validate the default value.
-  if (!empty($instance['default_value_widget'])) {
-    $field = field_info_field($instance['field_name']);
-
-    // Extract field values.
-    $items = array();
-    $form_state_copy = array('values' => $instance['default_value_widget']);
-    field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state_copy);
-
-    // Validate the values and report errors.
-    $errors = array();
-    $function = $field['module'] . '_field_validate';
-    if (function_exists($function)) {
-      $function(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $errors);
-    }
-    if ($errors) {
-      field_default_form_errors(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $errors);
-    }
+  // Extract field values.
+  $items = array();
+  field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
+  // Validate the values and report errors.
+  $errors = array();
+  $function = $field['module'] . '_field_validate';
+  if (function_exists($function)) {
+    $function(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $errors);
+  }
+  if (isset($errors[$field_name][LANGUAGE_NONE])) {
+    $form_state['storage']['field_info'][$field_name][LANGUAGE_NONE]['errors'] = $errors[$field_name][LANGUAGE_NONE];
+    field_default_form_errors(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
   }
 }
 
@@ -1260,18 +1254,12 @@ function field_ui_field_edit_form_submit
   field_update_field($field);
 
   // Handle the default value.
-  if (!empty($instance['default_value_widget'])) {
-    // Extract field values.
-    $items = array();
-    $form_state_copy = array('values' => $instance['default_value_widget']);
-    field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state_copy);
-
-    // Prepare field values.
-    field_default_submit(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state_copy);
-
-    $instance['default_value'] = $items ? $items : NULL;
-    unset($instance['default_value_widget']);
-  }
+  // Extract field values.
+  $items = array();
+  field_default_extract_form_values(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
+  // Prepare field values.
+  field_default_submit(NULL, NULL, $field, $instance, LANGUAGE_NONE, $items, $form, $form_state);
+  $instance['default_value'] = $items ? $items : NULL;
 
   // Update the instance settings.
   $instance_source = field_info_instance($instance['object_type'], $instance['field_name'], $instance['bundle']);
Index: modules/field_ui/field_ui.test
===================================================================
RCS file: /cvs/drupal/drupal/modules/field_ui/field_ui.test,v
retrieving revision 1.6
diff -u -p -r1.6 field_ui.test
--- modules/field_ui/field_ui.test	2 Dec 2009 19:26:22 -0000	1.6
+++ modules/field_ui/field_ui.test	13 Dec 2009 01:26:17 -0000
@@ -236,8 +236,8 @@ class FieldUITestCase extends DrupalWebT
 
     $langcode = LANGUAGE_NONE;
     $admin_path = 'admin/structure/types/manage/' . $this->hyphen_type . '/fields/' . $field_name;
-    $element_id = "edit-instance-default-value-widget-$field_name-$langcode-0-value";
-    $element_name = "instance[default_value_widget][$field_name][$langcode][0][value]";
+    $element_id = "edit-$field_name-$langcode-0-value";
+    $element_name = "{$field_name}[$langcode][0][value]";
 
     $this->drupalGet($admin_path);
     $this->assertFieldById($element_id, '', t('The default value widget was empty.'));
Index: modules/file/file.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/file/file.field.inc,v
retrieving revision 1.13
diff -u -p -r1.13 file.field.inc
--- modules/file/file.field.inc	12 Dec 2009 20:16:03 -0000	1.13
+++ modules/file/file.field.inc	13 Dec 2009 01:26:17 -0000
@@ -500,9 +500,9 @@ function file_field_widget(&$form, &$for
     $elements['#process'] = array('file_field_widget_process_multiple');
     $elements['#title'] = $element['#title'];
     $elements['#description'] = $element['#description'];
-    $elements['#object_type'] = $element['#object_type'];
-    $elements['#bundle'] = $element['#bundle'];
     $elements['#field_name'] = $element['#field_name'];
+    $elements['#language'] = $element['#language'];
+    $elements['#display_field'] = $field['settings']['display_field'];
 
     // Add some properties that will eventually be added to the file upload
     // field. These are added here so that they may be referenced easily through
@@ -570,7 +570,7 @@ function file_field_widget_value($elemen
   if ($input) {
     // Checkboxes lose their value when empty.
     // If the display field is present make sure its unchecked value is saved.
-    $field = field_info_field($element['#field_name']);
+    $field = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['field'];
     if (empty($input['display'])) {
       $input['display'] = $field['settings']['display_field'] ? 0 : 1;
     }
@@ -598,8 +598,8 @@ function file_field_widget_process($elem
   $item = $element['#value'];
   $item['fid'] = $element['fid']['#value'];
 
-  $field = field_info_field($element['#field_name']);
-  $instance = field_info_instance($element['#object_type'], $element['#field_name'], $element['#bundle']);
+  $field = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['field'];
+  $instance = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['instance'];
   $settings = $instance['widget']['settings'];
 
   $element['#theme'] = 'file_widget';
@@ -710,9 +710,6 @@ function theme_file_widget($variables) {
 function theme_file_widget_multiple($variables) {
   $element = $variables['element'];
 
-  $field = field_info_field($element['#field_name']);
-  $instance = field_info_instance($element['#object_type'], $element['#field_name'], $element['#bundle']);
-
   // Get our list of widgets in order.
   $widgets = array();
   foreach (element_children($element) as $key) {
@@ -727,7 +724,7 @@ function theme_file_widget_multiple($var
   // Build up a table of applicable fields.
   $headers = array();
   $headers[] = t('File information');
-  if (!empty($field['settings']['display_field'])) {
+  if ($element['#display_field']) {
     $headers[] = array(
       'data' => t('Display'),
       'class' => array('checkbox'),
@@ -755,7 +752,7 @@ function theme_file_widget_multiple($var
 
     // Render the "Display" option in its own own column.
     $display = '';
-    if (!empty($field['settings']['display_field'])) {
+    if ($element['#display_field']) {
       unset($element[$key]['display']['#title']);
       $display = array(
         'data' => drupal_render($element[$key]['display']),
@@ -773,7 +770,7 @@ function theme_file_widget_multiple($var
 
     $row = array();
     $row[] = $information;
-    if (!empty($field['settings']['display_field'])) {
+    if ($element['#display_field']) {
       $row[] = $display;
     }
     $row[] = $weight;
Index: modules/image/image.field.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.field.inc,v
retrieving revision 1.7
diff -u -p -r1.7 image.field.inc
--- modules/image/image.field.inc	12 Dec 2009 20:16:03 -0000	1.7
+++ modules/image/image.field.inc	13 Dec 2009 01:26:17 -0000
@@ -346,8 +346,8 @@ function image_field_widget_process($ele
   $item = $element['#value'];
   $item['fid'] = $element['fid']['#value'];
 
-  $field = field_info_field($element['#field_name']);
-  $instance = field_info_instance($element['#object_type'], $element['#field_name'], $element['#bundle']);
+  $instance = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['instance'];
+
   $settings = $instance['settings'];
   $widget_settings = $instance['widget']['settings'];
 
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.548
diff -u -p -r1.548 taxonomy.module
--- modules/taxonomy/taxonomy.module	12 Dec 2009 20:16:03 -0000	1.548
+++ modules/taxonomy/taxonomy.module	13 Dec 2009 01:26:17 -0000
@@ -1271,7 +1271,7 @@ function taxonomy_autocomplete_validate(
   // them here and process them independently.
   if ($tags = $element['#value']) {
     // Collect candidate vocabularies.
-    $field = $form_state['complete form']['#fields'][$element['#field_name']]['field'];
+    $field = $form_state['storage']['field_info'][$element['#field_name']][$element['#language']]['field'];
     $vids = array();
     foreach ($field['settings']['allowed_values'] as $tree) {
       $vids[] = $tree['vid'];
@@ -1309,10 +1309,9 @@ function taxonomy_autocomplete_validate(
 /**
  * Implements hook_field_widget_error().
  */
-function taxonomy_field_widget_error($element, $error) {
+function taxonomy_field_widget_error($element, $error, $form, &$form_state) {
   form_error($element, $error['message']);
 }
-
 /**
  * Implements hook_field_settings_form().
  */
