diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 37977f30b6dc176c143cd24136d926a4184847f9..267417301b4b8d7b0dd694bdfbd28b9df3191325 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -3,6 +3,7 @@
 Feeds 6.x 1.0 xxxxx xx, xxxx-xx-xx
 ----------------------------------
 
+- #708228 Scott Reynolds, alex_b: Break FeedsImportBatch into separate classes.
 - alex_b: Support mapping to OpenID, using OpenID as a unique mapping target.
 - alex_b: Handle exceptions outside of Importer/Source facade methods.
 - #600584 alex_b: Use Batch API. NOTE: third party plugins/extensions
diff --git a/includes/FeedsBatch.inc b/includes/FeedsBatch.inc
index faf7f197d3ff7543add68bafcdf6386fc7ee043f..7700b79f95db8de50ef1719b0a1a15d3e5fb09e3 100644
--- a/includes/FeedsBatch.inc
+++ b/includes/FeedsBatch.inc
@@ -20,76 +20,70 @@ class FeedsBatch {
 }
 
 /**
- * A FeedsImportBatch is the actual content retrieved from a FeedsSource. On
+ * A FeedsImportBatch wraps the actual content retrieved from a FeedsSource. On
  * import, it is created on the fetching stage and passed through the parsing
  * and processing stage where it is normalized and consumed.
  *
- * @see FeedsSource class
- * @see FeedsFetcher class
+ * A Fetcher must return a FeedsImportBatch object on fetch(). To that end it
+ * must use either one of the existing implementations of FeedsImportBatch
+ * (FeedsFileBatch or FeedsHTTPBatch) or it must extend FeedsImportBatch and
+ * implement at least
+ *
+ * - getRaw() returning the raw content from the source as a string and
+ * - getFilePath() returning a path to a file containing the raw content from
+ *   the source.
+ *
+ * A Parser must populate a FeedsImportBatch object through the set methods upon
+ * parse(). For instance:
+ *
+ * $batch->setTitle('My imported document');
+ * $batch->setItems($parsed_rows);
+ *
+ * Finally, a processor can work off the information produced on the parsing
+ * stage by consuming items with $batch->shiftItem().
+ *
+ * while ($item = $batch->shiftItem()) {
+ *   $object = $this->map($item);
+ *   $object->save();
+ * }
+ *
+ * Note: Knowledge of the internal structure of a single item in the $items
+ * array is managed by the mapping API specified in FeedsParser class and
+ * FeedsProcessor class.
+ *
+ * @see FeedsFileBatch
+ * @see FeedsHTTPBatch
  */
