/// <summary>  Retrieves the set of all rings and performs an aromaticity detection based
 /// on Hueckels 4n + 2 rule. An AllRingsFinder with customized timeout may be
 /// assigned to this method.
 /// </summary>
 /// <param name="removeAromatictyFlags"> When true, we leaves ChemObjects that 
 /// are already marked as aromatic as they are
 /// </param>
 /// <param name="atomContainer">         AtomContainer to be searched for
 /// </param>
 /// <param name="arf">                   AllRingsFinder to be employed for the
 /// ringsearch. Use this to customize the 
 /// AllRingsFinder timeout feature
 /// rings
 /// </param>
 /// <returns>			True, if molecule has aromatic features                               	 
 /// </returns>
 /// <exception cref="CDKException"> 	Thrown in case of errors or an 
 /// AllRingsFinder timeout
 /// </exception>
 public static bool detectAromaticity(IAtomContainer atomContainer, bool removeAromatictyFlags, AllRingsFinder arf)
 {
     //logger.debug("Entered Aromaticity Detection");
     //logger.debug("Starting AllRingsFinder");
     long before = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
     if (arf == null)
     {
         arf = new AllRingsFinder();
         arf.setTimeout(timeout);
     }
     ringSet = arf.findAllRings(atomContainer);
     long after = (System.DateTime.Now.Ticks - 621355968000000000) / 10000;
     //logger.debug("time for finding all rings: " + (after - before) + " milliseconds");
     //logger.debug("Finished AllRingsFinder");
     if (ringSet.AtomContainerCount > 0)
     {
         return detectAromaticity(atomContainer, ringSet, removeAromatictyFlags);
     }
     return false;
 }
        /// <summary>  Generate canonical SMILES from the <code>molecule</code>. This method
        /// canonicaly lables the molecule but dose not perform any checks on the
        /// chemical validity of the molecule. Does not care about multiple molecules.
        /// IMPORTANT: A precomputed Set of All Rings (SAR) can be passed to this 
        /// SmilesGenerator in order to avoid recomputing it. Use setRings() to 
        /// assign the SAR.
        /// 
        /// </summary>
        /// <param name="molecule">                The molecule to evaluate
        /// </param>
        /// <param name="chiral">                  true=SMILES will be chiral, false=SMILES
        /// will not be chiral.
        /// </param>
        /// <param name="doubleBondConfiguration"> Description of Parameter
        /// </param>
        /// <returns>                          Description of the Returned Value
        /// </returns>
        /// <exception cref="CDKException">        At least one atom has no Point2D;
        /// coordinates are needed for creating the chiral smiles. This excpetion
        /// can only be thrown if chiral smiles is created, ignore it if you want a
        /// non-chiral smiles (createSMILES(AtomContainer) does not throw an
        /// exception).
        /// </exception>
        /// <seealso cref="org.openscience.cdk.graph.invariant.CanonicalLabeler.canonLabel(IAtomContainer)">
        /// </seealso>
        //UPGRADE_NOTE: Synchronized keyword was removed from method 'createSMILESWithoutCheckForMultipleMolecules'. Lock expression was added. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1027'"
        public virtual System.String createSMILESWithoutCheckForMultipleMolecules(IMolecule molecule, bool chiral, bool[] doubleBondConfiguration)
        {
            lock (this)
            {
                if (molecule.AtomCount == 0)
                {
                    return "";
                }
                canLabler.canonLabel(molecule);
                brokenBonds.Clear();
                ringMarker = 0;
                IAtom[] all = molecule.Atoms;
                IAtom start = null;
                for (int i = 0; i < all.Length; i++)
                {
                    IAtom atom = all[i];
                    if (chiral && atom.getPoint2d() == null)
                    {
                        throw new CDKException("Atom number " + i + " has no 2D coordinates, but 2D coordinates are needed for creating chiral smiles");
                    }
                    //System.out.println("Setting all VISITED flags to false");
                    atom.setFlag(CDKConstants.VISITED, false);
                    if ((long)((System.Int64)atom.getProperty("CanonicalLable")) == 1)
                    {
                        start = atom;
                    }
                }

                //detect aromaticity
                if (rings == null)
                {
                    if (ringFinder == null)
                    {
                        ringFinder = new AllRingsFinder();
                    }
                    rings = ringFinder.findAllRings(molecule);
                }
                HueckelAromaticityDetector.detectAromaticity(molecule, rings, false);
                if (chiral && rings.AtomContainerCount > 0)
                {
                    System.Collections.ArrayList v = RingPartitioner.partitionRings(rings);
                    //System.out.println("RingSystems: " + v.size());
                    for (int i = 0; i < v.Count; i++)
                    {
                        int counter = 0;
                        IAtomContainer allrings = RingSetManipulator.getAllInOneContainer((IRingSet)v[i]);
                        for (int k = 0; k < allrings.AtomCount; k++)
                        {
                            if (!BondTools.isStereo(molecule, allrings.getAtomAt(k)) && hasWedges(molecule, allrings.getAtomAt(k)) != null)
                            {
                                IBond bond = molecule.getBond(allrings.getAtomAt(k), hasWedges(molecule, allrings.getAtomAt(k)));
                                if (bond.Stereo == CDKConstants.STEREO_BOND_UP)
                                {
                                    allrings.getAtomAt(k).setProperty(RING_CONFIG, UP);
                                }
                                else
                                {
                                    allrings.getAtomAt(k).setProperty(RING_CONFIG, DOWN);
                                }
                                counter++;
                            }
                        }
                        if (counter == 1)
                        {
                            for (int k = 0; k < allrings.AtomCount; k++)
                            {
                                allrings.getAtomAt(k).setProperty(RING_CONFIG, UP);
                            }
                        }
                    }
                }

                System.Text.StringBuilder l = new System.Text.StringBuilder();
                createSMILES(start, l, molecule, chiral, doubleBondConfiguration);
                rings = null;
                return l.ToString();
            }
        }