/// <summary>
        /// This is our ugly Async OnReceive event handler.
        /// This chunks the input stream based on the length of the provided buffer and processes out
        /// as many frames as it can.   It then moves the unprocessed data to the beginning of the buffer.
        /// </summary>
        /// <param name="ar">Our Async State from beginread</param>
        private void OnReceive(IAsyncResult ar)
        {
            WebSocketState _socketState = ar.AsyncState as WebSocketState;

            try
            {
                int bytesRead = _networkContext.Stream.EndRead(ar);
                if (bytesRead == 0)
                {
                    // Do Disconnect
                    _networkContext.Stream.Dispose();
                    _networkContext = null;
                    return;
                }
                _bufferPosition += bytesRead;

                if (_bufferPosition > _bufferLength)
                {
                    // Message too big for chunksize..   not sure how this happened...
                    //Close(string.Empty);
                }

                int  offset                = 0;
                bool headerread            = true;
                int  headerforwardposition = 0;
                while (headerread && offset < bytesRead)
                {
                    if (_socketState.FrameComplete)
                    {
                        WebsocketFrameHeader pheader = WebsocketFrameHeader.ZeroHeader;

                        headerread = WebSocketReader.TryReadHeader(_buffer, offset, _bufferPosition - offset, out pheader,
                                                                   out headerforwardposition);
                        offset += headerforwardposition;

                        if (headerread)
                        {
                            _socketState.FrameComplete = false;
                            if (pheader.PayloadLen > (ulong)_maxPayloadBytes)
                            {
                                Close("Invalid Payload size");

                                return;
                            }
                            if (pheader.PayloadLen > 0)
                            {
                                if ((int)pheader.PayloadLen > _bufferPosition - offset)
                                {
                                    byte[] writebytes = new byte[_bufferPosition - offset];

                                    Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition - offset);
                                    _socketState.ExpectedBytes = (int)pheader.PayloadLen;
                                    _socketState.ReceivedBytes.AddRange(writebytes);
                                    _socketState.Header = pheader; // We need to add the header so that we can unmask it
                                    offset += (int)_bufferPosition - offset;
                                }
                                else
                                {
                                    byte[] writebytes = new byte[pheader.PayloadLen];
                                    Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)pheader.PayloadLen);
                                    WebSocketReader.Mask(pheader.Mask, writebytes);
                                    pheader.IsMasked           = false;
                                    _socketState.FrameComplete = true;
                                    _socketState.ReceivedBytes.AddRange(writebytes);
                                    _socketState.Header = pheader;
                                    offset += (int)pheader.PayloadLen;
                                }
                            }
                            else
                            {
                                pheader.Mask = 0;
                                _socketState.FrameComplete = true;
                                _socketState.Header        = pheader;
                            }

                            if (_socketState.FrameComplete)
                            {
                                ProcessFrame(_socketState);
                                _socketState.Header.SetDefault();
                                _socketState.ReceivedBytes.Clear();
                                _socketState.ExpectedBytes = 0;
                            }
                        }
                    }
                    else
                    {
                        WebsocketFrameHeader frameHeader = _socketState.Header;
                        int bytesleft = _socketState.ExpectedBytes - _socketState.ReceivedBytes.Count;

                        if (bytesleft > _bufferPosition)
                        {
                            byte[] writebytes = new byte[_bufferPosition];

                            Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition);
                            _socketState.ReceivedBytes.AddRange(writebytes);
                            _socketState.Header = frameHeader; // We need to add the header so that we can unmask it
                            offset += (int)_bufferPosition;
                        }
                        else
                        {
                            byte[] writebytes = new byte[_bufferPosition];
                            Buffer.BlockCopy(_buffer, offset, writebytes, 0, (int)_bufferPosition);
                            _socketState.FrameComplete = true;
                            _socketState.ReceivedBytes.AddRange(writebytes);
                            _socketState.Header = frameHeader;
                            offset += (int)_bufferPosition;
                        }
                        if (_socketState.FrameComplete)
                        {
                            ProcessFrame(_socketState);
                            _socketState.Header.SetDefault();
                            _socketState.ReceivedBytes.Clear();
                            _socketState.ExpectedBytes = 0;
                            // do some processing
                        }
                    }
                }
                if (offset > 0)
                {
                    // If the buffer is maxed out..  we can just move the cursor.   Nothing to move to the beginning.
                    if (offset < _buffer.Length)
                    {
                        Buffer.BlockCopy(_buffer, offset, _buffer, 0, _bufferPosition - offset);
                    }
                    _bufferPosition -= offset;
                }
                if (_networkContext.Stream != null && _networkContext.Stream.CanRead && !_closing)
                {
                    _networkContext.Stream.BeginRead(_buffer, _bufferPosition, _bufferLength - _bufferPosition, OnReceive,
                                                     _socketState);
                }
                else
                {
                    // We can't read the stream anymore...
                }
            }
            catch (IOException)
            {
                Close("Undefined Error");
            }
            catch (ObjectDisposedException)
            {
                try
                {
                    Close("Undefined Error");
                }
                catch (Exception)
                {
                    // we don't care
                }
            }
            catch (NullReferenceException)
            {
                // The socket was probably disposed
            }
        }