diff --git a/feeds.module b/feeds.module
index f0dd48c..a295b28 100644
--- a/feeds.module
+++ b/feeds.module
@@ -427,26 +427,34 @@ function feeds_theme() {
  *   Node object or FeedsImporter id.
  */
 function feeds_access($action, $param) {
+  $importer_ids = array();
   if (!in_array($action, array('import', 'clear', 'unlock'))) {
     // If $action is not one of the supported actions, we return access denied.
     return FALSE;
   }
 
-  $importer_id = FALSE;
   if (is_string($param)) {
-    $importer_id = $param;
+    // If checking the access of a single importer build the array manually.
+    $importer_ids[$param] = $param;
   }
   elseif ($param instanceof FeedsImporter) {
-    $importer_id = $param->id;
+    $importer_ids[$param->id] = $param->id;
   }
   elseif ($param->type) {
-    $importer_id = feeds_get_importer_id($param->type);
-  }
-
-  // Check for permissions if feed id is present, otherwise return FALSE.
-  if ($importer_id) {
-    if (user_access('administer feeds') || user_access("{$action} {$importer_id} feeds")) {
-      return TRUE;
+    // If checking the access for a content type,
+    // check all importers available for it.
+    $importer_ids = feeds_get_importer_ids($param->type);
+  }
+
+  // Loop through all importers. if the user has access to one,
+  // they have access to the item.
+  $administer_feeds = user_access('administer feeds');
+  foreach ($importer_ids as $importer_id) {
+    // Check for permissions if feed id is present, otherwise return FALSE.
+    if ($importer_id) {
+      if ($administer_feeds || user_access($action . ' ' . $importer_id . ' feeds')) {
+        return TRUE;
+      }
     }
   }
   return FALSE;
@@ -486,7 +494,7 @@ function feeds_exit() {
   foreach ($jobs as $job) {
     if (!isset($job['fetcher']) || !isset($job['source'])) {
       continue;
-     }
+    }
     $job['fetcher']->subscribe($job['source']);
   }
 
@@ -581,10 +589,24 @@ function feeds_entity_delete($entity, $type) {
 }
 
 /**
+ * Implements hook_node_prepare().
+ */
+function feeds_node_prepare($node) {
+  if ($importer_ids = feeds_get_importer_ids($node->type)) {
+    $node->feeds = array();
+    foreach ($importer_ids as $importer_id) {
+      $source = feeds_source($importer_id, empty($node->nid) ? 0 : $node->nid);
+      $node->feeds[$importer_id] = array();
+      $node->feeds[$importer_id] += $source->configDefaults();
+    }
+  }
+}
+
+/**
  * Implements hook_node_validate().
  */
 function feeds_node_validate($node, $form, &$form_state) {
-  if (!$importer_id = feeds_get_importer_id($node->type)) {
+  if (!$importer_ids = feeds_get_importer_ids($node->type)) {
     return;
   }
   // Keep a copy of the title for subsequent node creation stages.
@@ -593,28 +615,31 @@ function feeds_node_validate($node, $form, &$form_state) {
   $last_title = &drupal_static('feeds_node_last_title');
   $last_feeds = &drupal_static('feeds_node_last_feeds');
 
-  // On validation stage we are working with a FeedsSource object that is
-  // not tied to a nid - when creating a new node there is no
-  // $node->nid at this stage.
-  $source = feeds_source($importer_id);
-
   // Node module magically moved $form['feeds'] to $node->feeds :P.
   // configFormValidate may modify $last_feed, smuggle it to update/insert stage
   // through a static variable.
-  $last_feeds = $node->feeds;
-  $source->configFormValidate($last_feeds);
-
-  // If node title is empty, try to retrieve title from feed.
-  if (trim($node->title) == '') {
-    try {
-      $source->addConfig($last_feeds);
-      if (!$last_title = $source->preview()->title) {
-        throw new Exception();
+  $last_feeds = isset($node->feeds) ? $node->feeds : array();
+
+  $trimmed_node_title = trim($node->title);
+  // On validation stage we are working with a FeedsSource object that is
+  // not tied to a nid - when creating a new node there is no
+  // $node->nid at this stage.
+  foreach ($importer_ids as $importer_id) {
+    $source = feeds_source($importer_id);
+    $source->configFormValidate($last_feeds[$importer_id]);
+
+    // If node title is empty, try to retrieve title from feed.
+    if ($trimmed_node_title == '') {
+      try {
+        $source->addConfig($last_feeds[$importer_id]);
+        if (!$last_title = $source->preview()->title) {
+          throw new Exception(t('Could not retrieve title from feed'));
+        }
+      }
+      catch (Exception $e) {
+        drupal_set_message($e->getMessage(), 'error');
+        form_set_error('title', t('Could not retrieve title from feed.'), array('error' => array('title')));
       }
-    }
-    catch (Exception $e) {
-      drupal_set_message($e->getMessage(), 'error');
-      form_set_error('title', t('Could not retrieve title from feed.'));
     }
   }
 }
@@ -642,14 +667,16 @@ function feeds_node_presave($node) {
 function feeds_node_insert($node) {
   // Source attached to node.
   feeds_node_update($node);
-  if (isset($node->feeds) && $importer_id = feeds_get_importer_id($node->type)) {
-    $source = feeds_source($importer_id, $node->nid);
-    // Start import if requested.
-    if (feeds_importer($importer_id)->config['import_on_create'] && !isset($node->feeds['suppress_import'])) {
-      $source->startImport();
+  if (isset($node->feeds) && ($importer_ids = feeds_get_importer_ids($node->type, $node->nid))) {
+    foreach ($importer_ids as $importer_id) {
+      $source = feeds_source($importer_id, $node->nid);
+      // Start import if requested.
+      if (feeds_importer($importer_id)->config['import_on_create'] && !isset($node->feeds['suppress_import'])) {
+        $source->startImport();
+      }
+      // Schedule the source.
+      $source->schedule();
     }
-    // Schedule the source.
-    $source->schedule();
   }
 }
 
@@ -658,10 +685,15 @@ function feeds_node_insert($node) {
  */
 function feeds_node_update($node) {
   // Source attached to node.
-  if (isset($node->feeds) && $importer_id = feeds_get_importer_id($node->type)) {
-    $source = feeds_source($importer_id, $node->nid);
-    $source->addConfig($node->feeds);
-    $source->save();
+  if (isset($node->feeds) && ($importer_ids = feeds_get_importer_ids($node->type))) {
+    foreach ($importer_ids as $importer_id) {
+      $source = feeds_source($importer_id, $node->nid);
+      // Config may be empty if defined so by importer.
+      if ($node->feeds[$importer_id]) {
+        $source->addConfig($node->feeds[$importer_id]);
+      }
+      $source->save();
+    }
   }
 }
 
@@ -673,8 +705,10 @@ function feeds_node_delete($node) {
   // Make sure we don't leave any orphans behind: Do not use
   // feeds_get_importer_id() to determine importer id as the importer may have
   // been deleted.
-  if ($importer_id = db_query("SELECT id FROM {feeds_source} WHERE feed_nid = :nid", array(':nid' => $node->nid))->fetchField()) {
-    feeds_source($importer_id, $node->nid)->delete();
+  if ($importer_ids = db_query("SELECT id FROM {feeds_source} WHERE feed_nid = :nid", array(':nid' => $node->nid))) {
+    foreach ($importer_ids as $row) {
+      feeds_source($row->id, $node->nid)->delete();
+    }
   }
 }
 
@@ -682,25 +716,34 @@ function feeds_node_delete($node) {
  * Implements hook_form_BASE_FORM_ID_alter().
  */
 function feeds_form_node_form_alter(&$form, $form_state) {
-  if ($importer_id = feeds_get_importer_id($form['#node']->type)) {
-    // Set title to not required, try to retrieve it from feed.
-    if (isset($form['title'])) {
-      $form['title']['#required'] = FALSE;
-    }
-
-    // Enable uploads.
-    $form['#attributes']['enctype'] = 'multipart/form-data';
-
-    // Build form.
-    $source = feeds_source($importer_id, empty($form['#node']->nid) ? 0 : $form['#node']->nid);
+  if ($importer_ids = feeds_get_importer_ids($form['#node']->type)) {
     $form['feeds'] = array(
       '#type' => 'fieldset',
       '#title' => t('Feed'),
       '#tree' => TRUE,
       '#weight' => 0,
     );
-    $form['feeds'] += $source->configForm($form_state);
-    $form['#feed_id'] = $importer_id;
+
+    // Enable uploads.
+    if (count($importer_ids)) {
+      $form['#attributes']['enctype'] = 'multipart/form-data';
+    }
+
+    foreach ($importer_ids as $importer_id) {
+      // Set title to not required, try to retrieve it from feed.
+      if (isset($form['title'])) {
+        $form['title']['#required'] = FALSE;
+      }
+
+      // Build form.
+      $source = feeds_source($importer_id, empty($form['#node']->nid) ? 0 : $form['#node']->nid);
+      $form['feeds'][$importer_id] = $source->configForm($form_state);
+      $class = get_class(feeds_importer($importer_id)->fetcher);
+      $form['feeds'][$importer_id][$class]['source']['#title'] = $form['feeds'][$importer_id][$class]['source']['#title']
+        . ' - '
+        . $source->importer->config['name'];
+      $form['#feed_id'] = $importer_id;
+    }
   }
 }
 
@@ -845,11 +888,11 @@ function feeds_flush_caches() {
 /**
  * Loads all importers.
  *
- * @param $load_disabled
+ * @param bool $load_disabled
  *   Pass TRUE to load all importers, enabled or disabled, pass FALSE to only
  *   retrieve enabled importers.
  *
- * @return
+ * @return array
  *   An array of all feed configurations available.
  */
 function feeds_importer_load_all($load_disabled = FALSE) {
@@ -871,7 +914,7 @@ function feeds_importer_load_all($load_disabled = FALSE) {
 /**
  * Gets an array of enabled importer ids.
  *
- * @return
+ * @return array
  *   An array where the values contain ids of enabled importers.
  */
 function feeds_enabled_importers() {
@@ -881,10 +924,10 @@ function feeds_enabled_importers() {
 /**
  * Gets an enabled importer configuration by content type.
  *
- * @param $content_type
+ * @param string $content_type
  *   A node type string.
  *
- * @return
+ * @return array
  *   A FeedsImporter id if there is an importer for the given content type,
  *   FALSE otherwise.
  */
@@ -894,6 +937,57 @@ function feeds_get_importer_id($content_type) {
 }
 
 /**
+ * Gets an enabled importer configuration by content type.
+ *
+ * @param string $content_type
+ *   A node type string.
+ * @param int $feed_nid
+ *   Nid for feed.
+ *
+ * @return array
+ *   A list of FeedsImporters attached to the given content type.
+ */
+function feeds_get_importer_ids($content_type, $feed_nid = NULL) {
+  $all_importers = _feeds_importer_digest();
+  $importers = array();
+  foreach ($all_importers as $importer => $type) {
+    if ($type == $content_type) {
+      $importers[$importer] = $importer;
+    }
+  }
+  // Sort those importers by weight.
+  if (!empty($importers)) {
+    $weights = _feeds_get_importer_weights($importers);
+    // Sort these arrays by key, then sort together.
+    ksort($weights);
+    ksort($importers);
+    array_multisort($weights, $importers);
+  }
+  return $importers;
+}
+
+/**
+ * Get importer.
+ *
+ * @param array $importers
+ * @param bool|TRUE $sorted
+ *
+ * @return mixed
+ */
+function _feeds_get_importer_weights($importers, $sorted = TRUE) {
+  foreach (feeds_importer_load_all() as $importer) {
+    if (isset($importers[$importer->id])) {
+      $importer_weights[$importer->id] = isset($importer->config['weight']) ?
+        $importer->config['weight'] : '0';
+    }
+  }
+  if ($sorted) {
+    asort($importer_weights);
+  }
+  return $importer_weights;
+}
+
+/**
  * Helper function for feeds_get_importer_id() and feeds_enabled_importers().
  */
 function _feeds_importer_digest() {
@@ -905,7 +999,8 @@ function _feeds_importer_digest() {
     else {
       $importers = array();
       foreach (feeds_importer_load_all() as $importer) {
-        $importers[$importer->id] = isset($importer->config['content_type']) ? $importer->config['content_type'] : '';
+        $importers[$importer->id] = isset($importer->config['content_type']) ?
+          $importer->config['content_type'] : '';
       }
       cache_set(__FUNCTION__, $importers);
     }
@@ -1154,6 +1249,9 @@ function feeds_include_library($file, $library) {
  *   The name of the library. If libraries module is installed,
  *   feeds_library_exists() will look for libraries with this name managed by
  *   libraries module.
+ *
+ * @return bool
+ *   If library exists or not.
  */
 function feeds_library_exists($file, $library) {
   $path = module_exists('libraries') ? libraries_get_path($library) : FALSE;
@@ -1175,7 +1273,7 @@ function feeds_library_exists($file, $library) {
   return FALSE;
 }
 
- /**
+/**
  * Checks whether simplepie exists.
  */
 function feeds_simplepie_exists() {
@@ -1240,7 +1338,7 @@ function feeds_alter($type, &$data) {
 /**
  * Copy of valid_url() that supports the webcal scheme.
  *
- * @see valid_url().
+ * @see valid_url()
  *
  * @todo Replace with valid_url() when http://drupal.org/node/295021 is fixed.
  */
@@ -1275,7 +1373,7 @@ function feeds_valid_url($url, $absolute = FALSE) {
  *   Information about a new job to queue; or if set to NULL (default), leaves
  *   the current queued jobs unchanged.
  *
- * @return
+ * @return array
  *   An array of subscribe jobs to process.
  *
  * @see feeds_exit()
@@ -1292,7 +1390,7 @@ function feeds_set_subscription_job(array $job = NULL) {
 /**
  * Returns the list of queued jobs to be run.
  *
- * @return
+ * @return array
  *   An array of subscribe jobs to process.
  *
  * @see feeds_set_subscription_job()
@@ -1326,7 +1424,7 @@ function feeds_entity_property_info_alter(&$info) {
  * Gets the feed_nid for an entity for use in entity metadata.
  */
 function feeds_get_feed_nid_entity_callback($entity, array $options, $name, $entity_type) {
-  list($entity_id, , ) = entity_extract_ids($entity_type, $entity);
+  list($entity_id, ,) = entity_extract_ids($entity_type, $entity);
 
   $feed_nid = NULL;
   if ($entity_id) {
@@ -1354,7 +1452,7 @@ function feeds_file_download($uri) {
     return;
   }
 
-   // Get the file record based on the URI. If not in the database just return.
+  // Get the file record based on the URI. If not in the database just return.
   $files = file_load_multiple(array(), array('uri' => $uri));
   foreach ($files as $item) {
     // Since some database servers sometimes use a case-insensitive comparison
diff --git a/feeds.pages.inc b/feeds.pages.inc
index eeeab90..2317847 100644
--- a/feeds.pages.inc
+++ b/feeds.pages.inc
@@ -92,8 +92,9 @@ function feeds_import_form(array $form, array &$form_state, FeedsImporter $impor
   $progress = $source->progressImporting();
   if ($progress !== FEEDS_BATCH_COMPLETE) {
     $form['submit']['#disabled'] = TRUE;
-    $form['submit']['#value'] =
-      t('Importing (@progress %)', array('@progress' => number_format(100 * $progress, 0)));
+    $form['submit']['#value'] = t('Importing (@progress %)', array(
+      '@progress' => number_format(100 * $progress, 0),
+    ));
   }
   return $form;
 }
@@ -131,25 +132,64 @@ function feeds_import_form_submit($form, &$form_state) {
  * Render a feeds import form on node/id/import pages.
  */
 function feeds_import_tab_form($form, &$form_state, $node) {
-  $importer_id = feeds_get_importer_id($node->type);
-  $source = feeds_source($importer_id, $node->nid);
+  $total_progress = 0;
+
+  $importer_ids = feeds_get_importer_ids($node->type, $node->nid);
 
   $form = array();
-  $form['#feed_nid'] = $node->nid;
-  $form['#importer_id'] = $importer_id;
-  $form['#redirect'] = 'node/' . $node->nid;
-  $form['source_status'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Status'),
-    '#tree' => TRUE,
-    '#value' => feeds_source_status($source),
-  );
-  $form = confirm_form($form, t('Import all content from source?'), 'node/' . $node->nid, '', t('Import'), t('Cancel'), 'confirm feeds update');
-  $progress = $source->progressImporting();
-  if ($progress !== FEEDS_BATCH_COMPLETE) {
-    $form['actions']['submit']['#disabled'] = TRUE;
-    $form['actions']['submit']['#value'] =
-      t('Importing (@progress %)', array('@progress' => number_format(100 * $progress, 0)));
+  if ($importer_ids) {
+    $form['#feed_nid'] = $node->nid;
+    $form['#redirect'] = 'node/' . $node->nid;
+    $form = confirm_form($form, t('Import all content from source?'),
+      'node/' . $node->nid, '', t('Import'), t('Cancel'),
+      'confirm feeds update');
+    foreach ($importer_ids as $importer_id => $weight) {
+      $source = feeds_source($importer_id, $node->nid);
+      $form[$importer_id]['source_status'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('@source_name: Status', array(
+          '@source_name' => $source->importer->config['name'],
+        )),
+        '#tree' => TRUE,
+        '#value' => feeds_source_status($source),
+      );
+      $progress = $source->progressImporting();
+      $total_progress += $progress;
+    }
+    if (count($importer_ids) == 1) {
+      $form['importer_ids'] = array(
+        '#type' => 'value',
+        '#value' => array($importer_id),
+      );
+    }
+    else {
+      $options = array();
+      foreach ($importer_ids as $importer_id => $weight) {
+        $source = feeds_source($importer_id, $node->nid);
+        $options[$importer_id] = $source->importer->config['name'];
+      }
+      $form['importer_ids'] = array(
+        '#type' => 'checkboxes',
+        '#options' => $options,
+        '#default_value' => array_keys($options),
+        '#title' => t('Sources'),
+        '#description' => t('Select the sources to import.'),
+      );
+    }
+
+    if (count($importer_ids)) {
+      $progress = $total_progress / count($importer_ids);
+      if ($progress !== FEEDS_BATCH_COMPLETE) {
+        $form['actions']['submit']['#disabled'] = TRUE;
+        $form['actions']['submit']['#value'] = t('Importing (@progress %)',
+          array('@progress' => number_format(100 * $progress, 0)));
+      }
+    }
+  }
+  else {
+    $form['no_source'] = array(
+      '#markup' => t('No feeds sources added to node.'),
+    );
   }
   return $form;
 }
@@ -159,7 +199,9 @@ function feeds_import_tab_form($form, &$form_state, $node) {
  */
 function feeds_import_tab_form_submit($form, &$form_state) {
   $form_state['redirect'] = $form['#redirect'];
-  feeds_source($form['#importer_id'], $form['#feed_nid'])->startImport();
+  foreach (array_filter($form_state['values']['importer_ids']) as $importer_id) {
+    feeds_source($importer_id, $form['#feed_nid'])->startImport();
+  }
 }
 
 /**
@@ -169,30 +211,87 @@ function feeds_import_tab_form_submit($form, &$form_state) {
  * Therefore $node may be missing.
  */
 function feeds_delete_tab_form(array $form, array &$form_state, FeedsImporter $importer = NULL, $node = NULL) {
+  $total_progress = 0;
   if (empty($node)) {
     $source = feeds_source($importer->id);
     $form['#redirect'] = 'import/' . $source->id;
+    $importer_ids = array($importer->id);
   }
   else {
-    $importer_id = feeds_get_importer_id($node->type);
-    $source = feeds_source($importer_id, $node->nid);
-    $form['#redirect'] = 'node/' . $source->feed_nid;
+    $importer_ids = feeds_get_importer_ids($node->type, $node->nid);
+    $form['#redirect'] = 'node/' . $node->nid;
   }
-  // Form cannot pass on source object.
-  $form['#importer_id'] = $source->id;
-  $form['#feed_nid'] = $source->feed_nid;
-  $form['source_status'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Status'),
-    '#tree' => TRUE,
-    '#value' => feeds_source_status($source),
-  );
-  $form = confirm_form($form, t('Delete all items from source?'), $form['#redirect'], '', t('Delete'), t('Cancel'), 'confirm feeds update');
-  $progress = $source->progressClearing();
-  if ($progress !== FEEDS_BATCH_COMPLETE) {
-    $form['actions']['submit']['#disabled'] = TRUE;
-    $form['actions']['submit']['#value'] =
-      t('Deleting (@progress %)', array('@progress' => number_format(100 * $progress, 0)));
+
+  if ($importer_ids) {
+    // Form cannot pass on source object.
+    $form['#feed_nid'] = empty($node) ? '' : $node->nid;
+    foreach ($importer_ids as $import_id => $weight) {
+      $source = empty($node) ? $source : feeds_source($import_id, $node->nid);
+      if (!empty($node)) {
+        $form[$import_id]['source_status'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('@source_name: Status', array(
+            '@source_name' => $source->importer->config['name'],
+          )),
+          '#tree' => TRUE,
+          '#value' => feeds_source_status($source),
+        );
+      }
+      else {
+        $form['source_status'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('@source_name: Status', array(
+            '@source_name' => $source->importer->config['name'],
+          )),
+          '#tree' => TRUE,
+          '#value' => feeds_source_status($source),
+        );
+      }
+      $progress = $source->progressClearing();
+      $total_progress += $progress;
+    }
+
+    // Set importer ids.
+    // If this is a stand-alone form then importer will be passed.
+    if ($importer) {
+      $form['importer_ids'] = array(
+        '#type' => 'value',
+        '#value' => array($importer->id => $importer->id),
+      );
+    }
+    else {
+      $options = array();
+      foreach ($importer_ids as $importer_id => $weight) {
+        $source = feeds_source($importer_id, $node->nid);
+        $options[$importer_id] = $source->importer->config['name'];
+      }
+      $form['importer_ids'] = array(
+        '#type' => 'checkboxes',
+        '#options' => $options,
+        '#default_value' => array_keys($options),
+        '#title' => t('Sources'),
+        '#description' => t('Select the sources to delete items from.'),
+      );
+    }
+
+    $form = confirm_form($form, t('Delete all items from source?'),
+      $form['#redirect'], '', t('Delete'), t('Cancel'), 'confirm feeds update');
+
+    if (count($importer_ids)) {
+      $progress = $total_progress / count($importer_ids);
+      if ($progress !== FEEDS_BATCH_COMPLETE) {
+        $form['actions']['submit']['#disabled'] = TRUE;
+        $form['actions']['submit']['#value'] = t('Deleting (@progress %)',
+          array(
+            '@progress' => number_format(100 * $progress, 0),
+          ));
+      }
+    }
+  }
+  else {
+    $form['no_source'] = array(
+      '#markup' => t('No feeds sources added to node.'),
+    );
   }
   return $form;
 }
@@ -203,7 +302,9 @@ function feeds_delete_tab_form(array $form, array &$form_state, FeedsImporter $i
 function feeds_delete_tab_form_submit($form, &$form_state) {
   $form_state['redirect'] = $form['#redirect'];
   $feed_nid = empty($form['#feed_nid']) ? 0 : $form['#feed_nid'];
-  feeds_source($form['#importer_id'], $feed_nid)->startClear();
+  foreach (array_filter($form_state['values']['importer_ids']) as $importer_id) {
+    feeds_source($importer_id, $feed_nid)->startClear();
+  }
 }
 
 /**
@@ -231,7 +332,8 @@ function feeds_unlock_tab_form($form, &$form_state, FeedsImporter $importer = NU
     '#tree' => TRUE,
     '#value' => feeds_source_status($source),
   );
-  $form = confirm_form($form, t('Unlock this importer?'), $form['#redirect'], '', t('Delete'), t('Cancel'), 'confirm feeds update');
+  $form = confirm_form($form, t('Unlock this importer?'),
+    $form['#redirect'], '', t('Delete'), t('Cancel'), 'confirm feeds update');
   if ($source->progressImporting() == FEEDS_BATCH_COMPLETE && $source->progressClearing() == FEEDS_BATCH_COMPLETE) {
     $form['source_locked'] = array(
       '#type' => 'markup',
@@ -257,7 +359,7 @@ function feeds_unlock_tab_form_submit($form, &$form_state) {
   $feed_nid = empty($form['#feed_nid']) ? 0 : $form['#feed_nid'];
   $importer_id = $form['#importer_id'];
 
-  //Is there a more API-friendly way to set the state?
+  // Is there a more API-friendly way to set the state?
   db_update('feeds_source')
     ->condition('id', $importer_id)
     ->condition('feed_nid', $feed_nid)
@@ -281,7 +383,7 @@ function feeds_fetcher_callback($importer, $feed_nid = 0) {
 }
 
 /**
- * Template generation
+ * Template generation.
  */
 function feeds_importer_template(FeedsImporter $importer) {
   if ($importer->parser instanceof FeedsCSVParser) {
@@ -318,18 +420,26 @@ function theme_feeds_source_status($v) {
   $items = array();
   if ($v['progress_importing']) {
     $progress = number_format(100.0 * $v['progress_importing'], 0);
-    $items[] = t('Importing - @progress % complete.', array('@progress' => $progress));
+    $items[] = t('Importing - @progress % complete.', array(
+      '@progress' => $progress,
+    ));
   }
   if ($v['progress_clearing']) {
     $progress = number_format(100.0 * $v['progress_clearing'], 0);
-    $items[] = t('Deleting items - @progress % complete.', array('@progress' => $progress));
+    $items[] = t('Deleting items - @progress % complete.', array(
+      '@progress' => $progress,
+    ));
   }
   if (!count($items)) {
     if ($v['count']) {
       if ($v['imported']) {
-        $items[] = t('Last import: @ago ago.', array('@ago' => format_interval(REQUEST_TIME - $v['imported'], 1)));
+        $items[] = t('Last import: @ago ago.', array(
+          '@ago' => format_interval(REQUEST_TIME - $v['imported'], 1),
+        ));
       }
-      $items[] = t('@count imported items total.', array('@count' => $v['count']));
+      $items[] = t('@count imported items total.', array(
+        '@count' => $v['count'],
+      ));
     }
     else {
       $items[] = t('No imported items.');
@@ -357,7 +467,9 @@ function theme_feeds_upload($variables) {
       $summary .= l(check_plain($file->filename), $wrapper->getExternalUrl());
     }
     else {
-      $summary .= t('URI scheme %scheme not available.', array('%scheme' =>  file_uri_scheme($uri)));
+      $summary .= t('URI scheme %scheme not available.', array(
+        '%scheme' => file_uri_scheme($uri),
+      ));
     }
     $summary .= '</div>';
     $summary .= '<div class="file-size">';
@@ -369,7 +481,8 @@ function theme_feeds_upload($variables) {
     $summary .= '</div>';
   }
   // Prepend the summary to the form field.
-  $element['#children'] = '<div class="feeds-file">' . $summary . '<div class="feeds-file-upload">' . $element['#children'];
+  $element['#children'] = '<div class="feeds-file">' . $summary .
+    '<div class="feeds-file-upload">' . $element['#children'];
   // Render file upload field using theme_form_element().
   $output = theme('form_element', $element);
   // Close "feeds-file" and "feeds-file-upload" divs.
diff --git a/feeds_import/feeds_import.test b/feeds_import/feeds_import.test
index ee62de0..e5a1f7a 100644
--- a/feeds_import/feeds_import.test
+++ b/feeds_import/feeds_import.test
@@ -100,9 +100,10 @@ class FeedsExamplesNodeTestCase extends FeedsWebTestCase {
     $this->assertText('Updated 7 nodes');
 
     // Import a tab separated file.
+    $this->drupalGet('import/node/delete-items');
     $this->drupalPost('import/node/delete-items', array(), 'Delete');
     $edit = array(
-      'files[feeds]' => $this->absolutePath() . '/tests/feeds/nodes.tsv',
+      'files[node]' => $this->absolutePath() . '/tests/feeds/nodes.tsv',
       'feeds[FeedsCSVParser][delimiter]' => "TAB",
     );
     $this->drupalPost('import/node', $edit, 'Import');
diff --git a/feeds_news/feeds_news.feeds_importer_default.inc b/feeds_news/feeds_news.feeds_importer_default.inc
index 3fa5ee7..2820269 100644
--- a/feeds_news/feeds_news.feeds_importer_default.inc
+++ b/feeds_news/feeds_news.feeds_importer_default.inc
@@ -106,7 +106,7 @@ function feeds_news_feeds_importer_default() {
           ),
           1 => array(
             'source' => 'xmlurl',
-            'target' => 'feeds_source',
+            'target' => 'feeds_source_feed',
             'unique' => 1,
           ),
         ),
diff --git a/feeds_ui/feeds_ui.test b/feeds_ui/feeds_ui.test
index 4b90a6d..9884d34 100644
--- a/feeds_ui/feeds_ui.test
+++ b/feeds_ui/feeds_ui.test
@@ -108,8 +108,10 @@ class FeedsUIUserInterfaceTestCase extends FeedsWebTestCase {
     // Create a feed node.
     $edit = array(
       'title' => 'Development Seed',
-      'feeds[FeedsHTTPFetcher][source]' => $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2',
-      );
+      'feeds[test_feed][FeedsHTTPFetcher][source]' =>
+      $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') .
+      '/tests/feeds/developmentseed.rss2',
+    );
     $this->drupalPost('node/add/page', $edit, 'Save');
     $this->assertText('Basic page Development Seed has been created.');
 
diff --git a/includes/FeedsImporter.inc b/includes/FeedsImporter.inc
index 5286b1d..15bb7a8 100644
--- a/includes/FeedsImporter.inc
+++ b/includes/FeedsImporter.inc
@@ -193,6 +193,7 @@ class FeedsImporter extends FeedsConfigurable {
         'plugin_key' => 'FeedsNodeProcessor',
       ),
       'content_type' => '',
+      'weight' => 0,
       'update' => 0,
       'import_period' => 1800, // Refresh every 30 minutes by default.
       'expire_period' => 3600, // Expire every hour by default, this is a hidden setting.
@@ -220,6 +221,12 @@ class FeedsImporter extends FeedsConfigurable {
       '#description' => t('A description of this importer.'),
       '#default_value' => $config['description'],
     );
+    $form['weight'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Weight'),
+      '#description' => t('Determines the effective processing order of this feed relative to others that might run at the same time.'),
+      '#default_value' => $config['weight'],
+    );
     $node_types = node_type_get_names();
     array_walk($node_types, 'check_plain');
     $form['content_type'] = array(
diff --git a/includes/FeedsSource.inc b/includes/FeedsSource.inc
index 1fc5209..47c893f 100644
--- a/includes/FeedsSource.inc
+++ b/includes/FeedsSource.inc
@@ -33,7 +33,7 @@ interface FeedsSourceInterface {
    *
    * @see FeedsPlugin class.
    *
-   * @return
+   * @return bool
    *   TRUE if a plugin handles source specific configuration, FALSE otherwise.
    */
   public function hasSourceConfig();
@@ -124,9 +124,9 @@ class FeedsState {
    * - $progress is larger than $total
    * - $progress approximates $total so that $finished rounds to 1.0
    *
-   * @param $total
+   * @param int $total
    *   A natural number that is the total to be worked off.
-   * @param $progress
+   * @param int $progress
    *   A natural number that is the progress made on $total.
    */
   public function progress($total, $progress) {
@@ -143,6 +143,7 @@ class FeedsState {
       $this->progress = FEEDS_BATCH_COMPLETE;
     }
   }
+
 }
 
 /**
@@ -215,7 +216,8 @@ class FeedsSource extends FeedsConfigurable {
   }
 
   /**
-   * Returns the FeedsImporter object that this source is expected to be used with.
+   * Returns the FeedsImporter object that this source is expected
+   * to be used with.
    */
   public function importer() {
     return $this->importer;
@@ -224,7 +226,7 @@ class FeedsSource extends FeedsConfigurable {
   /**
    * Preview = fetch and parse a feed.
    *
-   * @return
+   * @return object
    *   FeedsParserResult object.
    *
    * @throws
@@ -366,7 +368,7 @@ class FeedsSource extends FeedsConfigurable {
    * This method only executes the current batch chunk, then returns. If you are
    * looking to import an entire source, use FeedsSource::startImport() instead.
    *
-   * @return
+   * @return float
    *   FEEDS_BATCH_COMPLETE if the import process finished. A decimal between
    *   0.0 and 0.9 periodic if import is still in progress.
    *
@@ -430,7 +432,7 @@ class FeedsSource extends FeedsConfigurable {
    * looking to delete all items of a source, use FeedsSource::startClear()
    * instead.
    *
-   * @return
+   * @return float
    *   FEEDS_BATCH_COMPLETE if the clearing process finished. A decimal between
    *   0.0 and 0.9 periodic if clearing is still in progress.
    *
@@ -528,10 +530,10 @@ class FeedsSource extends FeedsConfigurable {
    *
    * @todo Rename getConfigFor() accordingly to config().
    *
-   * @param $stage
+   * @param string $stage
    *   One of FEEDS_FETCH, FEEDS_PARSE, FEEDS_PROCESS or FEEDS_PROCESS_CLEAR.
    *
-   * @return
+   * @return object
    *   The FeedsState object for the given stage.
    */
   public function state($stage) {
@@ -563,24 +565,31 @@ class FeedsSource extends FeedsConfigurable {
 
     // Store the source property of the fetcher in a separate column so that we
     // can do fast lookups on it.
+    // Only save if there is a source so they can be optional on entities.
     $source = '';
-    if (isset($config[get_class($this->importer->fetcher)]['source'])) {
-      $source = $config[get_class($this->importer->fetcher)]['source'];
-    }
-    $object = array(
-      'id' => $this->id,
-      'feed_nid' => $this->feed_nid,
-      'imported' => $this->imported,
-      'config' => $config,
-      'source' => $source,
-      'state' => isset($this->state) ? $this->state : FALSE,
-      'fetcher_result' => isset($this->fetcher_result) ? $this->fetcher_result : FALSE,
-    );
-    if (db_query_range("SELECT 1 FROM {feeds_source} WHERE id = :id AND feed_nid = :nid", 0, 1, array(':id' => $this->id, ':nid' => $this->feed_nid))->fetchField()) {
-      drupal_write_record('feeds_source', $object, array('id', 'feed_nid'));
-    }
-    else {
-      drupal_write_record('feeds_source', $object);
+    if (isset($config[get_class($this->importer->fetcher)]['source']) &&
+      $source = $config[get_class($this->importer->fetcher)]['source']) {
+      $object = array(
+        'id' => $this->id,
+        'feed_nid' => $this->feed_nid,
+        'imported' => $this->imported,
+        'config' => $config,
+        'source' => $source,
+        'state' => isset($this->state) ? $this->state : FALSE,
+        'fetcher_result' => isset($this->fetcher_result) ? $this->fetcher_result : FALSE,
+      );
+      if (db_query_range("SELECT 1 FROM {feeds_source} WHERE id = :id AND feed_nid = :nid",
+        0, 1,
+        array(
+          ':id' => $this->id,
+          ':nid' => $this->feed_nid,
+        )
+      )->fetchField()) {
+        drupal_write_record('feeds_source', $object, array('id', 'feed_nid'));
+      }
+      else {
+        drupal_write_record('feeds_source', $object);
+      }
     }
   }
 
@@ -590,7 +599,12 @@ class FeedsSource extends FeedsConfigurable {
    * @todo Patch CTools to move constants from export.inc to ctools.module.
    */
   public function load() {
-    if ($record = db_query("SELECT imported, config, state, fetcher_result FROM {feeds_source} WHERE id = :id AND feed_nid = :nid", array(':id' => $this->id, ':nid' => $this->feed_nid))->fetchObject()) {
+    if ($record = db_query("SELECT imported, config, state, fetcher_result FROM {feeds_source} WHERE id = :id AND feed_nid = :nid",
+      array(
+        ':id' => $this->id,
+        ':nid' => $this->feed_nid,
+      )
+    )->fetchObject()) {
       // While FeedsSource cannot be exported, we still use CTool's export.inc
       // export definitions.
       ctools_include('export');
@@ -635,7 +649,7 @@ class FeedsSource extends FeedsConfigurable {
   /**
    * Only return source if configuration is persistent and valid.
    *
-   * @see FeedsConfigurable::existing().
+   * @see FeedsConfigurable::existing()
    */
   public function existing() {
     // If there is no feed nid given, there must be no content type specified.
@@ -656,7 +670,7 @@ class FeedsSource extends FeedsConfigurable {
    * @param FeedsSourceInterface $client
    *   An object that is an implementer of FeedsSourceInterface.
    *
-   * @return
+   * @return array
    *   An array stored for $client.
    */
   public function getConfigFor(FeedsSourceInterface $client) {
@@ -672,7 +686,7 @@ class FeedsSource extends FeedsConfigurable {
    * @param $config
    *   The configuration for $client.
    *
-   * @return
+   * @return array
    *   An array stored for $client.
    */
   public function setConfigFor(FeedsSourceInterface $client, $config) {
@@ -739,10 +753,10 @@ class FeedsSource extends FeedsConfigurable {
    * submits a source for import or clearing, we will leave her without any
    * visual indicators of an ongoing job.
    *
-   * @see FeedsSource::startImport().
-   * @see FeedsSource::startClear().
+   * @see FeedsSource::startImport()
+   * @see FeedsSource::startClear()
    *
-   * @param $method
+   * @param string $method
    *   Method to execute on importer; one of 'import' or 'clear'.
    *
    * @throws Exception $e
@@ -762,13 +776,13 @@ class FeedsSource extends FeedsConfigurable {
   /**
    * Batch API helper. Starts a Batch API job.
    *
-   * @see FeedsSource::startImport().
-   * @see FeedsSource::startClear().
+   * @see FeedsSource::startImport()
+   * @see FeedsSource::startClear()
    * @see feeds_batch()
    *
-   * @param $title
+   * @param string $title
    *   Title to show to user when executing batch.
-   * @param $method
+   * @param string $method
    *   Method to execute on importer; one of 'import' or 'clear'.
    */
   protected function startBatchAPIJob($title, $method) {
diff --git a/plugins/FeedsFileFetcher.inc b/plugins/FeedsFileFetcher.inc
index 6f1b310..a687aa0 100644
--- a/plugins/FeedsFileFetcher.inc
+++ b/plugins/FeedsFileFetcher.inc
@@ -30,7 +30,11 @@ class FeedsFileFetcherResult extends FeedsFetcherResult {
    */
   public function getFilePath() {
     if (!is_readable($this->file_path)) {
-      throw new Exception(t('File @filepath is not accessible.', array('@filepath' => $this->file_path)));
+      throw new Exception(t('File @filepath is not accessible.',
+        array(
+          '@filepath' => $this->file_path,
+        )
+      ));
     }
     return $this->sanitizeFile($this->file_path);
   }
@@ -65,14 +69,15 @@ class FeedsFileFetcher extends FeedsFetcher {
       return new FeedsFileFetcherResult($file);
     }
 
-    throw new Exception(t('Resource is not a file or it is an empty directory: %source', array('%source' => $source_config['source'])));
+    throw new Exception(t('Resource is not a file or it is an empty directory: %source',
+      array('%source' => $source_config['source'])));
   }
 
   /**
    * Returns an array of files in a directory.
    *
    * @param string $dir
-   *   A stream wreapper URI that is a directory.
+   *   A stream wrapper URI that is a directory.
    *
    * @return array
    *   An array of stream wrapper URIs pointing to files. The array is empty if
@@ -107,10 +112,14 @@ class FeedsFileFetcher extends FeedsFetcher {
       );
       $form['upload'] = array(
         '#type' => 'file',
+        '#name' => 'files[' . $this->id . ']',
         '#title' => empty($this->config['direct']) ? t('File') : NULL,
-        '#description' => empty($source_config['source']) ? t('Select a file from your local system.') : t('Select a different file from your local system.'),
+        '#description' => empty($source_config['source']) ?
+        t('Select a file from your local system.') :
+        t('Select a different file from your local system.'),
         '#theme_wrappers' => array('feeds_upload'),
-        '#file_info' => empty($source_config['fid']) ? NULL : file_load($source_config['fid']),
+        '#file_info' => empty($source_config['fid']) ?
+        NULL : file_load($source_config['fid']),
         '#size' => 10,
       );
     }
@@ -118,8 +127,10 @@ class FeedsFileFetcher extends FeedsFetcher {
       $form['source'] = array(
         '#type' => 'textfield',
         '#title' => t('File'),
-        '#description' => t('Specify a path to a file or a directory. Prefix the path with a scheme. Available schemes: @schemes.', array('@schemes' => implode(', ', $this->config['allowed_schemes']))),
-        '#default_value' => empty($source_config['source']) ? '' : $source_config['source'],
+        '#description' => t('Specify a path to a file or a directory. Prefix the path with a scheme. Available schemes: @schemes.',
+          array('@schemes' => implode(', ', $this->config['allowed_schemes']))),
+        '#default_value' => empty($source_config['source']) ?
+        '' : $source_config['source'],
       );
     }
     return $form;
@@ -139,20 +150,33 @@ class FeedsFileFetcher extends FeedsFetcher {
         if (user_access('administer feeds')) {
           $plugin_key = feeds_importer($this->id)->config[$this->pluginType()]['plugin_key'];
           $link = url('admin/structure/feeds/' . $this->id . '/settings/' . $plugin_key);
-          form_set_error('feeds][FeedsFileFetcher][source', t('Upload failed. Please check the upload <a href="@link">settings.</a>', array('@link' => $link)));
+          form_set_error('feeds][FeedsFileFetcher][source',
+            t('Upload failed. Please check the upload <a href="@link">settings.</a>',
+              array('@link' => $link))
+          );
         }
         else {
-          form_set_error('feeds][FeedsFileFetcher][source', t('Upload failed. Please contact your site administrator.'));
+          form_set_error('feeds][FeedsFileFetcher][source',
+            t('Upload failed. Please contact your site administrator.')
+          );
         }
-        watchdog('feeds', 'The upload directory %directory required by a feed could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', array('%directory' => $feed_dir));
+        watchdog('feeds', 'The upload directory %directory required by a feed could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.',
+          array('%directory' => $feed_dir)
+        );
       }
       // Validate and save uploaded file.
-      elseif ($file = file_save_upload('feeds', array('file_validate_extensions' => array(0 => $this->config['allowed_extensions'])), $feed_dir)) {
+      elseif ($file = file_save_upload($this->id,
+        array(
+          'file_validate_extensions' => array(
+            0 => $this->config['allowed_extensions'],
+          ),
+        ), $feed_dir)) {
         $values['source'] = $file->uri;
         $values['file'] = $file;
       }
       elseif (empty($values['source'])) {
-        form_set_error('feeds][FeedsFileFetcher][source', t('Please upload a file.'));
+        form_set_error('feeds][FeedsFileFetcher][source',
+          t('Please upload a file.'));
       }
       else {
         // File present from previous upload. Nothing to validate.
@@ -162,11 +186,17 @@ class FeedsFileFetcher extends FeedsFetcher {
       // Check if chosen url scheme is allowed.
       $scheme = file_uri_scheme($values['source']);
       if (!$scheme || !in_array($scheme, $this->config['allowed_schemes'])) {
-        form_set_error('feeds][FeedsFileFetcher][source', t("The file needs to reside within the site's files directory, its path needs to start with scheme://. Available schemes: @schemes.", array('@schemes' => implode(', ', $this->config['allowed_schemes']))));
+        form_set_error('feeds][FeedsFileFetcher][source',
+          t("The file needs to reside within the site's files directory, its path needs to start with scheme://. Available schemes: @schemes.",
+            array(
+              '@schemes' => implode(', ', $this->config['allowed_schemes']),
+            ))
+        );
       }
       // Check whether the given path is readable.
       elseif (!is_readable($values['source'])) {
-        form_set_error('feeds][FeedsFileFetcher][source', t('The specified file or directory does not exist.'));
+        form_set_error('feeds][FeedsFileFetcher][source',
+          t('The specified file or directory does not exist.'));
       }
     }
   }
@@ -241,11 +271,17 @@ class FeedsFileFetcher extends FeedsFetcher {
     $form['directory'] = array(
       '#type' => 'textfield',
       '#title' => t('Upload directory'),
-      '#description' => t('Directory where uploaded files get stored. Prefix the path with a scheme. Available schemes: @schemes.', array('@schemes' => implode(', ', $this->getSchemes()))),
+      '#description' => t('Directory where uploaded files get stored. Prefix the path with a scheme. Available schemes: @schemes.',
+        array('@schemes' => implode(', ', $this->getSchemes()))
+      ),
       '#default_value' => $this->config['directory'],
       '#states' => array(
-        'visible' => array(':input[name="direct"]' => array('checked' => FALSE)),
-        'required' => array(':input[name="direct"]' => array('checked' => FALSE)),
+        'visible' => array(
+          ':input[name="direct"]' => array('checked' => FALSE),
+        ),
+        'required' => array(
+          ':input[name="direct"]' => array('checked' => FALSE),
+        ),
       ),
     );
     if ($options = $this->getSchemeOptions()) {
@@ -256,7 +292,9 @@ class FeedsFileFetcher extends FeedsFetcher {
         '#options' => $options,
         '#description' => t('Select the schemes you want to allow for direct upload.'),
         '#states' => array(
-          'visible' => array(':input[name="direct"]' => array('checked' => TRUE)),
+          'visible' => array(
+            ':input[name="direct"]' => array('checked' => TRUE),
+          ),
         ),
       );
     }
@@ -286,7 +324,8 @@ class FeedsFileFetcher extends FeedsFetcher {
       // Validate the URI scheme of the upload directory.
       $scheme = file_uri_scheme($values['directory']);
       if (!$scheme || !in_array($scheme, $this->getSchemes())) {
-        form_set_error('directory', t('Please enter a valid scheme into the directory location.'));
+        form_set_error('directory',
+          t('Please enter a valid scheme into the directory location.'));
 
         // Return here so that attempts to create the directory below don't
         // throw warnings.
@@ -295,7 +334,8 @@ class FeedsFileFetcher extends FeedsFetcher {
 
       // Ensure that the upload directory exists.
       if (!file_prepare_directory($values['directory'], FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
-        form_set_error('directory', t('The chosen directory does not exist and attempts to create it failed.'));
+        form_set_error('directory',
+          t('The chosen directory does not exist and attempts to create it failed.'));
       }
     }
   }
diff --git a/plugins/FeedsHTTPFetcher.inc b/plugins/FeedsHTTPFetcher.inc
index cd91b63..0c2667c 100644
--- a/plugins/FeedsHTTPFetcher.inc
+++ b/plugins/FeedsHTTPFetcher.inc
@@ -238,7 +238,7 @@ class FeedsHTTPFetcher extends FeedsFetcher {
     }
 
     if (!feeds_valid_url($values['source'], TRUE)) {
-      $form_key = 'feeds][' . get_class($this) . '][source';
+      $form_key = 'feeds][' . $this->id . '][' . get_class($this) . '][source';
       form_set_error($form_key, t('The URL %source is invalid.', array('%source' => $original_url)));
     }
     elseif ($this->config['auto_detect_feeds']) {
diff --git a/plugins/FeedsNodeProcessor.inc b/plugins/FeedsNodeProcessor.inc
index 2cfdf30..8a769dc 100644
--- a/plugins/FeedsNodeProcessor.inc
+++ b/plugins/FeedsNodeProcessor.inc
@@ -97,7 +97,9 @@ class FeedsNodeProcessor extends FeedsProcessor {
       // could be invalid.
       if (!$author) {
         $message = 'User %uid is not a valid user.';
-        throw new FeedsAccessException(t($message, array('%uid' => $entity->uid)));
+        throw new FeedsAccessException(t($message,
+          array('%uid' => $entity->uid))
+        );
       }
 
       if (empty($entity->nid) || !empty($entity->is_new)) {
@@ -128,7 +130,7 @@ class FeedsNodeProcessor extends FeedsProcessor {
    */
   protected function entityValidate($entity) {
     if (!isset($entity->uid) || !is_numeric($entity->uid)) {
-       $entity->uid = $this->config['author'];
+      $entity->uid = $this->config['author'];
     }
   }
 
@@ -185,7 +187,7 @@ class FeedsNodeProcessor extends FeedsProcessor {
       '#title' => t('Author'),
       '#description' => t('Select the author of the nodes to be created - leave empty to assign "anonymous".'),
       '#autocomplete_path' => 'user/autocomplete',
-      '#default_value' => empty($author->name) ?  'anonymous' : check_plain($author->name),
+      '#default_value' => empty($author->name) ? 'anonymous' : check_plain($author->name),
     );
     $form['authorize'] = array(
       '#type' => 'checkbox',
@@ -193,7 +195,10 @@ class FeedsNodeProcessor extends FeedsProcessor {
       '#description' => t('Check that the author has permission to create the node.'),
       '#default_value' => $this->config['authorize'],
     );
-    $period = drupal_map_assoc(array(FEEDS_EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800, 2592000, 2592000 * 3, 2592000 * 6, 31536000), 'feeds_format_expire');
+    $period = drupal_map_assoc(array(
+      FEEDS_EXPIRE_NEVER, 3600, 10800, 21600, 43200, 86400, 259200, 604800,
+      2592000, 2592000 * 3, 2592000 * 6, 31536000,
+    ), 'feeds_format_expire');
     $form['expire'] = array(
       '#type' => 'select',
       '#title' => t('Expire nodes'),
@@ -234,31 +239,42 @@ class FeedsNodeProcessor extends FeedsProcessor {
    * Override setTargetElement to operate on a target item that is a node.
    */
   public function setTargetElement(FeedsSource $source, $target_node, $target_element, $value) {
+    $id = $this->bundle();
+    if ($target_element == 'feeds_source_' . $id) {
+      // Get the class of the feed node importer's fetcher and set the source
+      // property. See feeds_node_update() how $node->feeds gets stored.
+      $class = get_class(feeds_importer($id)->fetcher);
+      $target_node->feeds[$id][$class]['source'] = $value;
+      // This effectively suppresses 'import on submission' feature.
+      // See feeds_node_insert().
+      $target_node->feeds['suppress_import'] = TRUE;
+    }
+    if (substr($target_element, 0, 13) == 'feeds_source_') {
+      foreach ($target_node->feeds as $key => $feed) {
+        if ($target_element == 'feeds_source_' . $key) {
+          $class = get_class(feeds_importer($id)->fetcher);
+          $target_node->feeds[$key][$class]['source'] = $value;
+        }
+      }
+    }
+
     switch ($target_element) {
       case 'created':
         $target_node->created = feeds_to_unixtime($value, REQUEST_TIME);
         break;
-      case 'feeds_source':
-        // Get the class of the feed node importer's fetcher and set the source
-        // property. See feeds_node_update() how $node->feeds gets stored.
-        if ($id = feeds_get_importer_id($this->bundle())) {
-          $class = get_class(feeds_importer($id)->fetcher);
-          $target_node->feeds[$class]['source'] = $value;
-          // This effectively suppresses 'import on submission' feature.
-          // See feeds_node_insert().
-          $target_node->feeds['suppress_import'] = TRUE;
-        }
-        break;
+
       case 'user_name':
         if ($user = user_load_by_name($value)) {
           $target_node->uid = $user->uid;
         }
         break;
+
       case 'user_mail':
         if ($user = user_load_by_mail($value)) {
           $target_node->uid = $user->uid;
         }
         break;
+
       default:
         parent::setTargetElement($source, $target_node, $target_element, $value);
         break;
@@ -330,13 +346,15 @@ class FeedsNodeProcessor extends FeedsProcessor {
     }
 
     // If the target content type is a Feed node, expose its source field.
-    if ($id = feeds_get_importer_id($this->bundle())) {
-      $name = feeds_importer($id)->config['name'];
-      $targets['feeds_source'] = array(
-        'name' => t('Feed source'),
-        'description' => t('The content type created by this processor is a Feed Node, it represents a source itself. Depending on the fetcher selected on the importer "@importer", this field is expected to be for example a URL or a path to a file.', array('@importer' => $name)),
-        'optional_unique' => TRUE,
-      );
+    if ($ids = feeds_get_importer_ids($this->config['bundle'])) {
+      foreach ($ids as $id) {
+        $name = feeds_importer($id)->config['name'];
+        $targets['feeds_source_' . $id] = array(
+          'name' => t('Feed source ' . $name),
+          'description' => t('The content type created by this processor is a Feed Node, it represents a source itself. Depending on the fetcher selected on the importer "@importer", this field is expected to be for example a URL or a path to a file.', array('@importer' => $name)),
+          'optional_unique' => TRUE,
+        );
+      }
     }
 
     $this->getHookTargets($targets);
@@ -357,16 +375,24 @@ class FeedsNodeProcessor extends FeedsProcessor {
     foreach ($this->uniqueTargets($source, $result) as $target => $value) {
       switch ($target) {
         case 'nid':
-          $nid = db_query("SELECT nid FROM {node} WHERE nid = :nid", array(':nid' => $value))->fetchField();
+          $nid = db_query("SELECT nid FROM {node} WHERE nid = :nid",
+            array(':nid' => $value))->fetchField();
           break;
+
         case 'title':
-          $nid = db_query("SELECT nid FROM {node} WHERE title = :title AND type = :type", array(':title' => $value, ':type' => $this->bundle()))->fetchField();
+          $nid = db_query("SELECT nid FROM {node} WHERE title = :title AND type = :type",
+            array(':title' => $value, ':type' => $this->bundle()))
+            ->fetchField();
           break;
-        case 'feeds_source':
-          if ($id = feeds_get_importer_id($this->bundle())) {
-            $nid = db_query("SELECT fs.feed_nid FROM {node} n JOIN {feeds_source} fs ON n.nid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source", array(':id' => $id, ':source' => $value))->fetchField();
+      }
+      if (isset($this->config['content_type']) &&
+        $ids = feeds_get_importer_ids($this->config['content_type'])) {
+        foreach ($ids as $id) {
+          if ($target == 'feeds_source_' . $id) {
+            $nid = db_query("SELECT fs.feed_nid FROM {node} n JOIN {feeds_source} fs ON n.nid = fs.feed_nid WHERE fs.id = :id AND fs.source = :source",
+              array(':id' => $id, ':source' => $value))->fetchField();
           }
-          break;
+        }
       }
       if ($nid) {
         // Return with the first nid found.
diff --git a/tests/feeds.test b/tests/feeds.test
index b3ce145..b413942 100644
--- a/tests/feeds.test
+++ b/tests/feeds.test
@@ -261,7 +261,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
     // Create a feed node.
     $edit = array(
       'title' => $title,
-      'feeds[FeedsHTTPFetcher][source]' => $feed_url,
+      'feeds[' . $id  . '][FeedsHTTPFetcher][source]' => $feed_url,
     );
     $this->drupalPost('node/add/' . str_replace('_', '-', $content_type), $edit, 'Save');
     $this->assertText('has been created.');
@@ -297,10 +297,10 @@ class FeedsWebTestCase extends DrupalWebTestCase {
    * @param $title
    *   Optional parameter to change title of feed node.
    */
-  public function editFeedNode($nid, $feed_url, $title = '') {
+  public function editFeedNode($nid, $feed_url, $id = 'syndication', $title = '') {
     $edit = array(
       'title' => $title,
-      'feeds[FeedsHTTPFetcher][source]' => $feed_url,
+      'feeds[' . $id . '][FeedsHTTPFetcher][source]' => $feed_url,
     );
     // Check that the update was saved.
     $this->drupalPost('node/' . $nid . '/edit', $edit, 'Save');
@@ -363,7 +363,7 @@ class FeedsWebTestCase extends DrupalWebTestCase {
 
     $this->assertTrue(file_exists($file), 'Source file exists');
     $edit = array(
-      'files[feeds]' => $file,
+      "files[$id]" => $file,
     );
     $this->drupalPost('import/' . $id, $edit, 'Import');
   }
diff --git a/tests/feeds/feed_without_guid.rss2 b/tests/feeds/feed_without_guid.rss2
index af4569f..b740e6c 100644
--- a/tests/feeds/feed_without_guid.rss2
+++ b/tests/feeds/feed_without_guid.rss2
@@ -1,189 +1,189 @@
-<rss version="2.0">
-<channel>
-	<generator>Rss generator</generator>
-	<pubDate>2009.10.20. 16:49:01</pubDate>
-	<title>Magyar Nemzet Online - Hírek</title>
-	<description>Magyar Nemzet Online - Hírek</description>
-	<link>http://www.mno.hu</link>
-	<language>HU</language>
-	<image>
-		<url>http://www.mno.hu/docfiles/rss/mno01.jpg</url>
-		<link>http://www.mno.hu</link>
-		<description>Magyar Nemzet Online - Hírek</description>
-		<title>Magyar Nemzet Online - Hírek</title>
-		<width>88</width>
-		<height>31</height>
-	</image>
-		<item>
-		<title>
-			Megint csak a balhé + Videó
-		</title>
-		<description>
-			Az egykori kiváló labdarúgó, Paul Gascoigne ezúttal sem futballtudása vagy esetleges edzői karrierjével került a címlapokra. A korábbi válogatott középpályás most egy snooker klubban okozott botrányt: lefejelte, majd bocsánatkérésként arcon csókolta az egyik kidobót. Utóbbi úriember meggondolatlanul cselekedett, mikor rászólt a sztárra, hogy tilos a dohányzás. 
-		</description>
-		<pubDate>
-			2009-10-20 16:49 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/671000
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Az uniós tejalap csak filléreket hoz a magyar termelőknek
-		</title>
-		<description>
-			A magyar tejtermelők véleménye szerint az unió által kvóta alapon kioszthatónak minősített 280 millió eurós tejalap nem igazán hathatós segítség, mivel az tejkvóta-kilogrammonként mindössze 50 fillér többletet jelenthet egy termelő számára – mondta az MTI megkeresésére kedden Bakos Erzsébet, a Tej Terméktanács szakmai koordinátora.<br /><a href="http://mno.hu/portal/670961"><strong><br /><span class="content_blog_lead" style="font-weight: bold"></span><strong><strong><strong><strong>•</strong></strong> Sürgősséggel döntenek a tejalapról</strong></strong></strong></a> 
-		</description>
-		<pubDate>
-			2009-10-20 16:48 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670998
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Pluszban zárt a BUX
-		</title>
-		<description>
-			A Budapesti Értéktőzsde részvényindexe, a BUX 70,24 pontos, 0,33 százalékos emelkedéssel, 21.474,51 ponton zárt kedden. 
-		</description>
-		<pubDate>
-			2009-10-20 16:44 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/671006
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Bajnait fogadja a pápa
-		</title>
-		<description>
-			Bajnai Gordon miniszterelnök november 13-án a Vatikánba utazik, hogy találkozzon XVI. Benedek pápával – erősítette meg a nol.hu információját a kormányszóvivő. 
-		</description>
-		<pubDate>
-			2009-10-20 16:40 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670997
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Élelmiszereink 11 százaléka „saját” 
-		</title>
-		<description>
-			Egyre többet költünk élelmiszerre, és egyre kevesebb élelmiszert termelünk meg magunknak - derül ki a KSH 2000-2007 közötti éveket vizsgáló statisztikájából. Állati zsírt és cukrot kevesebbet fogyasztunk, gyorsétterembe viszont többet járunk.
-		</description>
-		<pubDate>
-			2009-10-20 16:31 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670989
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Leleplezte magát a Heves megyei szocialista közgyűlési elnök
-		</title>
-		<description>
-			Leleplezte magát Sós Tamás, a hevesi megyegyűlés elnöke, mert korábban azt állította, hogy az egri kórház fejlesztése csak magánműködtető bevonásával képzelhető el – jelentette ki kedden Egerben a megyegyűlés Fidesz-frakciójának igazgatója. Ezzel szemben Sós Tamás most bejelentette, hogy az intézmény 4,6-4,8 milliárd forintnyi uniós fejlesztési forrásra számíthat – mondta sajtótájékoztatón Herman István. 
-		</description>
-		<pubDate>
-			2009-10-20 16:28 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670999
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Oszkóék gyomra nem korog
-		</title>
-		<description>
-			Állítólag százezer ember éhezik Magyarországon, vagyis ott, ahol „nagy a jólét”, ahová nem gyűrűznek be mindenféle válságok, és csupa remek ember rendelkezik az erőforrások és a döntési folyamatok felett. Végül is tízmillióhoz képest mi ez a százezer? Nyilván így gondolja ezt a teljes szocialista élcsapat is, mert egyetlen hangot sem hallattak az ügyben. De talán jobb is. 
-		</description>
-		<pubDate>
-			2009-10-20 16:28 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670522
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Áramot vezetett a kerítésbe, hat év fegyházbüntetést kapott
-		</title>
-		<description>
-			Hat év fegyházbüntetésre ítélte kedden a Szabolcs-Szatmár-Bereg Megyei Bíróság azt a 41 éves kisari férfit, aki idén áprilisban áramot vezetett lakóházának kerítésébe, később pedig alkoholos állapotban késsel sebezte meg életveszélyesen az édesanyját, az ítélet nem jogerős. 
-		</description>
-		<pubDate>
-			2009-10-20 16:22 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670994
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			„A kormány elvesz, majd nagy csinnadrattával morzsákat oszt”
-		</title>
-		<description>
-			A tehetséggondozásra, az ország jövőjének a megalapozására kell, hogy legyen pénze a kormánynak – mondta Bajnai Gordon a kedden bejelentett tehetségsegítő programról. Sió László, a Fidesz szakpolitikusa szerint a kormány két kézzel elvesz, majd nagy csinnadrattával morzsákat oszt. Igen alacsony a ténylegesen kifizetett források aránya – reagált a hírre Cser-Palkovics András.
-		</description>
-		<pubDate>
-			2009-10-20 16:18 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670996
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-		<item>
-		<title>
-			Hőszivattyút telepítenek az iskolába
-		</title>
-		<description>
-			Mintegy 550 millió forintból teljesen felújítják a békési kistérségi általános iskola és pedagógiai szakszolgálat dr. Hepp Ferencről elnevezett tagintézményét – közölte Békés polgármestere kedden sajtótájékoztatón. A hőszigetelési munkák mellett hőszivattyú telepítésével is próbálják csökkenteni az energiafogyasztást.
-		</description>
-		<pubDate>
-			2009-10-20 16:13 +0200
-		</pubDate>
-		<link>
-			http://www.mno.hu/portal/670987
-		</link>
-		<category>
-			Online
-		</category>
-	</item>
-	</channel>
-</rss>
-		
+<rss version="2.0">
+<channel>
+	<generator>Rss generator</generator>
+	<pubDate>2009.10.20. 16:49:01</pubDate>
+	<title>Magyar Nemzet Online - Hírek</title>
+	<description>Magyar Nemzet Online - Hírek</description>
+	<link>http://www.mno.hu</link>
+	<language>HU</language>
+	<image>
+		<url>http://www.mno.hu/docfiles/rss/mno01.jpg</url>
+		<link>http://www.mno.hu</link>
+		<description>Magyar Nemzet Online - Hírek</description>
+		<title>Magyar Nemzet Online - Hírek</title>
+		<width>88</width>
+		<height>31</height>
+	</image>
+		<item>
+		<title>
+			Megint csak a balhé + Videó
+		</title>
+		<description>
+			Az egykori kiváló labdarúgó, Paul Gascoigne ezúttal sem futballtudása vagy esetleges edzői karrierjével került a címlapokra. A korábbi válogatott középpályás most egy snooker klubban okozott botrányt: lefejelte, majd bocsánatkérésként arcon csókolta az egyik kidobót. Utóbbi úriember meggondolatlanul cselekedett, mikor rászólt a sztárra, hogy tilos a dohányzás. 
+		</description>
+		<pubDate>
+			2009-10-20 16:49 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/671000
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Az uniós tejalap csak filléreket hoz a magyar termelőknek
+		</title>
+		<description>
+			A magyar tejtermelők véleménye szerint az unió által kvóta alapon kioszthatónak minősített 280 millió eurós tejalap nem igazán hathatós segítség, mivel az tejkvóta-kilogrammonként mindössze 50 fillér többletet jelenthet egy termelő számára – mondta az MTI megkeresésére kedden Bakos Erzsébet, a Tej Terméktanács szakmai koordinátora.<br /><a href="http://mno.hu/portal/670961"><strong><br /><span class="content_blog_lead" style="font-weight: bold"></span><strong><strong><strong><strong>•</strong></strong> Sürgősséggel döntenek a tejalapról</strong></strong></strong></a> 
+		</description>
+		<pubDate>
+			2009-10-20 16:48 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670998
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Pluszban zárt a BUX
+		</title>
+		<description>
+			A Budapesti Értéktőzsde részvényindexe, a BUX 70,24 pontos, 0,33 százalékos emelkedéssel, 21.474,51 ponton zárt kedden. 
+		</description>
+		<pubDate>
+			2009-10-20 16:44 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/671006
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Bajnait fogadja a pápa
+		</title>
+		<description>
+			Bajnai Gordon miniszterelnök november 13-án a Vatikánba utazik, hogy találkozzon XVI. Benedek pápával – erősítette meg a nol.hu információját a kormányszóvivő. 
+		</description>
+		<pubDate>
+			2009-10-20 16:40 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670997
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Élelmiszereink 11 százaléka „saját” 
+		</title>
+		<description>
+			Egyre többet költünk élelmiszerre, és egyre kevesebb élelmiszert termelünk meg magunknak - derül ki a KSH 2000-2007 közötti éveket vizsgáló statisztikájából. Állati zsírt és cukrot kevesebbet fogyasztunk, gyorsétterembe viszont többet járunk.
+		</description>
+		<pubDate>
+			2009-10-20 16:31 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670989
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Leleplezte magát a Heves megyei szocialista közgyűlési elnök
+		</title>
+		<description>
+			Leleplezte magát Sós Tamás, a hevesi megyegyűlés elnöke, mert korábban azt állította, hogy az egri kórház fejlesztése csak magánműködtető bevonásával képzelhető el – jelentette ki kedden Egerben a megyegyűlés Fidesz-frakciójának igazgatója. Ezzel szemben Sós Tamás most bejelentette, hogy az intézmény 4,6-4,8 milliárd forintnyi uniós fejlesztési forrásra számíthat – mondta sajtótájékoztatón Herman István. 
+		</description>
+		<pubDate>
+			2009-10-20 16:28 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670999
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Oszkóék gyomra nem korog
+		</title>
+		<description>
+			Állítólag százezer ember éhezik Magyarországon, vagyis ott, ahol „nagy a jólét”, ahová nem gyűrűznek be mindenféle válságok, és csupa remek ember rendelkezik az erőforrások és a döntési folyamatok felett. Végül is tízmillióhoz képest mi ez a százezer? Nyilván így gondolja ezt a teljes szocialista élcsapat is, mert egyetlen hangot sem hallattak az ügyben. De talán jobb is. 
+		</description>
+		<pubDate>
+			2009-10-20 16:28 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670522
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Áramot vezetett a kerítésbe, hat év fegyházbüntetést kapott
+		</title>
+		<description>
+			Hat év fegyházbüntetésre ítélte kedden a Szabolcs-Szatmár-Bereg Megyei Bíróság azt a 41 éves kisari férfit, aki idén áprilisban áramot vezetett lakóházának kerítésébe, később pedig alkoholos állapotban késsel sebezte meg életveszélyesen az édesanyját, az ítélet nem jogerős. 
+		</description>
+		<pubDate>
+			2009-10-20 16:22 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670994
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			„A kormány elvesz, majd nagy csinnadrattával morzsákat oszt”
+		</title>
+		<description>
+			A tehetséggondozásra, az ország jövőjének a megalapozására kell, hogy legyen pénze a kormánynak – mondta Bajnai Gordon a kedden bejelentett tehetségsegítő programról. Sió László, a Fidesz szakpolitikusa szerint a kormány két kézzel elvesz, majd nagy csinnadrattával morzsákat oszt. Igen alacsony a ténylegesen kifizetett források aránya – reagált a hírre Cser-Palkovics András.
+		</description>
+		<pubDate>
+			2009-10-20 16:18 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670996
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+		<item>
+		<title>
+			Hőszivattyút telepítenek az iskolába
+		</title>
+		<description>
+			Mintegy 550 millió forintból teljesen felújítják a békési kistérségi általános iskola és pedagógiai szakszolgálat dr. Hepp Ferencről elnevezett tagintézményét – közölte Békés polgármestere kedden sajtótájékoztatón. A hőszigetelési munkák mellett hőszivattyú telepítésével is próbálják csökkenteni az energiafogyasztást.
+		</description>
+		<pubDate>
+			2009-10-20 16:13 +0200
+		</pubDate>
+		<link>
+			http://www.mno.hu/portal/670987
+		</link>
+		<category>
+			Online
+		</category>
+	</item>
+	</channel>
+</rss>
+		
diff --git a/tests/feeds_processor_node.test b/tests/feeds_processor_node.test
index 2c97142..6c5560d 100644
--- a/tests/feeds_processor_node.test
+++ b/tests/feeds_processor_node.test
@@ -24,7 +24,8 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
   public function setUp() {
     parent::setUp();
 
-    // Set the front page to show 20 nodes so we can easily see what is aggregated.
+    // Set the front page to show 20 nodes so we can easily see what
+    // is aggregated.
     variable_set('default_nodes_main', 20);
 
     // Set the teaser length display to unlimited otherwise tests looking for
@@ -356,7 +357,8 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
 
     // Create a feed node.
     $edit = array(
-      'files[feeds]' => $this->absolutePath() . '/tests/feeds/drupalplanet.rss2',
+      'files[syndication_standalone]' => $this->absolutePath() .
+      '/tests/feeds/drupalplanet.rss2',
     );
     $this->drupalPost('import/syndication_standalone', $edit, 'Import');
     $this->assertText('Created 25 nodes');
@@ -409,8 +411,8 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
   /**
    * Test validation of feed URLs.
    */
-  public function testFeedURLValidation() {
-    $edit['feeds[FeedsHTTPFetcher][source]'] = 'invalid://url';
+  public function testFeedURLValidation($id = 'syndication') {
+    $edit['feeds[' . $id . '][FeedsHTTPFetcher][source]'] = 'invalid://url';
     $this->drupalPost('node/add/page', $edit, 'Save');
     $this->assertText('The URL invalid://url is invalid.');
   }
@@ -418,15 +420,18 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
   /**
    * Test using non-normal URLs like feed:// and webcal://.
    */
-  public function testOddFeedSchemes() {
+  public function testOddFeedSchemes($id = 'syndication') {
     $url = $GLOBALS['base_url'] . '/' . drupal_get_path('module', 'feeds') . '/tests/feeds/developmentseed.rss2';
 
     $schemes = array('feed', 'webcal');
     $item_count = 0;
     foreach ($schemes as $scheme) {
-      $feed_url = strtr($url, array('http://' => $scheme . '://', 'https://' => $scheme . '://'));
+      $feed_url = strtr($url, array(
+        'http://' => $scheme . '://',
+        'https://' => $scheme . '://',
+      ));
 
-      $edit['feeds[FeedsHTTPFetcher][source]'] = $feed_url;
+      $edit['feeds[' . $id . '][FeedsHTTPFetcher][source]'] = $feed_url;
       $this->drupalPost('node/add/page', $edit, 'Save');
       $this->assertText('Basic page Development Seed - Technological Solutions for Progressive Organizations has been created.');
       $this->assertText('Created 10 nodes.');
@@ -438,7 +443,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
   /**
    * Test that feed elements and links are not found on non-feed nodes.
    */
-  public function testNonFeedNodeUI() {
+  public function testNonFeedNodeUI($id = 'syndication') {
     // There should not be feed links on an article node.
     $non_feed_node = $this->drupalCreateNode(array('type' => 'article'));
     $this->drupalGet('node/' . $non_feed_node->nid);
@@ -447,7 +452,7 @@ class FeedsRSStoNodesTest extends FeedsWebTestCase {
 
     // Navigate to a non-feed node form, there should be no Feed field visible.
     $this->drupalGet('node/add/article');
-    $this->assertNoFieldByName('feeds[FeedsHTTPFetcher][source]');
+    $this->assertNoFieldByName('feeds[' . $id . '][FeedsHTTPFetcher][source]');
   }
 
   /**
