给 OpenPOP.Net 加一个小功能,可用于收取邮件时监测数据流量!

/*
最近写了一个自动收邮件的机器人,原来一开始偷懒"娶"了 COM 组件 JMail:
封装 JMail 4.4 的 POP3 为 .Net 组件 (.dll 程序集),实现 "邮件(附件) 到达" 等 "事件"!
后来经人介绍认识了 OpenPOP.Net
我就移情别恋,再后来我们就相爱了,再后来我就修理她:
加一个小功能(红色字体代码部分),可用于收取邮件时监测数据流量!

老规矩: 我的代码随便 Copy & Paste 到任意一个 .cs 文件中 csc 即可测试! (结构不够清晰
,目的就是方便测试代码)

*/
//OpenPOP.Net
namespace OpenPOP.MIMEParser
{
 using System;
 using System.IO;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Collections;
 using System.Globalization;

 ///


 /// Summary description for Attachment.
 ///

 public class Attachment : IComparable
 {
  #region Member Variables

  private string _contentType = null;
  private string _contentCharset = null;
  private string _contentFormat = null;
  private string _contentTransferEncoding = null;
  private string _contentDescription = null;
  private string _contentDisposition = null;
  private string _contentFileName = "";
  private string _defaultFileName = "body.htm";
  private string _defaultFileName2 = "body*.htm";
  private string _defaultReportFileName = "report.htm";
  private string _defaultMIMEFileName = "body.eml";
  private string _defaultMSTNEFFileName = "winmail.dat";
  private string _contentID = null;
  private long _contentLength = 0;
  private string _rawAttachment = null;
  private bool _inBytes = false;
  private byte[] _rawBytes = null;

  #endregion

  #region Properties

  ///


  /// raw attachment content bytes
  ///

  public byte[] RawBytes
  {
   get
   {
    return _rawBytes;
   }
   set
   {
    _rawBytes = value;
   }
  }

  ///


  /// whether attachment is in bytes
  ///

  public bool InBytes
  {
   get
   {
    return _inBytes;
   }
   set
   {
    _inBytes = value;
   }
  }

  ///


  /// Content length
  ///

  public long ContentLength
  {
   get
   {
    return _contentLength;
   }
  }

  ///


  /// verify the attachment whether it is a real attachment or not
  ///

  /// this is so far not comprehensive and needs more work to finish
  public bool NotAttachment
  {
   get
   {
    /*    if (_contentDisposition==null||_contentType==null)
         return true;
        else
         return (_contentDisposition.IndexOf("attachment")==-1 && _contentType.IndexOf("text/plain")!=-1); */
    /*    if (_contentType==null)
         return true;
        else
         return (_contentFileName!="");*/
    if ((_contentType == null || _contentFileName == "") && _contentID == null) //&&_contentType.ToLower().IndexOf("text/")!=-1)
     return true;
    else
     return false;

   }
  }

  ///


  /// Content format
  ///

  public string ContentFormat
  {
   get
   {
    return _contentFormat;
   }
  }

  ///


  /// Content charset
  ///

  public string ContentCharset
  {
   get
   {
    return _contentCharset;
   }
  }

  ///


  /// default file name
  ///

  public string DefaultFileName
  {
   get
   {
    return _defaultFileName;
   }
   set
   {
    _defaultFileName = value;
   }
  }

  ///


  /// default file name 2
  ///

  public string DefaultFileName2
  {
   get
   {
    return _defaultFileName2;
   }
   set
   {
    _defaultFileName2 = value;
   }
  }

  ///


  /// default report file name
  ///

  public string DefaultReportFileName
  {
   get
   {
    return _defaultReportFileName;
   }
   set
   {
    _defaultReportFileName = value;
   }
  }

  ///


  /// default MIME File Name
  ///

  public string DefaultMIMEFileName
  {
   get
   {
    return _defaultMIMEFileName;
   }
   set
   {
    _defaultMIMEFileName = value;
   }
  }

  ///


  /// Content Type
  ///

  public string ContentType
  {
   get
   {
    return _contentType;
   }
  }

  ///


  /// Content Transfer Encoding
  ///

  public string ContentTransferEncoding
  {
   get
   {
    return _contentTransferEncoding;
   }
  }

  ///


  /// Content Description
  ///

  public string ContentDescription
  {
   get
   {
    return _contentDescription;
   }
  }

  ///


  /// Content File Name
  ///

  public string ContentFileName
  {
   get
   {
    return _contentFileName;
   }
   set
   {
    _contentFileName = value;
   }
  }

  ///


  /// Content Disposition
  ///

  public string ContentDisposition
  {
   get
   {
    return _contentDisposition;
   }
  }

  ///


  /// Content ID
  ///

  public string ContentID
  {
   get
   {
    return _contentID;
   }
  }

  ///


  /// Raw Attachment
  ///

  public string RawAttachment
  {
   get
   {
    return _rawAttachment;
   }
  }

  ///


  /// decoded attachment in bytes
  ///

  public byte[] DecodedAttachment
  {
   get
   {
    return DecodedAsBytes();
   }
  }

  #endregion

  ///


  /// release all objects
  ///

  ~Attachment()
  {
   _rawBytes = null;
   _rawAttachment = null;
  }

  ///


  /// New Attachment
  ///

  /// attachment bytes content
  /// file length
  /// file name
  /// content type
  public Attachment(byte[] bytAttachment, long lngFileLength, string strFileName, string strContentType)
  {
   _inBytes = true;
   _rawBytes = bytAttachment;
   _contentLength = lngFileLength;
   _contentFileName = strFileName;
   _contentType = strContentType;
  }

  ///


  /// New Attachment
  ///

  /// attachment bytes content
  /// file name
  /// content type
  public Attachment(byte[] bytAttachment, string strFileName, string strContentType)
  {
   _inBytes = true;
   _rawBytes = bytAttachment;
   _contentLength = bytAttachment.Length;
   _contentFileName = strFileName;
   _contentType = strContentType;
  }

  ///


  /// New Attachment
  ///

  /// attachment content
  /// content type
  /// whether only parse the header or not
  public Attachment(string strAttachment, string strContentType, bool blnParseHeader)
  {
   if (!blnParseHeader)
   {
    _contentFileName = _defaultMSTNEFFileName;
    _contentType = strContentType;
   }
   this.NewAttachment(strAttachment, blnParseHeader);
  }

  ///


  /// New Attachment
  ///

  /// attachment content
  public Attachment(string strAttachment)
  {
   this.NewAttachment(strAttachment, true);
  }

  ///


  /// create attachment
  ///

  /// raw attachment text
  /// parse header
  private void NewAttachment(string strAttachment, bool blnParseHeader)
  {
   _inBytes = false;

   if (strAttachment == null)
    throw new ArgumentNullException("strAttachment");

   StringReader srReader = new StringReader(strAttachment);

   if (blnParseHeader)
   {
    string strLine = srReader.ReadLine();
    while (Utility.IsNotNullTextEx(strLine))
    {
     ParseHeader(srReader, ref strLine);
     if (Utility.IsOrNullTextEx(strLine))
      break;
     else
      strLine = srReader.ReadLine();
    }
   }

   this._rawAttachment = srReader.ReadToEnd();
   _contentLength = this._rawAttachment.Length;
  }

  ///


  /// Parse header fields and set member variables
  ///

  /// string reader
  /// header line
  private void ParseHeader(StringReader srReader, ref string strLine)
  {
   string[] array = Utility.GetHeadersValue(strLine); //Regex.Split(strLine,":");
   string[] values = Regex.Split(array[1], ";"); //array[1].Split(';');
   string strRet = null;

   switch (array[0].ToUpper())
   {
    case "CONTENT-TYPE":
     if (values.Length > 0)
      _contentType = values[0].Trim();
     if (values.Length > 1)
     {
      _contentCharset = Utility.GetQuotedValue(values[1], "=", "charset");
     }
     if (values.Length > 2)
     {
      _contentFormat = Utility.GetQuotedValue(values[2], "=", "format");
     }
     _contentFileName = Utility.ParseFileName(strLine);
     if (_contentFileName == "")
     {
      strRet = srReader.ReadLine();
      if (strRet == "")
      {
       strLine = "";
       break;
      }
      _contentFileName = Utility.ParseFileName(strLine);
      if (_contentFileName == "")
       ParseHeader(srReader, ref strRet);
     }
     break;
    case "CONTENT-TRANSFER-ENCODING":
     _contentTransferEncoding = Utility.SplitOnSemiColon(array[1])[0].Trim();
     break;
    case "CONTENT-DESCRIPTION":
     _contentDescription = Utility.DecodeText(Utility.SplitOnSemiColon(array[1])[0].Trim());
     break;
    case "CONTENT-DISPOSITION":
     if (values.Length > 0)
      _contentDisposition = values[0].Trim();

     ///reported by grandepuffo @ https://sourceforge.net/forum/message.php?msg_id=2589759
     //_contentFileName=values[1];
     if (values.Length > 1)
     {
      _contentFileName = values[1];
     }
     else
     {
      _contentFileName = "";
     }

     if (_contentFileName == "")
      _contentFileName = srReader.ReadLine();

     _contentFileName = _contentFileName.Replace("\t", "");
     _contentFileName = Utility.GetQuotedValue(_contentFileName, "=", "filename");
     _contentFileName = Utility.DecodeText(_contentFileName);
     break;
    case "CONTENT-ID":
     _contentID = Utility.SplitOnSemiColon(array[1])[0].Trim('<').Trim('>');
     break;
   }
  }

  ///


  /// verify the encoding
  ///

  /// encoding to verify
  /// true if encoding
  private bool IsEncoding(string encoding)
  {
   return _contentTransferEncoding.ToLower().IndexOf(encoding.ToLower()) != -1;
  }

  ///


  /// Decode the attachment to text
  ///

