private void ParseKeyStrokes(DataSet dsCollector)
        {
            CharStream = "";
            DataTable dtCollector = dsCollector.Tables[0];

            string sampleId = dsCollector.Tables[0].Rows[0].Field<string>("SampleId");
            string securityId = dsCollector.Tables[0].Rows[0].Field<string>("SecurityId");

            StringBuilder output = new StringBuilder();
            int startIndexOffset = 0, cursorPosition = 0;
            byte shiftDown = 0;
            SelectionBounds selection = new SelectionBounds();

            // Extract individual key strokes from each row
            for (int i = 0; i < dtCollector.Rows.Count; i++)
            {

                DataRow row = dtCollector.Rows[i];

                int eve = Convert.ToInt16(row["KeyEvent"]);
                long when = Convert.ToInt64(row["AbsoluteTimestamp"]);
                int vkCode = Convert.ToInt32(row["VkCode"]);
                char keyChar = VkCodeToChar(vkCode, shiftDown != 0);

                if (keyChar != 65535 && eve == 1)
                    CharStream += keyChar;

                if (eve == 1)
                {
                    if (vkCode == 8 || vkCode == 25)
                        cursorPosition--;
                    else
                        cursorPosition++;
                    if (cursorPosition < 0)
                        cursorPosition = 0;
                }
                KeyStroke key;
                key.isKeyPress = eve == 1;
                key.keyChar = keyChar;
                key.keyCode = vkCode;
                key.timestamp = when;
                key.cursorPosition = cursorPosition;

                shiftDown = ProcessKeyStroke(output, startIndexOffset, shiftDown, selection, key);
            }
            FinalText = output.ToString();
        }
        private static byte ProcessKeyStroke(StringBuilder output, int startIndexOffset, byte shiftDown, SelectionBounds selection, KeyStroke k)
        {
            int relativeIndex = k.cursorPosition - startIndexOffset;
            if (relativeIndex < 0)
                relativeIndex = 0;
            if (k.isKeyPress)
            {
                switch (k.keyCode)
                {
                    case VK_BACK: // Backspace
                        if (relativeIndex == 0)
                        {
                            break;
                        }
                        if(output.Length > 0)
                        {
                            if (!selection.isEmpty())
                            {
                                if (selection.start < 0)
                                    selection.start = 0;
                                else if (selection.start >= output.Length)
                                    selection.start = output.Length - 1;

                                if (selection.end < 0)
                                    selection.end = 0;
                                else if (selection.end >= output.Length)
                                    selection.end = output.Length - 1;

                                selection.checkOrder();

                                output.Remove(selection.start, selection.end - selection.start);
                                selection.start = selection.end = -1;
                            }
                            else
                            {
                                if (relativeIndex > output.Length - 1)
                                    relativeIndex = output.Length - 1;
                                output.Remove(relativeIndex, 1);
                            }
                        }
                        break;

                    case VK_SHIFT:
                        shiftDown |= 0x04;
                        if (selection.isActive())
                        { // There is already an active
                            // selection -- hitting select again
                            // shouldn't change anything
                            break;
                        }
                        // selection
                        selection.start = relativeIndex;
                        selection.end = relativeIndex;
                        break;
                    case VK_LSHIFT:
                        shiftDown |= 0x02;
                        if (selection.isActive())
                        { // There is already an active
                            // selection -- hitting select again
                            // shouldn't change anything
                            break;
                        }
                        // selection
                        selection.start = relativeIndex;
                        selection.end = relativeIndex;
                        break;
                    case VK_RSHIFT: // Shift
                        shiftDown |= 0x01;
                        if (selection.isActive())
                        { // There is already an active
                            // selection -- hitting select again
                            // shouldn't change anything
                            break;
                        }
                        // selection
                        selection.start = relativeIndex;
                        selection.end = relativeIndex;
                        break;
                    case VK_DELETE: // Delete
                        if (relativeIndex > output.Length - 1)
                        {
                            break;
                        }
                        if (!selection.isEmpty())
                        {
                            selection.checkOrder();
                            output.Remove(selection.start, selection.end - selection.start);
                        }
                        else
                        {
                            output.Remove(relativeIndex, 1);
                        }
                        selection.start = selection.end = -1;

                        break;
                    case VK_LEFT: // 37: // Arrows
                        if (shiftDown == 0)
                        {
                            // clear the selection, if not currently shifting.
                            selection.start = selection.end = -1;
                        }
                        else if (selection.isActive())
                        {
                            selection.end = relativeIndex - 1;
                        }
                        break;
                    case VK_RIGHT: // 39:
                        if (shiftDown == 0)
                        {
                            // clear the selection, if not currently shifting.
                            selection.start = selection.end = -1;
                        }
                        else if (selection.isActive())
                        {
                            selection.end = relativeIndex + 1;
                        }
                        break;
                    case 38:
                    case 40:
                        if (shiftDown == 0)
                        {
                            // clear the selection, if not currently shifting.
                            selection.start = selection.end = -1;
                        }
                        else if (selection.isActive())
                        {
                            selection.end = relativeIndex;
                        }
                        break;
                    default:
                        if (k.keyChar == 65535)
                        {
                            break;
                        }
                        if (k.keyChar < 9) // nonprinted
                        {
                            break;
                        }
                        if (k.keyChar > 11 && k.keyChar < 13)
                        {
                            break;
                        }
                        if (k.keyChar > 13 && k.keyChar < 32)
                        {
                            break;
                        }
                        // Printable characters
                        if (selection.isActive() && !selection.isEmpty())
                        {
                            selection.checkOrder();
                            if (selection.start < output.Length)
                            {
                                if (selection.end < output.Length)
                                    output.Remove(selection.start, selection.end - selection.start);
                                else
                                    output.Remove(selection.start, output.Length - selection.start);
                            }
                        }
                        if (relativeIndex < 0)
                        {
                            relativeIndex = 0;
                        }
                        if (relativeIndex > output.Length)
                        {
                            relativeIndex = output.Length;
                        }
                        output.Insert(relativeIndex, k.keyChar);
                        // After a printed character the selection is cleared.
                        selection.start = selection.end = -1;
                        break;
                }
            }
            else
            {
                if (k.keyCode == VK_LSHIFT)
                {
                    shiftDown &= 0xFD;
                }
                else if (k.keyCode == VK_SHIFT)
                {
                    shiftDown &= 0xFB;
                }
                else if (k.keyCode == VK_RSHIFT)
                {
                    shiftDown &= 0xFE;
                }
            }
            return shiftDown;
        }