anchor.diff:  %% Function: end_invite(State)
   %%           State = state record()
   %% Descrip.: Ends an INVITE transaction. This is called when our user
  -%%           specified timeout occurs, or when Timer C fires.
  -%%           Whichever happens first.
  -%% Returns : NewState = state record()
  -%%--------------------------------------------------------------------
  +%%           specified timeout (timer invite_timeout) occurs, or when
  +%%           Timer C fires. Whichever happens first.
  +%% Returns : NewState = state record()
  +%%--------------------------------------------------------------------
  +end_invite(#state{cancelled=true}=State) ->
  +    logger:log(debug, "~s: End invite: Not doing anything since request is already cancelled.",
  +	       [State#state.logtag]),
  +    State;
   end_invite(State) when is_record(State, state) ->
       Request = State#state.request,
       URI = Request#request.uri,
  
positive.code:     LogTag = State#state.logtag,
      Request = State#state.request,
      {URI, Header} = {Request#request.uri, Request#request.header},
      logger:log(debug, "~s: initiate_cancel() Sending CANCEL ~s", [LogTag, sipurl:print(URI)]),
      {CSeqNum, _} = sipheader:cseq(Header),
      CancelId = {CSeqNum, "CANCEL"},
      %% Delete all Via headers. initiate_request() uses send_proxy_request() which
      %% will add one for this proxy, and that is the only one that should be in a
      %% CANCEL. Set CSeq method to CANCEL and delete all Require and Proxy-Require
      %% headers. All this according to RFC 3261 9.1 Client Behaviour.
      CancelHeader1 = keylist:set("CSeq", [sipheader:cseq_print(CancelId)],
  				Header),
      CancelHeader2 = keylist:delete('via', CancelHeader1),
      CancelHeader3 = keylist:delete('require', CancelHeader2),
      CancelHeader4 = keylist:delete('proxy-require', CancelHeader3),
      CancelHeader5 = keylist:delete('content-type', CancelHeader4),
      CancelHeader6 = keylist:delete('content-length', CancelHeader5),
      CancelHeader = keylist:set("Content-Length", ["0"], CancelHeader6),
      CancelRequest = siprequest:set_request_body(#request{method="CANCEL", uri=URI, header=CancelHeader}, <<>>),
      T1 = sipserver:get_env(timerT1, 500),
      NewState = add_timer(64 * T1, "quit after CANCEL", {terminate_transaction}, State),
      Socket = State#state.socket,
      Dst = State#state.dst,
      %% Must use branch from original request sent out, so that next hop can match
      %% this ACK to the right transaction. tl_branch is not necessarily the same as branch
      %% since the transport layer can be configured to add a stateless loop cookie.
      Branch = State#state.tl_branch,
      %% XXX is the 32 * T1 correct for CANCEL?
  
negative.code:     Desc = lists:flatten(
  	     io_lib:format("~s: ~s ~s (dst ~s)", [RegBranch, Method,
  						  sipurl:print(URI), sipdst:dst2str(Dst)])),
      LogTag = lists:concat([RegBranch, " ", Method]),
      %% Get ourselves into the transaction state list first of all
      case transactionstatelist:add_client_transaction(Method, RegBranch, self(), Desc) of
  	{duplicate, _} ->
  