docs: function State() {
      var name, opts, f;
  
      if (arguments.length === 3 && typeof arguments[0] === 'string' && typeof arguments[1] === 'object' && typeof arguments[2] === 'function') {
        name = arguments[0];
        opts = arguments[1];
        f = arguments[2];
      }
      else if (arguments.length === 2 && typeof arguments[0] === 'string' && typeof arguments[1] === 'object') {
        name = arguments[0];
        opts = arguments[1];
        f = function() {};
      }
      else if (arguments.length === 2 && typeof arguments[0] === 'string' && typeof arguments[1] === 'function') {
        name = arguments[0];
        opts = {};
        f = arguments[1];
      }
      else if (arguments.length === 2 && typeof arguments[0] === 'object' && typeof arguments[1] === 'function') {
        name = '';
        opts = arguments[0];
        f = arguments[1];
      }
      else if (arguments.length === 1 && typeof arguments[0] === 'string') {
        name = arguments[0];
        opts = {};
        f = function() {};
      }
      else if (arguments.length === 1 && typeof arguments[0] === 'object') {
        name = '';
        opts = arguments[0];
        f = function() {};
      }
      else if (arguments.length === 1 && typeof arguments[0] === 'function') {
        name = '';
        opts = {};
        f = arguments[0];
      }
      else if (arguments.length === 0) {
        name = '';
        opts = {};
        f = function() {};
      }
      else {
        throw new TypeError('State: invalid arguments');
      }
  
      if (opts.concurrent && opts.H) {
        throw new Error('State: history states are not allowed on concurrent states');
      }
  
      this.name            = name;
      this.substateMap     = {};
      this.substates       = [];
      this.superstate      = null;
      this.enters          = [];
      this.exits           = [];
      this.events          = {};
      this.concurrent      = !!opts.concurrent;
      this.history         = !!(opts.H);
      this.deep            = opts.H === '*';
      this.__isCurrent__   = false;
      this.__cache__       = {};
      this.__transitions__ = [];
      this.trace           = false;
  
      if (f) { f.call(this); }
    }