docs: def tree_to_graph(bbltree:BubbleTree) -> Graph or Digraph:
      """Compute as a graphviz.Graph instance the given graph.
  
      If given BubbleTree instance is oriented, returned value
      is a graphviz.Digraph.
  
      See http://graphviz.readthedocs.io/en/latest/examples.html#cluster-py
      for graphviz API
  
      """
      GraphObject = Digraph if bbltree.oriented else Graph
      def create(name:str):
          """Return a graphviz graph figurating a powernode"""
          ret = GraphObject('cluster_' + name)
          # dirty hack to get links between clusters: add a blank node inside
          # so the subgraph don't take it's name directly, but the blank node do.
          # ret.body.append('label = "{}"'.format(name))  # replaced by:
          ret.node(name, style='invis', shape='point')
          # ret.body.append('style=plaintext')
          ret.body.append('color=lightgrey')
          ret.body.append('label=""')
          ret.body.append('shape=ellipse')
          ret.body.append('penwidth=2')
          ret.body.append('pencolor=black')
          return ret
      nodes = frozenset(bbltree.nodes())
      subgraphs = {}
      # build for each powernode the associated subgraph, and add its successors
      for powernode in bbltree.powernodes():
          if powernode not in subgraphs:
              subgraphs[powernode] = create(powernode)
          for succ in bbltree.inclusions[powernode]:
              if succ not in subgraphs:
                  if succ not in nodes:
                      subgraphs[succ] = create(succ)
                  else:
                      subgraphs[powernode].node(succ)
      # add to Graph instances the Graph of successors as subgraphs 
      for powernode, succs in bbltree.inclusions.items():
          for succ in succs:
              if succ not in nodes:
                  subgraphs[powernode].subgraph(subgraphs[succ])
      # build the final graph by adding to it subgraphs of roots
      graph = GraphObject('graph', graph_attr={'compound': 'true'})
      for root in bbltree.roots:
          if root in subgraphs:
              graph.subgraph(subgraphs[root])
      # add the edges to the final graph
      for source, targets in bbltree.edges.items():
          for target in targets:
              if source <= target:
                  attrs = {}
                  if source not in nodes:
                      attrs.update({'ltail': 'cluster_' + source})
                  if target not in nodes:
                      attrs.update({'lhead': 'cluster_' + target})
                  graph.edge(source, target, **attrs)
      # print(graph)  # debug line
      # graph.view()  # debug line
      return graph