docs: function($target, customRule) {
  
          var $form = null, _id = null;
  
          try {
              if ( $target.getAttribute && $target.getAttribute('id') ) {
                  _id = $target.getAttribute('id');
                  if ( typeof(instance.$forms[_id]) != 'undefined')
                      $form = instance.$forms[_id];
                  else
                      throw new Error('form instance `'+ _id +'` not found');
  
              } else {
                  throw new Error('Validator::bindForm($target, customRule): `$target` must be a DOM element\n'+err.stack )
              }
          } catch(err) {
              throw new Error('Validator::bindForm($target, customRule) could not bind form `'+ $target +'`\n'+err.stack )
          }
  
          if ( typeof($form) != 'undefined' && $form.binded) {
              return false
          }
  
          var withRules = false, rule = null, evt = '', procced = null;
  
          if ( typeof(customRule) != 'undefined' || typeof(_id) == 'string' && typeof(instance.rules[_id.replace(/\-/g, '.')]) != 'undefined' ) {
              withRules = true;
  
              if ( customRule && typeof(customRule) == 'object' ) {
                  rule = customRule
              } else if ( customRule && typeof(customRule) == 'string' && typeof(instance.rules[customRule.replace(/\-/g, '.')]) != 'undefined') {
                  rule = instance.rules[customRule.replace(/\-/g, '.')]
              } else {
                  rule = instance.rules[_id.replace(/\-/g, '.')]
              }
  
              $form.rules = rule
          }
  
          // form fields
          if (!$form.defaultFields)
              $form.defaultFields = {};
  
          // binding form elements
          var type        = null
              , id        = null
              // input: checkbox, radio
              , $inputs   = $target.getElementsByTagName('input')
              // select
              , $select   = $target.getElementsByTagName('select')
          ;
  
          var elId = null;
          for (var i = 0, len = $inputs.length; i < len; ++i) {
              elId = $inputs[i].getAttribute('id');
              if (!elId) {
                  elId = 'input.' + uuid.v1();
                  $inputs[i].setAttribute('id', elId)
              }
  
              if (!$form.defaultFields[ elId ])
                  $form.defaultFields[ elId ] = $inputs[i].value;
          }
  
          var selectedIndex = null, selectedValue = null;
          for (var s = 0, sLen = $select.length; s < sLen; ++s) {
              elId = $select[s].getAttribute('id');
              if (!elId) {
                  elId = 'select.' + uuid.v1();
                  $select[s].setAttribute('id', elId)
              }
  
              if ($select[s].options && !$form.defaultFields[ elId ]) {
                  selectedIndex = 0;
                  selectedValue = $select[s].getAttribute('data-value');
  
                  if ( $select[s].options[ $select[s].selectedIndex ].index ) {
                      selectedIndex = $select[s].options[ $select[s].selectedIndex ].index
                  } else if ( typeof(selectedValue) != 'undefined' ) {
                      for (var o = 0, oLen = $select[s].options.length; o < oLen; ++o ) {
                          if ( $select[s].options[o].value == selectedValue) {
                              selectedIndex = o;
                              break
                          }
                      }
                  }
  
                  $form.defaultFields[ elId ] = selectedIndex;
                  // update select
                  $select[s].options[ selectedIndex ].selected = true;
                  $select[s].setAttribute('data-value',  $select[s].options[ selectedIndex ].value);
  
              }
          }
  
          var updateCheckBox = function($el) {
  
              var checked     = $el.checked;
  
              if ( !checked || checked == 'null' || checked == 'false' || checked == '' ) {
  
                  // prevents ticking behavior
                  setTimeout(function () {
                      $el.checked = false;
                  }, 0);
  
                  $el.removeAttribute('checked');
                  $el.value = false;
                  $el.setAttribute('value', 'false');
  
              } else {
  
                  // prevents ticking behavior
                  setTimeout(function () {
                      $el.checked = true;
                  }, 0);
  
                  $el.setAttribute('checked', 'checked');
                  //boolean exception handling
                  $el.value = true;
                  $el.setAttribute('value', 'true');
  
              }
          };
  
          var updateRadio = function($el, isInit) {
              var checked = $el.checked;
              var isBoolean = /^(true|false)$/i.test($el.value);
  
              // loop if radio group
              if (!isInit) {
                  var radioGroup = document.getElementsByName($el.name);
                  //console.log('found ', radioGroup.length, radioGroup)
                  for (var r = 0, rLen = radioGroup.length; r < rLen; ++r) {
                      if (radioGroup[r].id !== $el.id) {
                          radioGroup[r].checked = false;
                          radioGroup[r].removeAttribute('checked');
                      }
                  }
              }
  
              if ( !checked || checked == 'null' || checked == 'false' || checked == '' ) {
  
                  // prevents ticking behavior
                  setTimeout(function () {
                      $el.checked = false;
                  }, 0)
  
                  $el.removeAttribute('checked');
  
                  if (isBoolean) {
                      $el.value = false;
                  }
  
              } else {
  
                  // prevents ticking behavior
                  setTimeout(function () {
                      $el.checked = true;
                  }, 0)
  
                  $el.setAttribute('checked', 'checked');
  
                  if (isBoolean) { // no multiple choice supported
                      $el.value = true;
                  }
                  var radioGroup = document.getElementsByName($el.name);
                      //console.log('found ', radioGroup.length, radioGroup)
                      for (var r = 0, rLen = radioGroup.length; r < rLen; ++r) {
                          if (radioGroup[r].id !== $el.id) {
                              radioGroup[r].checked = false;
                              radioGroup[r].removeAttribute('checked');
                              if (isBoolean) {
                                  radioGroup[r].value = false;
                              }
                          }
                      }
  
  
              }
          }
  
          evt = 'click';
  
          procced = function () {
              // click proxy
              addListener(gina, $target, 'click', function(event) {
  
                  if ( /(label)/i.test(event.target.tagName) )
                      return false;
  
                  if ( typeof(event.target.id) == 'undefined' || !event.target.getAttribute('id') ) {
                      event.target.setAttribute('id', 'click.' + uuid.v1() );
                      event.target.id = event.target.getAttribute('id')
                  } else {
                      event.target.id = event.target.getAttribute('id')
                  }
  
  
                  if (/^click\./.test(event.target.id) || withRules) {
  
                      var _evt = event.target.id;
  
                      if (!_evt) return false;
  
                      if ( ! /^click\./.test(_evt) ) {
                          _evt = event.target.id
                      }
  
                      // prevent event to be triggered twice
                      if ( typeof(event.defaultPrevented) != 'undefined' && event.defaultPrevented )
                          return false;
  
                      if (gina.events[_evt]) {
                          cancelEvent(event);
  
                          triggerEvent(gina, event.target, _evt, event.detail);
                      }
  
                  }
  
              })
          }
  
  
          procced()
  
          for (var i=0, len = $inputs.length; i<len; ++i) {
              type    = $inputs[i].getAttribute('type');
  
              if ( typeof($inputs[i].id) == 'undefined' || $inputs[i].id == '' ) {
                  $inputs[i]['id'] = type +'-'+ uuid.v1();
                  $inputs[i].setAttribute('id', $inputs[i]['id'])
              }
  
  
              // recover default state only on value === true || false || on
              if ( typeof(type) != 'undefined' && type == 'checkbox' && /^(true|false|on)$/i.test($inputs[i].value) || typeof(type) != 'undefined' && type == 'checkbox' && !$inputs[i].getAttribute('value') ) {
  
                  if ( !/^(true|false|on)$/i.test($inputs[i].value)  ) {
  
                      if ( !$inputs[i].checked || $inputs[i].checked == 'null' || $inputs[i].checked == 'false' || $inputs[i].checked == '' ) {
                          $inputs[i].value = false;
                          $inputs[i].setAttribute('value', false)
                      } else {
                          $inputs[i].value = true;
                          $inputs[i].setAttribute('value', true)
                      }
                  }
  
  
                  evt = $inputs[i].id;
  
                  procced = function ($el, evt) {
  
                      // recover default state only on value === true || false
                      addListener(gina, $el, evt, function(event) {
  
                          if ( /^(true|false|on)$/i.test(event.target.value) ) {
                              cancelEvent(event);
                              updateCheckBox(event.target);
                          }
                      });
  
                      // default state recovery
                      var value = $el.value || $el.getAttribute('value') || $el.getAttribute('data-value');
                      if ( /^(true|false|on)$/i.test(value)  ) {
  
                          if ( typeof(value) != 'undefined' && /^(true|on|false)$/.test(value) ) {
                              $el.checked = /true|on/.test(value) ? true : false;
                          }
  
                          updateCheckBox($el);
                      }
  
  
                  }
  
                  if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == $inputs[i].id ) {
                      removeListener(gina, $inputs[i], evt);
                      procced($inputs[i], evt)
  
                  } else {
                      procced($inputs[i], evt)
                  }
  
              } else if ( typeof(type) != 'undefined' && type == 'radio' ) {
  
                  evt = $inputs[i].id;
  
                  procced = function ($el, evt) {
                      addListener(gina, $el, evt, function(event) {
  
                          cancelEvent(event);
                          updateRadio(event.target);
                      });
  
  
                      updateRadio($el, true);
                  }
  
                  if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == $inputs[i].id ) {
                      removeListener(gina, $inputs[i], evt);
                      procced(event.target, evt)
  
                  } else {
                      procced($inputs[i], evt)
                  }
              }
          }
  
  
          if (withRules) {
  
              evt = 'validate.' + _id;
              procced = function () {
  
                  // attach form event
                  addListener(gina, $target, evt, function(event) {
                      cancelEvent(event);
  
  
                      var result = event['detail'] || $form.eventData.validation;
                      //console.log('$form[ '+_id+' ] validation done !!!\n isValid ? ', result['isValid'](), '\nErrors -> ', result['errors'], '\nData -> ', result['data']);
  
                      handleErrorsDisplay(event['target'], result['errors'], result['data']);
  
                      var _id = event.target.getAttribute('id');
  
                      if ( result['isValid']() ) { // send if valid
                          // now sending to server
                          // TODO - remove comments, or replace 'submit' by 'submit.' + _id
                          //if ( $form.withUserBindings && /validate\./.test(event.type) && typeof(gina.events[event.type]) != 'undefined' ) {
                          //    triggerEvent(gina, event.target, 'submit', result)
                          //} else {
  
                              if (instance.$forms[_id]) {
                                  instance.$forms[_id].send(result['data']);
                              } else if ($form) { // just in case the form is being destroyed
                                  $form.send(result['data']);
                              }
                          //}
                      }
  
                      return false
  
                  })
              }
  
              if ( typeof(gina.events[evt]) != 'undefined' && gina.events[evt] == 'validate.' + _id ) {
                  removeListener(gina, $form, evt, procced)
              } else {
                  procced()
              }
  
  
  
              var proccedToSubmit = function (evt, $submit) {
                  // console.log('placing submit ', evt, $submit);
                  // attach submit events
                  addListener(gina, $submit, evt, function(event) {
                      // start validation
                      cancelEvent(event);
  
                      // getting fields & values
                      var $fields     = {}
                          , fields    = { '_length': 0 }
                          , id        = $target.getAttribute('id')
                          , rules     = ( typeof(gina.validator.$forms[id]) != 'undefined' ) ? gina.validator.$forms[id].rules : null
                          , name      = null
                          , value     = 0
                          , type      = null
                          , index     = { checkbox: 0, radio: 0 };
  
  
                      for (var i = 0, len = $target.length; i<len; ++i) {
  
                          name    = $target[i].getAttribute('name');
  
                          if (!name) continue;
  
                          // TODO - add switch cases against tagName (checkbox/radio)
                          if ( typeof($target[i].type) != 'undefined' && $target[i].type == 'radio' || typeof($target[i].type) != 'undefined' && $target[i].type == 'checkbox' ) {
  
                              if ( $target[i].checked ) {
                                  fields[name] = $target[i].value
                              }  else if ( // force validator to pass `false` if boolean is required explicitly
                              rules
                              && typeof(rules[name]) != 'undefined'
                              && typeof(rules[name].isBoolean)
                              && typeof(rules[name].isRequired)
                              ) {
                                  fields[name] = false;
                              }
  
                          } else {
                              fields[name]    = $target[i].value;
                          }
  
  
                          $fields[name]   = $target[i];
                          // reset filed error data attributes
                          $fields[name].setAttribute('data-gina-form-errors', '');
  
                          ++fields['_length']
                      }
  
                      //console.log('$fields =>\n' + $fields);
  
                      //instance.$forms[ $target.getAttribute('id') ].sent = false;
  
                      if ( fields['_length'] == 0 ) { // nothing to validate
                          delete fields['_length'];
                          var result = {
                              'errors'    : [],
                              'isValid'   : function() { return true },
                              'data'      : formatData(fields)
                          };
  
                          triggerEvent(gina, $target, 'validate.' + _id, result)
  
                      } else {
                          // update rule in case the current event is triggered outside the main sequence
                          // e.g.: form `id` attribute rewritten on the fly
                          _id = $target.getAttribute('id');
                          var customRule = $target.getAttribute('data-gina-form-rule');
  
                          if ( customRule ) { // 'data-gina-form-rule'
                              rule = gina.validator.rules[ customRule.replace(/\-/g, '.') ];
                          } else {
                              rule = gina.validator.$forms[ _id ].rules;
                          }
  
                          //console.log('testing rule [ '+_id.replace(/\-/g, '.') +' ]\n'+ JSON.stringify(rule, null, 4));
                          //console.log('validating ', $form, fields, rule);
                          validate($target, fields, $fields, rule, function onValidation(result){
                              //console.log('validation result ', 'validate.' + _id, JSON.stringify(result.data, null, 2));
                              //console.log('events ', 'validate.' + _id, self.events )
                              triggerEvent(gina, $target, 'validate.' + _id, result)
                          })
                      }
  
                  });
              }
  
  
              // binding submit button
              var $submit = null, $buttons = [], $buttonsTMP = [], buttonId = null;
              $buttonsTMP = $target.getElementsByTagName('button');
              if ( $buttonsTMP.length > 0 ) {
                  for(var b = 0, len = $buttonsTMP.length; b < len; ++b) {
                      if ($buttonsTMP[b].type == 'submit')
                          $buttons.push($buttonsTMP[b])
                  }
              }
  
              $buttonsTMP = $target.getElementsByTagName('a');
              if ( $buttonsTMP.length > 0 ) {
                  for(var b = 0, len = $buttonsTMP.length; b < len; ++b) {
                      if ( $buttonsTMP[b].attributes.getNamedItem('data-gina-form-submit'))
                          $buttons.push($buttonsTMP[b])
                  }
              }
  
  
              var onclickAttribute = null, isSubmitType = false;
              for (var b=0, len=$buttons.length; b<len; ++b) {
  
                  $submit = $buttons[b];
  
                  if ($submit.tagName == 'A') { // without this test, XHR callback is ignored
                      //console.log('a#$buttons ', $buttonsTMP[b]);
                      onclickAttribute    = $submit.getAttribute('onclick');
                      isSubmitType        = $submit.getAttribute('data-gina-form-submit');
  
                      if ( !onclickAttribute && !isSubmitType) {
                          $submit.setAttribute('onclick', 'return false;')
                      } else if ( !/return false/ && !isSubmitType) {
                          if ( /\;$/.test(onclickAttribute) ) {
                              onclickAttribute += 'return false;'
                          } else {
                              onclickAttribute += '; return false;'
                          }
                      }
                  }
  
                  if (!$submit['id']) {
  
                      evt = 'click.'+ uuid.v1();
                      $submit['id'] = evt;
                      $submit.setAttribute( 'id', evt);
  
                  } else {
                      evt = $submit['id'];
                  }
  
  
                  if ( typeof(gina.events[evt]) == 'undefined' || gina.events[evt] != $submit.id ) {
                      proccedToSubmit(evt, $submit)
                  }
  
              }
          }
  
  
  
          evt = 'submit';
  
          // submit proxy
          addListener(gina, $target, evt, function(e) {
  
              var $target     = e.target
                  , id        = $target.getAttribute('id')
                  , isBinded  = instance.$forms[id].binded
              ;
  
              // prevent event to be triggered twice
              if ( typeof(e.defaultPrevented) != 'undefined' && e.defaultPrevented )
                  return false;
  
              if (withRules || isBinded) {
                  cancelEvent(e);
              }
  
  
              // just collect data for over forms
              // getting fields & values
              var $fields     = {}
                  , fields    = { '_length': 0 }
                  , id        = $target.getAttribute('id')
                  , rules     = ( typeof(gina.validator.$forms[id]) != 'undefined' ) ? gina.validator.$forms[id].rules : null
                  , name      = null
                  , value     = 0
                  , type      = null
                  , index     = { checkbox: 0, radio: 0 };
  
  
              for (var i = 0, len = $target.length; i<len; ++i) {
                  name = $target[i].getAttribute('name');
  
                  if (!name) continue;
  
                  // checkbox/radio
                  if ( typeof($target[i].type) != 'undefined' && $target[i].type == 'radio' || typeof($target[i].type) != 'undefined' && $target[i].type == 'checkbox' ) {
  
                      if ( $target[i].checked ) {
                          fields[name] = $target[i].value
                      }  else if ( // force validator to pass `false` if boolean is required explicitly
                      rules
                      && typeof(rules[name]) != 'undefined'
                      && typeof(rules[name].isBoolean)
                      && typeof(rules[name].isRequired)
                      ) {
                          fields[name] = false;
                      }
  
                  } else {
                      fields[name]    = $target[i].value;
                  }
  
  
  
                  $fields[name] = $target[i];
                  // reset filed error data attributes
                  $fields[name].setAttribute('data-gina-form-errors', '');
  
                  ++fields['_length']
              }
  
  
              if ( fields['_length'] == 0 ) { // nothing to validate
  
                  delete fields['_length'];
                  var result = {
                      'errors'    : [],
                      'isValid'   : function() { return true },
                      'data'      : formatData(fields)
                  };
  
                  if ( typeof(gina.events['submit.' + id]) != 'undefined' ) { // if `on('submit', cb)` is binded
                      triggerEvent(gina, $target, 'submit.' + id, result);
                  } else {
                      triggerEvent(gina, $target, 'validate.' + id, result);
                  }
  
              } else {
                  // update rule in case the current event is triggered outside the main sequence
                  // e.g.: form `id` attribute rewritten on the fly
                  //ruleId = id.replace(/-/g, '.');
                  //if ( typeof(instance.$forms[id].rules) != 'undefined' )
                  //    rule = instance.$forms[id].rules;
  
                  var customRule = $target.getAttribute('data-gina-form-rule');
  
                  if ( customRule ) { // 'data-gina-form-rule'
                      rule = gina.validator.rules[ customRule.replace(/\-/g, '.') ];
                  } else {
                      rule = gina.validator.$forms[ id ].rules;
                  }
  
                  validate($target, fields, $fields, rule, function onValidation(result){
                      if ( typeof(gina.events['submit.' + id]) != 'undefined' ) { // if `on('submit', cb)` is binded
                          triggerEvent(gina, $target, 'submit.' + id, result);
                      } else {
                          triggerEvent(gina, $target, 'validate.' + id, result);
                      }
                  })
              }
          });
  
          instance.$forms[_id]['binded']  = true;
      }