anchor.diff:          protocol = Protocol,
           reconnect_state = ReconnectState,
           socket_options = SocketOptions
  -    } = State) ->
  +    } = State, ClientState) ->
   
       case Protocol:new(Ip, Port, SocketOptions) of
           {ok, Socket} ->
  -            {ok, ClientState} = Client:init(),
  +            {ok, ClientState2} = Client:init(),
               inet:setopts(Socket, [{active, false}]),
   
  -            case Client:setup(Socket, ClientState) of
  -                {ok, ClientState2} ->
  +            case Client:setup(Socket, ClientState2) of
  +                {ok, ClientState3} ->
                       inet:setopts(Socket, [{active, true}]),
   
                       {ok, State#state {
  -                        client_state = ClientState2,
                           reconnect_state = reconnect_state_reset(ReconnectState),
                           socket = Socket
  -                    }};
  -                {error, Reason, ClientState2} ->
  +                    }, ClientState3};
  +                {error, Reason, ClientState3} ->
                       shackle_utils:warning_msg(PoolName,
                           "setup error: ~p", [Reason]),
   
  -                    reconnect(State#state {
  -                        client_state = ClientState2
  -                    })
  +                    reconnect(State, ClientState3)
               end;
           {error, Reason} ->
               shackle_utils:warning_msg(PoolName,
                   "~p connect error: ~p", [Protocol, Reason]),
  -            reconnect(State)
  +            reconnect(State, ClientState)
       end;
   handle_msg(#cast {} = Cast, #state {
           socket = undefined,
           name = Name
  -    } = State) ->
  +    } = State, ClientState) ->
   
       reply(Name, {error, no_socket}, Cast),
  -    {ok, State};
  +    {ok, State, ClientState};
   handle_msg(#cast {request = Request} = Cast, #state {
           client = Client,
  -        client_state = ClientState,
           header = Header,
           pool_name = PoolName,
           protocol = Protocol,
           socket = Socket
  -    } = State) ->
  +    } = State, ClientState) ->
   
       {ok, ExtRequestId, Data, ClientState2} =
           Client:handle_request(Request, ClientState),
  
positive.code:     exit(Reason).
  
  %% private
  close(#state {name = Name} = State) ->
      reply_all(Name, {error, socket_closed}),
      reconnect(State).
  
  handle_msg(?MSG_CONNECT, #state {
          client = Client,
  
negative.code:     timer_ref        :: undefined | reference()
  }).
  
  -type client_state() :: term().
  -type state() :: #state {}.
  
  %% public
  