/**
   * Creates all edges in the internal model
   *
   * @param layout reference to the layout algorithm
   * @param vertices the vertices whom are to have an internal representation created
   * @param internalVertices the blank internal vertices to have their information filled in using
   *     the real vertices
   */
  protected void createInternalCells(
      mxHierarchicalLayout layout, Object[] vertices, mxGraphHierarchyNode[] internalVertices) {
    mxGraph graph = layout.getGraph();

    // Create internal edges
    for (int i = 0; i < vertices.length; i++) {
      internalVertices[i] = new mxGraphHierarchyNode(vertices[i]);
      vertexMapper.put(vertices[i], internalVertices[i]);

      // If the layout is deterministic, order the cells
      Object[] conns = graph.getConnections(vertices[i], parent);
      List<Object> outgoingCells = Arrays.asList(graph.getOpposites(conns, vertices[i]));
      internalVertices[i].connectsAsSource =
          new LinkedHashSet<mxGraphHierarchyEdge>(outgoingCells.size());

      // Create internal edges, but don't do any rank assignment yet
      // First use the information from the greedy cycle remover to
      // invert the leftward edges internally
      Iterator<Object> iter = outgoingCells.iterator();

      while (iter.hasNext()) {
        // Don't add self-loops
        Object cell = iter.next();

        if (cell != vertices[i]
            && graph.getModel().isVertex(cell)
            && !layout.isVertexIgnored(cell)) {
          // Allow for parallel edges
          Object[] edges = graph.getEdgesBetween(vertices[i], cell, true);

          if (edges != null && edges.length > 0) {
            ArrayList<Object> listEdges = new ArrayList<Object>(edges.length);

            for (int j = 0; j < edges.length; j++) {
              listEdges.add(edges[j]);
            }

            mxGraphHierarchyEdge internalEdge = new mxGraphHierarchyEdge(listEdges);
            Iterator<Object> iter2 = listEdges.iterator();

            while (iter2.hasNext()) {
              Object edge = iter2.next();
              edgeMapper.put(edge, internalEdge);

              // Resets all point on the edge and disables the edge style
              // without deleting it from the cell style
              graph.resetEdge(edge);

              if (layout.isDisableEdgeStyle()) {
                layout.setEdgeStyleEnabled(edge, false);
                layout.setOrthogonalEdge(edge, true);
              }
            }

            internalEdge.source = internalVertices[i];
            internalVertices[i].connectsAsSource.add(internalEdge);
          }
        }
      }

      // Ensure temp variable is cleared from any previous use
      internalVertices[i].temp[0] = 0;
    }
  }