docs: function(options) {
        return {
  
          /**
           * Check whether an attribute or a set of attributes are valid. It will default to use the model's current values but
           * you can pass in different values to use in the validation process instead.
           * @param attr {String or Object or Array} Either the name of the attribute, an array containing many attribute names, or
           * on object with attribute name to values
           * @param [value] {Any} a value to use for the attribute value instead of using the model's value.
           * @return undefined if no errors, a validation exception if a single attribute, or an object with attribute name as key
           * and the error as the value
           * @method preValidate
           */
          preValidate: function(attr, value) {
            var self = this,
                result = {},
                error;
            if (_.isArray(attr)) {
              _.each(attr, function(attr) {
                error = self.preValidate(attr);
                if (error) {
                  result[attr] = error;
                }
              });
              return _.isEmpty(result) ? undefined : result;
            } else if (_.isObject(attr)) {
              _.each(attr, function(value, key) {
                error = self.preValidate(key, value);
                if (error) {
                  result[key] = error;
                }
              });
              return _.isEmpty(result) ? undefined : result;
            } else {
              if (_.isUndefined(value) && isNestedModel(this)) {
                value = this.get(attr);
              }
              return validateAttr(this, value, attr);
            }
          },
  
          // Check to see if an attribute, an array of attributes or the
          // entire model is valid. Passing true will force a validation
          // of the model.
          isValid: function(option) {
            var flattened, attrs, error, invalidAttrs;
  
            option = option || getOptionsAttrs(options);
  
            if(_.isString(option)){
              attrs = [option];
            } else if(_.isArray(option)) {
              attrs = option;
            }
            if (attrs) {
              // Loop through all attributes
              _.each(attrs, function (attr) {
                var value;
                if (isNestedModel(this)) {
                  value = this.get(attr);
                } else {
                  value = flatten(this.attributes)[attr];
                }
                error = validateAttr(this, value, attr);
                if (error) {
                  invalidAttrs = invalidAttrs || {};
                  invalidAttrs[attr] = error;
                }
              }, this);
            }
  
            if (option === true) {
              invalidAttrs = this.validate();
            }
            if (invalidAttrs) {
              this.trigger('invalid', this, invalidAttrs, {validationError: invalidAttrs});
            }
            return attrs ? !invalidAttrs : this.validation ? this._isValid : true;
          },
  
          // This is called by Backbone when it needs to perform validation.
          // You can call it manually without any parameters to validate the
          // entire model.
          validate: function(attrs, setOptions){
            var model = this;
            var opt = _.extend({}, options, setOptions);
            var validatedAttrs = getValidatedAttrs(model, getOptionsAttrs(options));
            var allAttrs = _.extend({}, validatedAttrs, model.attributes, attrs);
            var flattened = _.extend(flatten(allAttrs), attrs); // allow people to pass in nested attributes
            var changedAttrs = attrs ? flatten(attrs) : flattened;
            var result = validateModel(model, allAttrs, _.pick(flattened, _.keys(validatedAttrs)));
            model._isValid = result.isValid;
  
            // Trigger validated events.
            // Need to defer this so the model is actually updated before
            // the event is triggered.
            _.defer(function() {
              model.trigger('validated', model._isValid, model, result.invalidAttrs);
              model.trigger('validated:' + (model._isValid ? 'valid' : 'invalid'), model, result.invalidAttrs);
            });
  
            // Return any error messages to Backbone, unless the forceUpdate flag is set.
            // Then we do not return anything and fools Backbone to believe the validation was
            // a success. That way Backbone will update the model regardless.
            if (!opt.forceUpdate && _.intersection(_.keys(result.invalidAttrs), _.keys(changedAttrs)).length > 0) {
              return result.invalidAttrs;
            }
          }
        };
      }