-class FeedsImportBatch extends FeedsBatch {
-
-  protected $url;
-  protected $file_path;
-  protected $raw;
-  protected $items;
+abstract class FeedsImportBatch extends FeedsBatch {
+  protected $title;
+  protected $description;
   protected $link;
+  protected $items;
 
-  /**
-   * Constructor.
-   *
-   * Either $url or $file_path must be given.
-   */
-  public function __construct($url = NULL, $file_path = NULL) {
-    $this->url = $url;
-    $this->file_path = $file_path;
+  public function __construct() {
+    $this->title = '';
+    $this->description = '';
+    $this->link = '';
     $this->items = array();
-    parent::__construct();
   }
 
   /**
    * @return
-   *   The raw content of the feed.
-   */
-  public function getRaw() {
-    if ($this->file_path) {
-      return file_get_contents(realpath($this->file_path));
-    }
-    elseif ($this->url) {
-      feeds_include_library('http_request.inc', 'http_request');
-      $result = http_request_get($this->url);
-      if ($result->code != 200) {
-        throw new Exception(t('Download of @url failed with code !code.', array('@url' => $this->url, '!code' => $result->code)));
-      }
-      return $result->data;
-    }
-  }
-
-  /**
-   * @return
-   *   Path to the feed. This path is relative to Drupal's root directory.
-   *   If the feed is not local, getFilePath downloads it to file directory.
+   *   The raw content from the source as a string.
+   *
+   * @throws Exception
+   *   If an unexpected problem occurred.
    */
-  public function getFilePath() {
-    if (!isset($this->file_path)) {
-      $dest = file_destination(file_directory_path() .'/feeds/'. get_class($this) .'_'. md5($this->url) .'_'. time(), FILE_EXISTS_RENAME);
-      $this->file_path = file_save_data($this->getRaw(), $dest);
-      if($this->file_path === 0) {
-        throw new Exception(t('Cannot write content to %dest', array('%dest' => $dest)));
-      }
-    }
-    return $this->file_path;
-  }
+  public abstract function getRaw();
 
   /**
    * @return
-   *   URL to the document.
+   *   A path to a file containing the raw content as a source.
+   *
+   * @throws Exception
+   *   If an unexpected problem occurred.
    */
-  public function getURL() {
-    if (!isset($this->url) && isset($this->file)) {
-      return $_GLOBALS['base_url'] .'/'. $this->file;
-    }
-  }
+  public abstract function getFilePath();
 
   /**
    * @return
@@ -113,7 +107,7 @@ class FeedsImportBatch extends FeedsBatch {
    *   feed). Falls back to URL if not available.
    */
   public function getLink() {
-    return isset($this->link) ? $this->link : $this->getURL();
+    return $this->link;
   }
 
   /**
diff --git a/plugins/FeedsFileFetcher.inc b/plugins/FeedsFileFetcher.inc
index 951fa81c957d12375608d937052ca184c58a7b6d..8f1af798005d40b9c7775273d3c17feb9c42eeac 100644
--- a/plugins/FeedsFileFetcher.inc
+++ b/plugins/FeedsFileFetcher.inc
@@ -3,9 +3,39 @@
 
 /**
  * @file
- * Home of the FeedsFileFetcher.
+ * Home of the FeedsFileFetcher and related classes.
  */
 
+/**
+ * Definition of the import batch object created on the fetching stage by
+ * FeedsFileFetcher.
+ */
+class FeedsFileBatch extends FeedsImportBatch {
+  protected $file_path;
+
+  /**
+   * Constructor.
+   */
+  public function __construct($file_path) {
+    $this->file_path = $file_path;
+    parent::__construct();
+  }
+
+  /**
+   * Implementation of FeedsImportBatch::getRaw();
+   */
+  public function getRaw() {
+    return file_get_contents(realpath($this->file_path));
+  }
+
+  /**
+   * Implementation of FeedsImportBatch::getFilePath().
+   */
+  public function getFilePath() {
+    return $this->file_path;
+  }
+}
+
 /**
  * Fetches data via HTTP.
  */
@@ -16,7 +46,7 @@ class FeedsFileFetcher extends FeedsFetcher {
    */
   public function fetch(FeedsSource $source) {
     $source_config = $source->getConfigFor($this);
-    return new FeedsImportBatch(NULL, $source_config['source']);
+    return new FeedsFileBatch($source_config['source']);
   }
 
   /**
diff --git a/plugins/FeedsHTTPFetcher.inc b/plugins/FeedsHTTPFetcher.inc
index dda77f9677ae5fcd50953e10a472090e1fcbdbeb..0467ca6466213731ad2b201d983cff664bbe77b5 100644
--- a/plugins/FeedsHTTPFetcher.inc
+++ b/plugins/FeedsHTTPFetcher.inc
@@ -3,9 +3,52 @@
 
 /**
  * @file
- * Home of the FeedsHTTPFetcher.
+ * Home of the FeedsHTTPFetcher and related classes.
  */
 
+/**
+ * Definition of the import batch object created on the fetching stage by
+ * FeedsHTTPFetcher.
+ */
+class FeedsHTTPBatch extends FeedsImportBatch {
+  protected $url;
+  protected $file_path;
+
+  /**
+   * Constructor.
+   */
+  public function __construct($url = NULL) {
+    $this->url = $url;
+    parent::__construct();
+  }
+
+  /**
+   * Implementation of FeedsImportBatch::getRaw();
+   */
+  public function getRaw() {
+    feeds_include_library('http_request.inc', 'http_request');
+    $result = http_request_get($this->url);
+    if ($result->code != 200) {
+      throw new Exception(t('Download of @url failed with code !code.', array('@url' => $this->url, '!code' => $result->code)));
+    }
+    return $result->data;
+  }
+
+  /**
+   * Implementation of FeedsImportBatch::getFilePath().
+   */
+  public function getFilePath() {
+    if (!isset($this->file_path)) {
+      $dest = file_destination(file_directory_path() .'/feeds/'. get_class($this) .'_'. md5($this->url) .'_'. time(), FILE_EXISTS_RENAME);
+      $this->file_path = file_save_data($this->getRaw(), $dest);
+      if($this->file_path === 0) {
+        throw new Exception(t('Cannot write content to %dest', array('%dest' => $dest)));
+      }
+    }
+    return $this->file_path;
+  }
+}
+
 /**
  * Fetches data via HTTP.
  */
@@ -16,7 +59,7 @@ class FeedsHTTPFetcher extends FeedsFetcher {
    */
   public function fetch(FeedsSource $source) {
     $source_config = $source->getConfigFor($this);
-    return new FeedsImportBatch($source_config['source']);
+    return new FeedsHTTPBatch($source_config['source']);
   }
 
   /**