public void Merge(List <CGPoint> points, int low, int mid, int high)
        {
            var rtlleftHull             = CGUtils.RightmostThenLowest(points, low, mid);
            var ltlRightHull            = CGUtils.LeftmostThenLowest(points, mid, high);
            var leftHullUpperTanPooint  = rtlleftHull;
            var rightHullUpperTanPooint = ltlRightHull;

            while (!isTangentPoint(leftHullUpperTanPooint, rightHullUpperTanPooint, false) || !isTangentPoint(rightHullUpperTanPooint, leftHullUpperTanPooint, true))
            {
                while (!isTangentPoint(leftHullUpperTanPooint, rightHullUpperTanPooint, false))
                {
                    rightHullUpperTanPooint = rightHullUpperTanPooint.pred;
                }
                while (!isTangentPoint(rightHullUpperTanPooint, leftHullUpperTanPooint, true))
                {
                    leftHullUpperTanPooint = leftHullUpperTanPooint.succ;
                }
            }
            var leftHullLowerTanPooint  = rtlleftHull;
            var rightHullLowerTanPooint = ltlRightHull;

            while (!isTangentPoint(leftHullLowerTanPooint, rightHullLowerTanPooint, true) || !isTangentPoint(rightHullLowerTanPooint, leftHullLowerTanPooint, false))
            {
                while (!isTangentPoint(leftHullLowerTanPooint, rightHullLowerTanPooint, true))
                {
                    rightHullLowerTanPooint = rightHullLowerTanPooint.succ;
                }
                while (!isTangentPoint(rightHullLowerTanPooint, leftHullLowerTanPooint, false))
                {
                    leftHullLowerTanPooint = leftHullLowerTanPooint.pred;
                }
            }
            ResetCGPointsBetweenFromAndToPointsInCCWOrder(leftHullLowerTanPooint, leftHullUpperTanPooint);
            ResetCGPointsBetweenFromAndToPointsInCCWOrder(rightHullUpperTanPooint, rightHullLowerTanPooint);
            leftHullLowerTanPooint.isExtreme  = true;
            rightHullLowerTanPooint.isExtreme = true;
            leftHullLowerTanPooint.succ       = rightHullLowerTanPooint;
            rightHullLowerTanPooint.pred      = leftHullLowerTanPooint;
            leftHullUpperTanPooint.isExtreme  = true;
            rightHullUpperTanPooint.isExtreme = true;
            leftHullUpperTanPooint.pred       = rightHullUpperTanPooint;
            rightHullUpperTanPooint.succ      = leftHullUpperTanPooint;
        }