public Node(GeometricTree <TItem, TVector, TBound> tree, TBound bounds, int depth, int maxDepth)
            {
                _tree     = tree;
                _depth    = depth;
                _maxDepth = maxDepth;

                Bounds = bounds;
            }
            private int RemoveRecursive(TBound bounds, Predicate <Member> predicate, bool removeSingle)
            {
                //We want to skip this node if the boundary doesn't intersect it... unless it's the root which can contain items outside it's boundary!
                if (!_tree.Intersects(Bounds, ref bounds) && !_tree._root.Equals(this))
                {
                    return(0);
                }

                int removed = 0;

                //Either we're removing the first item which matches the predicate, or all items which match
                if (removeSingle)
                {
                    // Find single item and remove it, then exit instantly
                    var index = Items.FindIndex(predicate);
                    if (index != -1)
                    {
                        Items.RemoveAt(index);
                        return(1);
                    }
                }
                else
                {
                    //We're removing all predicate matches
                    removed += Items.RemoveAll(predicate);
                }

                //Remove items from children (and aggregate total removed count)
                if (Children != null)
                {
                    foreach (var child in Children)
                    {
                        removed += child.RemoveRecursive(bounds, predicate, removeSingle);

                        //Early exit if we can
                        if (removed > 0 && removeSingle)
                        {
                            return(removed);
                        }
                    }
                }

                return(removed);
            }
            public IEnumerable <Member> Intersects(TBound bounds)
            {
                var nodes = new List <Node>(50)
                {
                    this
                };

                var root = true;

                while (nodes.Count > 0)
                {
                    //Remove node
                    var n = nodes[nodes.Count - 1];
                    nodes.RemoveAt(nodes.Count - 1);

                    //Skip nodes we do not intersect (unless this is the root, in which case we always want to check it)
                    if (!root && !_tree.Intersects(n.Bounds, ref bounds))
                    {
                        continue;
                    }

                    //yield items as appropriate
                    foreach (var member in n.Items)
                    {
                        if (_tree.Intersects(member.Bounds, ref bounds))
                        {
                            yield return(member);
                        }
                    }

                    //push children onto stack to be checked
                    if (n.Children != null)
                    {
                        nodes.AddRange(n.Children);
                    }

                    root = false;
                }
            }
            public int Remove(TBound bounds, Predicate <TItem> pred)
            {
                var predInner = new Predicate <Member>(a => pred(a.Value));

                return(RemoveRecursive(bounds, predInner, false));
            }
            public int Remove(TBound bounds, TItem item)
            {
                var pred = new Predicate <Member>(a => a.Value.Equals(item));

                return(RemoveRecursive(bounds, pred, true));
            }
        /// <summary>
        ///  быстрая сортировка для узлов по их MBR. axe - ось по которой происходит сортировка, bound - граница по которой происходит сортировка (левая/правая)
        /// </summary>
        /// <param name="List"></param>
        /// <param name="iLo"></param>
        /// <param name="iHi"></param>
        /// <param name="axe"></param>
        /// <param name="bound"></param>
        #region
        private void QuickSort(int[] List, int iLo, int iHi, TAxis axe, TBound bound)
        {
            //Console.WriteLine("QuickSort2 work");
            int    Lo = iLo, Hi = iHi;
            int    T;
            double Mid = 0.0;

            switch (bound)
            {
            case TBound.Left:
            {
                switch (axe)
                {
                case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.X; break;

                case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.Y; break;
                }
            }
            break;

            case TBound.Right:
            {
                switch (axe)
                {
                case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.X; break;

                case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.Y; break;
                }
            }
            break;
            }

            do
            {
                switch (bound)
                {
                case TBound.Left:
                {
                    switch (axe)
                    {
                    case TAxis.X:
                    {
                        while (FNodeArr[List[Lo]].mbr.Left.X < Mid)
                        {
                            Lo++;
                        }
                        while (FNodeArr[List[Hi]].mbr.Left.X > Mid)
                        {
                            Hi--;
                        }
                    }
                    break;

                    case TAxis.Y:
                    {
                        while (FNodeArr[List[Lo]].mbr.Left.Y < Mid)
                        {
                            Lo++;
                        }
                        while (FNodeArr[List[Hi]].mbr.Left.Y > Mid)
                        {
                            Hi--;
                        }
                    }
                    break;
                    }
                }
                break;

                case TBound.Right:
                {
                    switch (axe)
                    {
                    case TAxis.X:
                    {
                        while (FNodeArr[List[Lo]].mbr.Right.X < Mid)
                        {
                            Lo++;
                        }
                        while (FNodeArr[List[Hi]].mbr.Right.X > Mid)
                        {
                            Hi--;
                        }
                    }
                    break;

                    case TAxis.Y:
                    {
                        while (FNodeArr[List[Lo]].mbr.Right.Y < Mid)
                        {
                            Lo++;
                        }
                        while (FNodeArr[List[Hi]].mbr.Right.Y > Mid)
                        {
                            Hi--;
                        }
                    }
                    break;
                    }
                }
                break;
                }

                if (Lo <= Hi)
                {
                    T        = List[Lo];
                    List[Lo] = List[Hi];
                    List[Hi] = T;
                    Lo++;
                    Hi--;
                }
            } while (Lo <= Hi);

            if (Hi > iLo)
            {
                QuickSort(List, iLo, Hi, axe, bound);
            }
            if (Lo < iHi)
            {
                QuickSort(List, Lo, iHi, axe, bound);
            }
        }