diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc
index 5bebe9b..f0fcb36 100644
--- a/modules/field/field.attach.inc
+++ b/modules/field/field.attach.inc
@@ -555,16 +555,19 @@ function _field_invoke_get_instances($entity_type, $bundle, $options) {
  * @param $langcode
  *   The language the field values are going to be entered, if no language
  *   is provided the default site language will be used.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  *
  * @see field_form_get_state()
  * @see field_form_set_state()
  */
-function field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode = NULL) {
+function field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode = NULL, $options = array()) {
   // Set #parents to 'top-level' by default.
   $form += array('#parents' => array());
 
   // If no language is provided use the default site language.
-  $options = array('language' => field_valid_language($langcode));
+  $options['language'] = field_valid_language($langcode);
   $form += (array) _field_invoke_default('form', $entity_type, $entity, $form, $form_state, $options);
 
   // Add custom weight handling.
@@ -769,13 +772,17 @@ function field_attach_load_revision($entity_type, $entities, $options = array())
  *   If validation errors are found, a FieldValidationException is thrown. The
  *   'errors' property contains the array of errors, keyed by field name,
  *   language and delta.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  */
-function field_attach_validate($entity_type, $entity) {
+function field_attach_validate($entity_type, $entity, $options = array()) {
   $errors = array();
   // Check generic, field-type-agnostic errors first.
-  _field_invoke_default('validate', $entity_type, $entity, $errors);
+  $null = NULL;
+  _field_invoke_default('validate', $entity_type, $entity, $errors, $null, $options);
   // Check field-type specific errors.
-  _field_invoke('validate', $entity_type, $entity, $errors);
+  _field_invoke('validate', $entity_type, $entity, $errors, $null, $options);
 
   // Let other modules validate the entity.
   // Avoid module_invoke_all() to let $errors be taken by reference.
@@ -817,14 +824,17 @@ function field_attach_validate($entity_type, $entity) {
  *   full form structure, or a sub-element of a larger form.
  * @param $form_state
  *   An associative array containing the current state of the form.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  */
-function field_attach_form_validate($entity_type, $entity, $form, &$form_state) {
+function field_attach_form_validate($entity_type, $entity, $form, &$form_state, $options = array()) {
   // Extract field values from submitted values.
   _field_invoke_default('extract_form_values', $entity_type, $entity, $form, $form_state);
 
   // Perform field_level validation.
   try {
-    field_attach_validate($entity_type, $entity);
+    field_attach_validate($entity_type, $entity, $options);
   }
   catch (FieldValidationException $e) {
     // Pass field-level validation errors back to widgets for accurate error
@@ -836,7 +846,7 @@ function field_attach_form_validate($entity_type, $entity, $form, &$form_state)
         field_form_set_state($form['#parents'], $field_name, $langcode, $form_state, $field_state);
       }
     }
-    _field_invoke_default('form_errors', $entity_type, $entity, $form, $form_state);
+    _field_invoke_default('form_errors', $entity_type, $entity, $form, $form_state, $options);
   }
 }
 
@@ -857,12 +867,15 @@ function field_attach_form_validate($entity_type, $entity, $form, &$form_state)
  *   full form structure, or a sub-element of a larger form.
  * @param $form_state
  *   An associative array containing the current state of the form.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  */
-function field_attach_submit($entity_type, $entity, $form, &$form_state) {
+function field_attach_submit($entity_type, $entity, $form, &$form_state, $options = array()) {
   // Extract field values from submitted values.
   _field_invoke_default('extract_form_values', $entity_type, $entity, $form, $form_state);
 
-  _field_invoke_default('submit', $entity_type, $entity, $form, $form_state);
+  _field_invoke_default('submit', $entity_type, $entity, $form, $form_state, $options);
 
   // Let other modules act on submitting the entity.
   // Avoid module_invoke_all() to let $form_state be taken by reference.
@@ -1093,9 +1106,12 @@ function field_attach_delete_revision($entity_type, $entity) {
  * @param $langcode
  *   (Optional) The language the field values are to be shown in. If no language
  *   is provided the current language is used.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  */
-function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcode = NULL) {
-  $options = array('language' => array());
+function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcode = NULL, $options = array()) {
+  $options['language'] = array();
 
   // To ensure hooks are only run once per entity, only process items without
   // the _field_view_prepared flag.
@@ -1167,14 +1183,17 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcod
  * @param $langcode
  *   The language the field values are to be shown in. If no language is
  *   provided the current language is used.
+ * @param array $options
+ *   An associative array of additional options. See field_invoke_method() for
+ *   details.
  * @return
  *   A renderable array for the field values.
  */
-function field_attach_view($entity_type, $entity, $view_mode, $langcode = NULL) {
+function field_attach_view($entity_type, $entity, $view_mode, $langcode = NULL, $options = array()) {
   // Determine the actual language to display for each field, given the
   // languages available in the field data.
   $display_language = field_language($entity_type, $entity, NULL, $langcode);
-  $options = array('language' => $display_language);
+  $options['language'] = $display_language;
 
   // Invoke field_default_view().
   $null = NULL;
diff --git a/modules/field/tests/field.test b/modules/field/tests/field.test
index 8004178..e74df7d 100644
--- a/modules/field/tests/field.test
+++ b/modules/field/tests/field.test
@@ -85,12 +85,28 @@ class FieldAttachTestCase extends FieldTestCase {
     }
     parent::setUp($modules);
 
-    $this->field_name = drupal_strtolower($this->randomName() . '_field_name');
-    $this->field = array('field_name' => $this->field_name, 'type' => 'test_field', 'cardinality' => 4);
-    $this->field = field_create_field($this->field);
-    $this->field_id = $this->field['id'];
-    $this->instance = array(
-      'field_name' => $this->field_name,
+    $this->createFieldWithInstance();
+  }
+
+  /**
+   * Create a field and an instance of it.
+   *
+   * @param string $suffix
+   *   (optional) A string that should only contain characters that are valid in
+   *   PHP variable names as well.
+   */
+  function createFieldWithInstance($suffix = '') {
+    $field_name = 'field_name' . $suffix;
+    $field = 'field' . $suffix;
+    $field_id = 'field_id' . $suffix;
+    $instance = 'instance' . $suffix;
+
+    $this->$field_name = drupal_strtolower($this->randomName() . '_field_name' . $suffix);
+    $this->$field = array('field_name' => $this->$field_name, 'type' => 'test_field', 'cardinality' => 4);
+    $this->$field = field_create_field($this->$field);
+    $this->$field_id = $this->{$field}['id'];
+    $this->$instance = array(
+      'field_name' => $this->$field_name,
       'entity_type' => 'test_entity',
       'bundle' => 'test_bundle',
       'label' => $this->randomName() . '_label',
@@ -107,7 +123,7 @@ class FieldAttachTestCase extends FieldTestCase {
         )
       )
     );
-    field_create_instance($this->instance);
+    field_create_instance($this->$instance);
   }
 }
 
@@ -641,13 +657,18 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
    * Test field_attach_view() and field_attach_prepare_view().
    */
   function testFieldAttachView() {
+    $this->createFieldWithInstance('_2');
+
     $entity_type = 'test_entity';
     $entity_init = field_test_create_stub_entity();
     $langcode = LANGUAGE_NONE;
+    $options = array('field_name' => $this->field_name_2);
 
     // Populate values to be displayed.
     $values = $this->_generateTestFieldValues($this->field['cardinality']);
     $entity_init->{$this->field_name}[$langcode] = $values;
+    $values_2 = $this->_generateTestFieldValues($this->field_2['cardinality']);
+    $entity_init->{$this->field_name_2}[$langcode] = $values_2;
 
     // Simple formatter, label displayed.
     $entity = clone($entity_init);
@@ -662,15 +683,47 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
       ),
     );
     field_update_instance($this->instance);
+    $formatter_setting_2 = $this->randomName();
+    $this->instance_2['display'] = array(
+      'full' => array(
+        'label' => 'above',
+        'type' => 'field_test_default',
+        'settings' => array(
+          'test_formatter_setting' => $formatter_setting_2,
+        )
+      ),
+    );
+    field_update_instance($this->instance_2);
+    // View all fields.
     field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full');
     $entity->content = field_attach_view($entity_type, $entity, 'full');
     $output = drupal_render($entity->content);
     $this->content = $output;
-    $this->assertRaw($this->instance['label'], "Label is displayed.");
+    $this->assertRaw($this->instance['label'], "First field's label is displayed.");
     foreach ($values as $delta => $value) {
       $this->content = $output;
       $this->assertRaw("$formatter_setting|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
     }
+    $this->assertRaw($this->instance_2['label'], "Second field's label is displayed.");
+    foreach ($values_2 as $delta => $value) {
+      $this->content = $output;
+      $this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
+    }
+    // View single field (the second field).
+    field_attach_prepare_view($entity_type, array($entity->ftid => $entity), 'full', $langcode, $options);
+    $entity->content = field_attach_view($entity_type, $entity, 'full', $langcode, $options);
+    $output = drupal_render($entity->content);
+    $this->content = $output;
+    $this->assertNoRaw($this->instance['label'], "First field's label is not displayed.");
+    foreach ($values as $delta => $value) {
+      $this->content = $output;
+      $this->assertNoRaw("$formatter_setting|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
+    }
+    $this->assertRaw($this->instance_2['label'], "Second field's label is displayed.");
+    foreach ($values_2 as $delta => $value) {
+      $this->content = $output;
+      $this->assertRaw("$formatter_setting_2|{$value['value']}", "Value $delta is displayed, formatter settings are applied.");
+    }
 
     // Label hidden.
     $entity = clone($entity_init);
@@ -697,7 +750,7 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
     $this->content = $output;
     $this->assertNoRaw($this->instance['label'], "Hidden field: label is not displayed.");
     foreach ($values as $delta => $value) {
-      $this->assertNoRaw($value['value'], "Hidden field: value $delta is not displayed.");
+      $this->assertNoRaw("$formatter_setting|{$value['value']}", "Hidden field: value $delta is not displayed.");
     }
 
     // Multiple formatter.
@@ -907,11 +960,13 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
    * hook_field_validate.
    */
   function testFieldAttachValidate() {
+    $this->createFieldWithInstance('_2');
+
     $entity_type = 'test_entity';
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
     $langcode = LANGUAGE_NONE;
 
-    // Set up values to generate errors
+    // Set up all but one values of the first field to generate errors.
     $values = array();
     for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
       $values[$delta]['value'] = -1;
@@ -920,6 +975,14 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
     $values[1]['value'] = 1;
     $entity->{$this->field_name}[$langcode] = $values;
 
+    // Set up all values of the second field to generate errors.
+    $values_2 = array();
+    for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) {
+      $values_2[$delta]['value'] = -1;
+    }
+    $entity->{$this->field_name_2}[$langcode] = $values_2;
+
+    // Validate all fields.
     try {
       field_attach_validate($entity_type, $entity);
     }
@@ -929,26 +992,57 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
 
     foreach ($values as $delta => $value) {
       if ($value['value'] != 1) {
-        $this->assertIdentical($errors[$this->field_name][$langcode][$delta][0]['error'], 'field_test_invalid', "Error set on value $delta");
-        $this->assertEqual(count($errors[$this->field_name][$langcode][$delta]), 1, "Only one error set on value $delta");
+        $this->assertIdentical($errors[$this->field_name][$langcode][$delta][0]['error'], 'field_test_invalid', "Error set on first field's value $delta");
+        $this->assertEqual(count($errors[$this->field_name][$langcode][$delta]), 1, "Only one error set on first field's value $delta");
         unset($errors[$this->field_name][$langcode][$delta]);
       }
       else {
-        $this->assertFalse(isset($errors[$this->field_name][$langcode][$delta]), "No error set on value $delta");
+        $this->assertFalse(isset($errors[$this->field_name][$langcode][$delta]), "No error set on first field's value $delta");
       }
     }
-    $this->assertEqual(count($errors[$this->field_name][$langcode]), 0, 'No extraneous errors set');
+    foreach ($values_2 as $delta => $value) {
+      $this->assertIdentical($errors[$this->field_name_2][$langcode][$delta][0]['error'], 'field_test_invalid', "Error set on second field's value $delta");
+      $this->assertEqual(count($errors[$this->field_name_2][$langcode][$delta]), 1, "Only one error set on second field's value $delta");
+      unset($errors[$this->field_name_2][$langcode][$delta]);
+    }
+    $this->assertEqual(count($errors[$this->field_name][$langcode]), 0, 'No extraneous errors set for first field');
+    $this->assertEqual(count($errors[$this->field_name_2][$langcode]), 0, 'No extraneous errors set for second field');
+
+    // Validate a single field.
+    $options = array('field_name' => $this->field_name_2);
+    try {
+      field_attach_validate($entity_type, $entity, $options);
+    }
+    catch (FieldValidationException $e) {
+      $errors = $e->errors;
+    }
+
+    foreach ($values_2 as $delta => $value) {
+      $this->assertIdentical($errors[$this->field_name_2][$langcode][$delta][0]['error'], 'field_test_invalid', "Error set on second field's value $delta");
+      $this->assertEqual(count($errors[$this->field_name_2][$langcode][$delta]), 1, "Only one error set on second field's value $delta");
+      unset($errors[$this->field_name_2][$langcode][$delta]);
+    }
+    $this->assertFalse(isset($errors[$this->field_name]), 'No validation errors are set for the first field, despite it having errors');
+    $this->assertEqual(count($errors[$this->field_name_2][$langcode]), 0, 'No extraneous errors set for second field');
 
     // Check that cardinality is validated.
-    $entity->{$this->field_name}[$langcode] = $this->_generateTestFieldValues($this->field['cardinality'] + 1);
+    $entity->{$this->field_name_2}[$langcode] = $this->_generateTestFieldValues($this->field_2['cardinality'] + 1);
+    // When validating all fields.
     try {
       field_attach_validate($entity_type, $entity);
     }
     catch (FieldValidationException $e) {
       $errors = $e->errors;
     }
-    $this->assertEqual($errors[$this->field_name][$langcode][0][0]['error'], 'field_cardinality', t('Cardinality validation failed.'));
-
+    $this->assertEqual($errors[$this->field_name_2][$langcode][0][0]['error'], 'field_cardinality', 'Cardinality validation failed.');
+    // When validating a single field (the second field).
+    try {
+      field_attach_validate($entity_type, $entity, $options);
+    }
+    catch (FieldValidationException $e) {
+      $errors = $e->errors;
+    }
+    $this->assertEqual($errors[$this->field_name_2][$langcode][0][0]['error'], 'field_cardinality', 'Cardinality validation failed.');
   }
 
   /**
@@ -958,34 +1052,59 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
    * widgets show up.
    */
   function testFieldAttachForm() {
+    $this->createFieldWithInstance('_2');
+
     $entity_type = 'test_entity';
     $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+    $langcode = LANGUAGE_NONE;
 
+    // When generating form for all fields.
     $form = array();
     $form_state = form_state_defaults();
     field_attach_form($entity_type, $entity, $form, $form_state);
 
-    $langcode = LANGUAGE_NONE;
-    $this->assertEqual($form[$this->field_name][$langcode]['#title'], $this->instance['label'], "Form title is {$this->instance['label']}");
+    $this->assertEqual($form[$this->field_name][$langcode]['#title'], $this->instance['label'], "First field's form title is {$this->instance['label']}");
+    $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2['label'], "Second field's form title is {$this->instance_2['label']}");
     for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
       // field_test_widget uses 'textfield'
-      $this->assertEqual($form[$this->field_name][$langcode][$delta]['value']['#type'], 'textfield', "Form delta $delta widget is textfield");
-    }
+        $this->assertEqual($form[$this->field_name][$langcode][$delta]['value']['#type'], 'textfield', "First field's form delta $delta widget is textfield");
+      }
+      for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) {
+        // field_test_widget uses 'textfield'
+        $this->assertEqual($form[$this->field_name_2][$langcode][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield");
+      }
+
+      // When generating form for a single field (the second field).
+      $options = array('field_name' => $this->field_name_2);
+      $form = array();
+      $form_state = form_state_defaults();
+      field_attach_form($entity_type, $entity, $form, $form_state, NULL, $options);
+
+      $this->assertFalse(isset($form[$this->field_name]), 'The first field does not exist in the form');
+      $this->assertEqual($form[$this->field_name_2][$langcode]['#title'], $this->instance_2['label'], "Second field's form title is {$this->instance_2['label']}");
+      for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) {
+        // field_test_widget uses 'textfield'
+        $this->assertEqual($form[$this->field_name_2][$langcode][$delta]['value']['#type'], 'textfield', "Second field's form delta $delta widget is textfield");
+      }
   }
 
   /**
    * Test field_attach_submit().
    */
   function testFieldAttachSubmit() {
+    $this->createFieldWithInstance('_2');
+
     $entity_type = 'test_entity';
-    $entity = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+    $entity_init = field_test_create_stub_entity(0, 0, $this->instance['bundle']);
+    $langcode = LANGUAGE_NONE;
 
-    // Build the form.
+    // Build the form for all fields.
     $form = array();
     $form_state = form_state_defaults();
-    field_attach_form($entity_type, $entity, $form, $form_state);
+    field_attach_form($entity_type, $entity_init, $form, $form_state);
 
     // Simulate incoming values.
+    // First field.
     $values = array();
     $weights = array();
     for ($delta = 0; $delta < $this->field['cardinality']; $delta++) {
@@ -999,22 +1118,59 @@ class FieldAttachOtherTestCase extends FieldAttachTestCase {
     }
     // Leave an empty value. 'field_test' fields are empty if empty().
     $values[1]['value'] = 0;
-
-    $langcode = LANGUAGE_NONE;
+    // Second field.
+    $values_2 = array();
+    $weights_2 = array();
+    for ($delta = 0; $delta < $this->field_2['cardinality']; $delta++) {
+      $values_2[$delta]['value'] = mt_rand(1, 127);
+      // Assign random weight.
+      do {
+        $weight = mt_rand(0, $this->field_2['cardinality']);
+      } while (in_array($weight, $weights_2));
+      $weights_2[$delta] = $weight;
+      $values_2[$delta]['_weight'] = $weight;
+    }
+    // Leave an empty value. 'field_test' fields are empty if empty().
+    $values_2[1]['value'] = 0;
     // Pretend the form has been built.
     drupal_prepare_form('field_test_entity_form', $form, $form_state);
     drupal_process_form('field_test_entity_form', $form, $form_state);
     $form_state['values'][$this->field_name][$langcode] = $values;
+    $form_state['values'][$this->field_name_2][$langcode] = $values_2;
+
+    // Call field_attach_submit() for all fields.
+    $entity = clone($entity_init);
     field_attach_submit($entity_type, $entity, $form, $form_state);
 
     asort($weights);
+    asort($weights_2);
     $expected_values = array();
+    $expected_values_2 = array();
     foreach ($weights as $key => $value) {
       if ($key != 1) {
         $expected_values[] = array('value' => $values[$key]['value']);
       }
     }
     $this->assertIdentical($entity->{$this->field_name}[$langcode], $expected_values, 'Submit filters empty values');
+    foreach ($weights_2 as $key => $value) {
+      if ($key != 1) {
+        $expected_values_2[] = array('value' => $values_2[$key]['value']);
+      }
+    }
+    $this->assertIdentical($entity->{$this->field_name_2}[$langcode], $expected_values_2, 'Submit filters empty values');
+
+    // Call field_attach_submit() for a single field (the second field).
+    $options = array('field_name' => $this->field_name_2);
+    $entity = clone($entity_init);
+    field_attach_submit($entity_type, $entity, $form, $form_state, $options);
+    $expected_values_2 = array();
+    foreach ($weights_2 as $key => $value) {
+      if ($key != 1) {
+        $expected_values_2[] = array('value' => $values_2[$key]['value']);
+      }
+    }
+    $this->assertFalse(isset($entity->{$this->field_name}), 'The first field does not exist in the entity object');
+    $this->assertIdentical($entity->{$this->field_name_2}[$langcode], $expected_values_2, 'Submit filters empty values');
   }
 }
 
