/// <summary>
        /// Creates a molecule graph for use with jgrapht.
        /// Bond orders are not respected.
        /// </summary>
        /// <param name="molecule">the specified molecule</param>
        /// <returns>a graph representing the molecule</returns>
	    static public SimpleGraph getMoleculeGraph(IAtomContainer molecule) {
		    SimpleGraph graph = new SimpleGraph();
		    for (int i=0; i<molecule.AtomCount; i++	) {
			    IAtom atom = molecule.Atoms[i];
			    graph.addVertex(atom);
		    }
    		
		    for (int i=0; i<molecule.getBondCount(); i++	) {
			    IBond bond = molecule.Bonds[i];
    			
			    /*
			    int order = (int) bond.getOrder();
			    for (int j=0; j<order; j++) {
				    graph.addEdge(bond.getAtoms()[0], bond.getAtoms()[1]);
			    }
			    */
			    graph.addEdge(bond.getAtoms()[0], bond.getAtoms()[1]);
		    }
		    return graph;
	    }
        public virtual System.Collections.IList equivalenceClasses()
        {
            int[] weight = weightVector();

            System.Object[] cyclesArray = (System.Object[])SupportClass.ICollectionSupport.ToArray(cycles_Renamed_Field);
            System.Array.Sort(cyclesArray, new AnonymousClassComparator(this));

            System.Collections.ICollection essentialCycles = this.essentialCycles();

            bool[][] u = new bool[cyclesArray.Length][];
            for (int i = 0; i < cyclesArray.Length; i++)
            {
                u[i] = new bool[edgeList.Count];
            }

            bool[][] a = getCycleEdgeIncidenceMatrix(cyclesArray);
            bool[][] ai = inverseBinaryMatrix(a, cyclesArray.Length);

            for (int i = 0; i < cyclesArray.Length; i++)
            {
                for (int j = 0; j < cyclesArray.Length; j++)
                {
                    u[i][j] = ai[j][i];
                }
            }

            UndirectedGraph h = new SimpleGraph();
            h.addAllVertices(cycles_Renamed_Field);

            ConnectivityInspector connectivityInspector = new ConnectivityInspector(h);

            int left = 0;
            for (int right = 0; right < weight.Length; right++)
            {
                if ((right < weight.Length - 1) && (weight[right + 1] == weight[right]))
                    continue;

                // cyclesArray[left] to cyclesArray[right] have same weight

                // First test (compute pre-classes):
                // Check if there is a cycle that can replace a[i] as well as a[j] in a basis
                // This is done by finding a cycle C with <C,u[i]>=1 and <C,u[j]>=1

                for (int i = left; i <= right; i++)
                {
                    if (SupportClass.ICollectionSupport.Contains(essentialCycles, (SimpleCycle)cyclesArray[i]))
                        continue;

                    for (int j = i + 1; j <= right; j++)
                    {
                        if (SupportClass.ICollectionSupport.Contains(essentialCycles, (SimpleCycle)cyclesArray[j]))
                            continue;

                        // check if cyclesArray[i] and cyclesArray[j] are already in the same class
                        if (connectivityInspector.pathExists(cyclesArray[i], cyclesArray[j]))
                            continue;

                        bool sameClass = false;

                        AuxiliaryGraph2 auxGraph = new AuxiliaryGraph2(this, graph, edgeList, u[i], u[j]);

                        //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
                        for (System.Collections.IEnumerator it = graph.vertexSet().GetEnumerator(); it.MoveNext(); )
                        {
                            //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
                            System.Object vertex = it.Current;

                            // check if the vertex is incident to an edge with u[edge] == 1
                            bool shouldSearchCycle = false;

                            System.Collections.ICollection incidentEdges = graph.edgesOf(vertex);

                            System.Collections.IEnumerator edgeIterator = incidentEdges.GetEnumerator();
                            //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
                            while (edgeIterator.MoveNext())
                            {
                                //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
                                Edge edge = (Edge)edgeIterator.Current;
                                int index = getEdgeIndex(edge);
                                if (u[i][index] || u[j][index])
                                {
                                    shouldSearchCycle = true;
                                    break;
                                }
                            }

                            if (shouldSearchCycle)
                            {

                                System.Object auxVertex00 = auxGraph.auxVertex00(vertex);
                                System.Object auxVertex11 = auxGraph.auxVertex11(vertex);

                                System.Collections.IList auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11);

                                double pathWeight = auxPath.Count;

                                if (pathWeight == weight[left])
                                {
                                    sameClass = true;
                                    break;
                                }
                            }
                        }

                        if (sameClass)
                        {
                            h.addEdge(cyclesArray[i], cyclesArray[j]);
                        }
                    }
                }

                // Second test (compute equivalence classes):
                // Check if there are two cycle Ci, Cj that can replace a[i], a[j]
                // and have a common cycle a[k] in their basis representation
                // This is done by finding a cycle a[k] with <u[k],u[i]>=1 and <u[k],u[j]>=1

                for (int i = left; i <= right; i++)
                {
                    if (SupportClass.ICollectionSupport.Contains(essentialCycles, (SimpleCycle)cyclesArray[i]))
                        continue;

                    for (int j = i + 1; j <= right; j++)
                    {
                        if (SupportClass.ICollectionSupport.Contains(essentialCycles, (SimpleCycle)cyclesArray[j]))
                            continue;

                        // check if cyclesArray[i] and cyclesArray[j] are already in the same class
                        if (connectivityInspector.pathExists(cyclesArray[i], cyclesArray[j]))
                            continue;

                        bool sameClass = false;

                        for (int k = 0; ((SimpleCycle)cyclesArray[k]).weight() < weight[left]; k++)
                        {

                            AuxiliaryGraph2 auxGraph = new AuxiliaryGraph2(this, graph, edgeList, u[i], u[k]);

                            bool shortestPathFound = false;
                            //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
                            for (System.Collections.IEnumerator it = graph.vertexSet().GetEnumerator(); it.MoveNext(); )
                            {
                                //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
                                System.Object vertex = it.Current;

                                System.Object auxVertex00 = auxGraph.auxVertex00(vertex);
                                System.Object auxVertex11 = auxGraph.auxVertex11(vertex);

                                System.Collections.IList auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11);

                                double pathWeight = auxPath.Count;

                                if (pathWeight == weight[left])
                                {
                                    shortestPathFound = true;
                                    break;
                                }
                            }

                            if (!shortestPathFound)
                                continue;

                            auxGraph = new AuxiliaryGraph2(this, graph, edgeList, u[j], u[k]);

                            //UPGRADE_TODO: Method 'java.util.Iterator.hasNext' was converted to 'System.Collections.IEnumerator.MoveNext' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratorhasNext'"
                            for (System.Collections.IEnumerator it = graph.vertexSet().GetEnumerator(); it.MoveNext(); )
                            {
                                //UPGRADE_TODO: Method 'java.util.Iterator.next' was converted to 'System.Collections.IEnumerator.Current' which has a different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1073_javautilIteratornext'"
                                System.Object vertex = it.Current;

                                System.Object auxVertex00 = auxGraph.auxVertex00(vertex);
                                System.Object auxVertex11 = auxGraph.auxVertex11(vertex);

                                System.Collections.IList auxPath = BFSShortestPath.findPathBetween(auxGraph, auxVertex00, auxVertex11);

                                double pathWeight = auxPath.Count;

                                if (pathWeight == weight[left])
                                {
                                    sameClass = true;
                                    break;
                                }
                            }

                            if (sameClass)
                                break;
                        }

                        if (sameClass)
                        {
                            h.addEdge(cyclesArray[i], cyclesArray[j]);
                        }
                    }
                }

                left = right + 1;
            }

            return connectivityInspector.connectedSets();
        }
		private System.Collections.IList lazyFindBiconnectedSets()
		{
			if (biconnectedSets_Renamed_Field == null)
			{
				biconnectedSets_Renamed_Field = new System.Collections.ArrayList();
				
                IList inspector = new ConnectivityInspector(graph).connectedSets();
                System.Collections.IEnumerator connectedSets = inspector.GetEnumerator();
				
				while (connectedSets.MoveNext())
				{
                    object obj = ((DictionaryEntry)connectedSets.Current).Value;
                    if (!(obj is CSGraphT.SupportClass.HashSetSupport))
                        continue;
					CSGraphT.SupportClass.SetSupport connectedSet = (CSGraphT.SupportClass.SetSupport)obj;
					if (connectedSet.Count == 1)
					{
						continue;
					}
					
					org._3pq.jgrapht.Graph subgraph = new Subgraph(graph, connectedSet, null);
					
					// do DFS
					
					// Stack for the DFS
					System.Collections.ArrayList vertexStack = new System.Collections.ArrayList();
					
					CSGraphT.SupportClass.SetSupport visitedVertices = new CSGraphT.SupportClass.HashSetSupport();
					IDictionary parent = new System.Collections.Hashtable();
					IList dfsVertices = new System.Collections.ArrayList();
					
					CSGraphT.SupportClass.SetSupport treeEdges = new CSGraphT.SupportClass.HashSetSupport();

                    System.Object currentVertex = subgraph.vertexSet()[0];//.ToArray()[0];

					vertexStack.Add(currentVertex);
					visitedVertices.Add(currentVertex);
					
					while (!(vertexStack.Count == 0))
					{
						currentVertex = SupportClass.StackSupport.Pop(vertexStack);
						
						System.Object parentVertex = parent[currentVertex];
						
						if (parentVertex != null)
						{
							Edge edge = subgraph.getEdge(parentVertex, currentVertex);
							
							// tree edge
							treeEdges.Add(edge);
						}
						
						visitedVertices.Add(currentVertex);
						
						dfsVertices.Add(currentVertex);
						
						System.Collections.IEnumerator edges = subgraph.edgesOf(currentVertex).GetEnumerator();
						while (edges.MoveNext())
						{
							// find a neighbour vertex of the current vertex 
							Edge edge = (Edge)edges.Current;
							
							if (!treeEdges.Contains(edge))
							{
								System.Object nextVertex = edge.oppositeVertex(currentVertex);
								
								if (!visitedVertices.Contains(nextVertex))
								{
									vertexStack.Add(nextVertex);
									
									parent[nextVertex] = currentVertex;
								}
								else
								{
									// non-tree edge
								}
							}
						}
					}
					
					// DFS is finished. Now create the auxiliary graph h
					// Add all the tree edges as vertices in h
					SimpleGraph h = new SimpleGraph();
					
					h.addAllVertices(treeEdges);
					
					visitedVertices.Clear();
					
					CSGraphT.SupportClass.SetSupport connected = new CSGraphT.SupportClass.HashSetSupport();
					
					for (System.Collections.IEnumerator it = dfsVertices.GetEnumerator(); it.MoveNext(); )
					{
						System.Object v = it.Current;
						
						visitedVertices.Add(v);
						
						// find all adjacent non-tree edges
						for (System.Collections.IEnumerator adjacentEdges = subgraph.edgesOf(v).GetEnumerator(); adjacentEdges.MoveNext();)
						{
							Edge l = (Edge)adjacentEdges.Current;
							if (!treeEdges.Contains(l))
							{
								h.addVertex(l);
								System.Object u = l.oppositeVertex(v);
								
								// we need to check if (u,v) is a back-edge
								if (!visitedVertices.Contains(u))
								{
									while (u != v)
									{
										System.Object pu = parent[u];
										Edge f = subgraph.getEdge(u, pu);
										
										h.addEdge(f, l);
										
										if (!connected.Contains(f))
										{
											connected.Add(f);
											u = pu;
										}
										else
										{
											u = v;
										}
									}
								}
							}
						}
					}
					
					ConnectivityInspector connectivityInspector = new ConnectivityInspector(h);
					
					biconnectedSets_Renamed_Field.Add(connectivityInspector.connectedSets());
				}
			}
			
			return biconnectedSets_Renamed_Field;
		}