anchor.diff:  %% all of these header fields are mandatory in all SIP responses.
   %% @end
   -spec validate_response(#sip_response{}) -> ok | {error, Reason :: term()}.
  -validate_response(#sip_response{headers = Headers} = Response) ->
  -    IsNotDialogEstablishing = not is_dialog_establishing(Response),
  -    CountFun =
  -        fun ({Name, Value}, Counts) ->
  -                 % assign tuple index for every header being counted
  -                 Idx = case Name of
  -                           to -> 1;
  -                           from -> 2;
  -                           cseq -> 3;
  -                           'call-id' -> 4;
  -                           via -> 5;
  -                           contact -> 6;
  -                           _ -> 0
  -                       end,
  -                 if
  -                     Idx > 0 ->
  -                         Incr = if is_list(Value) -> length(Value); true -> 1 end,
  -                         setelement(Idx, Counts, element(Idx, Counts) + Incr);
  -                     true -> Counts
  -                 end
  -        end,
  -
  -    % Count headers
  -    case lists:foldl(CountFun, {0, 0, 0, 0, 0, 0}, Headers) of
  -        C when C >= {1, 1, 1, 1, 1, 0}, % Each header must be at least once (except contact),
  -               C =< {1, 1, 1, 1, a, 0}, % except Via:, which must be at least once (atom > every possible number)
  -
  -              % The Contact header field MUST be present and contain exactly one SIP
  -               % or SIPS URI in any response that can result in the establishment of a
  -               % dialog
  -               (IsNotDialogEstablishing orelse element(6, C) =:= 1)
  -          -> ok;
  -        _ -> {error, invalid_headers}
  -    end.
  +validate_response(#sip_response{} = Msg) ->
  +    IsNotDialogEstablishing = not is_dialog_establishing(Msg),
  +    do([error_m ||
  +        check(count(to, Msg) =:= 1, {invalid, to}),
  +        check(count(from, Msg) =:= 1, {invalid, from}),
  +        check(count(cseq, Msg) =:= 1, {invalid, cseq}),
  +        check(count('call-id', Msg) =:= 1, {invalid, 'call-id'}),
  +        % Must be at least one via
  +        check(count(via, Msg) >= 1, {invalid, via}),
  +        % 12.1.1 The UAS MUST add a Contact header field to the response.
  +        check(IsNotDialogEstablishing orelse is_contact_valid(Msg), {invalid, contact})]).
   
   
   %% @doc
  
positive.code: %% requests.
  %% @end
  -spec validate_request(#sip_request{}) -> ok | {error, Reason :: term()}.
  validate_request(#sip_request{method = Method, headers = Headers}) ->
      CountFun =
          fun ({Name, Value}, Counts) ->
                   % assign tuple index for every header being counted
                   Idx = case Name of
                             to -> 1;
                             from -> 2;
                             cseq -> 3;
                             'call-id' -> 4;
                             'max-forwards' -> 5;
                             via -> 6;
                             contact -> 7;
                             _ -> 0
                         end,
                   if
                       Idx > 0 ->
                           Incr = if is_list(Value) -> length(Value); true -> 1 end,
                           setelement(Idx, Counts, element(Idx, Counts) + Incr);
                       true -> Counts
                   end
          end,
  
      % Count headers
      case lists:foldl(CountFun, {0, 0, 0, 0, 0, 0, 0}, Headers) of
          C when C >= {1, 1, 1, 1, 1, 1, 0}, % Each header must be at least once (except contact),
                 C =< {1, 1, 1, 1, 1, a, 0}, % except Via:, which must be at least once (atom > every possible number)
  
                 % The Contact header field MUST be present and contain exactly one SIP
                 % or SIPS URI in any request that can result in the establishment of a
                 % dialog.
                 (Method =/= 'INVITE' orelse element(7, C) =:= 1)
            -> ok;
          _ -> {error, invalid_headers}
      end.
  
  %% @doc Validate that response contains all required headers
  %% A valid SIP response formulated by a UAS MUST, at a minimum, contain
  
negative.code: %%% @copyright 2011 Ivan Dubrov. See LICENSE file.
  %%%----------------------------------------------------------------
  -module(sip_message).
  -compile({parse_transform, do}).
  
  %%-----------------------------------------------------------------
  %% Exports
  