  /// Decoded attachment text
  public string DecodeAsText()
  {
   string decodedAttachment = null;

   try
   {
    if (_contentType.ToLower() == "message/rfc822".ToLower())
     decodedAttachment = Utility.DecodeText(_rawAttachment);
    else if (_contentTransferEncoding != null)
    {
     decodedAttachment = _rawAttachment;

     if (!IsEncoding("7bit"))
     {
      if (IsEncoding("8bit") && _contentCharset != null & _contentCharset != "")
       decodedAttachment = Utility.Change(decodedAttachment, _contentCharset);

      if (Utility.IsQuotedPrintable(_contentTransferEncoding))
       decodedAttachment = DecodeQP.ConvertHexContent(decodedAttachment);
      else if (IsEncoding("8bit"))
       decodedAttachment = decodedAttachment;
      else
       decodedAttachment = Utility.deCodeB64s(Utility.RemoveNonB64(decodedAttachment));
     }
    }
    else if (_contentCharset != null)
     decodedAttachment = Utility.Change(_rawAttachment, _contentCharset); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));
    else
     decodedAttachment = _rawAttachment;
   }
   catch
   {
    decodedAttachment = _rawAttachment;
   }
   return decodedAttachment;
  }

  ///


  /// decode attachment to be a message object
  ///

  /// message
  public Message DecodeAsMessage()
  {
   bool blnRet = false;
   return new Message(ref blnRet, "", false, _rawAttachment, false);
  }

  ///


  /// Decode the attachment to bytes
  ///

  /// Decoded attachment bytes
  public byte[] DecodedAsBytes()
  {
   if (_rawAttachment == null)
    return null;
   if (_contentFileName != "")
   {
    byte[] decodedBytes = null;

    if (_contentType != null && _contentType.ToLower() == "message/rfc822".ToLower())
     decodedBytes = Encoding.Default.GetBytes(Utility.DecodeText(_rawAttachment));
    else if (_contentTransferEncoding != null)
    {
     string bytContent = _rawAttachment;

     if (!IsEncoding("7bit"))
     {
      if (IsEncoding("8bit") && _contentCharset != null & _contentCharset != "")
       bytContent = Utility.Change(bytContent, _contentCharset);

      if (Utility.IsQuotedPrintable(_contentTransferEncoding))
       decodedBytes = Encoding.Default.GetBytes(DecodeQP.ConvertHexContent(bytContent));
      else if (IsEncoding("8bit"))
       decodedBytes = Encoding.Default.GetBytes(bytContent);
      else
       decodedBytes = Convert.FromBase64String(Utility.RemoveNonB64(bytContent));
     }
     else
      decodedBytes = Encoding.Default.GetBytes(bytContent);
    }
    else if (_contentCharset != null)
     decodedBytes = Encoding.Default.GetBytes(Utility.Change(_rawAttachment, _contentCharset)); //Encoding.Default.GetString(Encoding.GetEncoding(_contentCharset).GetBytes(_rawAttachment));
    else
     decodedBytes = Encoding.Default.GetBytes(_rawAttachment);

    return decodedBytes;
   }
   else
   {
    return null;
   }
  }

  public int CompareTo(object attachment)
  {
   return (this.RawAttachment.CompareTo(((Attachment) (attachment)).RawAttachment));
  }
 }

 public enum MessageImportanceType
 {
  HIGH = 5,
  NORMAL = 3,
  LOW = 1
 }

 ///


 /// Decoding Quoted-Printable text
 ///
 ///

 public class DecodeQP
 {
  public DecodeQP()
  {
  }

  ///


  /// Decoding Quoted-Printable string
  ///

  /// Quoted-Printable encoded string
  /// encoding method
  /// decoded string
  public static string ConvertHexToString(string Hexstring, string Encoding)
  {
   try
   {
    return ConvertHexToString(Hexstring, System.Text.Encoding.GetEncoding(Encoding));
   }
   catch
   {
    return ConvertHexContent(Hexstring);
   }
  }

  ///


  /// Decoding Quoted-Printable string
  ///

  /// Quoted-Printable encoded string
  /// encoding method
  /// decoded string
  public static string ConvertHexToString(string Hexstring, Encoding encode)
  {
   try
   {
    if (Hexstring == null || Hexstring.Equals("")) return "";

    if (Hexstring.StartsWith("=")) Hexstring = Hexstring.Substring(1);

    string[] aHex = Hexstring.Split(new char[1] {'='});
    byte[] abyte = new Byte[aHex.Length];

    for (int i = 0; i < abyte.Length; i++)
    {
     // Console.WriteLine(aHex[i]);
     abyte[i] = (byte) int.Parse(aHex[i], NumberStyles.HexNumber);
    }
    return encode.GetString(abyte);
   }
   catch
   {
    return Hexstring;
   }
  }

  ///


  /// Decoding Quoted-Printable string at a position
  ///

  /// Quoted-Printable encoded string
  /// encoding method, "Default" is suggested
  /// position to start, normally 0
  /// decoded string
  public static string ConvertHexContent(string Hexstring, Encoding encode, long nStart)
  {
   if (nStart >= Hexstring.Length) return Hexstring;

   //to hold string to be decoded
   StringBuilder sbHex = new StringBuilder();
   sbHex.Append("");
   //to hold decoded string
   StringBuilder sbEncoded = new StringBuilder();
   sbEncoded.Append("");
   //wether we reach Quoted-Printable string
   bool isBegin = false;
   string temp;
   int i = (int) nStart;

   while (i < Hexstring.Length)
   {
    //init next loop
    sbHex.Remove(0, sbHex.Length);
    isBegin = false;
    int count = 0;

    while (i < Hexstring.Length)
    {
     temp = Hexstring.Substring(i, 1); //before reaching Quoted-Printable string, one char at a time
     if (temp.StartsWith("="))
     {
      temp = Hexstring.Substring(i, 3); //get 3 chars
      if (temp.EndsWith("\r\n")) //return char
      {
       if (isBegin && (count%2 == 0))
        break;
       // sbEncoded.Append("");
       i = i + 3;
      }
      else if (!temp.EndsWith("3D"))
      {
       sbHex.Append(temp);
       isBegin = true; //we reach Quoted-Printable string, put it into buffer
       i = i + 3;
       count++;
      }
      else //if it ends with 3D, it is "="
      {
       if (isBegin && (count%2 == 0)) //wait until even items to handle all character sets
        break;

       sbEncoded.Append("=");
       i = i + 3;
      }

     }
     else
     {
      if (isBegin) //we have got the how Quoted-Printable string, break it
       break;
      sbEncoded.Append(temp); //not Quoted-Printable string, put it into buffer
      i++;
     }

    }
    //decode Quoted-Printable string
    sbEncoded.Append(ConvertHexToString(sbHex.ToString(), encode));
   }

   return sbEncoded.ToString();
  }


  ///


  /// Decoding Quoted-Printable string using default encoding and begin at 0
  ///

  /// Quoted-Printable encoded string
  /// decoded string
  public static string ConvertHexContent(string Hexstring)
  {
   if (Hexstring == null || Hexstring.Equals("")) return Hexstring;

   return ConvertHexContent(Hexstring, Encoding.Default, 0);

  }
 }

 ///


 /// Message Parser.
 ///

 public class Message
 {
  #region Member Variables

  private ArrayList _attachments = new ArrayList();
  private string _rawHeader = null;
  private string _rawMessage = null;
  private string _rawMessageBody = null;
  private int _attachmentCount = 0;
  private string _replyTo = null;
  private string _replyToEmail = null;
  private string _from = null;
  private string _fromEmail = null;
  private string _date = null;
  private string _dateTimeInfo = null;
  private string _subject = null;
  private string[] _to = new string[0];
  private string[] _cc = new string[0];
  private string[] _bcc = new string[0];
  private ArrayList _keywords = new ArrayList();
  private string _contentType = null;
  private string _contentCharset = null;
  private string _reportType = null;
  private string _contentTransferEncoding = null;
  private bool _html = false;
  private long _contentLength = 0;
  private string _contentEncoding = null;
  private string _returnPath = null;
  private string _mimeVersion = null;
  private string _received = null;
  private string _importance = null;
  private string _messageID = null;
  private string _attachmentboundry = null;
  private string _attachmentboundry2 = null;
  private bool _hasAttachment = false;
  private string _dispositionNotificationTo = null;
  private ArrayList _messageBody = new ArrayList();
  private string _basePath = null;
  private bool _autoDecodeMSTNEF = false;
  private Hashtable _customHeaders = new Hashtable();

  #endregion

  #region Properties

  ///


  /// custom headers
  ///

  public Hashtable CustomHeaders
  {
   get
   {
    return _customHeaders;
   }
   set
   {
    _customHeaders = value;
   }
  }

  ///


  /// whether auto decoding MS-TNEF attachment files
  ///

  public bool AutoDecodeMSTNEF
  {
   get
   {
    return _autoDecodeMSTNEF;
   }
   set
   {
    _autoDecodeMSTNEF = value;
   }
  }

  ///


  /// path to extract MS-TNEF attachment files
  ///

  public string BasePath
  {
   get
   {
    return _basePath;
   }
   set
   {
    try
    {
     if (value.EndsWith("\\"))
      _basePath = value;
     else
      _basePath = value + "\\";
    }
    catch
    {
    }
   }
  }

  ///


  /// message keywords
  ///

  public ArrayList Keywords
  {
   get
   {
    return _keywords;
   }
  }

  ///


  /// disposition notification
  ///

  public string DispositionNotificationTo
  {
   get
   {
    return _dispositionNotificationTo;
   }
  }

  ///


  /// received server
  ///

  public string Received
  {
   get
   {
    return _received;
   }
  }

  ///


  /// importance level
  ///

  public string Importance
  {
   get
   {
    return _importance;
   }
  }

  ///


  /// importance level type
  ///

  public MessageImportanceType ImportanceType
  {
   get
   {
    switch (_importance.ToUpper())
    {
     case "5":
     case "HIGH":
      return MessageImportanceType.HIGH;
     case "3":
     case "NORMAL":
      return MessageImportanceType.NORMAL;
     case "1":
     case "LOW":
      return MessageImportanceType.LOW;
     default:
      return MessageImportanceType.NORMAL;
    }
   }
  }

  ///


  /// Content Charset
  ///

  public string ContentCharset
  {
   get
   {
    return _contentCharset;
   }
  }

  ///


  /// Content Transfer Encoding
  ///

  public string ContentTransferEncoding
  {
   get
   {
    return _contentTransferEncoding;
   }
  }

  ///


  /// Message Bodies
  ///

  public ArrayList MessageBody
  {
   get
   {
    return _messageBody;
   }
  }

  ///


  /// Attachment Boundry
  ///

  public string AttachmentBoundry
  {
   get
   {
    return _attachmentboundry;
   }
  }

  ///


  /// Alternate Attachment Boundry
  ///

  public string AttachmentBoundry2
  {
   get
   {
    return _attachmentboundry2;
   }
  }

  ///


  /// Attachment Count
  ///

  public int AttachmentCount
  {
   get
   {
    return _attachmentCount;
   }
  }

  ///


  /// Attachments
  ///

  public ArrayList Attachments
  {
   get
   {
    return _attachments;
   }
  }

  ///


  /// CC
  ///

  public string[] CC
  {
   get
   {
    return _cc;
   }
  }

  ///


  /// BCC
  ///

  public string[] BCC
  {
   get
   {
    return _bcc;
   }
  }

  ///


  /// TO
  ///

  public string[] TO
  {
   get
   {
    return _to;
   }
  }

  ///


  /// Content Encoding
  ///

  public string ContentEncoding
  {
   get
   {
    return _contentEncoding;
   }
  }

  ///


  /// Content Length
  ///

  public long ContentLength
  {
   get
   {
    return _contentLength;
   }
  }

  ///


  /// Content Type
  ///

  public string ContentType
  {
   get
   {
    return _contentType;
   }
  }

  ///


  /// Report Type
  ///

  public string ReportType
  {
   get
   {
    return _reportType;
   }
  }

  ///


  /// HTML
  ///

  public bool HTML
  {
   get
   {
    return _html;
   }
  }

  ///


  /// Date
  ///

  public string Date
  {
   get
   {
    return _date;
   }
  }

  ///


  /// DateTime Info
  ///

  public string DateTimeInfo
  {
   get
   {
    return _dateTimeInfo;
   }
  }

  ///


  /// From name
  ///

  public string From
  {
   get
   {
    return _from;
   }
  }

  ///


  /// From Email
  ///

  public string FromEmail
  {
   get
   {
    return _fromEmail;
   }
  }

  ///


  /// Reply to name
  ///

  public string ReplyTo
  {
   get
   {
    return _replyTo;
   }
  }

  ///


  /// Reply to email
  ///

  public string ReplyToEmail
  {
   get
   {
    return _replyToEmail;
   }
  }

  ///


  /// whether has attachment
  ///

  public bool HasAttachment
  {
   get
   {
    return _hasAttachment;
   }
  }

  ///


  /// raw message body
  ///

  public string RawMessageBody
  {
   get
   {
    return _rawMessageBody;
   }
  }

  ///


  /// Message ID
  ///

  public string MessageID
  {
   get
   {
    return _messageID;
   }
  }

  ///


  /// MIME version
  ///

  public string MimeVersion
  {
   get
   {
    return _mimeVersion;
   }
  }

  ///


  /// raw header
  ///

  public string RawHeader
  {
   get
   {
    return _rawHeader;
   }
  }

  ///


  /// raw message
  ///

  public string RawMessage
  {
   get
   {
    return _rawMessage;
   }
  }

  ///


  /// return path
  ///

  public string ReturnPath
  {
   get
   {
    return _returnPath;
   }
  }

  ///


  /// subject
  ///

  public string Subject
  {
   get
   {
    return _subject;
   }
  }

  #endregion

  ///


  /// release all objects
  ///

  ~Message()
  {
   _attachments.Clear();
   _attachments = null;
   _keywords.Clear();
   _keywords = null;
   _messageBody.Clear();
   _messageBody = null;
   _customHeaders.Clear();
   _customHeaders = null;
  }

  ///


  /// New Message
  ///

  /// reference for the finishing state
  /// path to extract MS-TNEF attachment files
  /// whether auto decoding MS-TNEF attachments
  /// whether only decode the header without body
  /// file of email content to load from
  public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, bool blnOnlyHeader, string strEMLFile)
  {
   string strMessage = null;
   if (Utility.ReadPlainTextFromFile(strEMLFile, ref strMessage))
   {
    NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);
   }
   else
    blnFinish = true;
  }

  ///


  /// New Message
  ///

  /// reference for the finishing state
  /// path to extract MS-TNEF attachment files
  /// whether auto decoding MS-TNEF attachments
  /// raw message content
  /// whether only decode the header without body
  public Message(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
  {
   NewMessage(ref blnFinish, strBasePath, blnAutoDecodeMSTNEF, strMessage, blnOnlyHeader);
  }

  ///


  /// New Message
  ///

  /// reference for the finishing state
  /// raw message content
  /// whether only decode the header without body
  public Message(ref bool blnFinish, string strMessage, bool blnOnlyHeader)
  {
   NewMessage(ref blnFinish, "", false, strMessage, blnOnlyHeader);
  }

  ///


  /// New Message
  ///

  /// reference for the finishing state
  /// raw message content
  public Message(ref bool blnFinish, string strMessage)
  {
   NewMessage(ref blnFinish, "", false, strMessage, false);
  }

  ///


  /// get valid attachment
  ///

  /// attachment index in the attachments collection
  /// attachment
  public Attachment GetAttachment(int intAttachmentNumber)
  {
   if (intAttachmentNumber < 0 || intAttachmentNumber > _attachmentCount || intAttachmentNumber > _attachments.Count)
   {
    Utility.LogError("GetAttachment():attachment not exist");
    throw new ArgumentOutOfRangeException("intAttachmentNumber");
   }
   return (Attachment) _attachments[intAttachmentNumber];
  }

  ///


  /// New Message
  ///

  /// reference for the finishing state
  /// path to extract MS-TNEF attachment files
  /// whether auto decoding MS-TNEF attachments
  /// raw message content
  /// whether only decode the header without body
  /// construction result whether successfully new a message
  private bool NewMessage(ref bool blnFinish, string strBasePath, bool blnAutoDecodeMSTNEF, string strMessage, bool blnOnlyHeader)
  {
   StringReader srdReader = new StringReader(strMessage);
   StringBuilder sbdBuilder = new StringBuilder();
   _basePath = strBasePath;
   _autoDecodeMSTNEF = blnAutoDecodeMSTNEF;

   _rawMessage = strMessage;

   string strLine = srdReader.ReadLine();
   while (Utility.IsNotNullTextEx(strLine))
   {
    sbdBuilder.Append(strLine + "\r\n");
    ParseHeader(sbdBuilder, srdReader, ref strLine);
    if (Utility.IsOrNullTextEx(strLine))
     break;
    else
     strLine = srdReader.ReadLine();
   }

   _rawHeader = sbdBuilder.ToString();

   SetAttachmentBoundry2(_rawHeader);

   if (_contentLength == 0)
    _contentLength = strMessage.Length; //_rawMessageBody.Length;

   if (blnOnlyHeader == false)
   {
    _rawMessageBody = srdReader.ReadToEnd().Trim();

    //the auto reply mail by outlook uses ms-tnef format
    if ((_hasAttachment == true && _attachmentboundry != null) || MIMETypes.IsMSTNEF(_contentType))
    {
     set_attachments();

     if (this.Attachments.Count > 0)
     {
      Attachment at = this.GetAttachment(0);
      if (at != null && at.NotAttachment)
       this.GetMessageBody(at.DecodeAsText());
      else
      {
      }
      //in case body parts as text[0] html[1]
      if (this.Attachments.Count > 1 && !this.IsReport())
      {
       at = this.GetAttachment(1);
       if (at != null && at.NotAttachment)
        this.GetMessageBody(at.DecodeAsText());
       else
       {
       }
      }
     }
     else
     {
     }
    }
    else
    {
     GetMessageBody(_rawMessageBody);
    }
   }

   blnFinish = true;
   return true;
  }

  ///


  /// parse message body
  ///

  /// raw message body
  /// message body
  public string GetTextBody(string strBuffer)
  {
   if (strBuffer.EndsWith("\r\n."))
    return strBuffer.Substring(0, strBuffer.Length - "\r\n.".Length);
   else
    return strBuffer;
  }

  ///


  /// parse message body
  ///

  /// raw message body
  public void GetMessageBody(string strBuffer)
  {
   int end, begin;
   string body;
   string encoding = "";

   begin = end = 0;
   _messageBody.Clear();

   try
   {
    if (Utility.IsOrNullTextEx(strBuffer))
     return;
    else if (Utility.IsOrNullTextEx(_contentType) && _contentTransferEncoding == null)
    {
     _messageBody.Add(GetTextBody(strBuffer));
    }
    else if (_contentType != null && _contentType.IndexOf("digest") >= 0)
    {
     // this is a digest method
     //ParseDigestMessage(strBuffer);
     _messageBody.Add(GetTextBody(strBuffer));
    }
    else if (_attachmentboundry2 == null)
    {
     body = GetTextBody(strBuffer);

     if (Utility.IsQuotedPrintable(_contentTransferEncoding))
     {
      body = DecodeQP.ConvertHexContent(body);
     }
     else if (Utility.IsBase64(_contentTransferEncoding))
     {
      body = Utility.deCodeB64s(Utility.RemoveNonB64(body));
     }
     else if (Utility.IsNotNullText(_contentCharset))
     {
      body = Encoding.GetEncoding(_contentCharset).GetString(Encoding.Default.GetBytes(body));
     }
     _messageBody.Add(Utility.RemoveNonB64(body));
    }
    else
    {
     begin = 0;

     while (begin != -1)
     {
      // find "\r\n\r\n" denoting end of header
      begin = strBuffer.IndexOf("--" + _attachmentboundry2, begin);
      if (begin != -1)
      {
       encoding = MIMETypes.GetContentTransferEncoding(strBuffer, begin);

       begin = strBuffer.IndexOf("\r\n\r\n", begin + 1); //strBuffer.LastIndexOfAny(ALPHABET.ToCharArray());

       // find end of text
       end = strBuffer.IndexOf("--" + _attachmentboundry2, begin + 1);

       if (begin != -1)
       {
        if (end != -1)
        {
         begin += 4;
         if (begin >= end)
          continue;
         else if (this._contentEncoding != null && this._contentEncoding.IndexOf("8bit") != -1)
          body = Utility.Change(strBuffer.Substring(begin, end - begin - 2), _contentCharset);
         else
          body = strBuffer.Substring(begin, end - begin - 2);
        }
        else
        {
         body = strBuffer.Substring(begin);
        }

        if (Utility.IsQuotedPrintable(encoding))
        {
         string ret = body;
         ret = DecodeQP.ConvertHexContent(ret);
         _messageBody.Add(ret);
        }
        else if (Utility.IsBase64(encoding))
        {
         string ret = Utility.RemoveNonB64(body);
         ret = Utility.deCodeB64s(ret);
         if (ret != "\0")
          _messageBody.Add(ret);
         else
          _messageBody.Add(body);
        }
        else
         _messageBody.Add(body);

        if (end == -1) break;
       }
       else
       {
        break;
       }
      }
      else
      {
       if (_messageBody.Count == 0)
       {
        _messageBody.Add(strBuffer);
       }
       break;
      }
     }
    }
   }
   catch (Exception e)
   {
    Utility.LogError("GetMessageBody():" + e.Message);
    _messageBody.Add(Utility.deCodeB64s(strBuffer));
   }

   if (_messageBody.Count > 1)
    _html = true;
  }

  ///


  /// verify if the message is a report
  ///

  /// if it is a report message, return true, else, false
  public bool IsReport()
  {
   if (Utility.IsNotNullText(_contentType))
    return (_contentType.ToLower().IndexOf("report".ToLower()) != -1);
   else
    return false;
  }

  ///


  /// verify if the attachment is MIME Email file
  ///

  /// attachment
  /// if MIME Email file, return true, else, false
  public bool IsMIMEMailFile(Attachment attItem)
  {
   try
   {
    return (attItem.ContentFileName.ToLower().EndsWith(".eml".ToLower()) || attItem.ContentType.ToLower() == "message/rfc822".ToLower());
   }
   catch (Exception e)
   {
    Utility.LogError("IsMIMEMailFile():" + e.Message);
    return false;
   }
  }

  ///


  /// translate pictures url within the body
  ///

  /// message body
  /// pictures collection
  /// translated message body
  public string TranslateHTMLPictureFiles(string strBody, Hashtable hsbFiles)
  {
   try
   {
    for (int i = 0; i < this.AttachmentCount; i++)
    {
     Attachment att = this.GetAttachment(i);
     if (Utility.IsPictureFile(att.ContentFileName) == true)
     {
      if (Utility.IsNotNullText(att.ContentID))
       //support for embedded pictures
       strBody = strBody.Replace("cid:" + att.ContentID, hsbFiles[att.ContentFileName].ToString());

      strBody = strBody.Replace(att.ContentFileName, hsbFiles[att.ContentFileName].ToString());
     }
    }
   }
   catch (Exception e)
   {
    Utility.LogError("TranslateHTMLPictureFiles():" + e.Message);
   }
   return strBody;
  }

  ///


  /// translate pictures url within the body
  ///

  /// message body
  /// path of the pictures
  /// translated message body
  public string TranslateHTMLPictureFiles(string strBody, string strPath)
  {
   try
   {
    if (!strPath.EndsWith("\\"))
    {
     strPath += "\\";
    }
    for (int i = 0; i < this.AttachmentCount; i++)
    {
     Attachment att = this.GetAttachment(i);
     if (Utility.IsPictureFile(att.ContentFileName) == true)
     {
      if (Utility.IsNotNullText(att.ContentID))
       //support for embedded pictures
       strBody = strBody.Replace("cid:" + att.ContentID, strPath + att.ContentFileName);
      strBody = strBody.Replace(att.ContentFileName, strPath + att.ContentFileName);
     }
    }
   }
   catch (Exception e)
   {
    Utility.LogError("TranslateHTMLPictureFiles():" + e.Message);
   }
   return strBody;
  }

  ///


  /// Get the proper attachment file name
  ///

  /// attachment
  /// propery attachment file name
  public string GetAttachmentFileName(Attachment attItem)
  {
   int items = 0;

   //return unique body file names
   for (int i = 0; i < _attachments.Count; i++)
   {
    if (attItem.ContentFileName == attItem.DefaultFileName)
    {
     items++;
     attItem.ContentFileName = attItem.DefaultFileName2.Replace("*", items.ToString());
    }
   }
   string name = attItem.ContentFileName;

   return (name == null || name == "" ? (IsReport() == true ? (this.IsMIMEMailFile(attItem) == true ? attItem.DefaultMIMEFileName : attItem.DefaultReportFileName) : (attItem.ContentID != null ? attItem.ContentID : attItem.DefaultFileName)) : name);
  }

  ///


  /// save attachments to a defined path
  ///

  /// path to have attachments to be saved to
  /// true if save successfully, false if failed
  public bool SaveAttachments(string strPath)
  {
   if (Utility.IsNotNullText(strPath))
   {
    try
    {
     bool blnRet = true;

     if (!strPath.EndsWith("\\"))
     {
      strPath += "\\";
     }
     for (int i = 0; i < this.Attachments.Count; i++)
     {
      Attachment att = GetAttachment(i);
      blnRet = SaveAttachment(att, strPath + GetAttachmentFileName(att));
      if (!blnRet)
       break;
     }
     return blnRet;
    }
    catch (Exception e)
    {
     Utility.LogError(e.Message);
     return false;
    }
   }
   else
    return false;
  }

  ///


  /// save attachment to file
  ///

  /// Attachment
  /// File to be saved to
  /// true if save successfully, false if failed
  public bool SaveAttachment(Attachment attItem, string strFileName)
  {
   byte[] da;
   try
   {
    //    FileStream fs=File.Create(strFileName);
    //    byte[] da;
    //    if(attItem.ContentFileName.Length>0)
    //    {
    //     da=attItem.DecodedAttachment;
    //    }
    //    else
    //    {
    //     this.GetMessageBody(attItem.DecodeAttachmentAsText());
    //     da=Encoding.Default.GetBytes((string)this.MessageBody[this.MessageBody.Count-1]);
    //    }
    //    fs.Write(da,0,da.Length);
    //    fs.Close();
    //    return true;
    if (attItem.InBytes)
    {
     da = attItem.RawBytes;
    }
    else if (attItem.ContentFileName.Length > 0)
    {
     da = attItem.DecodedAttachment;
    }
    else if (attItem.ContentType.ToLower() == "message/rfc822".ToLower())
    {
     da = Encoding.Default.GetBytes(attItem.RawAttachment);
    }
    else
    {
     this.GetMessageBody(attItem.DecodeAsText());
     da = Encoding.Default.GetBytes((string) this.MessageBody[this.MessageBody.Count - 1]);
    }
    return Utility.SaveByteContentToFile(strFileName, da);
   }
   catch
   {
    /*Utility.LogError("SaveAttachment():"+e.Message);
    return false;*/
    da = Encoding.Default.GetBytes(attItem.RawAttachment);
    return Utility.SaveByteContentToFile(strFileName, da);
   }
  }

  ///


  /// set attachments
  ///

  private void set_attachments()
  {
   int indexOf_attachmentstart = 0;
   int indexOfAttachmentEnd = 0;
   bool processed = false;

   Attachment att = null;

   SetAttachmentBoundry2(_rawMessageBody);

   while (!processed)
   {
    if (Utility.IsNotNullText(_attachmentboundry))
    {
     indexOf_attachmentstart = _rawMessageBody.IndexOf(_attachmentboundry, indexOf_attachmentstart) + _attachmentboundry.Length;
     if (_rawMessageBody == "" || indexOf_attachmentstart < 0) return;

     indexOfAttachmentEnd = _rawMessageBody.IndexOf(_attachmentboundry, indexOf_attachmentstart + 1);
    }
    else
    {
     indexOfAttachmentEnd = -1;
    }

    //if(indexOfAttachmentEnd<0)return;
    if (indexOfAttachmentEnd != -1)
    {
    }
    else if (indexOfAttachmentEnd == -1 && !processed && _attachmentCount == 0)
    {
     processed = true;
     indexOfAttachmentEnd = _rawMessageBody.Length;
    }
    else
     return;

    if (indexOf_attachmentstart == indexOfAttachmentEnd - 9)
    {
     indexOf_attachmentstart = 0;
     processed = true;
    }

    string strLine = _rawMessageBody.Substring(indexOf_attachmentstart, (indexOfAttachmentEnd - indexOf_attachmentstart - 2));
    bool isMSTNEF;
    isMSTNEF = MIMETypes.IsMSTNEF(_contentType);
    att = new Attachment(strLine.Trim(), _contentType, !isMSTNEF);

    //ms-tnef format might contain multiple attachments
    if (MIMETypes.IsMSTNEF(att.ContentType) && AutoDecodeMSTNEF && !isMSTNEF)
    {
     Utility.LogError("set_attachments():found ms-tnef file");
     TNEFParser tnef = new TNEFParser();
     TNEFAttachment tatt = new TNEFAttachment();
     Attachment attNew = null;

     tnef.Verbose = false;
     tnef.BasePath = this.BasePath;
     //tnef.LogFilePath=this.BasePath + "OpenPOP.TNEF.log";
     if (tnef.OpenTNEFStream(att.DecodedAsBytes()))
     {
      if (tnef.Parse())
      {
       for (IDictionaryEnumerator i = tnef.Attachments().GetEnumerator(); i.MoveNext(); )
       {
        tatt = (TNEFAttachment) i.Value;
        attNew = new Attachment(tatt.FileContent, tatt.FileLength, tatt.FileName, MIMETypes.GetMimeType(tatt.FileName));
        _attachmentCount++;
        _attachments.Add(attNew);
       }
      }
      else
       Utility.LogError("set_attachments():ms-tnef file parse failed");
     }
     else
      Utility.LogError("set_attachments():ms-tnef file open failed");
    }
    else
    {
     _attachmentCount++;
     _attachments.Add(att);
    }

    indexOf_attachmentstart++;
   }
  }

  ///


  /// Set alternative attachment boundry
  ///

  /// raw message
  private void SetAttachmentBoundry2(string strBuffer)
  {
   int indexOfAttachmentBoundry2Begin = 0;
   int indexOfAttachmentBoundry2End = 0;
   indexOfAttachmentBoundry2Begin = strBuffer.ToLower().IndexOf("Multipart/Alternative".ToLower());
   if (indexOfAttachmentBoundry2Begin != -1)
   {
    /*    indexOfAttachmentBoundry2Begin=strBuffer.IndexOf("boundary=\"");
        indexOfAttachmentBoundry2End=strBuffer.IndexOf("\"",indexOfAttachmentBoundry2Begin+10);
        if(indexOfAttachmentBoundry2Begin!=-1&&indexOfAttachmentBoundry2End!=-1)
         _attachmentboundry2=strBuffer.Substring(indexOfAttachmentBoundry2Begin+10,indexOfAttachmentBoundry2End-indexOfAttachmentBoundry2Begin-10).Trim();
    */
    indexOfAttachmentBoundry2Begin = strBuffer.IndexOf("boundary=");
    if (indexOfAttachmentBoundry2Begin != -1)
    {
     int p = strBuffer.IndexOf("\r\n", indexOfAttachmentBoundry2Begin);
     string s = strBuffer.Substring(indexOfAttachmentBoundry2Begin + 29, 4);
     indexOfAttachmentBoundry2End = strBuffer.IndexOf("\r\n", indexOfAttachmentBoundry2Begin + 9);
     if (indexOfAttachmentBoundry2End == -1)
      indexOfAttachmentBoundry2End = strBuffer.Length;
     _attachmentboundry2 = Utility.RemoveQuote(strBuffer.Substring(indexOfAttachmentBoundry2Begin + 9, indexOfAttachmentBoundry2End - indexOfAttachmentBoundry2Begin - 9));
    }
   }
   else
   {
    _attachmentboundry2 = _attachmentboundry;
   }
  }

  ///


  /// Save message content to eml file
  ///

  ///
  ///
  public bool SaveToMIMEEmailFile(string strFile, bool blnReplaceExists)
  {
   return Utility.SavePlainTextToFile(strFile, _rawMessage, blnReplaceExists);
  }

  ///


  /// parse multi-line header
  ///

  /// string builder to hold header content
  /// string reader to get each line of the header
  /// first line content
  /// reference header line
  /// collection to hold every content line
  private void ParseStreamLines(StringBuilder sbdBuilder
                                , StringReader srdReader
                                , string strValue
                                , ref string strLine
                                , ArrayList alCollection)
  {
   string strFormmated;
   int intLines = 0;
   alCollection.Add(strValue);

   sbdBuilder.Append(strLine);

   strLine = srdReader.ReadLine();

   while (strLine.Trim() != "" && (strLine.StartsWith("\t") || strLine.StartsWith(" ")))
   {
    strFormmated = strLine.Substring(1);
    alCollection.Add(Utility.DecodeLine(strFormmated));
    sbdBuilder.Append(strLine);
    strLine = srdReader.ReadLine();
    intLines++;
   }

   if (strLine != "")
   {
    sbdBuilder.Append(strLine);
   }
   else if (intLines == 0)
   {
    strLine = srdReader.ReadLine();
    sbdBuilder.Append(strLine);
   }

   ParseHeader(sbdBuilder, srdReader, ref strLine);
  }

  ///


  /// parse multi-line header
  ///

  /// string builder to hold header content
  /// string reader to get each line of the header
  /// collection key
  /// first line content
  /// reference header line
  /// collection to hold every content line
  private void ParseStreamLines(StringBuilder sbdBuilder
                                , StringReader srdReader
                                , string strName
                                , string strValue
                                , ref string strLine
                                , Hashtable hstCollection)
  {
   string strFormmated;
   string strReturn = strValue;
   int intLines = 0;

   //sbdBuilder.Append(strLine);

   strLine = srdReader.ReadLine();
   while (strLine.Trim() != "" && (strLine.StartsWith("\t") || strLine.StartsWith(" ")))
   {
    strFormmated = strLine.Substring(1);
    strReturn += Utility.DecodeLine(strFormmated);
    sbdBuilder.Append(strLine + "\r\n");
    strLine = srdReader.ReadLine();
    intLines++;
   }
   if (!hstCollection.ContainsKey(strName))
    hstCollection.Add(strName, strReturn);

   if (strLine != "")
   {
    sbdBuilder.Append(strLine + "\r\n");
   }
   else if (intLines == 0)
   {
    //     strLine=srdReader.ReadLine();
    //     sbdBuilder.Append(strLine + "\r\n");
   }

   ParseHeader(sbdBuilder, srdReader, ref strLine);
  }

  ///


  /// parse multi-line header
  ///

  /// string builder to hold header content
  /// string reader to get each line of the header
  /// first line content
  /// reference header line
  /// return value
  /// decode each line
  private void ParseStreamLines(StringBuilder sbdBuilder
                                , StringReader srdReader
                                , string strValue
                                , ref string strLine
                                , ref string strReturn
                                , bool blnLineDecode)
  {
   string strFormmated;
   int intLines = 0;
   strReturn = strValue;

   sbdBuilder.Append(strLine + "\r\n");

   if (blnLineDecode == true)
    strReturn = Utility.DecodeLine(strReturn);

   strLine = srdReader.ReadLine();
   while (strLine.Trim() != "" && (strLine.StartsWith("\t") || strLine.StartsWith(" ")))
   {
    strFormmated = strLine.Substring(1);
    strReturn += (blnLineDecode == true ? Utility.DecodeLine(strFormmated) : "\r\n" + strFormmated);
    sbdBuilder.Append(strLine + "\r\n");
    strLine = srdReader.ReadLine();
    intLines++;
   }

   if (strLine != "")
   {
    sbdBuilder.Append(strLine + "\r\n");
   }
   else if (intLines == 0)
   {
    strLine = srdReader.ReadLine();
    sbdBuilder.Append(strLine + "\r\n");
   }

   if (!blnLineDecode)
   {
    strReturn = Utility.RemoveWhiteBlanks(Utility.DecodeText(strReturn));
   }

   ParseHeader(sbdBuilder, srdReader, ref strLine);
  }

  ///


  /// Parse the headers populating respective member fields
  ///

  /// string builder to hold the header content
  /// string reader to get each line of the header
  /// reference header line
  private void ParseHeader(StringBuilder sbdBuilder, StringReader srdReader, ref string strLine)
  {
   string[] array = Utility.GetHeadersValue(strLine); //Regex.Split(strLine,":");

   switch (array[0].ToUpper())
   {
    case "TO":
     _to = array[1].Split(',');
     for (int i = 0; i < _to.Length; i++)
     {
      _to[i] = Utility.DecodeLine(_to[i].Trim());
     }
     break;

    case "CC":
     _cc = array[1].Split(',');
     for (int i = 0; i < _cc.Length; i++)
     {
      _cc[i] = Utility.DecodeLine(_cc[i].Trim());
     }
     break;

    case "BCC":
     _bcc = array[1].Split(',');
     for (int i = 0; i < _bcc.Length; i++)
     {
      _bcc[i] = Utility.DecodeLine(_bcc[i].Trim());
     }
     break;

    case "FROM":
     Utility.ParseEmailAddress(array[1], ref _from, ref _fromEmail);
     break;

    case "REPLY-TO":
     Utility.ParseEmailAddress(array[1], ref _replyTo, ref _replyToEmail);
     break;

    case "KEYWORDS": //ms outlook keywords
     ParseStreamLines(sbdBuilder, srdReader, array[1].Trim(), ref strLine, _keywords);
     break;

    case "RECEIVED":
     ParseStreamLines(sbdBuilder, srdReader, array[1].Trim(), ref strLine, ref _received, true);
     break;

    case "IMPORTANCE":
     _importance = array[1].Trim();
     break;

    case "DISPOSITION-NOTIFICATION-TO":
     _dispositionNotificationTo = array[1].Trim();
     break;

    case "MIME-VERSION":
     _mimeVersion = array[1].Trim();
     break;

    case "SUBJECT":
    case "THREAD-TOPIC":
     string strRet = null;
     for (int i = 1; i < array.Length; i++)
     {
      strRet += array[i];
     }
     ParseStreamLines(sbdBuilder, srdReader, strRet, ref strLine, ref _subject, false);
     break;

    case "RETURN-PATH":
     _returnPath = array[1].Trim().Trim('>').Trim('<');
     break;

    case "MESSAGE-ID":
     _messageID = array[1].Trim().Trim('>').Trim('<');
     break;

    case "DATE":
     for (int i = 1; i < array.Length; i++)
     {
      _dateTimeInfo += array[i];
     }
     _dateTimeInfo = _dateTimeInfo.Trim();
     _date = Utility.ParseEmailDate(_dateTimeInfo);
     break;

    case "CONTENT-LENGTH":
     _contentLength = Convert.ToInt32(array[1]);
     break;

    case "CONTENT-TRANSFER-ENCODING":
     _contentTransferEncoding = array[1].Trim();
     break;

    case "CONTENT-TYPE":
     //if already content type has been assigned
     if (_contentType != null)
      return;

     strLine = array[1];

     _contentType = strLine.Split(';')[0];
     _contentType = _contentType.Trim();

     int intCharset = strLine.IndexOf("charset=");
     if (intCharset != -1)
     {
      int intBound2 = strLine.ToLower().IndexOf(";", intCharset + 8);
      if (intBound2 == -1)
       intBound2 = strLine.Length;
      intBound2 -= (intCharset + 8);
      _contentCharset = strLine.Substring(intCharset + 8, intBound2);
      _contentCharset = Utility.RemoveQuote(_contentCharset);
     }
     else
     {
      intCharset = strLine.ToLower().IndexOf("report-type=".ToLower());
      if (intCharset != -1)
      {
       int intPos = strLine.IndexOf(";", intCharset + 13);
       _reportType = strLine.Substring(intCharset + 12, intPos - intCharset - 13);
      }
      else if (strLine.ToLower().IndexOf("boundary=".ToLower()) == -1)
      {
       strLine = srdReader.ReadLine();
       if (strLine == "")
        return;
       intCharset = strLine.ToLower().IndexOf("charset=".ToLower());
       if (intCharset != -1)
        _contentCharset = strLine.Substring(intCharset + 9, strLine.Length - intCharset - 10);
       else if (strLine.IndexOf(":") != -1)
       {
        sbdBuilder.Append(strLine + "\r\n");
        ParseHeader(sbdBuilder, srdReader, ref strLine);
        return;
       }
       else
       {
        sbdBuilder.Append(strLine + "\r\n");
       }
      }
     }
     if (_contentType == "text/plain")
      return;
     else if (_contentType.ToLower() == "text/html" || _contentType.ToLower().IndexOf("multipart/") != -1)
      _html = true;

     if (strLine.Trim().Length == _contentType.Length + 1 || strLine.ToLower().IndexOf("boundary=".ToLower()) == -1)
     {
      strLine = srdReader.ReadLine();
      if (strLine == null || strLine == "" || strLine.IndexOf(":") != -1)
      {
       sbdBuilder.Append(strLine + "\r\n");
       ParseHeader(sbdBuilder, srdReader, ref strLine);
       return;
      }
      else
      {
       sbdBuilder.Append(strLine + "\r\n");
      }

      if (strLine.ToLower().IndexOf("boundary=".ToLower()) == -1)
      {
       _attachmentboundry = srdReader.ReadLine();
       sbdBuilder.Append(_attachmentboundry + "\r\n");
      }
      _attachmentboundry = strLine;
     }
     else
     {
      /*if(strLine.IndexOf(";")!=-1)
       _attachmentboundry=strLine.Split(';')[1];
      else*/
      _attachmentboundry = strLine;
     }

     int intBound = _attachmentboundry.ToLower().IndexOf("boundary=");
     if (intBound != -1)
     {
      int intBound2 = _attachmentboundry.ToLower().IndexOf(";", intBound + 10);
      if (intBound2 == -1)
       intBound2 = _attachmentboundry.Length;
      intBound2 -= (intBound + 9);
      _attachmentboundry = _attachmentboundry.Substring(intBound + 9, intBound2);
     }
     _attachmentboundry = Utility.RemoveQuote(_attachmentboundry);
     _hasAttachment = true;

     break;

    default:
     if (array.Length > 1) //here we parse all custom headers
     {
      string headerName = array[0].Trim();
      if (headerName.ToUpper().StartsWith("X")) //every custom header starts with "X"
      {
       ParseStreamLines(sbdBuilder, srdReader, headerName, array[1].Trim(), ref strLine, _customHeaders);
      }
     }
     break;
   }
  }
 }

 ///


 /// MIMETypes
 ///

 public class MIMETypes
 {
  public const string MIMEType_MSTNEF = "application/ms-tnef";
  private const string Content_Transfer_Encoding_Tag = "Content-Transfer-Encoding";
  private static Hashtable _MIMETypeList = null;


  public static string GetContentTransferEncoding(string strBuffer, int pos)
  {
   int begin = 0, end = 0;
   begin = strBuffer.ToLower().IndexOf(Content_Transfer_Encoding_Tag.ToLower(), pos);
   if (begin != -1)
   {
    end = strBuffer.ToLower().IndexOf("\r\n".ToLower(), begin + 1);
    return strBuffer.Substring(begin + Content_Transfer_Encoding_Tag.Length + 1, end - begin - Content_Transfer_Encoding_Tag.Length).Trim();
   }
   else
    return "";
  }

  public static bool IsMSTNEF(string strContentType)
  {
   if (strContentType != null & strContentType != "")
    if (strContentType.ToLower() == MIMEType_MSTNEF.ToLower())
     return true;
    else
     return false;
   else
    return false;
  }

  public static string ContentType(string strExtension)
  {
   if (_MIMETypeList.ContainsKey(strExtension))
    return _MIMETypeList[strExtension].ToString();
   else
    return null;
  }

  public static Hashtable MIMETypeList
  {
   get
   {
    return _MIMETypeList;
   }
   set
   {
    _MIMETypeList = value;
   }
  }

  ~MIMETypes()
  {
   _MIMETypeList.Clear();
   _MIMETypeList = null;
  }

  public MIMETypes()
  {
   _MIMETypeList.Add(".323", "text/h323");
   _MIMETypeList.Add(".3gp", "video/3gpp");
   _MIMETypeList.Add(".3gpp", "video/3gpp");
   _MIMETypeList.Add(".acp", "audio/x-mei-aac");
   _MIMETypeList.Add(".act", "text/xml");
   _MIMETypeList.Add(".actproj", "text/plain");
   _MIMETypeList.Add(".ade", "application/msaccess");
   _MIMETypeList.Add(".adp", "application/msaccess");
   _MIMETypeList.Add(".ai", "application/postscript");
   _MIMETypeList.Add(".aif", "audio/aiff");
   _MIMETypeList.Add(".aifc", "audio/aiff");
   _MIMETypeList.Add(".aiff", "audio/aiff");
   _MIMETypeList.Add(".asf", "video/x-ms-asf");
   _MIMETypeList.Add(".asm", "text/plain");
   _MIMETypeList.Add(".asx", "video/x-ms-asf");
   _MIMETypeList.Add(".au", "audio/basic");
   _MIMETypeList.Add(".avi", "video/avi");
   _MIMETypeList.Add(".bmp", "image/bmp");
   _MIMETypeList.Add(".bwp", "application/x-bwpreview");
   _MIMETypeList.Add(".c", "text/plain");
   _MIMETypeList.Add(".cat", "application/vnd.ms-pki.seccat");
   _MIMETypeList.Add(".cc", "text/plain");
   _MIMETypeList.Add(".cdf", "application/x-cdf");
   _MIMETypeList.Add(".cer", "application/x-x509-ca-cert");
   _MIMETypeList.Add(".cod", "text/plain");
   _MIMETypeList.Add(".cpp", "text/plain");
   _MIMETypeList.Add(".crl", "application/pkix-crl");
   _MIMETypeList.Add(".crt", "application/x-x509-ca-cert");
   _MIMETypeList.Add(".cs", "text/plain");
   _MIMETypeList.Add(".css", "text/css");
   _MIMETypeList.Add(".csv", "application/vnd.ms-excel");
   _MIMETypeList.Add(".cxx", "text/plain");
   _MIMETypeList.Add(".dbs", "text/plain");
   _MIMETypeList.Add(".def", "text/plain");
   _MIMETypeList.Add(".der", "application/x-x509-ca-cert");
   _MIMETypeList.Add(".dib", "image/bmp");
   _MIMETypeList.Add(".dif", "video/x-dv");
   _MIMETypeList.Add(".dll", "application/x-msdownload");
   _MIMETypeList.Add(".doc", "application/msword");
   _MIMETypeList.Add(".dot", "application/msword");
   _MIMETypeList.Add(".dsp", "text/plain");
   _MIMETypeList.Add(".dsw", "text/plain");
   _MIMETypeList.Add(".dv", "video/x-dv");
   _MIMETypeList.Add(".edn", "application/vnd.adobe.edn");
   _MIMETypeList.Add(".eml", "message/rfc822");
   _MIMETypeList.Add(".eps", "application/postscript");
   _MIMETypeList.Add(".etd", "application/x-ebx");
   _MIMETypeList.Add(".etp", "text/plain");
   _MIMETypeList.Add(".exe", "application/x-msdownload");
   _MIMETypeList.Add(".ext", "text/plain");
   _MIMETypeList.Add(".fdf", "application/vnd.fdf");
   _MIMETypeList.Add(".fif", "application/fractals");
   _MIMETypeList.Add(".fky", "text/plain");
   _MIMETypeList.Add(".gif", "image/gif");
   _MIMETypeList.Add(".gz", "application/x-gzip");
   _MIMETypeList.Add(".h", "text/plain");
   _MIMETypeList.Add(".hpp", "text/plain");
   _MIMETypeList.Add(".hqx", "application/mac-binhex40");
   _MIMETypeList.Add(".hta", "application/hta");
   _MIMETypeList.Add(".htc", "text/x-component");
   _MIMETypeList.Add(".htm", "text/html");
   _MIMETypeList.Add(".html", "text/html");
   _MIMETypeList.Add(".htt", "text/webviewhtml");
   _MIMETypeList.Add(".hxx", "text/plain");
   _MIMETypeList.Add(".i", "text/plain");
   _MIMETypeList.Add(".iad", "application/x-iad");
   _MIMETypeList.Add(".ico", "image/x-icon");
   _MIMETypeList.Add(".ics", "text/calendar");
   _MIMETypeList.Add(".idl", "text/plain");
   _MIMETypeList.Add(".iii", "application/x-iphone");
   _MIMETypeList.Add(".inc", "text/plain");
   _MIMETypeList.Add(".infopathxml", "application/ms-infopath.xml");
   _MIMETypeList.Add(".inl", "text/plain");
   _MIMETypeList.Add(".ins", "application/x-internet-signup");
   _MIMETypeList.Add(".iqy", "text/x-ms-iqy");
   _MIMETypeList.Add(".isp", "application/x-internet-signup");
   _MIMETypeList.Add(".java", "text/java");
   _MIMETypeList.Add(".jfif", "image/jpeg");
   _MIMETypeList.Add(".jnlp", "application/x-java-jnlp-file");
   _MIMETypeList.Add(".jpe", "image/jpeg");
   _MIMETypeList.Add(".jpeg", "image/jpeg");
   _MIMETypeList.Add(".jpg", "image/jpeg");
   _MIMETypeList.Add(".jsl", "text/plain");
   _MIMETypeList.Add(".kci", "text/plain");
   _MIMETypeList.Add(".la1", "audio/x-liquid-file");
   _MIMETypeList.Add(".lar", "application/x-laplayer-reg");
   _MIMETypeList.Add(".latex", "application/x-latex");
   _MIMETypeList.Add(".lavs", "audio/x-liquid-secure");
   _MIMETypeList.Add(".lgn", "text/plain");
   _MIMETypeList.Add(".lmsff", "audio/x-la-lms");
   _MIMETypeList.Add(".lqt", "audio/x-la-lqt");
   _MIMETypeList.Add(".lst", "text/plain");
   _MIMETypeList.Add(".m1v", "video/mpeg");
   _MIMETypeList.Add(".m3u", "audio/mpegurl");
   _MIMETypeList.Add(".m4e", "video/mpeg4");
   _MIMETypeList.Add(".MAC", "image/x-macpaint");
   _MIMETypeList.Add(".mak", "text/plain");
   _MIMETypeList.Add(".man", "application/x-troff-man");
   _MIMETypeList.Add(".map", "text/plain");
   _MIMETypeList.Add(".mda", "application/msaccess");
   _MIMETypeList.Add(".mdb", "application/msaccess");
   _MIMETypeList.Add(".mde", "application/msaccess");
   _MIMETypeList.Add(".mdi", "image/vnd.ms-modi");
   _MIMETypeList.Add(".mfp", "application/x-shockwave-flash");
   _MIMETypeList.Add(".mht", "message/rfc822");
   _MIMETypeList.Add(".mhtml", "message/rfc822");
   _MIMETypeList.Add(".mid", "audio/mid");
   _MIMETypeList.Add(".midi", "audio/mid");
   _MIMETypeList.Add(".mk", "text/plain");
   _MIMETypeList.Add(".mnd", "audio/x-musicnet-download");
   _MIMETypeList.Add(".mns", "audio/x-musicnet-stream");
   _MIMETypeList.Add(".MP1", "audio/mp1");
   _MIMETypeList.Add(".mp2", "video/mpeg");
   _MIMETypeList.Add(".mp2v", "video/mpeg");
   _MIMETypeList.Add(".mp3", "audio/mpeg");
   _MIMETypeList.Add(".mp4", "video/mp4");
   _MIMETypeList.Add(".mpa", "video/mpeg");
   _MIMETypeList.Add(".mpe", "video/mpeg");
   _MIMETypeList.Add(".mpeg", "video/mpeg");
   _MIMETypeList.Add(".mpf", "application/vnd.ms-mediapackage");
   _MIMETypeList.Add(".mpg", "video/mpeg");
   _MIMETypeList.Add(".mpg4", "video/mp4");
   _MIMETypeList.Add(".mpga", "audio/rn-mpeg");
   _MIMETypeList.Add(".mpv2", "video/mpeg");
   _MIMETypeList.Add(".NMW", "application/nmwb");
   _MIMETypeList.Add(".nws", "message/rfc822");
   _MIMETypeList.Add(".odc", "text/x-ms-odc");
   _MIMETypeList.Add(".odh", "text/plain");
   _MIMETypeList.Add(".odl", "text/plain");
   _MIMETypeList.Add(".p10", "application/pkcs10");
   _MIMETypeList.Add(".p12", "application/x-pkcs12");
   _MIMETypeList.Add(".p7b", "application/x-pkcs7-certificates");
   _MIMETypeList.Add(".p7c", "application/pkcs7-mime");
   _MIMETypeList.Add(".p7m", "application/pkcs7-mime");
   _MIMETypeList.Add(".p7r", "application/x-pkcs7-certreqresp");
   _MIMETypeList.Add(".p7s", "application/pkcs7-signature");
   _MIMETypeList.Add(".PCT", "image/pict");
   _MIMETypeList.Add(".pdf", "application/pdf");
   _MIMETypeList.Add(".pdx", "application/vnd.adobe.pdx");
   _MIMETypeList.Add(".pfx", "application/x-pkcs12");
   _MIMETypeList.Add(".pic", "image/pict");
   _MIMETypeList.Add(".PICT", "image/pict");
   _MIMETypeList.Add(".pko", "application/vnd.ms-pki.pko");
   _MIMETypeList.Add(".png", "image/png");
   _MIMETypeList.Add(".pnt", "image/x-macpaint");
   _MIMETypeList.Add(".pntg", "image/x-macpaint");
   _MIMETypeList.Add(".pot", "application/vnd.ms-powerpoint");
   _MIMETypeList.Add(".ppa", "application/vnd.ms-powerpoint");
   _MIMETypeList.Add(".pps", "application/vnd.ms-powerpoint");
   _MIMETypeList.Add(".ppt", "application/vnd.ms-powerpoint");
   _MIMETypeList.Add(".prc", "text/plain");
   _MIMETypeList.Add(".prf", "application/pics-rules");
   _MIMETypeList.Add(".ps", "application/postscript");
   _MIMETypeList.Add(".pub", "application/vnd.ms-publisher");
   _MIMETypeList.Add(".pwz", "application/vnd.ms-powerpoint");
   _MIMETypeList.Add(".qt", "video/quicktime");
   _MIMETypeList.Add(".qti", "image/x-quicktime");
   _MIMETypeList.Add(".qtif", "image/x-quicktime");
   _MIMETypeList.Add(".qtl", "application/x-quicktimeplayer");
   _MIMETypeList.Add(".qup", "application/x-quicktimeupdater");
   _MIMETypeList.Add(".r1m", "application/vnd.rn-recording");
   _MIMETypeList.Add(".r3t", "text/vnd.rn-realtext3d");
   _MIMETypeList.Add(".RA", "audio/vnd.rn-realaudio");
   _MIMETypeList.Add(".RAM", "audio/x-pn-realaudio");
   _MIMETypeList.Add(".rat", "application/rat-file");
   _MIMETypeList.Add(".rc", "text/plain");
   _MIMETypeList.Add(".rc2", "text/plain");
   _MIMETypeList.Add(".rct", "text/plain");
   _MIMETypeList.Add(".rec", "application/vnd.rn-recording");
   _MIMETypeList.Add(".rgs", "text/plain");
   _MIMETypeList.Add(".rjs", "application/vnd.rn-realsystem-rjs");
   _MIMETypeList.Add(".rjt", "application/vnd.rn-realsystem-rjt");
   _MIMETypeList.Add(".RM", "application/vnd.rn-realmedia");
   _MIMETypeList.Add(".rmf", "application/vnd.adobe.rmf");
   _MIMETypeList.Add(".rmi", "audio/mid");
   _MIMETypeList.Add(".RMJ", "application/vnd.rn-realsystem-rmj");
   _MIMETypeList.Add(".RMM", "audio/x-pn-realaudio");
   _MIMETypeList.Add(".rms", "application/vnd.rn-realmedia-secure");
   _MIMETypeList.Add(".rmvb", "application/vnd.rn-realmedia-vbr");
   _MIMETypeList.Add(".RMX", "application/vnd.rn-realsystem-rmx");
   _MIMETypeList.Add(".RNX", "application/vnd.rn-realplayer");
   _MIMETypeList.Add(".rp", "image/vnd.rn-realpix");
   _MIMETypeList.Add(".RPM", "audio/x-pn-realaudio-plugin");
   _MIMETypeList.Add(".rqy", "text/x-ms-rqy");
   _MIMETypeList.Add(".rsml", "application/vnd.rn-rsml");
   _MIMETypeList.Add(".rt", "text/vnd.rn-realtext");
   _MIMETypeList.Add(".rtf", "application/msword");
   _MIMETypeList.Add(".rul", "text/plain");
   _MIMETypeList.Add(".RV", "video/vnd.rn-realvideo");
   _MIMETypeList.Add(".s", "text/plain");
   _MIMETypeList.Add(".sc2", "application/schdpl32");
   _MIMETypeList.Add(".scd", "application/schdpl32");
   _MIMETypeList.Add(".sch", "application/schdpl32");
   _MIMETypeList.Add(".sct", "text/scriptlet");
   _MIMETypeList.Add(".sd2", "audio/x-sd2");
   _MIMETypeList.Add(".sdp", "application/sdp");
   _MIMETypeList.Add(".sit", "application/x-stuffit");
   _MIMETypeList.Add(".slk", "application/vnd.ms-excel");
   _MIMETypeList.Add(".sln", "application/octet-stream");
   _MIMETypeList.Add(".SMI", "application/smil");
   _MIMETypeList.Add(".smil", "application/smil");
   _MIMETypeList.Add(".snd", "audio/basic");
   _MIMETypeList.Add(".snp", "application/msaccess");
   _MIMETypeList.Add(".spc", "application/x-pkcs7-certificates");
   _MIMETypeList.Add(".spl", "application/futuresplash");
   _MIMETypeList.Add(".sql", "text/plain");
   _MIMETypeList.Add(".srf", "text/plain");
   _MIMETypeList.Add(".ssm", "application/streamingmedia");
   _MIMETypeList.Add(".sst", "application/vnd.ms-pki.certstore");
   _MIMETypeList.Add(".stl", "application/vnd.ms-pki.stl");
   _MIMETypeList.Add(".swf", "application/x-shockwave-flash");
   _MIMETypeList.Add(".tab", "text/plain");
   _MIMETypeList.Add(".tar", "application/x-tar");
   _MIMETypeList.Add(".tdl", "text/xml");
   _MIMETypeList.Add(".tgz", "application/x-compressed");
   _MIMETypeList.Add(".tif", "image/tiff");
   _MIMETypeList.Add(".tiff", "image/tiff");
   _MIMETypeList.Add(".tlh", "text/plain");
   _MIMETypeList.Add(".tli", "text/plain");
   _MIMETypeList.Add(".torrent", "application/x-bittorrent");
   _MIMETypeList.Add(".trg", "text/plain");
   _MIMETypeList.Add(".txt", "text/plain");
   _MIMETypeList.Add(".udf", "text/plain");
   _MIMETypeList.Add(".udt", "text/plain");
   _MIMETypeList.Add(".uls", "text/iuls");
   _MIMETypeList.Add(".user", "text/plain");
   _MIMETypeList.Add(".usr", "text/plain");
   _MIMETypeList.Add(".vb", "text/plain");
   _MIMETypeList.Add(".vcf", "text/x-vcard");
   _MIMETypeList.Add(".vcproj", "text/plain");
   _MIMETypeList.Add(".viw", "text/plain");
   _MIMETypeList.Add(".vpg", "application/x-vpeg005");
   _MIMETypeList.Add(".vspscc", "text/plain");
   _MIMETypeList.Add(".vsscc", "text/plain");
   _MIMETypeList.Add(".vssscc", "text/plain");
   _MIMETypeList.Add(".wav", "audio/wav");
   _MIMETypeList.Add(".wax", "audio/x-ms-wax");
   _MIMETypeList.Add(".wbk", "application/msword");
   _MIMETypeList.Add(".wiz", "application/msword");
   _MIMETypeList.Add(".wm", "video/x-ms-wm");
   _MIMETypeList.Add(".wma", "audio/x-ms-wma");
   _MIMETypeList.Add(".wmd", "application/x-ms-wmd");
   _MIMETypeList.Add(".wmv", "video/x-ms-wmv");
   _MIMETypeList.Add(".wmx", "video/x-ms-wmx");
   _MIMETypeList.Add(".wmz", "application/x-ms-wmz");
   _MIMETypeList.Add(".wpl", "application/vnd.ms-wpl");
   _MIMETypeList.Add(".wprj", "application/webzip");
   _MIMETypeList.Add(".wsc", "text/scriptlet");
   _MIMETypeList.Add(".wvx", "video/x-ms-wvx");
   _MIMETypeList.Add(".XBM", "image/x-xbitmap");
   _MIMETypeList.Add(".xdp", "application/vnd.adobe.xdp+xml");
   _MIMETypeList.Add(".xfd", "application/vnd.adobe.xfd+xml");
   _MIMETypeList.Add(".xfdf", "application/vnd.adobe.xfdf");
   _MIMETypeList.Add(".xla", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlb", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlc", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xld", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlk", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xll", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlm", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xls", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlt", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlv", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xlw", "application/vnd.ms-excel");
   _MIMETypeList.Add(".xml", "text/xml");
   _MIMETypeList.Add(".xpl", "audio/scpls");
   _MIMETypeList.Add(".xsl", "text/xml");
   _MIMETypeList.Add(".z", "application/x-compress");
   _MIMETypeList.Add(".zip", "application/x-zip-compressed");
  }

  ///

Returns the MIME content-type for the supplied file extension
  /// string MIME type (Example: \"text/plain\")
  public static string GetMimeType(string strFileName)
  {
   try
   {
    string strFileExtension = new FileInfo(strFileName).Extension;
    string strContentType = null;
    bool MONO = false;

    if (MONO)
    {
     strContentType = MIMETypes.ContentType(strFileExtension);
    }
    else
    {
     Microsoft.Win32.RegistryKey extKey = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(strFileExtension);
     strContentType = (string) extKey.GetValue("Content Type");
    }

    if (strContentType.ToString() != null)
    {
     return strContentType.ToString();
    }
    else
    {
     return "application/octet-stream";
    }
   }
   catch (System.Exception)
   {
    return "application/octet-stream";
   }
  }

 }

 ///


 /// Summary description for Coding.
 ///

 public class QuotedCoding
 {
  ///
  /// zwraca tablice bajtow
  /// zamienia 3 znaki np '=A9' na odp wartosc.
  /// zamienia '_' na znak 32
  ///

  /// Kupis_Pawe=B3
  /// Kupis Pawe?/returns>
  public static byte[] GetByteArray(string s)
  {
   byte[] buffer = new byte[s.Length];

   int bufferPosition = 0;
   if (s.Length > 1)
   {
    for (int i = 0; i < s.Length; i++)
    {
     if (s[i] == '=')
     {
      if (s[i + 1] == '\r' && s[i + 2] == '\n')
       bufferPosition--;
      else
       buffer[bufferPosition] = System.Convert.ToByte(s.Substring(i + 1, 2), 16);
      i += 2;
     }
     else if (s[i] == '_')
      buffer[bufferPosition] = 32;
     else
      buffer[bufferPosition] = (byte) s[i];
     bufferPosition++;
    }
   }
   else
   {
    buffer[bufferPosition] = 32;
   }

   byte[] newArray = new byte[bufferPosition];
   Array.Copy(buffer, newArray, bufferPosition);
   return newArray;
  }

  ///


  /// Decoduje string "=?iso-8859-2?Q?Kupis_Pawe=B3?="
  /// lub zakodowany base64
  /// na poprawny
  ///

  /// "=?iso-8859-2?Q?Kupis_Pawe=B3?="
  /// Kupis Pawe?/returns>
  public static string DecodeOne(string s)
  {
   char[] separator = {'?'};
   string[] sArray = s.Split(separator);
   if (sArray[0].Equals("=") == false)
    return s;

   byte[] bArray;
   //rozpoznaj rodzj kodowania
   if (sArray[2].ToUpper() == "Q") //querystring
    bArray = GetByteArray(sArray[3]);
   else if (sArray[2].ToUpper() == "B") //base64
    bArray = Convert.FromBase64String(sArray[3]);
   else
    return s;
   //pobierz strone kodowa
   Encoding encoding = Encoding.GetEncoding(sArray[1]);
   return encoding.GetString(bArray);
  }

  ///


  /// decoduje string zamienia wpisy (=?...?=) na odp wartosci
  ///

  /// "ala i =?iso-8859-2?Q?Kupis_Pawe=B3?= ma kota"
  /// "ala i Pawe?Kupis ma kota"
  public static string Decode(string s)
  {
   StringBuilder retstring = new StringBuilder();
   int old = 0, start = 0, stop;
   for (;; )
   {
    start = s.IndexOf("=?", start);
    if (start == -1)
    {
     retstring.Append(s, old, s.Length - old);
     return retstring.ToString();
    }
    stop = s.IndexOf("?=", start + 2);
    if (stop == -1) //blad w stringu
     return s;
    retstring.Append(s, old, start - old);
    retstring.Append(DecodeOne(s.Substring(start, stop - start + 2)));
    start = stop + 2;
    old = stop + 2;
   }
  }

 }

 ///


 /// TNEFAttachment
 ///

 public class TNEFAttachment
 {
  #region Member Variables

  private string _fileName = "";
  private long _fileLength = 0;
  private string _subject = "";
  private byte[] _fileContent = null;

  #endregion

  #region Properties

  ///


  /// attachment subject
  ///

  public string Subject
  {
   get
   {
    return _subject;
   }
   set
   {
    _subject = value;
   }
  }

  ///


  /// attachment file length
  ///

  public long FileLength
  {
   get
   {
    return _fileLength;
   }
   set
   {
    _fileLength = value;
   }
  }

  ///


  /// attachment file name
  ///

  public string FileName
  {
   get
   {
    return _fileName;
   }
   set
   {
    _fileName = value;
   }
  }

  ///


  /// attachment file content
  ///

  public byte[] FileContent
  {
   get
   {
    return _fileContent;
   }
   set
   {
    _fileContent = value;
   }
  }

  #endregion

  public TNEFAttachment()
  {
  }

  ~TNEFAttachment()
  {
   _fileContent = null;
  }
 }

 ///


 /// OpenPOP.MIMEParser.TNEFParser
 ///

 public class TNEFParser
 {
  #region Member Variables

  private const int TNEF_SIGNATURE = 0x223e9f78;
  private const int LVL_MESSAGE = 0x01;
  private const int LVL_ATTACHMENT = 0x02;
  private const int _string = 0x00010000;
  private const int _BYTE = 0x00060000;
  private const int _WORD = 0x00070000;
  private const int _DWORD = 0x00080000;

  private const int AVERSION = (_DWORD | 0x9006);
  private const int AMCLASS = (_WORD | 0x8008);
  private const int ASUBJECT = (_DWORD | 0x8004);
  private const int AFILENAME = (_string | 0x8010);
  private const int ATTACHDATA = (_BYTE | 0x800f);

  private Stream fsTNEF;
  private Hashtable _attachments = new Hashtable();
  private TNEFAttachment _attachment = null;

  private bool _verbose = false;
  //private string _logFile="OpenPOP.TNEF.log";
  private string _basePath = null;
  private int _skipSignature = 0;
  private bool _searchSignature = false;
  private long _offset = 0;
  private long _fileLength = 0;
  private string _tnefFile = "";
  private string strSubject;

  #endregion

  #region Properties

  //  public string LogFilePath
  //  {
  //   get{return _logFile;}
  //   set{_logFile=value;}
  //  }

  public string TNEFFile
  {
   get
   {
    return _tnefFile;
   }
   set
   {
    _tnefFile = value;
   }
  }

  public bool Verbose
  {
   get
   {
    return _verbose;
   }
   set
   {
    _verbose = value;
   }
  }

  public string BasePath
  {
   get
   {
    return _basePath;
   }
   set
   {
    try
    {
     if (value.EndsWith("\\"))
      _basePath = value;
     else
      _basePath = value + "\\";
    }
    catch
    {
    }
   }
  }

  public int SkipSignature
  {
   get
   {
    return _skipSignature;
   }
   set
   {
    _skipSignature = value;
   }
  }

  public bool SearchSignature
  {
   get
   {
    return _searchSignature;
   }
   set
   {
    _searchSignature = value;
   }
  }

  public long Offset
  {
   get
   {
    return _offset;
   }
   set
   {
    _offset = value;
   }
  }

  #endregion

  private int GETINT32(byte[] p)
  {
   return (p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24));
  }

  private short GETINT16(byte[] p)
  {
   return (short) (p[0] + (p[1] << 8));
  }

  private int geti32()
  {
   byte[] buf = new byte[4];

   if (StreamReadBytes(buf, 4) != 1)
   {
    Utility.LogError("geti32():unexpected end of input\n");
    return 1;
   }
   return GETINT32(buf);
  }

  private int geti16()
  {
   byte[] buf = new byte[2];

   if (StreamReadBytes(buf, 2) != 1)
   {
    Utility.LogError("geti16():unexpected end of input\n");
    return 1;
   }
   return GETINT16(buf);
  }

  private int geti8()
  {
   byte[] buf = new byte[1];

   if (StreamReadBytes(buf, 1) != 1)
   {
    Utility.LogError("geti8():unexpected end of input\n");
    return 1;
   }
   return (int) buf[0];
  }

  private int StreamReadBytes(byte[] buffer, int size)
  {
   try
   {
    if (fsTNEF.Position + size <= _fileLength)
    {
     fsTNEF.Read(buffer, 0, size);
     return 1;
    }
    else
     return 0;
   }
   catch (Exception e)
   {
    Utility.LogError("StreamReadBytes():" + e.Message);
    return 0;
   }
  }

  private void CloseTNEFStream()
  {
   try
   {
    fsTNEF.Close();
   }
   catch (Exception e)
   {
    Utility.LogError("CloseTNEFStream():" + e.Message);
   }
  }

  ///


  /// Open the MS-TNEF stream from file
  ///

  /// MS-TNEF file
  ///
  public bool OpenTNEFStream(string strFile)
  {
   //Utility.LogFilePath=LogFilePath;

   TNEFFile = strFile;
   try
   {
    fsTNEF = new FileStream(strFile, FileMode.Open, FileAccess.Read);
    FileInfo fi = new FileInfo(strFile);
    _fileLength = fi.Length;
    fi = null;
    return true;
   }
   catch (Exception e)
   {
    Utility.LogError("OpenTNEFStream(File):" + e.Message);
    return false;
   }
  }

  ///


  /// Open the MS-TNEF stream from bytes
  ///

  /// MS-TNEF bytes
  ///
  public bool OpenTNEFStream(byte[] bytContents)
  {
   //Utility.LogFilePath=LogFilePath;

   try
   {
    fsTNEF = new MemoryStream(bytContents);
    _fileLength = bytContents.Length;
    return true;
   }
   catch (Exception e)
   {
    Utility.LogError("OpenTNEFStream(Bytes):" + e.Message);
    return false;
   }
  }

  ///


  /// Find the MS-TNEF signature
  ///

  /// true if found, vice versa
  public bool FindSignature()
  {
   bool ret = false;
   long lpos = 0;

   int d;

   try
   {
    for (lpos = 0;; lpos++)
    {
     if (fsTNEF.Seek(lpos, SeekOrigin.Begin) == -1)
     {
      PrintResult("No signature found\n");
      return false;
     }

     d = geti32();
     if (d == TNEF_SIGNATURE)
     {
      PrintResult("Signature found at {0}\n", lpos);
      break;
     }
    }
    ret = true;
   }
   catch (Exception e)
   {
    Utility.LogError("FindSignature():" + e.Message);
    ret = false;
   }

   fsTNEF.Position = lpos;

   return ret;
  }

  private void decode_attribute(int d)
  {
   byte[] buf = new byte[4000];
   int len;
   int v;
   int i;

   len = geti32(); /* data length */

   switch (d & 0xffff0000)
   {
    case _BYTE:
     PrintResult("Attribute {0} =", d & 0xffff);
     for (i = 0; i < len; i += 1)
     {
      v = geti8();

      if (i < 10) PrintResult(" {0}", v);
      else if (i == 10) PrintResult("...");
     }
     PrintResult("\n");
     break;
    case _WORD:
     PrintResult("Attribute {0} =", d & 0xffff);
     for (i = 0; i < len; i += 2)
     {
      v = geti16();

      if (i < 6) PrintResult(" {0}", v);
      else if (i == 6) PrintResult("...");
     }
     PrintResult("\n");
     break;
    case _DWORD:
     PrintResult("Attribute {0} =", d & 0xffff);
     for (i = 0; i < len; i += 4)
     {
      v = geti32();

      if (i < 4) PrintResult(" {0}", v);
      else if (i == 4) PrintResult("...");
     }
     PrintResult("\n");
     break;
    case _string:
     StreamReadBytes(buf, len);

     PrintResult("Attribute {0} = {1}\n", d & 0xffff, Encoding.Default.GetString(buf));
     break;
    default:
     StreamReadBytes(buf, len);
     PrintResult("Attribute {0}\n", d);
     break;
   }

   geti16(); /* checksum */
  }

  private void decode_message()
  {
   int d;

   d = geti32();

   decode_attribute(d);
  }

  private void decode_attachment()
  {
   byte[] buf = new byte[4096];
   int d;
   int len;
   int i, chunk;

   d = geti32();

   switch (d)
   {
    case ASUBJECT:
     len = geti32();

     StreamReadBytes(buf, len);

     byte[] _subjectBuffer = new byte[len - 1];

     Array.Copy(buf, _subjectBuffer, (long) len - 1);

     strSubject = Encoding.Default.GetString(_subjectBuffer);

     PrintResult("Found subject: {0}", strSubject);

     geti16(); /* checksum */

     break;

    case AFILENAME:
     len = geti32();
     StreamReadBytes(buf, len);
     //PrintResult("File-Name: {0}\n", buf);
     byte[] _fileNameBuffer = new byte[len - 1];
     Array.Copy(buf, _fileNameBuffer, (long) len - 1);

     if (_fileNameBuffer == null) _fileNameBuffer = Encoding.Default.GetBytes("tnef.dat");
     string strFileName = Encoding.Default.GetString(_fileNameBuffer);

     PrintResult("{0}: WRITING {1}\n", BasePath, strFileName);

     //new attachment found because attachment data goes before attachment name
     _attachment.FileName = strFileName;
     _attachment.Subject = strSubject;
     _attachments.Add(_attachment.FileName, _attachment);

     geti16(); /* checksum */

     break;

    case ATTACHDATA:
     len = geti32();
     PrintResult("ATTACH-DATA: {0} bytes\n", len);

     _attachment = new TNEFAttachment();
     _attachment.FileContent = new byte[len];
     _attachment.FileLength = len;

     for (i = 0; i < len; )
     {
      chunk = len - i;
      if (chunk > buf.Length) chunk = buf.Length;

      StreamReadBytes(buf, chunk);

      Array.Copy(buf, 0, _attachment.FileContent, i, chunk);

      i += chunk;
     }

     geti16(); /* checksum */

     break;

    default:
     decode_attribute(d);
     break;
   }
  }

  ///


  /// decoded attachments
  ///

  /// attachment array
  public Hashtable Attachments()
  {
   return _attachments;
  }

  ///


  /// save all decoded attachments to files
  ///

  /// true is succeded, vice versa
  public bool SaveAttachments()
  {
   bool blnRet = false;
   IDictionaryEnumerator ideAttachments = _attachments.GetEnumerator();

   while (ideAttachments.MoveNext())
   {
    blnRet = SaveAttachment((TNEFAttachment) ideAttachments.Value);
   }

   return blnRet;
  }

  ///


  /// save a decoded attachment to file
  ///

  /// decoded attachment
  /// true is succeded, vice versa
  public bool SaveAttachment(TNEFAttachment attachment)
  {
   try
   {
    string strOutFile = BasePath + attachment.FileName;

    if (File.Exists(strOutFile))
     File.Delete(strOutFile);
    FileStream fsData = new FileStream(strOutFile, FileMode.CreateNew, FileAccess.Write);

    fsData.Write(attachment.FileContent, 0, (int) attachment.FileLength);

    fsData.Close();

    return true;
   }
   catch (Exception e)
   {
    Utility.LogError("SaveAttachment():" + e.Message);
    return false;
   }
  }

  ///


  /// parse MS-TNEF stream
  ///

  /// true is succeded, vice versa
  public bool Parse()
  {
   byte[] buf = new byte[4];
   int d;

   if (FindSignature())
   {
    if (SkipSignature < 2)
    {
     d = geti32();
     if (SkipSignature < 1)
     {
      if (d != TNEF_SIGNATURE)
      {
       PrintResult("Seems not to be a TNEF file\n");
       return false;
      }
     }
    }

    d = geti16();
    PrintResult("TNEF Key is: {0}\n", d);
    for (;; )
    {
     if (StreamReadBytes(buf, 1) == 0)
      break;

     d = (int) buf[0];

     switch (d)
     {
      case LVL_MESSAGE:
       PrintResult("{0}: Decoding Message Attributes\n", fsTNEF.Position);
       decode_message();
       break;
      case LVL_ATTACHMENT:
       PrintResult("Decoding Attachment\n");
       decode_attachment();
       break;
      default:
       PrintResult("Coding Error in TNEF file\n");
       return false;
     }
    }
    return true;
   }
   else
    return false;
  }

  private void PrintResult(string strResult, params object[] strContent)
  {
   string strRet = string.Format(strResult, strContent);
   if (Verbose)
    Utility.LogError(strRet);
  }

  ~TNEFParser()
  {
   _attachments = null;
   CloseTNEFStream();
  }

  public TNEFParser()
  {
  }

  ///


  /// open MS-TNEF stream from a file
  ///

  /// MS-TNEF file
  public TNEFParser(string strFile)
  {
   OpenTNEFStream(strFile);
  }

  ///


  /// open MS-TNEF stream from bytes
  ///

  /// MS-TNEF bytes
  public TNEFParser(byte[] bytContents)
  {
   OpenTNEFStream(bytContents);
  }
 }

 ///


 /// Summary description for Utility.
 ///

 public class Utility
 {
  private static bool m_blnLog = false;
  private static string m_strLogFile = "OpenPOP.log";

  public Utility()
  {
  }

  //  public static string[] SplitText(string strText, string strSplitter)
  //  {
  //   string []segments=new string[0];
  //   int indexOfstrSplitter=strText.IndexOf(strSplitter);
  //   if(indexOfstrSplitter!=-1)
  //   {
  //
  //   }
  //   return segments;
  //  }
  //

  ///


  /// Verifies whether the file is of picture type or not
  ///

  /// File to be verified
  /// True if picture file, false if not
  public static bool IsPictureFile(string strFile)
  {
   try
   {
    if (strFile != null && strFile != "")
    {
     strFile = strFile.ToLower();
     if (strFile.EndsWith(".jpg") || strFile.EndsWith(".bmp") || strFile.EndsWith(".ico") || strFile.EndsWith(".gif") || strFile.EndsWith(".png"))
      return true;
     else
      return false;
    }
    else
     return false;
   }
   catch
   {
    return false;
   }
  }

  ///


  /// Parse date time info from MIME header
  ///

  /// Encoded MIME date time
  /// Decoded date time info
  public static string ParseEmailDate(string strDate)
  {
   string strRet = strDate.Trim();
   int indexOfTag = strRet.IndexOf(",");
   if (indexOfTag != -1)
   {
    strRet = strRet.Substring(indexOfTag + 1);
   }

   strRet = QuoteText(strRet, "+");
   strRet = QuoteText(strRet, "-");
   strRet = QuoteText(strRet, "GMT");
   strRet = QuoteText(strRet, "CST");
   return strRet.Trim();
  }

  ///


  /// Quote the text according to a tag
  ///

  /// Text to be quoted
  /// Quote tag
  /// Quoted Text
  public static string QuoteText(string strText, string strTag)
  {
   int indexOfTag = strText.IndexOf(strTag);
   if (indexOfTag != -1)
    return strText.Substring(0, indexOfTag - 1);
   else
    return strText;
  }

  ///


  /// Parse file name from MIME header
  ///

  /// MIME header
  /// Decoded file name
  public static string ParseFileName(string strHeader)
  {
   string strTag;
   strTag = "filename=";
   int intPos = strHeader.ToLower().IndexOf(strTag);
   if (intPos == -1)
   {
    strTag = "name=";
    intPos = strHeader.ToLower().IndexOf(strTag);
   }
   string strRet;
   if (intPos != -1)
   {
    strRet = strHeader.Substring(intPos + strTag.Length);
    intPos = strRet.ToLower().IndexOf(";");
    if (intPos != -1)
     strRet = strRet.Substring(1, intPos - 1);
    strRet = RemoveQuote(strRet);
   }
   else
    strRet = "";

   return strRet;
  }

  ///


  /// Parse email address from MIME header
  ///

  /// MIME header
  /// Decoded user name
  /// Decoded email address
  /// True if decoding succeeded, false if failed
  public static bool ParseEmailAddress(string strEmailAddress, ref string strUser, ref string strAddress)
  {
   int indexOfAB = strEmailAddress.Trim().LastIndexOf("<");
   int indexOfEndAB = strEmailAddress.Trim().LastIndexOf(">");
   strUser = strEmailAddress;
   strAddress = strEmailAddress;
   if (indexOfAB >= 0 && indexOfEndAB >= 0)
   {
    if (indexOfAB > 0)
    {
     strUser = strUser.Substring(0, indexOfAB - 1);
     //     strUser=strUser.Substring(0,indexOfAB-1).Trim('\"');
     //     if(strUser.IndexOf("\"")>=0)
     //     {
     //      strUser=strUser.Substring(1,strUser.Length-1);
     //     }
    }
    strUser = strUser.Trim();
    strUser = strUser.Trim('\"');
    strAddress = strAddress.Substring(indexOfAB + 1, indexOfEndAB - (indexOfAB + 1));
   }
   strUser = strUser.Trim();
   strUser = DecodeText(strUser);
   strAddress = strAddress.Trim();

   return true;
  }

  ///


  /// Save byte content to a file
  ///

  /// File to be saved to
  /// Byte array content
  /// True if saving succeeded, false if failed
  public static bool SaveByteContentToFile(string strFile, byte[] bytContent)
  {
   try
   {
    if (File.Exists(strFile))
     File.Delete(strFile);
    FileStream fs = File.Create(strFile);
    fs.Write(bytContent, 0, bytContent.Length);
    fs.Close();
    return true;
   }
   catch (Exception e)
   {
    Utility.LogError("SaveByteContentToFile():" + e.Message);
    return false;
   }
  }

  ///


  /// Save text content to a file
  ///

  /// File to be saved to
  /// Text content
  /// Replace file if exists
  /// True if saving succeeded, false if failed
  public static bool SavePlainTextToFile(string strFile, string strText, bool blnReplaceExists)
  {
   try
   {
    bool blnRet = true;

    if (File.Exists(strFile))
    {
     if (blnReplaceExists)
      File.Delete(strFile);
     else
      blnRet = false;
    }

    if (blnRet == true)
    {
     StreamWriter sw = File.CreateText(strFile);
     sw.Write(strText);
     sw.Close();
    }

    return blnRet;
   }
   catch (Exception e)
   {
    Utility.LogError("SavePlainTextToFile():" + e.Message);
    return false;
   }
  }

  ///


  /// Read text content from a file
  ///

  /// File to be read from
  /// Read text content
  /// True if reading succeeded, false if failed
  public static bool ReadPlainTextFromFile(string strFile, ref string strText)
  {
   if (File.Exists(strFile))
   {
    StreamReader fs = new StreamReader(strFile);
    strText = fs.ReadToEnd();
    fs.Close();
    return true;
   }
   else
    return false;
  }

  ///


  /// Sepearte header name and header value
  ///

  ///
  ///
  public static string[] GetHeadersValue(string strRawHeader)
  {
   if (strRawHeader == null)
    throw new ArgumentNullException("strRawHeader", "Argument was null");

   string[] array = new string[2] {"", ""};
   int indexOfColon = strRawHeader.IndexOf(":");

   try
   {
    array[0] = strRawHeader.Substring(0, indexOfColon).Trim();
    array[1] = strRawHeader.Substring(indexOfColon + 1).Trim();
   }
   catch (Exception)
   {
   }

   return array;
  }

  ///


  /// Get quoted text
  ///

  /// Text with quotes
  /// Splitter
  /// Target tag
  /// Text without quote
  public static string GetQuotedValue(string strText, string strSplitter, string strTag)
  {
   if (strText == null)
    throw new ArgumentNullException("strText", "Argument was null");

   string[] array = new string[2] {"", ""};
   int indexOfstrSplitter = strText.IndexOf(strSplitter);

   try
   {
    array[0] = strText.Substring(0, indexOfstrSplitter).Trim();
    array[1] = strText.Substring(indexOfstrSplitter + 1).Trim();
    int pos = array[1].IndexOf("\"");
    if (pos != -1)
    {
     int pos2 = array[1].IndexOf("\"", pos + 1);
     array[1] = array[1].Substring(pos + 1, pos2 - pos - 1);
    }
   }
   catch (Exception)
   {
   }

   //return array;
   if (array[0].ToLower() == strTag.ToLower())
    return array[1].Trim();
   else
    return null;

   /*   string []array=null;
      try
      {
       array=Regex.Split(strText,strSplitter);
       //return array;
       if(array[0].ToLower()==strTag.ToLower())
        return RemoveQuote(array[1].Trim());
       else
        return null;
      }
      catch
      {return null;}*/
  }

  ///


  /// Change text encoding
  ///

  /// Source encoded text
  /// New charset
  /// Encoded text with new charset
  public static string Change(string strText, string strCharset)
  {
   if (strCharset == null || strCharset == "")
    return strText;
   byte[] b = Encoding.Default.GetBytes(strText);
   return new string(Encoding.GetEncoding(strCharset).GetChars(b));
  }

  ///


  /// Remove non-standard base 64 characters
  ///

  /// Source text
  /// standard base 64 text
  public static string RemoveNonB64(string strText)
  {
   return strText.Replace("\0", "");
  }

  ///


  /// Remove white blank characters
  ///

  /// Source text
  /// Text with white blanks
  public static string RemoveWhiteBlanks(string strText)
  {
   return strText.Replace("\0", "").Replace("\r\n", "");
  }

  ///


  /// Remove quotes
  ///

  /// Text with quotes
  /// Text without quotes
  public static string RemoveQuote(string strText)
  {
   string strRet = strText;
   if (strRet.StartsWith("\""))
    strRet = strRet.Substring(1);
   if (strRet.EndsWith("\""))
    strRet = strRet.Substring(0, strRet.Length - 1);
   return strRet;
  }

  ///


  /// Decode one line of text
  ///

  /// Encoded text
  /// Decoded text
  public static string DecodeLine(string strText)
  {
   return DecodeText(RemoveWhiteBlanks(strText));
  }

  ///


  /// Verifies wether the text is a valid MIME Text or not
  ///

  /// Text to be verified
  /// True if MIME text, false if not
  private static bool IsValidMIMEText(string strText)
  {
   int intPos = strText.IndexOf("=?");
   return (intPos != -1 && strText.IndexOf("?=", intPos + 6) != -1 && strText.Length > 7);
  }

  ///


  /// Decode text
  ///

  /// Source text
  /// Decoded text
  public static string DecodeText(string strText)
  {
   /*try
   {
    string strRet="";
    string strBody="";
    MatchCollection mc=Regex.Matches(strText,@"\=\?(?\S+)\?(?\w)\?(?\S+)\?\=");

    for(int i=0;i    {
     if(mc[i].Success)
     {
      strBody=mc[i].Groups["Content"].Value;

      switch(mc[i].Groups["Encoding"].Value.ToUpper())
      {
       case "B":
        strBody=deCodeB64s(strBody,mc[i].Groups["Charset"].Value);
        break;
       case "Q":
        strBody=DecodeQP.ConvertHexContent(strBody);//, m.Groups["Charset"].Value);
        break;
       default:
        break;
      }
      strRet+=strBody;
     }
     else
     {
      strRet+=mc[i].Value;
     }
    }
    return strRet;
   }
   catch
   {return strText;}*/

   try
   {
    string strRet = "";
    string[] strParts = Regex.Split(strText, "\r\n");
    string strBody = "";
    const string strRegEx = @"\=\?(?\S+)\?(?\w)\?(?\S+)\?\=";
    Match m = null;

    for (int i = 0; i < strParts.Length; i++)
    {
     m = Regex.Match(strParts[i], strRegEx);
     if (m.Success)
     {
      strBody = m.Groups["Content"].Value;

      switch (m.Groups["Encoding"].Value.ToUpper())
      {
       case "B":
        strBody = deCodeB64s(strBody, m.Groups["Charset"].Value);
        break;
       case "Q":
        strBody = DecodeQP.ConvertHexContent(strBody); //, m.Groups["Charset"].Value);
        break;
       default:
        break;
      }
      strRet += strBody;
     }
     else
     {
      if (!IsValidMIMEText(strParts[i]))
       strRet += strParts[i];
      else
      {
       //blank text
      }
     }
    }
    return strRet;
   }
   catch
   {
    return strText;
   }

   /*  
     {
      try
      {
       if(strText!=null&&strText!="")
       {
        if(IsValidMIMEText(strText))
        {
         //position at the end of charset
         int intPos=strText.IndexOf("=?");
         int intPos2=strText.IndexOf("?",intPos+2);
         if(intPos2>3)
         {
          string strCharset=strText.Substring(2,intPos2-2);
          string strEncoding=strText.Substring(intPos2+1,1);
          int intPos3=strText.IndexOf("?=",intPos2+3);
          string strBody=strText.Substring(intPos2+3,intPos3-intPos2-3);
          string strHead="";
          if(intPos>0)
          {
           strHead=strText.Substring(0,intPos-1);
          }
          string strEnd="";
          if(intPos3          {
           strEnd=strText.Substring(intPos3+2);
          }
          switch(strEncoding.ToUpper())
          {
           case "B":
            strBody=deCodeB64s(strBody);
            break;
           case "Q":
            strBody=DecodeQP.ConvertHexContent(strBody);
            break;
           default:
            break;
          }
          strText=strHead+strBody+strEnd;
          if(IsValidMIMEText(strText))
           return DecodeText(strText);
          else
           return strText;
         }
         else
         {return strText;}
        }
        else
        {return strText;}
       }
       else
       {return strText;}
      }
      catch
      {return strText;}*/
  }

  ///


  ///
  ///

  ///
  ///
  public static string deCodeB64s(string strText)
  {
   return Encoding.Default.GetString(deCodeB64(strText));
  }

  public static string deCodeB64s(string strText, string strEncoding)
  {
   try
   {
    if (strEncoding.ToLower() == "ISO-8859-1".ToLower())
     return deCodeB64s(strText);
    else
     return Encoding.GetEncoding(strEncoding).GetString(deCodeB64(strText));
   }
   catch
   {
    return deCodeB64s(strText);
   }
  }

  private static byte[] deCodeB64(string strText)
  {
   byte[] by = null;
   try
   {
    if (strText != "")
    {
     by = Convert.FromBase64String(strText);
     //strText=Encoding.Default.GetString(by);
    }
   }
   catch (Exception e)
   {
    by = Encoding.Default.GetBytes("\0");
    LogError("deCodeB64():" + e.Message);
   }
   return by;
  }

  ///


  /// Turns file logging on and off.
  ///

  /// Comming soon.
  public static bool Log
  {
   get
   {
    return m_blnLog;
   }
   set
   {
    m_blnLog = value;
   }
  }

  internal static void LogError(string strText)
  {
   //Log=true;
   if (Log)
   {
    FileInfo file = null;
    FileStream fs = null;
    StreamWriter sw = null;
    try
    {
     file = new FileInfo(m_strLogFile);
     sw = file.AppendText();
     //fs = new FileStream(m_strLogFile, FileMode.OpenOrCreate, FileAccess.Write);
     //sw = new StreamWriter(fs);
     sw.WriteLine(DateTime.Now);
     sw.WriteLine(strText);
     sw.WriteLine("\r\n");
     sw.Flush();
    }
    finally
    {
     if (sw != null)
     {
      sw.Close();
      sw = null;
     }
     if (fs != null)
     {
      fs.Close();
      fs = null;
     }

    }
   }
  }

  public static bool IsQuotedPrintable(string strText)
  {
   if (strText != null)
    return (strText.ToLower() == "quoted-printable".ToLower());
   else
    return false;
  }

  public static bool IsBase64(string strText)
  {
   if (strText != null)
    return (strText.ToLower() == "base64".ToLower());
   else
    return false;
  }

  public static string[] SplitOnSemiColon(string strText)
  {
   if (strText == null)
    throw new ArgumentNullException("strText", "Argument was null");

   string[] array = null;
   int indexOfColon = strText.IndexOf(";");

   if (indexOfColon < 0)
   {
    array = new string[1];
    array[0] = strText;
    return array;
   }
   else
   {
    array = new string[2];
   }

   try
   {
    array[0] = strText.Substring(0, indexOfColon).Trim();
    array[1] = strText.Substring(indexOfColon + 1).Trim();
   }
   catch (Exception)
   {
   }

   return array;
  }

  public static bool IsNotNullText(string strText)
  {
   try
   {
    return (strText != null && strText != "");
   }
   catch
   {
    return false;
   }
  }

  public static bool IsNotNullTextEx(string strText)
  {
   try
   {
    return (strText != null && strText.Trim() != "");
   }
   catch
   {
    return false;
   }
  }

  public static bool IsOrNullTextEx(string strText)
  {
   try
   {
    return (strText == null || strText.Trim() == "");
   }
   catch
   {
    return false;
   }
  }

 }

}

