docs: def generate_dot(self, name, urls={}, env=None,
                       graph_attrs={}, node_attrs={}, edge_attrs={}):
          # type: (unicode, Dict, BuildEnvironment, Dict, Dict, Dict) -> unicode
          """Generate a graphviz dot graph from the classes that were passed in
          to __init__.
  
          *name* is the name of the graph.
  
          *urls* is a dictionary mapping class names to HTTP URLs.
  
          *graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing
          key/value pairs to pass on as graphviz properties.
          """
          g_attrs = self.default_graph_attrs.copy()
          n_attrs = self.default_node_attrs.copy()
          e_attrs = self.default_edge_attrs.copy()
          c_attrs = self.default_cluster_attrs.copy()
          g_attrs.update(graph_attrs)
          n_attrs.update(node_attrs)
          e_attrs.update(edge_attrs)
          if env:
              g_attrs.update(env.config.inheritance_graph_attrs)
              n_attrs.update(env.config.inheritance_node_attrs)
              e_attrs.update(env.config.inheritance_edge_attrs)
              c_attrs.update(env.config.inheritance_cluster_attrs)
  
          res = []  # type: List[unicode]
          res.append('digraph %s {\n' % name)
          res.append(self._format_graph_attrs(g_attrs))
  
          subgraphs = defaultdict(list)  # subgraph_name => list of node names
  
          for name, fullname, bases, tooltip in sorted(self.class_info):
              subgraph_name = ".".join(fullname.split(".")[:-1])
              subgraphs[subgraph_name].append(name)
              # Write the node
              this_node_attrs = n_attrs.copy()
              if fullname in urls:
                  this_node_attrs['URL'] = '"%s"' % urls[fullname]
                  this_node_attrs['target'] = '"_top"'
              if tooltip:
                  this_node_attrs['tooltip'] = tooltip
              res.append('  "%s" [%s];\n' %
                         (name, self._format_node_attrs(this_node_attrs)))
  
              # Write the edges
              for base_name in bases:
                  res.append('  "%s" -> "%s" [%s];\n' %
                             (base_name, name,
                              self._format_node_attrs(e_attrs)))
  
          if self.cluster_modules:
              for subgraph_name in subgraphs:
                  res.append('subgraph cluster_%s {\n'
                             % subgraph_name.replace('.', '_'))
                  res.append('  label="%s";\n' % subgraph_name)
                  res.append('  graph[' + self._format_node_attrs(c_attrs) +
                             "];\n")
                  res.append('  ' + "; ".join(subgraphs[subgraph_name]) + "\n")
                  res.append('}\n')
  
          res.append('}\n')
          return ''.join(res)