/// <summary>
        /// Reads cell matrix form the output buffer using the provided rectangle.
        /// </summary>
        /// <param name="region"></param>
        /// <returns></returns>
        public CellBuffer ReadOutput(Region region)
        {
            var handle = GetOutputBuffer();

            //Get len of X coordinate, the plan here is to partition by Y
            var sizeOfX = (region.Width - region.Left + 1) * 4;

            //partition by Y coordinate.
            var partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX));

            int sizeOfY = (region.Height - region.Top);

            //if Y is smaller then the partition by Y then we need
            //to set the partiton size to Y size.
            if (sizeOfY < partitionY)
            {
                partitionY = sizeOfY;
            }

            ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD();
            bufferCoord.X = 0;
            bufferCoord.Y = 0;

            ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD();
            bufferSize.X = (short)(region.Width - region.Left);

            CellBuffer cells = new CellBuffer(sizeOfY, bufferSize.X);

            int cursor = 0;
            int i      = 0;

            do
            {
                i += partitionY;

                //the size of the Y coordinate is always the size of the buffer.
                bufferSize.X = (short)(region.Width - region.Left);
                bufferSize.Y = (short)partitionY;

                //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer.
                if (i > sizeOfY)
                {
                    int diff = i - sizeOfY;
                    bufferSize.Y = (short)(partitionY - diff);
                }

                //Fill the buffer part.
                ConsoleHostNativeMethods.SMALL_RECT readRegion = new ConsoleHostNativeMethods.SMALL_RECT();

                readRegion.Left   = (short)region.Left;
                readRegion.Top    = (short)region.Top;
                readRegion.Right  = (short)(region.Left + bufferSize.X);
                readRegion.Bottom = (short)(region.Top + bufferSize.Y);

                ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[bufferSize.X * bufferSize.Y];
                buffer = DotConsoleNative.ReadConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref readRegion);

                //Fill the output buffer cells.
                int idx = 0;
                for (int k = cursor; k < bufferSize.Y; k++)
                {
                    for (int n = 0; n < bufferSize.X; n++)
                    {
                        cells.Cells[k, n].Attributes = buffer[idx].Attributes;
                        cells.Cells[k, n].Char       = buffer[idx].UnicodeChar;
                        idx++;
                    }
                    cursor = k;
                }
            }while (i < sizeOfY);

            return(cells);
        }
        public void WriteOutput(Coordinates orgin, CellBuffer cellBuffer)
        {
            var handle = GetOutputBuffer();

            //Get len of X coordinate, the plan here is to partition by Y
            var sizeOfX = cellBuffer.GetLengthOfX() * 4;

            //partition by Y coordinate.
            int partitionY = (int)Math.Ceiling((decimal)(maxBufferSize / sizeOfX));

            var sizeOfY = cellBuffer.GetLengthOfY();

            //if Y is smaller then the partition by Y then we need
            //to set the partiton size to Y size.
            if (sizeOfY < partitionY)
            {
                partitionY = sizeOfY;
            }

            //Get partitoned buffer size.
            int charBufferSize = (int)(partitionY * cellBuffer.GetLengthOfX());

            int cursor = 0;
            int i      = 0;

            do
            {
                i += partitionY;

                //If we exceeded the maximum size of the buffer we need to substract to the size of the remaining buffer.
                if (i > sizeOfY)
                {
                    int diff = i - sizeOfY;
                    i = i - diff;
                }

                //Fill the buffer part.
                ConsoleHostNativeMethods.CHAR_INFO[] buffer = new ConsoleHostNativeMethods.CHAR_INFO[charBufferSize];
                int idx = 0;
                for (int y = cursor; y < i; y++)
                {
                    for (int x = 0; x < cellBuffer.GetLengthOfX(); x++)
                    {
                        var cellToWrite = cellBuffer[y, x];

                        if (cellToWrite.Attributes == 0)
                        {
                            //Don't set the foreground color for empty cells this will force the ConsoleHost
                            //to do a very expensive calculation for each cell and slow things down.
                            cellToWrite.Attributes = (ushort)DotConsoleNative.ToNativeConsoleColor(0, BackgroundColor);
                        }

                        buffer[idx].Attributes  = cellToWrite.Attributes;
                        buffer[idx].UnicodeChar = cellToWrite.Char;
                        idx++;
                    }
                }

                ConsoleHostNativeMethods.COORD bufferSize = new ConsoleHostNativeMethods.COORD();
                bufferSize.X = (short)cellBuffer.GetLengthOfX();
                bufferSize.Y = (short)partitionY;

                ConsoleHostNativeMethods.COORD bufferCoord = new ConsoleHostNativeMethods.COORD();
                bufferCoord.X = 0;
                bufferCoord.Y = 0;

                ConsoleHostNativeMethods.SMALL_RECT writeRegion = new ConsoleHostNativeMethods.SMALL_RECT();
                writeRegion.Left   = (short)orgin.X;
                writeRegion.Top    = (short)(orgin.Y + cursor);
                writeRegion.Right  = (short)(orgin.X + bufferSize.X);
                writeRegion.Bottom = (short)(orgin.Y + cursor + bufferSize.Y);

                DotConsoleNative.WriteConsoleOutput(handle, buffer, bufferSize, bufferCoord, ref writeRegion);

                cursor = i;
            }while (i < sizeOfY);
        }