/// <summary>
        /// Constructs both a forward and a backward mapping between reduced vertex indices and original vertex indices.
        /// </summary>
        /// <param name="reindexationMapping">the mapping from reduced vertex indices back to original vertex indices</param>
        /// <param name="reductionMapping">the mapping from original vertex indices to reduced vertex indices</param>
        private void BuildReindexationMappings(out ReindexationMapping reindexationMapping, out Dictionary <int, int> reductionMapping)
        {
            reindexationMapping = new ReindexationMapping(vertexCount);

            reductionMapping = new Dictionary <int, int>();
            int counter = 0;
            int vertex  = -1;

            while ((vertex = notRemovedVertices.NextElement(vertex)) != -1)
            {
                reductionMapping.Add(vertex, counter);
                reindexationMapping.Add(vertex);
                counter++;
            }
        }
        /// <summary>
        /// separates the graph at a given safe separator into subgraphs.
        /// If a tree decomposition for one subgraph has already been calculated, the index of that subgraph is also given out
        /// </summary>
        /// <param name="separator">the safe separator</param>
        /// <param name="reconstructionIndexationMappings">the corresponding mapping for reindexing the vertices in the subgraphs back to their old indices within this graph</param>
        /// <param name="alreadyCalculatedComponent">Optionally, a component whose subgraph has an already calculated PTD.
        ///                                         (This happens when a safe separator is found during the "HasTreewidth" calculation.)</param>
        /// <param name="alreadyCalculatedComponentIndex">-1, if no alreadyCalculatedComponent is passed, else the index in the list of subgraphs of the subgraph corresponding to that component</param>
        /// <returns>a list of the subgraphs</returns>
        public List <Graph> Separate(BitSet separator, out List <ReindexationMapping> reconstructionIndexationMappings, out int alreadyCalculatedComponentIndex, BitSet alreadyCalculatedComponent = null)
        {
            alreadyCalculatedComponentIndex = -1;
            List <Graph> subGraphs         = new List <Graph>();
            List <int>   separatorVertices = separator.Elements();

            reconstructionIndexationMappings = new List <ReindexationMapping>();

            // for each component
            foreach ((BitSet component, BitSet _) in ComponentsAndNeighbors(separator))
            {
                if (alreadyCalculatedComponent != null && component.Equals(alreadyCalculatedComponent))
                {
                    alreadyCalculatedComponentIndex = subGraphs.Count;
                }
                List <int> vertices = component.Elements();
                component.UnionWith(separator);

                // map vertices from this graph to the new subgraph and vice versa
                Dictionary <int, int> reductionMapping = new Dictionary <int, int>(vertexCount + separatorVertices.Count);
                ReindexationMapping   reconstructionIndexationMapping = new ReindexationMapping(vertexCount);
                reconstructionIndexationMappings.Add(reconstructionIndexationMapping);
                for (int i = 0; i < vertices.Count; i++)
                {
                    reductionMapping[vertices[i]] = i;
                    reconstructionIndexationMapping.Add(vertices[i]);
                }

                // don't forget the separator
                for (int i = 0; i < separatorVertices.Count; i++)
                {
                    int u = separatorVertices[i];
                    reductionMapping[u] = vertices.Count + i;
                    reconstructionIndexationMapping.Add(u);
                }

                // create new adjacency list
                List <int>[] subAdjacencyList = new List <int> [vertices.Count + separatorVertices.Count];
                for (int i = 0; i < vertices.Count; i++)
                {
                    int oldVertex = vertices[i];
                    int newVertex = reductionMapping[oldVertex];
                    subAdjacencyList[newVertex] = new List <int>(adjacencyList[oldVertex].Count);
                    foreach (int oldNeighbor in adjacencyList[oldVertex])
                    {
                        int newNeighbor = reductionMapping[oldNeighbor];
                        subAdjacencyList[newVertex].Add(newNeighbor);
                    }
                }

                // also for the separator
                for (int i = 0; i < separatorVertices.Count; i++)
                {
                    int u = separatorVertices[i];
                    subAdjacencyList[vertices.Count + i] = new List <int>();
                    foreach (int oldNeighbor in adjacencyList[u])
                    {
                        if (component[oldNeighbor])
                        {
                            int newNeighbor = reductionMapping[oldNeighbor];
                            subAdjacencyList[vertices.Count + i].Add(newNeighbor);
                        }
                    }
                }

                Graph subGraph = new Graph(subAdjacencyList);
                subGraphs.Add(subGraph);
            }

            // print some stats
            if (verbose)
            {
                Console.WriteLine("splitted graph {0} with {1} vertices and {2} edges into {3} smaller graphs:", graphID, vertexCount, edgeCount, subGraphs.Count);
                foreach (Graph subGraph in subGraphs)
                {
                    Console.WriteLine("        graph {0} with {1} vertices and {2} edges", subGraph.graphID, subGraph.vertexCount, subGraph.edgeCount);
                }
            }

            return(subGraphs);
        }