namespace OpenPOP.POP3
{
 using System;
 using System.IO;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Collections;
 using System.Net.Sockets;
 using System.Security.Cryptography;
 using System.Threading;

 ///


 /// Possible responses received from the server when performing an Authentication
 ///

 public enum AuthenticationResponse
 {
  ///
  /// Authentication succeeded
  ///

  SUCCESS = 0,
  ///
  /// Login doesn't exist on the POP3 server
  ///
  
  INVALIDUSER = 1,
  ///
  /// Password is invalid for the give login
  ///

  INVALIDPASSWORD = 2,
  ///
  /// Invalid login and/or password
  ///

  INVALIDUSERORPASSWORD = 3
 }

 ///


 /// Authentication method to use
 ///

 /// TRYBOTH means code will first attempt by using APOP method as its more secure.
 ///  In case of failure the code will fall back to USERPASS method.
 ///

 public enum AuthenticationMethod
 {
  ///
  /// Authenticate using the USER/PASS method. USER/PASS is secure but all POP3 servers may not support this method
  ///

  USERPASS = 0,
  ///
  /// Authenticate using the APOP method
  ///

  APOP = 1,
  ///
  /// Authenticate using USER/PASS. In case USER/PASS fails then revert to APOP
  ///

  TRYBOTH = 2
 }

