diff --git a/feeds.api.php b/feeds.api.php
index 389da82..3a3d754 100644
--- a/feeds.api.php
+++ b/feeds.api.php
@@ -205,6 +205,11 @@ function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
       'name' => t('My custom node field'),
       'description' => t('Description of what my custom node field does.'),
       'callback' => 'my_module_set_target',
+
+      // Specify both summary_callback and form_callback to add a per mapping
+      // configuration form.
+      'summary_callback' => 'my_module_summary_callback',
+      'form_callback' => 'my_module_form_callback',
     );
     $targets['my_node_field2'] = array(
       'name' => t('My Second custom node field'),
@@ -226,9 +231,12 @@ function hook_feeds_processor_targets_alter(&$targets, $entity_type, $bundle_nam
  *   A string identifying the target on the node.
  * @param $value
  *   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) {
+function my_module_set_target($source, $entity, $target, $value, $mapping) {
   $entity->{$target}[$entity->language][0]['value'] = $value;
   if (isset($source->importer->processor->config['input_format'])) {
     $entity->{$target}[$entity->language][0]['format'] = 
@@ -237,5 +245,56 @@ function my_module_set_target($source, $entity, $target, $value) {
 }
 
 /**
+ * Example of the summary_callback specified in
+ * hook_feeds_processor_targets_alter().
+ *
+ * @param $mapping
+ *   Associative array of the mapping settings.
+ * @param $target
+ *   Array of target settings, as defined by the processor or
+ *   hook_feeds_processor_targets_alter().
+ * @param $form
+ *   The whole mapping form.
+ * @param $form_state
+ *   The form state of the mapping form.
+ *
+ * @return
+ *   Returns, as a string that may contain HTML, the summary to display while
+ *   the full form isn't visible.
+ *   If the return value is empty, no summary and no option to view the form
+ *   will be displayed.
+ */
+function my_module_summary_callback($mapping, $target, $form, $form_state) {
+  if (empty($mapping['my_setting'])) {
+    return t('My setting <strong>not</strong> active');
+  }
+  else {
+    return t('My setting <strong>active</strong>');
+  }
+}
+
+/**
+ * Example of the form_callback specified in
+ * hook_feeds_processor_targets_alter().
+ *
+ * The arguments are the same that my_module_summary_callback() gets.
+ *
+ * @see my_module_summary_callback()
+ *
+ * @return
+ *   The per mapping configuration form. Once the form is saved, $mapping will
+ *   be populated with the form values.
+ */
+function my_module_form_callback($mapping, $target, $form, $form_state) {
+  return array(
+    'my_setting' => array(
+      '#type' => 'checkbox',
+      '#title' => t('My setting checkbox'),
+      '#default_value' => !empty($mapping['my_setting']),
+    ),
+  );
+}
+
+/**
  * @}
  */
diff --git a/feeds_ui/feeds_ui.admin.inc b/feeds_ui/feeds_ui.admin.inc
index b66f963..70f9ff3 100644
--- a/feeds_ui/feeds_ui.admin.inc
+++ b/feeds_ui/feeds_ui.admin.inc
@@ -500,6 +500,8 @@ function feeds_ui_mapping_form($form, &$form_state, $importer) {
   $form['#importer'] = $importer;
   $form['#mappings'] = $mappings = $importer->processor->getMappings();
   $form['help']['#markup'] = feeds_ui_mapping_help();
+  $form['#prefix'] = '<div id="feeds-ui-mapping-form-wrapper">';
+  $form['#suffix'] = '</div>';
 
   // Get mapping sources from parsers and targets from processor, format them
   // for output.
@@ -531,23 +533,16 @@ function feeds_ui_mapping_form($form, &$form_state, $importer) {
   );
   $form['legendset']['legend'] = $legend;
 
-  // Add unique and remove forms to mappings.
-  $form['unique_flags'] = $form['remove_flags'] = array(
+  // Add config forms and remove flags to mappings.
+  $form['config'] = $form['remove_flags'] = array(
     '#tree' => TRUE,
   );
   if (is_array($mappings)) {
     foreach ($mappings as $i => $mapping) {
-      $param = array(
-        'processor' => $importer->processor,
-        'mapping' => $mapping,
-      );
-      if (isset($targets[$mapping['target']]['optional_unique']) && $targets[$mapping['target']]['optional_unique'] === TRUE) {
-        $form['unique_flags'][$i] = array(
-          '#type' => 'checkbox',
-          '#default_value' => !empty($mapping['unique']),
-          '#attributes' => array('class' => array('feeds-ui-trigger-submit')),
-        );
+      if (isset($targets[$mapping['target']])) {
+        $form['config'][$i] = feeds_ui_mapping_settings_form($form, $form_state, $i, $mapping, $targets[$mapping['target']]);
       }
+
       $form['remove_flags'][$i] = array(
         '#type' => 'checkbox',
         '#title' => t('Remove'),
@@ -579,6 +574,7 @@ function feeds_ui_mapping_form($form, &$form_state, $importer) {
     '#type' => 'submit',
     '#value' => t('Add'),
     '#submit' => array('feeds_ui_mapping_form_add_submit'),
+    '#validate' => array('feeds_ui_mapping_form_add_validate'),
   );
   $form['save'] = array(
     '#type' => 'submit',
@@ -589,6 +585,138 @@ function feeds_ui_mapping_form($form, &$form_state, $importer) {
 }
 
 /**
+ * Per mapper configuration form that is a part of feeds_ui_mapping_form().
+ */
+function feeds_ui_mapping_settings_form($form, $form_state, $i, $mapping, $target) {
+  $form_state += array(
+    'mapping_settings_edit' => NULL,
+    'mapping_settings' => array(),
+  );
+
+  $base_button = array(
+    '#submit' => array('feeds_ui_mapping_form_multistep_submit'),
+    '#ajax' => array(
+      'callback' => 'feeds_ui_mapping_settings_form_callback',
+      'wrapper' => 'feeds-ui-mapping-form-wrapper',
+      'effect' => 'fade',
+      'progress' => 'none',
+    ),
+    '#i' => $i,
+  );
+
+
+  if (isset($form_state['mapping_settings'][$i])) {
+    $mapping = $form_state['mapping_settings'][$i] + $mapping;
+  }
+
+  if ($form_state['mapping_settings_edit'] === $i) {
+    // Build the form.
+    if (isset($target['form_callback'])) {
+      $settings_form = call_user_func($target['form_callback'], $mapping, $target, $form, $form_state);
+    }
+    else {
+      $settings_form = array();
+    }
+
+    // Merge in the optional unique form.
+    $settings_form += feeds_ui_mapping_settings_optional_unique_form($mapping, $target, $form, $form_state);
+
+    return array(
+      '#type' => 'container',
+      'settings' => $settings_form,
+      'save_settings' => $base_button + array(
+        '#type' => 'submit',
+        '#name' => 'mapping_settings_update_' . $i,
+        '#value' => t('Update'),
+        '#op' => 'update',
+      ),
+      'cancel_settings' => $base_button + array(
+        '#type' => 'submit',
+        '#name' => 'mapping_settings_cancel_' . $i,
+        '#value' => t('Cancel'),
+        '#op' => 'cancel',
+      ),
+    );
+  }
+  else {
+    // Build the summary.
+    if (isset($target['summary_callback'])) {
+      $summary = call_user_func($target['summary_callback'], $mapping, $target, $form, $form_state);
+    }
+    else {
+      $summary = '';
+    }
+
+    // Append the optional unique summary.
+    if ($optional_unique_summary = feeds_ui_mapping_settings_optional_unique_summary($mapping, $target, $form, $form_state)) {
+      $summary .= ' ' . $optional_unique_summary;
+    }
+
+    if ($summary) {
+      return array(
+        'summary' => array(
+          '#prefix' => '<div>',
+          '#markup' => $summary,
+          '#suffix' => '</div>',
+        ),
+       'edit_settings' => $base_button + array(
+          '#type' => 'image_button',
+          '#name' => 'mapping_settings_edit_' . $i,
+          '#src' => 'misc/configure.png',
+          '#attributes' => array('alt' => t('Edit')),
+          '#op' => 'edit',
+        ),
+      );
+    }
+  }
+}
+
+/**
+ * Submit callback for a per mapper configuration form. Switches between edit
+ * and summary mode.
+ */
+function feeds_ui_mapping_form_multistep_submit($form, &$form_state) {
+  $trigger = $form_state['triggering_element'];
+
+  switch ($trigger['#op']) {
+    case 'edit':
+      $form_state['mapping_settings_edit'] = $trigger['#i'];
+      break;
+
+    case 'update':
+      $values = $form_state['values']['config'][$trigger['#i']]['settings'];
+      $form_state['mapping_settings'][$trigger['#i']] = $values;
+      unset($form_state['mapping_settings_edit']);
+      break;
+
+    case 'cancel':
+      unset($form_state['mapping_settings_edit']);
+      break;
+  }
+
+  $form_state['rebuild'] = TRUE;
+}
+
+/**
+ * AJAX callback that returns the whole feeds_ui_mapping_form().
+ */
+function feeds_ui_mapping_settings_form_callback($form, $form_state) {
+  return $form;
+}
+
+/**
+ * Validation for source and target selection.
+ */
+function feeds_ui_mapping_form_add_validate($form, &$form_state) {
+  if ($form_state['values']['source'] == '') {
+    form_set_error('source', t('You must select a mapping source.'));
+  }
+  if ($form_state['values']['target'] == '') {
+    form_set_error('target', t('You must select a mapping target.'));
+  }
+}
+
+/**
  * Submit handler for add button on feeds_ui_mapping_form().
  */
 function feeds_ui_mapping_form_add_submit($form, &$form_state) {
@@ -601,7 +729,7 @@ function feeds_ui_mapping_form_add_submit($form, &$form_state) {
       'unique' => FALSE,
     );
     $importer->processor->addConfig(array('mappings' => $mappings));
-    $importer->processor->save();
+    $importer->save();
     drupal_set_message(t('Mapping has been added.'));
   }
   catch (Exception $e) {
@@ -614,13 +742,26 @@ function feeds_ui_mapping_form_add_submit($form, &$form_state) {
  */
 function feeds_ui_mapping_form_submit($form, &$form_state) {
   $processor = $form['#importer']->processor;
-  // We may set some unique flags to mappings that we remove in the subsequent
+
+  $form_state += array(
+    'mapping_settings' => array(),
+    'mapping_settings_edit' => NULL,
+  );
+
+  // If an item is in edit mode, prepare it for saving.
+  if ($form_state['mapping_settings_edit'] !== NULL) {
+    $values = $form_state['values']['config'][$form_state['mapping_settings_edit']]['settings'];
+    $form_state['mapping_settings'][$form_state['mapping_settings_edit']] = $values;
+  }
+
+  // We may set some settings to mappings that we remove in the subsequent
   // step, that's fine.
   $mappings = $form['#mappings'];
-  if (isset($form_state['values']['unique_flags'])) {
-    foreach ($form_state['values']['unique_flags'] as $k => $v) {
-      $mappings[$k]['unique'] = $v;
-    }
+  foreach ($form_state['mapping_settings'] as $k => $v) {
+    $mappings[$k] = array(
+      'source' => $mappings[$k]['source'],
+      'target' => $mappings[$k]['target'],
+    ) + $v;
   }
 
   if (!empty($form_state['values']['remove_flags'])) {
@@ -633,7 +774,7 @@ function feeds_ui_mapping_form_submit($form, &$form_state) {
     $mappings = array_values($mappings);
   }
   $processor->addConfig(array('mappings' => $mappings));
-  $processor->save();
+  $form['#importer']->save();
   drupal_set_message(t('Your changes have been saved.'));
 }
 
@@ -660,6 +801,38 @@ function _feeds_ui_format_options($options) {
 }
 
 /**
+ * Per mapping settings summary callback. Shows whether a mapping is used as
+ * unique or not.
+ */
+function feeds_ui_mapping_settings_optional_unique_summary($mapping, $target, $form, $form_state) {
+  if (!empty($target['optional_unique'])) {
+    if ($mapping['unique']) {
+      return t('Used as <strong>unique</strong>.');
+    } else {
+      return t('Not used as unique.');
+    }
+  }
+}
+
+/**
+ * Per mapping settings form callback. Lets the user choose if a target is as
+ * unique or not.
+ */
+function feeds_ui_mapping_settings_optional_unique_form($mapping, $target, $form, $form_state) {
+  $settings_form = array();
+
+  if (!empty($target['optional_unique'])) {
+    $settings_form['unique'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Unique'),
+      '#default_value' => !empty($mapping['unique']),
+    );
+  }
+
+  return $settings_form;
+}
+
+/**
  * Theme feeds_ui_overview_form().
  */
 function theme_feeds_ui_overview_form($variables) {
@@ -801,7 +974,7 @@ function theme_feeds_ui_mapping_form($variables) {
   $header = array(
     t('Source'),
     t('Target'),
-    t('Unique target'),
+    t('Target configuration'),
     '&nbsp;',
   );
   $rows = array();
@@ -813,7 +986,7 @@ function theme_feeds_ui_mapping_form($variables) {
       $rows[] = array(
         check_plain($source),
         $target,
-        drupal_render($form['unique_flags'][$i]),
+        drupal_render($form['config'][$i]),
         drupal_render($form['remove_flags'][$i]),
       );
     }
@@ -832,7 +1005,7 @@ function theme_feeds_ui_mapping_form($variables) {
     '',
     drupal_render($form['add']),
   );
-  $output = '<div class="help feeds-admin-ui""' . drupal_render($form['help']) . '</div>';
+  $output = '<div class="help feeds-admin-ui">' . drupal_render($form['help']) . '</div>';
   $output .= theme('table', array('header' => $header, 'rows' => $rows));
 
   // Build the help table that explains available sources.
diff --git a/plugins/FeedsProcessor.inc b/plugins/FeedsProcessor.inc
index 029f9f4..9c6221f 100644
--- a/plugins/FeedsProcessor.inc
+++ b/plugins/FeedsProcessor.inc
@@ -404,10 +404,10 @@ 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'];
-        $callback($source, $target_item, $mapping['target'], $value);
+        $callback($source, $target_item, $mapping['target'], $value, $mapping);
       }
       else {
-        $this->setTargetElement($source, $target_item, $mapping['target'], $value);
+        $this->setTargetElement($source, $target_item, $mapping['target'], $value, $mapping);
       }
     }
     return $target_item;
