/**
  * Traverse tree recursively and generate dot code for edges.
  *
  * @param n The root node to start with.
  * @param nodeIds The map containing the node IDs.
  * @param nextNodeId The counter for the IDs of the nodes.
  * @param ps The stream in which the dot code will be written.
  * @param shortLabels Determines whether to use short labels or not.
  */
 private static void dotEdgesFromSubTree(
     final AbstractCallTreeNode<?> n,
     final Map<AbstractCallTreeNode<?>, Integer> nodeIds,
     final AtomicInteger nextNodeId,
     final PrintStream ps,
     final boolean shortLabels) {
   final StringBuilder strBuild = new StringBuilder(64);
   nodeIds.put(n, nextNodeId.get());
   strBuild
       .append(nextNodeId.getAndIncrement())
       .append("[label =\"")
       .append(
           n.isRootNode()
               ? SystemModelRepository.ROOT_NODE_LABEL // NOCS
               : AbstractCallTreeFilter.nodeLabel(n, shortLabels)) // NOCS
       .append("\",shape=" + DotFactory.DOT_SHAPE_NONE + "];");
   ps.println(strBuild.toString());
   for (final WeightedDirectedCallTreeEdge<?> child : n.getChildEdges()) {
     AbstractCallTreeFilter.dotEdgesFromSubTree(
         child.getTarget(), nodeIds, nextNodeId, ps, shortLabels);
   }
 }