/// <summary>
        /// Adds a fractal to a region
        /// </summary>
        /// <param name="rci"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        public static void createFractal(RegionConstructionInfo rci, Point start, Point end)
        {
            float maxOffset = 60.0f;
            float threshold = 7000.0f;

            List<LineSegment> fractal =
                Fractal.fractalLineSegment(
                    new LineSegment(new Vector2(start.X, start.Y), new Vector2(end.X, end.Y)),
                    maxOffset,
                    threshold);

            rci.fractals.Add(new LineFractalInfo(fractal));
        }
        /// <summary>
        /// Converts RegionMarker's into RegionConstructionInfo's by creating endpoints for boundary lines
        /// </summary>
        /// <param name="markers"></param>
        /// <returns></returns>
        public static Dictionary<Point, RegionConstructionInfo> buildConstructionInfo(Dictionary<Point, RegionMarker> markers)
        {
            Dictionary<Point, RegionConstructionInfo> rcis =
                new Dictionary<Point,RegionConstructionInfo>();

            Random rand = RandomManager.get();

            foreach (RegionMarker marker in markers.Values)
            {
                RegionConstructionInfo rci = new RegionConstructionInfo(marker);
                rcis.Add(rci.location, rci);

                if (marker.connectsTop && rcis.ContainsKey(new Point(marker.location.X, marker.location.Y - 1)))
                {
                    RegionConstructionInfo above = rcis[new Point(marker.location.X, marker.location.Y - 1)];
                    rci.topLeft = above.bottomLeft;
                    rci.topRight = above.bottomRight;
                    rci.pathTop = above.pathBottom;
                }
                else
                {
                    rci.topLeft = rand.Next(0, REGION_WIDTH / 4);
                    rci.topRight = rand.Next(REGION_WIDTH * 3 / 4, REGION_WIDTH);
                    rci.pathTop = rand.Next(REGION_WIDTH / 3, REGION_WIDTH * 2 / 3);
                }

                if (marker.connectsLeft && rcis.ContainsKey(new Point(marker.location.X-1, marker.location.Y)))
                {
                    RegionConstructionInfo left = rcis[new Point(marker.location.X-1, marker.location.Y)];
                    rci.leftTop = left.rightTop;
                    rci.leftBottom = left.rightBottom;
                    rci.pathLeft = left.pathRight;
                }
                else
                {
                    rci.leftTop = rand.Next(0, REGION_HEIGHT / 4);
                    rci.leftBottom = rand.Next(REGION_HEIGHT * 3 / 4, REGION_HEIGHT);
                    rci.pathLeft = rand.Next(REGION_HEIGHT / 3, REGION_HEIGHT * 2 / 3);
                }

                if (marker.connectsBottom && rcis.ContainsKey(new Point(marker.location.X, marker.location.Y+1)))
                {
                    RegionConstructionInfo below = rcis[new Point(marker.location.X, marker.location.Y+1)];
                    rci.bottomLeft = below.topLeft;
                    rci.bottomRight = below.topRight;
                    rci.pathBottom = below.pathTop;
                }
                else
                {
                    rci.bottomLeft = rand.Next(0, REGION_WIDTH / 4);
                    rci.bottomRight = rand.Next(REGION_WIDTH * 3 / 4, REGION_WIDTH);
                    rci.pathBottom = rand.Next(REGION_WIDTH / 3, REGION_WIDTH * 2 / 3);
                }

                if (marker.connectsRight && rcis.ContainsKey(new Point(marker.location.X + 1, marker.location.Y)))
                {
                    RegionConstructionInfo right = rcis[new Point(marker.location.X + 1, marker.location.Y)];
                    rci.rightTop = right.leftTop;
                    rci.rightBottom = right.leftBottom;
                    rci.pathRight = right.pathRight;
                }
                else
                {
                    rci.rightTop = rand.Next(0, REGION_HEIGHT / 4);
                    rci.rightBottom = rand.Next(REGION_HEIGHT * 3 / 4, REGION_HEIGHT);
                    rci.pathRight = rand.Next(REGION_HEIGHT / 3, REGION_HEIGHT * 2 / 3);
                }
            }

            return rcis;
        }
        /// <summary>
        /// Creates a Region based on the specified parameters.
        /// </summary>
        /// <param name="rci">Properties of the region to be created.</param>
        /// <returns>A Region object with its areas all created and populated appropriately.</returns>
        public static Region constructRegion(RegionConstructionInfo rci)
        {
            Region r = new Region(rci.location);

            for (int i = 0; i < Region.AREAS_WIDE; ++i)
            {
                for (int j = 0; j < Region.AREAS_TALL; ++j)
                {
                    Point globalLocation = new Point(
                        rci.location.X * Region.AREAS_WIDE + i,
                        rci.location.Y * Region.AREAS_TALL + j);
                    Area a = Area.makeEmptyArea(globalLocation);
                    a.fractals = mapFractals(rci.fractals, i, j);

                    populateArea(a);

                    r.areas[i, j] = a;
                }
            }

            return r;
        }