digraph {
        /* new idea */

        title [label="Mailbox\nMachine" style="dotted"]

        {rank=same; S0A S0B}
        S0A [label="S0A:\nunknown"]
        S0A -> S0B [label="connected"]
        S0B [label="S0B:\nunknown\n(bound)" color="orange"]

        S0B -> S0A [label="lost"]

        S0A -> P0A_queue [label="add_message" style="dotted"]
        P0A_queue [shape="box" label="queue" style="dotted"]
        P0A_queue -> S0A [style="dotted"]
        S0B -> P0B_queue [label="add_message" style="dotted"]
        P0B_queue [shape="box" label="queue" style="dotted"]
        P0B_queue -> S0B [style="dotted"]

        subgraph {rank=same; S1A P_open}
        S0A -> S1A [label="got_mailbox"]
        S1A [label="S1A:\nknown"]
        S1A -> P_open [label="connected"]
        S1A -> P1A_queue [label="add_message" style="dotted"]
        P1A_queue [shape="box" label="queue" style="dotted"]
        P1A_queue -> S1A [style="dotted"]
        S1A -> S2A [style="invis"]
        P_open -> P2_connected [style="invis"]

        S0A -> S2A [style="invis"]
        S0B -> P_open [label="got_mailbox" color="orange" fontcolor="orange"]
        P_open [shape="box"
                label="store mailbox\nRC.tx_open\nRC.tx_add(queued)" color="orange"]
        P_open -> S2B [color="orange"]

        subgraph {rank=same; S2A S2B P2_connected}
        S2A [label="S2A:\nknown\nmaybe opened"]
        S2B [label="S2B:\nopened\n(bound)" color="green"]
        S2A -> P2_connected [label="connected"]
        S2B -> S2A [label="lost"]

        P2_connected [shape="box" label="RC.tx_open\nRC.tx_add(queued)"]
        P2_connected -> S2B

        S2A -> P2_queue [label="add_message" style="dotted"]
        P2_queue [shape="box" label="queue" style="dotted"]
        P2_queue -> S2A [style="dotted"]

        S2B -> P2_send [label="add_message"]
        P2_send [shape="box" label="queue\nRC.tx_add(msg)"]
        P2_send -> S2B

        {rank=same; P2_send P2_close P2_process_theirs}
        P2_process_theirs -> P2_close [style="invis"]
        S2B -> P2_process_ours [label="rx_message\n(ours)"]
        P2_process_ours [shape="box" label="dequeue"]
        P2_process_ours -> S2B
        S2B -> P2_process_theirs [label="rx_message\n(theirs)"
                                  color="orange" fontcolor="orange"]
        P2_process_theirs [shape="box" color="orange"
                           label="N.release\nO.got_message if new\nrecord"
                           ]
        P2_process_theirs -> S2B [color="orange"]

        S2B -> P2_close [label="close" color="red"]
        P2_close [shape="box" label="RC.tx_close" color="red"]
        P2_close -> S3B [color="red"]

        subgraph {rank=same; S3A P3_connected S3B}
        S3A [label="S3A:\nclosing"]
        S3A -> P3_connected [label="connected"]
        P3_connected [shape="box" label="RC.tx_close"]
        P3_connected -> S3B
        #S3A -> S3A [label="add_message"] # implicit
        S3B [label="S3B:\nclosing\n(bound)" color="red"]
        S3B -> S3B [label="add_message\nrx_message\nclose"]
        S3B -> S3A [label="lost"]

        subgraph {rank=same; P3A_done P3B_done}
        P3A_done [shape="box" label="T.mailbox_done" color="red"]
        P3A_done -> S4A
        S3B -> P3B_done [label="rx_closed" color="red"]
        P3B_done [shape="box" label="T.mailbox_done" color="red"]
        P3B_done -> S4B

        subgraph {rank=same; S4A S4B}
        S4A [label="S4A:\nclosed"]
        S4B [label="S4B:\nclosed"]
        S4A -> S4B [label="connected"]
        S4B -> S4A [label="lost"]
        S4B -> S4B [label="add_message\nrx_message\nclose"] # is "close" needed?

        S0A -> P3A_done [label="close" color="red"]
        S0B -> P3B_done [label="close" color="red"]
        S1A -> P3A_done [label="close" color="red"]
        S2A -> S3A [label="close" color="red"]
        
}