/// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="server">Reference to owner relay server.</param>
        /// <param name="file">Message file to relay.</param>
        /// <param name="relay_retry">If true then first time relay, otherwise retry attempt.</param>
        public Relay_Session(Relay_Server server,string file,bool relay_retry)
        {
            m_pRelayServer = server;
            m_MessageFile  = file;
            m_relay_retry  = relay_retry;

            m_pMessageStream = File.Open(m_MessageFile,FileMode.Open,FileAccess.ReadWrite,FileShare.Read);
            m_pRelayInfo = new RelayInfo(m_pMessageStream,m_pRelayServer.UndeliveredAfter,m_pRelayServer.UndeliveredWarningAfter);
            m_SessionID = Guid.NewGuid().ToString();
            m_SessionStartTime = DateTime.Now;
            m_pSmtpClient = new SmtpClientEx();
            m_pSmtpClient.DnsServers = new string[]{m_pRelayServer.Dns1,m_pRelayServer.Dns2};
            if(m_pRelayServer.LogCommands){
                m_pSmtpClient.SessionLog += new LogEventHandler(OnSMTP_LogPart);
            }

            m_pConnectPoints = new Queue<IPAddress>();
        }
        /// <summary>
        /// Creates undelivered warning for user and places it to relay folder.
        /// </summary>
        /// <param name="relayInfo">Relay info</param>
        /// <param name="error">SMTP returned error text.</param>
        /// <param name="file">Messsage file.</param>
        private void MakeUndeliveredWarning(RelayInfo relayInfo,string error,Stream file)
        {
            try{
                // If sender isn't specified, we can't send warning to sender.
                // Just skip warning sending.
                if(relayInfo.From.Length == 0){
                    return;
                }

                file.Position = relayInfo.MessageStartPos;
                RelayVariablesManager variablesMgr = new RelayVariablesManager(this,error,file);
                file.Position = relayInfo.MessageStartPos;

                ServerReturnMessage messageTemplate = m_pRelayServer.UndeliveredMessage;
                if(messageTemplate == null){
                    string bodyRtf = "" +
                    "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Verdana;}{\\f1\\fnil\\fcharset186 Verdana;}{\\f2\\fswiss\\fcharset186{\\*\\fname Arial;}Arial Baltic;}{\\f3\\fnil\\fcharset0 Microsoft Sans Serif;}}\r\n" +
                    "{\\colortbl ;\\red0\\green64\\blue128;\\red255\\green0\\blue0;\\red0\\green128\\blue0;}\r\n" +
                    "\\viewkind4\\uc1\\pard\\f0\\fs20 This e-mail is generated by the Server(\\cf1 <#relay.hostname>\\cf0 )  to notify you, \\par\r\n" +
                    "\\lang1061\\f1 that \\lang1033\\f0 your message to \\cf1 <#relay.to>\\cf0  dated \\b\\fs16 <#message.header[\"Date:\"]>\\b0  \\fs20 could not be sent at the first attempt.\\par\r\n" +
                    "\\par\r\n" +
                    "Recipient \\i <#relay.to>'\\i0 s Server (\\cf1 <#relay.session_hostname>\\cf0 ) returned the following response: \\cf2 <#relay.error>\\cf0\\par\r\n" +
                    "\\par\r\n" +
                    "\\par\r\n" +
                    "Please note Server will attempt to deliver this message for \\b <#relay.undelivered_after>\\b0  hours.\\par\r\n" +
                    "\\par\r\n" +
                    "--------\\par\r\n" +
                    "\\par\r\n" +
                    "Your original message is attached to this e-mail (\\b data.eml\\b0 )\\par\r\n" +
                    "\\par\r\n" +
                    "\\fs16 The tracking number for this message is \\cf3 <#relay.session_messageid>\\cf0\\fs20\\par\r\n" +
                    "\\lang1061\\f2\\par\r\n" +
                    "\\pard\\lang1033\\f3\\fs17\\par\r\n" +
                    "}\r\n";

                    messageTemplate = new ServerReturnMessage("Delayed delivery notice: <#message.header[\"Subject:\"]>",bodyRtf);
                }

                // Make new message
                Mime m = new Mime();
                MimeEntity mainEntity = m.MainEntity;
                // Force to create From: header field
                mainEntity.From = new AddressList();
                mainEntity.From.Add(new MailboxAddress("postmaster"));
                // Force to create To: header field
                mainEntity.To = new AddressList();
                mainEntity.To.Add(new MailboxAddress(relayInfo.From));
                mainEntity.Subject = variablesMgr.Process(messageTemplate.Subject);
                mainEntity.ContentType = MediaType_enum.Multipart_mixed;

                string rtf = variablesMgr.Process(messageTemplate.BodyTextRtf);

                MimeEntity multipartAlternativeEntity = mainEntity.ChildEntities.Add();
                multipartAlternativeEntity.ContentType = MediaType_enum.Multipart_alternative;

                MimeEntity textEntity = multipartAlternativeEntity.ChildEntities.Add();
                textEntity.ContentType = MediaType_enum.Text_plain;
                textEntity.ContentTransferEncoding = ContentTransferEncoding_enum.QuotedPrintable;
                textEntity.DataText = SCore.RtfToText(rtf);

                MimeEntity htmlEntity = multipartAlternativeEntity.ChildEntities.Add();
                htmlEntity.ContentType = MediaType_enum.Text_html;
                htmlEntity.ContentTransferEncoding = ContentTransferEncoding_enum.QuotedPrintable;
                htmlEntity.DataText = SCore.RtfToHtml(rtf);

                MimeEntity attachmentEntity = mainEntity.ChildEntities.Add();
                attachmentEntity.ContentType = MediaType_enum.Application_octet_stream;
                attachmentEntity.ContentDisposition = ContentDisposition_enum.Attachment;
                attachmentEntity.ContentTransferEncoding = ContentTransferEncoding_enum.Base64;
                attachmentEntity.ContentDisposition_FileName = "data.eml";
                attachmentEntity.DataFromStream(file);

                using(MemoryStream strm = new MemoryStream()){
                    m.ToStream(strm);
                    m_pRelayServer.VirtualServer.ProcessAndStoreMessage("",new string[]{relayInfo.From},strm,null);
                }
            }
            catch(Exception x){
                Error.DumpError(x,new System.Diagnostics.StackTrace());
            }
        }