 ///


 /// Thrown when the POP3 Server sends an error (-ERR) during intial handshake (HELO)
 ///

 public class PopServerNotAvailableException : Exception
 {
 }

 ///


 /// Thrown when the specified POP3 Server can not be found or connected with
 ///
 
 public class PopServerNotFoundException : Exception
 {
 }

 ///


 /// Thrown when the attachment is not in a format supported by OpenPOP.NET
 ///

 /// Supported attachment encodings are Base64,Quoted Printable,MS TNEF
 public class AttachmentEncodingNotSupportedException : Exception
 {
 }

 ///


 /// Thrown when the supplied login doesn't exist on the server
 ///

 /// Should be used only when using USER/PASS Authentication Method
 public class InvalidLoginException : Exception
 {
 }

 ///


 /// Thrown when the password supplied for the login is invalid
 ///
 
 /// Should be used only when using USER/PASS Authentication Method
 public class InvalidPasswordException : Exception
 {
 }

 ///


 /// Thrown when either the login or the password is invalid on the POP3 Server
 ///

 /// /// Should be used only when using APOP Authentication Method
 public class InvalidLoginOrPasswordException : Exception
 {
 }

 ///


 /// Thrown when the user mailbox is in a locked state
 ///

 /// The mail boxes are locked when an existing session is open on the mail server. Lock conditions are also met in case of aborted sessions
 public class PopServerLockException : Exception
 {
 }

