InStream - indicates an exception was caught
            internally due to a stream error, and that I/O
            operations should not continue

            Input: Nothing.

            Returns: True if there is an error

         --*/

        internal bool ErrorInStream {
            get {
                return m_ErrorException!=null;
            }
        }

        /*++

            CallDone - calls out to the Connection that spawned this
            Stream (using the DoneRead/DoneWrite method).
            If the Connection specified that we don't need to
            do this, or if we've already done this already, then
            we return silently.

            Input: Nothing.

            Returns: Nothing.

         --*/
        internal void CallDone()
        {
            CallDone(null);
        }
        private void CallDone(ConnectionReturnResult returnResult)
        {
            GlobalLog.Enter("ConnectStream#" + ValidationHelper.HashString(this) + "::CallDone");
            if ( Interlocked.Increment( ref m_DoneCalled) == 1 )
            {
                if (!WriteStream)
                {
#if DEBUG
                    GlobalLog.DebugRemoveRequest(m_Request);
#endif
                    if (returnResult == null) {
                        //readstartnextrequest will call setresponses internally.

                        if (m_Chunked)
                        {
                            int leftoverBufferOffset;
                            int leftoverBufferSize;
                            byte[] leftoverBuffer;

                            if (m_ChunkParser.TryGetLeftoverBytes(out leftoverBuffer, out leftoverBufferOffset, 
                                out leftoverBufferSize))
                            {
                                m_Connection.SetLeftoverBytes(leftoverBuffer, leftoverBufferOffset, leftoverBufferSize);
                            }
                        }
                        m_Connection.ReadStartNextRequest(m_Request, ref returnResult);
                    }
                    else{
                        ConnectionReturnResult.SetResponses(returnResult);
                    }
                }
                else
                {
                    m_Request.WriteCallDone(this, returnResult);
                }
            }
            GlobalLog.Leave("ConnectStream#" + ValidationHelper.HashString(this) + "::CallDone");
        }

        internal void ProcessWriteCallDone(ConnectionReturnResult returnResult)
        {
            GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ProcessWriteCallDone()");

            try {
                if (returnResult == null) {
                    m_Connection.WriteStartNextRequest(m_Request, ref returnResult);

                    // If the request is Sync, then we do our Read here for data
                    if (!m_Request.Async)
                    {
                        object syncReaderResult = m_Request.ConnectionReaderAsyncResult.InternalWaitForCompletion();

                        //we should only do a syncread if we didn't already read the response
                        //via poll when we handed back the request stream
                        if (syncReaderResult == null && m_Request.NeedsToReadForResponse)
#if DEBUG
                            // Remove once mixed sync/async requests are supported.
                            using (GlobalLog.SetThreadKind(ThreadKinds.Sync))
#endif
                        {
                            m_Connection.SyncRead(m_Request, true, false);
                        }
                    }

                    m_Request.NeedsToReadForResponse = true;
                }

                ConnectionReturnResult.SetResponses(returnResult);
            }
            finally {
                // This will decrement the response window on the write side AND may
                // result in either immediate or delayed processing of a response for the m_Request instance
                if (IsPostStream || m_Request.Async)
                    m_Request.CheckWriteSideResponseProcessing();
            }
        }

        internal bool IsClosed {
            get {
                return m_ShutDown!= 0;
            }
        }

        /*++

            Read property for this class. We return the readability of
            this stream. This is a read only property.

            Input: Nothing.

            Returns: True if this is a read stream, false otherwise.

         --*/

        public override bool CanRead {
            get {
                return!WriteStream &&!IsClosed;
            }
        }

        /*++

            Seek property for this class. Since this stream is not
            seekable, we just return false. This is a read only property.

            Input: Nothing.

            Returns: false

         --*/

        public override bool CanSeek {
            get {
                return false;
            }
        }

        /*++

            CanWrite property for this class. We return the writeability of
            this stream. This is a read only property.

            Input: Nothing.

            Returns: True if this is a write stream, false otherwise.

         --*/

        public override bool CanWrite {
            get {
                return WriteStream &&!IsClosed;
            }
        }


        /*++

            Length property for this class. Since we don't support seeking,
            this property just throws a NotSupportedException.

            Input: Nothing.

            Returns: Throws exception.

         --*/

        public override long Length {
            get {
                throw new NotSupportedException(SR.GetString(SR.net_noseek));
            }
        }

        /*++

            Position property for this class. Since we don't support seeking,
            this property just throws a NotSupportedException.

            Input: Nothing.

            Returns: Throws exception.

         --*/

        public override long Position {
            get {
                throw new NotSupportedException(SR.GetString(SR.net_noseek));
            }

            set {
                throw new NotSupportedException(SR.GetString(SR.net_noseek));
            }
        }


        /*++

            Eof property to indicate when the read is no longer allowed,
            because all data has been already read from socket.

            Input: Nothing.

            Returns: true/false depending on whether we are complete

         --*/

        internal bool Eof {
            get {
                if (ErrorInStream) {
                    return true;
                }
                else if (m_Chunked) {
                    return m_ChunkEofRecvd;
                }
                else if (m_ReadBytes == 0) {
                    return true;
                }
                else if (m_ReadBytes == -1) {
                    return(m_DoneCalled > 0 && m_ReadBufferSize <= 0);
                }
                else {
                    return false;
                }
            }
        }

        /*++
            Uses an old Stream to resubmit buffered data using the current
             stream, this is used in cases of POST, or authentication,
             where we need to buffer upload data so that it can be resubmitted

            Input:

                OldStream - Old Stream that was previously used

            Returns:

                Nothing.

        --*/

        // 
        internal void ResubmitWrite(ConnectStream oldStream, bool suppressWrite) {
            GlobalLog.Enter("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite", ValidationHelper.HashString(oldStream));
            GlobalLog.ThreadContract(ThreadKinds.Sync, "ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite");

            //
            // 




            //
            // we're going to resubmit
            //
            try {
                Interlocked.CompareExchange(ref m_CallNesting, Nesting.InternalIO, Nesting.Idle);
                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite() Inc: " + m_CallNesting.ToString());

                GlobalLog.Print("ConnectStream#" + ValidationHelper.HashString(this) + "::ResubmitWrite(), callNesting : " + m_CallNesting.ToString() + " IsClosed = " + IsClosed);
                //
                // no need to buffer here:
                // we're already resubmitting buffered data give it to the connection to put it on the wire again
                // we set BytesLeftToWrite to 0 'cause even on failure there can be no recovery,
                // so just leave it to IOError() to clean up and don't call ResubmitWrite()
                //
                ScatterGatherBuffers bufferedData = oldStream.BufferedData;
                SafeSetSocketTimeout(SocketShutdown.Send);
                if (!WriteChunked) {
                    if (!suppressWrite)
                        m_Connection.Write(bufferedData);
                }
                else {
                    // we have the data buffered, but we still want to chunk.

                    // first set this to disable Close() from sending a chunk terminator.
                    GlobalLog.Assert(m_HttpWriteMode!= HttpWriteMode.None, "ConnectStream#{0}::Resubmit