--- includes/node_form.inc	Fri Jan 16 05:21:36 1970
+++ includes/node_form.inc	Fri Jan 16 05:21:36 1970
@@ -20,39 +20,7 @@
  * @see cck_private_fields_form_alter()
  */
 function _cck_private_fields_node_form_alter(&$form, &$form_state, $private_fields) {
-  static $js_settings_processed;
-
-  // Configure privacy options for fields in this node form.
-  $privacy_status_options = array(
-    CCK_FIELDS_PRIVACY_STATUS_PUBLIC => array(
-      'name' => t('Public'),
-      'class' => 'cck-private-field-status-icon-public',
-      'label' => t('Public - visible to everyone.'),
-    ),
-    CCK_FIELDS_PRIVACY_STATUS_HIDDEN => array(
-      'name' => t('Hidden'),
-      'class' => 'cck-private-field-status-icon-hidden',
-      'label' => t('Hidden - visible to you, hidden from everyone else.'),
-    ),
-  );
-
-  // Enable 'Private' option, only if supported.
-  if (cck_private_fields_get_private_field_access_module()) {
-    $privacy_status_options[CCK_FIELDS_PRIVACY_STATUS_PRIVATE] = array(
-      'name' => t('Private'),
-      'class' => 'cck-private-field-status-icon-private',
-      'label' => t('Private - visible to you and your friends.'),
-    );
-  }
-
-  // Make sure Drupal settings are not sent more than once per page.
-  if (!isset($js_settings_processed)) {
-    $js_settings = array(
-      'privacyStatusOptions' => $privacy_status_options,
-      'privacyStatusForm' => drupal_get_form('cck_private_field_privacy_settings_dialog', $privacy_status_options),
-      'privateFields' => array(),
-    );
-  }
+  static $form_delta = 0;
 
   // Grab information about the fields we are interested in.
   $type_name = $form['type']['#value'];
@@ -76,7 +44,13 @@
       }
 
       // See if the current user is allowed to edit privacy settings for this field.
-      $edit_privacy_access = user_access(cck_private_fields_build_permission_name('edit', $field_name));
+      // We disregard permissions on the user registration form when content_profile module is in use.
+      if ($_GET['q'] == 'user/register' && module_exists('content_profile_registration')) {
+        $edit_privacy_access = TRUE;
+      }
+      else {
+        $edit_privacy_access = user_access(cck_private_fields_build_permission_name('edit', $field_name));
+      }
 
       $private_fields[$field_name] = array(
         'field' => $field,
@@ -85,40 +59,22 @@
         'group_table_id' => $group_table_id,
         'multiple_columns' => $multiple_columns,
       );
-
-      // Prepare field information for sending to client-side behavior?
-      if ($edit_privacy_access && !isset($js_settings_processed)) {
-        $js_settings['privateFields'][$field_name] = array(
-          'label' => check_plain($field['widget']['label']),
-          'group_type' => $group_type,
-          'group_table_id' => $group_table_id,
-          'multiple_columns' => $multiple_columns,
-        );
-      }
     }
   }
 
   // Prepare the form for private fields handling.
-  $form['#cck_private_fields'] = $private_fields;
-  $form['cck_private_fields'] = array(
+  // We append the type name to preserve fields when multiple node forms are being rendered.
+  $form['#cck_private_fields_' . $form_delta] = $private_fields;
+  $form['cck_private_fields_' . $form_delta] = array(
     '#tree' => TRUE,
     '#weight' => 100,
+    '#pre_render' => array('_cck_private_fields_hidden_form_build'),
   );
 
   // Scan the form recursively to find fields with privacy options enabled.
-  _cck_private_fields_node_form_recursive($form, $form, $form_state);
+  _cck_private_fields_node_form_recursive($form, $form, $form_state, $form_delta);
 
-  // Send our javascript and stylesheets to the page.
-  $module_path = drupal_get_path('module', 'cck_private_fields');
-  drupal_add_css($module_path .'/css/privacy_status_dialog.css');
-  drupal_add_js($module_path .'/js/privacy_status_dialog.js');
-  jquery_ui_add(array('ui.dialog', 'ui.draggable'));
-
-  // Make sure Drupal settings are not sent more than once per page.
-  if (!isset($js_settings_processed)) {
-    drupal_add_js(array('CCKPrivateFields' => $js_settings), 'setting');
-    $js_settings_processed = TRUE;
-  }
+  $form_delta++;
 }
 
 /**
@@ -135,12 +91,12 @@
  * @see node_save()
  * @see cck_private_fields_nodeapi()
  */
