    protected MutableLayoutRow oneStep(@NotNull MutableLayoutRow row) {
        int newRowIndex = row.getGraphNodeRow().getRowIndex() + 1;
        if (newRowIndex == graph.getNodeRows().size()) {
            throw new NoSuchElementException();
        }
        List<GraphElement> layoutRow = row.getModifiableOrderedGraphElements();
        for (ListIterator<GraphElement> iterator = layoutRow.listIterator(); iterator.hasNext(); ) {
            GraphElement element = iterator.next();
            Node node = element.getNode();
            if (node != null) {
                List<Edge> edges = node.getDownEdges();
                if (edges.size() == 0) {
                    iterator.remove();
                } else {
                    iterator.remove();
                    for (Edge edge : orderAddEdges(edges)) {
                        Node downNode = edge.getDownNode();
                        if (downNode.getRowIndex() == newRowIndex) {
                            if (downNode.getBranch() == edge.getBranch()) {
                                iterator.add(downNode);
                            }
                        } else {
                            iterator.add(edge);
                        }
                    }
                }
            } else {
                Edge edge = element.getEdge();
                if (edge == null) {
                    throw new IllegalStateException("unexpected element class");
                }
                if (edge.getDownNode().getRowIndex() == newRowIndex) {
                    if (edge.getBranch() == edge.getDownNode().getBranch()) {
                        iterator.set(edge.getDownNode());
                    } else {
                        iterator.remove();
                    }
                }
            }
        }
        NodeRow nextGraphRow = graph.getNodeRows().get(newRowIndex);
        for (Node node : nextGraphRow.getNodes()) {
            if (node.getUpEdges().isEmpty()) {
                layoutRow.add(node);
            }
        }
        row.setNodeRow(nextGraphRow);
        return row;
    }

    protected MutableLayoutRow oneStep(@NotNull MutableLayoutRow row) {
        int newRowIndex = row.getGraphNodeRow().getRowIndex() + 1;
        if (newRowIndex == graph.getNodeRows().size()) {
            throw new NoSuchElementException();
        }
        List<GraphElement> layoutRow = row.getModifiableOrderedGraphElements();
        Set<Node> addedNodeInNextRow = new HashSet<Node>();
        for (ListIterator<GraphElement> iterator = layoutRow.listIterator(); iterator.hasNext(); ) {
            GraphElement element = iterator.next();
            Node node = element.getNode();
            if (node != null) {
                List<Edge> edges = node.getDownEdges();
                if (edges.size() == 0) {
                    iterator.remove();
                } else {
                    iterator.remove();
                    for (Edge edge : orderAddEdges(edges)) {
                        Node downNode = edge.getDownNode();
                        if (downNode.getRowIndex() == newRowIndex) {
                            if (!addedNodeInNextRow.contains(downNode)) {
                                iterator.add(downNode);
                                addedNodeInNextRow.add(downNode);
                            }
                        } else {
                            iterator.add(edge);
                        }
                    }
                }
            } else {
                Edge edge = element.getEdge();
                if (edge == null) {
                    throw new IllegalStateException("unexpected element class");
                }
                if (edge.getDownNode().getRowIndex() == newRowIndex) {
                    if (!addedNodeInNextRow.contains(edge.getDownNode())) {
                        iterator.set(edge.getDownNode());
                        addedNodeInNextRow.add(edge.getDownNode());
                    } else {
                        iterator.remove();
                    }
                }
            }
        }
        NodeRow nextGraphRow = graph.getNodeRows().get(newRowIndex);
        for (Node node : nextGraphRow.getNodes()) {
            if (node.getUpEdges().isEmpty()) {
                layoutRow.add(node);
            }
        }
        row.setNodeRow(nextGraphRow);
        return row;
    }
