TestOnLayoutBegin6()
    {
        // Request that intergroup edges be combined, and there are some.

        const Double GroupRectanglePenWidth = 4.567;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Combine;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

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

        IEdgeCollection oEdges = oGraph.Edges;

        // Not intergroup.

        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false);

        // Intergroup, between groups 1 and 2.

        IEdge oEdge3 = oEdges.Add(aoVertices[0], aoVertices[2], false);
        IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[2], false);
        IEdge oEdge5 = oEdges.Add(aoVertices[1], aoVertices[3], false);

        // Intergroup, between groups 2 and 3.

        IEdge oEdge6 = oEdges.Add(aoVertices[2], aoVertices[4], false);
        IEdge oEdge7 = oEdges.Add(aoVertices[3], aoVertices[4], false);

        // Intergroup, between groups 1 and 3.

        IEdge oEdge8 = oEdges.Add(aoVertices[1], aoVertices[4], false);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupInfo oGroup3 = new GroupInfo();
        oGroup3.Vertices.AddLast( aoVertices[4] );
        oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2, oGroup3},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(3, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );
        Assert.AreEqual( oGroup3, oGroupInfo[2] );

        Assert.IsTrue( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsFalse( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge3.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge4.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge5.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge6.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge7.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge8.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( 3,
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count() );

        IntergroupEdgeInfo oCombinedIntergroupEdge;

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 0
                &&
                intergroupEdgeInfo.Group2Index == 1
                );

        Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(1, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(3, oCombinedIntergroupEdge.Edges);

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 0
                &&
                intergroupEdgeInfo.Group2Index == 2
                );

        Assert.AreEqual(0, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(1, oCombinedIntergroupEdge.Edges);

        oCombinedIntergroupEdge =
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Single(
                intergroupEdgeInfo =>
                intergroupEdgeInfo.Group1Index == 1
                &&
                intergroupEdgeInfo.Group2Index == 2
                );

        Assert.AreEqual(1, oCombinedIntergroupEdge.Group1Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Group2Index);
        Assert.AreEqual(2, oCombinedIntergroupEdge.Edges);
    }
    TestOnLayoutBegin()
    {
        // Draw rectangles, hide intergroup edges.

        const Double GroupRectanglePenWidth = 1.23;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Hide;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

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

        IEdgeCollection oEdges = oGraph.Edges;
        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[0], aoVertices[2], false);
        IEdge oEdge3 = oEdges.Add(aoVertices[2], aoVertices[3], false);
        IEdge oEdge4 = oEdges.Add(aoVertices[1], aoVertices[3], false);

        // oEdge2 is intergroup.  Give it an initial visibility. 

        oEdge2.SetValue(ReservedMetadataKeys.Visibility,
            VisibilityKeyValue.Filtered);

        // (oEdge4 is intergroup.  Don't give it an initial visibility.)

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(2, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );

        Assert.IsTrue( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( VisibilityKeyValue.Filtered,
            oEdge2.GetValue(ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge2.ContainsKey(
            ReservedMetadataKeys.Visibility) );

        Assert.AreEqual( VisibilityKeyValue.Hidden,
            oEdge2.GetValue(ReservedMetadataKeys.Visibility) );

        Assert.IsFalse( oEdge3.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsTrue( oEdge4.ContainsKey(
            ReservedMetadataKeys.Visibility) );

        Assert.AreEqual( VisibilityKeyValue.Hidden,
            oEdge4.GetValue(ReservedMetadataKeys.Visibility) );

        // Verify that OnLayoutBegin() reverses the metadata changes.

        GroupMetadataManager.OnLayoutBegin(oGraph);

        VerifyOriginalMetadata(oGraph, oEdge1, oEdge2, oEdge3, oEdge4);
    }
    TestOnLayoutBegin5()
    {
        // Request that intergroup edges be combined, although there are none.

        const Double GroupRectanglePenWidth = 4.567;

        const IntergroupEdgeStyle IntergroupEdgeStyle =
            IntergroupEdgeStyle.Combine;

        IGraph oGraph = new Graph(GraphDirectedness.Undirected);

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

        IEdgeCollection oEdges = oGraph.Edges;
        IEdge oEdge1 = oEdges.Add(aoVertices[0], aoVertices[1], false);
        IEdge oEdge2 = oEdges.Add(aoVertices[2], aoVertices[3], false);

        GroupInfo oGroup1 = new GroupInfo();
        oGroup1.Vertices.AddLast( aoVertices[0] );
        oGroup1.Vertices.AddLast( aoVertices[1] );
        oGroup1.Rectangle = Rectangle.FromLTRB(1, 2, 3, 4);

        GroupInfo oGroup2 = new GroupInfo();
        oGroup2.Vertices.AddLast( aoVertices[2] );
        oGroup2.Vertices.AddLast( aoVertices[3] );
        oGroup2.Rectangle = Rectangle.FromLTRB(5, 6, 7, 8);

        GroupInfo oGroup3 = new GroupInfo();
        oGroup3.Vertices.AddLast( aoVertices[4] );
        oGroup3.Rectangle = Rectangle.FromLTRB(9, 10, 11, 12);

        GroupMetadataManager.OnLayoutBegin(oGraph);

        GroupMetadataManager.OnLayoutUsingGroupsEnd(oGraph,
            new GroupInfo[] {oGroup1, oGroup2, oGroup3},
            GroupRectanglePenWidth, IntergroupEdgeStyle);

        GroupLayoutDrawingInfo oGroupLayoutDrawingInfo;

        Assert.IsTrue( GroupMetadataManager.TryGetGroupLayoutDrawingInfo(
            oGraph, out oGroupLayoutDrawingInfo) );

        Assert.AreEqual(GroupRectanglePenWidth,
            oGroupLayoutDrawingInfo.PenWidth);

        IList<GroupInfo> oGroupInfo = oGroupLayoutDrawingInfo.GroupsToDraw;

        Assert.AreEqual(3, oGroupInfo.Count);
        Assert.AreEqual( oGroup1, oGroupInfo[0] );
        Assert.AreEqual( oGroup2, oGroupInfo[1] );
        Assert.AreEqual( oGroup3, oGroupInfo[2] );

        Assert.IsFalse( oGraph.ContainsKey(
            ReservedMetadataKeys.IntergroupEdgesHidden) );

        Assert.IsFalse( oEdge1.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.IsFalse( oEdge2.ContainsKey(
            ReservedMetadataKeys.SavedVisibility) );

        Assert.AreEqual( 0,
            oGroupLayoutDrawingInfo.CombinedIntergroupEdges.Count() );
    }