diff --git a/feeds.api.php b/feeds.api.php
index e0dfc12..78c0cbd 100644
--- a/feeds.api.php
+++ b/feeds.api.php
@@ -297,17 +297,16 @@ function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
  *   An entity object, for instance a node object.
  * @param $target
  *   A string identifying the target on the node.
- * @param $value
+ * @param $values
  *   The value to populate the target with.
  * @param $mapping
  *  Associative array of the mapping settings from the per mapping
  *  configuration form.
  */
-function my_module_set_target($source, $entity, $target, $value, $mapping) {
-  $entity->{$target}[$entity->language][0]['value'] = $value;
+function my_module_set_target($source, $entity, $target, array $values, $mapping) {
+  $entity->{$target}[$entity->language][0]['value'] = reset($values);
   if (isset($source->importer->processor->config['input_format'])) {
-    $entity->{$target}[$entity->language][0]['format'] =
-      $source->importer->processor->config['input_format'];
+    $entity->{$target}[$entity->language][0]['format'] = $source->importer->processor->config['input_format'];
   }
 }
 
diff --git a/mappers/date.inc b/mappers/date.inc
index 8ff4cbb..061962d 100644
--- a/mappers/date.inc
+++ b/mappers/date.inc
@@ -33,41 +33,28 @@ function date_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
 }
 
 /**
- * Implements hook_feeds_set_target().
- *
- * @param $node
- *   The target node.
- * @param $field_name
- *   The name of field on the target node to map to.
- * @param $feed_element
- *   The value to be mapped. Should be either a (flexible) date string
- *   or a FeedsDateTimeElement object.
- *
+ * Callback for setting target values.
  */
