diff --git a/plugins/feeds/UCFeedsProductProcessor.inc b/plugins/feeds/UCFeedsProductProcessor.inc
new file mode 100644
index 0000000..2a3a78a
--- /dev/null
+++ b/plugins/feeds/UCFeedsProductProcessor.inc
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * Ubercart Feeds Product Processor 
+ */
+class UCFeedsProductProcessor extends FeedsNodeProcessor {
+
+  /**
+   * Override parent::configForm().
+   * Only allow Ubercart product node types.
+   */
+  public function configForm(&$form_state) {
+    $types = uc_product_types();
+    foreach ($types as $t) {
+    	$options[$t] = $t;
+    }
+    $form = parent::configForm($form_state);
+    $form['content_type']['#options'] = $options;
+    return $form;
+  }
+
+  /**
+   * Override parent::getMappingTargets().
+   * Provide Ubercart product targets.
+   */
+  public function getMappingTargets() {
+  	$targets = parent::getMappingTargets();
+    // Model
+    $targets['uc_product:model'] = array(
+      'name' => t('UC: Model/SKU'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Model/SKU'))),
+      'optional_unique' => TRUE,
+    );
+    // List price
+    $targets['uc_product:list_price'] = array(
+      'name' => t('UC: List price'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('List price'))),
+    );
+    // Cost
+    $targets['uc_product:cost'] = array(
+      'name' => t('UC: Cost'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Cost'))),
+    );
+    // Sell price
+    $targets['uc_product:sell_price'] = array(
+      'name' => t('UC: Sell price'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Sell price'))),
+    );
+    // Weight
+    $targets['uc_product:weight'] = array(
+      'name' => t('UC: Weight'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Weight'))),
+    );
+    $targets['uc_product:weight_units'] = array(
+      'name' => t('UC: Weight Unit'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Weight Unit'))),
+    );
+    // Dims
+    $targets['uc_product:length'] = array(
+      'name' => t('UC: Length'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Length'))),
+    );
+    $targets['uc_product:width'] = array(
+      'name' => t('UC: Width'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Width'))),
+    );
+    $targets['uc_product:height'] = array(
+      'name' => t('UC: Height'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Height'))),
+    );
+    $targets['uc_product:length_units'] = array(
+      'name' => t('UC: Dimension Units'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Dimension Units'))),
+    );
+    $targets['uc_product:pkg_qty'] = array(
+      'name' => t('UC: Package Quantity'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Package Quantity'))),
+    );
+    $targets['uc_product:default_qty'] = array(
+      'name' => t('UC: Default Quantity'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Default Quantity to add to cart'))),
+    );
+    // Shippable
+    $targets['uc_product:shippable'] = array(
+      'name' => t('UC: Shippable'),
+      'callback' => 'uc_feeds_feeds_set_target',
+      'description' => t('Ubercart: !mapper', array('!mapper' => t('Shippable'))),
+    );    
+    // Stock
+    if (module_exists('uc_stock')) {
+      $targets['uc_stock:stock'] = array(
+        'name' => t('UC: Stock Level'),
+        'callback' => 'uc_feeds_feeds_set_target',
+        'description' => t('Ubercart: !mapper', array('!mapper' => t('Stock'))),
+      );
+    }
+    // TODO : Price By Role, others?
+    // Need new patches
+
+    // Attributes
+    if (module_exists('uc_attribute') && function_exists('uc_attribute_load_multiple')) {
+      $attribs = uc_attribute_load_multiple();
+      foreach ($attribs as $attrib) {
+        $aid = $attrib->aid;
+        foreach ($attrib->options as $option) {
+          $oid = $option->oid;
+          $targets['uc_attribute:attribute_price_' . $aid . '_' . $oid] = array(
+            'name' => t('UCA Price: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name)),
+            'callback' => 'uc_feeds_feeds_set_target',
+            'description' => t('Ubercart: !mapper', array(
+                '!mapper' => t('Attribute Price: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name))
+              )
+            ),
+          );
+        }
+      }
+      foreach ($attribs as $attrib) {
+        $aid = $attrib->aid;
+        foreach ($attrib->options as $option) {
+          $oid = $option->oid;
+          $targets['uc_attribute:attribute_weight_' . $aid . '_' . $oid] = array(
+            'name' => t('UCA Weight: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name)),
+            'callback' => 'uc_feeds_feeds_set_target',
+            'description' => t('Ubercart: !mapper', array(
+                '!mapper' => t('Attribute Weight: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name))
+              )
+            ),
+          );
+        }
+      }
+    }
+    return $targets;
+  }
+
+  /**
+   * Override parent::existingItemId().
+   * Check to see if a product exists based on its model.
+   */
+  protected function existingItemId(FeedsImportBatch $batch, FeedsSource $source) {
+
+    // Execute the parent method first.
+    $nid = parent::existingItemId($batch, $source);
+
+    // If a node id wasn't found, try the unique model target.
+    if (empty($nid)) {
+      foreach ($this->uniqueTargets($batch) as $target => $value) {
+        switch ($target) {
+          case 'uc_product:model':
+            $nid = db_result(db_query("SELECT nid FROM {uc_products} WHERE model = '%s'", $value));
+            break;
+        }
+      }
+    }
+
+    // If the node id is still empty, set it to 0.
+    if (empty($nid)) {
+      $nid = 0;
+    }
+
+    // Return the node id.
+    return $nid;
+  }
+
+  /**
+   * Override parent::buildNode().
+   * Set a flag on the node so others can look for it in hook_nodeapi().
+   *   The flag is: $node->uc_feeds_import = TRUE;
+   */
+  protected function buildNode($nid, $feed_nid) {
+    $node = parent::buildNode($nid, $feed_nid);
+    $node->uc_feeds_import = TRUE;
+    return $node;
+  }
+}
+
diff --git a/uc_feeds.module b/uc_feeds.module
index 4fabd7d..90ea563 100644
--- a/uc_feeds.module
+++ b/uc_feeds.module
@@ -5,130 +5,21 @@
  */
 
 /**
- * Implementation of hook_feeds_node_processor_targets_alter().
- * @param array $targets
- * @param string $content_type
- * @return void
- */
-function uc_feeds_feeds_node_processor_targets_alter(&$targets, $content_type) {
-  // Proceed only if the content_type is a product type.
-  if (in_array($content_type, uc_product_types())) {
-    // Model
-    $targets['uc_product:model'] = array(
-      'name' => t('UC: Model/SKU'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Model/SKU'))),
-    );
-    // List price
-    $targets['uc_product:list_price'] = array(
-      'name' => t('UC: List price'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('List price'))),
-    );
-    // Cost
-    $targets['uc_product:cost'] = array(
-      'name' => t('UC: Cost'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Cost'))),
-    );
-    // Sell price
-    $targets['uc_product:sell_price'] = array(
-      'name' => t('UC: Sell price'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Sell price'))),
-    );
-    // Weight
-    $targets['uc_product:weight'] = array(
-      'name' => t('UC: Weight'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Weight'))),
-    );
-    $targets['uc_product:weight_units'] = array(
-      'name' => t('UC: Weight Unit'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Weight Unit'))),
-    );
-    // Dims
-    $targets['uc_product:length'] = array(
-      'name' => t('UC: Length'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Length'))),
-    );
-    $targets['uc_product:width'] = array(
-      'name' => t('UC: Width'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Width'))),
-    );
-    $targets['uc_product:height'] = array(
-      'name' => t('UC: Height'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Height'))),
-    );
-    $targets['uc_product:length_units'] = array(
-      'name' => t('UC: Dimension Units'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Dimension Units'))),
-    );
-    $targets['uc_product:pkg_qty'] = array(
-      'name' => t('UC: pkg_qty'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Package Quantity'))),
-    );
-    $targets['uc_product:default_qty'] = array(
-      'name' => t('UC: default_qty'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Default Quantity to add to cart'))),
-    );
-    // Shippable
-    $targets['uc_product:shippable'] = array(
-      'name' => t('UC: Shippable'),
-      'callback' => 'uc_feeds_feeds_set_target',
-      'description' => t('Ubercart: !mapper', array('!mapper' => t('Shippable'))),
-    );    
-    // Stock
-    if (module_exists('uc_stock')) {
-      $targets['uc_stock:stock'] = array(
-        'name' => t('UC: Stock Level'),
-        'callback' => 'uc_feeds_feeds_set_target',
-        'description' => t('Ubercart: !mapper', array('!mapper' => t('Stock'))),
-      );
-    }
-    // TODO : Price By Role, others?
-    // Need new patches
-
-    // Attributes
-    if (module_exists('uc_attribute') && function_exists('uc_attribute_load_multiple')) {
-      $attribs = uc_attribute_load_multiple();
-      foreach ($attribs as $attrib) {
-        $aid = $attrib->aid;
-        foreach ($attrib->options as $option) {
-          $oid = $option->oid;
-          $targets['uc_attribute:attribute_price_' . $aid . '_' . $oid] = array(
-            'name' => t('UCA Price: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name)),
-            'callback' => 'uc_feeds_feeds_set_target',
-            'description' => t('Ubercart: !mapper', array(
-                '!mapper' => t('Attribute Price: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name))
-              )
-            ),
-          );
-        }
-      }
-      foreach ($attribs as $attrib) {
-        $aid = $attrib->aid;
-        foreach ($attrib->options as $option) {
-          $oid = $option->oid;
-          $targets['uc_attribute:attribute_weight_' . $aid . '_' . $oid] = array(
-            'name' => t('UCA Weight: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name)),
-            'callback' => 'uc_feeds_feeds_set_target',
-            'description' => t('Ubercart: !mapper', array(
-                '!mapper' => t('Attribute Weight: @attribute:@option', array('@attribute' => $attrib->name, '@option' => $option->name))
-              )
-            ),
-          );
-        }
-      }
-    }
-  }
+* Implementation of hook_feeds_plugins().
+*/
+function uc_feeds_feeds_plugins() {
+  $info = array();
+  $info['UCFeedsProductProcessor'] = array(
+    'name' => 'Ubercart Product Processor',
+    'description' => 'Create and update Ubercart product nodes from parsed content.',
+    'handler' => array(
+      'parent' => 'FeedsNodeProcessor', // A plugin needs to derive either directly or indirectly from FeedsFetcher, FeedsParser or FeedsProcessor.
+      'class' => 'UCFeedsProductProcessor',
+      'file' => 'UCFeedsProductProcessor.inc',
+      'path' => drupal_get_path('module', 'uc_feeds') . '/plugins/feeds',
+    ),
+  );
+  return $info;
 }
 
 /**
