anchor.diff:          ok ->
               shackle_queue:add(ExtRequestId, Cast),
   
  -            {ok, State#state {
  -                client_state = ClientState2
  -            }};
  +            {ok, State, ClientState2};
           {error, Reason} ->
               shackle_utils:warning_msg(PoolName, "tcp send error: ~p", [Reason]),
               Protocol:close(Socket),
  -            close(State)
  +            close(State, ClientState2)
       end;
  -handle_msg({inet_reply, _Socket, ok}, State) ->
  -    {ok, State};
  +handle_msg({inet_reply, _Socket, ok}, State, ClientState) ->
  +    {ok, State, ClientState};
   handle_msg({inet_reply, _Socket, {error, Reason}}, #state {
           pool_name = PoolName
  -    } = State) ->
  +    } = State, ClientState) ->
   
       shackle_utils:warning_msg(PoolName, "udp send error: ~p", [Reason]),
  -    {ok, State};
  -handle_msg({tcp, _Port, Data}, State) ->
  -    handle_msg_data(Data, State);
  +    {ok, State, ClientState};
  +handle_msg({tcp, _Port, Data}, State, ClientState) ->
  +    handle_msg_data(Data, State, ClientState);
   handle_msg({tcp_closed, Socket}, #state {
           socket = Socket,
           pool_name = PoolName
  -    } = State) ->
  +    } = State, ClientState) ->
   
       shackle_utils:warning_msg(PoolName, "tcp connection closed", []),
  -    close(State);
  +    close(State, ClientState);
   handle_msg({tcp_error, Socket, Reason}, #state {
           socket = Socket,
           pool_name = PoolName
  -    } = State) ->
  +    } = State, ClientState) ->
   
       shackle_utils:warning_msg(PoolName, "tcp connection error: ~p", [Reason]),
       shackle_tcp:close(Socket),
  -    close(State);
  -handle_msg({udp, _Socket, _Ip, _InPortNo, Data}, State) ->
  -    handle_msg_data(Data, State).
  -
  -handle_msg_data(Data, #state {
  -        client = Client,
  -        client_state = ClientState
  -    } = State) ->
  -
  +    close(State, ClientState);
  +handle_msg({udp, _Socket, _Ip, _InPortNo, Data}, State, ClientState) ->
  +    handle_msg_data(Data, State, ClientState).
  +
  +handle_msg_data(Data, #state {client = Client} = State, ClientState) ->
       {ok, Replies, ClientState2} = Client:handle_data(Data, ClientState),
       ok = process_replies(Replies, State),
  -
  -    {ok, State#state {
  -        client_state = ClientState2
  -    }}.
  -
  -loop(#state {parent = Parent} = State) ->
  +    {ok, State, ClientState2}.
  +
  +loop(#state {parent = Parent} = State, ClientState) ->
       receive
           {'EXIT', Parent, Reason} ->
  -            terminate(Reason, State);
  +            terminate(Reason, State, ClientState);
           {system, From, Request} ->
  -            sys:handle_system_msg(Request, From, Parent, ?MODULE, [], State);
  +            sys:handle_system_msg(Request, From, Parent, ?MODULE, [],
  +                {State, ClientState});
           Msg ->
  -            {ok, State2} = handle_msg(Msg, State),
  -            loop(State2)
  +            {ok, State2, ClientState2} = handle_msg(Msg, State, ClientState),
  +            loop(State2, ClientState2)
       end.
   
   process_replies([], _State) ->
  
positive.code:     timer_ref        :: undefined | reference()
  }).
  
  -type state() :: #state {}.
  
  %% public
  
negative.code: 
  terminate(Reason, #state {
          client = Client,
          name = Name,
          timer_ref = TimerRef
      }, ClientState) ->
  
      shackle_utils:cancel_timer(TimerRef),
      ok = Client:terminate(ClientState),
  