 ///


 /// Summary description for MyMD5.
 ///

 public class MyMD5
 {
  public static string GetMD5Hash(String input)
  {
   MD5 md5 = new MD5CryptoServiceProvider();
   //the GetBytes method returns byte array equavalent of a string
   byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);
   char[] temp = new char[res.Length];
   //copy to a char array which can be passed to a String constructor
   System.Array.Copy(res, temp, res.Length);
   //return the result as a string
   return new String(temp);
  }

  public static string GetMD5HashHex(String input)
  {
   MD5 md5 = new MD5CryptoServiceProvider();
   DES des = new DESCryptoServiceProvider();
   //the GetBytes method returns byte array equavalent of a string
   byte[] res = md5.ComputeHash(Encoding.Default.GetBytes(input), 0, input.Length);

   String returnThis = "";

   for (int i = 0; i < res.Length; i++)
   {
    returnThis += System.Uri.HexEscape((char) res[i]);
   }
   returnThis = returnThis.Replace("%", "");
   returnThis = returnThis.ToLower();

   return returnThis;


  }

 }

 ///


 /// POPClient
 ///

 public class POPClient
 {
  ///
  /// Event that fires when begin to connect with target POP3 server.
  ///

  public event EventHandler CommunicationBegan;

  ///


  /// Event that fires when connected with target POP3 server.
  ///

  public event EventHandler CommunicationOccured;

  ///


  /// Event that fires when disconnected with target POP3 server.
  ///

  public event EventHandler CommunicationLost;

  ///


  /// Event that fires when authentication began with target POP3 server.
  ///

  public event EventHandler AuthenticationBegan;

  ///


  /// Event that fires when authentication finished with target POP3 server.
  ///

  public event EventHandler AuthenticationFinished;

  ///


  /// Event that fires when message transfer has begun.
  ///
  
  public event EventHandler MessageTransferBegan;

  ///


  /// Event that fires when message transfer has finished.
  ///

  public event EventHandler MessageTransferFinished;

  internal void OnCommunicationBegan(EventArgs e)
  {
   if (CommunicationBegan != null)
    CommunicationBegan(this, e);
  }

  internal void OnCommunicationOccured(EventArgs e)
  {
   if (CommunicationOccured != null)
    CommunicationOccured(this, e);
  }

  internal void OnCommunicationLost(EventArgs e)
  {
   if (CommunicationLost != null)
    CommunicationLost(this, e);
  }

  internal void OnAuthenticationBegan(EventArgs e)
  {
   if (AuthenticationBegan != null)
    AuthenticationBegan(this, e);
  }

  internal void OnAuthenticationFinished(EventArgs e)
  {
   if (AuthenticationFinished != null)
    AuthenticationFinished(this, e);
  }

  internal void OnMessageTransferBegan(EventArgs e)
  {
   if (MessageTransferBegan != null)
    MessageTransferBegan(this, e);
  }

  internal void OnMessageTransferFinished(EventArgs e)
  {
   if (MessageTransferFinished != null)
    MessageTransferFinished(this, e);
  }

  private const string RESPONSE_OK = "+OK";
  //private const string RESPONSE_ERR="-ERR";
  private TcpClient clientSocket = null;
  private StreamReader reader;
  private StreamWriter writer;
  private string _Error = "";
  private int _receiveTimeOut = 60000;
  private int _sendTimeOut = 60000;
  private int _receiveBufferSize = 4090;
  private int _sendBufferSize = 4090;
  private string _basePath = null;
  private bool _receiveFinish = false;
  private bool _autoDecodeMSTNEF = true;
  private int _waitForResponseInterval = 200;
  private int _receiveContentSleepInterval = 100;
  private string _aPOPTimestamp;
  private string _lastCommandResponse;
  private bool _connected = true;


  public bool Connected
  {
   get
   {
    return _connected;
   }
  }

  public string APOPTimestamp
  {
   get
   {
    return _aPOPTimestamp;
   }
  }

  ///


  /// receive content sleep interval
  ///

  public int ReceiveContentSleepInterval
  {
   get
   {
    return _receiveContentSleepInterval;
   }
   set
   {
    _receiveContentSleepInterval = value;
   }
  }

  ///


  /// wait for response interval
  ///

  public int WaitForResponseInterval
  {
   get
   {
    return _waitForResponseInterval;
   }
   set
   {
    _waitForResponseInterval = value;
   }
  }

  ///


  /// whether auto decoding MS-TNEF attachment files
  ///

  public bool AutoDecodeMSTNEF
  {
   get
   {
    return _autoDecodeMSTNEF;
   }
   set
   {
    _autoDecodeMSTNEF = value;
   }
  }

  ///


  /// path to extract MS-TNEF attachment files
  ///

  public string BasePath
  {
   get
   {
    return _basePath;
   }
   set
   {
    try
    {
     if (value.EndsWith("\\"))
      _basePath = value;
     else
      _basePath = value + "\\";
    }
    catch
    {
    }
   }
  }

  ///


  /// Receive timeout for the connection to the SMTP server in milliseconds.
  /// The default value is 60000 milliseconds.
  ///

  public int ReceiveTimeOut
  {
   get
   {
    return _receiveTimeOut;
   }
   set
   {
    _receiveTimeOut = value;
   }
  }

  ///


  /// Send timeout for the connection to the SMTP server in milliseconds.
  /// The default value is 60000 milliseconds.
  ///

  public int SendTimeOut
  {
   get
   {
    return _sendTimeOut;
   }
   set
   {
    _sendTimeOut = value;
   }
  }

  ///


  /// Receive buffer size
  ///

  public int ReceiveBufferSize
  {
   get
   {
    return _receiveBufferSize;
   }
   set
   {
    _receiveBufferSize = value;
   }
  }

  ///


  /// Send buffer size
  ///

  public int SendBufferSize
  {
   get
   {
    return _sendBufferSize;
   }
   set
   {
    _sendBufferSize = value;
   }
  }

  private void WaitForResponse(bool blnCondiction, int intInterval)
  {
   if (intInterval == 0)
    intInterval = WaitForResponseInterval;
   while (!blnCondiction == true)
   {
    Thread.Sleep(intInterval);
   }
  }

  private void WaitForResponse(ref StreamReader rdReader, int intInterval)
  {
   if (intInterval == 0)
    intInterval = WaitForResponseInterval;
   //while(rdReader.Peek()==-1 || !rdReader.BaseStream.CanRead)
   while (!rdReader.BaseStream.CanRead)
   {
    Thread.Sleep(intInterval);
   }
  }

  private void WaitForResponse(ref StreamReader rdReader)
  {
   DateTime dtStart = DateTime.Now;
   TimeSpan tsSpan;
   while (!rdReader.BaseStream.CanRead)
   {
    tsSpan = DateTime.Now.Subtract(dtStart);
    if (tsSpan.Milliseconds > _receiveTimeOut)
     break;
    Thread.Sleep(_waitForResponseInterval);
   }
  }

  private void WaitForResponse(ref StreamWriter wrWriter, int intInterval)
  {
   if (intInterval == 0)
    intInterval = WaitForResponseInterval;
   while (!wrWriter.BaseStream.CanWrite)
   {
    Thread.Sleep(intInterval);
   }
  }

  ///


  /// Examines string to see if it contains a timestamp to use with the APOP command
  /// If it does, sets the ApopTimestamp property to this value
  ///

  /// string to examine
  private void ExtractApopTimestamp(string strResponse)
  {
   Match match = Regex.Match(strResponse, "<.+>");
   if (match.Success)
   {
    _aPOPTimestamp = match.Value;
   }
  }

  ///


  /// Tests a string to see if it's a "+OK" string
  ///

  /// string to examine
  /// true if response is an "+OK" string
  private bool IsOkResponse(string strResponse)
  {
   return (strResponse.Substring(0, 3) == RESPONSE_OK);
  }

  ///


  /// get response content
  ///

  /// string to examine
  /// response content
  private string GetResponseContent()
  {
   return _lastCommandResponse.Substring(3);
  }

  ///


  /// Sends a command to the POP server.
  ///

  /// command to send to server
  /// Do not give error
  /// true if server responded "+OK"
  private bool SendCommand(string strCommand, bool blnSilent)
  {
   _lastCommandResponse = "";
   try
   {
    if (writer.BaseStream.CanWrite)
    {
     writer.WriteLine(strCommand);
     writer.Flush();
     //WaitForResponse(ref reader,WaitForResponseInterval);
     WaitForResponse(ref reader);
     _lastCommandResponse = reader.ReadLine();
     return IsOkResponse(_lastCommandResponse);
    }
    else
     return false;
   }
   catch (Exception e)
   {
    if (!blnSilent)
    {
     _Error = strCommand + ":" + e.Message;
     Utility.LogError(_Error);
    }
    return false;
   }
  }

  ///


  /// Sends a command to the POP server.
  ///

  /// command to send to server
  /// true if server responded "+OK"
  private bool SendCommand(string strCommand)
  {
   return SendCommand(strCommand, false);
  }

  ///


  /// Sends a command to the POP server, expects an integer reply in the response
  ///

  /// command to send to server
  /// integer value in the reply
  private int SendCommandIntResponse(string strCommand)
  {
   int retVal = 0;
   if (SendCommand(strCommand))
   {
    try
    {
     retVal = int.Parse(_lastCommandResponse.Split(' ')[1]);
    }
    catch (Exception e)
    {
     Utility.LogError(strCommand + ":" + e.Message);
    }
   }
   return retVal;
  }

  ///


  /// Construct new POPClient
  ///

  public POPClient()
  {
   Utility.Log = false;
  }

  ///


  /// Construct new POPClient
  ///

  public POPClient(string strHost, int intPort, string strlogin, string strPassword, AuthenticationMethod authenticationMethod)
  {
   Connect(strHost, intPort);
   Authenticate(strlogin, strPassword, authenticationMethod);
  }

  ///


  /// connect to remote server
  ///

  /// POP3 host
  /// POP3 port
  public void Connect(string strHost, int intPort)
  {
   OnCommunicationBegan(EventArgs.Empty);

   clientSocket = new TcpClient();
   clientSocket.ReceiveTimeout = _receiveTimeOut;
   clientSocket.SendTimeout = _sendTimeOut;
   clientSocket.ReceiveBufferSize = _receiveBufferSize;
   clientSocket.SendBufferSize = _sendBufferSize;

   try
   {
    clientSocket.Connect(strHost, intPort);
   }
   catch (SocketException e)
   {
    Disconnect();
    Utility.LogError("Connect():" + e.Message);
    throw new PopServerNotFoundException();
   }

   reader = new StreamReader(clientSocket.GetStream(), Encoding.Default, true);
   writer = new StreamWriter(clientSocket.GetStream());
   writer.AutoFlush = true;

   WaitForResponse(ref reader, WaitForResponseInterval);

   string strResponse = reader.ReadLine();

   if (IsOkResponse(strResponse))
   {
    ExtractApopTimestamp(strResponse);
    _connected = true;
    OnCommunicationOccured(EventArgs.Empty);
   }
   else
   {
    Disconnect();
    Utility.LogError("Connect():" + "Error when login, maybe POP3 server not exist");
    throw new PopServerNotAvailableException();
   }
  }

  ///


  /// Disconnect from POP3 server
  ///

  public void Disconnect()
  {
   try
   {
    clientSocket.ReceiveTimeout = 500;
    clientSocket.SendTimeout = 500;
    SendCommand("QUIT", true);
    clientSocket.ReceiveTimeout = _receiveTimeOut;
    clientSocket.SendTimeout = _sendTimeOut;
    reader.Close();
    writer.Close();
    clientSocket.GetStream().Close();
    clientSocket.Close();
   }
   catch
   {
    //Utility.LogError("Disconnect():"+e.Message);
   }
   finally
   {
    reader = null;
    writer = null;
    clientSocket = null;
   }
   OnCommunicationLost(EventArgs.Empty);
  }

  ///


  /// release me
  ///

  ~POPClient()
  {
   Disconnect();
  }

  ///


  /// verify user and password
  ///

  /// user name
  /// password
  public void Authenticate(string strlogin, string strPassword)
  {
   Authenticate(strlogin, strPassword, AuthenticationMethod.USERPASS);
  }

  ///


  /// verify user and password
  ///

  /// user name
  /// strPassword
  /// verification mode
  public void Authenticate(string strlogin, string strPassword, AuthenticationMethod authenticationMethod)
  {
   if (authenticationMethod == AuthenticationMethod.USERPASS)
   {
    AuthenticateUsingUSER(strlogin, strPassword);
   }
   else if (authenticationMethod == AuthenticationMethod.APOP)
   {
    AuthenticateUsingAPOP(strlogin, strPassword);
   }
   else if (authenticationMethod == AuthenticationMethod.TRYBOTH)
   {
    try
    {
     AuthenticateUsingUSER(strlogin, strPassword);
    }
    catch (InvalidLoginException e)
    {
     Utility.LogError("Authenticate():" + e.Message);
    }
    catch (InvalidPasswordException e)
    {
     Utility.LogError("Authenticate():" + e.Message);
    }
    catch (Exception e)
    {
     Utility.LogError("Authenticate():" + e.Message);
     AuthenticateUsingAPOP(strlogin, strPassword);
    }
   }
  }

  ///


  /// verify user and password
  ///

  /// user name
  /// password
  private void AuthenticateUsingUSER(string strlogin, string strPassword)
  {
   OnAuthenticationBegan(EventArgs.Empty);

   if (!SendCommand("USER " + strlogin))
   {
    Utility.LogError("AuthenticateUsingUSER():wrong user");
    throw new InvalidLoginException();
   }

   WaitForResponse(ref writer, WaitForResponseInterval);

   if (!SendCommand("PASS " + strPassword))
   {
    if (_lastCommandResponse.ToLower().IndexOf("lock") != -1)
    {
     Utility.LogError("AuthenticateUsingUSER():maildrop is locked");
     throw new PopServerLockException();
    }
    else
    {
     Utility.LogError("AuthenticateUsingUSER():wrong password or " + GetResponseContent());
     throw new InvalidPasswordException();
    }
   }

   OnAuthenticationFinished(EventArgs.Empty);
  }

  ///


  /// verify user and password using APOP
  ///

  /// user name
  /// password
  private void AuthenticateUsingAPOP(string strlogin, string strPassword)
  {
   OnAuthenticationBegan(EventArgs.Empty);

   if (!SendCommand("APOP " + strlogin + " " + MyMD5.GetMD5HashHex(strPassword)))
   {
    Utility.LogError("AuthenticateUsingAPOP():wrong user or password");
    throw new InvalidLoginOrPasswordException();
   }

   OnAuthenticationFinished(EventArgs.Empty);
  }

  /*  private string GetCommand(string input)
    {   
     try
     {
      return input.Split(' ')[0];
     }
     catch(Exception e)
     {
      Utility.LogError("GetCommand():"+e.Message);
      return "";
     }
    }*/

  private string[] GetParameters(string input)
  {
   string[] temp = input.Split(' ');
   string[] retStringArray = new string[temp.Length - 1];
   Array.Copy(temp, 1, retStringArray, 0, temp.Length - 1);

   return retStringArray;
  }

  ///


  /// get message count
  ///

  /// message count
  public int GetMessageCount()
  {
   return SendCommandIntResponse("STAT");
  }

  ///


  /// Deletes message with given index when Close() is called
  ///

  ///
  public bool DeleteMessage(int intMessageIndex)
  {
   return SendCommand("DELE " + intMessageIndex.ToString());
  }

  ///


  /// Deletes messages
  ///

  public bool DeleteAllMessages()
  {
   int messageCount = GetMessageCount();
   for (int messageItem = messageCount; messageItem > 0; messageItem--)
   {
    if (!DeleteMessage(messageItem))
     return false;
   }
   return true;
  }

  ///


  /// quit POP3 server
  ///

  public bool QUIT()
  {
   return SendCommand("QUIT");
  }

  ///


  /// keep server active
  ///

  public bool NOOP()
  {
   return SendCommand("NOOP");
  }

  ///


  /// keep server active
  ///

  public bool RSET()
  {
   return SendCommand("RSET");
  }

  ///


  /// identify user
  ///

  public bool USER()
  {
   return SendCommand("USER");

  }

  ///


  /// get messages info
  ///

  /// message number
  /// Message object
  public MIMEParser.Message GetMessageHeader(int intMessageNumber)
  {
   OnMessageTransferBegan(EventArgs.Empty);

   //MIMEParser.Message msg = FetchMessage("TOP " + intMessageNumber.ToString() + " 0", true);

   //modify by playyuer $at$ Microshaoft.com
   MIMEParser.Message msg = FetchMessage(intMessageNumber, "TOP {0} 0", true);

   OnMessageTransferFinished(EventArgs.Empty);

   return msg;
  }

  ///


  /// get message uid
  ///

  /// message number
  public string GetMessageUID(int intMessageNumber)
  {
   string[] strValues = null;
   if (SendCommand("UIDL " + intMessageNumber.ToString()))
   {
    strValues = GetParameters(_lastCommandResponse);
   }
   return strValues[1];
  }

  ///


  /// get message uids
  ///

  public ArrayList GetMessageUIDs()
  {
   ArrayList uids = new ArrayList();
   if (SendCommand("UIDL"))
   {
    string strResponse = reader.ReadLine();
    while (strResponse != ".")
    {
     uids.Add(strResponse.Split(' ')[1]);
     strResponse = reader.ReadLine();
    }
    return uids;
   }
   else
   {
    return null;
   }
  }

  ///


  /// Get the sizes of all the messages
  /// CAUTION:  Assumes no messages have been deleted
  ///

  /// Size of each message
  public ArrayList LIST()
  {
   ArrayList sizes = new ArrayList();
   if (SendCommand("LIST"))
   {
    string strResponse = reader.ReadLine();
    while (strResponse != ".")
    {
     sizes.Add(int.Parse(strResponse.Split(' ')[1]));
     strResponse = reader.ReadLine();
    }
    return sizes;
   }
   else
   {
    return null;
   }
  }

  ///


  /// get the size of a message
  ///

  /// message number
  /// Size of message
  public int LIST(int intMessageNumber)
  {
   return SendCommandIntResponse("LIST " + intMessageNumber.ToString());
  }

  //add by playyuer $at$ Microshaoft.com
  public delegate void DataEventHandler(int MessageID, int Data);

  public event DataEventHandler DataArrival;

  public void OnMessageReceiving(int MessageID, int Data)
  {
   if (DataArrival != null)
   {
    DataArrival(MessageID, Data);
   }
  }

  ///


  /// read stream content
  ///

  /// length of content to read
  /// content
  ///
  private string ReceiveContent(int MessageID, int intContentLength)
  {
   string strResponse = null;
   StringBuilder builder = new StringBuilder();

   WaitForResponse(ref reader, WaitForResponseInterval);

   strResponse = reader.ReadLine();
   int intLines = 0;
   int intLen = 0;
   
   //add by playyuer $at$ microshaoft.com
   OnMessageReceiving(MessageID, intLen);

   while (strResponse != ".") // || (intLen   {
    builder.Append(strResponse + "\r\n");
    intLines += 1;
    intLen += strResponse.Length + "\r\n".Length;

    //add by playyuer $at$ microshaoft.com
    OnMessageReceiving(MessageID, intLen);

    WaitForResponse(ref reader, 1);

    strResponse = reader.ReadLine();
    if ((intLines%_receiveContentSleepInterval) == 0) //make an interval pause to ensure response from server
     Thread.Sleep(1);
   }

   OnMessageReceiving(MessageID,-1); //接收一封邮件完毕

   builder.Append(strResponse + "\r\n");

   return builder.ToString();

  }

  ///


  /// get message info
  ///

  /// message number on server
  /// Message object
  public MIMEParser.Message GetMessage(int intNumber, bool blnOnlyHeader)
  {
   OnMessageTransferBegan(EventArgs.Empty);

   //modify by playyuer $at$ Microshaoft.com
   MIMEParser.Message msg = FetchMessage(intNumber, "RETR {0}", blnOnlyHeader);

   OnMessageTransferFinished(EventArgs.Empty);

   return msg;
  }

  ///


  /// fetches a message or a message header
  ///

  /// Command to send to Pop server
  /// Only return message header?
  /// Message object
  public MIMEParser.Message FetchMessage(string strCommand, bool blnOnlyHeader)
  {
   _receiveFinish = false;
   if (!SendCommand(strCommand))
    return null;

   try
   {
    string receivedContent = ReceiveContent(0, -1);

    MIMEParser.Message msg = new MIMEParser.Message(ref _receiveFinish, _basePath, _autoDecodeMSTNEF, receivedContent, blnOnlyHeader);

    WaitForResponse(_receiveFinish, WaitForResponseInterval);

    return msg;
   }
   catch (Exception e)
   {
    Utility.LogError("FetchMessage():" + e.Message);
    return null;
   }
  }

  //overload by playyuer©㊣®microshaoft.com
  public MIMEParser.Message FetchMessage(int MessageID, string strCommand, bool blnOnlyHeader)
  {
   _receiveFinish = false;

   string s = string.Format(strCommand, MessageID).ToUpper();
   if (!SendCommand(s))
    return null;

   try
   {
    string receivedContent = ReceiveContent(MessageID, -1);

    MIMEParser.Message msg = new MIMEParser.Message(ref _receiveFinish, _basePath, _autoDecodeMSTNEF, receivedContent, blnOnlyHeader);

    WaitForResponse(_receiveFinish, WaitForResponseInterval);

    return msg;
   }
   catch (Exception e)
   {
    Utility.LogError("FetchMessage():" + e.Message);
    return null;
   }
  }

 }

 ///


 /// Utility functions
 ///

 public class Utility
 {
  ///
  /// Weather auto loggin is on or off
  ///

  private static bool m_blnLog = false;

  ///


  /// The file name in which the logging will be done
  ///

  private static string m_strLogFile = "OpenPOP.log";

  ///


  /// Turns file logging on and off.

Change Property Name


  ///

  /// Comming soon.
  public static bool Log
  {
   get
   {
    return m_blnLog;
   }
   set
   {
    m_blnLog = value;
   }
  }

  ///


  /// Log an error to the log file
  ///

  /// The error text to log
  internal static void LogError(string strText)
  {
   //Log=true;
   if (Log)
   {
    FileInfo file = null;
    FileStream fs = null;
    StreamWriter sw = null;
    try
    {
     file = new FileInfo(m_strLogFile);
     sw = file.AppendText();
     //fs = new FileStream(m_strLogFile, FileMode.OpenOrCreate, FileAccess.Write);
     //sw = new StreamWriter(fs);
     sw.WriteLine(DateTime.Now);
     sw.WriteLine(strText);
     sw.WriteLine("\r\n");
     sw.Flush();
    }
    finally
    {
     if (sw != null)
     {
      sw.Close();
      sw = null;
     }
     if (fs != null)
     {
      fs.Close();
      fs = null;
     }

    }
   }
  }

 }

}


