anchor.diff:  %% @end
   -spec set_controlling_process(Connection :: pid(), Client :: pid()) -> ok | {error, unauthorized}.
   set_controlling_process(Conn, Client) ->
  -    gen_fsm:sync_send_all_state_event(Conn, {set_controlling_process, Client}).
  +    gen_statem:call(Conn, {set_controlling_process, Client}).
   
   %%
   %% gen_fsm callbacks
  
positive.code:         _ -> dbus_transport:close(Sock)
      end,
      ok.
  
  %%%
  %%% gen_fsm states
  %%%
  %% @doc Default is to use EXTERNAL mechanism first. If it fails, server
  %% will answer with list of possible authentications.
  %% Mimic C implementation
  %%
  %% @end
  connected(auth, {_Pid, Tag}=From, #state{sock=Sock, mechs=[Mech|Rest]}=State) ->
      case Mech:init() of
          {ok, Resp} ->
              ?debug("DBUS auth: sending initial data~n", []),
              dbus_transport:send(Sock, << "AUTH ", Resp/binary, "\r\n" >>),
              {reply, {ok, {self(), Tag}}, waiting_for_ok, 
               State#state{waiting=[From], mechs=Rest}};
          {continue, Resp, MechState} ->
              ?debug("DBUS auth: sending initial data (continue)~n", []),
              dbus_transport:send(Sock, << "AUTH ", Resp/binary, "\r\n" >>),
              {reply, {ok, {self(), Tag}}, waiting_for_data,
               State#state{waiting=[From], mechs=Rest, mech_state={Mech, MechState}}}
      end;
  
  connected({call, _}, _From, State) ->
      {reply, {error, authentication_needed}, connected, State};
  
  connected(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, connected, State}.
  
  
  waiting_for_ok({call, _}, _From, State) ->
      {reply, {error, authentication_needed}, waiting_for_ok, State};
  
  waiting_for_ok(auth, {_Pid, Tag}=From, #state{waiting=Waiting}=State) ->
      {reply, {ok, {self(), Tag}}, waiting_for_ok, 
       State#state{waiting=[From|Waiting]}};
  waiting_for_ok(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, waiting_for_ok, State}.
  
  
  waiting_for_data({call, _}, _From, State) ->
      {reply, {error, authentication_needed}, waiting_for_data, State};
  
  waiting_for_data(auth, {_Pid, Tag}=From, #state{waiting=Waiting}=State) ->
      {reply, {ok, {self(), Tag}}, waiting_for_data, 
       State#state{waiting=[From|Waiting]}};
  waiting_for_data(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, waiting_for_data, State}.
  
  
  waiting_for_reject({call, _}, _From, State) ->
      {reply, {error, authentication_needed}, waiting_for_reject, State};
  
  waiting_for_reject(auth, {_Pid, Tag}=From, #state{waiting=Waiting}=State) ->
      {reply, {ok, {self(), Tag}}, waiting_for_reject, State#state{waiting=[From|Waiting]}};
  waiting_for_reject(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, waiting_for_reject, State}.
  
  
  waiting_for_agree({call, _}, _From, State) ->
      {reply, {error, authentication_needed}, waiting_for_agree, State};
  
  waiting_for_agree(auth, {_Pid, Tag}=From, #state{waiting=Waiting}=State) ->
      {reply, {ok, {self(), Tag}}, waiting_for_agree, 
       State#state{waiting=[From|Waiting]}};
  waiting_for_agree(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, waiting_for_agree, State}.
  
  
  authenticated(auth, _From, State) ->
      {reply, authenticated, authenticated, State};
  
  authenticated({call, #dbus_message{}=Msg}, {Pid, Tag}, 
                #state{sock=Sock, serial=S, pending=Pending}=State) ->
      Data = dbus_marshaller:marshal_message(dbus_message:set_serial(S, Msg)),
      true = ets:insert(Pending, {S, Pid, Tag}),
      ok = dbus_transport:send(Sock, Data),
      {reply, {ok, {self(), Tag}}, authenticated, State#state{serial=S+1}};
  
  authenticated(_Evt, _From, State) ->
      ?debug("Unexpected event: ~p~n", [_Evt]),
      {reply, {error, invalid_event}, authenticated, State}.
  
  %%%
  %%% Priv
  
negative.code: -spec start_link(bus_id(), list()) -> {ok, dbus_connection()} | {error, term()}.
  start_link(BusId, Options) when is_record(BusId, bus_id),
                                  is_list(Options) ->
      case gen_statem:start_link(?MODULE, [BusId, Options, self()], []) of
          {ok, Pid} -> {ok, {?MODULE, Pid}};
          {error, Err} -> {error, Err}
      end.
  