class RemoveUpDownBonds extends AbstractFunction<Graph,Graph> {

    public Graph apply(final Graph g)
            throws InvalidSmilesException {

        Graph h = new Graph(g.order());

        // copy atom/topology information this is unchanged
        for (int u = 0; u < g.order(); u++) {
            h.addAtom(g.atom(u));
            h.addTopology(g.topologyOf(u));
        }

        int[] ordering = new DepthFirstOrder(g).visited;

        Map<Edge, Edge> replacements = new HashMap<Edge, Edge>();
        Set<Integer> dbCentres = new TreeSet<Integer>();

        // change edges (only changed added to replacement)
        for (int u = 0; u < g.order(); u++) {
            for (final Edge e : g.edges(u)) {
                if (e.other(u) > u && e.bond() == Bond.DOUBLE) {
                    removeRedundant(g, e, ordering, replacements);
                    dbCentres.add(u);
                    dbCentres.add(e.other(u));
                }
            }
        }

        // ensure we haven't accidentally removed one between two
        for (Edge e : new HashSet<Edge>(replacements.keySet())) {
            if (dbCentres.contains(e.either())
                    && dbCentres.contains(e.other(e.either()))) {
                replacements.remove(e);
            }
        }

        // append the edges, replacing any which need to be changed
        for (int u = 0; u < g.order(); u++) {
            for (Edge e : g.edges(u)) {
                if (e.other(u) > u) {
                    Edge replacement = replacements.get(e);
                    if (replacement != null)
                        e = replacement;
                    h.addEdge(e);
                }
            }
        }

        return h;
    }

}