Index: fieldgroup.module
===================================================================
--- fieldgroup.module	(revision 3208)
+++ fieldgroup.module	(working copy)
@@ -56,6 +56,11 @@
 function fieldgroup_edit_group_form($content_type, $group_name, $action) {
   $groups = fieldgroup_groups($content_type['type']);
   $group = $groups[$group_name];
+  
+  $group_options[0] = t('Top');
+  foreach ($groups AS $name => $item) {
+  	$group_options[$name] = $item['label'];
+  }
 
   if ($action == 'add') {
     //adding a new one
@@ -84,6 +89,12 @@
     '#default_value' => $group['label'],
     '#required' => TRUE,
   );
+  $form['settings']['parent'] = array(
+    '#type' => 'select',
+    '#title' => t('Parent Group'),
+    '#default_value' => $group['settings']['parent'],
+    '#options' => $group_options
+  );
   $form['settings']['#tree'] = TRUE;
   $form['settings']['form'] = array(
     '#type' => 'fieldset',
@@ -290,24 +301,51 @@
 function fieldgroup_form_alter($form_id, &$form) {
   if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
     foreach (fieldgroup_groups($form['type']['#value']) as $group_name => $group) {
-      $form[$group_name] = array(
-        '#type' => 'fieldset',
-        '#title' => check_plain(t($group['label'])),
-        '#collapsed' => $group['settings']['form']['style'] == 'fieldset_collapsed',
-        '#collapsible' => in_array($group['settings']['form']['style'], array('fieldset_collapsed', 'fieldset_collapsible')),
-        '#weight' => $group['weight'],
-        '#description' => content_filter_xss(t($group['settings']['form']['description'])),
-        '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
-      );
+      if ($group['settings']['parent'] && arg(0) != 'admin') {
+        $form[$group['settings']['parent']][$group_name] = array(
+          '#type' => 'fieldset',
+          '#title' => t($group['label']),
+          '#collapsed' => $group['settings']['collapsed'],
+          '#collapsible' => $group['settings']['collapsible'],
+          '#description' => $group['description'],
+          '#weight' => $group['weight'],
+          '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
+        );
+      } 
+      else {
+        $form[$group_name] = array(
+          '#type' => 'fieldset',
+          '#title' => t($group['label']),
+          '#collapsed' => $group['settings']['collapsed'],
+          '#collapsible' => $group['settings']['collapsible'],
+          '#description' => $group['description'],
+          '#weight' => $group['weight'],
+          '#attributes' => array('class' => strtr($group['group_name'], '_', '-')),
+        );
+      }
       foreach ($group['fields'] as $field_name => $field) {
         if (isset($form[$field_name])) {
-          $form[$group_name][$field_name] = $form[$field_name];
+          if ($group['settings']['parent'] && arg(0) != 'admin') {
+            $form[$group['settings']['parent']][$group_name][$field_name] = $form[$field_name];
+          }
+          else {
+            $form[$group_name][$field_name] = $form[$field_name];
+          }
           unset($form[$field_name]);
         }
       }
-      if (!empty($group['fields']) && !element_children($form[$group_name])) {
-        //hide the fieldgroup, because the fields are hidden too
-        unset($form[$group_name]);
+      if (!empty($group['fields'])) {
+        // Hide the fieldgroup, because the fields are hidden too.
+        if ($group['settings']['parent'] && arg(0) != 'admin') {
+          if (!element_children($form[$group['settings']['parent']][$group_name])) {
+            unset($form[$group['settings']['parent']][$group_name]);
+          }
+        }
+        else {
+          if (!element_children($form[$group_name])) {
+            unset($form[$group_name]);
+          }
+        }
       }
     }
 
@@ -364,7 +402,15 @@
   switch ($op) {
     case 'view':
       $context = $teaser ? 'teaser' : 'full';
-      foreach (fieldgroup_groups($node->type) as $group_name => $group) {
+      $parent_groups = array();
+      $groups = fieldgroup_groups($node->type);
+      foreach ($groups as $group_name => $group) {
+        if ($group['settings']['parent']) {
+          $parent_groups[] = $group['settings']['parent'];
+        }
+      }
+      $visible_parent_groups = array();
+      foreach ($groups as $group_name => $group) {
         $label = $group['settings']['display']['label'] == 'above';
         $element = array(
           '#title' => $label ? check_plain(t($group['label'])) : '',
@@ -388,20 +434,54 @@
             $element['#type'] = 'fieldset';
             break;
         }
-        $node->content[$group_name] = $element;
+        if ($group['settings']['parent']) {
+          $node->content[$group['settings']['parent']][$group_name] = $element;
+        }
+        else {
+          $node->content[$group_name] = $element;
+        }
 
         $visible = FALSE;
+        // Check if this group is a parent of any other.
+        if (in_array($group_name, $parent_groups)) {
+          $visible = TRUE;
+        }
         foreach ($group['fields'] as $field_name => $field) {
           if (isset($node->content[$field_name])) {
-            $node->content[$group_name][$field_name] = $node->content[$field_name];
+            if ($group['settings']['parent']) {
+              $node->content[$group['settings']['parent']][$group_name][$field_name] = $node->content[$field_name];
+            }
+            else {
+              $node->content[$group_name][$field_name] = $node->content[$field_name];
+            }
             if ($node->content[$field_name]['#access'] && !empty($node->content[$field_name]['#value'])) {
               $visible = TRUE;
+              // If this fieldgroup has a parent, is visible and isn't already
+              // in the list of visible parents, add it.
+              if ($group['settings']['parent'] && !in_array($group['settings']['parent'], $visible_parent_groups)) {
+                $visible_parent_groups[] = $group['settings']['parent'];
+              }
+              // May not need to check current group, but is best to be safe.
+              if (!in_array($group_name, $visible_parent_groups)) {
+                $visible_parent_groups[] = $group_name;
+              }
             }
             unset($node->content[$field_name]);
           }
         }
         if (!$visible) {
           // Hide the group, because the fields are empty or not accessible.
+          if ($group['settings']['parent']) {
+            unset($node->content[$group['settings']['parent']][$group_name]);
+          }
+          else {
+            unset($node->content[$group_name]);
+          }
+        }
+      }
+      // Unset all parent fieldgroups that don't have any visible children.
+      foreach ($parent_groups as $group_name) {
+        if (!in_array($group_name, $visible_parent_groups)) {
           unset($node->content[$group_name]);
         }
       }
