anchor.diff:      zip([], [], Result);
   zip([H1|R1], [H2|R2], {Result, TooMany}) ->
       zip(R1, R2, {[{H1, H2}|Result], TooMany}).
  +
  +-compile(export_all).
  +
  +validate_date(Date) when is_binary(Date) ->
  +    validate_date(binary_to_list(Date));
  +validate_date(Date) ->
  +    case validator(fun year/2, Date, year()) of
  +        {ok, [Year, Month, Day, T], TimeString} when ((T == "t") or (T == "T")) ->
  +            case validator(fun time_check/2, TimeString, time_check()) of
  +                {ok, [Hour, Minute, Second], TimeZoneString} ->
  +                    validate_datetime({Year, Month, Day}, {Hour, Minute, Second}, TimeZoneString);
  +                _ ->
  +                    false
  +            end;
  +        _ -> false
  +    end.
  +
  +
  +validate_datetime({Year, Month, Day} = DateTuple, {Hour, Minute, Second} = TimeTuple, TimeZoneString) ->
  +    case {calendar:valid_date(Year, Month, Day), valid_time(Hour, Minute, Second)} of
  +        {true, true} -> check_time_zone(DateTuple, TimeTuple, TimeZoneString);
  +        _ -> false
  +    end.
  +
  +check_time_zone(DateTuple, TimeTuple, TimeZoneString) ->
  +    case validator(fun get_timezone/2, TimeZoneString, get_timezone()) of
  +        {ok, "Z", _} ->
  +            {true, {DateTuple, TimeTuple}};
  +        {ok, [T | Other], _} when ((T == "+") or (T == "-")) ->
  +            add_time({DateTuple, TimeTuple}, T, Other);
  +        _ ->
  +            false
  +    end.
  +
  +valid_time(H, M, S) when (H >= 0) and (H =< 23) and (M >= 0) and (M =< 59) and (S >= 0) and (S =< 59) ->
  +    true;
  +valid_time(_, _, _) ->
  +    false.
  +
  +validator(_Fun, _Date, 0) -> false;
  +validator(Fun, Date, N) ->
  +    case Fun(Date, N) of
  +        {ok, Result, EndOfString} ->
  +            {ok, Result, EndOfString};
  +        _ ->
  +            validator(Fun, Date, N - 1)
  +    end.
  +
  +year() -> 2.
  +year(Date, 1) -> io_lib:fread("~4d-~2d-~2d~1c", Date);
  +year(Date, 2) -> io_lib:fread("~4d~2d~2d~1c", Date).
  +time_check() -> 2.
  +time_check(Time, 1) -> io_lib:fread("~2d:~2d:~2d", Time);
  +time_check(Time, 2) -> io_lib:fread("~2d~2d~2d", Time).
  +get_timezone() -> 4.
  +get_timezone(TimeZone, 1) -> io_lib:fread("~1c~2d", TimeZone);
  +get_timezone(TimeZone, 2) -> io_lib:fread("~1c~2d:2d", TimeZone);
  +get_timezone(TimeZone, 3) -> io_lib:fread("~1c~2d~2d", TimeZone);
  +get_timezone("Z", 4) -> {ok, "Z", []};
  +get_timezone(_TimeZone, _N) -> false.
  +
  +add_time(DateTime, T, [H | Tail]) ->
  +    Seconds1 = calendar:datetime_to_gregorian_seconds(DateTime),
  +    Seconds2 = add(T, Seconds1, H * 3600),
  +    Seconds3 =  case Tail of
  +                    [] ->
  +                        Seconds2;
  +                    [Minutes] ->
  +                        add(T, Seconds2, Minutes * 60)
  +                end,
  +    {true, calendar:gregorian_seconds_to_datetime(Seconds3)}.
  +
  +add("+", A, B) -> A - B;
  +add("-", A, B) -> A + B.
  
positive.code:         _T ->
              case type(PType, GivenValue) of
                  true -> GivenValue;
                  false -> throw({invalid, ["invalid parameter type for param '", PName, "': expected ", atom_to_list(PType)]})
              end
      end.
  
  
negative.code: type(string, Val) when is_binary(Val) -> true;
  type(list, Val) when is_list(Val) -> true;
  type(array, Val) when is_list(Val) -> true;
  type(iso_date, Val) when is_binary(Val) -> validate_date(Val);
  type(any, _Val) -> true;
  type(_T, _Val) -> false.
  
  