private void IHave(string argsText)
        {
            /* Rfc 977 3.4.1
                IHAVE <messageid>

                Responses:
                            235 article transferred ok
                            335 send article to be transferred.  End with <CR-LF>.<CR-LF>
                            435 article not wanted - do not send it
                            436 transfer failed - try again later
                            437 article rejected - do not try again

                The IHAVE command informs the server that the client has an article
                whose id is <messageid>.  If the server desires a copy of that
                article, it will return a response instructing the client to send the
                entire article.  If the server does not want the article (if, for
                example, the server already has a copy of it), a response indicating
                that the article is not wanted will be returned.

                If transmission of the article is requested, the client should send
                the entire article, including header and body, in the manner
                specified for text transmission from the server. A response code
                indicating success or failure of the transferral of the article will
                be returned.

                This function differs from the POST command in that it is intended
                for use in transferring already-posted articles between hosts.
                Normally it will not be used when the client is a personal
                newsreading program.  In particular, this function will invoke the
                server's news posting program with the appropriate settings (flags,
                options, etc) to indicate that the forthcoming article is being
                forwarded from another host.

                The server may, however, elect not to post or forward the article if
                after further examination of the article it deems it inappropriate to
                do so.  The 436 or 437 error codes may be returned as appropriate to
                the situation.

                Reasons for such subsequent rejection of an article may include such
                problems as inappropriate newsgroups or distributions, disk space
                limitations, article lengths, garbled headers, and the like.  These
                are typically restrictions enforced by the server host's news
                software and not necessarily the NNTP server itself.
            */

            //must this check in all newsgroups???
            if(m_pArticles == null)
            {
                NNTP_Articles_eArgs args = m_pNNTP_Server.OnGetXOVER(this,this.m_SelectedNewsGroup);
                m_pArticles = new NNTP_Articles();
                m_pArticles = args.Articles;
            }

            if(m_pArticles[argsText] == null)
            {
                SendData("335 send article to be transferred.  End with <CR-LF>.<CR-LF>\r\n");

                MemoryStream reply = null;
                ReadReplyCode replyCode = Core.ReadData(m_pClientSocket,out reply,null,m_pNNTP_Server.MaxMessageSize,m_pNNTP_Server.CommandIdleTimeOut,"\r\n.\r\n",".\r\n");
                if(replyCode == ReadReplyCode.Ok)
                {
                    long recivedCount = reply.Length;
                    //------- Do period handling and raise store event  --------//
                    // If line starts with '.', mail client adds additional '.',
                    // remove them.
                    using(MemoryStream msgStream = Core.DoPeriodHandling(reply,false))
                          {
                        reply.Close();
                        // get list of newsgroups to post to
                        string[] newsgroups = HeaderParser.ParseHeaderFields("Newsgroups:",msgStream.ToArray()).Split(Convert.ToChar(","));
                        //get all the necessary headers
                        HeaderParser hp = new HeaderParser(msgStream.ToArray());
                        string   msgId   = m_pNNTP_Server.OnStoreArticle(this,msgStream,newsgroups);
                        string   subject = hp.Subject;
                        string   from    = hp.From;
                        string   date    = hp.MessageDate.ToString("r",System.Globalization.DateTimeFormatInfo.InvariantInfo);
                        string   refs    = hp.References;
                        string   lines   = hp.Lines;
                        //Add msg to current article list

                        if(m_pNNTP_Server.LogCommands)
                        {
                            m_pLogWriter.AddEntry("big binary " + recivedCount.ToString() + " bytes" + "",this.SessionID,m_ConnectedIp,"S");
                        }

                        SendData("240 Article posted successfully.\r\n");
                    }
                    //----------------------------------------------------------//

                }
                else
                {
                    if(replyCode == ReadReplyCode.LengthExceeded)
                    {
                        SendData("441 Requested action aborted: exceeded storage allocation\r\n");
                    }
                    else
                    {
                        SendData("441 Error message not terminated with '.'\r\n");
                    }
                }
            }
            else
            {
                SendData("435 article not wanted - do not send it\r\n");
            }
        }
        private void Stat(string argsText)
        {
            /* Rfc 977 3.1.2
                STAT <message-id> or [nnn]

                Responses:
                            220 n <a> article retrieved - head and body follow
                                (n = article number, <a> = message-id)
                            221 n <a> article retrieved - head follows
                            222 n <a> article retrieved - body follows
                            223 n <a> article retrieved - request text separately
                            412 no newsgroup has been selected
                            420 no current article has been selected
                            423 no such article number in this group
                            430 no such article found

                The STAT command is similar to the ARTICLE command except that no
                text is returned.  When selecting by message number within a group,
                the STAT command serves to set the current article pointer without
                sending text. The returned acknowledgement response will contain the
                message-id, which may be of some value.  Using the STAT command to
                select by message-id is valid but of questionable value, since a
                selection by message-id does NOT alter the "current article pointer".

            */

            if(argsText == "")
            {
                argsText = m_CurrentArticle.ToString();
            }
            else
            {
                if(NNTP_API.IsNumeric(argsText))
                {
                    m_CurrentArticle = Convert.ToInt32(argsText);
                }
            }

            if(m_SelectedNewsGroup.Length == 0)
            {
                SendData("412 no newsgroup selected\r\n");
                return;
            }

            string article = m_pNNTP_Server.OnGetArticle(this,argsText);
            if(article != "")
            {
                HeaderParser hp = new HeaderParser(System.Text.Encoding.ASCII.GetBytes(article));
                SendData("223 " + argsText + " " + hp.MessageID + " article retrieved\r\n");
            }
            else
            {
                SendData("430 no such article found\r\n");
            }
        }
        /// <summary>
        /// Gets new article info for newsgroups.
        /// </summary>
        public void GetNewNews(string groups,DateTime since,NNTP_Articles articles)
        {
            byte[] fileData       = null;
            int    msgNo          = 1;
            Hashtable files       = new Hashtable();

            NNTP_NewsGroups newsgroups = ParseNewsGroups(groups);

            foreach(NNTP_NewsGroup group in newsgroups.Newsgroups)
            {

                string groupPath = group.Name.Replace(".","\\");
                string path = m_NNTPStorePath + "groups\\" + groupPath;
                if(!Directory.Exists(path)){
                    Directory.CreateDirectory(path);
                    AddGroup(group.Name);
                }
                string[] articls = Directory.GetFiles(path,"*.txt");

                foreach(string articl in articls)
                {
                    using(FileStream fs = File.OpenRead(articl))
                    {
                        fileData = new byte[fs.Length];
                        fs.Read(fileData,0,(int)fs.Length);
                    }
                    HeaderParser hp = new HeaderParser(fileData);
                    msgNo = Convert.ToInt32(Path.GetFileNameWithoutExtension(articl).Substring(0,Path.GetFileNameWithoutExtension(articl).IndexOf("_")));
                    string date = hp.MessageDate.ToString();

                    if(Convert.ToDateTime(date).CompareTo(since) > 0)
                    {
                        articles.Add(hp.MessageID,msgNo,hp.Subject,hp.From,date,hp.References,hp.Lines,fileData.Length.ToString());
                    }
                }
            }
        }
        private void Post()
        {
            /* Rfc 977 3.10.1
                Responses:
                            240 article posted ok
                            340 send article to be posted. End with <CR-LF>.<CR-LF>
                            440 posting not allowed
                            441 posting failed

                If posting is allowed, response code 340 is returned to indicate that
                the article to be posted should be sent. Response code 440 indicates
                that posting is prohibited for some installation-dependent reason.

                If posting is permitted, the article should be presented in the
                format specified by RFC850, and should include all required header
                lines. After the article's header and body have been completely sent
                by the client to the server, a further response code will be returned
                to indicate success or failure of the posting attempt.

                The text forming the header and body of the message to be posted
                should be sent by the client using the conventions for text received
                from the news server:  A single period (".") on a line indicates the
                end of the text, with lines starting with a period in the original
                text having that period doubled during transmission.

                No attempt shall be made by the server to filter characters, fold or
                limit lines, or otherwise process incoming text.  It is our intent
                that the server just pass the incoming message to be posted to the
                server installation's news posting software, which is separate from
                this specification.  See RFC850 for more details.

                Since most installations will want the client news program to allow
                the user to prepare his message using some sort of text editor, and
                transmit it to the server for posting only after it is composed, the
                client program should take note of the herald message that greeted it
                when the connection was first established. This message indicates
                whether postings from that client are permitted or not, and can be
                used to caution the user that his access is read-only if that is the
                case. This will prevent the user from wasting a good deal of time
                composing a message only to find posting of the message was denied.
                The method and determination of which clients and hosts may post is
                installation dependent and is not covered by this specification.

                Example:
                            C: POST
                            S: 340 Continue posting; Period on a line by itself to end
                            C: (transmits news article in RFC850 format)
                            C: .
                            S: 240 Article posted successfully.
            */

            SendData("340 Continue posting; Period on a line by itself to end\r\n");

            // Read message
            MemoryStream reply = null;
            ReadReplyCode replyCode = Core.ReadData(m_pClientSocket,out reply,null,m_pNNTP_Server.MaxMessageSize,m_pNNTP_Server.CommandIdleTimeOut,"\r\n.\r\n",".\r\n");
            if(replyCode == ReadReplyCode.Ok){
                long recivedCount = reply.Length;
                //------- Do period handling and raise store event  --------//
                // If line starts with '.', mail client adds additional '.',
                // remove them.
                using(MemoryStream msgStream = Core.DoPeriodHandling(reply,false)){
                    reply.Close();
                    // get list of newsgroups to post to
                    string[] newsgroups = HeaderParser.ParseHeaderFields("Newsgroups:",msgStream.ToArray()).Split(Convert.ToChar(","));
                    //get all the necessary headers
                    HeaderParser hp = new HeaderParser(msgStream.ToArray());
                    string   msgId   = m_pNNTP_Server.OnStoreArticle(this,msgStream,newsgroups);
                    string   subject = hp.Subject;
                    string   from    = hp.From;
                    string   date    = hp.MessageDate.ToString("r",System.Globalization.DateTimeFormatInfo.InvariantInfo);
                    string   refs    = hp.References;
                    string   lines   = hp.Lines;
                    //Add msg to current article list

                    if(m_pNNTP_Server.LogCommands){
                        m_pLogWriter.AddEntry("big binary " + recivedCount.ToString() + " bytes" + "",this.SessionID,m_ConnectedIp,"S");
                    }

                    SendData("240 Article posted successfully.\r\n");
                }
                //----------------------------------------------------------//

            }
            else{
                if(replyCode == ReadReplyCode.LengthExceeded){
                    SendData("441 Requested action aborted: exceeded storage allocation\r\n");
                }
                else{
                    SendData("441 Error message not terminated with '.'\r\n");
                }
            }
        }
        /// <summary>
        /// Gets article info for a newsgroup.
        /// </summary>
        public void GetArticles(string group,NNTP_Articles articles)
        {
            byte[] fileData       = null;
            int    msgNo          = 1;
            Hashtable files       = new Hashtable();
            group = group.Replace(".","\\");
            string path = m_NNTPStorePath + "groups\\" + group;
            if(!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
                AddGroup(group);
            }
            string[] articls = Directory.GetFiles(path,"*.txt");

            foreach(string articl in articls)
            {
                using(FileStream fs = File.OpenRead(articl))
                {
                    fileData = new byte[fs.Length];
                    fs.Read(fileData,0,(int)fs.Length);
                }
                HeaderParser hp = new HeaderParser(fileData);
                msgNo = Convert.ToInt32(Path.GetFileNameWithoutExtension(articl).Substring(0,Path.GetFileNameWithoutExtension(articl).IndexOf("_")));
                string date = hp.MessageDate.ToString();
                articles.Add(msgNo,hp.MessageID,hp.Subject,hp.From,date,hp.References,hp.Lines,fileData.Length.ToString());

            }
        }