anchor.diff:    {send_stop, Message:: term(), #state{} }.
   
   handle_info(Info,State) ->
  -  case hndl_info(Info,State) of
  -    {Result, OutMsg, State1} ->
  -      case Result of
  -        send_stop ->
  -          close_session(State1);
  -        _ -> ok
  -      end,
  -      check_out_message(Result, OutMsg, State1);
  -    {stop,NewState} ->
  -      close_session(NewState),
  -      {stop,NewState};
  -    Other -> Other
  -  end.
  -
  -
  --spec check_out_message(atom(), term(), #state{} ) -> {atom(), term(),
  +  send_message_or_close_session(hndl_info(Info,State)).
  +
  +
  +send_message_or_close_session({reply_stop,OutMsg,State}) ->
  +  close_session(State),
  +  check_and_return_out_message(reply_stop,OutMsg,State);
  +send_message_or_close_session({send_stop,OutMsg,State}) ->
  +  close_session(State),
  +  check_and_return_out_message(send_stop,OutMsg,State);
  +send_message_or_close_session({Result,OutMsg,State}) ->
  +  check_and_return_out_message(Result, OutMsg, State);
  +send_message_or_close_session({ok, State}) ->
  +  {ok, State};
  +send_message_or_close_session({stop,State}) ->
  +  close_session(State),
  +  {stop, State}.
  +
  +
  +-spec check_and_return_out_message(atom(), term(), #state{} ) -> {atom(), term(),
                                                               #state{} } |
                                                              {ok, #state{} }.
  -check_out_message(Result, Msg,State) ->
  -  %% case erwa_middleware:validate_out_message(Msg,State) of
  -  %%   false ->
  -  %%     {ok,State};
  -  %%   OutMsg ->
  -  %%     {Result,OutMsg,State}
  -  %% end.
  +check_and_return_out_message(Result, Msg,State) ->
  +  % TODO: implememnt
     {Result, Msg, State}.
   
   
  -hndl_msg({hello,RealmName,Details}, #state{id=SessionId} = State) ->
  -  AuthId = maps:get(authid, Details, anonymous),
  -  Roles = maps:get(roles, Details, []),
  -  case {AuthId == anonymous, erwa_user_db:allow_anonymous(RealmName, tcp)} of 
  -    {true, true} -> 
  +
  +-spec hndl_msg(term(),#state{}) -> {stop, #state{}} | {reply_stop | reply , term(),
  +                                              #state{}}.
  +
  +hndl_msg({hello,RealmName,Details}, State) ->
  +  handle_hello_message(RealmName, Details, State);
  +hndl_msg({authenticate,Signature,Extra},State) ->
  +  handle_authenticate_message(Signature,Extra,State);
  +
  +hndl_msg({abort,_Details,_ErrorUrl},#state{is_auth=false}=State) ->
  +  {stop,State#state{is_auth=false}};
  +
  +hndl_msg(Msg,#state{is_auth=true}=State) ->
  +  hndl_msg_authed(Msg,State);
  +
  +hndl_msg(_Msg,State) ->
  +  {stop,State}.
  +
  +
  +
  +hndl_msg_authed({subscribe,RequestId,Options,Topic},State) ->
  +  handle_subscribe_message(RequestId,Options,Topic,State);
  +hndl_msg_authed({unsubscribe,RequestId,SubscriptionId},State) ->
  +  handle_unsubscribe_message(RequestId, SubscriptionId, State);
  +hndl_msg_authed({publish,RequestId,Options,Topic,Arguments,ArgumentsKw},State) ->
  +  handle_publish_message(RequestId,Options,Topic,Arguments, ArgumentsKw, State);
  +hndl_msg_authed({register,RequestId,Options,ProcedureUri},State) ->
  +  handle_register_message(RequestId,Options,ProcedureUri,State);
  +hndl_msg_authed({unregister,RequestId,RegistrationId}, State) ->
  +  handle_unregister_message(RequestId,RegistrationId,State);
  +hndl_msg_authed({call,RequestId,Options,ProcedureUri,Arguments,ArgumentsKw},State) ->
  +  handle_call_message(RequestId,Options, ProcedureUri, Arguments, ArgumentsKw, State);
  +hndl_msg_authed({cancel,RequestId,Options},State) ->
  +  handle_cancel_message(RequestId,Options,State);
  +hndl_msg_authed({error,invocation,InvocationId,Details,Error,Arguments,ArgumentsKw},State) ->
  +  handle_error_invocation_message(InvocationId,Details,Error,Arguments,ArgumentsKw,State);
  +hndl_msg_authed({yield,InvocationId,Options,Arguments,ArgumentsKw},State) ->
  +  handle_yield_message(InvocationId,Options,Arguments,ArgumentsKw,State);
  +hndl_msg_authed({goodbye,Details,Reason},State) ->
  +  handle_goodbye_message(Details,Reason,State);
  +hndl_msg_authed(Msg, State) ->
  +  handle_unknown_message(Msg,State).
  +
  +
  +hndl_info({invocation,DealerId,ProcedureId,Options,Arguments,ArgumentsKw}, State) ->
  +  handle_invocation_info(DealerId,ProcedureId,Options,Arguments,ArgumentsKw, State);
  +hndl_info({interrupt,DealerId,Options},State) ->
  +  handle_interrupt_info(DealerId,Options,State);
  +hndl_info({result,CallRequestId,Details,Arguments,ArgumentsKw},State) ->
  +  handle_result_info(CallRequestId,Details,Arguments,ArgumentsKw,State);
  +hndl_info({error,call,CallRequestId,Details,ErrorUri,Arguments,ArgumentsKw},State) ->
  +  hndl_error_call_info(error,call,CallRequestId,Details,ErrorUri,Arguments,ArgumentsKw,State);
  +hndl_info({event,SubscriptionId,PublicationId,Details,Arguments,ArgumentsKw}, State) ->
  +  handl_event_info(SubscriptionId,PublicationId,Details,Arguments,ArgumentsKw,State);
  +hndl_info(routing_closing,State) ->
  +  handle_routing_closing_info(State); 
  +hndl_info(shutdown,State) ->
  +  handle_shutdown_info(State);
  +hndl_info(Info, State) ->
  +  handle_unknown_info(Info, State).
  +
  +
  +
  +
  +%%%%% hello message %%%%%%%%%%%%%%%%%%%%%
  +handle_hello_message(RealmName, Details, State) ->
  +  Args = gather_hello_args(Details,RealmName),
  +  reply_to_hello(check_authentication(Args),Args,State).
  +
  +reply_to_hello(anonymous, #{ realm := RealmName }, #state{id=SessionId}=State) ->
         case erwa_sess_man:connect_to(RealmName) of
           ok ->
             %% SessionData = #{authid => anonymous, role => anonymous, session =>
  
positive.code:     {error,_} ->
        %% TODO: change the reply for eg partitioned calls
        {reply, {error,call,RequestId,#{},no_such_procedure}, State}
    end;
  
  
  
  
  hndl_msg_authed({error,invocation,InvocationId,Details,Error,Arguments,ArgumentsKw},#state{invocations=Invs,id=SessionId, realm_name=Realm}=State) ->
    case lists:keyfind(InvocationId,1,Invs) of
      {InvocationId,DealerId} ->
        ok = erwa_invocation:error(DealerId,Details,Error,Arguments,ArgumentsKw,SessionId,Realm),
        {ok,State#state{invocations = lists:keydelete(InvocationId,1,Invs)}};
      _ ->
        {ok,State}
    end;
  
  hndl_msg_authed({yield,InvocationId,Options,Arguments,ArgumentsKw},#state{invocations=Invs,id=SessionId, realm_name=Realm}=State) ->
    case lists:keyfind(InvocationId,1,Invs) of
      {InvocationId,DealerId} ->
        ok = erwa_invocation:yield(DealerId,Options,Arguments,ArgumentsKw,SessionId,Realm),
        {ok,State#state{invocations = lists:keydelete(InvocationId,1,Invs)}};
      _ ->
        {ok,State}
    end;
  
  hndl_msg_authed({goodbye,_Details,_Reason},#state{goodbye_sent=GBSent}=State) ->
    case GBSent of
      true ->
        {stop,State};
      false ->
        Msg = {goodbye,#{},goodbye_and_out},
        {reply_stop,Msg,State}
    end;
  
  hndl_msg_authed(_Msg, State) ->
    {stop, State }.
  
  
  
  
  
  
  hndl_info({invocation,DealerId,ProcedureId,Options,Arguments,ArgumentsKw}, #state{invocation_id=ID, invocations=Invs}=State) ->
    NewState = State#state{invocations=[{ID,DealerId}|Invs],invocation_id=ID+1},
    {send,{invocation,ID,ProcedureId,Options,Arguments,ArgumentsKw},NewState};
  
  hndl_info({interrupt,DealerId,Options},#state{invocations=Invs, client_roles=Roles}=State) ->
    {InvocationId,DealerId} = lists:keyfind(DealerId,2,Invs),
    Features = maps:get(features,maps:get(callee,Roles),#{}),
    case maps:get(call_canceling,Features,false) of
      true ->
        {send,{interrupt,InvocationId,Options},State};
      _ ->
        {ok,State#state{invocations=lists:keydelete(InvocationId,1,Invs)}}
    end;
  
  hndl_info({result,CallRequestId,_,_,_}=Msg,#state{calls=Calls}=State) ->
    {send,Msg,State#state{calls=lists:keydelete(CallRequestId,1,Calls)}};
  
  hndl_info({error,call,CallRequestId,_,_,_,_}=Msg,#state{calls=Calls}=State) ->
    {send,Msg,State#state{calls=lists:keydelete(CallRequestId,1,Calls)}};
  
  hndl_info({event,_,_,_,_,_}=Msg,State) ->
    {send,Msg,State};
  
  hndl_info(routing_closing,#state{goodbye_sent=GBsent}=State) ->
    Msg = {goodbye,#{},close_realm},
    case GBsent of
      false ->
        {send_stop,Msg,State#state{goodbye_sent=true}};
      _ ->
        {stop,State}
    end;
  
  hndl_info(shutdown,State) ->
    {stop,State};
  
  hndl_info(Info, State) ->
    error("unknown Msg ~p~n",[Info]),
    {ok,State}.
  
  
  
  close_session(#state{id=SessionId,realm_name=RealmName}) ->
  
negative.code:                 invocation_id = 1,
                  invocations = [],
                  calls = [],
                  client_role = anonymous 
                  }).
  
  
  