docs: function Rule(ruleString, params, data) {
      Tools.call(this, ruleString);
  
      /**
       * @public
       * @memberOf {Rule}
       * @property
       * @type {Object}
       * */
      this.params = _.extend({
          basePath: '',
          queryEq: '=',
          querySep: '&'
      }, params);
  
      /**
       * @public
       * @memberOf {Rule}
       * @property
       * @type {Object}
       * */
      this.data = _.extend({
          name: uniqueId()
      }, data);
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {Array<String>}
       * */
      this._pathParams = this._findPathParams();
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {Object}
       * */
      this._queryParams = this._compileQueryParams();
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {Array}
       * */
      this._queryParamsNames = _.keys(this._queryParams);
  
      this.params.types = _.extend({}, commonTypes, this.params.types);
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {Object}
       * */
      this._kinds = _.mapValues(this.params.types, function (regex, kind) {
          return new Kind(kind, regex);
      });
  
      _.forEach([{
          rules: this._pathParams,
          defaultKind: 'Segment'
      }, {
          rules: this._pathRule.query,
          defaultKind: 'String'
      }], function (setup) {
          _.forEach(setup.rules, function (rule) {
              if (!rule.kind) {
                  if (rule.regex) {
                      rule.setUniqueKindName();
                      this._kinds[rule.kind] = new Kind(rule.kind, rule.regex);
                  } else {
                      rule.kind = setup.defaultKind;
                  }
              }
  
              if (!_.has(this._kinds, rule.kind)) {
                  throw new TypeError(f('Unknown %j parameter type %j', rule.name, rule.kind));
              }
          }, this);
      }, this);
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {Object}
       * */
      this._paramsCount = this._compileParamsCount();
  
      /**
       * @protected
       * @memberOf {Rule}
       * @property
       * @type {RegExp}
       * */
      this._matchRegExp = this._compileMatchRegExp();
  }