private void Work()
        {
            try
            {
                _Reader = new StreamReader(_Socket.GetStream(), Encoding.UTF8);

                JsonSerializer serializer = JsonSerializer.CreateDefault();

                while (_IsRunning)
                {
                    while (!_Reader.EndOfStream /*&& IsSocketConnected()*/)
                    {
                        string responseJson = _Reader.ReadLine();

                        if (GazeManager.DebugMode)
                        {
                            Debug.WriteLine("IN: " + responseJson);
                        }

                        if (!String.IsNullOrEmpty(responseJson) && null != _ResponseListener)
                        {
                            JsonTextReader jsreader = new JsonTextReader(new StringReader(responseJson));
                            JObject        json     = (JObject)serializer.Deserialize(jsreader);
                            JToken         value;

                            int id = 0;
                            if (json.TryGetValue(Protocol.KEY_ID, out value))
                            {
                                id = (int)value;
                            }

                            //get ongoing request if any
                            IRequest request;
                            _OnGoingRequests.TryRemove(id, out request);

                            //get status code
                            json.TryGetValue(Protocol.KEY_STATUSCODE, out value);

                            ResponseBase response = null;
                            if ((int)value == (int)HttpStatusCode.OK)
                            {
                                if (request != null)
                                {
                                    //matching request handles parsing
                                    response             = (ResponseBase)request.ParseJsonResponse(json);
                                    response.TransitTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - request.TimeStamp;
                                }
                                else
                                {
                                    // Incoming message has no id and is a reponse to a process or a pushed gaze data frame
                                    json.TryGetValue(Protocol.KEY_CATEGORY, out value);

                                    if (value.ToObject <String>().Equals(Protocol.CATEGORY_CALIBRATION))
                                    {
                                        // response is calibration result
                                        response = json.ToObject <CalibrationPointEndResponse>();
                                    }
                                    else if (null != (response = _NetworkLayer.ParseIncomingProcessResponse(json, value)))
                                    {
                                        // We allow the network layer extensions to optionally handle the process reponse
                                    }
                                    else
                                    {
                                        // response is gaze data frame
                                        response = json.ToObject <TrackerGetResponse>();
                                    }
                                }
                            }
                            else
                            {
                                //request failed
                                response          = json.ToObject <ResponseFailed>();
                                response.Category = "";  //we reset category to simplify parsing logic

                                if (request != null)
                                {
                                    response.TransitTime = (DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond) - request.TimeStamp;
                                }
                            }

                            if (GazeManager.DebugMode && null != response && response.TransitTime != 0)
                            {
                                Debug.WriteLine("IN: transitTime " + response.TransitTime);
                            }

                            if (null != _ResponseListener)
                            {
                                _ResponseListener.OnGazeApiResponse(response, request);
                            }
                        }
                    }
                }
            }
            catch (ThreadInterruptedException tie)
            {
                Debug.WriteLine("Incoming stream handler interrupted: " + tie.Message);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Exception while establishing incoming socket connection: " + e.Message);

                if (GazeManager.DebugMode)
                {
                    Debug.WriteLine(e.StackTrace);
                }
            }
            finally
            {
                if (null != _Reader)
                {
                    _Reader.Close();
                }

                //connection has been lost
                _NetworkLayer.Close();
            }

            if (GazeManager.DebugMode)
            {
                Debug.WriteLine("IncommingStreamHandler closing down");
            }
        }