anchor.diff:  -module(etorrent_udp_tracker).
   
   -include("types.hrl").
  +-include("log.hrl").
   -behaviour(gen_fsm).
   
   %% API
  --export([start_link/1, announce/2, announce/3, msg/2]).
  +-export([start_link/1, announce/2, announce/3]).
  +
  +%% Internally used calls
  +-export([msg/2]).
   
   %% gen_fsm callbacks
   -export([init/1, idle/2, idle/3, request_conn/2, request_conn/3, has_conn/2, has_conn/3,
  
positive.code:     erlang:send_after(timer:seconds(60), self(), connid_expired),
      ARes = announce_requests(ConnID, S#state.announce_stack),
      {next_state, has_conn, #state { conn_id = ConnID,
  			        scrape_stack = [],
  			        announce_stack = [],
  			        response = S#state.response ++ ARes }};
  request_conn({msg, {TID, {announce_response, Peers, Status}}}, #state { response = R} = S) ->
      announce_reply(Peers, Status, proplists:lookup(TID, R)),
      PL = proplists:delete(TID, R),
      {next_state, request_conn, S#state { response = PL }};
  request_conn({announce, Requestor, PL, R}, #state { announce_stack = Q } = S) ->
      {next_state, request_conn, S#state { scrape_stack = [{announce, Requestor, PL, R} | Q]}};
  request_conn(_Event, S) ->
      {next_state, request_tr, S}.
  
  %% The has_conn is when we currently have a live conn ID from the server
  has_conn({announce, _, _, _} = M, #state { response = Resp } = S) ->
      Ares = announce_requests(S#state.conn_id, [M]),
      {next_state, has_conn, S#state { response = [Ares | Resp] }};
  has_conn({msg, {TID, {announce_response, Peers, Status}}}, #state { response = R} = S) ->
      announce_reply(Peers, Status, proplists:lookup(TID, R)),
      PL = proplists:delete(TID, R),
      {next_state, has_conn, S#state { response = PL }};
  has_conn(_Event, S) ->
      {next_state, has_tr, S}.
  
  idle(_Event, _F, S) ->
      {reply, ok, idle, S}.
  
negative.code: 	{announce, _, _, _} = AnnReq ->
  	    NPL = proplists:delete(Tid, R),
  	    NewReq = announce_requests(ConnId, [AnnReq], N),
  	    %% TODO: Consider messaging back the fail here
  	    {next_state, has_conn, S#state { response = NewReq ++ NPL }}
      end;
  handle_info({announce_timeout, _N, Tid}, SN, #state { response = R,
  						      announce_stack = Stack } = S) ->
      etorrent_udp_tracker_mgr:unreg_tr_id(Tid),
      case proplists:lookup(Tid, R) of
  	none ->
  	    {next_state, has_conn, S};
  	{announce, _, _, _} = AnnReq ->
  	    NPL = proplists:delete(Tid, R),
  	    %% If idle, grab hold of a conn_id!
  	    NewTid = case SN of
  			 request_conn -> S#state.conn_id;
  			 idle -> Tid = request_connid(0),
  				 {req, Tid}
  		     end,
  	    {next_state, request_conn, S#state { response = NPL,
  						 conn_id = NewTid,
  						 announce_stack = [AnnReq | Stack] }}
      end;
  handle_info({transaction_timeout, N, Tid}, request_conn,
  	    #state { conn_id = {req, Tid} } = S) ->
  