diff --git a/sites/all/modules/webform_validation/webform_validation.module b/sites/all/modules/webform_validation/webform_validation.module
index 02042e3..58fcec3 100644
--- a/sites/all/modules/webform_validation/webform_validation.module
+++ b/sites/all/modules/webform_validation/webform_validation.module
@@ -147,6 +147,15 @@ function webform_validation_validate($form, &$form_state) {
         if (isset($flat_values[$cid])) {
           $items[$cid] = $flat_values[$cid];
         }
+        if (webform_component_feature($component['type'], 'group')) {
+          $childs = webform_validation_get_all_childs($nid, $cid);
+          $child_keys = array_keys($childs);
+          foreach ($child_keys as $child_key) {
+            $items[$cid][$child_key] = $flat_values[$child_key];
+          }
+          // prefix childs array keys for consistence (see later)
+          $items[$cid] = webform_validation_prefix_keys($items[$cid]);
+        }
       }
       // prefix array keys to avoid reindexing by the module_invoke_all function call
       $items = webform_validation_prefix_keys($items);
@@ -157,9 +166,11 @@ function webform_validation_validate($form, &$form_state) {
         $errors = webform_validation_unprefix_keys($errors);
         $components = webform_validation_unprefix_keys($component_definitions);
         foreach ($errors as $item_key => $error) {
-          // build the proper form element error key, taking into account hierarchy
-          $error_key = 'submitted][' . webform_validation_parent_tree($item_key, $components) . $components[$item_key]['form_key'];
-          form_set_error($error_key, $error);
+          if (!webform_component_feature($component['type'], 'group')) {
+            // build the proper form element error key, taking into account hierarchy
+            $error_key = 'submitted][' . webform_validation_parent_tree($item_key, $components) . $components[$item_key]['form_key'];
+            form_set_error($error_key, $error);
+          }
         }
       }
     }
diff --git a/sites/all/modules/webform_validation/webform_validation.rules.inc b/sites/all/modules/webform_validation/webform_validation.rules.inc
index ce483f0..0ec1e21 100644
--- a/sites/all/modules/webform_validation/webform_validation.rules.inc
+++ b/sites/all/modules/webform_validation/webform_validation.rules.inc
@@ -64,6 +64,18 @@ function webform_validation_get_all_components($nid) {
 }
 
 /**
+ * Get info on all components childs that are available on a webform
+ */
+function webform_validation_get_all_childs($nid, $pid) {
+  $components = array();
+  $result = db_query("SELECT * FROM {webform_component} WHERE nid = :nid AND pid = :pid", array(':nid' => $nid, ':pid' => $pid), array('fetch' => PDO::FETCH_ASSOC));
+  foreach ($result as $row) {
+    $components[$row['cid']] = $row;
+  }
+  return $components;
+}
+
+/**
  * This helper function takes a list of full component info arrays and returns a basic representation of it for output purposes.
  */
 function webform_validation_rule_components_basic($components) {
diff --git a/sites/all/modules/webform_validation/webform_validation.validators.inc b/sites/all/modules/webform_validation/webform_validation.validators.inc
index d777c03..5432085 100644
--- a/sites/all/modules/webform_validation/webform_validation.validators.inc
+++ b/sites/all/modules/webform_validation/webform_validation.validators.inc
@@ -240,6 +240,37 @@ function webform_validation_webform_validation_validators() {
       ),
       'description' => t("Validates that user-entered data matches a username"),
     ),
+    'required' => array(
+      'name' => 'Required (workaround for set personal error message)',
+      'component_types' => array(
+        'textfield',
+        'textarea',
+        'email',
+        'hidden',
+      ),
+      'custom_error' => TRUE,
+      'description' => t('Make fields required with a custom error message. You could use %name for the label of fields in error messages'),
+    ),
+    'fieldset_child_required' => array(
+      'name' => 'Fieldset Child Required',
+      'component_types' => array(
+        'fieldset',
+      ),
+      'custom_data' => array(
+        'label' => t('Minimum number of childs required'),
+        'description' => t('Optionally specify the minimum number of childs required.') . ' '
+          . t('Usage') . ':' . theme('item_list', array(
+            'items' => array(
+              t('empty: all childs is required'),
+              t('"4": minimum 4 childs required'),
+            )
+          )
+        ),
+        'required' => FALSE,
+      ),
+      'custom_error' => TRUE,
+      'description' => t('Make fieldset childs required. Validation is made by "required" rule'),
+    ),
   );
 }
 
@@ -474,6 +505,78 @@ function webform_validation_webform_validation_validate($validator_name, $items,
         }
         return $errors;
         break;
+      case 'required':
+        foreach ($items as $key => $val) {
+          $trimmed = trim($val);
+          if ($trimmed === '') {
+            $name = $components[$key]['name'];
+            $error_message = str_ireplace('%name', $name, $rule['error_message']);
+            $errors[$key] = check_plain($error_message);
+          }
+        }
+        return $errors;
+        break;
+      case 'fieldset_child_required':
+        if ($rule['data'] !== '') {
+          $matches = array();
+          if (!preg_match('/^\s*?([0-9]+)\s*?$/', $rule['data'], $matches)) {
+            $min_required = NULL;
+          }
+          else {
+            $min_required = $matches[1];
+          }
+        }
+        else {
+          $min_required = NULL;
+        }
+
+        foreach ($items as $key => $childs) {
+          $total_childs = count($childs);
+
+          // TODO: if a fieldset have also a child fieldset how happens?
+          // TODO: For validate required child is used "required" validator.
+          //       Required validato works only for some component_types (textarea, textfield, email and hidden)
+          //       is needed to check if child type is supported.
+          $childs_errors = module_invoke_all("webform_validation_validate", 'required', $childs, $components, $rule);
+          $empty_childs = count($childs_errors);
+          $filled_childs = $total_childs - $empty_childs;
+
+          if (isset($min_required) && ($min_required <= $total_childs)) {
+            if ($filled_childs < $min_required) {
+              $delta_required = $min_required - $filled_childs;
+            }
+            else {
+              $delta_required = 0;
+            }
+          }
+          else {
+            $delta_required = $empty_childs;
+          }
+
+
+          if ($delta_required > 0) {
+            $fieldset_error = check_plain($rule['error_message']);
+
+            $childs_errors = webform_validation_unprefix_keys($childs_errors);
+            $other_components = webform_validation_unprefix_keys($components);
+
+            $childs_keys = array_keys($childs_errors);
+
+            foreach ($childs_keys as $child_key) {
+              if ($delta_required > 0) {
+                $delta_required -= 1;
+                // build the proper form element error key, taking into account hierarchy
+                $error_key = 'submitted][' . webform_validation_parent_tree($child_key, $other_components) . $other_components[$child_key]['form_key'];
+                form_set_error($error_key, $fieldset_error);
+
+              }
+            }
+            // Don't show replicated error message (set only 1 general error for fieldset)
+            $_SESSION['messages']['error'] = array_unique($_SESSION['messages']['error']);
+          }
+        }
+        return $errors;
+        break;
     }
   }
 }
