           valid = false
       else
         if v?.constraints? and 'required' in v.constraints
-          console.error "WARNING: Required attribute #{k} not found at",p
+          @_emit_validation_error(data,spec,'required',p,data)
+          valid = false
     return valid
 
   _validate_attribute:(attr,spec,path)=>
     if Array.isArray(spec)
-      console.log "ALTERNATIVES AT",path
       for alt,i in spec
         if @_validate_attribute(attr,alt,path)
-          console.log "RETURNING true DUE TO ALT",i
           return true
-      console.log "RETURNING false DUE TO NO MATCING ALT"
       return false
     else
       valid = true
       unless attr?
         if spec?.constraints? and 'required' in spec.constraints
-          console.error "WARNING: Required attribute not found at",path
+          @_emit_validation_error(attr,spec,'required',path,attr)
           valid = false
         else
-          console.log "ok (null) at",path
+          @_emit_message "ok","(null)",path
       else
         # DATATYPE
         switch spec.datatype
           when 'string'
             unless typeof attr is 'string'
-              console.error "expected string, found ",typeof attr," at",path
-              valid = false
-            else
-              console.log 'ok (string) at',path
+              @_emit_validation_error(attr,spec,'datatype',path,attr,'string')
+              valid = false
+            else
+              @_emit_message "ok","(string)",path
           when 'number'
             unless typeof attr is 'number'
-              console.error "expected number, found ",typeof attr," at",path
-              valid = false
-            else
-              console.log 'ok (number) at',path
+              @_emit_validation_error(attr,spec,'datatype',path,attr,'number')
+              valid = false
+            else
+              @_emit_message "ok","(number)",path
           when 'array'
             unless Array.isArray(attr)
-              console.error "expected array, found ",typeof attr," at",path
-              valid = false
-            else
-              console.log 'ok (array) at',path
+              @_emit_validation_error(attr,spec,'datatype',path,attr,'array')
+              valid = false
+            else
+              @_emit_message "ok","(array)",path
               for elt,i in attr
                 p = [].concat(path)
                 p.push "[#{i}]"

class JSONSpec
  normalize:(src)=>
    dst = {}
    for k,v of src
      console.log k
      dst[k] = @_normalize_attributes(v)
    return dst


                  if not @_validate_attribute(attr[k],v,p)
                    valid = false
          else
            @_emit_validation_error(attr,spec,'not-supported',path,spec.datatype)
            valid = false
        # ENUM
        if spec.enum?
          unless attr in spec.enum
            @_emit_validation_error(attr,spec,'enum',path,attr,spec.enum)
            valid = false
          else
            @_emit_message "ok","(enum)",path
        # RANGE
        if spec.range?
          if spec.range.length is 2 or spec.range[2] is 'inclusive'
            unless spec.range[0] <= attr <= spec.range[1]
              @_emit_validation_error(attr,spec,"range",path,attr,spec.range)
              valid = false
            else
              @_emit_message "ok","(range)",path
          else
            unless spec.range[0] < attr < spec.range[1]
              @_emit_validation_error(attr,spec,"range",path,attr,spec.range)
              valid = false
            else
              @_emit_message "ok","(range)",path
        # FORMAT
        if spec.format?
          for f in spec.format
            switch f
              when 'singleline'
                if SINGLE_LINE_REGEXP.test attr
                  @_emit_validation_error(attr,spec,"format-forbidden",path,attr,SINGLE_LINE_REGEXP)
                  valid = false
                else
                  @_emit_message "ok","(singleline)",path
              when 'iso8601date'
                unless ISO_8601_REGEXP.test attr
                  @_emit_validation_error(attr,spec,"format-required",path,attr,ISO_8601_REGEXP)
                  valid = false
                else
                  @_emit_message "ok","(iso8601date)",path
              when 'uri'
                unless URI_REGEXP.test attr
                  @_emit_validation_error(attr,spec,"format-required",path,attr,URI_REGEXP)
                  valid = false
                else
                  @_emit_message "ok","(uri)",path
      @_emit_message "returning",valid,path
      return valid


################################################################################

