Index: webform_hooks.php
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform_hooks.php,v
retrieving revision 1.9.2.3
diff -u -r1.9.2.3 webform_hooks.php
--- webform_hooks.php	29 Mar 2010 03:19:49 -0000	1.9.2.3
+++ webform_hooks.php	10 Apr 2010 00:17:10 -0000
@@ -180,8 +180,12 @@
  *
  *     - csv
  *     - email
+ *     - email_address
+ *     - email_name
  *     - required
  *     - conditional
+ *     - spam_analysis
+ *     - group
  *
  *   Note that these features do not indicate the default state, but determine
  *   if the component can have this property at all. Setting "required" to TRUE
Index: webform.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/webform.module,v
retrieving revision 1.196.2.18
diff -u -r1.196.2.18 webform.module
--- webform.module	8 Apr 2010 07:54:18 -0000	1.196.2.18
+++ webform.module	10 Apr 2010 00:17:10 -0000
@@ -657,6 +657,7 @@
       'features' => array(
         'required' => FALSE,
         'conditional' => FALSE,
+        'group' => TRUE,
       ),
       'file' => 'components/fieldset.inc',
     ),
@@ -1958,7 +1959,7 @@
   if (is_array($form_values)) {
     foreach ($form_values as $form_key => $value) {
       $cid = webform_get_cid($node, $form_key, $parent);
-      if (is_array($value) && isset($node->webform['components'][$cid]['type']) && $node->webform['components'][$cid]['type'] == 'fieldset') {
+      if (is_array($value) && isset($node->webform['components'][$cid]['type']) && webform_component_feature($node->webform['components'][$cid]['type'], 'group')) {
         _webform_client_form_submit_process($node, $form_values[$form_key], $types, $cid);
       }
 
@@ -1986,7 +1987,7 @@
     foreach ($fieldset as $form_key => $value) {
       $cid = webform_get_cid($node, $form_key, $parent);
 
-      if (is_array($value) && $node->webform['components'][$cid]['type'] == 'fieldset') {
+      if (is_array($value) && webform_component_feature($node->webform['components'][$cid]['type'], 'group')) {
         $values += _webform_client_form_submit_flatten($node, $value, $cid);
       }
       else {
@@ -2088,10 +2089,11 @@
  */
 function theme_webform_element_text($element, $value) {
   $output = '';
+  $is_group = webform_component_feature($element['#component']['type'], 'group');
 
   // Output the element title.
   if (isset($element['#title'])) {
-    if ($element['#component']['type'] == 'fieldset') {
+    if ($is_group) {
       $output .= '--' . $element['#title'] . '--';
     }
     elseif (!in_array(substr($element['#title'], -1), array('?', ':', '!', '%', ';', '@'))) {
@@ -2104,7 +2106,7 @@
 
   // Wrap long values at 65 characters, allowing for a few fieldset indents.
   // It's common courtesy to wrap at 75 characters in e-mails.
-  if ($element['#component']['type'] != 'fieldset' && strlen($value) > 65) {
+  if ($is_group && strlen($value) > 65) {
     $value = wordwrap($value, 65, "\n");
     $lines = explode("\n", $value);
     foreach ($lines as $key => $line) {
@@ -2119,7 +2121,7 @@
   }
 
   // Indent fieldsets.
-  if ($element['#component']['type'] == 'fieldset') {
+  if ($is_group) {
     $lines = explode("\n", $output);
     foreach ($lines as $number => $line) {
       if (strlen($line)) {
Index: includes/webform.components.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/webform/includes/webform.components.inc,v
retrieving revision 1.25.2.11
diff -u -r1.25.2.11 webform.components.inc
--- includes/webform.components.inc	3 Apr 2010 02:49:16 -0000	1.25.2.11
+++ includes/webform.components.inc	10 Apr 2010 00:17:11 -0000
@@ -198,7 +198,7 @@
         l(t('Delete'), 'node/' . $node->nid . '/webform/components/' . $cid . '/delete', array('query' => drupal_get_destination())),
       );
       $row_class = 'draggable';
-      if ($component['type'] != 'fieldset' && $component['type'] != 'pagebreak') {
+      if (!webform_component_feature($component['type'], 'group') && $component['type'] != 'pagebreak') {
         $row_class .= ' tabledrag-leaf';
       }
       if ($component['type'] == 'pagebreak') {
@@ -399,7 +399,7 @@
   if (variable_get('webform_enable_fieldset', TRUE) && is_array($node->webform['components'])) {
     $options = array('0' => t('Root'));
     foreach ($node->webform['components'] as $existing_cid => $value) {
-      if ($value['type'] == 'fieldset' && (!isset($component['cid']) || $existing_cid != $component['cid'])) {
+      if (webform_component_feature($value['type'], 'group') && (!isset($component['cid']) || $existing_cid != $component['cid'])) {
         $options[$existing_cid] = $value['name'];
       }
     }
@@ -597,7 +597,7 @@
     '#value' => $component,
   );
 
-  if ($node->webform['components'][$cid]['type'] == 'fieldset') {
+  if (webform_component_feature($node->webform['components'][$cid]['type'], 'group')) {
     $question = t('Delete the %name fieldset?', array('%name' => $node->webform['components'][$cid]['name']));
     $description = t('This will immediately delete the %name fieldset and all children elements within %name from the %webform webform. This cannot be undone.', array('%name' => $node->webform['components'][$cid]['name'], '%webform' => $node->title));
   }
@@ -707,7 +707,7 @@
   $original_cid = $component['cid'];
   unset($component['cid']);
   $new_cid = webform_component_insert($component);
-  if ($component['type'] == 'fieldset') {
+  if (webform_component_feature($component['type'], 'group')) {
     foreach ($node->webform['components'] as $cid => $child_component) {
       if ($child_component['pid'] == $original_cid) {
         $child_component['pid'] = $new_cid;
@@ -731,6 +731,7 @@
     'required' => TRUE,
     'conditional' => TRUE,
     'spam_analysis' => FALSE,
+    'group' => FALSE,
   );
   return isset($components[$type]['features'][$feature]) ? $components[$type]['features'][$feature] : $defaults[$feature];
 }
