digraph G {
  // rankdir=LR;
  newrank=true;

  Network [shape=box];
  {Network; Transition_router; rank=source};

  subgraph cluster_participating {
    label="Participating";
    "Transition_handler.Validator";
    "Transition_handler.Processor";
    "transition has parent" [shape=diamond];
    {Catchup_scheduler; Catchup; Unprocessed_transition_cache [color=red]; rank=same};
    Breadcrumb_builder;
    Transition_frontier [color=red];
  }

  subgraph cluster_bootstrapping {
    label="Bootstrapping";
    Bootstrap_controller;
  }

  {"Transition_handler.Validator"; Bootstrap_controller; rank=same};

  Network -> Transition_router [label="transitions",color=blue];
  Transition_router -> {"Transition_handler.Validator", Bootstrap_controller}
    [label="transitions (overflow: drop old)",color=blue];

  Bootstrap_controller -> Transition_router [label="transition frontier",color=green];

  "Transition_handler.Validator" -> "Transition_handler.Processor"
    [label="transitions (overflow: drop old)",color=blue];
  "Transition_handler.Processor" -> "transition has parent";
  "Transition_handler.Processor" -> Catchup_scheduler [label="notify"];
  "transition has parent" -> Transition_frontier [label="yes",color=red];
  "transition has parent" -> Catchup_scheduler [label="no"];

  {Catchup_scheduler, Catchup} -> Breadcrumb_builder;
  Catchup_scheduler -> Catchup [label="transition rose tree (overflow: drop old)",color=blue];
  Breadcrumb_builder -> "Transition_handler.Processor" [label="bulk breadcrumbs (overflow: blocking",color=blue];

  "Transition_handler.Validator" -> Unprocessed_transition_cache [color=green];
  "Transition_handler.Processor" -> Unprocessed_transition_cache [color=red];
  Breadcrumb_builder -> Unprocessed_transition_cache [color=red];
}
