New feature: error list and common format of error messages

This pull request contains two features implemented:

* The brand new API for collecting errors found during validation. The original one is left as-is for performance and compatibility reasons, while the one is introduced with a side function taking two additional arguments: collector fun and accumulator term. In the end, the accumulator value is returned if at least one error is found. By default simple list appender is used as a collector.

```erlang
-spec validate_with_accumulator( Schema      :: json_term(),
                                 Data        :: json_term(),
                                 ParseFun    :: parser(),
                                 Accumulator :: accumulator(),
                                 Initial     :: term()
                               ) ->
    {ok, json_term()} | {error, term()}.
```
* Errors now organized uniformly into tuples of three or four elements in order to enable custom collectors and more precise error handling

```erlang
-type reason() ::
            { 'missing_id_field', Field :: binary() }
          | { 'missing_required_property', Name :: binary() }
          | { 'missing_dependency', Name :: binary() }
          | { 'no_match', Pattern :: binary() }
          |   'no_extra_properties_allowed'
          |   'no_extra_items_allowed'
          |   'not_allowed'
          | { 'not_unique', Value :: json_term() }
          |   'not_in_range'
          |   'not_divisible'
          |   'wrong_type'
          | { 'wrong_type_items', Items :: json_term() }
          | { 'wrong_type_dependency', Dependency :: json_term() }
          |   'wrong_size'
          |   'wrong_length'
          |   'wrong_format'.
-type error() :: { 'schema_invalid', Schema :: json_term(), reason() } | 
                 { 'data_invalid',   Schema :: json_term(), reason(), Data :: json_term() }.
```

The default collector callback accumulates all errors into a list and then returns the full collection. In case of successful result, the original Json is returned as usual.
This particular implementation is intended to be used in case where performance is not a key point, since the original API is obviously faster. Though it should not significantly degrade the overall performance.