class PiBondingMovementReaction extends ReactionEngine implements IReactionProcess {

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

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

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

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

        AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(reactant);
        /*
         * 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);

        //		if((Boolean)paramsMap.get("lookingSymmetry")){
        //			Aromaticity.cdkLegacy().apply(reactant);
        //		}

        AllRingsFinder arf = new AllRingsFinder();
        IRingSet ringSet = arf.findAllRings(reactant);
        for (int ir = 0; ir < ringSet.getAtomContainerCount(); ir++) {
            IRing ring = (IRing) ringSet.getAtomContainer(ir);

            //only rings with even number of atoms
            int nrAtoms = ring.getAtomCount();
            if (nrAtoms % 2 == 0) {
                int nrSingleBonds = 0;
                for (IBond iBond : ring.bonds()) {
                    if (iBond.getOrder() == IBond.Order.SINGLE) nrSingleBonds++;
                }
                //if exactly half (nrAtoms/2==nrSingleBonds)
                if (nrSingleBonds != 0 && nrAtoms / 2 == nrSingleBonds) {
                    Iterator<IBond> bondfs = ring.bonds().iterator();
                    boolean ringCompletActive = false;
                    while (bondfs.hasNext()) {
                        if (bondfs.next().getFlag(CDKConstants.REACTIVE_CENTER))
                            ringCompletActive = true;
                        else {
                            ringCompletActive = false;
                            break;
                        }
                    }
                    if (!ringCompletActive) continue;

                    IReaction reaction = reactants.getBuilder().newInstance(IReaction.class);
                    reaction.addReactant(reactant);

                    IAtomContainer reactantCloned;
                    try {
                        reactantCloned = reactant.clone();
                    } catch (CloneNotSupportedException e) {
                        throw new CDKException("Could not clone IAtomContainer!", e);
                    }

                    for (IBond bondi : ring.bonds()) {
                        int bondiP = reactant.indexOf(bondi);
                        if (bondi.getOrder() == IBond.Order.SINGLE)
                            BondManipulator.increaseBondOrder(reactantCloned.getBond(bondiP));
                        else
                            BondManipulator.decreaseBondOrder(reactantCloned.getBond(bondiP));

                    }

                    reaction.addProduct(reactantCloned);
                    setOfReactions.addReaction(reaction);
                }

            }
        }

        return setOfReactions;
    }

    public  PiBondingMovementReaction();

}