/// <summary>
            /// Is called when source stream read line reading has completed.
            /// </summary>
            /// <param name="op">Asynchronous operation.</param>
            private void ReadLineCompleted(ReadLineAsyncOP op)
            {
                try{
                    if(op.Error != null){
                        m_pException = op.Error;
                        SetState(AsyncOP_State.Completed);
                    }
                    else{
                        // We have readed all source stream data, we are done.
                        if(op.BytesInBuffer == 0){
                            // Line ends CRLF.
                            if(m_EndsCRLF){
                                m_BytesWritten += 3;
                                m_pOwner.BeginWrite(new byte[]{(byte)'.',(byte)'\r',(byte)'\n'},0,3,this.SendTerminatorCompleted,null);
                            }
                            // Line doesn't end CRLF, we need to add it.
                            else{
                                m_BytesWritten += 5;
                                m_pOwner.BeginWrite(new byte[]{(byte)'\r',(byte)'\n',(byte)'.',(byte)'\r',(byte)'\n'},0,5,this.SendTerminatorCompleted,null);
                            }

                            op.Dispose();
                        }
                        // Write readed line.
                        else{
                            m_BytesWritten += op.BytesInBuffer;

                            // Check if line ends CRLF.
                            if(op.BytesInBuffer >= 2 && op.Buffer[op.BytesInBuffer - 2] == '\r' && op.Buffer[op.BytesInBuffer - 1] == '\n'){
                                m_EndsCRLF = true;
                            }
                            else{
                                m_EndsCRLF = false;
                            }

                            // Period handling. If line starts with period(.), additional period is added.
                            if(op.Buffer[0] == '.'){
                                byte[] buffer = new byte[op.BytesInBuffer + 1];
                                buffer[0] = (byte)'.';
                                Array.Copy(op.Buffer,0,buffer,1,op.BytesInBuffer);

                                m_pOwner.BeginWrite(buffer,0,buffer.Length,this.SendLineCompleted,null);
                            }
                            // Normal line.
                            else{
                                m_pOwner.BeginWrite(op.Buffer,0,op.BytesInBuffer,this.SendLineCompleted,null);
                            }
                        }
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    SetState(AsyncOP_State.Completed);
                    op.Dispose();
                }
            }
            /// <summary>
            /// Starts operation processing.
            /// </summary>
            /// <param name="owner">Owner SmartStream.</param>
            /// <returns>Returns true if asynchronous operation in progress or false if operation completed synchronously.</returns>
            /// <exception cref="ArgumentNullException">Is raised when <b>owner</b> is null reference.</exception>
            internal bool Start(SmartStream owner)
            {
                if(owner == null){
                    throw new ArgumentNullException("owner");
                }

                m_pOwner = owner;

                SetState(AsyncOP_State.Active);

                try{
                    // Read line.
                    m_pReadLineOP = new ReadLineAsyncOP(new byte[32000],SizeExceededAction.ThrowException);
                    m_pReadLineOP.Completed += delegate(object s,EventArgs<ReadLineAsyncOP> e){
                        ReadLineCompleted(m_pReadLineOP);
                    };
                    if(m_pStream.ReadLine(m_pReadLineOP,true)){
                        ReadLineCompleted(m_pReadLineOP);
                    }
                }
                catch(Exception x){
                    m_pException = x;
                    SetState(AsyncOP_State.Completed);
                    m_pReadLineOP.Dispose();
                }

                // Set flag rise CompletedAsync event flag. The event is raised when async op completes.
                // If already completed sync, that flag has no effect.
                lock(m_pLock){
                    m_RiseCompleted = true;

                    return m_State == AsyncOP_State.Active;
                }
            }