docs: function(value, options){
          // implicitly pass undefined
          if(typeof value === 'undefined') return undefined;
          
          // make sure the default options object exists
          if(typeof this.options !== 'object') this.options = {};
          
          // build up a base config from the pre-defined defaults
          var config = {};
          config.prototypes = validate.isArray(this.options.prototypes) ? this.options.prototypes : [];
          config.inverseMatch = this.options.inverseMatch ? true : false;
          config.message = validateParams.extractValidatorMessage(this, options);
          
          // interpret the passed value
          if(typeof options === 'boolean'){
              // false prevents a validator from running, so the value must be true
              config.prototypes.push(Object);
          }else if(validate.isArray(options)){
              config.prototypes = config.prototypes.concat(options);
          }else if(validate.isObject(options)){
              if(validate.isArray(options.prototypes)){
                  config.prototypes = config.prototypes.concat(options.prototypes);
              }
              if(options.inverseMatch) config.inverseMatch = true;
              if(validate.isString(options.message)) config.message = options.message;
          }else{
              throw new Error('invalid options passed - must be true, an array, or a plain object');
          }
          
          // validate the passed prototypes
          var prototypeList = [];
          config.prototypes.forEach(function(p){
              if(typeof p === 'function'){
                  prototypeList.push(p);
              }else{
                  validateParams._warn('ignoring invalid prototype: ' + String(p));
              }
          });
          if(prototypeList.length === 0){
              throw new Error('no valid prototypes specified');
          }
          
          // do the actual validation
          var errors = [];
          if(config.inverseMatch){
              // do a reverse match
              prototypeList.forEach(function(p){
                  if(value instanceof p){
                      errors.push("can't have prototype " + String(p));
                  }
              });
          }else{
              // do a regular forward match
              var matched = false;
              prototypeList.forEach(function(p){
                  if(value instanceof p){
                      matched = true;
                  }
              });
              if(!matched){
                  errors.push("must have one of the following prototypes: " + humanJoin(prototypeList) + "'");
              }
          }
          
          // return as appropriate
          if(errors.length > 0){
              return config.message ? config.message : errors;
          }
          return undefined;
      }