diff --git a/rpx_core.module b/rpx_core.module
index 4883728..d7c218d 100644
--- a/rpx_core.module
+++ b/rpx_core.module
@@ -550,30 +550,45 @@ function _rpx_import_user_data($account) {
   $map = variable_get('rpx_profile_fields_map', array());
   $provider = $_SESSION['rpx_last_provider_info']['name'];
   $rpx_data = rpx_core_get_rpx_session();
+  // Array of field names => callbacks.
+  // Parameters for callback: node object &$node, field object $field, formatted
+  // new value $new_value, raw data from rpx $rpx_data.
+  $custom_import_handlers = module_invoke_all('rpx_custom_data_import');
 
-  if (module_exists('profile')) {
-    // Collect fields list and load them together
-    $field_names = array();
-    foreach ($map as $mid => $mapping) {
-      // Filter-out at least non-updatable fields
-      if (!isset($mapping['update']) || $mapping['update'] == RPX_UPDATE_NONE) {
-        continue;
-      }
-      $field_names[] = $mapping['field'];
+  // Collect fields list and load them together
+  $profile_field_names = $content_profile_field_names = $profile_fields = array();
+  foreach ($map as $mid => $mapping) {
+    // Filter-out at least non-updatable fields
+    if (!isset($mapping['update']) || $mapping['update'] == RPX_UPDATE_NONE) {
+      continue;
+    }
+
+
+    // test for field origin
+    if (module_exists('profile') && strpos($mapping['field'], 'profile_') === 0) {
+      $profile_field_names[] = $mapping['field'];
+    }
+    elseif (module_exists('content_profile') && strpos($mapping['field'], 'field_') === 0) {
+      $content_profile_field_names[] = $mapping['field'];
     }
-    $profile_fields = _rpx_profile_get_fields($field_names, FALSE);
   }
 
+  $profile_fields += _rpx_profile_get_fields($profile_field_names, FALSE);
+  $profile_fields += _rpx_content_profile_get_fields($content_profile_field_names, $account);
+
+  // Used for content_profile fields.
+  $node = new stdClass;
   foreach ($map as $mid => $mapping) {
+    $field = $profile_fields[$mapping['field']];
+
     // Should we try to update the field at all?
     if (!isset($mapping['update']) || $mapping['update'] == RPX_UPDATE_NONE) {
       continue;
     }
 
-    $new_data = _rpx_data_map($rpx_data, $mapping['fid']);
-
     // Only update if provider returned data for the field.
-    if($new_data === '') {
+    $new_data = _rpx_data_map($rpx_data, $mapping['fid']);
+    if ($new_data === '') {
       continue;
     }
 
@@ -600,30 +615,26 @@ function _rpx_import_user_data($account) {
       }
     }
 
-    // Import into the profile fields.
-    if(module_exists('profile')) {
-      // Check that field still exists.
-      if (!isset($profile_fields[$mapping['field']])) {
-        _rpx_report_missing_field('profile', $mapping['field'], $account->name);
-        continue;
-      }
-
-      $field = $profile_fields[$mapping['field']];
-      $old_value = db_result(db_query("SELECT value FROM {profile_values} WHERE fid = %d AND uid = %d", $field->fid, $account->uid));
+    // Check that field still exists.
+    if (!isset($profile_fields[$mapping['field']])) {
+      _rpx_report_missing_field($field->origin, $mapping['field'], $account->name);
+      continue;
+    }
 
-      // If we should only update empty field, make sure the field is empty.
-      if ($mapping['update'] == RPX_UPDATE_EMPTY) {
-        if ($old_value && $old_value !== '') {
-          continue;
-        }
-      }
+    // If we should only update empty field, make sure the field is empty.
+    $old_value = _rpx_profile_get_field_value($field, $account);
+    if ($mapping['update'] == RPX_UPDATE_EMPTY && $old_value && $old_value !== '') {
+      continue;
+    }
 
-      $new_value = _rpx_profile_format_value($field, $new_data);
-      if ($new_value === NULL) {
-        watchdog('rpx_core', 'Wrong data format for field %field_name.', array('%field_name' => $mapping['field']), WATCHDOG_WARNING);
-        continue;
-      }
+    $new_value = _rpx_profile_format_value($field, $new_data);
+    if ($new_value === NULL) {
+      watchdog('rpx_core', 'Wrong data format for field %field_name.', array('%field_name' => $mapping['field']), WATCHDOG_WARNING);
+      continue;
+    }
 
+    // Import into the profile fields.
+    if ($field->origin == 'profile') {
       // Import the data.
       if ($old_value !== FALSE) {
         if (_profile_field_serialize($field->type)) {
@@ -640,6 +651,17 @@ function _rpx_import_user_data($account) {
       }
     }
 
+    // Import into the content profile fields (setup node values).
+    if ($field->origin == 'content_profile') {
+      // invoke hook_rpx_custom_data_import
+      if (isset($custom_import_handlers[$field->name]) && function_exists($custom_import_handlers[$field->name])) {
+        call_user_func($custom_import_handlers[$field->name], $node, $field, $new_value, $rpx_data);
+      }
+      else {
+        $node->{$field->name}[0][$field->column] = $new_value;
+      }
+    }
+
     // Record the provider's name as the last provider used in the mapping.
     if($mapping['update'] != RPX_UPDATE_ADD) {
       db_query("UPDATE {rpx_mapping_provider} SET name = '%s' WHERE uid = %d AND mid = %d", $provider, $account->uid, $mid);
@@ -648,6 +670,34 @@ function _rpx_import_user_data($account) {
       }
     }
   }
+
+  // Import all the content profile data in 1 node_save action.
+  if (module_exists('content_profile')) {
+    // Merge objects
+    $node = (object) ((array) $node + (array) content_profile_load('profile', $account->uid));
+    node_save($node);
+  }
+
+  drupal_set_message(t('user profile data import completed'));
+}
+
+
+/**
+ * Retrieve field value from profile
+ *
+ * @param object $field
+ *   Profile field object to get data from.
+ * @return
+ *   the field value
+ */
+function _rpx_profile_get_field_value($field, $account) {
+  if ($field->origin == 'profile') {
+    return db_result(db_query("SELECT value FROM {profile_values} WHERE fid = %d AND uid = %d", $field->fid, $account->uid));
+  }
+  if ($field->origin == 'content_profile') {
+    $node = content_profile_load('profile', $account->uid);
+    return $node->{$field->name}[0][$field->column];
+  }
 }
 
 /**
@@ -663,8 +713,7 @@ function _rpx_import_user_data($account) {
 function _rpx_profile_get_fields($names = array(), $reg_form = FALSE) {
   static $cache = array();
 
-  $result = array();
-  $load = array();
+  $result = $load = array();
   foreach ($names as $name) {
     if (isset($cache[$name])) {
       $result[$name] = $cache[$name];
@@ -687,6 +736,7 @@ function _rpx_profile_get_fields($names = array(), $reg_form = FALSE) {
     }
     $res = db_query($sql, $args);
     while ($field = db_fetch_object($res)) {
+      $field->origin = 'profile';
       $result[$field->name] = $cache[$field->name] = $field;
     }
   }
@@ -695,6 +745,68 @@ function _rpx_profile_get_fields($names = array(), $reg_form = FALSE) {
 }
 
 /**
+ * Retrieve content profile fields meta-information for selected fields.
+ *
+ * @param array $names
+ *   Profile fields to get information about.
+ * @return
+ *   An array of profile_fields data for each field.
+ */
+function _rpx_content_profile_get_fields($names = array(), $account, $reg_form = FALSE) {
+  static $cache = array();
+
+  $result = $load = array();
+  foreach ($names as $name) {
+    if (isset($cache[$name])) {
+      $result[$name] = $cache[$name];
+    }
+    else {
+      $load[] = $name;
+    }
+  }
+
+  if (!empty($load)) {
+    foreach ($names as $name) {
+      // basic data
+      $field = new stdClass;
+      $field->origin = 'content_profile';
+      $field->name = $name;
+      $field->registration_hide = false;
+
+      // cck data
+      $field_info = content_fields($name);
+      $field->type = $field_info['type'];
+      $field->multiple = $field_info['multiple'];
+      foreach ($field_info['columns'] as $key => $values) {
+        $field->column = $key;
+        break; // try only the first column
+      }
+
+      // content profile registration data
+      if (module_exists('content_profile_registration')) {
+        $node_types = content_profile_get_types('names');
+        foreach ($node_types as $type) {
+          if (in_array($name, content_profile_get_settings($type, 'registration_hide'))) {
+            $field->registration_hide = true;
+          }
+        }
+      }
+
+      $result[$name] = $cache[$name] = $field;
+    }
+  }
+
+  if ($reg_form) {
+    foreach ($result as $rfield) {
+      if ($rfield->registration_hide) {
+        unset($result[$rfield->name]);
+      }
+    }
+  }
+  return $result;
+}
+
+/**
  * Format value for profile field.
  *
  * @param object $field
@@ -705,36 +817,48 @@ function _rpx_profile_get_fields($names = array(), $reg_form = FALSE) {
  *   Mixed formatted value or NULL if formatting isn't possible.
  */
 function _rpx_profile_format_value($field, $value) {
-  switch ($field->type) {
-    case 'date':
-      if (!preg_match('/^(\d{4})\-(\d{2})\-(\d{2})$/', $value, $parsed_date)) {
-        return NULL;
-      }
+  if ($field->origin == 'profile') {
+    switch ($field->type) {
+      case 'date':
+        if (!preg_match('/^(\d{4})\-(\d{2})\-(\d{2})$/', $value, $parsed_date)) {
+          return NULL;
+        }
 
-      // Profile stores days and months without leading zeroes
-      $result = array(
-        'year' => $parsed_date[1],
-        'month' => ltrim($parsed_date[2], '0'),
-        'day' => ltrim($parsed_date[3], '0'),
-      );
-      return $result;
-
-    case 'selection':
-      // Split just like Profile module does
-      $options = split("[\n\r]", $field->options);
-      foreach ($options as $option) {
-        if ($option = trim($option)) {
-          if (drupal_strtolower($value) == drupal_strtolower($option)) {
-            return $option;
+        // Profile stores days and months without leading zeroes
+        $result = array(
+          'year' => $parsed_date[1],
+          'month' => ltrim($parsed_date[2], '0'),
+          'day' => ltrim($parsed_date[3], '0'),
+        );
+        return $result;
+
+      case 'selection':
+        // Split just like Profile module does
+        $options = split("[\n\r]", $field->options);
+        foreach ($options as $option) {
+          if ($option = trim($option)) {
+            if (drupal_strtolower($value) == drupal_strtolower($option)) {
+              return $option;
+            }
           }
         }
-      }
-      // No matches found, value can't be formatted
-      return NULL;
+        // No matches found, value can't be formatted
+        return NULL;
 
-    default:
-      // single, multi-line text and URL fields
-      return $value;
+      default:
+        // single, multi-line text and URL fields
+        return $value;
+    }
+  }
+
+  if ($field->origin == 'content_profile') {
+    switch ($field->type) {
+      case 'date':
+      case 'selection':
+      default:
+        // single, multi-line text and URL fields
+        return $value;
+    }
   }
 }
 
diff --git a/rpx_ui.module b/rpx_ui.module
index 4baafd1..ed2f5e0 100644
--- a/rpx_ui.module
+++ b/rpx_ui.module
@@ -324,11 +324,28 @@ function rpx_get_enabled_provider_array($force_lookup = FALSE) {
 function _rpx_drupal_field_catalog() {
   $fields = array();
 
+  // todo: Build an array containing the fields defined by the User core module.
+/*
+  $fields['name'] = 'User: Name';
+  $fields['mail'] = 'User: Email';
+  $fields['picture'] = 'User: Picture';
+*/
+
   // Build an array containing the fields defined by the Profile core module.
   if (module_exists('profile')) {
     $result = db_query("SELECT fid, title, name FROM {profile_fields} WHERE type IN ('textfield', 'textarea', 'url', 'date', 'selection') ORDER BY weight, title");
     while ($row = db_fetch_object($result)) {
-      $fields[$row->name] = $row->title;
+      $fields[$row->name] = 'Profile: '.$row->title;
+    }
+  }
+
+  // Build an array containing the fields defined by the Content Profile contributed module.
+  if (module_exists('content_profile')) {
+    foreach (content_profile_get_types() as $type => $info) {
+      $typeinfo = content_types($type);
+      foreach ($typeinfo['fields'] as $fieldname => $fieldinfo) {
+        $fields[$fieldname] = 'Content Profile: '.($fieldinfo['label'] ? $fieldinfo['label'] : $fieldinfo['field_name']);
+      }
     }
   }
 
