public ProperHierarchicalGraph(ISimpleNode[] hierarchicalGraph, int deepestLayer) {
   this.allNodes = hierarchicalGraph;
   this.deepestLayer = deepestLayer;
   for (int index = 1; index <= deepestLayer; index++) {
     nodesByLayer.put(index, new ArrayList<ISimpleNode>());
   }
   for (ISimpleNode node : hierarchicalGraph) {
     for (ISimpleNode child : node.getChildren()) {
       String message = node + " and " + child + " are more than one layer apart.";
       Preconditions.checkArgument(child.getLayer() - node.getLayer() == 1, message);
     }
     nodesByLayer.get(node.getLayer()).add(node);
   }
   this.type = identifyGraphType();
 }
 private ProperHierarchicalGraph(ISimpleNode[] nodes, int deepestLayer, IGraphType type) {
   this.allNodes = nodes;
   this.deepestLayer = deepestLayer;
   this.type = type;
   for (int index = 1; index - 1 < deepestLayer; index++) {
     nodesByLayer.put(index, new ArrayList<ISimpleNode>());
   }
   for (ISimpleNode node : nodes) {
     nodesByLayer.get(node.getLayer()).add(node);
   }
 }
 private List<ISimpleNode> insertDummyNodes(IRegularNode node, ISimpleNode child) {
   List<ISimpleNode> dummyNodes = new ArrayList<>();
   node.removeChild(child);
   child.removeParent(node);
   int nodeLayer = node.getLayer();
   ISimpleNode currentChild = child;
   while (currentChild.getLayer() - 1 > nodeLayer) {
     currentChild = createDummyEdge(currentChild);
     dummyNodes.add(currentChild);
   }
   node.addChild(currentChild);
   currentChild.addParent(node);
   return dummyNodes;
 }
 @Override
 public ISimpleNode[] removeLongEdges(IRegularNode[] acyclicGraph) {
   List<ISimpleNode> hierarchicalGraph = new ArrayList<>();
   Collections.addAll(hierarchicalGraph, acyclicGraph);
   for (IRegularNode node : acyclicGraph) {
     if (node.getLowerToChildren()) {
       int minimumChildLayer = Integer.MAX_VALUE;
       for (ISimpleNode child : node.getChildren()) {
         minimumChildLayer = Math.min(child.getLayer(), minimumChildLayer);
       }
       if (minimumChildLayer > node.getLayer()) {
         node.setLayer(minimumChildLayer - 1);
       }
     }
     for (ISimpleNode child : node.getChildren()) {
       if (isLongEdge(node, child)) {
         List<ISimpleNode> insertedNodes = insertDummyNodes(node, child);
         hierarchicalGraph.addAll(insertedNodes);
       }
     }
   }
   return hierarchicalGraph.toArray(new ISimpleNode[hierarchicalGraph.size()]);
 }
 private int getChildDistance(IRegularNode node, ISimpleNode child) {
   return child.getLayer() - node.getLayer();
 }
 private DummyNode createDummyEdge(ISimpleNode child) {
   DummyNode dummyNode = new DummyNode(child, child.getLayer() - 1);
   child.addParent(dummyNode);
   return dummyNode;
 }