anchor.diff:       io_lib:format('This printout is generated ~s. ~n',[datetime()])
       ].
   
  -
  -print_system({{server,ssh_system_sup,Addr,Port,Profile}, Pid, supervisor, [ssh_system_sup]}) ->
  -    [io_lib:format(?INDENT"Local: ~s (~p children) Profile ~p~n",
  -                   [fmt_host_port({Addr,Port}),
  -                    ssh_acceptor:number_of_connections(Pid),
  -                    Profile
  +print_sups(Role, StartPid) ->
  +    walk_tree(Role, get_subs_tree(StartPid)).
  +
  +%%%================================================================
  +get_subs_tree(StartPid) ->
  +    lists:foldl(fun({Id,_,worker,_}=C, Acc) -> [{C,chspec(StartPid,Id)}|Acc];
  +                   ({Id,Pid,supervisor,_}=C, Acc) -> [{C,chspec(StartPid,Id),get_subs_tree(Pid)}|Acc]
  +                end, [], children(StartPid)).
  +
  +chspec(Sup, Id) ->
  +    try supervisor:get_childspec(Sup, Id)
  +    of
  +        {ok,Spec} -> Spec;
  +        {error,_} -> undefined
  +    catch _:_ -> undefined
  +    end.
  +    
  +%%%----------------------------------------------------------------
  +walk_tree(Role, Tree) ->
  +    walk_tree(Role, Tree, _Indent=?inc(0)).
  + 
  +walk_tree(Role, [{{_,_,supervisor,_},_,_}=H|T], Indent) ->
  +    [io_lib:format('~s',[format_sup(Role,H,Indent)]) |
  +     walk_tree(Role, T, Indent)
  +    ];
  +walk_tree(Role, [{{_,_,worker,_},_}=H|T], Indent) ->
  +    [io_lib:format('~s',[format_wrk(Role,H,Indent)]) |
  +     walk_tree(Role, T, Indent)
  +    ];
  +walk_tree(_Role, [], _) ->
  +    "".
  +
  +
  +format_sup(server,
  +           {{{ssh_system_sup,LocalAddress},Pid,supervisor,[ssh_system_sup]}, _Spec,
  +            [{{{ssh_acceptor_sup,Address},AccSupPid,supervisor,[ssh_acceptor_sup]}, _AccSupSpec,
  +              [{{{ssh_acceptor_sup,Address},AccPid,worker,[ssh_acceptor]}, _AccSpec}]}
  +             | Children]
  +           }, Indent) ->
  +   [indent(Indent),
  +    io_lib:format("Local listen: ~s, Daemon_ref = ~s~n"
  +                  "~ssys_sup=~s, acc_sup=~s, acc=~s~n",
  +                  [format_address(LocalAddress),print_pid(Pid),
  +                   indent(Indent),print_pid(Pid),print_pid(AccSupPid),print_pid(AccPid)]),
  +    walk_tree(server, Children, ?inc(Indent)),
  +    io_lib:nl() % Separate system supervisors by an empty line
  +   ];
  +format_sup(server, {{{ssh_system_sup,LocalAddress},Pid,supervisor,[ssh_system_sup]}, _Spec, Children}, Indent) ->
  +    [indent(Indent),
  +     io_lib:format("Local listen: none (was: ~s), Daemon_ref = ~s~n"
  +                   "~ssys_sup=~s~n",
  +                   [format_address(LocalAddress),print_pid(Pid),
  +                    indent(Indent),print_pid(Pid)]),
  +     walk_tree(server, Children, ?inc(Indent)),
  +     io_lib:nl() % Separate system supervisors by an empty line
  +    ];
  +format_sup(client, {{{ssh_system_sup,LocalAddress},Pid,supervisor,[ssh_system_sup]}, _Spec, Children}, Indent) ->
  +    [indent(Indent),
  +     io_lib:format("Local:  ~s sys_sup=~s~n", [format_address(LocalAddress), print_pid(Pid)]),
  +     walk_tree(client, Children, ?inc(Indent)),
  +     io_lib:nl() % Separate system supervisors by an empty line
  +    ];
  +format_sup(Role,
  +           {{Ref,SubSysSup,supervisor,[ssh_subsystem_sup]}, _SubSysSpec,
  +            [{{connection,ConnPid,worker,[ssh_connection_handler]}, _ConnSpec} 
  +             | Children]
  +           },
  +           Indent) when is_reference(Ref) ->
  +    [io_lib:format("~sRemote: ~s (Version: ~s)~n"
  +                   "~sConnectionRef=~s, subsys_sup=~s~n",
  +                   [indent(Indent), peer_addr(ConnPid), peer_version(Role,ConnPid),
  +                    indent(Indent), print_pid(ConnPid), print_pid(SubSysSup)
                      ]),
  -     lists:map(fun print_subsystem/1, children(Pid))
  -    ];
  -print_system({{client,ssh_system_sup,Addr,Port,Profile}, Pid, supervisor, [ssh_system_sup]}) ->
  -    [io_lib:format(?INDENT"Local: ~s Profile ~p~n",
  -                   [fmt_host_port({Addr,Port}),
  -                    Profile
  -                   ]),
  -     lists:map(fun print_subsystem/1, children(Pid))
  -    ];
  -print_system({_, _Pid, worker, [ssh_controller]}) ->
  -    ""; % io_lib:format(?INDENT"Controller~n",[]);
  -print_system(_X) ->
  -    io_lib:format(?INDENT"nyi system ~p~n",[_X]).
  -
  -
  -
  -
  -print_subsystem({{ssh_acceptor_sup,_Addr,_Port,_Profile}, _Pid, supervisor, [ssh_acceptor_sup]}) ->
  -    io_lib:format(?INDENT?INDENT"Acceptor~n",[]);
  -print_subsystem({Ref,Pid,supervisor,[ssh_subsystem_sup]}) when is_reference(Ref),
  -                                                               is_pid(Pid) ->
  -    Cs = children(Pid),
  -    [
  -     lists:map(
  -       fun(Sup) ->
  -                [print_conn(P) || {undefined,P,worker,[ssh_connection_handler]} <- children(Sup)]
  -       end,
  -       [P ||  {_Ref,P,supervisor,[ssh_connection_sup]} <- Cs]),
  -
  -     lists:map(
  -       fun(Sup) ->
  -                [print_ch(M,P) || {_Ref,P,worker,[M]} <- children(Sup),
  -                                lists:member(M, [ssh_channel,
  -                                                 ssh_channel_sup,
  -                                                 ssh_client_channel,
  -                                                 ssh_daemon_channel,
  -                                                 ssh_server_channel
  -                                                ])]
  -       end,
  -       [P ||  {_Ref,P,supervisor,[ssh_channel_sup]} <- Cs]),
  -
  -     lists:map(
  -       fun(Sup) ->
  -               [io_lib:format(?INDENT?INDENT?INDENT"TCP/IP fwd acceptor: ~p~n", [Pa]) 
  -                || {undefined,Pa,worker,[ssh_tcpip_forward_acceptor]} <- children(Sup)]
  -       end,
  -       [P ||  {_Ref,P,supervisor,[ssh_tcpip_forward_acceptor_sup]} <- Cs])
  -    ];
  -
  -print_subsystem(_X) ->
  -    io_lib:format(?INDENT?INDENT"nyi subsystem ~p~n",[_X]).
  -
  -
  -print_conn(Pid) ->
  +     walk_tree(Role,
  +               [{H,{connref,ConnPid},Cs} || {H,_,Cs} <- Children],
  +               ?inc(Indent)),
  +     io_lib:nl() % Separate sub system supervisors by an empty line
  +    ];
  +format_sup(Role, {{channel_sup,Pid,supervisor,[ssh_channel_sup]}, {connref,ConnPid}, Children}, Indent) ->
  +    [indent(Indent),
  +     case Children of
  +         [] ->
  +             io_lib:format("No open channels (chan_sup=~s).~n",[print_pid(Pid)]);
  +         _ ->
  +             Cinfo = try
  +                         {ok,L} = ssh_connection_handler:info(ConnPid),
  +                         L
  +                     catch
  +                         _:_ -> []
  +                     end,
  +             [io_lib:format("Open channels (chan_sup=~s):~n",[print_pid(Pid)]),
  +              walk_tree(Role,
  +                        [{ChH, lists:keyfind(ChPid,#channel.user,Cinfo)} || {ChH={_,ChPid,_,_},_} <- Children],
  +                        ?inc(Indent))
  +             ]
  +     end
  +    ];
  +format_sup(Role, {{tcpip_forward_acceptor_sup,Pid,supervisor,[ssh_tcpip_forward_acceptor_sup]}, {connref,_ConnPid}, Children}, Indent) ->
  +    [indent(Indent),
  +     case Children of
  +         [] ->
  +             io_lib:format("TCP/IP forwarding not started (fwd_sup=~s)~n", [print_pid(Pid)]);
  +         _ ->
  +             [io_lib:format("TCP/IP forwarding (fwd_sup=~s):~n", [print_pid(Pid)]),
  +              walk_tree(Role, Children, ?inc(Indent))
  +             ]
  +     end
  +    ];
  +format_sup(Role, {H, Spec, Children}, Indent) ->
  +    [indent(Indent),
  +     io_lib:format("?: ~200p ~s ~n", [H,print_spec(Spec)]),
  +     walk_tree(Role, Children, ?inc(Indent))
  +    ].
  +
  +
  +format_wrk(_Role, {{{ssh_acceptor_sup,Address},Pid,worker,[ssh_acceptor]}, _Spec}, Indent) ->
  +    [indent(Indent),
  +     io_lib:format("acceptor: ~s ~s~n", [format_address(Address),print_pid(Pid)])
  +    ];
  +format_wrk(_Role, {{{From,To},Pid,worker,[ssh_tcpip_forward_acceptor]}, _Spec}, Indent) ->
  +    io_lib:format("~sssh_tcpip_forward_acceptor ~s From: ~s, To: ~s~n", [indent(Indent),print_pid(Pid),
  +                                                                         format_address(From), format_address(To)]);
  +format_wrk(_Role, {{Ref,Pid,worker,[Cb]}, C}, Indent) when is_reference(Ref) ->
  +    Str =
  +        try io_lib:format("~p: (remote ~p)~s~s", [C#channel.local_id, C#channel.remote_id,
  +                                          if_true(C#channel.sent_close, " sent_close"),
  +                                          if_true(C#channel.recv_close, " recv_close")
  +                                         ])
  +        catch
  +            _:_ -> "?:"
  +        end,
  +    ChCb = try
  +               case Cb of
  +                   ssh_server_channel -> io_lib:format(" ~s", [Cb:get_print_info(Pid, channel_cb)]);
  +                   ssh_client_channel -> io_lib:format(" ~s", [Cb:get_print_info(Pid, channel_cb)]);
  +                   _ -> ""
  +               end
  +           catch _:_ -> ""
  +           end,
  +    [indent(Indent),
  +     io_lib:format("ch ~s ~p~s ~s~n", [Str, Cb, ChCb, print_pid(Pid)])
  +    ];
  +format_wrk(_Role, {H,Spec}, Indent) ->
  +    [indent(Indent),
  +     io_lib:format("?: ~200p ~s~n", [H,print_spec(Spec)])
  +    ].
  +
  +
  +
  +if_true(true, Str) -> Str;
  +if_true(_, _) -> "".
  +    
  +
  +peer_version(Role, Pid) ->
       try
  -	{{_Local,Remote},StrM} = ssh_connection_handler:get_print_info(Pid),
  -        io_lib:format(?INDENT?INDENT"Remote: ~s ConnectionRef = ~p ~s~n",[fmt_host_port(Remote),Pid,StrM])
  +        Key =
  +            case Role of
  +                client -> server_version;
  +                server -> client_version
  +            end,
  +        [{Key, {{_,_},V}}] =
  +             ssh_connection_handler:connection_info(Pid, [Key]),
  +        V
       catch
  -      	C:E ->
  -	    io_lib:format('****print_conn FAILED for ConnPid ~p: ~p:~p~n',[Pid, C, E])
  -    end.  
  -        
  -
  -print_ch(CBmod, Pid) ->
  +        _:_ -> "?"
  +    end.
  +
  +peer_addr(Pid) ->
       try
  -	{{_ConnManager,ChannelID}, Str} = ssh_server_channel:get_print_info(Pid),
  -	io_lib:format(?INDENT?INDENT?INDENT"ch ~p ~p ~p: ~s~n",[ChannelID, Pid, CBmod, Str])
  +        [{peer,{_,AddrPort}}] =
  +            ssh_connection_handler:connection_info(Pid, [peer]),
  +        ssh_lib:format_address_port(AddrPort)
       catch
  -	C:E ->
  -	    io_lib:format('****print_ch FAILED for ChanPid ~p: ~p:~p~n',[Pid, C, E])
  -    end.
  -
  -%%%================================================================
  -walk_sups(StartPid) ->
  -    walk_sups(children(StartPid), _Indent=?inc(0)).
  -
  -walk_sups([H={_,Pid,_,_}|T], Indent) ->
  -    [indent(Indent),
  -     io_lib:format('~200p  ~p is ~s~n',[H,Pid,dead_or_alive(Pid)]),
  -     case H of
  -	 {_,_,supervisor,[ssh_connection_handler]} -> "";
  -	 {_,Pid,supervisor,_} -> walk_sups(children(Pid), ?inc(Indent));
  -	 _ -> ""
  -     end,
  -     walk_sups(T, Indent)
  -    ];
  -walk_sups([], _) ->
  -    "".
  +        _:_ -> "?"
  +    end.
  +    
  +
  +format_address(#address{address=Addr, port=Port, profile=Prof}) ->
  +    io_lib:format("~s (profile ~p)", [ssh_lib:format_address_port({Addr,Port}),Prof]);
  +format_address(A) ->
  +    io_lib:format("~p",[A]).
  +
  +
  +print_pid(Pid) ->
  +    io_lib:format("~p~s",[Pid, dead_or_alive(Pid)]).
   
   dead_or_alive(Name) when is_atom(Name) ->
       case whereis(Name) of
   	undefined ->
  -	    "**UNDEFINED**";
  +	    " **UNDEFINED**";
   	Pid ->
   	    dead_or_alive(Pid)
       end;
   dead_or_alive(Pid) when is_pid(Pid) ->
  -    case process_info(Pid) of
  -	undefined -> "**DEAD**";
  -	_ -> "alive"
  +    case process_info(Pid,message_queue_len) of
  +	undefined -> " ***DEAD***";
  +        {message_queue_len,N} when N>10 -> io_lib:format(" ***msg_queue_len: ~p***",[N]);
  +        {message_queue_len,N} when N>0 -> io_lib:format(" (msg_queue_len: ~p)",[N]);
  +	_ -> ""
       end.
   
   indent(I) -> io_lib:format('~*c',[I,$ ]).
  
positive.code: 
  -export([print/0,
  	 print/1,
  	 string/0,
  	 collect_pids/0
  	]).
  
  -include("ssh_connect.hrl").
  
  print() ->
  
negative.code: 	    []
      end.
  
  %%%================================================================
  print_spec(_Spec) -> "".
  
  %%%================================================================
  underline(Str, LineChar) ->
  