/// <summary>
        /// Renders a test image.
        /// </summary>
        /// <param name="width">Width of the test image.</param>
        /// <param name="height">Height of the test image.</param>
        /// <param name="blockSize">Block size used for coloring the test image.</param>
        /// <param name="tileX">The x-coordinate of the tile being requested; used for dynamically coloring the image.</param>
        /// <param name="tileY">The y-coordinate of the tile being requested; used for dynamically coloring the image.</param>
        /// <returns></returns>
        protected virtual Image RenderTestImage(int width, int height, int?blockSize, int tileX, int tileY)
        {
            // correct block size
            if (blockSize.GetValueOrDefault(0) < 8)
            {
                blockSize = Math.Max(width, height);
            }

            // set of colors we're working with
            var colors = new[] { Color.Red, Color.Blue, Color.Green, Color.Cyan, Color.Violet, Color.Yellow };

            // determine colors to be used,
            // set up reduced color set

            const int mod    = 64;
            var       color0 = colors[(tileX + tileY) % colors.Length];
            var       color1 = Color.FromArgb(255, Math.Max(0, color0.R - mod), Math.Max(0, color0.G - mod), Math.Max(0, color0.B - mod));
            var       color2 = Color.FromArgb(255, Math.Min(255, color0.R + mod), Math.Min(255, color0.G + mod), Math.Min(255, color0.B + mod));

            colors = new[] { color1, color2 };

            Func <int, int> nextColor = index => (index + 1) % colors.Length;

            var colorStart = 0;
            var colorIndex = 0;

            // create resulting image
            var bmp = new Bitmap(width, height);

            // get graphics object for drawing into the image
            using (var g = Graphics.FromImage(bmp))
                // loop through blocks
                if (blockSize != null)
                {
                    foreach (var block in BlockBuilder.GetBlocks(width, height, blockSize.Value))
                    {
                        // BlockBuilder.GetBlocks returns blocks column-wise
                        // so we use block.y0 == 0 to trigger a color swap
                        if (block.Y0 == 0)
                        {
                            colorStart = nextColor(colorIndex = colorStart);
                        }

                        // render current block
                        g.FillRectangle(new SolidBrush(colors[colorIndex]), block.X0, block.Y0, block.X1 - block.X0 + 1,
                                        block.Y1 - block.Y0 + 1);

                        // next block > next color
                        colorIndex = nextColor(colorIndex);
                    }
                }

            // return image
            return(bmp);
        }