anchor.diff:  -export([start_link/7,
           choke/1,
           unchoke/1,
  -        have/2,
  -        cancel/4,
           initialize/2,
           incoming_msg/2,
           stop/1]).
  +
  +%% gproc registry entries
  +-export([register_server/2,
  +         lookup_server/2,
  +         await_server/2,
  +         lookup_peers/1]).
   
   %% gen_server callbacks
   -export([init/1,
  
positive.code:     #state{
          send_pid=SendPid,
          remote_pieces=Pieceset,
          remote_request_set=OpenRequests,
          download=Download} = State,
      case gb_sets:size(OpenRequests) of
          N when N > ?LOW_WATERMARK ->
              {ok, State};
          %% Optimization: Only replenish pieces modulo some N
          N when is_integer(N) ->
              Numchunks = ?HIGH_WATERMARK - N,
              case etorrent_download:request_chunks(Pieceset, Numchunks, Download) of
                  {ok, not_interested} ->
                      statechange_interested(State, false),
                      {ok, State#state{local_interested=false}};
                  {ok, assigned} ->
                      {ok, State};
                  {ok, Chunks} ->
                      NewRequests = queue_items(SendPid, Chunks, OpenRequests),
                      NewState = State#state{remote_request_set=NewRequests},
                      {ok, NewState}
              end
      end.
  
  %% @doc Send chunk messages for each chunk we decided to queue.
  %%   also add these chunks to the piece request set.
  %% @end
  -spec queue_items(pid(), list(), gb_set()) -> gb_set().
  queue_items(SendPid, Chunks, Requestset) ->
      lists:foldl(fun({_, _, _}=Chunk, Acc) ->
          etorrent_peer_send:local_request(SendPid, Chunk),
          gb_sets:insert(Chunk, Acc)
      end, Requestset, Chunks).
  
  % @doc Initialize the connection, depending on the way the connection is
  connection_initialize(incoming, S) ->
  
negative.code: 
  
  %% @private
  handle_info({chunk, {fetched, Index, Offset, Length, _}}, State) ->
      #state{send_pid=SendPid, remote_request_set=Requests} = State,
      Hasrequest = etorrent_rqueue:member(Index, Offset, Length, Requests),
      NewRequests = if
          not Hasrequest ->
              Requests;
          Hasrequest ->
              etorrent_peer_send:cancel(SendPid, Index, Offset, Length),
              etorrent_rqueue:delete(Index, Offset, Length, Requests)
      end,
      NewState = State#state{remote_request_set=NewRequests},
      {noreply, NewState};
  
  handle_info({piece, {valid, Piece}}, State) ->
      #state{send_pid=SendPid} = State,
      etorrent_peer_send:have(SendPid, Piece),
      {noreply, State};
  
  handle_info({piece, {unassigned, _}}, State) ->
      {ok, NewState} = try_to_queue_up_pieces(State),
      {noreply, NewState};
  
  handle_info({download, Update}, State) ->
      #state{download=Download} = State,
      NewDownload = etorrent_download:update(Update, Download),
      NewState = State#state{download=NewDownload},
      {noreply, NewState};
  
  handle_info({tcp, _, _}, State) ->
      ?ERR([wrong_controller]),
      {noreply, State};
  
  handle_info(Info, State) ->
      ?WARN([unknown_msg, Info]),
      {noreply, State}.
  