-function _cck_private_fields_node_form_recursive(&$form, &$elements, &$form_state) {
+function _cck_private_fields_node_form_recursive(&$form, &$elements, &$form_state, $form_delta) {
   foreach (element_children($elements) as $field_name) {
     if (isset($elements[$field_name]) && $elements[$field_name]) {
 
       // See if this is one of those fields where privacy options are enabled.
-      if (isset($form['#cck_private_fields'][$field_name])) {
+      if (isset($form['#cck_private_fields_' . $form_delta][$field_name])) {
 
         // Ignore hidden elements.
         if (isset($elements[$field_name]['#type']) && $elements[$field_name]['#type'] == 'hidden') {
@@ -148,12 +104,12 @@
         }
 
         // Load information about the field.
-        $field = $form['#cck_private_fields'][$field_name]['field'];
+        $field = $form['#cck_private_fields_' . $form_delta][$field_name]['field'];
 
         // Get the privacy status for this field from $form_state if it is
         // a form preview.
-        if (isset($form_state['values']['cck_private_fields']) && isset($form_state['values']['cck_private_fields'][$field_name])) {
-          $field_privacy_status = $form_state['values']['cck_private_fields'][$field_name];
+        if (isset($form_state['values']['cck_private_fields_' . $form_delta]) && isset($form_state['values']['cck_private_fields_' . $form_delta][$field_name])) {
+          $field_privacy_status = $form_state['values']['cck_private_fields_' . $form_delta][$field_name];
         }
         // If this is a node edit form, get the privacy status from database.
         elseif (isset($form['vid']['#value'])) {
@@ -167,51 +123,151 @@
 
         // Allow access to change the privacy options for this field only to
         // users with appropriate permissions.
-        if (!$form['#cck_private_fields'][$field_name]['edit_privacy_access']) {
+        if (!$form['#cck_private_fields_' . $form_delta][$field_name]['edit_privacy_access']) {
           // This user is not allowed, but we still need field privacy settings
           // in the form, so that this data is available to node_submit().
-          $form['cck_private_fields'][$field_name] = array(
+          $form['cck_private_fields_' . $form_delta][$field_name] = array(
             '#type' => 'value',
             '#value' => $field_privacy_status,
+            '#multigroup' => $form['#cck_private_fields_' . $form_delta][$field_name]['group_type'],
+            '#edit_privacy_access' => $form['#cck_private_fields_' . $form_delta][$field_name]['edit_privacy_access'],
+            '#field_lable' => $form['#cck_private_fields_' . $form_delta][$field_name]['field']['widget']['label'],
+            '#group_type' => $form['#cck_private_fields_' . $form_delta][$field_name]['group_type'],
+            '#group_table_id' =>$form['#cck_private_fields_' . $form_delta][$field_name]['group_table_id'],
+            '#multiple_columns' => $form['#cck_private_fields_' . $form_delta][$field_name]['multiple_columns'],
           );
         }
         else {
           // Send the privacy status for this field as a hidden form element.
-          $form['cck_private_fields'][$field_name] = array(
+          $form['cck_private_fields_' . $form_delta][$field_name] = array(
             '#type' => 'hidden',
             '#default_value' => $field_privacy_status,
+            '#multigroup' => $form['#cck_private_fields_' . $form_delta][$field_name]['group_type'],
+            '#edit_privacy_access' => $form['#cck_private_fields_' . $form_delta][$field_name]['edit_privacy_access'],
+            '#field_lable' => $form['#cck_private_fields_' . $form_delta][$field_name]['field']['widget']['label'],
+            '#group_type' => $form['#cck_private_fields_' . $form_delta][$field_name]['group_type'],
+            '#group_table_id' =>$form['#cck_private_fields_' . $form_delta][$field_name]['group_table_id'],
+            '#multiple_columns' => $form['#cck_private_fields_' . $form_delta][$field_name]['multiple_columns'],
           );
 
           // Render the privacy status icon.
           // Note however that fields in multigroups configured to use
           // multiple columns table are targeted client-side.
-          if ($form['#cck_private_fields'][$field_name]['group_type'] != 'multigroup' || !$form['#cck_private_fields'][$field_name]['multiple_columns']) {
-            $old_prefix = (isset($elements[$field_name]['#prefix']) ? $elements[$field_name]['#prefix'] : '');
-            $old_suffix = (isset($elements[$field_name]['#suffix']) ? $elements[$field_name]['#suffix'] : '');
-
-            $wrapper_class = 'cck-private-field-wrapper cck-private-field-wrapper-';
-            $wrapper_class .= (isset($elements[$field_name]['#theme']) && $elements[$field_name]['#theme'] == 'content_multiple_values' ? 'multiple' : 'single');
-            $wrapper_class .= ' cck-private-field-name-'. $field_name .' clear-block';
-
-            $new_prefix = '<div class="'. $wrapper_class .'"><div class="cck-private-field-status-icon"></div>';
-            $new_suffix = '</div>';
-
-            if ($field['multiple'] > 1) {
-              $new_prefix .= '<div>';
-              $new_suffix .= '</div>';
+          if ($form['#cck_private_fields_' . $form_delta][$field_name]['group_type'] != 'multigroup' || !$form['#cck_private_fields_' . $form_delta][$field_name]['multiple_columns']) {
+            $elements[$field_name]['#multiple'] = $field['multiple'];
+            $elements[$field_name]['#form_delta'] = $form_delta;
+            if (!isset($elements[$field_name]['#pre_render'])) {
+              $elements[$field_name]['#pre_render'] = array();
             }
-
-            $elements[$field_name]['#prefix'] = $new_prefix . $old_prefix;
-            $elements[$field_name]['#suffix'] = $old_suffix . $new_suffix;
+            array_unshift($elements[$field_name]['#pre_render'], '_cck_private_fields_wrapper_form_build');
           }
         }
       }
       else {
         // Recurse through all children elements.
-        _cck_private_fields_node_form_recursive($form, $elements[$field_name], $form_state);
+        _cck_private_fields_node_form_recursive($form, $elements[$field_name], $form_state, $form_delta);
       }
     }
   }
+}
+
+/**
+ * Render the privacy status icon.
+ * Note however that fields in multigroups configured to use
+ * multiple columns table are targeted client-side.
+ */
+function cck_private_field_form_wrapper($field) {
+  $field_name = $field['#field_name'];
+
+  $old_prefix = (isset($field['#prefix']) ? $field['#prefix'] : '');
+  $old_suffix = (isset($field['#suffix']) ? $field['#suffix'] : '');
+
+  $wrapper_class = 'cck-private-field-wrapper cck-private-field-wrapper-';
+  $wrapper_class .= (isset($field['#theme']) && $field['#theme'] == 'content_multiple_values' ? 'multiple' : 'single');
+  $wrapper_class .= ' cck-private-field-name-'. $field_name .' clear-block';
+  $wrapper_class .= ' cck-private-field-delta-'. $field['#form_delta'];
+
+  $new_prefix = '<div class="'. $wrapper_class .'"><div class="cck-private-field-status-icon"></div>';
+  $new_suffix = '</div>';
+
+  if ($field['multiple'] > 1) {
+    $new_prefix .= '<div>';
+    $new_suffix .= '</div>';
+  }
+
+  $field['#prefix'] = $new_prefix . $old_prefix;
+  $field['#suffix'] = $old_suffix . $new_suffix;
+  return $field;
+}
+
+function cck_private_field_form_js($fields) {
+  static $js_settings_processed, $form_delta = 0;
+
+  // Configure privacy options for fields in this node form.
+  $privacy_status_options = array(
+    CCK_FIELDS_PRIVACY_STATUS_PUBLIC => array(
+      'name' => t('Public'),
+      'class' => 'cck-private-field-status-icon-public',
+      'label' => t('Public - visible to everyone.'),
+    ),
+    CCK_FIELDS_PRIVACY_STATUS_HIDDEN => array(
+      'name' => t('Hidden'),
+      'class' => 'cck-private-field-status-icon-hidden',
+      'label' => t('Hidden - visible to you, hidden from everyone else.'),
+    ),
+  );
+
+  // Enable 'Private' option, only if supported.
+  if (cck_private_fields_get_private_field_access_module()) {
+    $privacy_status_options[CCK_FIELDS_PRIVACY_STATUS_PRIVATE] = array(
+      'name' => t('Private'),
+      'class' => 'cck-private-field-status-icon-private',
+      'label' => t('Private - visible to you and your friends.'),
+    );
+  }
+
+  // Make sure Drupal settings dialog are not sent more than once per page.
+  if (!isset($js_settings_processed)) {
+    $js_settings = array(
+      'privacyStatusOptions' => $privacy_status_options,
+      'privacyStatusForm' => drupal_get_form('cck_private_field_privacy_settings_dialog', $privacy_status_options),
+    );
+    // we only want to add the form and options once
+    drupal_add_js(array('CCKPrivateFields' => $js_settings), 'setting');
+  }
+
+  // We reset settings to only have fields
+  $js_settings = array(
+    'privateFields' => array()
+  );
+
+  foreach (element_children($fields) as $field_name) {
+    if (isset($fields[$field_name]) && $fields[$field_name]) {
+      // Prepare field information for sending to client-side behavior?
+      if ($fields[$field_name]['#edit_privacy_access']) {
+        $js_settings['privateFields'][$field_name] = array(
+          'label' => check_plain($fields[$field_name]['#field_lable']),
+          'group_type' => $fields[$field_name]['#group_type'],
+          'group_table_id' => $fields[$field_name]['#group_table_id'],
+          'multiple_columns' => $fields[$field_name]['#multiple_columns'],
+        );
+      }
+    }
+  }
+
+  // Send our javascript and stylesheets to the page.
+  $module_path = drupal_get_path('module', 'cck_private_fields');
+  drupal_add_css($module_path .'/css/privacy_status_dialog.css');
+  drupal_add_js($module_path .'/js/privacy_status_dialog.js');
+  jquery_ui_add(array('ui.dialog', 'ui.draggable'));
+
+  // Settings are accumulated per a form and every add_js call overwrites the previous
+  drupal_add_js(array('CCKPrivateFields' => $js_settings), 'setting');
+  $js_settings_processed = TRUE;
+
+  $form_delta++;
+
+  return $fields;
 }
 
 /**
--- cck_private_fields.module	Fri Jan 16 05:21:36 1970
+++ cck_private_fields.module	Fri Jan 16 05:21:36 1970
@@ -67,9 +67,38 @@
 }
 
 /**
+ * Pre-render hidden form values to add JS
+ */
+function _cck_private_fields_hidden_form_build($form_element) {
+  module_load_include('inc', 'cck_private_fields', 'includes/common');
+  module_load_include('inc', 'cck_private_fields', 'includes/node_form');
+  return cck_private_field_form_js($form_element);
+}
+
+/**
+ * Pre-render private fields with wrapper
+ */
+function _cck_private_fields_wrapper_form_build($form_element) {
+  module_load_include('inc', 'cck_private_fields', 'includes/common');
+  module_load_include('inc', 'cck_private_fields', 'includes/node_form');
+  return cck_private_field_form_wrapper($form_element);
+}
+
+/**
  * Implementation of hook_nodeapi().
  */
 function cck_private_fields_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+
+  // We need to know the form delta.
+  if ($op == 'update' || $op == 'insert') {
+    $delta_count = 0;
+    foreach ($node as $key => $value) {
+      if (strpos($key, 'cck_private_fields_') === 0) {
+        $delta_count++;
+      }
+    }
+  }
+
   switch ($op) {
     case 'load':
       module_load_include('inc', 'cck_private_fields', 'includes/common');
@@ -78,21 +107,25 @@
       );
 
     case 'update':
-      if (!empty($node->cck_private_fields) && is_array($node->cck_private_fields)) {
-        db_query("DELETE FROM {cck_private_fields} WHERE vid = %d", $node->vid);
+      for ($x=0; $x < $delta_count; $x++) {
+        if (!empty($node->{'cck_private_fields_' . $x}) && is_array($node->{'cck_private_fields_' . $x})) {
+          db_query("DELETE FROM {cck_private_fields} WHERE vid = %d", $node->vid);
+        }
       }
       // Fallback to 'insert' case is intentional.
 
     case 'insert':
-      if (!empty($node->cck_private_fields) && is_array($node->cck_private_fields)) {
-        module_load_include('inc', 'cck_private_fields', 'includes/common');
+      for ($x=0; $x < $delta_count; $x++) {
+        if (!empty($node->{'cck_private_fields_' . $x}) && is_array($node->{'cck_private_fields_' . $x})) {
+          module_load_include('inc', 'cck_private_fields', 'includes/common');
 
-        $private_fields = cck_private_fields_get_content_private_fields($node->type);
-        foreach ($node->cck_private_fields as $field_name => $privacy_status) {
-          if ($private_fields[$field_name] !== FALSE) {
-            db_query("INSERT INTO {cck_private_fields} (nid, vid, content_type, field_name, privacy_status) VALUES (%d, %d, '%s', '%s', %d)", array(
-              $node->nid, $node->vid, $node->type, $field_name, $privacy_status
-            ));
+          $private_fields = cck_private_fields_get_content_private_fields($node->type);
+          foreach ($node->{'cck_private_fields_' . $x} as $field_name => $privacy_status) {
+            if ($private_fields[$field_name] !== FALSE) {
+              db_query("INSERT INTO {cck_private_fields} (nid, vid, content_type, field_name, privacy_status) VALUES (%d, %d, '%s', '%s', %d)", array(
+                $node->nid, $node->vid, $node->type, $field_name, $privacy_status
+              ));
+            }
           }
         }
       }
--- js/privacy_status_dialog.js	Fri Jan 16 05:21:36 1970
+++ js/privacy_status_dialog.js	Fri Jan 16 05:21:36 1970
@@ -33,10 +33,20 @@
     var hoverClass = ($wrapper.hasClass('cck-private-field-wrapper-multiple') ? 'cck-private-field-wrapper-multiple-hover' : 'cck-private-field-wrapper-single-hover');
     var fieldName = this.className.replace(/^.*cck-private-field-name-(field_[_a-z0-9]+).*$/, '$1');
 
-    self.setStatusIcon(context, fieldName, $statusIcon);
+    var formDelta = null;
+    var classes = $wrapper.attr('class').split( ' ' );
+    for (var i = 0; i < classes.length; i++) {
+      var class = classes[i];
+      if (class.match( /^cck-private-field-delta-/ )) {
+        formDelta = class.replace("cck-private-field-delta-",'');
+        break;
+      }
+    }
+
+    self.setStatusIcon(context, fieldName, $statusIcon, formDelta);
 
     $statusIcon.bind('click', function() {
-      self.openDialog(context, fieldName);
+      self.openDialog(context, fieldName, formDelta);
       return false;
     }).hover(
       function() { $wrapper.addClass(hoverClass); },
@@ -48,10 +58,10 @@
 /**
  * CCK Private Fields dialog.
  */
-Drupal.CCKPrivateFieldsDialog.setStatusIcon = function(context, fieldName, $statusIcon) {
+Drupal.CCKPrivateFieldsDialog.setStatusIcon = function(context, fieldName, $statusIcon, formDelta) {
   var self = this, settings = Drupal.settings.CCKPrivateFields;
 
-  var privacyStatus = $('input[name="cck_private_fields['+ fieldName +']"]', context).val();
+  var privacyStatus = $('input[name="cck_private_fields_' + formDelta + '['+ fieldName +']"]', context).val();
   if (!settings.privacyStatusOptions[privacyStatus]) {
     privacyStatus = 0;
   }
@@ -67,7 +77,7 @@
 /**
  * CCK Private Fields dialog.
  */
-Drupal.CCKPrivateFieldsDialog.openDialog = function(context, fieldName) {
+Drupal.CCKPrivateFieldsDialog.openDialog = function(context, fieldName, formDelta) {
   var self = this, settings = Drupal.settings.CCKPrivateFields;
 
   // Build the dialog container.
@@ -88,7 +98,7 @@
 
   // Get the current privacy status for this field from the corresponding
   // hidden element in the form.
-  var privacyStatus = $('input[name="cck_private_fields['+ fieldName +']"]', context).val();
+  var privacyStatus = $('input[name="cck_private_fields_' + formDelta + '['+ fieldName +']"]', context).val();
 
   // Set the privacy status in the dialog form element.
   $('input[name="cck-private-fields-dialog-status-options"][value='+ privacyStatus +']', $dialogContainer).attr('checked', 'checked');
@@ -97,8 +107,8 @@
   // corresponding hidden element, and then close the dialog.
   $('#edit-cck-private-fields-dialog-status-button-ok', $dialogContainer).bind('click', function() {
     var privacyStatus = $('input[name="cck-private-fields-dialog-status-options"]:checked', $dialogContainer).val();
-    $('input[name="cck_private_fields['+ fieldName +']"]', context).val(privacyStatus);
-    self.setStatusIcon(context, fieldName, $('.cck-private-field-status-icon-'+ fieldName));
+    $('input[name="cck_private_fields_' + formDelta + '['+ fieldName +']"]', context).val(privacyStatus);
+    self.setStatusIcon(context, fieldName, $('.cck-private-field-status-icon-'+ fieldName), formDelta);
     $dialogContainer.dialog('close');
     return false;
   });
