import validators, schema, compound

default_validators = dict(
    [(name.lower(), getattr(validators, name))
     for name in dir(validators)])

def get_messages(cls, message):
    if not message:
        return {}
    else:
        return dict([(k, message) for k in cls._messages.keys()])

def to_bool(value):
    value = value.strip().lower()
    if value in ('true', 't', 'yes', 'y', 'on', '1'):
        return True
    elif value in ('false', 'f', 'no', 'n', 'off', '0'):
        return False
    else:
        raise ValueError("Not a boolean value: %r (use 'true'/'false')")

class SchemaBuilder(object):

    def __init__(self, validators=default_validators):
        self.validators = validators
        self._schema = None

    def reset(self):
        self._schema = schema.Schema()

    def schema(self):
        return self._schema
        
    def listen_input(self, parser, tag, attrs):
        get_attr = parser.get_attr
        name = get_attr(attrs, 'name')
        if not name:
            # @@: should warn if you try to validate unnamed fields
            return
        v = compound.All()
        message = get_attr(attrs, 'form:message')
        required = to_bool(get_attr(attrs, 'form:required', 'false'))
        if required:
            v.validators.append(
                validators.NotEmpty(
                messages=get_messages(validators.NotEmpty, message)))
        v_type = get_attr(attrs, 'form:validate', None)
        if v_type:
            pos = v_type.find(':')
            if pos != -1:
                # @@: should parse args
                args = (v_type[pos+1:],)
                v_type = v_type[:pos]
            else:
                args = ()
            v_type = v_type.lower()
            v_class = self.validators.get(v_type)
            if not v_class:
                raise ValueError("Invalid validation type: %r" % v_type)
            kw_args={'messages': get_messages(v_class, message)}
            v_inst = v_class(
                *args, **kw_args)
            v.validators.append(v_inst)
        self._schema.add_field(name, v)

@@ -1077,16 +1077,17 @@
   return
+%0D
 %0A       
@@ -1105,16 +1105,229 @@
 nd.All()
+%0D%0A        # for checkboxes, we must set if_missing = False%0D%0A        if tag.lower() == %22input%22:%0D%0A            if get_attr(attrs, %22type%22).lower() == %22checkbox%22:%0D%0A                v.validators.append(validators.Bool())
 %0A       

fix for htmlfill_schemabuilder.py for checkboxes to work properly with Bool