/// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        /// <summary>
        /// Processes the data event.
        /// </summary>
        /// <returns>
        /// The data event.
        /// </returns>
        /// <param name='e'>
        /// E.
        /// </param>
        /// <param name='Root'>
        /// Root.
        /// </param>
        /// <param name='VG'>
        /// V.
        /// </param>
        /// <param name='ys'>
        /// Ys.
        /// </param>
        /// <param name='CircleCheckList'>
        /// Circle check list.
        /// </param>
        /// <exception cref='Exception'>
        /// Represents errors that occur during application execution.
        /// </exception>
        public static VNode ProcessDataEvent(VDataEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            if (Root == null)
            {
                Root            = new VDataNode(e.DataPoint);
                CircleCheckList = new VDataNode[] { Root as VDataNode };
                return(Root);
            }

            //1. Find the node to be replaced
            VNode     C     = VNode.FindDataNode(Root, ys, e.DataPoint.X);
            VDataNode cData = C as VDataNode;

            if (cData == null)
            {
                throw new Exception("Can't cast to data node");
            }

            //2. Create the subtree (ONE Edge, but two VEdgeNodes)
            VoronoiEdge VE = new VoronoiEdge();

            VE.LeftData  = cData.DataPoint;
            VE.RightData = e.DataPoint;
            VE.VVertexA  = Fortune.VVUnkown;
            VE.VVertexB  = Fortune.VVUnkown;
            VG.Edges.Add(VE);

            VNode SubRoot;

            if (Math.Abs(VE.LeftData.Y - VE.RightData.Y) < 1e-10)
            {
                if (VE.LeftData.X < VE.RightData.X)
                {
                    SubRoot       = new VEdgeNode(VE, false);
                    SubRoot.Left  = new VDataNode(VE.LeftData);
                    SubRoot.Right = new VDataNode(VE.RightData);
                }
                else
                {
                    SubRoot       = new VEdgeNode(VE, true);
                    SubRoot.Left  = new VDataNode(VE.RightData);
                    SubRoot.Right = new VDataNode(VE.LeftData);
                }

                CircleCheckList = new VDataNode[] { SubRoot.Left as VDataNode, SubRoot.Right as VDataNode };
            }
            else
            {
                SubRoot             = new VEdgeNode(VE, false);
                SubRoot.Left        = new VDataNode(VE.LeftData);
                SubRoot.Right       = new VEdgeNode(VE, true);
                SubRoot.Right.Left  = new VDataNode(VE.RightData);
                SubRoot.Right.Right = new VDataNode(VE.LeftData);
                CircleCheckList     = new VDataNode[] { SubRoot.Left as VDataNode, SubRoot.Right.Left as VDataNode, SubRoot.Right.Right as VDataNode };
            }

            //3. Apply subtree
            if (C.Parent == null)
            {
                return(SubRoot);
            }

            C.Parent.Replace(C, SubRoot);

            return(Root);
        }
        /// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        /// <summary>
        /// Processes the data event.
        /// </summary>
        /// <returns>
        /// The data event.
        /// </returns>
        /// <param name='e'>
        /// E.
        /// </param>
        /// <param name='Root'>
        /// Root.
        /// </param>
        /// <param name='VG'>
        /// V.
        /// </param>
        /// <param name='ys'>
        /// Ys.
        /// </param>
        /// <param name='CircleCheckList'>
        /// Circle check list.
        /// </param>
        /// <exception cref='Exception'>
        /// Represents errors that occur during application execution.
        /// </exception>
        public static VNode ProcessDataEvent( VDataEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList )
        {
            if( Root == null ) {
                Root = new VDataNode( e.DataPoint );
                CircleCheckList = new VDataNode[] {Root as VDataNode};
                return Root;
            }

            //1. Find the node to be replaced
            VNode C = VNode.FindDataNode( Root, ys, e.DataPoint.X );
            VDataNode cData = C as VDataNode;

            if( cData == null ) {
                throw new Exception( "Can't cast to data node" );
            }

            //2. Create the subtree (ONE Edge, but two VEdgeNodes)
            VoronoiEdge VE = new VoronoiEdge();
            VE.LeftData = cData.DataPoint;
            VE.RightData = e.DataPoint;
            VE.VVertexA = Fortune.VVUnkown;
            VE.VVertexB = Fortune.VVUnkown;
            VG.Edges.Add( VE );

            VNode SubRoot;
            if( Math.Abs( VE.LeftData.Y - VE.RightData.Y ) < 1e-10 ) {
                if( VE.LeftData.X < VE.RightData.X ) {
                    SubRoot = new VEdgeNode( VE, false );
                    SubRoot.Left = new VDataNode( VE.LeftData );
                    SubRoot.Right = new VDataNode( VE.RightData );
                } else {
                    SubRoot = new VEdgeNode( VE, true );
                    SubRoot.Left = new VDataNode( VE.RightData );
                    SubRoot.Right = new VDataNode( VE.LeftData );
                }

                CircleCheckList = new VDataNode[] {SubRoot.Left as VDataNode, SubRoot.Right as VDataNode};
            } else {
                SubRoot = new VEdgeNode( VE, false );
                SubRoot.Left = new VDataNode( VE.LeftData );
                SubRoot.Right = new VEdgeNode( VE, true );
                SubRoot.Right.Left = new VDataNode( VE.RightData );
                SubRoot.Right.Right = new VDataNode( VE.LeftData );
                CircleCheckList = new VDataNode[] {SubRoot.Left as VDataNode, SubRoot.Right.Left as VDataNode, SubRoot.Right.Right as VDataNode};
            }

            //3. Apply subtree
            if( C.Parent == null ) {
                return SubRoot;
            }

            C.Parent.Replace( C, SubRoot );

            return Root;
        }