private static void removeDuplicateAtomContainers(final IChemModel chemModel) {
		// we remove molecules which are in AtomContainerSet as well as in a
		// reaction
		final IReactionSet reactionSet = chemModel.getReactionSet();
		final IAtomContainerSet moleculeSet = chemModel.getMoleculeSet();
		if (reactionSet != null && moleculeSet != null) {
			final List<IAtomContainer> aclist = ReactionSetManipulator
					.getAllAtomContainers(reactionSet);
			for (int i = moleculeSet.getAtomContainerCount() - 1; i >= 0; i--) {
				for (int k = 0; k < aclist.size(); k++) {
					final String label = moleculeSet.getAtomContainer(i)
							.getID();
					if (aclist.get(k).getID().equals(label)) {
						chemModel.getMoleculeSet().removeAtomContainer(i);
						break;
					}
				}
			}
		}
	}
  /**
   * Initiate process. It is needed to call the addExplicitHydrogensToSatisfyValency from the class
   * tools.HydrogenAdder.
   *
   * @exception CDKException Description of the Exception
   * @param reactants reactants of the reaction.
   * @param agents agents of the reaction (Must be in this case null).
   */
  @TestMethod("testInitiate_IAtomContainerSet_IAtomContainerSet")
  public IReactionSet initiate(IAtomContainerSet reactants, IAtomContainerSet agents)
      throws CDKException {

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

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

    IReactionSet setOfReactions =
        DefaultChemObjectBuilder.getInstance().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 = reactants.getAtomContainer(0).atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (atomi.getFlag(CDKConstants.REACTIVE_CENTER)
          && reactant.getConnectedSingleElectronsCount(atomi) == 1) {

        Iterator<IBond> bondis = reactant.getConnectedBondsList(atomi).iterator();

        while (bondis.hasNext()) {
          IBond bondi = bondis.next();

          if (bondi.getFlag(CDKConstants.REACTIVE_CENTER)
              && bondi.getOrder() == IBond.Order.SINGLE) {

            IAtom atomj = bondi.getConnectedAtom(atomi);
            if (atomi.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.DOUBLE) {

                  IAtom atomk = bondj.getConnectedAtom(atomj);
                  if (atomk.getFlag(CDKConstants.REACTIVE_CENTER)
                      && (atomk.getFormalCharge() == CDKConstants.UNSET
                              ? 0
                              : atomk.getFormalCharge())
                          == 0
                      && reactant.getConnectedSingleElectronsCount(atomk) == 0) {

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

                    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);
                  }
                }
              }
            }
          }
        }
      }
    }
    return setOfReactions;
  }
	private static void removeEmptyAtomContainers(final IChemModel chemModel) {
		final IAtomContainerSet moleculeSet = chemModel.getMoleculeSet();
		if (moleculeSet != null && moleculeSet.getAtomContainerCount() == 0) {
			chemModel.setMoleculeSet(null);
		}
	}
  /**
   * Initiates the process for the given mechanism. The atoms to apply are mapped between reactants
   * and products.
   *
   * @param atomContainerSet
   * @param atomList The list of atoms taking part in the mechanism. Only allowed two atoms. The
   *     first atom is the atom which contains the ISingleElectron and the second third is the atom
   *     which will be removed the first atom
   * @param bondList The list of bonds taking part in the mechanism. Only allowed one bond. It is
   *     the bond which is moved
   * @return The Reaction mechanism
   */
  @TestMethod(value = "testInitiate_IAtomContainerSet_ArrayList_ArrayList")
  public IReaction initiate(
      IAtomContainerSet atomContainerSet, ArrayList<IAtom> atomList, ArrayList<IBond> bondList)
      throws CDKException {
    CDKAtomTypeMatcher atMatcher = CDKAtomTypeMatcher.getInstance(atomContainerSet.getBuilder());
    if (atomContainerSet.getAtomContainerCount() != 1) {
      throw new CDKException("RadicalSiteIonizationMechanism only expects one IMolecule");
    }
    if (atomList.size() != 3) {
      throw new CDKException("RadicalSiteIonizationMechanism expects three atoms in the ArrayList");
    }
    if (bondList.size() != 2) {
      throw new CDKException(
          "RadicalSiteIonizationMechanism only expect one bond in the ArrayList");
    }
    IAtomContainer molecule = atomContainerSet.getAtomContainer(0);
    IAtomContainer reactantCloned;
    try {
      reactantCloned = (IAtomContainer) molecule.clone();
    } catch (CloneNotSupportedException e) {
      throw new CDKException("Could not clone IMolecule!", e);
    }
    IAtom atom1 = atomList.get(0); // Atom containing the ISingleElectron
    IAtom atom1C = reactantCloned.getAtom(molecule.getAtomNumber(atom1));
    IAtom atom2 = atomList.get(1); // Atom
    IAtom atom2C = reactantCloned.getAtom(molecule.getAtomNumber(atom2));
    IAtom atom3 = atomList.get(2); // Atom to be saved
    IAtom atom3C = reactantCloned.getAtom(molecule.getAtomNumber(atom3));
    IBond bond1 = bondList.get(0); // Bond to increase the order
    int posBond1 = molecule.getBondNumber(bond1);
    IBond bond2 = bondList.get(1); // Bond to remove
    int posBond2 = molecule.getBondNumber(bond2);

    BondManipulator.increaseBondOrder(reactantCloned.getBond(posBond1));
    reactantCloned.removeBond(reactantCloned.getBond(posBond2));

    List<ISingleElectron> selectron = reactantCloned.getConnectedSingleElectronsList(atom1C);
    reactantCloned.removeSingleElectron(selectron.get(selectron.size() - 1));
    atom1C.setHybridization(null);
    AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(reactantCloned);
    IAtomType type = atMatcher.findMatchingAtomType(reactantCloned, atom1C);
    if (type == null) return null;

    atom2C.setHybridization(null);
    AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(reactantCloned);
    type = atMatcher.findMatchingAtomType(reactantCloned, atom2C);
    if (type == null) return null;

    reactantCloned.addSingleElectron(new SingleElectron(atom3C));
    atom3C.setHybridization(null);
    AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(reactantCloned);
    type = atMatcher.findMatchingAtomType(reactantCloned, atom3C);
    if (type == null) return null;

    IReaction reaction = DefaultChemObjectBuilder.getInstance().newInstance(IReaction.class);
    reaction.addReactant(molecule);

    /* mapping */
    for (IAtom atom : molecule.atoms()) {
      IMapping mapping =
          DefaultChemObjectBuilder.getInstance()
              .newInstance(
                  IMapping.class, atom, reactantCloned.getAtom(molecule.getAtomNumber(atom)));
      reaction.addMapping(mapping);
    }

    IAtomContainerSet moleculeSetP = ConnectivityChecker.partitionIntoMolecules(reactantCloned);
    for (int z = 0; z < moleculeSetP.getAtomContainerCount(); z++)
      reaction.addProduct((IAtomContainer) moleculeSetP.getAtomContainer(z));

    return reaction;
  }
  /**
   * Search if the setOfAtomContainer contains the atomContainer
   *
   * @param set ISetOfAtomContainer object where to search
   * @param atomContainer IAtomContainer to search
   * @return True, if the atomContainer is contained
   */
  private boolean existAC(IAtomContainerSet set, IAtomContainer atomContainer) {

    IAtomContainer acClone = null;
    try {
      acClone = (IMolecule) atomContainer.clone();
      if (!lookingSymmetry) {
        /*remove all aromatic flags*/
        for (IAtom atom : acClone.atoms()) atom.setFlag(CDKConstants.ISAROMATIC, false);
        for (IBond bond : acClone.bonds()) bond.setFlag(CDKConstants.ISAROMATIC, false);
      }
    } catch (CloneNotSupportedException e1) {
      e1.printStackTrace();
    }

    for (int i = 0; i < acClone.getAtomCount(); i++)
      //			if(acClone.getAtom(i).getID() == null)
      acClone.getAtom(i).setID("" + acClone.getAtomNumber(acClone.getAtom(i)));

    if (lookingSymmetry) {
      try {
        CDKHueckelAromaticityDetector.detectAromaticity(acClone);
      } catch (CDKException e) {
        e.printStackTrace();
      }
    } else {
      if (!lookingSymmetry) {
        /*remove all aromatic flags*/
        for (IAtom atom : acClone.atoms()) atom.setFlag(CDKConstants.ISAROMATIC, false);
        for (IBond bond : acClone.bonds()) bond.setFlag(CDKConstants.ISAROMATIC, false);
      }
    }
    for (int i = 0; i < set.getAtomContainerCount(); i++) {
      IAtomContainer ss = set.getAtomContainer(i);
      for (int j = 0; j < ss.getAtomCount(); j++)
        //				if(ss.getAtom(j).getID() == null)
        ss.getAtom(j).setID("" + ss.getAtomNumber(ss.getAtom(j)));

      try {

        if (!lookingSymmetry) {
          QueryAtomContainer qAC =
              QueryAtomContainerCreator.createSymbolChargeIDQueryContainer(acClone);
          if (UniversalIsomorphismTester.isIsomorph(ss, qAC)) {
            QueryAtomContainer qAC2 =
                QueryAtomContainerCreator.createSymbolAndBondOrderQueryContainer(acClone);
            if (UniversalIsomorphismTester.isIsomorph(ss, qAC2)) return true;
          }
        } else {
          QueryAtomContainer qAC =
              QueryAtomContainerCreator.createSymbolAndChargeQueryContainer(acClone);
          CDKHueckelAromaticityDetector.detectAromaticity(ss);
          if (UniversalIsomorphismTester.isIsomorph(ss, qAC)) return true;
        }

      } catch (CDKException e1) {
        System.err.println(e1);
        logger.error(e1.getMessage());
        logger.debug(e1);
      }
    }
    return false;
  }