Refactor coercions and validations

Change validate* function to allow for coercion to happen inside an
ongoing validation. This adds support for adding additional constraints
to coerced values.