diff --git a/salesforce_api/salesforce_api.module b/salesforce_api/salesforce_api.module
index ca6c20b..df0fafd 100644
--- a/salesforce_api/salesforce_api.module
+++ b/salesforce_api/salesforce_api.module
@@ -997,8 +997,8 @@ function salesforce_api_fieldmap_export_create($name, $drupal_data = NULL) {
 
     // Don't try to update or create fields to which those actions do not apply.
     if ((!$updateable && !$createable)
-      || (empty($drupal_data->salesforce->sfid) && !$createable)
-      || (!empty($drupal_data->salesforce->sfid) && !$updateable)) {
+      || (empty($drupal_data->salesforce[$name]->sfid) && !$createable)
+      || (!empty($drupal_data->salesforce[$name]->sfid) && !$updateable)) {
       continue;
     }
     // See if it's a special field
@@ -1188,10 +1188,10 @@ function salesforce_api_id_load($oid, $entity_name, $bundle_name = NULL) {
   else {
     $result = db_query("SELECT sfid, name FROM {salesforce_object_map} WHERE drupal_entity = :drupal_entity AND drupal_bundle = :drupal_bundle AND oid = :oid", array(':drupal_entity' => $entity_name, 'drupal_bundle' => $bundle_name, ':oid' => $oid));
   }
-  $data = $result->fetchObject();
+  $data = $result->fetchAllAssoc('name');
   // Return an empty array if no data was found.
   if (!$data) {
-    return (object) array('sfid' => NULL, 'name' => NULL);
+    return FALSE;
   }
   else {
     // Otherwise return the Salesforce object type and ID.
@@ -1361,6 +1361,49 @@ function salesforce_api_search_for_duplicates($direction, $entity_name, $bundle_
 }
 
 /**
+ * Retrieve matching object ids before creating a new object. This hook is 
+ * designed to eliminate creation of duplicate objects if so desired. For 
+ * example, an implementation of sf_user_sf_find_match might query Salesforce
+ * for Ids matching the user's email address before creating a new Contact.
+ *
+ * In the core Suite, this hook is implemented by the optional sf_match module.
+ *
+ * IMPORTANT: implementations of this function MUST ensure that matches are not
+ * IDs of deleted records in Salesforce. By default SOQL query() filters out
+ * deleted records, so sf_prematch_sf_find_match() fulfils this requirement.
+ *
+ * @param $direction
+ *  "import" or "export"
+ * @param $entity_name
+ *  "user", "node", etc.
+ * @param $bundle_name
+ *  the name of the bundle to which the entity belongs.
+ *  This is a node type in the case of node entities, or a vocabulary name, or 'user' for users.
+ * @param $entity
+ *  The Drupal entity to be matched, probably $user or $node
+ * @param $fieldmap_id
+ *  The id of the fieldmap being used to import or export the current object.
+ * @return
+ *  'import': an array of matching nid's, uid's, etc.
+ *  'export': an array of matching Salesforce Id's @see IMPORTANT note above.
+ */
+function salesforce_api_sf_find_match($direction, $entity_name, $bundle_name, $entity, $fieldmap_name) {
+  if ($direction == 'export') {
+    if (!empty($entity->salesforce)) {
+			$this_fieldmap = salesforce_api_salesforce_fieldmap_load($fieldmap_name);
+      foreach ($entity->salesforce as $salesforce) {
+        $fieldmap = salesforce_api_salesforce_fieldmap_load($salesforce->name);
+        if ($fieldmap->drupal_entity == $entity_name && $fieldmap->drupal_bundle == $bundle_name && $fieldmap->salesforce == $this_fieldmap->salesforce) {
+          $existent_fieldmap_name = $fieldmap->name;
+          $existent_salesforce = (array)$salesforce;
+          return $entity->salesforce[$existent_fieldmap_name]->sfid;
+        }
+      }
+    }
+  }
+}
+
+/**
  * Implements hook_theme().
  *
  * Registers theme callback for admin screen
diff --git a/sf_entity/sf_entity.module b/sf_entity/sf_entity.module
index cfbeaf7..08f51c7 100644
--- a/sf_entity/sf_entity.module
+++ b/sf_entity/sf_entity.module
@@ -124,31 +124,9 @@ function sf_entity_save($entity, $type, $op) {
   // If this is an update, and the node already has a Salesforce mapping,
   // try to load it. If the load fails, we need to fetch the appropriate
   // fieldmap. Either way, we're upserting the Salesforce record.
-  $salesforce = (object) array('name' => NULL, 'sfid' => NULL);
   list($oid, $vid, $bundle) = entity_extract_ids($type, $entity);
-  if ($oid) {
-    $salesforce = salesforce_api_id_load($oid, $type, $bundle);
-  }
-
-  // If we have an existing link, attempt to load the associated map.
-  if (!empty($salesforce->name)) {
-    $map = salesforce_api_salesforce_fieldmap_load($salesforce->name);
-  }
-
-  // If the Salesforce link wasn't found, or if it was found but associated to a
-  // non-existent map, load any maps associated with this entity type.
-  // @todo: Determine why this isn't loading maps that should be there.
-  if (empty($salesforce->name) || empty($map)) {
-    $maps = salesforce_api_salesforce_fieldmap_load_by(array('drupal_entity' => $type, 'drupal_bundle' => $bundle));
-    if (empty($maps)) {
-      return;
-    }
-  }
-  // Otherwise, assign the single map as an array so we only have to write
-  // the preceding logic once.
-  else {
-    $maps = array($map->name => $map);
-  }
+  
+  $maps = salesforce_api_salesforce_fieldmap_load_by(array('drupal_entity' => $type, 'drupal_bundle' => $bundle));
 
   foreach ($maps as $map) {
     $auto_create = $map->automatic & SALESFORCE_AUTO_SYNC_CREATE;
@@ -156,33 +134,26 @@ function sf_entity_save($entity, $type, $op) {
     if ((!$auto_create && $op == 'insert')
           || (!$auto_update && $op == 'update')) {
       unset($maps[$map->name]);
+    } else {
+      // Check if there is more than one fieldmap in the result.
+      // @todo: Is it necessary to use AND instead of &&
+      if (user_access('administer salesforce') AND next($maps)) {
+        if (!empty($map->description)) {
+          $description = '(' . $map->description . ')';
+        }
+        drupal_set_message(t('Warning: more than one "automatic" salesforce mapping detected. Used fieldmap !map_name @map_description.', array('!map_name' => l($map->name, SALESFORCE_PATH_FIELDMAPS . '/' . $map->name . '/edit'), '@map_description' => $description)), 'warning');
+      }
+      
+      $sfid = isset($entity->salesforce[$map->name]->sfid) ? $entity->salesforce[$map->name]->sfid : NULL;
+    
+      // Finally, export the entity to Salesforce.
+      try {
+        sf_entity_export($entity, $map->name, $sfid);
+      } catch (Exception $e) {
+        salesforce_api_log(SALESFORCE_LOG_SOME, 'Exception while attempting to export entity: ' . $e->getMessage(), array(), WATCHDOG_ERROR, l('view', entity_uri($type, $entity)));
+      }
     }
   }
-
-  // If all our maps were unset, abort this procedure.
-  if (empty($maps)) {
-    return;
-  }
-
-  // Otherwise, use the first fieldmap.
-  $map = reset($maps);
-  $salesforce->name = $map->name;
-
-  // Check if there is more than one fieldmap in the result.
-  // @todo: Is it necessary to use AND instead of &&
-  if (user_access('administer salesforce') AND next($maps)) {
-    if (!empty($map->description)) {
-      $description = '(' . $map->description . ')';
-    }
-    drupal_set_message(t('Warning: more than one "automatic" salesforce mapping detected. Used fieldmap !map_name @map_description.', array('!map_name' => l($map->name, SALESFORCE_PATH_FIELDMAPS . '/' . $map->name . '/edit'), '@map_description' => $description)), 'warning');
-  }
-
-  // Finally, export the entity to Salesforce.
-  try {
-    sf_entity_export($entity, $salesforce->name, $salesforce->sfid);
-  } catch (Exception $e) {
-    salesforce_api_log(SALESFORCE_LOG_SOME, 'Exception while attempting to export entity: ' . $e->getMessage(), array(), WATCHDOG_ERROR, l('view', entity_uri($type, $entity)));
-  }
 }
 
 /**
@@ -447,32 +418,36 @@ function sf_entity_salesforce_form($form, &$form_state, $entity_type, $entity) {
     '#type' => 'value',
     '#value' => array($oid, $vid, $bundle),
   );
-
-  if ($entity->salesforce->sfid) {
-    // Retrieve the object from Salesforce.
-    $sf_data = salesforce_api_retrieve(array($entity->salesforce->sfid), $entity->salesforce->name);
-    // Check to see if sf_data is an array of objects
-    if (is_array($sf_data) && count($sf_data) > 0) {
-      $sf_data = $sf_data[0];
-    }
-    // If $sf_data is empty, we assume the record is deleted. retrieve() does
-    // not return the ENTITY_IS_DELETED error that upsert() does.
-    if (!$sf_data && SALESFORCE_DELETED_POLICY_UPSERT == variable_get('salesforce_api_entity_deleted_policy', SALESFORCE_DELETED_POLICY_UPSERT)) {
-      drupal_set_message(t('Unable to retrieve Salesforce data for record !sfid. Drupal and Salesforce records have been unlinked.', array('!sfid' => $entity->salesforce->sfid)), 'warning');
-      // Unlink the object and reload the entity, resetting the cache
-      salesforce_api_id_unlink(array('oid' => $oid, 'name' => $entity->salesforce->name));
-      $entity = entity_load($entity_type, array($oid), array(), TRUE);
-    }
-    elseif (!$sf_data) {
-      drupal_set_message(t('Unable to retrieve Salesforce data for record !sfid.', array('!sfid' => $entity->salesforce->sfid)), 'warning');
+  
+  
+  if (isset($entity->salesforce) && !empty($entity->salesforce)) {
+    foreach ($entity->salesforce as $salesforce) {
+      if ($salesforce->sfid) {
+        // Retrieve the object from Salesforce.
+        $sf_data = salesforce_api_retrieve(array($salesforce->sfid), $salesforce->name);
+        // Check to see if sf_data is an array of objects
+        if (is_array($sf_data) && count($sf_data) > 0) {
+          $sf_data = $sf_data[0];
+        }
+        // If $sf_data is empty, we assume the record is deleted. retrieve() does
+        // not return the ENTITY_IS_DELETED error that upsert() does.
+        if (!$sf_data && SALESFORCE_DELETED_POLICY_UPSERT == variable_get('salesforce_api_entity_deleted_policy', SALESFORCE_DELETED_POLICY_UPSERT)) {
+          drupal_set_message(t('Unable to retrieve Salesforce data for record !sfid. Drupal and Salesforce records have been unlinked.', array('!sfid' => $salesforce->sfid)), 'warning');
+          // Unlink the object and reload the entity, resetting the cache
+          salesforce_api_id_unlink(array('oid' => $oid, 'name' => $salesforce->name));
+          $entity = entity_load($entity_type, array($oid), array(), TRUE);
+        }
+        elseif (!$sf_data) {
+          drupal_set_message(t('Unable to retrieve Salesforce data for record !sfid.', array('!sfid' => $salesforce->sfid)), 'warning');
+        }
+      }
     }
   }
 
   $options = salesforce_api_fieldmap_options($entity_type, $bundle);
   // Display an export button if the entity hasn't been exported before,
   // or doesn't currently have a linked object in Salesforce.
-  if (isset($entity->salesforce->sfid) && empty($entity->salesforce->sfid) ||
-      !isset($entity->salesforce->sfid)) {
+  if (!isset($entity->salesforce) || empty($entity->salesforce)) {
       $form['export'] = array(
         '#type' => 'fieldset',
         '#title' => t('Export to Salesforce'),
@@ -516,115 +491,118 @@ function sf_entity_salesforce_form($form, &$form_state, $entity_type, $entity) {
         );
     }
   }
-  elseif(isset($entity->salesforce->sfid) && !empty($entity->salesforce->sfid)) {
-    // Otherwise add synchronization information.
-    $form['sfid'] = array(
-      '#type' => 'value',
-      '#value' => $entity->salesforce->sfid,
-    );
-    $form['fieldmap'] = array(
-      '#type' => 'value',
-      '#value' => $entity->salesforce->name,
-    );
-
-    // Load the fieldmap data.
-    $map = salesforce_api_salesforce_fieldmap_load($entity->salesforce->name);
-    $sf_object_definition = salesforce_api_fieldmap_objects_load('salesforce', 'salesforce', $map->salesforce);
-    $export_data = salesforce_api_fieldmap_export_create($entity->salesforce->name, $entity);
-
-    $header = array(t('Field name'), t('Drupal @type value', array('@type' => salesforce_api_fieldmap_object_label('drupal', $map->drupal_entity, $map->drupal_bundle))), t('Salesforce @type value', array('@type' => salesforce_api_fieldmap_object_label('salesforce', 'salesforce', $map->salesforce))));
-    $rows = array();
-
-    foreach ($map->fields as $sf_fieldname => $drupal_fieldname) {
-      $row = array();
-      $row[] = $sf_object_definition['fields'][$sf_fieldname]['label'];
-      $row[] = isset($export_data->$sf_fieldname)
-        ? $export_data->$sf_fieldname : '&nbsp;';
-      $row[] = isset($sf_data->$sf_fieldname)
-        ? $sf_data->$sf_fieldname : '&nbsp;';
-      $rows[] = $row;
-    }
-
-    $form['mapped'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Mapped field values'),
-      '#description' => t('These fields have been mapped through fieldmap <a href="!url">@index</a>.', array('!url' => url(SALESFORCE_PATH_FIELDMAPS . '/' . $entity->salesforce->name . '/edit'), '@index' => $entity->salesforce->name)),
-    );
-    $form['mapped']['fieldmap_values'] = array(
-      '#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
-    );
-
-    $form['mapped']['export_values'] = array(
-      '#type' => 'submit',
-      '#value' => t('Export'),
-      '#attributes' => array('class' => array('sf-confirm')),
-    );
-    $form['mapped']['import_values'] = array(
-      '#type' => 'submit',
-      '#value' => t('Import'),
-      '#attributes' => array('class' => array('sf-confirm')),
-    );
-    $form['mapped']['unlink'] = array(
-      '#type' => 'submit',
-      '#value' => t('Unlink from Salesforce object...'),
-      '#attributes' => array('class' => array('sf-confirm')),
-    );
-
-    // Create a table for the unmapped fields.
-    $header = array(t('Field name'), t('Salesforce @type value', array('@type' => salesforce_api_fieldmap_object_label('salesforce', 'salesforce', $map->salesforce))));
-    $rows = array();
-
-    foreach ((array) $sf_data as $key => $value) {
-      if (!isset($map->fields[$key]) && isset($sf_object_definition['fields'][$key])) {
+//  elseif(isset($entity->salesforce->sfid) && !empty($entity->salesforce->sfid)) {
+  else {
+    foreach ($entity->salesforce as $salesforce) {
+      // Otherwise add synchronization information.
+      $form['sfid'] = array(
+        '#type' => 'value',
+        '#value' => $salesforce->sfid,
+      );
+      $form['fieldmap'] = array(
+        '#type' => 'value',
+        '#value' => $salesforce->name,
+      );
+  
+      // Load the fieldmap data.
+      $map = salesforce_api_salesforce_fieldmap_load($salesforce->name);
+      $sf_object_definition = salesforce_api_fieldmap_objects_load('salesforce', 'salesforce', $map->salesforce);
+      $export_data = salesforce_api_fieldmap_export_create($salesforce->name, $entity);
+  
+      $header = array(t('Field name'), t('Drupal @type value', array('@type' => salesforce_api_fieldmap_object_label('drupal', $map->drupal_entity, $map->drupal_bundle))), t('Salesforce @type value', array('@type' => salesforce_api_fieldmap_object_label('salesforce', 'salesforce', $map->salesforce))));
+      $rows = array();
+  
+      foreach ($map->fields as $sf_fieldname => $drupal_fieldname) {
+        $row = array();
+        $row[] = $sf_object_definition['fields'][$sf_fieldname]['label'];
+        $row[] = isset($export_data->$sf_fieldname)
+          ? $export_data->$sf_fieldname : '&nbsp;';
+        $row[] = isset($sf_data->$sf_fieldname)
+          ? $sf_data->$sf_fieldname : '&nbsp;';
+        $rows[] = $row;
+      }
+  
+      $form['mapped'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Mapped field values'),
+        '#description' => t('These fields have been mapped through fieldmap <a href="!url">@index</a>.', array('!url' => url(SALESFORCE_PATH_FIELDMAPS . '/' . $salesforce->name . '/edit'), '@index' => $salesforce->name)),
+      );
+      $form['mapped']['fieldmap_values'] = array(
+        '#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
+      );
+  
+      $form['mapped']['export_values'] = array(
+        '#type' => 'submit',
+        '#value' => t('Export'),
+        '#attributes' => array('class' => array('sf-confirm')),
+      );
+      $form['mapped']['import_values'] = array(
+        '#type' => 'submit',
+        '#value' => t('Import'),
+        '#attributes' => array('class' => array('sf-confirm')),
+      );
+      $form['mapped']['unlink'] = array(
+        '#type' => 'submit',
+        '#value' => t('Unlink from Salesforce object...'),
+        '#attributes' => array('class' => array('sf-confirm')),
+      );
+  
+      // Create a table for the unmapped fields.
+      $header = array(t('Field name'), t('Salesforce @type value', array('@type' => salesforce_api_fieldmap_object_label('salesforce', 'salesforce', $map->salesforce))));
+      $rows = array();
+  
+      foreach ((array) $sf_data as $key => $value) {
+        if (!isset($map->fields[$key]) && isset($sf_object_definition['fields'][$key])) {
+          $rows[] = array(
+            $sf_object_definition['fields'][$key]['label'],
+            $value,
+          );
+        }
+      }
+  
+      if (count($rows) > 0) {
+        $form['unmapped'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Unmapped fields'),
+          '#description' => t('These fields are available on Salesforce but are not currently mapped through the fieldmap used for this @entity.', array('@entity' => strtolower($info['label']))),
+          '#collapsible' => TRUE,
+          '#collapsed' => TRUE,
+        );
+        $form['unmapped']['unmapped_fields'] = array(
+          '#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
+        );
+      }
+  
+      $rows = array();
+  
+      foreach (salesforce_api_fieldmap_system_fields() as $key => $value) {
         $rows[] = array(
-          $sf_object_definition['fields'][$key]['label'],
-          $value,
+          $value['label'],
+          $sf_data->$key,
         );
       }
-    }
-
-    if (count($rows) > 0) {
-      $form['unmapped'] = array(
+  
+      $form['system'] = array(
         '#type' => 'fieldset',
-        '#title' => t('Unmapped fields'),
-        '#description' => t('These fields are available on Salesforce but are not currently mapped through the fieldmap used for this @entity.', array('@entity' => strtolower($info['label']))),
+        '#title' => t('System fields'),
+        '#description' => t('These fields provide additional system information about the Salesforce object but cannot be exported to Salesforce.'),
         '#collapsible' => TRUE,
         '#collapsed' => TRUE,
       );
-      $form['unmapped']['unmapped_fields'] = array(
+      $form['system']['system_fields'] = array(
         '#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
       );
-    }
-
-    $rows = array();
-
-    foreach (salesforce_api_fieldmap_system_fields() as $key => $value) {
-      $rows[] = array(
-        $value['label'],
-        $sf_data->$key,
+  
+      $form['raw'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Raw data'),
+        '#collapsible' => TRUE,
+        '#collapsed' => TRUE,
+      );
+      $form['raw']['data'] = array(
+        '#markup' => '<pre>' . print_r($sf_data, TRUE) . '</pre>',
       );
     }
-
-    $form['system'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('System fields'),
-      '#description' => t('These fields provide additional system information about the Salesforce object but cannot be exported to Salesforce.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form['system']['system_fields'] = array(
-      '#markup' => theme('table', array('header' => $header, 'rows' => $rows)),
-    );
-
-    $form['raw'] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Raw data'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
-    );
-    $form['raw']['data'] = array(
-      '#markup' => '<pre>' . print_r($sf_data, TRUE) . '</pre>',
-    );
   }
 
   return $form;
@@ -722,7 +700,7 @@ function sf_entity_export($entity, $name, $sfid = NULL) {
     $matches = salesforce_api_search_for_duplicates('export', $map->drupal_entity, $map->drupal_bundle, $entity, $name);
     if (!empty($matches)) {
       $sfid = reset($matches);
-      $entity->salesforce->sfid = $sfid;
+      $entity->salesforce[$name]->sfid = $sfid;
       salesforce_api_id_save($id, $sfid, $name, $map->drupal_entity, $map->drupal_bundle);
       $entity = entity_load($map->drupal_entity, array($id), array(), TRUE);
     }
@@ -771,7 +749,7 @@ function sf_entity_export($entity, $name, $sfid = NULL) {
       && SALESFORCE_DELETED_POLICY_UPSERT == variable_get('salesforce_api_entity_deleted_policy', SALESFORCE_DELETED_POLICY_UPSERT)) {
       // If the entity is deleted, unlink ALL the linked drupal objects.
       salesforce_api_id_unlink(array('sfid' => $object->Id));
-      $entity->salesforce->sfid = $object->Id = NULL;
+      $entity->salesforce[$name]->sfid = $object->Id = NULL;
 
       // Look for any matching records which we might want to update instead of
       // creating duplicates. Assume that salesforce_api_search_for_duplicates()
@@ -779,7 +757,7 @@ function sf_entity_export($entity, $name, $sfid = NULL) {
       $matches = salesforce_api_search_for_duplicates('export', $map->drupal_entity, $map->drupal_bundle, $entity, $name);
       if (!empty($matches)) {
         $sfid = reset($matches);
-        $entity->salesforce->sfid = $sfid;
+        $entity->salesforcep[$name]->sfid = $sfid;
       }
 
       salesforce_api_log(SALESFORCE_LOG_SOME, 'Salesforce record deleted. Attempting to unlink and upsert. <pre>%response</pre>',
@@ -993,7 +971,7 @@ function sf_entity_import($sf_data, $name, $id = NULL, $options = array()) {
         || (($map->automatic & SALESFORCE_AUTO_SYNC_UPDATE) && !$create)
         || (!empty($options['extra-linked']) && $options['extra-linked'] == TRUE)) {
       // Store the Salesforce ID for the entity and return TRUE.
-      salesforce_api_id_save($id, $entity->salesforce->sfid, $name, $map->drupal_entity, $map->drupal_bundle);
+      salesforce_api_id_save($id, $entity->salesforce[$name]->sfid, $name, $map->drupal_entity, $map->drupal_bundle);
     }
   }
   // Allow modules to respond after an import.