//前妻 jmail 的外衣不能扔继续留给 OpenPOP.Net 穿
//《封装 JMail 4.4 的 POP3 为 .Net 组件 (.dll 程序集),实现 "邮件(附件) 到达" 等 "事件"!
/*
w3 JMail v4.4 Professional 的获取请自行 google!
或参阅 http://community.csdn.net/Expert/TopicView.asp?id=3739405

w3 JMail v4.4 Professional 是一个 COM 的组件,我用 C# 把其 POP3 COM 类封装成
一个用于收取邮件的 .Net 组件:
实现了
 //同步事件
  public event MessagesEventHandler MessageReceived; //一封邮件已收到本地
  public event MessagesEventHandler MessageReceive; //一封邮件正到达
  //可用于收取邮件的每个附件处理
  public event AttachmentsEventHandler AttachmentReceive; //一封邮件的附件正到达

 //发生异常事件
  public event MessagesEventHandler MessageException;
  public event AttachmentsEventHandler AttachmentException;

因此在调用该组件的主调程序中可根据分析邮件的主题或附件等结果作不同处理!

将如下所有代码:
1.复制到 Microsoft Visual Studio .Net 2003 的新建的 "控制台应用程序" 项目的 *.cs 文件中
2.然后添加引用 JMail 4.x Library!
jmail 的注册方法,运行命令行: regsvr32 e:\jmail\jmail.dll
3.F5 运行

或者
将如下所有代码:
1.复制到任意一个 *.cs 文件中保存!(如: e:\temp\OpenMail.cs)
2.使用 tlbimp.exe(类型库导入程序)实用工具生成一个 .Net 程序集
执行命令行: (位于 Ms VS.Net 安装目录下的: E:\MsVS.Net\SDK\v1.1\Bin\TlbImp.exe)
tlbimp.exe e:\jmail\jmail.dll /out:e:\temp\jmail.net.dll /namespace:jmail
生成的 jmail.net.dll 与 *.cs 文件放在同一目录下!
3.执行 csc 命令行编译 *.cs
编译成 exe : (这里是为了演示测试效果所以编译成 exe)
csc.exe OpenMail.cs /r:jmail.net.dll
编译成 dll ,即可由别的 .Net 程序添加引用:
csc.exe /t:library OpenMail.cs /r:jmail.net.dll

(当然也可将 namespace Microshaoft.OpenMail 下的代码单独编译成 dll)
*/