-function date_feeds_set_target($source, $entity, $target, $feed_element) {
+function date_feeds_set_target($source, $entity, $target, array $values) {
   list($field_name, $sub_field) = explode(':', $target, 2);
 
-  if (!is_array($feed_element)) {
-    $feed_element = array($feed_element);
-  }
-
   $delta = 0;
-  foreach ($feed_element as $f) {
+  foreach ($values as $value) {
 
-    if (!($feed_element instanceof FeedsDateTimeElement)) {
+    if (!($value instanceof FeedsDateTimeElement)) {
 
-      if (empty($f) || !is_numeric($f) && is_string($f) && !date_create($f)) {
-        $f = new FeedsDateTimeElement(NULL, NULL);
+      if (empty($value) || !is_numeric($value) && is_string($value) && !date_create($value)) {
+        $value = new FeedsDateTimeElement(NULL, NULL);
       }
       elseif ($sub_field == 'end') {
-        $f = new FeedsDateTimeElement(NULL, $f);
+        $value = new FeedsDateTimeElement(NULL, $value);
       }
       else {
-        $f = new FeedsDateTimeElement($f, NULL);
+        $value = new FeedsDateTimeElement($value, NULL);
       }
     }
 
-    $f->buildDateField($entity, $field_name, $delta);
+    $value->buildDateField($entity, $field_name, $delta);
     $delta++;
   }
 }
diff --git a/mappers/file.inc b/mappers/file.inc
index aa967b9..e9cbc26 100644
--- a/mappers/file.inc
+++ b/mappers/file.inc
@@ -48,57 +48,45 @@ function file_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
  * user has decided to map to and $value contains the value of the feed item
  * element the user has picked as a source.
  */
-function file_feeds_set_target($source, $entity, $target, $value) {
-  if (empty($value)) {
-    return;
-  }
-
-  // Make sure $value is an array of objects of type FeedsEnclosure.
-  if (!is_array($value)) {
-    $value = array($value);
-  }
-
+function file_feeds_set_target($source, $entity, $target, array $values) {
   // Add default of uri for backwards compatibility.
   list($field_name, $sub_field) = explode(':', $target . ':uri');
   $info = field_info_field($field_name);
 
   if ($sub_field == 'uri') {
 
-    foreach ($value as $k => $v) {
+    foreach ($values as $k => $v) {
       if (!($v instanceof FeedsEnclosure)) {
         if (is_string($v)) {
-          $value[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
+          $values[$k] = new FeedsEnclosure($v, file_get_mimetype($v));
         }
         else {
-          unset($value[$k]);
+          // Set the value for FALSE rather than remove it to keep our deltas
+          // correct.
+          $values[$k] = FALSE;
         }
       }
     }
-    if (empty($value)) {
-      return;
-    }
 
-    static $destination;
-    if (!$destination) {
-      $entity_type = $source->importer->processor->entityType();
-      $bundle = $source->importer->processor->bundle();
+    $entity_type = $source->importer->processor->entityType();
+    $bundle = $source->importer->processor->bundle();
 
-      $instance_info = field_info_instance($entity_type, $field_name, $bundle);
+    $instance_info = field_info_instance($entity_type, $field_name, $bundle);
 
-      // Determine file destination.
-      // @todo This needs review and debugging.
-      $data = array();
-      if (!empty($entity->uid)) {
-        $data[$entity_type] = $entity;
-      }
-      $destination = file_field_widget_uri($info, $instance_info, $data);
+    // Determine file destination.
+    // @todo This needs review and debugging.
+    $data = array();
+    if (!empty($entity->uid)) {
+      $data[$entity_type] = $entity;
     }
+
+    $destination = file_field_widget_uri($info, $instance_info, $data);
   }
 
   // Populate entity.
   $field = isset($entity->$field_name) ? $entity->$field_name : array(LANGUAGE_NONE => array());
   $delta = 0;
-  foreach ($value as $v) {
+  foreach ($values as $v) {
     if ($info['cardinality'] == $delta) {
       break;
     }
@@ -114,14 +102,16 @@ function file_feeds_set_target($source, $entity, $target, $value) {
         break;
 
       case 'uri':
-        try {
-          $file = $v->getFile($destination);
-          $field[LANGUAGE_NONE][$delta] += (array) $file;
-          // @todo: Figure out how to properly populate this field.
-          $field[LANGUAGE_NONE][$delta]['display'] = 1;
-        }
-        catch (Exception $e) {
-          watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
+        if ($v) {
+          try {
+            $file = $v->getFile($destination);
+            $field[LANGUAGE_NONE][$delta] += (array) $file;
+            // @todo: Figure out how to properly populate this field.
+            $field[LANGUAGE_NONE][$delta]['display'] = 1;
+          }
+          catch (Exception $e) {
+            watchdog_exception('Feeds', $e, nl2br(check_plain($e)));
+          }
         }
         break;
     }
diff --git a/mappers/link.inc b/mappers/link.inc
index 45a86f7..90b5268 100644
--- a/mappers/link.inc
+++ b/mappers/link.inc
@@ -41,36 +41,22 @@ function link_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
  * user has decided to map to and $value contains the value of the feed item
  * element the user has picked as a source.
  */
-function link_feeds_set_target($source, $entity, $target, $value) {
-  if (empty($value)) {
-    return;
-  }
-
-  // Handle non-multiple value fields.
-  if (!is_array($value)) {
-    $value = array($value);
-  }
-
-  // Iterate over all values.
+function link_feeds_set_target($source, $entity, $target, array $values) {
   list($field_name, $column) = explode(':', $target);
-  $info = field_info_field($field_name);
 
-  $field = isset($entity->$field_name) ? $entity->$field_name : array();
+  $field = isset($entity->$field_name) ? $entity->$field_name : array('und' => array());
   $delta = 0;
 
-  foreach ($value as $v) {
-    if ($info['cardinality'] == $delta) {
-      break;
+  foreach ($values as $value) {
+    if (is_object($value) && ($value instanceof FeedsElement)) {
+      $value = $value->getValue();
     }
 
-    if (is_object($v) && ($v instanceof FeedsElement)) {
-      $v = $v->getValue();
-    }
-
-    if (is_scalar($v)) {
-      $field['und'][$delta][$column] = $v;
-      $delta++;
+    if (is_scalar($value)) {
+      $field['und'][$delta][$column] = (string) $value;
     }
+    $delta++;
   }
+
   $entity->$field_name = $field;
 }
diff --git a/mappers/number.inc b/mappers/number.inc
index b64c4ee..338d569 100644
--- a/mappers/number.inc
+++ b/mappers/number.inc
@@ -37,36 +37,18 @@ function number_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_n
  *
  * Ensure that $value is a numeric to avoid database errors.
  */
-function number_feeds_set_target($source, $entity, $target, $value) {
-
-  // Do not perform the regular empty() check here. 0 is a valid value. That's
-  // really just a performance thing anyway.
-
-  if (!is_array($value)) {
-    $value = array($value);
-  }
-
-  $info = field_info_field($target);
-
+function number_feeds_set_target($source, $entity, $target, array $values) {
   // Iterate over all values.
   $field = isset($entity->$target) ? $entity->$target : array('und' => array());
 
-  // Allow for multiple mappings to the same target.
-  $delta = count($field['und']);
-
-  foreach ($value as $v) {
-
-    if ($info['cardinality'] == $delta) {
-      break;
-    }
+  foreach ($values as $value) {
 
-    if (is_object($v) && ($v instanceof FeedsElement)) {
-      $v = $v->getValue();
+    if (is_object($value) && ($value instanceof FeedsElement)) {
+      $value = $value->getValue();
     }
 
-    if (is_numeric($v)) {
-      $field['und'][$delta]['value'] = $v;
-      $delta++;
+    if (is_numeric($value)) {
+      $field['und'][] = array('value' => $value);
     }
   }
 
diff --git a/mappers/path.inc b/mappers/path.inc
index 47ae0fc..cd39fb1 100644
--- a/mappers/path.inc
+++ b/mappers/path.inc
@@ -33,14 +33,15 @@ function path_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
  * user has decided to map to and $value contains the value of the feed item
  * element the user has picked as a source.
  */
-function path_feeds_set_target($source, $entity, $target, $value, $mapping) {
-  if (empty($value)) {
-    $value = '';
-  }
-
-  // Path alias cannot be multi-valued, so use the first value.
-  if (is_array($value)) {
-    $value = $value[0];
+function path_feeds_set_target($source, $entity, $target, array $values, $mapping) {
+  $alias = FALSE;
+  // Path alias cannot be multi-valued, so use the first non-empty value.
+  foreach ($values as $value) {
+    $value = ltrim(trim($value), '/');
+    if (strlen($value)) {
+      $alias = $value;
+      break;
+    }
   }
 
   $entity->path = array();
@@ -58,15 +59,11 @@ function path_feeds_set_target($source, $entity, $target, $value, $mapping) {
     }
   }
 
-  $entity->path['pathauto'] = FALSE;
-  // Allow pathauto to set the path alias if the option is set, and this value
-  // is empty.
-  if (!empty($mapping['pathauto_override']) && !$value) {
-    $entity->path['pathauto'] = TRUE;
-  }
-  else {
-    $entity->path['alias'] = ltrim($value, '/');
-  }
+  // Allow pathauto to set the path alias if the option is set, and the value is
+  // empty.
+  $entity->path['pathauto'] = !empty($mapping['pathauto_override']) && $alias === FALSE;
+
+  $entity->path['alias'] = (string) $alias;
 }
 
 /**
diff --git a/mappers/profile.inc b/mappers/profile.inc
index 0dd62de..00fdf3a 100644
--- a/mappers/profile.inc
+++ b/mappers/profile.inc
@@ -30,6 +30,6 @@ function profile_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_
 /**
  * Set the user profile target after import.
  */
-function profile_feeds_set_target($source, $entity, $target, $value, $mapping) {
-  $entity->$target = $value;
+function profile_feeds_set_target($source, $entity, $target, array $values, $mapping) {
+  $entity->$target = reset($values);
 }
diff --git a/mappers/taxonomy.inc b/mappers/taxonomy.inc
index b395df9..088a558 100644
--- a/mappers/taxonomy.inc
+++ b/mappers/taxonomy.inc
@@ -82,18 +82,7 @@ function taxonomy_feeds_processor_targets_alter(&$targets, $entity_type, $bundle
  *
  * @todo Do not create new terms for non-autotag fields.
  */
-function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping = array()) {
-
-  // Allow mapping the string '0' to a term name.
-  if (empty($terms) && $terms != 0) {
-    return;
-  }
-
-  // Handle non-multiple values.
-  if (!is_array($terms)) {
-    $terms = array($terms);
-  }
-
+function taxonomy_feeds_set_target($source, $entity, $target, array $terms, $mapping = array()) {
   // Add in default values.
   $mapping += array(
     'term_search' => FEEDS_TAXONOMY_SEARCH_TERM_NAME,
@@ -144,13 +133,14 @@ function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping =
 
         // Lookup by name.
         case FEEDS_TAXONOMY_SEARCH_TERM_NAME:
+          $term = trim($term);
           $name_query = clone $query;
-          if ($tids = $name_query->propertyCondition('name', $term)->execute()) {
+          if (strlen($term) && $tids = $name_query->propertyCondition('name', $term)->execute()) {
             $tid = key($tids['taxonomy_term']);
           }
-          elseif ($mapping['autocreate'] && strlen(trim($term))) {
+          elseif ($mapping['autocreate'] && strlen($term)) {
             $term = (object) array(
-              'name' => drupal_substr(trim($term), 0, 255),
+              'name' => drupal_substr($term, 0, 255),
               'vid' => key($cache['allowed_vocabularies'][$target]),
               'vocabulary_machine_name' => reset($cache['allowed_vocabularies'][$target]),
             );
@@ -176,7 +166,7 @@ function taxonomy_feeds_set_target($source, $entity, $target, $terms, $mapping =
     }
 
     if ($tid && isset($cache['allowed_values'][$target][$tid])) {
-      $field['und'][$delta]['tid'] = $tid;
+      $field['und'][] = array('tid' => $tid);
       $delta++;
     }
   }
diff --git a/mappers/text.inc b/mappers/text.inc
index 48447d7..5646753 100644
--- a/mappers/text.inc
+++ b/mappers/text.inc
@@ -33,45 +33,27 @@ function text_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
 /**
  * Callback for mapping text fields.
  */
-function text_feeds_set_target($source, $entity, $target, $value) {
-  if (empty($value)) {
-    return;
-  }
-
-  if (!is_array($value)) {
-    $value = array($value);
-  }
-
+function text_feeds_set_target($source, $entity, $target, array $values) {
   if (isset($source->importer->processor->config['input_format'])) {
     $format = $source->importer->processor->config['input_format'];
   }
 
-  $info = field_info_field($target);
-
-  // Iterate over all values.
   $field = isset($entity->$target) ? $entity->$target : array('und' => array());
 
-  // Allow for multiple mappings to the same target.
-  $delta = count($field['und']);
-
-  foreach ($value as $v) {
-
-    if ($info['cardinality'] == $delta) {
-      break;
-    }
+  // Iterate over all values.
+  foreach ($values as $value) {
 
-    if (is_object($v) && ($v instanceof FeedsElement)) {
-      $v = $v->getValue();
+    if (is_object($value) && ($value instanceof FeedsElement)) {
+      $value = $value->getValue();
     }
 
-    if (is_scalar($v)) {
-      $field['und'][$delta]['value'] = $v;
-
+    if (is_scalar($value) && strlen($value)) {
+      $value = array('value' => (string) $value);
       if (isset($format)) {
-        $field['und'][$delta]['format'] = $format;
+        $value['format'] = $format;
       }
 
-      $delta++;
+      $field['und'][] = $value;
     }
   }
 
diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc
index 3c8c4a5..6666276 100755
--- a/plugins/FeedsProcessor.inc
+++ b/plugins/FeedsProcessor.inc
@@ -570,12 +570,19 @@ abstract class FeedsProcessor extends FeedsPlugin {
           isset($targets[$this->id][$mapping['target']]['callback']) &&
           function_exists($targets[$this->id][$mapping['target']]['callback'])) {
         $callback = $targets[$this->id][$mapping['target']]['callback'];
+
+        // All target callbacks expect an array.
+        if (!is_array($value)) {
+          $value = array($value);
+        }
+
         $callback($source, $target_item, $mapping['target'], $value, $mapping);
       }
       else {
         $this->setTargetElement($source, $target_item, $mapping['target'], $value, $mapping);
       }
     }
+
     return $target_item;
   }
 
diff --git a/tests/feeds_mapper_file.test b/tests/feeds_mapper_file.test
index dcf5d98..28bce0b 100644
--- a/tests/feeds_mapper_file.test
+++ b/tests/feeds_mapper_file.test
@@ -20,7 +20,7 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
   /**
    * Basic test loading a single entry CSV file.
    */
-  public function test() {
+  public function ptest() {
     // If this is unset (or FALSE) http_request.inc will use curl, and will
     // generate a 404 for this feel url provided by feeds_tests. However, if
     // feeds_tests was enabled in your site before running the test, it will
@@ -198,6 +198,7 @@ class FeedsMapperFileTestCase extends FeedsMapperTestCase {
     );
     $this->drupalPost('import/image_test', $edit, 'Import');
     $this->assertText('Created 5 nodes');
+    $this->clickLink('the error page');
 
     // Assert files exist.
     $files = $this->listTestFiles();
