/** Converts a Molecule Element from a CDK Molecule object */
  public MoleculeType convert(IMolecule molecule) throws MSMLConversionException {
    try {
      MoleculeType molMoleculeElement = ObjectFactorySingelton.getFactory().createMoleculeType();
      setMetaData(molMoleculeElement, molecule);
      // molMoleculeElement.setMoleculeClass(MoleculeClassType.HETERO);//?
      // Add Atom block:
      Iterable<IAtom> atomBlock = molecule.atoms();
      AtomArrayType atomArrayElement = convertAtoms(atomBlock, molMoleculeElement.getId());

      // Save hashes of atoms to map the atom back to the atom ID
      ArrayList<String> hashes = generateHashCodes(atomBlock);
      molMoleculeElement.setAtomArray(atomArrayElement);

      // Add bond block
      Iterable<IBond> bondBlock = molecule.bonds();
      BondArrayType bondArrayElement = convertBonds(bondBlock, molMoleculeElement.getId(), hashes);
      molMoleculeElement.setBondArray(bondArrayElement);

      // Add properties block
      for (Entry<Object, Object> prop : molecule.getProperties().entrySet()) {
        if (_excludedProperties.contains(prop.getKey())) continue;
        CustomProperty cmlProp = ObjectFactorySingelton.getFactory().createCustomProperty();
        cmlProp.setKey((String) prop.getKey());
        cmlProp.setValue((String) prop.getValue());
        molMoleculeElement.getCustomProperty().add(cmlProp);
      }

      return molMoleculeElement;
    } catch (Exception e) {
      String msg = "Conversion of MDL molecule structure failed! " + e.getMessage();
      LOGGER.error(msg, e);
      throw new MSMLConversionException(msg, e);
    }
  }
  /**
   * 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);
     }
   }
 }