/// <summary>
        /// Reserves a rectangular area for the given image in this.Maze.
        /// The chosen location is remembered in this.imageLocations.
        /// Returns true if the reservation was successful.
        /// </summary>
        /// <param name="contourImage"></param>
        /// <returns></returns>
        private bool AddImage(ContourImage contourImage)
        {
            Image img     = contourImage.DisplayedImage;
            int   padding = MazePainter.ApplyScaleFactor(8) + this.wallWidth;
            int   sqW     = (img.Width + padding) / this.gridWidth + 1;
            int   sqH     = (img.Height + padding) / this.gridWidth + 1;

            int xOffsetImg = (sqW * gridWidth - img.Width) / 2;
            int yOffsetImg = (sqH * gridWidth - img.Height) / 2;

            OutlineShape shape = (ContourImage.DisplayProcessedImage ? contourImage.GetCoveredShape(gridWidth, wallWidth, xOffsetImg, yOffsetImg) : null);

            Rectangle rect;

            if (Maze.ReserveRectangle(sqW, sqH, 2, shape, out rect))
            {
                // Remember the image data and location.  It will be painted in PaintMaze().
                int x = rect.X * gridWidth + xOffset + xOffsetImg;
                int y = rect.Y * gridWidth + yOffset + yOffsetImg;
                imageLocations.Add(new Rectangle(x, y, img.Width, img.Height));
                return(true);
            }
            else
            {
                return(false);
            }
        }
        /// <summary>
        /// Reserves a region of the maze covered by the coveringControl.
        /// This MazeUserControl and the coveringControl must have the same Parent, i.e. a common coordinate system.
        /// </summary>
        /// <param name="coveringControl"></param>
        /// <exception cref="ArgumentException">The given Control has a differnent Parent.</exception>
        public bool ReserveArea(Control coveringControl)
        {
            if (coveringControl.Parent != this.Parent)
            {
                throw new ArgumentException("Must have the same Parent.", nameof(coveringControl));
            }

            // Dimensions of the control in square coordinates.
            int x, y, w, h;

            x = XCoordinate(coveringControl.Left, true);
            y = YCoordinate(coveringControl.Top, true);

            w = 1 + XCoordinate(coveringControl.Right - 1, false) - x;
            h = 1 + YCoordinate(coveringControl.Bottom - 1, false) - y;

            int padding = wallWidth + MazePainter.ApplyScaleFactor(6);

            if (0 < x && x + w < Maze.XSize)
            {
                w = 1 + (coveringControl.Width + padding) / gridWidth;
            }
            if (0 < y && y + h < Maze.YSize)
            {
                h = 1 + (coveringControl.Height + padding) / gridWidth;
            }

            bool result = Maze.ReserveRectangle(x, y, w, h, null);

            // Move the control into the center of the reserved area.
            if (result)
            {
                int cx = coveringControl.Left;
                int cy = coveringControl.Top;

                if (0 < x && x + w < Maze.XSize)
                {
                    cx  = this.Location.X + xOffset + x * gridWidth;
                    cx += 1 + (w * gridWidth - wallWidth - coveringControl.Width) / 2;
                }
                if (0 < y && y + h < Maze.YSize)
                {
                    cy  = this.Location.Y + yOffset + y * gridWidth;
                    cy += 1 + (h * gridWidth - wallWidth - coveringControl.Height) / 2;
                }

                // Adjust the control's location
                coveringControl.Location = new Point(cx, cy);
                controlLocations.Add(coveringControl.Bounds);
            }

            return(result);
        }