docs: static String generateGraphVizDotFile(final ClassInfoList classInfoList, final float sizeX, final float sizeY,
              final boolean showFields, final boolean showFieldTypeDependencyEdges, final boolean showMethods,
              final boolean showMethodTypeDependencyEdges, final boolean showAnnotations,
              final boolean useSimpleNames, final ScanSpec scanSpec) {
          final StringBuilder buf = new StringBuilder(1024 * 1024);
          buf.append("digraph {\n");
          buf.append("size=\"").append(sizeX).append(',').append(sizeY).append("\";\n");
          buf.append("layout=dot;\n");
          buf.append("rankdir=\"BT\";\n");
          buf.append("overlap=false;\n");
          buf.append("splines=true;\n");
          buf.append("pack=true;\n");
          buf.append("graph [fontname = \"Courier, Regular\"]\n");
          buf.append("node [fontname = \"Courier, Regular\"]\n");
          buf.append("edge [fontname = \"Courier, Regular\"]\n");
  
          final ClassInfoList standardClassNodes = classInfoList.getStandardClasses();
          final ClassInfoList interfaceNodes = classInfoList.getInterfaces();
          final ClassInfoList annotationNodes = classInfoList.getAnnotations();
  
          for (final ClassInfo node : standardClassNodes) {
              buf.append('"').append(node.getName()).append('"');
              labelClassNodeHTML(node, "box", STANDARD_CLASS_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
                      buf);
              buf.append(";\n");
          }
  
          for (final ClassInfo node : interfaceNodes) {
              buf.append('"').append(node.getName()).append('"');
              labelClassNodeHTML(node, "diamond", INTERFACE_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
                      buf);
              buf.append(";\n");
          }
  
          for (final ClassInfo node : annotationNodes) {
              buf.append('"').append(node.getName()).append('"');
              labelClassNodeHTML(node, "oval", ANNOTATION_COLOR, showFields, showMethods, useSimpleNames, scanSpec,
                      buf);
              buf.append(";\n");
          }
  
          final Set<String> allVisibleNodes = new HashSet<>();
          allVisibleNodes.addAll(standardClassNodes.getNames());
          allVisibleNodes.addAll(interfaceNodes.getNames());
          allVisibleNodes.addAll(annotationNodes.getNames());
  
          buf.append('\n');
          for (final ClassInfo classNode : standardClassNodes) {
              for (final ClassInfo directSuperclassNode : classNode.getSuperclasses().directOnly()) {
                  if (directSuperclassNode != null && allVisibleNodes.contains(directSuperclassNode.getName())
                          && !directSuperclassNode.getName().equals("java.lang.Object")) {
                      // class --> superclass
                      buf.append("  \"").append(classNode.getName()).append("\" -> \"")
                              .append(directSuperclassNode.getName()).append("\" [arrowsize=2.5]\n");
                  }
              }
  
              for (final ClassInfo implementedInterfaceNode : classNode.getInterfaces().directOnly()) {
                  if (allVisibleNodes.contains(implementedInterfaceNode.getName())) {
                      // class --<> implemented interface
                      buf.append("  \"").append(classNode.getName()).append("\" -> \"")
                              .append(implementedInterfaceNode.getName())
                              .append("\" [arrowhead=diamond, arrowsize=2.5]\n");
                  }
              }
  
              if (showFieldTypeDependencyEdges && classNode.fieldInfo != null) {
                  for (final FieldInfo fi : classNode.fieldInfo) {
                      for (final String referencedFieldTypeName : fi.findReferencedClassNames()) {
                          if (allVisibleNodes.contains(referencedFieldTypeName)) {
                              // class --[ ] field type (open box)
                              buf.append("  \"").append(referencedFieldTypeName).append("\" -> \"")
                                      .append(classNode.getName())
                                      .append("\" [arrowtail=obox, arrowsize=2.5, dir=back]\n");
                          }
                      }
                  }
              }
  
              if (showMethodTypeDependencyEdges && classNode.methodInfo != null) {
                  for (final MethodInfo mi : classNode.methodInfo) {
                      for (final String referencedMethodTypeName : mi.findReferencedClassNames()) {
                          if (allVisibleNodes.contains(referencedMethodTypeName)) {
                              // class --[#] field type (open box)
                              buf.append("  \"").append(referencedMethodTypeName).append("\" -> \"")
                                      .append(classNode.getName())
                                      .append("\" [arrowtail=box, arrowsize=2.5, dir=back]\n");
                          }
                      }
                  }
              }
          }
          for (final ClassInfo interfaceNode : interfaceNodes) {
              for (final ClassInfo superinterfaceNode : interfaceNode.getInterfaces().directOnly()) {
                  if (allVisibleNodes.contains(superinterfaceNode.getName())) {
                      // interface --<> superinterface
                      buf.append("  \"").append(interfaceNode.getName()).append("\" -> \"")
                              .append(superinterfaceNode.getName()).append("\" [arrowhead=diamond, arrowsize=2.5]\n");
                  }
              }
          }
          if (showAnnotations) {
              for (final ClassInfo annotationNode : annotationNodes) {
                  for (final ClassInfo annotatedClassNode : annotationNode.getClassesWithAnnotationDirectOnly()) {
                      if (allVisibleNodes.contains(annotatedClassNode.getName())) {
                          // annotated class --o annotation
                          buf.append("  \"").append(annotatedClassNode.getName()).append("\" -> \"")
                                  .append(annotationNode.getName()).append("\" [arrowhead=dot, arrowsize=2.5]\n");
                      }
                  }
                  for (final ClassInfo classWithMethodAnnotationNode : annotationNode
                          .getClassesWithMethodAnnotationDirectOnly()) {
                      if (allVisibleNodes.contains(classWithMethodAnnotationNode.getName())) {
                          // class with method annotation --o method annotation
                          buf.append("  \"").append(classWithMethodAnnotationNode.getName()).append("\" -> \"")
                                  .append(annotationNode.getName()).append("\" [arrowhead=odot, arrowsize=2.5]\n");
                      }
                  }
                  for (final ClassInfo classWithMethodAnnotationNode : annotationNode
                          .getClassesWithFieldAnnotationDirectOnly()) {
                      if (allVisibleNodes.contains(classWithMethodAnnotationNode.getName())) {
                          // class with field annotation --o method annotation
                          buf.append("  \"").append(classWithMethodAnnotationNode.getName()).append("\" -> \"")
                                  .append(annotationNode.getName()).append("\" [arrowhead=odot, arrowsize=2.5]\n");
                      }
                  }
              }
          }
          buf.append('}');
          return buf.toString();
      }