namespace Microshaoft.OpenMail
{
 //using jmail;
 //using System;

 public class POP3
 {
  public delegate void MessagesEventHandler(MessagesState oMessagesState);
  public delegate void AttachmentsEventHandler(AttachmentsState oAttachmentsState);

  //异步事件
  public event MessagesEventHandler MessagesReceiveAsync;
  public event AttachmentsEventHandler AttachmentsReceiveAsync;

  //同步事件
  public event MessagesEventHandler MessageReceived;
  public event MessagesEventHandler MessageReceive;
  public event AttachmentsEventHandler AttachmentReceive;

  //发生异常事件
  public event MessagesEventHandler MessageException;
  public event AttachmentsEventHandler AttachmentException;

  public delegate void DataEventHandler(int MessageID,int Data);

  public event DataEventHandler DataArrival;

  private string _UserName;
  private string _Password;
  private string _Server;
  private int _Port = 110;

  private static object _SyncObject = new object();

  public POP3(string UserName,string Password,string Server,int Port)
  {
   this._UserName = UserName;
   this._Password = Password;
   this._Server = Server;
   this._Port = Port;
  }

  public POP3(string UserName,string Password,string Server)
  {
   this._UserName = UserName;
   this._Password = Password;
   this._Server = Server;
  }

  public string UserName
  {
   get
   {
    return _UserName;
   }
   set
   {
    _UserName = value;
   }
  }

  public string Password
  {
   get
   {
    return _Password;
   }
   set
   {
    _Password = value;
   }
  }

  public string Server
  {
   get
   {
    return _Server;
   }
   set
   {
    _Server = value;
   }
  }

  public int Port
  {
   get
   {
    return _Port;
   }
   set
   {
    _Port = value;
   }
  }
  //[MTAThread]
  public void Execute()
  {
   this.Execute(false);
  }
  OpenPOP.POP3.POPClient pop3;

