diff --git a/feeds_ui/feeds_ui.admin.inc b/feeds_ui/feeds_ui.admin.inc
index f59a13c9d326cf8284bf215fa38521e5ee18fab5..3b36ed105b4545156da3c311d755e631e6033342 100644
--- a/feeds_ui/feeds_ui.admin.inc
+++ b/feeds_ui/feeds_ui.admin.inc
@@ -159,23 +159,26 @@ function feeds_ui_build_edit_form_submit($form, &$form_state) {
  */
 function feeds_ui_build_mapping_form(&$form_state, $feed) {
   $form = array();
+  $form['#feed'] = $feed;
 
   // Build a mapping form for each processor configured.
   $sources = $feed->parser->getMappingSources();
   foreach ($feed->processors as $class => $processor) {
+    // @todo: move actual form building into processors?
     $mappings = $processor->getMappings();
     $targets = $processor->getMappingTargets();
     $form['processors'][$class] = array(
       '#type' => 'fieldset',
       '#title' => $class, // @todo: human readable title.
+      '#tree' => TRUE,
     );
     $form['processors'][$class]['#mappings'] = $mappings;
     $form['processors'][$class]['#targets'] = $targets;
-    $form['processors'][$class]['sources'] = array(
+    $form['processors'][$class]['source'] = array(
       '#type' => 'select',
       '#options' => array('' => t('Select a source')) + drupal_map_assoc($sources),
     );
-    $form['processors'][$class]['targets'] = array(
+    $form['processors'][$class]['target'] = array(
       '#type' => 'select',
       '#options' => array('' => t('Select a target')) + drupal_map_assoc(array_keys($targets)),
     );
@@ -187,6 +190,15 @@ function feeds_ui_build_mapping_form(&$form_state, $feed) {
   return $form;
 }
 
+/**
+ * Submit handler for feeds_ui_build_mapping_form().
+ */
+function feeds_ui_build_mapping_form_submit($form, &$form_state) {
+  foreach ($form['#feed']->processors as $class => $processor) {
+    $processor->addMapping($form_state['values'][$class]['source'], $form_state['values'][$class]['target']);
+  }
+}
+
 /**
  * Edit plugin configuration.
  */
@@ -250,15 +262,18 @@ function theme_feeds_ui_build_mapping_form($form) {
     t('Source'),
     t('Target'),
     t('Unique'),
-    t('Remove'),
+    ' ',
   );
 
   foreach (element_children($form['processors']) as $processor) {
     $rows = array();
     if (is_array($form['processors'][$processor]['#mappings'])) {
-      foreach ($form['processors'][$processor]['#mappings'] as $mapping) {
+      foreach ($form['processors'][$processor]['#mappings'] as $source => $mapping) {
         $rows[] = array(
-          // @todo.
+          $source,
+          $mapping['target'],
+          $mapping['unique'] ? t('Yes') : t('No'),
+          t('Remove'),
         ); 
       }
     }
@@ -271,8 +286,8 @@ function theme_feeds_ui_build_mapping_form($form) {
       );
     }
     $rows[] = array(
-      drupal_render($form['processors'][$processor]['sources']),
-      drupal_render($form['processors'][$processor]['targets']),
+      drupal_render($form['processors'][$processor]['source']),
+      drupal_render($form['processors'][$processor]['target']),
       '',
       drupal_render($form['processors'][$processor]['add']),
     );
diff --git a/includes/feed.inc b/includes/feed.inc
index c7832886643e724a356e1aee5b4de3f48ee654ec..2fa712ca7269f736dbb3b0706e0c51e2205584cb 100644
--- a/includes/feed.inc
+++ b/includes/feed.inc
@@ -209,7 +209,7 @@ class FeedsConfigurable {
     $save->id = $this->id;
     $save->class = get_class($this);
     $save->config = $this->config;
-    db_query('DELETE FROM {feeds_configuration} WHERE id = "%s"', $save->id);
+    db_query('DELETE FROM {feeds_configuration} WHERE id = "%s" AND class = "%s"', $save->id, $save->class);
     drupal_write_record('feeds_configuration', $save);
   }
 
@@ -250,6 +250,8 @@ class FeedsConfigurable {
   /**
    * Get configuration.
    * 
+   * @todo: clean up fallback. Not clear when to use and when not to use getConfig().
+   * 
    * @param $fallback
    *   Set to false if method should NOT fall back to default configuration.
    */
@@ -262,6 +264,7 @@ class FeedsConfigurable {
 
   /**
    * Set configuration.
+   * @todo: save() automatically?
    * 
    * @param $config
    *   Array containing configuration information. Will be filtered by the keys returned by
@@ -393,6 +396,28 @@ class FeedsProcessor extends FeedsConfigurable {
   public function process($feed) {
   }
 
+  /**
+   * Declare default configuration.
+   */
+  public function getDefaultConfig() {
+    return array('mappings' => array());
+  }
+  
+  /**
+   * Add a mapping to existing mappings.
+   */
+  public function addMapping($source, $target, $unique = NULL) {
+    if (!empty($source) && !empty($target)) {
+      $config = $this->getConfig();
+      $config['mappings'][$source] = array(
+        'target' => $target,
+        'unique' => $unique,
+      );
+    }
+    $this->setConfig($config);
+    $this->save();
+  }
+
   /**
    * Declare possible mapping targets.
    *
@@ -410,7 +435,7 @@ class FeedsProcessor extends FeedsConfigurable {
    * Get mappings.
    */
   public function getMappings() {
-    return $this->config->mappings;
+    return $this->config['mappings'];
   }
 
   /**