private void TraceHBottomLines(List <BorderPoint> points, HashSet <BorderLine> result)
        {
            int index = 0, x1, x2, y, start;

            while (points.Count > index)
            {
                start = index;
                y     = points[index].mY;
                x1    = points[index].mX;
                x2    = x1;
                do
                {
                    x1 = x2;
                    index++;
                    if (points.Count > index)
                    {
                        x2 = points[index].mX;
                    }
                    else
                    {
                        break;
                    }
                } while ((x2 - x1 == 1) && (points[index].mY == y) && (index < points.Count));
                index--;
                BorderLine line = new BorderLine(new Point(points[start].mX, points[start].mY + 1), new Point(points[index].mX + 1, points[index].mY + 1));
                Thread.MemoryBarrier();
                result.Add(line);
                index++;
            }
        }
        private void TraceVRightLines(List <BorderPoint> points, HashSet <BorderLine> result)
        {
            int index = 0, y1, y2, x, start;

            while (points.Count > index)
            {
                start = index;
                x     = points[index].mX;
                y1    = points[index].mY;
                y2    = y1;
                do
                {
                    y1 = y2;
                    index++;
                    if (points.Count > index)
                    {
                        y2 = points[index].mY;
                    }
                    else
                    {
                        break;
                    }
                } while ((y2 - y1 == 1) && (points[index].mX == x) && (index < points.Count));
                index--;
                BorderLine line = new BorderLine(new Point(points[start].mX + 1, points[start].mY), new Point(points[index].mX + 1, points[index].mY + 1));
                Thread.MemoryBarrier();
                result.Add(line);
                index++;
            }
        }
        /// <summary>
        /// Assemble the give collection of <see cref="BorderLine"/> into a <see cref="GraphicsPath"/>.
        /// </summary>
        /// <param name="lines">The collection of <see cref="BorderLine"/> that define one or more closed shapes.</param>
        /// <returns><see cref="GraphicsPath"/> made up of one or more closed shapes.</returns>
        private GraphicsPath BuildPath(HashSet <BorderLine> lines)
        {
            lines = new HashSet <BorderLine>(lines);
            GraphicsPath path = new GraphicsPath();
            int          x;
            BorderLine   points = lines.First();

            path.StartFigure();
            path.AddLine(points.mStart, points.mEnd);
            lines.Remove(points);
            while (lines.Count > 0)
            {
                x = lines.Count;
                foreach (BorderLine line in lines.Where(line => path.GetLastPoint() == (PointF)line.mStart))
                {
                    path.AddLine(line.mStart, line.mEnd);
                    lines.Remove(line);
                    break;
                }
                if (x == lines.Count)
                {
                    path.StartFigure();
                    points = lines.First();
                    path.AddLine(points.mStart, points.mEnd);
                    lines.Remove(points);
                }
            }
            return(path);
        }
        /// <summary>
        /// Update the <paramref name="provinceLines"/> collection so that it contains <see cref="BorderLine"/> present in it
        /// or present in the outline of a shape define by <paramref name="complementingProvince"/> color, but not in both.
        /// </summary>
        /// <remarks>If <see cref="BorderLine"/> present in both collection only partially overlap, the updated <paramref name="provinceLines"/> will
        /// contain the segments resulted after a <see cref="BorderLine.Exclude(BorderLine)"/> operation.</remarks>
        /// <param name="provinceLines">The collection to be updated.</param>
        /// <param name="complementingProvince">The color of the shape whose outline will be used in the complement operation.</param>
        public void ComplementVirtualProvince(ref HashSet <BorderLine> provinceLines, Color complementingProvince)
        {
            HashSet <BorderLine> linesToRemove = new HashSet <BorderLine>(3);
            HashSet <BorderLine> linesFound    = new HashSet <BorderLine>(3);

            foreach (BorderLine lineToAddImmutable in this._mProvincesLines[complementingProvince])
            {
                BorderLine lineToAdd = lineToAddImmutable;
                bool       found     = false;
                linesToRemove.Clear();
                linesFound.Clear();
                BorderLine foundLine = BorderLine.EmptyLine;
                foreach (BorderLine lineExisting in provinceLines)
                {
                    //Search for any overlapping
                    if (lineExisting.IsOverlapping(lineToAdd))
                    {
                        found = true;
                        linesFound.Add(lineExisting);
                    }
                    //Search if two lines are in fact a bigger line
                    if (lineExisting.IsContinuous(lineToAdd))
                    {
                        linesToRemove.Add(lineExisting);
                        lineToAdd = lineToAdd.Concatenate(lineExisting);
                        found     = true;
                    }
                }
                if (found == false)
                {
                    provinceLines.Add(lineToAdd);
                }
                else
                {
                    // Remove lines marked for removal
                    provinceLines.ExceptWith(linesToRemove);
                    // If found to overlap with only one line, it's easy then
                    if (linesFound.Count == 1)
                    {
                        provinceLines.ExceptWith(linesFound);
                        BorderLine[] lines = lineToAdd.Exclude(linesFound.First());
                        if (lines != null)
                        {
                            provinceLines.UnionWith(lines);
                        }
                    }
                    else if (linesFound.Count > 1)
                    {
                        foreach (BorderLine lineFound in linesFound)
                        {
                            lineToAdd = lineFound.Exclude(lineToAdd)[0];
                        }
                        provinceLines.ExceptWith(linesFound);
                        provinceLines.Add(lineToAdd);
                    }
                    else
                    {
                        provinceLines.Add(lineToAdd);
                    }
                }
            }
        }