class RDBERule implements IRule {

    public List<Double> getRDBEValue(IMolecularFormula formula) {
        List<Double> RDBEList = new ArrayList<Double>();
        // The number of combinations with repetition
        // (v+n-1)!/[n!(v-1)!]
        int nE = 0; // number of elements to change
        List<Integer> nV = new ArrayList<Integer>(); // number of valence changing
        for (Iterator<IIsotope> it = formula.isotopes().iterator(); it.hasNext();) {
            IIsotope isotope = it.next();
            int[] valence = getOxidationState(formula.getBuilder().newInstance(IAtom.class, isotope.getSymbol()));
            if (valence.length != 1) {
                for (int i = 0; i < valence.length; i++) {
                    nV.add(valence[i]);
                }
                nE += MolecularFormulaManipulator.getElementCount(formula,
                        formula.getBuilder().newInstance(IElement.class, isotope.getSymbol()));
            }
        }

        double RDBE = 0;
        if (nE == 0) {
            for (Iterator<IIsotope> it = formula.isotopes().iterator(); it.hasNext();) {
                IIsotope isotope = it.next();
                int[] valence = getOxidationState(formula.getBuilder().newInstance(IAtom.class, isotope.getSymbol()));
                double value = (valence[0] - 2) * formula.getIsotopeCount(isotope) / 2.0;
                RDBE += value;
            }
            RDBE += 1;
            RDBEList.add(RDBE);
        } else {
            double RDBE_1 = 0;
            for (Iterator<IIsotope> it = formula.isotopes().iterator(); it.hasNext();) {
                IIsotope isotope = it.next();
                int[] valence = getOxidationState(formula.getBuilder().newInstance(IAtom.class, isotope.getSymbol()));
                double value = (valence[0] - 2) * formula.getIsotopeCount(isotope) * 0.5;
                RDBE_1 += value;
            }
            String[] valences = new String[nV.size()];
            for (int i = 0; i < valences.length; i++)
                valences[i] = Integer.toString(nV.get(i));

            Combinations c = new Combinations(valences, nE);
            while (c.hasMoreElements()) {
                double RDBE_int = 0.0;
                Object[] combo = (Object[]) c.nextElement();
                for (int i = 0; i < combo.length; i++) {
                    int value = (Integer.parseInt((String) combo[i]) - 2) / 2;
                    RDBE_int += value;
                }
                RDBE = 1 + RDBE_1 + RDBE_int;
                RDBEList.add(RDBE);
            }
        }
        return RDBEList;
    }

    public  RDBERule();

}