/// <summary>
        /// Creates a new Voronoi Graph given a set of Points
        /// </summary>
        /// <param name="Datapoints">Data points to base the Voronoi Graph around</param>
        /// <returns></returns>
        public static VoronoiGraph GenerateGraph(IEnumerable Datapoints)
        {
            BinaryPriorityQueue PQ = new BinaryPriorityQueue();

            Hashtable CurrentCircles = new Hashtable();

            VoronoiGraph Graph = new VoronoiGraph();

            VNode RootNode = null;

            foreach (Vector2 V in Datapoints)
            {
                PQ.Push(new VDataEvent(V));
            }

            while (PQ.Count > 0)
            {
                VEvent VE = PQ.Pop() as VEvent;
                VDataNode[] CircleCheckList;
                if (VE is VDataEvent)
                {
                    RootNode = VNode.ProcessDataEvent(VE as VDataEvent, RootNode, Graph, VE.Y, out CircleCheckList);
                }
                else if (VE is VCircleEvent)
                {
                    CurrentCircles.Remove(((VCircleEvent)VE).NodeN);
                    if (!((VCircleEvent)VE).Valid)
                        continue;
                    RootNode = VNode.ProcessCircleEvent(VE as VCircleEvent, RootNode, Graph, VE.Y, out CircleCheckList);
                }
                else throw new Exception("Got event of type " + VE.GetType().ToString() + "!");
                foreach (VDataNode VD in CircleCheckList)
                {
                    if (CurrentCircles.ContainsKey(VD))
                    {
                        ((VCircleEvent)CurrentCircles[VD]).Valid = false;
                        CurrentCircles.Remove(VD);
                    }
                    VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y);
                    if (VCE != null)
                    {
                        PQ.Push(VCE);
                        CurrentCircles[VD] = VCE;
                    }
                }
                if (VE is VDataEvent)
                {
                    Vector2 DP = ((VDataEvent)VE).DataPoint;
                    foreach (VCircleEvent VCE in CurrentCircles.Values)
                    {

                        if (Vector2.Distance(DP, VCE.Center) < VCE.Y - VCE.Center.y && Math.Abs(Vector2.Distance(DP, VCE.Center) - (VCE.Y - VCE.Center.y)) > 1e-10)
                            VCE.Valid = false;
                    }
                }
            }
            return Graph;
        }
 public static BinaryPriorityQueue Syncronized(BinaryPriorityQueue P)
 {
     return new BinaryPriorityQueue(ArrayList.Synchronized(P.InnerList), P.Comparer, false);
 }
 public static BinaryPriorityQueue ReadOnly(BinaryPriorityQueue P)
 {
     return new BinaryPriorityQueue(ArrayList.ReadOnly(P.InnerList), P.Comparer, false);
 }