/// <summary>
        /// Returns a region which is the result of mergin region1 and region2. Original regions are not modified.
        /// </summary>
        /// <returns>The merge.</returns>
        /// <param name="region1">Region1.</param>
        /// <param name="region2">Region2.</param>
        public Region RegionMerge(Region region1, Region region2)
        {
            Region newRegion = region1.Clone();

            RegionMagnet(newRegion, region2);
            Clipper clipper = new Clipper();

            clipper.AddPath(newRegion, PolyType.ptSubject);
            clipper.AddPath(region2, PolyType.ptClip);
            clipper.Execute(ClipType.ctUnion, newRegion);
            return(newRegion);
        }
        void CountrySubstractCountryEnclaves(int countryIndex, Region region, Poly2Tri.Polygon poly)
        {
            List <Region> negativeRegions = new List <Region> ();
            int           countryCount    = _countriesOrderedBySize.Count;

            for (int ops = 0; ops < countryCount; ops++)
            {
                int op = _countriesOrderedBySize [ops];
                if (op == countryIndex)
                {
                    continue;
                }
                Country opCountry       = _countries [op];
                Region  opCountryRegion = opCountry.regions [opCountry.mainRegionIndex];
                if (opCountryRegion.points.Length >= 5 && opCountry.mainRegion.rect2DArea < region.rect2DArea && opCountryRegion.rect2D.Overlaps(region.rect2D, true))
                {
                    if (region.Contains(opCountryRegion))                               // just check main region of province for speed purposes
                    {
                        negativeRegions.Add(opCountryRegion.Clone());
                    }
                }
            }
            // Collapse negative regions in big holes
            for (int nr = 0; nr < negativeRegions.Count - 1; nr++)
            {
                for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++)
                {
                    if (negativeRegions [nr].Intersects(negativeRegions [nr2]))
                    {
                        Clipper clipper = new Clipper();
                        int     control = negativeRegions [nr].points.Length;
                        clipper.AddPath(negativeRegions [nr], PolyType.ptSubject);
                        clipper.AddPath(negativeRegions [nr2], PolyType.ptClip);
                        clipper.Execute(ClipType.ctUnion);
                        negativeRegions.RemoveAt(nr2);
                        nr = -1;
                        break;
                    }
                }
            }

            // Substract holes
            for (int r = 0; r < negativeRegions.Count; r++)
            {
                Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(negativeRegions [r].points);
                poly.AddHole(polyHole);
            }
        }
        void ProvinceSubstractProvinceEnclaves(int provinceIndex, Region region, Poly2Tri.Polygon poly)
        {
            List <Region> negativeRegions = new List <Region> ();

            for (int oc = 0; oc < _countries.Length; oc++)
            {
                Country ocCountry = _countries [oc];
                if (ocCountry.hidden || ocCountry.provinces == null)
                {
                    continue;
                }
                Region mainCountryRegion = ocCountry.regions [ocCountry.mainRegionIndex];
                if (!mainCountryRegion.rect2D.Overlaps(region.rect2D))
                {
                    continue;
                }
                for (int op = 0; op < ocCountry.provinces.Length; op++)
                {
                    Province opProvince = ocCountry.provinces [op];
                    if (opProvince == provinces [provinceIndex])
                    {
                        continue;
                    }
                    if (opProvince.regions == null)
                    {
                        ReadProvincePackedString(opProvince);
                    }
                    if (opProvince.regions == null)
                    {
                        continue;
                    }
                    if (opProvince.regionsRect2D.Overlaps(region.rect2D, true))
                    {
                        Region oProvRegion = opProvince.regions [opProvince.mainRegionIndex];
                        if (region.Contains(oProvRegion))                               // just check main region of province for speed purposes
                        {
                            negativeRegions.Add(oProvRegion.Clone());
                        }
                    }
                }
            }
            // Collapse negative regions in big holes
            for (int nr = 0; nr < negativeRegions.Count - 1; nr++)
            {
                for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++)
                {
                    if (negativeRegions [nr].Intersects(negativeRegions [nr2]))
                    {
                        Clipper clipper = new Clipper();
                        int     control = negativeRegions [nr].points.Length;
                        clipper.AddPath(negativeRegions [nr], PolyType.ptSubject);
                        clipper.AddPath(negativeRegions [nr2], PolyType.ptClip);
                        clipper.Execute(ClipType.ctUnion);
                        negativeRegions.RemoveAt(nr2);
                        nr = -1;
                        break;
                    }
                }
            }

            // Substract holes
            int negativeRegionsCount = negativeRegions.Count;

            for (int r = 0; r < negativeRegionsCount; r++)
            {
                int       pointCount = negativeRegions [r].points.Length;
                Vector2[] pp         = new Vector2[pointCount];
                for (int p = 0; p < pointCount; p++)
                {
                    Vector2 point    = negativeRegions [r].points [p];
                    Vector2 midPoint = negativeRegions [r].center;
                    pp [p] = point + (midPoint - point) * 0.0001f;                     // prevents Poly2Tri issues when enclave boarders are to near from region borders
                }
                Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(pp);
                poly.AddHole(polyHole);
            }
        }