private static void ListenLoop()
        {
            _stream = _state.workClient.GetStream();
            NquireLog.WriteLine("Acquired network stream.");
            NquireListenerState lastState = ListenerState;
            string lastTouch = "-1";
            string data = string.Empty;

            // Loop to receive all the data sent by the client.
            //while ((i = _stream.Read(_state.buffer, 0, StateObject.BufferSize)) != 0)
            while (ListenerState != NquireListenerState.Closing)
            {
                lastState = ListenerState;

                // A scan or Touch has been sent from the device
                int i = 0;
                if ((i = _stream.Read(_state.buffer, 0, StateObject.BufferSize)) != 0)
                {
                    data = Encoding.ASCII.GetString(_state.buffer, 0, i);

                    // Two first chars of "KT" denotes the device has timed out to Idle
                    if (data.Substring(0, 2) == "KT")
                    {
                        NquireLog.WriteLine("Device timed out to Idle.");
                        ListenerState = NquireListenerState.Idle;
                    }
                    // A first char of "K" denotes a button Touch; the second char (0-9, a-f) denotes the button index / .gif name
                    else if (data.Substring(0, 1) == "K")
                    {
                        lastTouch = data.Substring(1, 1);

                        NquireLog.WriteLine(string.Format("Received Touch: Button {0}", lastTouch));
                        ListenerState = NquireListenerState.JustTouched;
                    }
                    // Otherwise it's a Scan
                    else
                    {
                        NquireInterpreter.Scans.Add(data.ToUpper());

                        NquireLog.WriteLine(string.Format("Received Scan: {0}", data));
                        ListenerState = NquireListenerState.JustScanned;
                    }
                    data = string.Empty;
                }

                switch (ListenerState)
                {
                    case NquireListenerState.JustScanned:
                        /*=========TEST=========
                        //Send back a response to the device
                        NquireLabel testLabel = new NquireLabel();
                        testLabel.nqText = "CRAIG";
                        testLabel.nqGifNamePressed = "1.gif";
                        testLabel.nqGifNameReleased = "1.gif";
                        testLabel.nqAlignment = NquireParamAlign.LEFT_TOP;
                        testLabel.nqFontSize = NquireParamFont.FONT_NORMAL;

                        NquireButton testButton = new NquireButton();
                        testButton.nqGifNameReleased = "1.gif";
                        testButton.nqGifNamePressed = "1.gif";

                        char[] cmd = testLabel.GetNquireString().Concat(testButton.GetNquireString()).ToArray();

                        SendNquireCommand(cmd, true);
                        ListenerState = NquireListenerState.WaitingTouch;
                        */

                        break;

                    case NquireListenerState.JustTouched:
                        if (lastTouch != "-1")
                        {

                            lastTouch = "-1";
                        }
                        break;

                    case NquireListenerState.WaitingTouch:
                        break;

                    case NquireListenerState.WaitingScan:
                        break;

                }

                if (lastState != ListenerState)
                {
                    NquireLog.WriteLine(string.Format("Listener State: {0}", ListenerState.ToString()));
                }

            }

            ListenerState = NquireListenerState.On;
        }
        public static void Disconnect()
        {
            TcpClient clientRef = _state.workClient;
            TcpListener serverRef = _state.workServer;

            clientRef.Close();
            NquireLog.WriteLine("TcpClient closed.");
            serverRef.Stop();
            NquireLog.WriteLine("TcpListener stopped.");

            ListenerState = NquireListenerState.Off;
        }
        private static void ConnectCallback(IAsyncResult ar)
        {
            try
            {
                TcpListener serverRef = (TcpListener)ar.AsyncState;
                _state.workClient = serverRef.EndAcceptTcpClient(ar);

                _connectDone.Set();
                ListenerState = NquireListenerState.Idle;

                NquireLog.WriteLine("Async: finished connecting.");
                NquireLog.WriteLine(string.Format("TcpClient connected to: {0}", IP.ToString() + ":" + Port));

                ListenLoop();
            }
            catch (Exception e)
            {
                ListenerState = NquireListenerState.Off;

                if (e is IOException)
                {
                    // Do nothing - avoids an IOException message being returned
                    // when the connection is terminated.
                }
                else
                {
                    NquireLog.WriteLine("Connection error!");
                    NquireLog.WriteLine(e.HResult.ToString());
                    NquireLog.WriteLine(e.ToString());
                }
            }
        }
        public static void Connect()
        {
            _connectDone.Reset();

            IP = IPAddress.Parse(Properties.Settings.Default.IPAddress);
            Port = int.Parse(Properties.Settings.Default.TCP);

            Client = new TcpClient();
            Server = new TcpListener(IP, Port);

            _state = new StateObject();
            _state.workClient = Client;
            _state.workServer = Server;

            ListenerState = NquireListenerState.On;

            Server.Start();
            NquireLog.WriteLine("TcpListener started.");

            NquireLog.WriteLine("Async: beginning connect...");
            Server.BeginAcceptTcpClient(new AsyncCallback(ConnectCallback), Server);

            _connectDone.WaitOne();
        }