Index: sf_node/sf_node.module
===================================================================
RCS file: /cvs/salesforce/sf_node/sf_node.module,v
retrieving revision 1.2
diff -u -r1.2 sf_node.module
--- sf_node/sf_node.module	30 Jun 2009 08:46:13 -0000	1.2
+++ sf_node/sf_node.module	2 Jul 2009 01:11:44 -0000
@@ -484,6 +484,18 @@
 
   // Load the fieldmap so we can get the object name.
   $map = salesforce_api_fieldmap_load($fieldmap);
+  
+  $prematch_found = false;
+  if (empty($sfid)) {
+    // call hook_sf_find_match to give opportunity to try to match existing sf object instead
+    // of creating a new one.
+    $matches = module_invoke_all('sf_find_match', 'export', 'node', $node, $map);
+    // TODO: handle case where multiple implementers of hook return multiple results.
+    if (count($matches)) {
+      $sfid = $matches[0];
+      $prematch_found = true;
+    }
+  }
 
   if (empty($sfid)) {
     // Export the object to Salesforce.
@@ -497,7 +509,8 @@
 
   // If the export was successful...
   if ($response->success) {
-    if (empty($sfid)) {
+    // If this is the first time this drupal object has been exported...
+    if (empty($sfid) || $prematch_found) {
       // Store the Salesforce ID for the node and return TRUE.
       salesforce_api_id_save('node', $node->nid, $response->id, $fieldmap);
     }
Index: sf_user/sf_user.module
===================================================================
RCS file: /cvs/salesforce/sf_user/sf_user.module,v
retrieving revision 1.2
diff -u -r1.2 sf_user.module
--- sf_user/sf_user.module	30 Jun 2009 08:46:13 -0000	1.2
+++ sf_user/sf_user.module	2 Jul 2009 01:14:53 -0000
@@ -334,6 +334,18 @@
 
   // Load the fieldmap so we can get the object name.
   $map = salesforce_api_fieldmap_load($fieldmap);
+  
+  $prematch_found = false;
+  if (empty($sfid)) {
+    // call hook_sf_find_match to give opportunity to try to match existing sf object instead
+    // of creating a new one.
+    $matches = module_invoke_all('sf_find_match', 'export', 'user', $account, $map);
+    // TODO: handle case where multiple implementers of hook return multiple results.
+    if (count($matches)) {
+      $sfid = $matches[0];
+      $prematch_found = true;
+    }
+  }
 
   if (empty($sfid)) {
     // Export the object to Salesforce.
@@ -347,7 +359,8 @@
 
   // If the export was successful...
   if ($response->success) {
-    if (empty($sfid)) {
+    // If this is the first time this drupal object has been exported...
+    if (empty($sfid) || $prematch_found) {
       // Store the Salesforce ID for the node and return TRUE.
       salesforce_api_id_save('user', $uid, $response->id, $fieldmap);
     }
--- sf_prematch.admin.inc
+++ sf_prematch.admin.inc
@@ -0,0 +1,240 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Admin functions for sf_prematch module.
+ */
+
+function sf_prematch_list() {
+  // Define the header for the admin table.
+  $header = array(
+    t('Index'),
+    t('Drupal object'),
+    t('Salesforce object'),
+    array('data' => t('Operations'), 'colspan' => 3),
+  );
+  
+  $result = db_query("SELECT salesforce_field_map.*, salesforce_prematch.rule " .
+    "FROM salesforce_field_map LEFT JOIN salesforce_prematch " .
+    "ON salesforce_field_map.fieldmap = salesforce_prematch.fieldmap"
+  );
+  $rows = array();
+
+  // Loop through all the indexed field maps.
+  while ($map = db_fetch_array($result)) {
+    if ($map['rule']) {
+    	$op_0 =  l(t('edit prematch'), SALESFORCE_PATH_FIELDMAPS . '/prematching/' . $map['fieldmap']);
+    	$op1 = l(t('delete prematch'), SALESFORCE_PATH_FIELDMAPS . '/prematching/' . $map['fieldmap'] . '/delete');
+    }
+    else {
+    	$op_0 =  l(t('add prematch'), SALESFORCE_PATH_FIELDMAPS . '/prematching/' . $map['fieldmap']);
+    	$op1 = '';
+    }
+    // Add the row to the table with the basic operations.
+    $rows[] = array(
+      $map['fieldmap'],
+      salesforce_api_fieldmap_object_label('drupal', $map['drupal']),
+      salesforce_api_fieldmap_object_label('salesforce', $map['salesforce']),
+      $op_0,
+      $op1,
+    );
+  }
+
+  // Add a message if no objects have been mapped.
+  if (count($rows) == 0) {
+    $rows[] = array(
+      array('data' => t('You have not yet defined any fieldmaps.'), 'colspan' => 7),
+    );
+  }
+
+  $output = theme('table', $header, $rows);
+	return $output;
+}
+
+// Displays the form to add prematching to a fieldmap.
+function sf_prematch_edit_form(&$form_state, $fieldmap) {
+  // Load the fieldmap from the database.
+  $map = salesforce_api_fieldmap_load($fieldmap);
+
+  // Return to the admin page if the fieldmap did not exist.
+  if (empty($map)) {
+    drupal_set_message(t('That fieldmap does not exist.'), 'error');
+    drupal_goto(SALESFORCE_PATH_FIELDMAPS);
+  }
+
+  // Return to the admin page if the fieldmap has no mapped fields.
+  if (empty($map['fields'])) {
+    drupal_set_message(t('That fieldmap exists, but does not have any fields.'), 'error');
+    drupal_goto(SALESFORCE_PATH_FIELDMAPS);
+  }
+  
+  // Load the prematch from the database.
+  $prematch = sf_prematch_match_by_load($fieldmap);
+
+  $form = array();
+
+  // Add the index to the form array.
+  $form['fieldmap_index'] = array(
+    '#type' => 'value',
+    '#value' => $fieldmap,
+  );
+
+  // Set flag for use in deciding where to redirect to on form submit.
+  $is_new = 
+  $form['new_prematch'] = array(
+    '#type' => 'value',
+    '#value' => ($prematch['primary_field'] == '' ||
+      (isset($form_state['values']['new_prematch']) && $form_state['values']['new_prematch'])),
+  );
+
+  // Add a description of the prematch to the form array.
+  $form['prematch_desc'] = array(
+    '#value' => '<p>' . t('Before creating a new object, attempt to match an existing one using the fields and rules below. (Click cancel to skip this step.)') . '</p>',
+  );
+  
+  // Add the select lists for the mapped Drupal field(s) to use in prematching.
+  $form['primary'] = array(
+    '#type' => 'select',
+    '#title' => t('Primary Field'),
+    '#options' => sf_prematch_get_options($map, true),
+    '#default_value' => $prematch['primary_field'],
+    '#required' => true,
+  );
+  
+  $options = sf_prematch_get_options($map);
+  
+  $form['secondary'] = array(
+    '#type' => 'select',
+    '#title' => t('Secondary Field'),
+    '#options' => $options,
+    '#default_value' => $prematch['secondary_field'],
+    '#required' => false,
+  );
+  $form['tertiary'] = array(
+    '#type' => 'select',
+    '#title' => t('Tertiary Field'),
+    '#options' => $options,
+    '#default_value' => $prematch['tertiary_field'],
+    '#required' => false,
+  );
+  
+  // Create options to use in rule select.
+  $options = array(
+    SF_PREMATCH_PRIMARY_SECONDARY_AND_TERTIARY => 'primary, secondary and tertiary fields',
+    SF_PREMATCH_PRIMARY_AND_SECONDARY => 'primary and secondary fields',
+    SF_PREMATCH_PRIMARY => 'primary field',
+  );
+
+  // Add the select list for prematching rule.
+  $form['rule'] = array(
+    '#type' => 'select',
+    '#title' => t('Only consider a match if the found object matches'),
+    '#options' => $options,
+    '#default_value' => $prematch['rule'],
+    '#required' => true,
+  );
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Save changes'),
+    '#suffix' => l(t('Cancel'), SALESFORCE_PATH_FIELDMAPS),
+  );
+  
+  return $form;
+}
+
+function sf_prematch_edit_form_validate($form, &$form_state) {
+  
+}
+
+function sf_prematch_edit_form_submit($form, &$form_state) {
+  $values = $form_state['values'];
+ 
+  // Store data in the database.
+  if ($values['new_prematch']) {
+    db_query("INSERT INTO {salesforce_prematch} (fieldmap, primary_field, secondary_field, tertiary_field, rule) VALUES(%d, '%s', '%s', '%s', %d)", $values['fieldmap_index'], $values['primary'], $values['secondary'], $values['tertiary'], $values['rule']);
+  }
+  else {
+  	db_query("UPDATE {salesforce_prematch} SET primary_field = '%s', secondary_field = '%s', tertiary_field = '%s', rule = %d WHERE fieldmap = %d", $values['primary'], $values['secondary'], $values['tertiary'], $values['rule'], $values['fieldmap_index']);
+  }
+    
+  // Display a message.
+  drupal_set_message(t('The changes have been saved.'));
+  
+  // Redirect to fieldmap list or prematching page.
+  if ($values['new_prematch']) {
+  	$form_state['redirect'] = SALESFORCE_PATH_FIELDMAPS;
+  }
+  else {
+  	$form_state['redirect'] = SALESFORCE_PATH_FIELDMAPS . '/prematching';
+  }
+}
+
+function sf_prematch_delete_form(&$form_state, $fieldmap) {
+  // Load the fieldmap and prematch from the database.
+  $map = salesforce_api_fieldmap_load($fieldmap);
+  $match_by = sf_prematch_match_by_load($fieldmap);
+
+  // Return to the admin page if the fieldmap did not exist.
+  if (empty($match_by)) {
+    drupal_set_message(t('That prematch does not exist.'), 'error');
+    drupal_goto(SALESFORCE_PATH_FIELDMAPS . '/prematching');
+  }
+
+  $form = array();
+
+  // Add the fieldmap to the form array.
+  $form['fieldmap_index'] = array(
+    '#type' => 'value',
+    '#value' => $fieldmap,
+  );
+
+  // Build the description text for this prematch.
+  $desc = t('You are about to delete the prematch for fieldmap ');
+  if ($map['action'] == 'import') {
+    $desc .= t('@index. That fieldmap maps Salesforce %salesforce objects to Drupal %drupal objects for import.', array('@index' => $map['fieldmap'], '%drupal' => $map['drupal'], '%salesforce' => $map['salesforce']));
+  }
+  else {
+    $desc .= t('@index. That fieldmap maps Drupal %drupal objects to Salesforce %salesforce objects for export.', array('@index' => $map['fieldmap'], '%drupal' => $map['drupal'], '%salesforce' => $map['salesforce']));
+  }
+
+  return confirm_form($form, t('Are you sure you want to delete this prematch?'), SALESFORCE_PATH_FIELDMAPS . '/prematching', $desc, t('Delete'));
+}
+
+function sf_prematch_delete_form_submit($form, &$form_state) {
+  // Delete the specified prematch.
+  sf_prematch_match_by_delete($form_state['values']['fieldmap_index']);
+
+  // Display a message and return to the admin prematch screen.
+  drupal_set_message(t('The prematch has been deleted.'));
+
+  $form_state['redirect'] = SALESFORCE_PATH_FIELDMAPS . '/prematching';
+}
+
+function sf_prematch_match_by_delete($fieldmap) {
+	db_query("DELETE FROM {salesforce_prematch} WHERE fieldmap = %d", $fieldmap);
+}
+
+function sf_prematch_get_options($map, $required = false) {
+  // Extract terms from $map.
+  if ($map['action'] == 'import') {
+  	$terms = array_keys($map['fields']);
+  }
+  else {
+  	$terms = array_values($map['fields']);
+  }
+  sort($terms);
+  
+  // Build terms into ordered options to use in select.
+  $options = array();
+  // Start with empty option if select is not required.
+  if (!$required) {$options[] = '';}
+  
+  // Add terms to options, making key = value so form value is key not integer.
+  foreach ($terms as $term) {
+  	$options[$term] = $term;
+  }
+  
+  return $options;
+}

--- sf_prematch.info
+++ sf_prematch.info
@@ -0,0 +1,6 @@
+; $Id$
+name = Salesforce Match
+description = Extends Salesforce API module so it checks for an existing sf object to match a drupal object before creating a new one in sf.
+dependencies[] = salesforce_api, sf_node
+package = Salesforce
+core = 6.x

--- sf_prematch.install
+++ sf_prematch.install
@@ -0,0 +1,71 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Installs tables needed for sf_prematch module.
+ */
+
+
+/**
+ * Implementation of hook_install().
+ */
+function sf_prematch_install() {
+  drupal_install_schema('sf_prematch');
+}
+
+/**
+ * Implementation of hook_uninstall().
+ */
+function sf_prematch_uninstall() {
+  drupal_uninstall_schema('sf_prematch');
+}
+
+/**
+ * Implementation of hook_schema().
+ */
+function sf_prematch_schema() {
+  $schema['salesforce_prematch'] = array(
+    'description' => t('Drupal to Salesforce object mapping table for pre-creation '),
+    'fields' => array(
+      'fieldmap' => array(
+        'description' => 'Fieldmap id FK',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => '0',
+      ),
+      'primary_field' => array(
+        'description' => 'Primary field or object name for use in prematching.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+      'secondary_field' => array(
+        'description' => 'Secondary field or object name for use in prematching.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => false,
+        'default' => '',
+      ),
+      'tertiary_field' => array(
+        'description' => 'Tertiary field or object name for use in prematching.',
+        'type' => 'varchar',
+        'length' => 128,
+        'not null' => false,
+        'default' => '',
+      ),
+      'rule' => array(
+        'description' => 'Int identifying rule for prematching (based on constants)',
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'default' => 0
+      ),
+    ),
+    'primary key' => array('fieldmap'),
+  );
+
+  return $schema;
+}

--- sf_prematch.main.inc
+++ sf_prematch.main.inc
@@ -0,0 +1,138 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Import/Export functions for sf_prematch module.
+ */
+
+/**
+ *  Use prematch rule to find a salesforce object to match the node.
+ *
+ * @param string $object_type
+ * @param stdObject $drupal_object
+ * @param array $map
+ * @param array $match_by
+ * @return string sfid
+ */
+function sf_prematch_export($object_type, $drupal_object, $map, $match_by) {
+  // Get information to allow using handlers to get values of Drupal fields.
+  $drupal_object_info = salesforce_api_fieldmap_objects_load('drupal', $map['drupal']);
+  $drupal_fields_info = $drupal_object_info['fields'];
+  
+  $values = array();
+  $select_clause = "SELECT id";
+  $drupal_to_salesforce_fieldmap = array_flip($map['fields']);
+  
+  // Create $values array allowing easy mapping from match_by fields to query fields and values.
+  // Also build out SOQL select clause to include all match by sf fields.
+  foreach ($match_by as $match_by_field => $drupal_field_name) {
+    if ($match_by_field == 'fieldmap' || $match_by_field == 'rule') {continue;}
+    $values[$match_by_field] = array();
+    // If a handler is specified for retrieving a value for the source field...
+    if (isset($drupal_fields_info[$drupal_field_name]['export'])) {
+      // Get the value for the field from the handler function.
+      $drupal_value = $drupal_fields_info[$drupal_field_name]['export']($drupal_object, $drupal_field_name);
+    }
+    // Otherwise set the field on the export object to the value of the source
+    // field if it's present on the source object.
+    elseif (isset($drupal_object->$drupal_field_name)) {
+      $drupal_value = $drupal_object->$drupal_field_name;
+    }
+    else {
+    	$drupal_value = null;
+    }
+    $values[$match_by_field]['drupal_value'] = $drupal_value;
+    $values[$match_by_field]['salesforce_field_name'] = $drupal_to_salesforce_fieldmap[$drupal_field_name];
+    
+    // If there's a salesforce field to match by, include it in the select clause.
+    if ($values[$match_by_field]['salesforce_field_name']) {
+    	$select_clause .= ', ' . $values[$match_by_field]['salesforce_field_name'];
+    }
+  }
+  
+  $sf_class = $map['salesforce'];
+  $from_where_clause = " FROM $sf_class WHERE ";
+  
+  // Use match by rule to build out where clause.
+  switch ($match_by['rule']) {
+  	case SF_PREMATCH_PRIMARY_SECONDARY_AND_TERTIARY:
+  		$from_where_clause .= $values['tertiary_field']['salesforce_field_name'] . " = '" .
+  		  $values['tertiary_field']['drupal_value'] . "' AND ";
+  	// no break;
+  	case SF_PREMATCH_PRIMARY_AND_SECONDARY:
+  		$from_where_clause .= $values['secondary_field']['salesforce_field_name'] . " = '" .
+  		  $values['secondary_field']['drupal_value'] . "' AND ";
+  	// no break;
+  	case SF_PREMATCH_PRIMARY:
+  		$from_where_clause .= $values['primary_field']['salesforce_field_name'] . " = '" .
+  		  $values['primary_field']['drupal_value'] . "'";
+  	break;
+  	default:
+  	  return;
+  	break;
+  }
+  
+  $query = $select_clause . $from_where_clause;
+  
+  // Run the SOQL query against the Salesforce API
+  if($sf = salesforce_api_connect()) {
+    try {
+      $result = $sf->client->query($query);
+    } 
+    catch (Exception $e) {
+      // TODO: watchdog($e->faultstring);
+      return;
+    }
+    
+    switch ($result->size) {
+    	case 0:
+    		return;
+    	break;
+    	case 1:
+    		return $result->records[0]->Id;
+    	break;
+    	default:
+    	  // TODO: handle multiple records
+    	break;
+    }
+  }
+}
+/*
+$result = Object of: stdClass
+  done = (boolean) true
+  queryLocator = null
+  records = Array [1]
+    0 = Object of: stdClass
+      Email = (string:19) sid@craftyspace.com
+      FirstName = (string:3) Sid
+      Id = (string:18) 003S0000004X3aDIAS
+      LastName = (string:6) Maskit
+  size = (int) 1
+*/
+
+/*
+$map = Array [6]
+  action = (string:0) 
+  automatic = (string:1) 0
+  drupal = (string:12) node_profile
+  fieldmap = (string:1) 4
+  fields = Array [4]
+    Email = (string:4) mail
+    FirstName = (string:16) field_first_name
+    LastName = (string:15) field_last_name
+    Volunteer_Interests__c = (string:25) field_volunteer_interests
+  salesforce = (string:7) Contact
+$node = Object of: stdClass
+$match_by = Array [5]
+  fieldmap = (string:1) 4
+  primary_field = (string:4) mail
+  rule = (string:1) 1
+  secondary_field = (string:15) field_last_name
+  tertiary_field = (string:16) field_first_name
+*/
+
+
+function sf_prematch_import($object_type, $object, $map, $match_by) {
+  return;
+}

--- sf_prematch.module
+++ sf_prematch.module
@@ -0,0 +1,156 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Extends Salesforce API module so checks for an existing match for an object before creating a new one.
+ */
+
+// Define constants for prematching rules.
+define('SF_PREMATCH_PRIMARY_SECONDARY_AND_TERTIARY', 1);
+define('SF_PREMATCH_PRIMARY_AND_SECONDARY', 2);
+define('SF_PREMATCH_PRIMARY', 3);
+
+/**
+ * Implementation of hook_menu().
+ */
+function sf_prematch_menu() {
+  $items[SALESFORCE_PATH_FIELDMAPS . '/prematching'] = array(
+    'title' => 'Prematching',
+    'description' => 'Create or edit prematching for a fieldmap.',
+    'page callback' => 'sf_prematch_list',
+    'access arguments' => array('administer prematching'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 15,
+    'file' => 'sf_prematch.admin.inc',
+  );
+  $items[SALESFORCE_PATH_FIELDMAPS . '/prematching/%'] = array(
+    'title' => 'Edit fieldmap prematching',
+    'description' => 'Edit an existing fieldmap prematch.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('sf_prematch_edit_form', 5),
+    'access arguments' => array('administer prematching'),
+    'type' => MENU_CALLBACK,
+    'file' => 'sf_prematch.admin.inc',
+  );
+  $items[SALESFORCE_PATH_FIELDMAPS . '/prematching/%/delete'] = array(
+    'title' => 'Delete prematching from a fieldmap',
+    'description' => 'Delete an existing fieldmap prematch.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('sf_prematch_delete_form', 5),
+    'access arguments' => array('administer prematching'),
+    'type' => MENU_CALLBACK,
+    'file' => 'sf_prematch.admin.inc',
+  );
+
+  return $items;
+}
+
+/**
+ * Implementation of hook_perm().
+ */
+function sf_prematch_perm() {
+  return array('administer prematching');
+}
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function sf_prematch_form_alter(&$form, $form_state, $form_id) {
+  if ($form_id == 'salesforce_api_settings_form') {
+    $form['sf_prematch'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Pre-creation prematching'),
+      '#description' => t('Placeholder for any pre-creation matching settings.'),
+      '#collapsible' => TRUE,
+      '#collapsed' => TRUE,
+      '#weight' => -1,
+    );
+  }
+  if ($form_id == 'salesforce_api_fieldmap_edit_form') {
+    if (!array_search('sf_prematch_fieldmap_edit_form_submit', $form['#submit'])) {
+    	$form['#submit'][] = 'sf_prematch_fieldmap_edit_form_submit';
+    }
+  }
+}
+
+/**
+ * Piggyback on fieldmap edit form submit so can redirect to prematch creation for the fieldmap.
+ *
+ * @param array $form
+ * @param array $form_state
+ */
+function sf_prematch_fieldmap_edit_form_submit($form, &$form_state) {
+  $fieldmap = $form_state['values']['fieldmap_index'];
+	$form_state['redirect'] = SALESFORCE_PATH_FIELDMAPS .'/prematching/'. $fieldmap;
+}
+
+/**
+ * Loads a prematch from the database.
+ *
+ * @param $fieldmap
+ *   The index of the fieldmap's prematch to load.
+ * @return
+ *   An array containing the prematch rule.
+ */
+function sf_prematch_match_by_load($fieldmap) {
+  static $match_bys;
+  if (!isset($match_bys[$fieldmap]) && $fieldmap != '') {
+    $result = db_query("SELECT * FROM {salesforce_prematch} WHERE fieldmap = %d", $fieldmap);
+    $match_by = db_fetch_array($result);
+    if (count($match_by)) {
+    	$match_bys[$fieldmap] = $match_by;
+    }
+    else {
+      $match_bys[0] = array(
+        'fieldmap' => $fieldmap,
+        'primary_field' => '',
+        'secondary_field' => '',
+        'tertiary_field' => '',
+        'rule' => 1
+      );
+      $fieldmap = 0;
+    }
+  }
+
+  return $match_bys[$fieldmap];
+}
+
+/**
+ * Implement hook_sf_find_match
+ *
+ * @param string $action
+ * @param stdClass $object
+ * @param array $map
+ */
+function sf_prematch_sf_find_match($action, $object_type, $object, $map) {
+  if ($action != 'export') {
+  	return;
+  }
+  $fieldmap = $map['fieldmap'];
+  $match_by = sf_prematch_match_by_load($fieldmap);
+  if ($match_by['primary_field'] == '') {return;}
+  require_once('sf_prematch.main.inc');
+	switch ($action) {
+	 	case 'export':
+	 		$result = sf_prematch_export($object_type, $object, $map, $match_by);
+	 	break;
+	 	case 'import':
+	 		$result = sf_prematch_import($object_type, $object, $map, $match_by);
+	 	break;
+	 	default:
+	 	  $result = null;
+	 	break;
+	}
+	return $result;
+}
+
+/**
+ * Implement hook_sf_fieldmap_deleted
+ *
+ * @param int $fieldmap
+ */
+function sf_prematch_sf_fieldmap_deleted($fieldmap) {
+  require_once('sf_prematch.main.inc');
+  sf_prematch_match_by_delete($fieldmap);
+}


