public static ColumnData asciiedges(List<Integer> seen, int rev, List<Integer> parents) {
        // """adds edge info to changelog DAG walk suitable for ascii()"""
        if (!seen.contains(rev)) {
            seen.add(rev);
        }

        int nodeidx = seen.indexOf(rev); // i.e. just looking up the index of the rev

        // seen maps revs -> ordinals

        List<Integer> known_parents = new ArrayList<Integer>();
        List<Integer> new_parents = new ArrayList<Integer>();

        for (int parent : parents) {
            if (seen.contains(parent)) {
                known_parents.add(parent);
            } else {
                new_parents.add(parent);
            }
        }

        int ncols = seen.size();
        seen.remove(nodeidx); // Correct? trying to get python slice assignement semantics
        seen.addAll(nodeidx, new_parents);

        List<AsciiEdge> edges = new ArrayList<AsciiEdge>();
        for (int parent : known_parents) {
            edges.add(new AsciiEdge(nodeidx, seen.indexOf(parent)));
        }

        if (new_parents.size() > 0) {
            edges.add(new AsciiEdge(nodeidx, nodeidx));
        }

        if (new_parents.size() > 1) {
            edges.add(new AsciiEdge(nodeidx, nodeidx + 1));
        }

        int nmorecols = seen.size() - ncols;
        String edgeDump = "";
        for (AsciiEdge edge : edges) {
            edgeDump += String.format("(%d, %d), ", edge.mStart, edge.mEnd);
        }
        return new ColumnData(nodeidx, edges, ncols, nmorecols);
    }