/**
 * validations
 *
 */
v = (function (tek) {
    var v = {};
    v.Schema = tek.define({
        init: function (def) {
            var s = this;
            s.validators = [];
            if (def) {
                Object.keys(def).forEach(function (property) {
                    Object.keys(def[property]).forEach(function (key) {
                        var expect = def[property][key];
                        s.addValidator(property, key, expect);
                    });
                });
            }
        },
        properties: {
            addValidator: function (property, key, expect) {
                var s = this;
                var Validator = v.Schema.resolveValidator(key);
                if (Validator) {
                    var validator = new Validator(expect);
                    validator.property = property;
                    s.validators.push(validator);
                } else {
                    console.error('[v.js] unknown schema:', key, expect);
                }
            },
            validate: function (values, callback) {
                var isEmpty = tek.validators.Validator.isEmpty;
                var s = this,
                    validators = s.validators,
                    count = validators.length,
                    errors = [];

                function next() {
                    count--;
                    var finish = count <= 0;
                    if (finish) {
                        callback(errors.length && errors || null);
                    }
                }

                validators.forEach(function (validator) {
                    var property = validator.property,
                        value = values[property];
                    var skip = isEmpty(value) && validator.skipIfEmpty;
                    if (skip) {
                        next();
                        return;
                    }
                    validator.validate(value, function (err) {
                        if (err) {
                            err.property= property;
                            errors.push(err);
                        }
                        next();
                    });
                });
            },
            clone: function () {
                var s = this,
                    clone = new v.Schema;
                clone.validators = s.validators;
                return clone;
            }
        }
    });
    v.Schema.resolveValidator = function (key) {
        var name = key.substr(0, 1).toUpperCase() + key.substr(1) + 'Validator';
        var Validator = tek.validators[name];
        if (Validator) {
            return Validator
        } else {
            if (typeof(value) === 'function') {
                return tek.validators['ConformValidator'];
            } else {
                return null;
            }
        }
    };
    v.Schema.Err = function (data) {
        var s = this;
        tek.copy(data, s);
    };


    /**
     * for serverside validation test
     */
    v.disableAllValidations = function () {
        console.warn('all clientside validation is disabled');
        v.Schema.prototype.validate = function (values, callback) {
            callback(null);
        };
    };
    return  v;
})(tek);

@@ -1051,33 +1051,35 @@
  function (value
-s
+Obj
 , callback) %7B%0A  
@@ -1694,17 +1694,101 @@
 alue
+s
  =
+ property.split(',').map(function (property) %7B%0A                            return
  value
-s
+Obj
 %5Bpro
@@ -1819,60 +1819,229 @@
     
-var skip = isEmpty(value) && validator.skipIfEmpty;%0A
+    %7D);%0A                    if (validator.skipIfEmpty) %7B%0A                        var skip = values.filter(function (value) %7B%0A                            return !isEmpty(value);%0A                        %7D).length == 0;%0A    
     
@@ -2084,32 +2084,36 @@
                 
+    
 next();%0A        
@@ -2132,16 +2132,20 @@
     
+   
+ 
 return;%0A
     
@@ -2140,16 +2140,20 @@
 return;%0A
+    
         
@@ -2190,34 +2190,63 @@
     
-validator.validate(value, 
+%7D%0A                    var validateArgs = values.concat(
 func
@@ -2333,16 +2333,17 @@
 property
+ 
 = proper
@@ -2466,32 +2466,103 @@
             %7D);%0A
+                    validator.validate.apply(validator, validateArgs);%0A
                 

modify validation