CalculateReciprocatedEdgeRatio
        (
            IGraph oGraph,
            Int32 iVertexPairsWithBothDirectedEdges
        )
        {
            Debug.Assert(oGraph != null);
            Debug.Assert(oGraph.Directedness == GraphDirectedness.Directed);
            Debug.Assert(iVertexPairsWithBothDirectedEdges >= 0);
            
            Int32 iTotalEdgesAfterMergingDupcliatesNoSelfLoops =
                new DuplicateEdgeDetector(oGraph)
                .TotalEdgesAfterMergingDuplicatesNoSelfLoops;

            if (iTotalEdgesAfterMergingDupcliatesNoSelfLoops == 0)
            {
                return (null);
            }

            return ((Double)iVertexPairsWithBothDirectedEdges * 2.0 /
                (Double)iTotalEdgesAfterMergingDupcliatesNoSelfLoops);
        }
        TryCalculateGraphMetrics
        (
            IGraph graph,
            BackgroundWorker backgroundWorker,
            out OverallMetrics graphMetrics
        )
        {
            Debug.Assert(graph != null);


            graphMetrics = null;

            if (!ReportProgressAndCheckCancellationPending(
                1, 3, backgroundWorker))
            {
                return (false);
            }

            DuplicateEdgeDetector oDuplicateEdgeDetector =
                new DuplicateEdgeDetector(graph);

            Int32 iVertices = graph.Vertices.Count;
            Int32 iEdges = graph.Edges.Count;
            Int32 iSelfLoops = CountSelfLoops(graph);

            Int32 iConnectedComponents, iSingleVertexConnectedComponents,
                iMaximumConnectedComponentVertices,
                iMaximumConnectedComponentEdges;

            CalculateConnectedComponentMetrics(graph, out iConnectedComponents,
                out iSingleVertexConnectedComponents,
                out iMaximumConnectedComponentVertices,
                out iMaximumConnectedComponentEdges);

            Nullable<Int32> iMaximumGeodesicDistance;
            Nullable<Double> dAverageGeodesicDistance;
            Nullable<Double> dModularity;

            if (!ReportProgressAndCheckCancellationPending(
                2, 3, backgroundWorker))
            {
                return (false);
            }

           // CalculateSnapOverallMetrics(graph, out iMaximumGeodesicDistance, out dAverageGeodesicDistance, out dModularity);

            Nullable<Double> dReciprocatedVertexPairRatio, dReciprocatedEdgeRatio;

            if (!(new OverallReciprocationCalculator())
                .TryCalculateGraphMetrics(graph, backgroundWorker,
                    out dReciprocatedVertexPairRatio, out dReciprocatedEdgeRatio))
            {
                return (false);
            }

            OverallMetrics oOverallMetrics = new OverallMetrics(
                graph.Directedness,
                oDuplicateEdgeDetector.UniqueEdges,
                oDuplicateEdgeDetector.EdgesWithDuplicates,
                iSelfLoops,
                iVertices,

                CalculateGraphDensity(graph, iVertices,
                    oDuplicateEdgeDetector.
                        TotalEdgesAfterMergingDuplicatesNoSelfLoops),

                0,                            //dModularity
                iConnectedComponents,
                iSingleVertexConnectedComponents,
                iMaximumConnectedComponentVertices,
                iMaximumConnectedComponentEdges,
                0,               //iMaximumGeodesicDistance
                0,               //dAverageGeodesicDistance
                dReciprocatedVertexPairRatio,
                dReciprocatedEdgeRatio
                );

            graphMetrics = oOverallMetrics;

            return (true);
        }