/// <summary>
        /// Reads and parses HTTP response from server.
        /// After return of function HTTP response is read.
        /// </summary>
        /// <param name="inStream">Network stream connected to server.</param>
        /// <param name="defaultKeepAlive">TBD</param>
        /// <returns>CoreResponseData that describes server response.</returns>
        private CoreResponseData ParseHTTPResponse(InputNetworkStreamWrapper inStream, bool defaultKeepAlive)
        {
            // CoreResponseData keeps all the information of the response.
            CoreResponseData ret = new CoreResponseData();
            // maximumHeadersLength is maximum total length of http header. Basically this is amount
            // of memory used for headers.
            int headersLength = m_maxResponseHeadersLen == -1 ? 0x7FFFFFFF : m_maxResponseHeadersLen * 1024;

            ret.m_shouldClose = !defaultKeepAlive;
            // Parse the request line.
            string line = inStream.Read_HTTP_Line(maxHTTPLineLength).Trim();

            // Cutoff white spaces
            int currentOffset = 0;
            for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ;

            // find HTTP version, read http/1.x
            string httpVersionString = line.Substring(0, currentOffset).ToLower();
            if (httpVersionString.Equals("http/1.1"))
            {
                ret.m_version = HttpVersion.Version11;
            }
            else if (httpVersionString.Equals("http/1.0"))
            {
                ret.m_version = HttpVersion.Version10;
            }
            else
            {
                ret.m_status = WebExceptionStatus.ServerProtocolViolation;
                ret.m_exceptionMessage = "Unknown http version: " + httpVersionString;
                return ret;
            }

            //advance to the status code
            for (; currentOffset < line.Length && ' ' == line[currentOffset]; ++currentOffset) ;

            // Read the status code
            int codeStart = currentOffset;
            for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ;
            int statusCode = -1;
            try
            {
                string statusCodeStr =
                    line.Substring(codeStart,
                                    currentOffset - codeStart);
                statusCode = Convert.ToInt32(statusCodeStr);
            }
            catch (Exception e)
            {
                ret.m_status = WebExceptionStatus.ServerProtocolViolation;
                ret.m_exceptionMessage = "Missing status code in HTTP reply";
                ret.m_innerException = e;
                return ret;
            }

            // If we get here - status code should be read.
            ret.m_statusCode = statusCode;

            // Advance to the status message.  The message is optional
            for (; currentOffset < line.Length && ' ' != line[currentOffset]; ++currentOffset) ;
            ret.m_statusDescription = line.Substring(currentOffset);

            ret.m_headers = new WebHeaderCollection(true);
            ret.m_chunked = false;
            ret.m_contentLength = -1;

            while ((line = inStream.Read_HTTP_Header(maxHTTPLineLength)).Length > 0)
            {
                // line.Length is used for the header. Substruct it.
                headersLength -= line.Length;
                // If total length used for header is exceeded, we break
                if (headersLength < 0)
                {
                    ret.m_status = WebExceptionStatus.ServerProtocolViolation;
                    ret.m_exceptionMessage = "Headers size exceed limit";
                    return ret;
                }

                // Now parse the header.
                int sepIdx = line.IndexOf(':');
                if (sepIdx == -1)
                {
                    ret.m_status = WebExceptionStatus.ServerProtocolViolation;
                    ret.m_exceptionMessage = "Illegal header format: " + line;
                    return ret;
                }

                string headerName = line.Substring(0, sepIdx);
                string headerValue = line.Substring(sepIdx + 1).TrimStart(null);
                string matchableHeaderName = headerName.ToLower();

                ret.m_headers.AddInternal(headerName, headerValue);
                if (matchableHeaderName.Equals("content-length"))
                {
                    try
                    {
                        ret.m_contentLength = Convert.ToInt32(headerValue);

                        // set the response stream length for the input stream, so that an EOF will be read
                        // if the caller tries to read base the response content length
                        inStream.m_BytesLeftInResponse = ret.m_contentLength;
                    }
                    catch (Exception e)
                    {
                        ret.m_status =
                            WebExceptionStatus.ServerProtocolViolation;
                        ret.m_exceptionMessage = "Content length NAN: " + headerValue;
                        ret.m_innerException = e;
                        return ret;
                    }
                }
                else if (matchableHeaderName.Equals("transfer-encoding"))
                {
                    if (headerValue.ToLower().IndexOf("chunked") != -1)
                    {
                        ret.m_chunked = true;
                    }
                }
                else if (matchableHeaderName.Equals("connection"))
                {
                    if (headerValue.ToLower().IndexOf(HttpKnownHeaderValues.close) != -1)
                    {
                        ret.m_shouldClose = true;
                    }
                }
            }

            return ret;
        }
        /// <summary>
        /// Parses request from client.
        /// Fills
        /// - HTTP Verb.
        /// - HTTP version.
        /// - Content Length.
        /// - Fills generic value name pair in WEB header collection.
        /// </summary>
        internal void ParseHTTPRequest()
        {
            // This is the request line.
            m_RequestString = m_clientStream.Read_HTTP_Line(HttpWebRequest.maxHTTPLineLength).Trim();

            // Split request line into 3 strings - VERB, URL and HTTP version.
            char[]   delimiter  = { ' ' };
            string[] requestStr = m_RequestString.Split(delimiter);
            // requestStr should consist of 3 parts.
            if (requestStr.Length < 3)
            {
                throw new ProtocolViolationException("Invalid HTTP request String: " + m_RequestString);
            }

            // We have at least 3 strings. Fills the proper fields
            m_requestVerb = requestStr[0];
            m_rawURL      = requestStr[1];

            // Process third string. It should be either http/1.1 or http/1.0
            string httpVerLowerCase = requestStr[2].ToLower();

            if (httpVerLowerCase.Equals("http/1.1"))
            {
                m_requestHttpVer = HttpVersion.Version11;
            }
            else if (httpVerLowerCase.Equals("http/1.0"))
            {
                m_requestHttpVer = HttpVersion.Version10;
            }
            else
            {
                throw new ProtocolViolationException("Unsupported HTTP version: " + requestStr[2]);
            }

            // Now it is list of HTTP headers:
            string line;
            int    headersLen = m_maxResponseHeadersLen;

            while ((line = m_clientStream.Read_HTTP_Header(HttpWebRequest.maxHTTPLineLength)).Length > 0)
            {
                // line.Length is used for the header. Substruct it.
                headersLen -= line.Length;
                // If total length used for header is exceeded, we break

                if (headersLen < 0)
                {
                    throw new ProtocolViolationException("Http Headers exceeding: " + m_maxResponseHeadersLen);
                }

                int sepIdx = line.IndexOf(':');
                if (sepIdx == -1)
                {
                    throw new ProtocolViolationException("Invalid HTTP Header: " + line);
                }

                string headerName          = line.Substring(0, sepIdx).Trim();
                string headerValue         = line.Substring(sepIdx + 1).Trim();
                string matchableHeaderName = headerName.ToLower();
                // Adds new header to collection.
                m_httpRequestHeaders.AddInternal(headerName, headerValue);

                // Now we check the value - name pair. For some of them we need to initilize member variables.
                headerName = headerName.ToLower();
                // If it is connection header
                if (headerName == "connection")
                {
                    // If value is "Keep-Alive" ( lower case now ), set m_KeepAlive to true;
                    headerValue = headerValue.ToLower();
                    m_KeepAlive = headerValue == "keep-alive";
                }

                // If user supplied user name and password - parse it and store in m_NetworkCredentials
                if (headerName == "authorization")
                {
                    int    sepSpace = headerValue.IndexOf(' ');
                    string authType = headerValue.Substring(0, sepSpace);
                    if (authType.ToLower() == "basic")
                    {
                        string authInfo = headerValue.Substring(sepSpace + 1);
                        // authInfo is base64 encoded username and password.
                        byte[] authInfoDecoded = ConvertBase64.FromBase64String(authInfo);
                        char[] authInfoDecChar = System.Text.Encoding.UTF8.GetChars(authInfoDecoded);
                        string strAuthInfo     = new string(authInfoDecChar);
                        // The strAuthInfo comes in format username:password. Parse it.
                        int sepColon = strAuthInfo.IndexOf(':');
                        if (sepColon != -1)
                        {
                            m_NetworkCredentials = new NetworkCredential(strAuthInfo.Substring(0, sepColon), strAuthInfo.Substring(sepColon + 1));
                        }
                    }
                }
            }

            // Http headers were processed. Now we search for content length.
            string strContentLen = m_httpRequestHeaders[HttpKnownHeaderNames.ContentLength];

            if (strContentLen != null)
            {
                try
                {
                    m_contentLength = Convert.ToInt32(strContentLen);
                }
                catch (Exception)
                {
                    throw new ProtocolViolationException("Invalid content length in request: " + strContentLen);
                }
            }
        }