anchor.diff:       } = UserInfo,
       {ok, IoList} = CmdMod:render([{user, User },{uid, Uid},{gid, Gid},{home_dir, HomeDir}]), 
       CmdList = binary:split(list_to_binary(IoList),[<<"\n">>],[global]),
  -    {ok, {ok,CmdList}};
  -execute_commands(_Mod,_Info, _Connection) ->
  -    {error, no_cmd_mod}.
  -
  -close_connection(_Con) ->
  +    {ok, State#state{cmd_list=CmdList, connection = Connection}};
  +create_command_list(_Mod, _Info, _Connection, State) ->
  +    {ok, State#state{error = connection_or_cmd_error}}. 
  +
  +trigger_next_command() ->
  +    gen_server:cast(self(),execute_cmd).
  +
  +execute_single_command_or_exit(State) ->
  +    #state{ cmd_list = CmdList,
  +            connection = Connection,
  +            error = Error,
  +            con_type = ConType,
  +            cmd_log = CmdLog
  +          } = State,
  +    execute_command_or_send_result(CmdList,ConType,Connection,Error,CmdLog,State).
  +
  +execute_command_or_send_result([],ConType,Connection,undefined,Log,State) ->
  +    close_connection(Connection,ConType),
  +    [LastResult|_] = Log,
  +    {ok,NewState} = send_reply({ok, LastResult},State),
  +    {stop,normal,NewState};
  +execute_command_or_send_result([Cmd|T],ConType,Connection,undefined,_Log,State) ->
  +    {ok, CmdState} = execute_command(Cmd,ConType,Connection),
  +    {noreply, State#state{cmd_state = CmdState}, cmd_list = T}.
  +
  +
  +execute_command(Cmd, ssh, Connection) ->
  +    {ok, ChannelId} = ssh_connection:session_channel(Connection,infinity),
  +    success = ssh_connection:exec(Connection,ChannelId,Cmd,infinity),
  +    {ok, #{channel_id => ChannelId, cmd => Cmd}}.
  +
  +
  +handle_ssh_result(SshCon,SshMsg, #state{connection = SshCon} = State) ->
  +    #state{
  +       cmd_state = #{ channel_id := ChannelId}
  +      } = State,
  +    {ok, NewState} = handle_ssh_message(SshMsg,ChannelId,State),
  +    {noreply, NewState};
  +handle_ssh_result(_SshCon,_SshMsg,State) ->
  +    {noreply,State}.
  +
  +handle_ssh_message({data,ChannelId,0,Data},ChannelId,State) ->
  +    % data on std out
  +    #state{ cmd_state = CmdState
  +          } = State,
  +    StdOut = [Data | maps:get(std_out,CmdState,[])],
  +    StdErr = [<<>> | maps:get(std_err,CmdState,[])],
  +    Update = #{std_out => StdOut, std_err => StdErr},
  +    NewState = State#state{ cmd_state = maps:merge(CmdState,Update) },
  +    {ok, NewState};
  +handle_ssh_message({data,ChannelId,1,Data},ChannelId,State) ->
  +    % data on std err 
  +    #state{ cmd_state = CmdState
  +          } = State,
  +    StdOut = [<<>> | maps:get(std_out,CmdState,[])],
  +    StdErr = [Data | maps:get(std_err,CmdState,[])],
  +    Update = #{std_out => StdOut, std_err => StdErr},
  +    NewState = State#state{ cmd_state = maps:merge(CmdState,Update) },
  +    {ok, NewState};
  +handle_ssh_message({eof,ChannelId},ChannelId,State) ->
  +    {ok, State};
  +handle_ssh_message({exit_signal,ChannelId, ExitSignal, ErrorMsg, Lang},ChannelId,State) ->
  +    #state{ cmd_state = CmdState
  +          } = State,
  +    Update = #{exit_signale => ExitSignal, err_msg => ErrorMsg, lang => Lang},
  +    NewState = State#state{ cmd_state = maps:merge(CmdState,Update) },
  +    {ok, NewState};
  +handle_ssh_message({exit_status,ChannelId, ExitStatus},ChannelId,State) ->
  +    #state{ cmd_state = CmdState
  +          } = State,
  +    Update = #{exit_status => ExitStatus},
  +    NewState = State#state{ cmd_state = maps:merge(CmdState,Update) },
  +    {ok, NewState};
  +handle_ssh_message({closed,ChannelId},ChannelId,State) ->
  +    #state{ cmd_state = CmdState,
  +            cmd_log = Log
  +          } = State,
  +    trigger_next_command(),
  +    NewState = State#state{ cmd_state = #{},
  +                            cmd_log = [ CmdState | Log] },
  +    {ok, NewState};
  +handle_ssh_message(_Msg,_ChannelId,State) ->
  +    {ok, State}.
  +
  +
  +
  +close_connection(Connection, ssh) ->
  +    ok = ssh:close(Connection);
  +close_connection(_,  local ) ->
  +    ok;
  +close_connection(_Con,_Info) ->
       ok.
  +
  +send_reply(_Reply,#state{client=undefined}=State) ->
  +    {ok,State};
  +send_reply(Reply,#state{client=Client}=State) ->
  +    gen_server:reply(Client,Reply),
  +    {ok,State#state{client=undefined}}.
  +
  
positive.code: 	{ok, State}.
  
  
  send_reply(_Reply,#state{client=undefined}=State) ->
      {ok,State};
  send_reply(Reply,#state{client=Client}=State) ->
      gen_server:reply(Client,Reply),
      {ok,State#state{client=undefined}}.
  
  % This is the main working function
  perform_request(State) ->
      #state{service_id = ServiceId,
             user_info = UserInfo
            } = State,
      {ok, ServiceInfo} = tts_service:get_info(ServiceId),
      {ok, Connection} = connect_to_service(ServiceInfo),
      {ok, CmdMod} = get_cmd_module(request,ServiceInfo),
      {ok, Result} = execute_commands(CmdMod,UserInfo,Connection),
      ok = close_connection(Connection),
      send_reply(Result ,State).
  
                        
  connect_to_service(#{con_type := local}) ->
      Connection = con,
      {ok, Connection};
  connect_to_service(#{con_type := ssh , con_host := _Host, key_set := true} = Info ) ->
      _Port = maps:get(con_port,Info,22),
      _User = maps:get(con_user,Info,<<"root">>),
      Connection = con,
      {ok, Connection};
  connect_to_service(#{con_type := ssh } ) ->
      throw(missing_ssh_config);
  connect_to_service( _ )  ->
  
negative.code:           service_info = undefined,
            user_info = undefined,
            token = undefined,
            params = undefined,
            connection = undefined,
            con_type = undefined,
            cmd_list = [],
            cmd_log = [],
            cmd_state = undefined,
            error = undefined
  }).
  
  %% API.
  