anchor.diff:  	]).
   
   %%% Behaviour callbacks
  --export([callback_mode/0, handle_event/4, terminate/3,
  +-export([init/1, callback_mode/0, handle_event/4, terminate/3,
   	 format_status/2, code_change/4]).
   
   %%% Exports not intended to be used :). They are used for spawning and tests
  
positive.code: 			     ) -> no_return().
  %% . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  init_connection_handler(Role, Socket, Opts) ->
      process_flag(trap_exit, true),
      S0 = init_process_state(Role, Socket, Opts),
      try
  	{Protocol, Callback, CloseTag} = ?GET_OPT(transport, Opts),
  	S0#data{ssh_params = init_ssh_record(Role, Socket, Opts),
  		 transport_protocol = Protocol,
  		 transport_cb = Callback,
  		 transport_close_tag = CloseTag
  		}
      of
  	S ->
  	    gen_statem:enter_loop(?MODULE,
  				  [], %%[{debug,[trace,log,statistics,debug]} || Role==server],
  				  {hello,Role},
  				  S)
      catch
  	_:Error ->
  	    gen_statem:enter_loop(?MODULE,
  				  [],
  				  {init_error,Error},
  				  S0)
      end.
  
  
  init_process_state(Role, Socket, Opts) ->
      D = #data{connection_state =
  		   C = #connection{channel_cache = ssh_channel:cache_create(),
  				   channel_id_seed = 0,
  				   port_bindings = [],
  				   requests = [],
  				   options = Opts},
  	       starter = ?GET_INTERNAL_OPT(user_pid, Opts),
  	       socket = Socket,
  	       opts = Opts
  	      },
      case Role of
  	client ->
  	    %% Start the renegotiation timers
  	    timer:apply_after(?REKEY_TIMOUT,      gen_statem, cast, [self(), renegotiate]),
  	    timer:apply_after(?REKEY_DATA_TIMOUT, gen_statem, cast, [self(), data_size]),
  	    cache_init_idle_timer(D);
  	server ->
              cache_init_idle_timer(
                D#data{connection_state = init_connection(Role, C, Opts)}
               )
      end.
  
  
  init_connection(server, C = #connection{}, Opts) ->
      Sups =          ?GET_INTERNAL_OPT(supervisors, Opts),
  
      SystemSup =     proplists:get_value(system_sup,     Sups),
      SubSystemSup =  proplists:get_value(subsystem_sup,  Sups),
      ConnectionSup = proplists:get_value(connection_sup, Sups),
  
      C#connection{cli_spec = ?GET_OPT(ssh_cli, Opts, {ssh_cli,[?GET_OPT(shell, Opts)]}),
  		 exec =     ?GET_OPT(exec,    Opts),
  		 system_supervisor = SystemSup,
  		 sub_system_supervisor = SubSystemSup,
  		 connection_supervisor = ConnectionSup
  		}.
  
  
  init_ssh_record(Role, Socket, Opts) ->
      {ok, PeerAddr} = inet:peername(Socket),
      KeyCb = ?GET_OPT(key_cb, Opts),
      AuthMethods =
          case Role of
  
negative.code: -type renegotiate_flag() :: init | renegotiate.
  
  -type state_name() :: 
          {hello, role()}
        | {kexinit, role(), renegotiate_flag()}
        | {key_exchange, role(), renegotiate_flag()}
        | {key_exchange_dh_gex_init, server, renegotiate_flag()}
  