docs: function (Vue) {
    var ref = Elements(Vue);
    var SingleElement = ref.SingleElement;
    var MultiElement = ref.MultiElement;
    var ComponentElement = ref.ComponentElement;
  
    function createValidityElement (vm, vnode) {
      return vm.multiple
        ? new MultiElement(vm)
        : checkBuiltInElement(vnode)
          ? new SingleElement(vm)
          : checkComponentElement(vnode)
            ? new ComponentElement(vm, vnode)
            : null
    }
  
    function watchModelable (val) {
      this.$emit('input', {
        result: this.result,
        progress: this.progress,
        progresses: this.progresses
      });
    }
  
    function created () {
      this._elementable = null;
  
      this._keysCached = memoize(function (results) {
        return Object.keys(results)
      });
  
      // for event control flags
      this._modified = false;
  
      // watch validation raw results
      this._watchValidationRawResults();
  
      var validation = this.$options.propsData ? this.$options.propsData.validation : null;
      if (validation) {
        var instance = validation.instance;
        var name = validation.name;
        var group = this.group;
        instance.register(this.field, this, { named: name, group: group });
      }
    }
  
    function destroyed () {
      var validation = this.$options.propsData ? this.$options.propsData.validation : null;
      if (validation) {
        var instance = validation.instance;
        var name = validation.name;
        var group = this.group;
        instance.unregister(this.field, { named: name, group: group });
      }
  
      if (this._unwatchResultProp) {
        this._unwatchResultProp();
        this._unwatchResultProp = null;
      }
  
      if (this._unwatchProgressProp) {
        this._unwatchProgressProp();
        this._unwatchProgressProp = null;
      }
  
      this._unwatchValidationRawResults();
  
      this._elementable.unlistenInputableEvent();
      if (this.autotouch === 'on') {
        this._elementable.unlistenToucheableEvent();
      }
      this._elementable = null;
    }
  
    function mounted () {
      this._elementable = createValidityElement(this, this._vnode);
      if (this._elementable) {
        if (this.autotouch === 'on') {
          this._elementable.listenToucheableEvent();
        }
        this._elementable.listenInputableEvent();
      } else {
        // TODO: should be warn
      }
  
      if (hasModelDirective(this.$vnode)) {
        this._unwatchResultProp = this.$watch('result', watchModelable);
        this._unwatchProgressProp = this.$watch('progress', watchModelable);
      }
  
      toggleClasses(this.$el, this.classes.untouched, addClass);
      toggleClasses(this.$el, this.classes.pristine, addClass);
    }
  
    return {
      created: created,
      destroyed: destroyed,
      mounted: mounted
    }
  }