class TautomerizationReaction extends ReactionEngine implements IReactionProcess {

    @Override
    public IReactionSet initiate(IAtomContainerSet reactants, IAtomContainerSet agents) throws CDKException {

        logger.debug("initiate reaction: TautomerizationReaction");

        if (reactants.getAtomContainerCount() != 1) {
            throw new CDKException("TautomerizationReaction only expects one reactant");
        }
        if (agents != null) {
            throw new CDKException("TautomerizationReaction don't expects agents");
        }

        IReactionSet setOfReactions = reactants.getBuilder().newInstance(IReactionSet.class);
        IAtomContainer reactant = reactants.getAtomContainer(0);

        /*
         * if the parameter hasActiveCenter is not fixed yet, set the active
         * centers
         */
        IParameterReact ipr = super.getParameterClass(SetReactionCenter.class);
        if (ipr != null && !ipr.isSetParameter()) setActiveCenters(reactant);

        Iterator<IAtom> atoms = reactant.atoms().iterator();
        while (atoms.hasNext()) {
            IAtom atomi = atoms.next(); // Atom pos 1
            if (atomi.getFlag(CDKConstants.REACTIVE_CENTER)
                    && (atomi.getFormalCharge() == CDKConstants.UNSET ? 0 : atomi.getFormalCharge()) == 0
                    && reactant.getConnectedSingleElectronsCount(atomi) == 0) {
                Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator();
                while (bondis.hasNext()) {
                    IBond bondi = bondis.next();
                    if (bondi.getFlag(CDKConstants.REACTIVE_CENTER) && bondi.getOrder() == IBond.Order.DOUBLE) {
                        IAtom atomj = bondi.getOther(atomi); // Atom pos 2
                        if (atomj.getFlag(CDKConstants.REACTIVE_CENTER)
                                && (atomj.getFormalCharge() == CDKConstants.UNSET ? 0 : atomj.getFormalCharge()) == 0
                                && reactant.getConnectedSingleElectronsCount(atomj) == 0) {
                            Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator();
                            while (bondjs.hasNext()) {
                                IBond bondj = bondjs.next();
                                if (bondj.equals(bondi)) continue;
                                if (bondj.getFlag(CDKConstants.REACTIVE_CENTER)
                                        && bondj.getOrder() == IBond.Order.SINGLE) {
                                    IAtom atomk = bondj.getOther(atomj); // Atom pos 3
                                    if (atomk.getFlag(CDKConstants.REACTIVE_CENTER)
                                            && (atomk.getFormalCharge() == CDKConstants.UNSET ? 0 : atomk
                                                    .getFormalCharge()) == 0
                                            && reactant.getConnectedSingleElectronsCount(atomk) == 0) {
                                        Iterator<IBond> bondks = reactant.getConnectedBondsList(atomk).iterator();
                                        while (bondks.hasNext()) {
                                            IBond bondk = bondks.next();
                                            if (bondk.equals(bondj)) continue;
                                            if (bondk.getFlag(CDKConstants.REACTIVE_CENTER)
                                                    && bondk.getOrder() == IBond.Order.SINGLE) {
                                                IAtom atoml = bondk.getOther(atomk); // Atom pos 4
                                                if (atoml.getFlag(CDKConstants.REACTIVE_CENTER)
                                                        && atoml.getSymbol().equals("H")) {

                                                    ArrayList<IAtom> atomList = new ArrayList<IAtom>();
                                                    atomList.add(atomi);
                                                    atomList.add(atomj);
                                                    atomList.add(atomk);
                                                    atomList.add(atoml);
                                                    ArrayList<IBond> bondList = new ArrayList<IBond>();
                                                    bondList.add(bondi);
                                                    bondList.add(bondj);
                                                    bondList.add(bondk);

                                                    IAtomContainerSet moleculeSet = reactant.getBuilder().newInstance(
                                                            IAtomContainerSet.class);
                                                    moleculeSet.addAtomContainer(reactant);
                                                    IReaction reaction = mechanism.initiate(moleculeSet, atomList,
                                                            bondList);
                                                    if (reaction == null)
                                                        continue;
                                                    else
                                                        setOfReactions.addReaction(reaction);

                                                    break; // because of the others atoms are hydrogen too.
                                                }
                                            }

                                        }
                                    }
                                }
                            }
                        }
                    }

                }

            }
        }

        return setOfReactions;
    }

    public  TautomerizationReaction();

}