Represents a graph.
A graph has a collection of Vertices and a collection of Edges that connect the Vertices. The property specifies the type of edges that can be added to the graph.
Inheritance: GraphVertexEdgeBase, IGraph
 SetUp()
 {
     m_oFanMotifCalculator = new FanMotifDetector();
     m_oGraph = new Graph();
     m_oVertices = m_oGraph.Vertices;
     m_oEdges = m_oGraph.Edges;
 }
 SetUp()
 {
     m_oConnectedComponentCalculator = new ConnectedComponentCalculator();
     m_oGraph = new Graph();
     m_oVertices = m_oGraph.Vertices;
     m_oEdges = m_oGraph.Edges;
 }
    SetUp()
    {
        m_oGraph = new Graph();

        Rectangle oRectangle = new Rectangle(21, 34, 56, 78);

        m_oLayoutContext = new LayoutContext(oRectangle);

        m_oLayOutGraphAsyncArguments =
            new LayOutGraphAsyncArguments(m_oGraph, m_oLayoutContext);
    }
 public Graph convert_to_graph(DataTable node_table, DataTable edge_table)
 {
     Graph oGraph = new Graph(GraphDirectedness.Directed);
     IVertexCollection oVertices = oGraph.Vertices;
     IEdgeCollection oEdges = oGraph.Edges;
     
     add_nodes(node_table, oVertices);
     add_edges(edge_table.Rows, oVertices, oEdges);
     
     return oGraph;
 }
    SetUp()
    {
        IVertex oVertex1 = new Vertex();
        IVertex oVertex2 = new Vertex();

        IGraph oGraph = new Graph();

        oGraph.Vertices.Add(oVertex1);
        oGraph.Vertices.Add(oVertex2);

        m_oEdge = new Edge(oVertex1, oVertex2, true);

        m_oEdgeEventArgs = new EdgeEventArgs(m_oEdge);
    }
        CreateGraph
        (
            Boolean bIsDirected
        )
        {
            m_oClusteringCoefficientCalculator =
                new ClusteringCoefficientCalculator();

            m_oGraph = new Graph(bIsDirected ?
                GraphDirectedness.Directed : GraphDirectedness.Undirected);

            m_oVertices = m_oGraph.Vertices;
            m_oEdges = m_oGraph.Edges;
        }
    SetUp()
    {
        m_oGraph = new Graph();

        Debug.Assert(m_oGraph.Vertices is VertexCollection);

        m_oVertexCollection = m_oGraph.Vertices;

        ( (VertexCollection)m_oVertexCollection ).VertexAdded +=
            new VertexEventHandler(this.VertexCollection_VertexAdded);

        ( (VertexCollection)m_oVertexCollection ).VertexRemoved +=
            new VertexEventHandler(this.VertexCollection_VertexRemoved);

        m_bVertexAdded = false;
        m_oAddedVertex = null;

        m_bVertexRemoved = false;
        m_oRemovedVertex = null;
    }
    TestEdgeToVertices()
    {
        // Valid vertices.

        MockVertex oVertex1 = new MockVertex();
        MockVertex oVertex2 = new MockVertex();

        IGraph oGraph = new Graph();

        oVertex1.ParentGraph = oGraph;
        oVertex2.ParentGraph = oGraph;

        IEdge oEdge = new MockEdge(oVertex1, oVertex2, false, false, 2);

        IVertex oVertexA, oVertexB;

        EdgeUtil.EdgeToVertices(oEdge, ClassName, MethodOrPropertyName,
            out oVertexA, out oVertexB);

        Assert.AreEqual(oVertex1, oVertexA);
        Assert.AreEqual(oVertex2, oVertexB);
    }
    SetUp()
    {
        m_oDirectedGraph = new Graph(GraphDirectedness.Directed);
        IVertexCollection oDirectedVertices = m_oDirectedGraph.Vertices;

        m_oDirectedVertexA = oDirectedVertices.Add();
        m_oDirectedVertexA.Name = "A";

        m_oDirectedVertexB = oDirectedVertices.Add();
        m_oDirectedVertexB.Name = "B";

        m_oDirectedVertexC = oDirectedVertices.Add();
        m_oDirectedVertexC.Name = "C";

        m_oDirectedVertexD = oDirectedVertices.Add();
        m_oDirectedVertexD.Name = "D";

        m_oDirectedVertexWithNullName = oDirectedVertices.Add();
        m_oDirectedVertexWithNullName.Name = null;


        m_oUndirectedGraph = new Graph(GraphDirectedness.Undirected);
        IVertexCollection oUndirectedVertices = m_oUndirectedGraph.Vertices;

        m_oUndirectedVertexA = oUndirectedVertices.Add();
        m_oUndirectedVertexA.Name = "A";

        m_oUndirectedVertexB = oUndirectedVertices.Add();
        m_oUndirectedVertexB.Name = "B";

        m_oUndirectedVertexC = oUndirectedVertices.Add();
        m_oUndirectedVertexC.Name = "C";

        m_oUndirectedVertexD = oUndirectedVertices.Add();
        m_oUndirectedVertexD.Name = "D";

        m_oUndirectedVertexWithNullName = oUndirectedVertices.Add();
        m_oUndirectedVertexWithNullName.Name = null;
    }
    TestTransformLayoutBad3()
    {
        // null newLayoutContext.

        try
        {
            IGraph oGraph = new Graph();

            LayoutContext oLayoutContext = new LayoutContext(Rectangle.Empty);

            m_oFruchtermanReingoldLayout.TransformLayout(
                oGraph, oLayoutContext, null);
        }
        catch (ArgumentNullException oArgumentNullException)
        {
            Assert.AreEqual(

                "Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "TransformLayout: newLayoutContext argument can't be"
                + " null.\r\n"
                + "Parameter name: newLayoutContext"
                ,
                oArgumentNullException.Message
                );

            throw oArgumentNullException;
        }
    }
    TestLayOut()
    {
        const Int32 Vertices = 100;

        IGraph oGraph = new Graph();

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, Vertices);

        TestGraphUtil.MakeGraphComplete(oGraph, aoVertices, false);

        // Initialize the vertex locations to impossible values.

        const Int32 ImpossibleCoordinate = Int32.MinValue;

        foreach (IVertex oVertex in aoVertices)
        {
            oVertex.Location = new Point(
                ImpossibleCoordinate, ImpossibleCoordinate);
        }

        const Int32 Width = 1000;
        const Int32 Height = 600;

        Rectangle oRectangle = new Rectangle(0, 0, Width, Height);

        LayoutContext oLayoutContext = new LayoutContext(oRectangle);

        m_oFruchtermanReingoldLayout.LayOutGraph(oGraph, oLayoutContext);

        foreach (IVertex oVertex in aoVertices)
        {
            PointF oLocation = oVertex.Location;

            Single fX = oLocation.X;

            Assert.AreNotEqual(fX, ImpossibleCoordinate);
            Assert.IsTrue(fX >= 0);
            Assert.IsTrue(fX <= Width);

            Single fY = oLocation.Y;

            Assert.AreNotEqual(fY, ImpossibleCoordinate);
            Assert.IsTrue(fY >= 0);
            Assert.IsTrue(fY <= Height);
        }
    }
    TestTransformLayoutBad3()
    {
        // null newLayoutContext.

        try
        {
            IGraph oGraph = new Graph();

            LayoutContext oLayoutContext = new LayoutContext(Rectangle.Empty);

            m_oFruchtermanReingoldLayout.TransformLayout(
                oGraph, oLayoutContext, null);
        }
        catch (ArgumentNullException oArgumentNullException)
        {
            String enMsg="Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "TransformLayout: newLayoutContext argument can't be"
                + " null.\r\n"
                + "Parameter name: newLayoutContext";
            String chMsg="Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "TransformLayout: newLayoutContext argument can't be"
                + " null.\r\n"
                + "參數名稱: newLayoutContext";
            Assert.IsTrue((enMsg == oArgumentNullException.Message ||
                chMsg == oArgumentNullException.Message) ? true : false
                );

            throw oArgumentNullException;
        }
    }
    TestSort4()
    {
        // Descending sort on Double.

        ByMetadataVertexSorter<Double> oByMetadataVertexSorter =
            new ByMetadataVertexSorter<Double>(SortKey);

        const Int32 Vertices = 100;

        IGraph oGraph = new Graph();

        IVertex [] aoUnsortedVertices =
            TestGraphUtil.AddVertices(oGraph, Vertices);

        IVertexCollection oVertexCollection = oGraph.Vertices;

        Int32 i;

        for (i = 0; i < Vertices; i++)
        {
            aoUnsortedVertices[i].SetValue( SortKey, (Double)(Vertices - i) );
        }

        oByMetadataVertexSorter.SortAscending = false;

        for (i = 0; i < Vertices; i++)
        {
            aoUnsortedVertices[i].SetValue( SortKey, (Double)(Vertices - i) );
        }

        ICollection<IVertex> oSortedVertices =
            oByMetadataVertexSorter.Sort(oVertexCollection);

        Assert.AreEqual(Vertices, oSortedVertices.Count);

        i = 0;

        foreach (IVertex oSortedVertex in oSortedVertices)
        {
            Assert.AreEqual(

                (Double)(Vertices - i),

                (Double)oSortedVertex.GetRequiredValue(
                    SortKey, typeof(Double) )
                );

            i++;
        }
    }
    TestLoopVertices
    (
        Boolean bTestPredecessorVertices,
        Boolean bTestSuccessorVertices,
        Boolean bTestAdjacentVertices
    )
    {
        IGraph oGraph = new Graph();

        // Add one vertex.

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 1);

        IVertex oVertex = aoVertices[0];

        IEdgeCollection oEdgeCollection = oGraph.Edges;

        // Add multiple self-loops, both undirected and directed.

        IEdge oUndirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, false);
        IEdge oUndirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, false);

        IEdge oDirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, true);
        IEdge oDirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, true);

        ICollection<IVertex> oVerticesA = null;

        if (bTestPredecessorVertices)
        {
            oVerticesA = oVertex.PredecessorVertices;
        }
        else if (bTestSuccessorVertices)
        {
            oVerticesA = oVertex.SuccessorVertices;
        }
        else if (bTestAdjacentVertices)
        {
            oVerticesA = oVertex.AdjacentVertices;
        }
        else
        {
            Debug.Assert(false);
        }

        Assert.AreEqual(1, oVerticesA.Count);

        HashSet<IVertex> oVerticesAHashSet = new HashSet<IVertex>(oVerticesA);

        Assert.IsTrue( oVerticesAHashSet.Contains(oVertex) );
    }
    TestLoopEdges
    (
        Boolean bTestIncomingEdges,
        Boolean bTestOutgoingEdges,
        Boolean bTestIncidentEdges
    )
    {
        IGraph oGraph = new Graph();

        // Add one vertex.

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 1);

        IVertex oVertex = aoVertices[0];

        IEdgeCollection oEdgeCollection = oGraph.Edges;

        // Add multiple self-loops, both undirected and directed.

        IEdge oUndirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, false);
        IEdge oUndirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, false);

        IEdge oDirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, true);
        IEdge oDirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, true);

        ICollection<IEdge> oEdges = null;

        if (bTestIncomingEdges)
        {
            oEdges = oVertex.IncomingEdges;
        }
        else if (bTestOutgoingEdges)
        {
            oEdges = oVertex.OutgoingEdges;
        }
        else if (bTestIncidentEdges)
        {
            oEdges = oVertex.IncidentEdges;

            Assert.AreEqual(oEdges.Count, oVertex.Degree);
        }
        else
        {
            Debug.Assert(false);
        }

        Assert.AreEqual(4, oEdges.Count);

        HashSet<IEdge> oEdgesHashSet = new HashSet<IEdge>(oEdges);

        Assert.IsTrue( oEdgesHashSet.Contains(oUndirectedEdge1) );
        Assert.IsTrue( oEdgesHashSet.Contains(oUndirectedEdge2) );

        Assert.IsTrue( oEdgesHashSet.Contains(oDirectedEdge1) );
        Assert.IsTrue( oEdgesHashSet.Contains(oDirectedEdge2) );
    }
    ImportWorkbookIntoGraph
    (
        Worksheet oSourceWorksheet,
        Range oNonEmptySourceRange,
        Int32 iColumnNumberToUseForVertex1OneBased,
        Int32 iColumnNumberToUseForVertex2OneBased,
        ICollection<Int32> oEdgeColumnNumbersToImportOneBased,
        ICollection<Int32> oVertex1ColumnNumbersToImportOneBased,
        ICollection<Int32> oVertex2ColumnNumbersToImportOneBased,
        Boolean bSourceColumnsHaveHeaders
    )
    {
        Debug.Assert(oSourceWorksheet != null);
        Debug.Assert(oNonEmptySourceRange != null);
        Debug.Assert(iColumnNumberToUseForVertex1OneBased >= 1);
        Debug.Assert(iColumnNumberToUseForVertex2OneBased >= 1);
        Debug.Assert(oEdgeColumnNumbersToImportOneBased != null);
        Debug.Assert(oVertex1ColumnNumbersToImportOneBased != null);
        Debug.Assert(oVertex2ColumnNumbersToImportOneBased != null);
        AssertValid();

        String [] asWorkbookColumnNames = GetWorkbookColumnNames(
            oSourceWorksheet, oNonEmptySourceRange, bSourceColumnsHaveHeaders);

        Int32 iColumns = oNonEmptySourceRange.Columns.Count;

        Int32 iFirstNonEmptyColumnOneBased =
            oNonEmptySourceRange.Columns.Column;

        if (bSourceColumnsHaveHeaders)
        {
            // Skip the header row.

            if (oNonEmptySourceRange.Rows.Count < 2)
            {
                OnInvalidSourceWorkbook(
                    "If the columns in the other workbook have headers, then"
                    + " there must be at least two rows.",

                    oSourceWorksheet, 1, 1
                    );
            }

            ExcelUtil.OffsetRange(ref oNonEmptySourceRange, 1, 0);

            ExcelUtil.ResizeRange(ref oNonEmptySourceRange,
                oNonEmptySourceRange.Rows.Count - 1, iColumns);
        }

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);
        IVertexCollection oVertices = oGraph.Vertices;
        IEdgeCollection oEdges = oGraph.Edges;

        // The key is a vertex name and the value is the corresponding IVertex
        // object.

        Dictionary<String, IVertex> oVertexNameDictionary =
            new Dictionary<String, IVertex>();

        foreach ( Range oSubrange in
            ExcelRangeSplitter.SplitRange(oNonEmptySourceRange, 500) )
        {
            Object [,] oSubrangeValues = ExcelUtil.GetRangeValues(oSubrange);
            Int32 iSubrangeRows = oSubrangeValues.GetUpperBound(0);

            for (Int32 iRowOneBased = 1; iRowOneBased <= iSubrangeRows;
                iRowOneBased++)
            {
                String sVertex1Name, sVertex2Name;

                if (
                    !ExcelUtil.TryGetNonEmptyStringFromCell(oSubrangeValues,
                        iRowOneBased,
                        iColumnNumberToUseForVertex1OneBased -
                            iFirstNonEmptyColumnOneBased + 1,
                        out sVertex1Name)
                    ||
                    !ExcelUtil.TryGetNonEmptyStringFromCell(oSubrangeValues,
                        iRowOneBased,
                        iColumnNumberToUseForVertex2OneBased -
                            iFirstNonEmptyColumnOneBased + 1,
                        out sVertex2Name)
                    )
                {
                    continue;
                }

                IVertex oVertex1 = WorksheetReaderBase.VertexNameToVertex(
                    sVertex1Name, oVertices, oVertexNameDictionary);

                IVertex oVertex2 = WorksheetReaderBase.VertexNameToVertex(
                    sVertex2Name, oVertices, oVertexNameDictionary);

                IEdge oEdge = oEdges.Add(oVertex1, oVertex2);

                // Add the edge and vertex attributes.

                AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames,
                    oSubrangeValues, iRowOneBased,
                    iFirstNonEmptyColumnOneBased,
                    oEdgeColumnNumbersToImportOneBased, oEdge);

                AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames,
                    oSubrangeValues, iRowOneBased,
                    iFirstNonEmptyColumnOneBased,
                    oVertex1ColumnNumbersToImportOneBased, oVertex1);

                AddAttributeValuesToEdgeOrVertex(asWorkbookColumnNames,
                    oSubrangeValues, iRowOneBased,
                    iFirstNonEmptyColumnOneBased,
                    oVertex2ColumnNumbersToImportOneBased, oVertex2);
            }
        }

        // Store metadata on the graph indicating the sets of keys that may be
        // present on the graph's edges and vertices.

        oGraph.SetValue(ReservedMetadataKeys.AllEdgeMetadataKeys,

            GetColumnNamesToImport(oNonEmptySourceRange,
                asWorkbookColumnNames, oEdgeColumnNumbersToImportOneBased)
            );

        List<Int32> oVertexColumnNumbersToImportOneBased = new List<Int32>();

        oVertexColumnNumbersToImportOneBased.AddRange(
            oVertex1ColumnNumbersToImportOneBased);

        oVertexColumnNumbersToImportOneBased.AddRange(
            oVertex2ColumnNumbersToImportOneBased);

        oGraph.SetValue( ReservedMetadataKeys.AllVertexMetadataKeys,

            GetColumnNamesToImport(oNonEmptySourceRange, asWorkbookColumnNames,
                oVertexColumnNumbersToImportOneBased)
            );

        return (oGraph);
    }
    TestSort2()
    {
        // Descending sort on Int32.

        const Int32 Vertices = 100;

        IGraph oGraph = new Graph();

        IVertex [] aoUnsortedVertices =
            TestGraphUtil.AddVertices(oGraph, Vertices);

        IVertexCollection oVertexCollection = oGraph.Vertices;

        Int32 i;

        for (i = 0; i < Vertices; i++)
        {
            aoUnsortedVertices[i].SetValue(SortKey, Vertices - i);
        }

        m_oByMetadataVertexSorter.SortAscending = false;

        ICollection<IVertex> oSortedVertices =
            m_oByMetadataVertexSorter.Sort(oVertexCollection);

        Assert.AreEqual(Vertices, oSortedVertices.Count);

        i = 0;

        foreach (IVertex oSortedVertex in oSortedVertices)
        {
            Assert.AreEqual(
                Vertices - i,
                (Int32)oSortedVertex.GetRequiredValue( SortKey, typeof(Int32) )
                );

            i++;
        }
    }
    TestParentGraph()
    {
        // Add the vertex to a graph.

        IGraph oGraph = new Graph();

        oGraph.Vertices.Add(m_oVertex);

        Assert.AreEqual(oGraph, m_oVertex.ParentGraph);
    }
        CreateGraph
        (
            Boolean bIsDirected
        )
        {
            m_oPageRankCalculator =
                new PageRankCalculator();

            m_oGraph = new Graph(bIsDirected ?
                GraphDirectedness.Directed : GraphDirectedness.Undirected);

            m_oVertices = m_oGraph.Vertices;
            m_oEdges = m_oGraph.Edges;
        }
    TestParentGraph2()
    {
        // Create a graph, populate the graph with vertices and edges, remove
        // the vertex from the graph.

        const Int32 Vertices = 100;

        // Create a graph with each vertex connected to all others.

        IGraph oGraph = new Graph();

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, Vertices);

        TestGraphUtil.MakeGraphComplete(oGraph, aoVertices, false);

        // Pick one of the vertices to test.

        IVertex oVertex = aoVertices[0];

        Assert.AreEqual(oGraph, oVertex.ParentGraph);

        // Remove the vertex.

        oGraph.Vertices.Remove(oVertex);

        Assert.IsNull(oVertex.ParentGraph);
    }
    TestLayOutGraphBad2()
    {
        // null layoutContext.

        try
        {
            IGraph oGraph = new Graph();

            m_oFruchtermanReingoldLayout.LayOutGraph(oGraph, null);

        }
        catch (ArgumentNullException oArgumentNullException)
        {
            String enMsg = "Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "LayOutGraph: layoutContext argument can't be null.\r\n"
                + "Parameter name: layoutContext";
            String chMsg = "Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "LayOutGraph: layoutContext argument can't be null.\r\n"
                + "參數名稱: layoutContext";
            Assert.IsTrue((enMsg == oArgumentNullException.Message ||
                chMsg == oArgumentNullException.Message) ? true : false
                );

            throw oArgumentNullException;
        }
    }
    TestGetConnectingEdges2()
    {
        // Create a graph and populate it with multiple self-loops.

        IGraph oGraph = new Graph();

        // Add two vertices.

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 2);

        IVertex oVertex = aoVertices[0];

        IEdgeCollection oEdgeCollection = oGraph.Edges;

        // Add multiple self-loops, both undirected and directed.

        IEdge oUndirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, false);
        IEdge oUndirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, false);

        IEdge oDirectedEdge1 = oEdgeCollection.Add(oVertex, oVertex, true);
        IEdge oDirectedEdge2 = oEdgeCollection.Add(oVertex, oVertex, true);

        // Add a non-self-loop.

        IEdge oNonSelfLoopEdge = oEdgeCollection.Add(
            oVertex, aoVertices[1], false);

        // If GetConnectingEdges() is passed its own vertex, it should return
        // self-loops.

        ICollection<IEdge> oConnectingEdges =
            oVertex.GetConnectingEdges(oVertex);

        Assert.IsNotNull(oConnectingEdges);

        Assert.AreEqual(4, oConnectingEdges.Count);

        // If GetConnectingEdges() is not passed its own vertex, it should not
        // return self-loops.

        oConnectingEdges = oVertex.GetConnectingEdges( aoVertices[1] );

        Assert.IsNotNull(oConnectingEdges);

        Assert.AreEqual(1, oConnectingEdges.Count);

        Assert.AreEqual( oNonSelfLoopEdge, oConnectingEdges.First() );
    }
    CloneAndFilterGraph
    (
        IGraph oGraph
    )
    {
        Debug.Assert(oGraph != null);
        AssertValid();

        IGraph oGraphClone = new Graph(GraphDirectedness.Undirected);

        // The key is the IVertex in oGraph and the value is the corresponding
        // IVertex in oGraphClone.

        Dictionary<IVertex, IVertex> oVertexDictionary =
            new Dictionary<IVertex, IVertex>();

        IVertexCollection oVerticesClone = oGraphClone.Vertices;

        foreach (IVertex oVertex in oGraph.Vertices)
        {
            VertexDrawingHistory oVertexDrawingHistory;

            // (If the vertex has no VertexDrawingHistory, it means that it's
            // hidden and should be ignored.)

            if ( DrawerBase.TryGetVertexDrawingHistory(oVertex,
                out oVertexDrawingHistory) )
            {
                IVertex oVertexClone = oVertex.Clone(true, true);
                oVertexClone.Location = oVertex.Location;
                oVerticesClone.Add(oVertexClone);
                oVertexDictionary.Add(oVertex, oVertexClone);
            }
        }

        // This is used to eliminate overlapping edges, where edges are
        // considered overlapping if they connect the same vertex pairs.  The
        // directedness of the edges is not taken into account.
        //
        // For readability calculations, there should be only one edge
        // connecting a pair of vertexes.

        HashSet<Int64> oVertexIDPairs = new HashSet<Int64>();

        IEdgeCollection oEdgesClone = oGraphClone.Edges;

        foreach (IEdge oEdge in oGraph.Edges)
        {
            EdgeDrawingHistory oEdgeDrawingHistory;
            Int64 i64VertexIDPair = EdgeUtil.GetVertexIDPair(oEdge, false);

            if (
                !oEdge.IsSelfLoop
                &&
                DrawerBase.TryGetEdgeDrawingHistory(oEdge,
                    out oEdgeDrawingHistory)
                &&
                !oVertexIDPairs.Contains(i64VertexIDPair)
                )
            {
                oEdgesClone.Add( oEdge.Clone(true, true,
                    oVertexDictionary[ oEdge.Vertices[0] ],
                    oVertexDictionary[ oEdge.Vertices[1] ], false) );

                oVertexIDPairs.Add(i64VertexIDPair);
            }
        }

        return (oGraphClone);
    }
    TestGetConnectingEdgesBad()
    {
        // null otherVertex.

        try
        {
            IGraph oGraph = new Graph();

            IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 1);

            ICollection<IEdge> oConnectingEdges =
                aoVertices[0].GetConnectingEdges(null);
        }
        catch (ArgumentNullException oArgumentNullException)
        {
            Assert.AreEqual(

                "Smrf.NodeXL.Core."
                + "Vertex.GetConnectingEdges: otherVertex argument can't be"
                + " null.\r\n"
                + "Parameter name: otherVertex"
                ,
                oArgumentNullException.Message
                );

            throw oArgumentNullException;
        }
    }
    CreateGraph
    (
        Boolean bDirected
    )
    {
        m_oGraph = new Graph(bDirected ? GraphDirectedness.Directed :
            GraphDirectedness.Undirected);

        m_oVertices = m_oGraph.Vertices;
        m_oEdges = m_oGraph.Edges;
    }
    TestIsIncidentEdge()
    {
        IGraph oGraph = new Graph();

        IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 4);

        IVertex oVertex0 = aoVertices[0];
        IVertex oVertex1 = aoVertices[1];
        IVertex oVertex2 = aoVertices[2];
        IVertex oVertex3 = aoVertices[3];

        IEdgeCollection oEdges = oGraph.Edges;

        IEdge oUndirectedEdge = oEdges.Add(oVertex0, oVertex1, false);

        Assert.IsTrue( oVertex0.IsIncidentEdge(oUndirectedEdge) );
        Assert.IsTrue( oVertex0.IsOutgoingEdge(oUndirectedEdge) );
        Assert.IsTrue( oVertex0.IsIncomingEdge(oUndirectedEdge) );

        IEdge oIncomingEdge = oEdges.Add(oVertex2, oVertex0, true);

        Assert.IsTrue( oVertex0.IsIncidentEdge(oIncomingEdge) );
        Assert.IsFalse( oVertex0.IsOutgoingEdge(oIncomingEdge) );
        Assert.IsTrue( oVertex0.IsIncomingEdge(oIncomingEdge) );

        IEdge oOutgoingEdge = oEdges.Add(oVertex0, oVertex3, true);

        Assert.IsTrue( oVertex0.IsIncidentEdge(oOutgoingEdge) );
        Assert.IsTrue( oVertex0.IsOutgoingEdge(oOutgoingEdge) );
        Assert.IsFalse( oVertex0.IsIncomingEdge(oOutgoingEdge) );

        IEdge oUndirectedSelfLoop = oEdges.Add(oVertex0, oVertex0, false);

        Assert.IsTrue( oVertex0.IsIncidentEdge(oUndirectedSelfLoop) );
        Assert.IsTrue( oVertex0.IsOutgoingEdge(oUndirectedSelfLoop) );
        Assert.IsTrue( oVertex0.IsIncomingEdge(oUndirectedSelfLoop) );

        IEdge oDirectedSelfLoop = oEdges.Add(oVertex0, oVertex0, true);

        Assert.IsTrue( oVertex0.IsIncidentEdge(oDirectedSelfLoop) );
        Assert.IsTrue( oVertex0.IsOutgoingEdge(oDirectedSelfLoop) );
        Assert.IsTrue( oVertex0.IsIncomingEdge(oDirectedSelfLoop) );

        IEdge oDisconnectedEdge = oEdges.Add(oVertex2, oVertex3, false);

        Assert.IsFalse( oVertex0.IsIncidentEdge(oDisconnectedEdge) );
        Assert.IsFalse( oVertex0.IsOutgoingEdge(oDisconnectedEdge) );
        Assert.IsFalse( oVertex0.IsIncomingEdge(oDisconnectedEdge) );
    }
    TestLayOutGraphBad2()
    {
        // null layoutContext.

        try
        {
            IGraph oGraph = new Graph();

            m_oFruchtermanReingoldLayout.LayOutGraph(oGraph, null);

        }
        catch (ArgumentNullException oArgumentNullException)
        {
            Assert.AreEqual(

                "Smrf.NodeXL.Layouts.FruchtermanReingoldLayout."
                + "LayOutGraph: layoutContext argument can't be null.\r\n"
                + "Parameter name: layoutContext"
                ,
                oArgumentNullException.Message
                );

            throw oArgumentNullException;
        }
    }
    TestIsIncomingEdgeBad()
    {
        // null edge.

        try
        {
            IGraph oGraph = new Graph();

            IVertex [] aoVertices = TestGraphUtil.AddVertices(oGraph, 1);

            aoVertices[0].IsIncomingEdge(null);
        }
        catch (ArgumentNullException oArgumentNullException)
        {
            Assert.AreEqual(

                "Smrf.NodeXL.Core."
                + "Vertex.IsIncomingEdge: edge argument can't be null.\r\n"
                + "Parameter name: edge"
                ,
                oArgumentNullException.Message
                );

            throw oArgumentNullException;
        }
    }
        CreateGraph
        (
            Boolean bIsDirected
        )
        {
            m_oEdgeReciprocationCalculator = new EdgeReciprocationCalculator();

            m_oGraph = new Graph(bIsDirected ?
                GraphDirectedness.Directed : GraphDirectedness.Undirected);

            m_oVertices = m_oGraph.Vertices;
            m_oEdges = m_oGraph.Edges;
        }
    ImportMatrixWorkbook
    (
        Microsoft.Office.Interop.Excel.Application application,
        String sourceWorkbookName,
        Boolean sourceWorkbookHasVertexNames,
        GraphDirectedness sourceWorkbookDirectedness
    )
    {
        Debug.Assert(application != null);
        Debug.Assert( !String.IsNullOrEmpty(sourceWorkbookName) );
        AssertValid();

        // Get the active worksheet of the source workbook.

        Worksheet oSourceWorksheet = GetActiveSourceWorksheet(
            application, sourceWorkbookName);

        // Read or create the names of the vertices in the source workbook.

        String [] asVertexNames;
        Int32 iFirstEdgeWeightRowOneBased, iFirstEdgeWeightColumnOneBased;

        if (sourceWorkbookHasVertexNames)
        {
            asVertexNames = ReadVertexNames(oSourceWorksheet);
            iFirstEdgeWeightRowOneBased = iFirstEdgeWeightColumnOneBased = 2;
        }
        else
        {
            asVertexNames = CreateVertexNames(oSourceWorksheet);
            iFirstEdgeWeightRowOneBased = iFirstEdgeWeightColumnOneBased = 1;
        }

        Int32 iVertices = asVertexNames.Length;

        switch (sourceWorkbookDirectedness)
        {
            case GraphDirectedness.Directed:

                break;

            case GraphDirectedness.Undirected:

                CheckSymmetryOfUndirectedMatrix(oSourceWorksheet,
                    iFirstEdgeWeightRowOneBased,
                    iFirstEdgeWeightColumnOneBased, iVertices);

                break;

            default:

                Debug.Assert(false);
                break;
        }

        // Create a graph and populate it with the vertices.

        IGraph oGraph = new Graph(sourceWorkbookDirectedness);
        IVertexCollection oVertices = oGraph.Vertices;
        IVertex[] aoOrderedVertices = new IVertex[iVertices];

        for (Int32 i = 0; i < iVertices; i++)
        {
            IVertex oVertex = oVertices.Add();
            oVertex.Name = asVertexNames[i];
            aoOrderedVertices[i] = oVertex;
        }

        // Read the edges and import them into the graph.

        ReadEdges(oSourceWorksheet, iFirstEdgeWeightRowOneBased,
            iFirstEdgeWeightColumnOneBased, oGraph, aoOrderedVertices);

        return (oGraph);
    }