/// <summary>
        /// Handles the socket's DidRead event after reading only the first four bytes of data.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/></param>
        /// <param name="readBytes">Array of <see cref="byte"/>s that were read</param>
        /// <param name="tag">The tag identifying the read operation</param>
        private void SocketDidReadIndicatorBytes(AsyncSocket socket, byte[] readBytes, long tag)
        {
            // remove this event handler since we dont need it any more
            socket.DidRead -= new AsyncSocket.SocketDidRead(this.SocketDidReadIndicatorBytes);

            Data   data = new Data(readBytes);
            string s    = data.ToString();

            if (tag == ACCEPT_TAG)
            {
                if (s == FlashPolicy.REQUEST_INDICATOR)
                {
                    GNTPFlashSocketReader gfsr = new GNTPFlashSocketReader(socket, allowBrowserConnections);
                    gfsr.Read(readBytes);
                }
                else if (s == WebSocketHandshakeHandler.REQUEST_INDICATOR)
                {
                    // this is a GNTP over WebSocket request, so we have to do the WebSocket handshake first
                    socket.Tag = readBytes;
                    WebSocketHandshakeHandler wshh = new WebSocketHandshakeHandler(socket, "*", "ws://localhost:23053");
                    wshh.DoHandshake(delegate()
                    {
                        // now pass off to the GNTPWebSocketReader (which is just a normal GNTPSocketReader that can deal with the WebSocket framing of packets)
                        GNTPWebSocketReader gwsr = new GNTPWebSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                        this.requestReader       = gwsr;
                        gwsr.MessageParsed      += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                        gwsr.Error += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                        gwsr.Read(readBytes);
                    });
                }
                else
                {
                    // this is a normal GNTP/TCP connection, so handle it as such
                    GNTPSocketReader gsr = new GNTPSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                    this.requestReader = gsr;
                    gsr.MessageParsed += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                    gsr.Error         += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                    gsr.Read(readBytes);
                }
            }
            else
            {
                WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST);
            }
        }
        /// <summary>
        /// Handles the socket's DidRead event after reading only the first four bytes of data.
        /// </summary>
        /// <param name="socket">The <see cref="AsyncSocket"/></param>
        /// <param name="readBytes">Array of <see cref="byte"/>s that were read</param>
        /// <param name="tag">The tag identifying the read operation</param>
        private void SocketDidReadIndicatorBytes(AsyncSocket socket, byte[] readBytes, long tag)
        {
            // remove this event handler since we dont need it any more
            socket.DidRead -= new AsyncSocket.SocketDidRead(this.SocketDidReadIndicatorBytes);

            Data data = new Data(readBytes);
            string s = data.ToString();

            if (tag == ACCEPT_TAG)
            {
                if (s == FlashPolicy.REQUEST_INDICATOR)
                {
                    GNTPFlashSocketReader gfsr = new GNTPFlashSocketReader(socket, allowBrowserConnections);
                    gfsr.Read(readBytes);
                }
                else if (s == WebSocketHandshakeHandler.REQUEST_INDICATOR)
                {
                    // this is a GNTP over WebSocket request, so we have to do the WebSocket handshake first
                    socket.Tag = readBytes;
                    WebSocketHandshakeHandler wshh = new WebSocketHandshakeHandler(socket, "*", "ws://localhost:23053");
                    wshh.DoHandshake(delegate()
                    {
                        // now pass off to the GNTPWebSocketReader (which is just a normal GNTPSocketReader that can deal with the WebSocket framing of packets)
                        GNTPWebSocketReader gwsr = new GNTPWebSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                        this.requestReader = gwsr;
                        gwsr.MessageParsed += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                        gwsr.Error += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                        gwsr.Read(readBytes);
                    });
                }
                else
                {
                    // this is a normal GNTP/TCP connection, so handle it as such
                    GNTPSocketReader gsr = new GNTPSocketReader(socket, passwordManager, passwordRequired, allowNetworkNotifications, allowBrowserConnections, allowSubscriptions, this.requestInfo);
                    this.requestReader = gsr;
                    gsr.MessageParsed += new GNTPRequestReader.GNTPRequestReaderMessageParsedEventHandler(requestReader_MessageParsed);
                    gsr.Error += new GNTPRequestReader.GNTPRequestReaderErrorEventHandler(requestReader_Error);
                    gsr.Read(readBytes);
                }
            }
            else
            {
                WriteError(socket, ErrorCode.INVALID_REQUEST, ErrorDescription.MALFORMED_REQUEST);
            }
        }