/**
   * Initiate process. It is needed to call the addExplicitHydrogensToSatisfyValency from the class
   * tools.HydrogenAdder.
   *
   * @param reactants reactants of the reaction
   * @param agents agents of the reaction (Must be in this case null)
   * @exception CDKException Description of the Exception
   */
  @TestMethod("testInitiate_IMoleculeSet_IMoleculeSet")
  public IReactionSet initiate(IMoleculeSet reactants, IMoleculeSet agents) throws CDKException {

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

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

    IReactionSet setOfReactions =
        DefaultChemObjectBuilder.getInstance().newInstance(IReactionSet.class);
    IMolecule reactant = reactants.getMolecule(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<IBond> bondis = reactant.bonds().iterator();
    while (bondis.hasNext()) {
      IBond bondi = bondis.next();
      IAtom atom1 = bondi.getAtom(0);
      IAtom atom2 = bondi.getAtom(1);
      if (bondi.getFlag(CDKConstants.REACTIVE_CENTER)
          && bondi.getOrder() != IBond.Order.SINGLE
          && atom1.getFlag(CDKConstants.REACTIVE_CENTER)
          && atom2.getFlag(CDKConstants.REACTIVE_CENTER)
          && (atom1.getFormalCharge() == CDKConstants.UNSET ? 0 : atom1.getFormalCharge()) == 0
          && (atom2.getFormalCharge() == CDKConstants.UNSET ? 0 : atom2.getFormalCharge()) == 0
          && reactant.getConnectedSingleElectronsCount(atom1) == 0
          && reactant.getConnectedSingleElectronsCount(atom2) == 0) {

        /**/
        for (int j = 0; j < 2; j++) {

          ArrayList<IAtom> atomList = new ArrayList<IAtom>();
          if (j == 0) {
            atomList.add(atom1);
            atomList.add(atom2);
          } else {
            atomList.add(atom2);
            atomList.add(atom1);
          }
          ArrayList<IBond> bondList = new ArrayList<IBond>();
          bondList.add(bondi);

          IMoleculeSet moleculeSet = reactant.getBuilder().newInstance(IMoleculeSet.class);
          moleculeSet.addMolecule(reactant);
          IReaction reaction = mechanism.initiate(moleculeSet, atomList, bondList);
          if (reaction == null) continue;
          else setOfReactions.addReaction(reaction);
        }
      }
    }
    return setOfReactions;
  }
 /**
  * set the active center for this molecule. The active center will be those which correspond with
  * A-B. If the bond is simple, it will be broken forming two fragments
  *
  * <pre>
  * A: Atom
  * #/=/-: bond
  * B: Atom
  *  </pre>
  *
  * @param reactant The molecule to set the activity
  * @throws CDKException
  */
 private void setActiveCenters(IMolecule reactant) throws CDKException {
   Iterator<IBond> bonds = reactant.bonds().iterator();
   while (bonds.hasNext()) {
     IBond bond = bonds.next();
     IAtom atom1 = bond.getAtom(0);
     IAtom atom2 = bond.getAtom(1);
     if (bond.getOrder() != IBond.Order.SINGLE
         && (atom1.getFormalCharge() == CDKConstants.UNSET ? 0 : atom1.getFormalCharge()) == 0
         && (atom2.getFormalCharge() == CDKConstants.UNSET ? 0 : atom2.getFormalCharge()) == 0
         && reactant.getConnectedSingleElectronsCount(atom1) == 0
         && reactant.getConnectedSingleElectronsCount(atom2) == 0) {
       atom1.setFlag(CDKConstants.REACTIVE_CENTER, true);
       atom2.setFlag(CDKConstants.REACTIVE_CENTER, true);
       bond.setFlag(CDKConstants.REACTIVE_CENTER, true);
     }
   }
 }
  /**
   * set the active center for this molecule. The active center will be those which correspond with
   * A-B-[C*].
   *
   * <pre>
   * A: Atom
   * -: bond
   * B: Atom
   * -: bond
   * C: Atom with single electron
   *  </pre>
   *
   * @param reactant The molecule to set the activity
   * @throws CDKException
   */
  private void setActiveCenters(IMolecule reactant) throws CDKException {

    Iterator<IAtom> atoms = reactant.atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (reactant.getConnectedSingleElectronsCount(atomi) == 1 && atomi.getFormalCharge() == 1) {

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

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

          if (bondi.getOrder() == IBond.Order.SINGLE) {

            IAtom atomj = bondi.getConnectedAtom(atomi);
            if (atomj.getFormalCharge() == 0) {

              Iterator<IBond> bondjs = reactant.getConnectedBondsList(atomj).iterator();
              while (bondjs.hasNext()) {
                IBond bondj = bondjs.next();

                if (bondj.equals(bondi)) continue;

                if (bondj.getOrder() == IBond.Order.SINGLE) {

                  IAtom atomk = bondj.getConnectedAtom(atomj);
                  if (atomk.getSymbol().equals("C") && atomk.getFormalCharge() == 0) {
                    atomi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    atomk.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondi.setFlag(CDKConstants.REACTIVE_CENTER, true);
                    bondj.setFlag(CDKConstants.REACTIVE_CENTER, true);
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  /**
   * Initiate process.
   *
   * @param reactants reactants of the reaction.
   * @param agents agents of the reaction (Must be in this case null).
   * @exception CDKException Description of the Exception
   */
  @TestMethod("testInitiate_IMoleculeSet_IMoleculeSet")
  public IReactionSet initiate(IMoleculeSet reactants, IMoleculeSet agents) throws CDKException {
    logger.debug("initiate reaction: RadicalChargeSiteInitiationReaction");

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

    IReactionSet setOfReactions = DefaultChemObjectBuilder.getInstance().newReactionSet();
    IMolecule reactant = reactants.getMolecule(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.getMolecule(0).atoms().iterator();
    while (atoms.hasNext()) {
      IAtom atomi = atoms.next();
      if (atomi.getFlag(CDKConstants.REACTIVE_CENTER)
          && reactant.getConnectedSingleElectronsCount(atomi) == 1
          && atomi.getFormalCharge() == 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 (atomj.getFlag(CDKConstants.REACTIVE_CENTER) && atomj.getFormalCharge() == 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.getConnectedAtom(atomj);
                  if (atomk.getFlag(CDKConstants.REACTIVE_CENTER)
                      && atomk.getSymbol().equals("C")
                      && atomk.getFormalCharge() == 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);

                    IMoleculeSet moleculeSet = reactant.getBuilder().newMoleculeSet();
                    moleculeSet.addMolecule(reactant);
                    IReaction reaction = mechanism.initiate(moleculeSet, atomList, bondList);
                    if (reaction == null) continue;
                    else setOfReactions.addReaction(reaction);
                  }
                }
              }
            }
          }
        }
      }
    }
    return setOfReactions;
  }