  public void Execute(bool IsAsync)
  {
   pop3 = new OpenPOP.POP3.POPClient();
   pop3.DataArrival += new OpenPOP.POP3.POPClient.DataEventHandler(pop3_DataArrival);
   try
   {
    //pop3.Timeout = 0;
    pop3.Connect(this._Server,this._Port);
    pop3.Authenticate(this._UserName,this._Password);
    
    //jmail.MessagesClass jms = (jmail.MessagesClass) pop3.Messages;
    int I = pop3.GetMessageCount();;
    MessagesState omss = null;
    for (int i = 0; i < I ; i++)
    {
     try
     {
      OpenPOP.MIMEParser.Message jmc = pop3.GetMessage(i+1,false);
      if (omss == null || omss.MessageID != i+1)
      {
       omss = new MessagesState(i+1,jmc,pop3);
      }
      if (this.MessageReceive != null)
      {
       this.MessageReceive(omss);
       if (!omss.CancelCurrent)
       {
        if (IsAsync)
        {
         //System.IAsyncResult iar =
         (new MessagesEventHandler(this.MessageExecuteAsync)).BeginInvoke(omss,new System.AsyncCallback(this.OnMessageCallBack),omss);
        }
        else
        {
         if (jmc != null)
         {
          int J = jmc.Attachments.Count;
          AttachmentsState oass = null;
          for (int j = 0; j < J; j++)
          {
           try
           {
            if (oass == null || oass.AttachmentID != j)
            {
             oass = new AttachmentsState(j,omss);
            }
            if (this.AttachmentReceive != null)
            {
             this.AttachmentReceive(oass);
             if (!oass.CancelCurrent)
             {
              string s = oass.FileName;
              omss.SetFilePath(System.IO.Path.GetDirectoryName(s) + @"\");
              oass.SaveToFile(s);
             }
            }

           }
           catch (System.Exception e)
           {
            if (this.AttachmentException != null)
            {
             oass.Exception = e;
             this.AttachmentException(oass);
             if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.CancelAll)
             {
              break;
             }
             else
              if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Retry)
             {
              j--;
             }
             else
              if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Ignore)
             {
              //continue;
             }
             else
              if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Throw)
             {
              throw e;
             }
            }
            else
            {
             throw e;
            }
           }
          }
          
         }
         
         if (this.MessageReceived != null)
         {
          this.MessageReceived(omss);
         }
        }
       }
      }
     }
     catch (System.Exception e)
     {
      if (this.MessageException != null)
      {
       omss.Exception = e;
       this.MessageException(omss);
       if (omss.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.CancelAll)
       {
        break;
       }
       else
        if (omss.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Retry)
       {
        i--;
       }
       else
        if (omss.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Ignore)
       {
        //continue;
       }
       else
        if (omss.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Throw)
       {
        throw e;
       }
      }
      else
      {
       throw e;
      }
     }
    }
   }
   catch (System.Exception e)
   {
    throw e;
   }
   finally
   {
    pop3.Disconnect();
    pop3 = null;
   }
   //System.Console.WriteLine("main end");
  }


  //[MTAThread]
  private void MessageExecuteAsync(MessagesState oMessagesState)
  {
   int J = oMessagesState.jMessage.Attachments.Count;
   for (int j = 0; j < J; j++)
   {
    AttachmentsState oass = new AttachmentsState(j,oMessagesState);
    //System.IAsyncResult iar =
    (new AttachmentsEventHandler(this.AttachmentExecuteAsync)).BeginInvoke(oass,new System.AsyncCallback(this.OnAttachemnetCallBack),oass);
   }
  }

  //[MTAThread]
  private void AttachmentExecuteAsync(AttachmentsState oAttachmentsState)
  {
   //
  }

  //[MTAThread]
  private void OnMessageCallBack(System.IAsyncResult iar)
  {
   MessagesState omss = (MessagesState) iar.AsyncState;
   if (this.MessagesReceiveAsync != null)
   {
    if (omss.jMessage.Attachments.Count == 0)
    {
     this.MessagesReceiveAsync(omss);
    }
   }
  }

  //[MTAThread]
  private void OnAttachemnetCallBack(System.IAsyncResult iar)
  {
   AttachmentsState oass = (AttachmentsState) iar.AsyncState;
   if (this.AttachmentsReceiveAsync != null)
   {
    this.AttachmentsReceiveAsync(oass);
   }
   if (!oass.CancelCurrent)
   {
    try
    {
     oass.SaveToFile(oass.FileName);
    }
    catch (System.Exception e)
    {
     oass.Exception = e;
     if (AttachmentException != null)
     {
      AttachmentException(oass);
      if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.CancelAll)
      {

      }
      else
       if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Retry)
      {
       this.OnAttachemnetCallBack((System.IAsyncResult) oass);
      }
      else
       if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Ignore)
      {

      }
      else
       if (oass.ExceptionAction == Microshaoft.OpenMail.ExceptionActions.Throw)
      {
       throw e;
      }
     }
    }
   }
   if (this.MessagesReceiveAsync != null)
   {
    if (oass.AttachmentsCount == 0)
    {
     this.MessagesReceiveAsync(oass.MessagesState);
    }
   }
  }

  private void pop3_DataArrival(int MessageID, int Data)
  {
   if (DataArrival != null)
   {
    DataArrival(MessageID,Data);
   }

  }
 }

 public class MessagesState //Messages 状态
 {
  private static object _SyncObject = new object();
  private int _MessageID;
  private OpenPOP.MIMEParser.Message _jMessage;
  //private jmail.MessagesClass _jMessages;
  private OpenPOP.POP3.POPClient _jPOP3;
  private string _FilePath;
  private bool _CancelCurrent ;

  private System.Exception _Exception;
  private ExceptionActions _ExceptionAction;


  public int ReceivedLength
  {
   get { return _ReceivedLength; }
   set { _ReceivedLength = value; }
  }

  private int _ReceivedLength;

 

  public ExceptionActions ExceptionAction
  {
   get
   {
    return _ExceptionAction;
   }
   set
   {
    this._ExceptionAction = value;
   }
  }

  public System.Exception Exception
  {
   get
   {
    return _Exception;
   }
   set
   {
    this._Exception = value;
   }
  }

  public string FilePath
  {
   get
   {
    return this._FilePath;
   }
  }

  internal void SetFilePath(string FilePath)
  {
   this._FilePath = FilePath;
  }

  public bool CancelCurrent
  {
   get
   {
    return this._CancelCurrent;
   }
   set
   {
    this._CancelCurrent = value;
   }
  }

  public int MessagesCount //尚未处理的邮件数
  {
   get
   {
    //lock(MessagesState._SyncObject)
   {
    return this._jPOP3.GetMessageCount() - this._MessageID;
   }
   }
  }

  public OpenPOP.MIMEParser.Message jMessage
  {
   get
   {
    return this._jMessage;
   }
  }

  public int MessageID
  {
   get
   {
    return this._MessageID;
   }
  }

  internal MessagesState(int MessageID,OpenPOP.MIMEParser.Message jMessage,OpenPOP.POP3.POPClient jPOP3)
  {
   this._MessageID = MessageID;
   this._jMessage = jMessage;
   //this._jMessages = jMessages;
   this._jPOP3 = jPOP3;
  }

  public void DeleteSingleMessage()
  {
   lock(MessagesState._SyncObject)
   {
    this.DeleteSingleMessage(this._MessageID);
   }
  
  }

  public void DeleteSingleMessage(int MessageID)
  {
   lock(MessagesState._SyncObject)
   {
    this._jPOP3.DeleteMessage(MessageID);
   }
  }

  public void DeleteMessages()
  {
   lock(MessagesState._SyncObject)
   {
    this._jPOP3.DeleteAllMessages();
   }
  }
 }


 public enum ExceptionActions
 {
  CancelAll,Ignore,Retry,Throw
 }

 public class AttachmentsState //Attachments 状态
 {
  private MessagesState _MessagesState;
  private int _AttachmentID;
  private string _FileName;
  private static object _SyncObject = new object();
  private OpenPOP.MIMEParser.Attachment _jAttachment;
  private bool _CancelCurrent;
  private System.Exception _Exception;
  private ExceptionActions _ExceptionAction;

  public ExceptionActions ExceptionAction
  {
   get
   {
    return _ExceptionAction;
   }
   set
   {
    this._ExceptionAction = value;
   }
  }

  public System.Exception Exception
  {
   get
   {
    return _Exception;
   }
   set
   {
    this._Exception = value;
   }
  }

  public bool CancelCurrent
  {
   get
   {
    return this._CancelCurrent;
   }
   set
   {
    this._CancelCurrent = value;
   }
  }

  public OpenPOP.MIMEParser.Attachment jAttachment
  {
   get
   {
    return this._jAttachment;
   }
  }

  public int AttachmentsCount //尚未处理的邮件附件数
  {
   get
   {
    //lock(AttachmentsState._SyncObject)
   {
    return this._MessagesState.jMessage.Attachments.Count - this._AttachmentID - 1;
   }
   }
  }

  public string FileName
  {
   get
   {
    return this._FileName;
   }
   set
   {
    this._FileName = value;
   }
  }

  public MessagesState MessagesState
  {
   get
   {
    return this._MessagesState;
   }
  }

  public int AttachmentID
  {
   get
   {
    return this._AttachmentID;
   }
  }

  public void SaveToFile(string FileName)
  {
   //if (!this.CancelCurrent)
  {
   this._MessagesState.jMessage.SaveAttachment(_jAttachment,FileName);
  }
  }

  internal AttachmentsState(int AttachmentID,MessagesState oMessagesState)
  {
   this._MessagesState = oMessagesState;
   this._AttachmentID = AttachmentID;
   this._jAttachment = (OpenPOP.MIMEParser.Attachment) oMessagesState.jMessage.Attachments[AttachmentID];
   this._FileName = System.String.Format("[{0}].{1}.[{2}].{3}",oMessagesState.MessageID,oMessagesState.jMessage.Subject,AttachmentID,oMessagesState.jMessage.GetAttachmentFileName(_jAttachment));
  }
 }
}

//下面写一个测试类: 定时收取邮件
//==========================================================================================
// Console 测试程序:
namespace Microshaoft.OpenMail.ConsoleApplicationTest
{
using System;
using Microshaoft.OpenMail;
using POP = Microshaoft.OpenMail.POP3;

class ConsoleApplicationTest
{
 string POP3_Server = "mail.xxxx.com";//System.Configuration.ConfigurationSettings.AppSettings["POP3_Server"];
 string POP3_User = "userid";//System.Configuration.ConfigurationSettings.AppSettings["POP3_User"];
 string POP3_Password = "password";//System.Configuration.ConfigurationSettings.AppSettings["POP3_Password"];

 int Interval = 20;//Convert.ToInt32(System.Configuration.ConfigurationSettings.AppSettings["TimerInterval"]);

 POP Pop1;

 bool IsBusy = false;

 static void Main()
 {
  ConsoleApplicationTest a = new ConsoleApplicationTest();

  a.Pop1 = new POP(a.POP3_User, a.POP3_Password, a.POP3_Server);
  //订阅同步事件
  a.Pop1.MessageReceived += new Microshaoft.OpenMail.POP3.MessagesEventHandler(a.Pop1_MessageReceived);
  a.Pop1.AttachmentReceive += new Microshaoft.OpenMail.POP3.AttachmentsEventHandler(a.Pop1_AttachmentReceive);
  a.Pop1.MessageReceive += new Microshaoft.OpenMail.POP3.MessagesEventHandler(a.Pop1_MessageReceive);
  //订阅 Exception 事件
  a.Pop1.AttachmentException += new Microshaoft.OpenMail.POP3.AttachmentsEventHandler(a.Pop1_AttachmentException);
  a.Pop1.DataArrival += new Microshaoft.OpenMail.POP3.DataEventHandler(a.Pop1_DataArrival);
  a.t = new System.Timers.Timer();
  a.t.Interval = 1000 * a.Interval; //每 30 秒收取一次邮件
  a.t.Elapsed += new System.Timers.ElapsedEventHandler(a.t_Elapsed);
  a.t_Elapsed(null, null);

  while (System.Console.ReadLine().ToLower() != "exit")
  {
   System.Console.WriteLine("press \"exit\" to exit this programe!");
  }
 }

 System.Timers.Timer t;

 private void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 {
  this.Run();
 }

 public void RefreshSettings()
 {
  System.Xml.XmlDocument xd = new System.Xml.XmlDocument();
  xd.Load(System.AppDomain.CurrentDomain.SetupInformation.ConfigurationFile);
  POP3_Server = xd.SelectSingleNode("/configuration/appSettings/add[@key=\"POP3_Server\"]").Attributes["value"].Value; //System.Configuration.ConfigurationSettings.AppSettings["POP3_Server"];
  POP3_User = xd.SelectSingleNode("/configuration/appSettings/add[@key=\"POP3_User\"]").Attributes["value"].Value; //System.Configuration.ConfigurationSettings.AppSettings["POP3_User"];
  POP3_Password = xd.SelectSingleNode("/configuration/appSettings/add[@key=\"POP3_Password\"]").Attributes["value"].Value; //System.Configuration.ConfigurationSettings.AppSettings["POP3_User"];//System.Configuration.ConfigurationSettings.AppSettings["POP3_Password"];
  Interval = Convert.ToInt32(xd.SelectSingleNode("/configuration/appSettings/add[@key=\"TimerInterval\"]").Attributes["value"].Value);
  t.Interval = Interval * 1000;
  this.Pop1.UserName = POP3_User;
  this.Pop1.Password = POP3_Password;
  this.Pop1.Server = POP3_Server;
 }

 private void DoWait()
 {
  Wait(ref IsBusy); //由委托调用的真正函数
 }

 private void Run()
 {
  if (!IsBusy)
  {
   System.Console.WriteLine("\nBusy {0}", System.DateTime.Now.ToLocalTime().ToUniversalTime());
   this.t.Enabled = false;
   this.IsBusy = true;
   //this.Pop1.Execute(true); //异步执行
   //RefreshSettings();
   try
   {
    this.Pop1.Execute(); //同步执行
   }
   catch (System.Exception ex)
   {
    System.Console.WriteLine(ex.Message);
   }
   finally
   {
    this.IsBusy = false;
    t.Enabled = true;
    //RefreshSettings();
    this.Idle();
   }
  }
 }

 private void Idle()
 {
  System.Console.WriteLine("\nIdle {0}", System.DateTime.Now.ToLocalTime().ToUniversalTime());
  System.Console.WriteLine("The programme will receive mails next time , after " + t.Interval.ToString() + "ms");
  System.Console.WriteLine("press \"exit\" to exit this programe!");
  new System.Threading.Thread(new System.Threading.ThreadStart(DoWait)).Start(); //监视线程: 显示滚动计数器
 }

 private void Pop1_MessagesReceiveAsync(MessagesState oMessagesState)
 {
 }

 private void Pop1_MessageReceived(MessagesState oMessagesState)
 {
  System.Console.WriteLine("\nMessage: [{0}].{1} of {2} Messages have been recieved! {3}", oMessagesState.MessageID, oMessagesState.jMessage.Subject, 0, oMessagesState.MessagesCount);

  //可以每收完一封邮件即删除
  if (!oMessagesState.CancelCurrent)
  {
   //oMessagesState.DeleteSingleMessage(oMessagesState.MessageID);
  }
 }

 private void Wait(ref bool Flag) //Flag 可在其他线程改
 {
  int i = 0;
  string bs = "";
  string s = "";
  while (!Flag)
  {
   s = System.DateTime.Now.ToString();
   System.Console.Write(bs + "\b\b\b" + ++i + " 秒," + s);
   System.Threading.Thread.Sleep(1000); // 1 second
   bs = new string('\b', Digits(i) + s.Length + 1); //19 为日期时间字符串长度, 1 是 ","
  }
  //System.Console.WriteLine();
 }


 private void Pop1_AttachmentReceive(AttachmentsState oAttachmentsState)
 {
  oAttachmentsState.CancelCurrent = true;
  //System.Console.WriteLine(oAttachmentsState.FileName);
  if (!oAttachmentsState.MessagesState.CancelCurrent)
  {
   string S = @"e:\temp\" + oAttachmentsState.FileName;
   oAttachmentsState.SaveToFile(S);
  }
 }

 private void Pop1_MessageReceive(MessagesState oMessagesState)
 {
  //oMessagesState.CancelCurrent = true;
  if (oMessagesState.jMessage.Subject != null)
  {

  }
 }

 private void Pop1_AttachmentException(Microshaoft.OpenMail.AttachmentsState oAttachmentsState)
 {
  System.Console.WriteLine("Execute Exception: {0}", oAttachmentsState.Exception.Message);
  oAttachmentsState.FileName = "e:\\temp\\copy of " + oAttachmentsState.jAttachment.DefaultFileName;
  oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Retry; //上一句文件改名后重新处理
  oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Ignore; //处理下一个附件
  //oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Throw;
 }

 string bs = ""; //用于记录上次的位数
 private void Pop1_DataArrival(int MessageID, int Data)
 {
  if (Data == 0)
  {
   System.Console.WriteLine();
   System.Console.Write("已接收 Message: [{0}] 数据:    ", MessageID);
   bs = "";
  }
  if (Data > 0)
  {
   System.Console.Write(bs + "\b\b\b" + Data + " 行");
   bs = new string('\b', Digits(Data));
  }
 }

 int Digits(int n) //数字所占位数
 {
  n = System.Math.Abs(n);
  n = n/10;
  int i = 1;
  while (n > 0)
  {
   n = n/10;
   i++;
  }
  return i;
 }
}
}


//================================================================================================
// Windows 测试程序:

namespace Microshaoft.OpenMail.WindowsApplicationTest
{
using System;
using System.Windows.Forms;

///


/// Form1 的摘要说明。
///

public class Form1 : System.Windows.Forms.Form
{
 private System.Windows.Forms.Button button1;
 private System.Windows.Forms.Timer timer1;
 private System.ComponentModel.IContainer components;

 public Form1()
 {
  //
  // Windows 窗体设计器支持所必需的
  //
  InitializeComponent();

  //
  // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
  //
 }

 ///


 /// 清理所有正在使用的资源。
 ///

 protected override void Dispose(bool disposing)
 {
  if (disposing)
  {
   if (components != null)
   {
    components.Dispose();
   }
  }
  base.Dispose(disposing);
 }

 #region Windows 窗体设计器生成的代码

 ///


 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
 /// 此方法的内容。
 ///

 private void InitializeComponent()
 {
  this.components = new System.ComponentModel.Container();
  this.button1 = new System.Windows.Forms.Button();
  this.timer1 = new System.Windows.Forms.Timer(this.components);
  this.SuspendLayout();
  //
  // button1
  //
  this.button1.Location = new System.Drawing.Point(24, 24);
  this.button1.Name = "button1";
  this.button1.Size = new System.Drawing.Size(80, 40);
  this.button1.TabIndex = 0;
  this.button1.Text = "button1";
  this.button1.Click += new System.EventHandler(this.button1_Click);
  //
  // timer1
  //
  this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
  //
  // Form1
  //
  this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
  this.ClientSize = new System.Drawing.Size(292, 273);
  this.Controls.Add(this.button1);
  this.Name = "Form1";
  this.Text = "Form1";
  this.ResumeLayout(false);

 }

 #endregion

 ///


 /// 应用程序的主入口点。
 ///

 [STAThread]
 public static void Main0() //Main() //若要单独的 Windows 程序可再换回 Main()
 {
  Application.Run(new Form1());
 }

 private Microshaoft.OpenMail.POP3 x;

 private void button1_Click(object sender, System.EventArgs e)
 {
  timer1.Interval = 1000 * 120; //每 120 秒收取一次邮件
  new System.Threading.Thread(new System.Threading.ThreadStart(this.ThreadProc)).Start();
  //this.ThreadProc();
 }

 private void ThreadProc()
 {
  button1.Enabled = false;
  x = new Microshaoft.OpenMail.POP3("UserName", "Password", "mail.xxx.com");
  x.MessageReceive += new Microshaoft.OpenMail.POP3.MessagesEventHandler(x_MessageReceive);
  x.MessageReceived += new Microshaoft.OpenMail.POP3.MessagesEventHandler(x_MessageReceived);
  x.AttachmentReceive += new Microshaoft.OpenMail.POP3.AttachmentsEventHandler(x_AttachmentReceive);
  x.AttachmentException += new Microshaoft.OpenMail.POP3.AttachmentsEventHandler(x_AttachmentException);
  timer1.Interval = 1000*120; //每 120 秒收取一次邮件
  timer1.Enabled = false;
  x.Execute();
  button1.Enabled = true;
 }

 private void x_MessageReceive(Microshaoft.OpenMail.MessagesState oMessagesState)
 {
  //System.Windows.Forms.MessageBox.Show(oMessagesState.MessageID.ToString());
  System.Console.WriteLine("{0},《{1}》", oMessagesState.MessageID.ToString(), oMessagesState.jMessage.Subject);

  //System.Console.WriteLine(oMessagesState.jMessage.Body);
  //System.Console.WriteLine(oMessagesState.jMessage.Text);

 }

 private void timer1_Tick(object sender, System.EventArgs e)
 {
  //x.Execute();
  new System.Threading.Thread(new System.Threading.ThreadStart(this.ThreadProc)).Start();
 }

 private void x_MessageReceived(Microshaoft.OpenMail.MessagesState oMessagesState)
 {
  if (oMessagesState.MessagesCount == 0)
  {
   //System.Windows.Forms.MessageBox.Show("game over");
  }
  else
  {
   System.Console.WriteLine(oMessagesState.MessageID.ToString());
  }
 }

 private void x_AttachmentReceive(Microshaoft.OpenMail.AttachmentsState oAttachmentsState)
 {
  oAttachmentsState.FileName = "e:\\temp\\" + oAttachmentsState.FileName;
  oAttachmentsState.SaveToFile(oAttachmentsState.FileName);
  if (oAttachmentsState.Exception != null)
  {
   //throw oAttachmentsState.Exception;
  }

  oAttachmentsState.CancelCurrent = true; //不Save处理当前附件
  if (oAttachmentsState.AttachmentsCount == 0)
  {
   //System.Windows.Forms.MessageBox.Show(oAttachmentsState.MessagesState.jMessage.Attachments.Count.ToString());
  }
  else
  {
   System.Console.WriteLine(oAttachmentsState.AttachmentID.ToString());
  }
 }

 private void x_AttachmentException(Microshaoft.OpenMail.AttachmentsState oAttachmentsState)
 {
  System.Console.WriteLine("Execute Exception: {0}", oAttachmentsState.Exception.Message);
  oAttachmentsState.FileName = "e:\\temp\\copy of " + oAttachmentsState.jAttachment.DefaultFileName;
  //oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Retry; //上一句文件改名后重新处理
  oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Ignore; //处理下一个附件
  //oAttachmentsState.ExceptionAction = Microshaoft.OpenMail.ExceptionActions.Throw;
 }
}
}

转载于:https://www.cnblogs.com/Microshaoft/archive/2005/03/21/122674.html

你可能感兴趣的:(java,c#,php)