public override KeyData[] UnescapeData(Stream inputStream)
        {
            var keys = new List<KeyData>();

            // Read escaped data from input stream.
            int inputByte;
            KeyData outputKey;

            while ((inputByte = inputStream.ReadByte()) != -1)
            {
                if (_bitMode == TerminalBitMode.Mode7Bit)
                {
                    // Check if current byte is start of control sequence.
                    if (inputByte == 0x1b) // ESC
                    {
                        outputKey = DecodeSequence7Bit(inputStream);
                    }
                    else
                    {
                        // Normal char
                        outputKey = new KeyData((byte)inputByte, false);
                    }
                }
                else if (_bitMode == TerminalBitMode.Mode8Bit)
                {
                    // Check if current byte is start of control sequence.
                    outputKey = DecodeSequence8Bit(inputStream);
                }
                else
                {
                    throw new InvalidOperationException("Bit mode is not valid for unescaping data.");
                }

                // Add current byte to output.
                keys.Add(outputKey);
            }

            return keys.ToArray();
        }
        protected void TerminalSendKeys(KeyData[] keys)
        {
            unsafe
            {
                var consoleParams = (ConsoleParams*)_consoleHandler.ConsoleParameters.Get();

                foreach (var key in keys)
                {
                    // Get virtual-key code for key.
                    IntPtr vKey = new IntPtr(key.IsVirtualKey ? key.Value : WinApi.VkKeyScan(
                        (char)key.Value));

                    // Send Key Down and then Key Up messages to console window.
                    WinApi.PostMessage(consoleParams->ConsoleWindowHandle, WinApi.WM_KEYDOWN, vKey,
                        CreateWmKeyDownLParam(1, 0, false, false, 0));
                    WinApi.PostMessage(consoleParams->ConsoleWindowHandle, WinApi.WM_KEYUP, vKey,
                        CreateWmKeyDownLParam(1, 0, false, true, 1));
                }
            }
        }
        protected KeyData DecodeSequence8Bit(Stream inputStream)
        {
            var keyData = new KeyData(0, true);

            // Read control character.
            var controlChar = (byte)inputStream.ReadByte();

            switch (controlChar)
            {
                case 0x9b: // CSI
                    keyData.Value = DecodeControlSequence(inputStream);
                    break;
                default:
                    keyData.Value = controlChar;
                    keyData.IsVirtualKey = false;
                    break;
            }

            return keyData;
        }
        protected KeyData DecodeSequence7Bit(Stream inputStream)
        {
            var keyData = new KeyData(0, true);

            // Read control character.
            var controlChar = (byte)inputStream.ReadByte();

            switch ((char)controlChar)
            {
                case '[': // CSI
                    keyData.Value = DecodeControlSequence(inputStream);
                    break;
                default:
                    XtermHelper.ThrowUnrecognisedCharException("Unrecognised 7-bit control character",
                        controlChar);
                    break;
            }

            return keyData;
        }