class FixBondOrdersTool {

    public IAtomContainer kekuliseAromaticRings(IAtomContainer molecule) throws CDKException {
        IAtomContainer mNew = null;
        try {
            mNew = (IAtomContainer) molecule.clone();
        } catch (Exception e) {
            throw new CDKException("Failed to clone source molecule");
        }

        IRingSet ringSet;

        try {
            ringSet = removeExtraRings(mNew);
        } catch (CDKException x) {
            throw x;
        } catch (Exception x) {
            throw new CDKException("failure in SSSRFinder.findAllRings", x);
        }

        if (ringSet == null) {
            throw new CDKException("failure in SSSRFinder.findAllRings");
        }

        //We need to establish which rings share bonds and set up sets of such interdependant rings
        List<Integer[]> rBondsArray = null;
        List<List<Integer>> ringGroups = null;

        //Start by getting a list (same dimensions and ordering as ringset) of all the ring bond numbers in the reduced ring set
        rBondsArray = getRingSystem(mNew, ringSet);
        //Now find out which share a bond and assign them accordingly to groups
        ringGroups = assignRingGroups(rBondsArray);

        //Loop through each group of rings checking all choices of double bond combis and seeing if you can get a
        //proper molecule.
        for (int i = 0; i < ringGroups.size(); i++) {

            //Set all ring bonds with single order to allow Matrix solving to work
            setAllRingBondsSingleOrder(ringGroups.get(i), ringSet);

            //Set up  lists of atoms, bonds and atom pairs for this ringGroup
            List<Integer> atomNos = null;
            atomNos = getAtomNosForRingGroup(mNew, ringGroups.get(i), ringSet);

            List<Integer> bondNos = null;
            bondNos = getBondNosForRingGroup(mNew, ringGroups.get(i), ringSet);

            //Array of same dimensions as bondNos (cols in Matrix)
            List<Integer[]> atomNoPairs = null;
            atomNoPairs = getAtomNoPairsForRingGroup(mNew, bondNos);

            //Set up ajacency Matrix
            Matrix M = new Matrix(atomNos.size(), bondNos.size());
            for (int x = 0; x < M.getRows(); x++) {
                for (int y = 0; y < M.getCols(); y++) {
                    if (Objects.equals(atomNos.get(x), atomNoPairs.get(y)[0])) {
                        M.set(x, y, 1);
                    } else {
                        if (Objects.equals(atomNos.get(x), atomNoPairs.get(y)[1])) {
                            M.set(x, y, 1);
                        } else {
                            M.set(x, y, 0);
                        }
                    }
                }
            }

            //Array of same dimensions as atomNos (rows in Matrix)
            List<Integer> freeValencies = null;
            freeValencies = getFreeValenciesForRingGroup(mNew, atomNos, M, ringSet);

            //Array of "answers"
            List<Integer> bondOrders = new ArrayList<Integer>();
            for (int j = 0; j < bondNos.size(); j++) {
                bondOrders.add(0);
            }

            if (solveMatrix(M, atomNos, bondNos, freeValencies, atomNoPairs, bondOrders)) {
                for (int j = 0; j < bondOrders.size(); j++) {
                    mNew.getBond(bondNos.get(j)).setOrder(
                            bondOrders.get(j) == 1 ? IBond.Order.SINGLE : IBond.Order.DOUBLE);
                }
            } else {
                //                TODO Put any failure code here
            }
        }
        return mNew;
    }

    public  FixBondOrdersTool();

}