anchor.diff:  
   -export([connect/3,
            disconnect/1,
  -         begin_request/3,
  +         begin_request/4,
            send/3,
            abort_request/2,
            end_request/2]).
   
   -export([start_link/3,
  -         init/1,
  -         handle_call/3,
  -         handle_cast/2,
  -         handle_info/2,
  -         terminate/2,
  -         code_change/3]).
  +         init/3]).
   
   -record(state, {socket :: undefined | inet:socket(),
                   address :: address(),
                   port :: port_number(),
  -                table :: ets:tid(),
  +                requests :: ets:tid(),
  +                monitors :: ets:tid(),
                   next_id = 1 :: req_id()}).
   
   
  
positive.code: 
  -module(ex_fcgi).
  -author('Anthony Ramine <nox@dev.extend.eu>').
  -behaviour(gen_server).
  
  
  -type short() :: 0..65535.
  
  -type address() :: string() | atom() | inet:ip_address().
  -type port_number() :: short().
  
negative.code:   Bin.
  
  
  -spec do_abort(req_id(), #state{}) -> #state{}.
  do_abort(ReqId, State) ->
    send({fcgi_abort_request, ReqId}, State).
  
  
  -spec initial_state(address(), port_number()) -> #state{}.
  initial_state(Address, Port) ->
    #state{address = Address, port = Port,
           requests = ets:new(requests, [private]),
           monitors = ets:new(monitors, [private])}.
  
  -spec next_req_id(#state{}) -> {req_id(), #state{}}.
  next_req_id(State = #state{next_id = ReqId}) ->
    {ReqId, State#state{next_id = ReqId + 1 rem 65535}}.
  
  -spec send_packets([ex_fcgi_protocol:packet()], #state{}) -> #state{}.
  send_packets(Packets, State = #state{socket = undefined}) ->
    send_packets(Packets, open_socket(State));
  send_packets(Packets, State = #state{socket = Socket}) ->
    ok = gen_tcp:send(Socket, [ ex_fcgi_protocol:encode(P) || P <- Packets ]),
    State.
  
  -spec send(ex_fcgi_protocol:packet(), #state{}) -> #state{}.
  send(Packet, State = #state{socket = undefined}) ->
    send(Packet, open_socket(State));
  send(Packet, State = #state{socket = Socket}) ->
    ok = gen_tcp:send(Socket, ex_fcgi_protocol:encode(Packet)),
    State.
  
  -spec open_socket(#state{socket :: undefined}) ->
                    #state{socket :: inet:socket()}.
  open_socket(State = #state{socket = undefined,
                             address = Address,
                             port = Port}) ->
    {ok, Socket} = gen_tcp:connect(Address, Port, [binary, {packet, fcgi}]),
    State#state{socket = Socket}.
  
  -spec insert({req_id(), Ref::reference(), Timer::reference(), pid(),
                MonitorRef::reference()}, #state{}) -> true.
  insert(Req = {ReqId, Ref, _Timer, _Pid, MonitorRef},
         #state{requests = Requests, monitors = Monitors}) ->
    true = ets:insert_new(Requests, [Req, {Ref, ReqId}]),
    true = ets:insert_new(Monitors, [{MonitorRef, Ref}]).
  
  -spec lookup(reference(), #state{}) -> [{reference(), req_id()}];
              (req_id(), #state{}) ->
                [{req_id(), Ref::reference(), Timer::reference(), pid(),
                 MonitorRef::reference()}].
  lookup(Key, #state{requests = Requests}) ->
    ets:lookup(Requests, Key).
  
  -spec delete(reference() | req_id(), #state{}) -> true.
  delete(Key, #state{requests = Requests}) ->
    ets:delete(Requests, Key).
  
  -spec lookup_monitor(reference(), #state{}) ->
                        [{MonitorRef::reference(), Ref::reference()}].
  lookup_monitor(MonitorRef, #state{monitors = Monitors}) ->
    ets:lookup(Monitors, MonitorRef).
  
  -spec delete_monitor(reference(), #state{}) -> true.
  delete_monitor(MonitorRef, #state{monitors = Monitors}) ->
    ets:delete(Monitors, MonitorRef).
  