.NET开发

本类阅读TOP10

·vs.net 2005中文版下载地址收藏
·NHibernate快速指南(翻译)
·【小技巧】一个判断session是否过期的小技巧
·通过Web Services上传和下载文件
·?dos下编译.net程序找不到csc.exe文件
·VB/ASP 调用 SQL Server 的存储过程
·学习笔记(补)《.NET框架程序设计(修订版)》--目录
·对比.NET PetShop和Duwamish来探讨Ado.NET的数据库编程模式
·Autodesk官方最新的.NET教程(一)(vb.net版)
·Duwamish深入剖析-结构篇

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
给 OpenPOP.Net 加一个小功能,可用于收取邮件时监测数据流量!

作者:未知 来源:月光软件站 加入时间:2005-2-28 月光软件站

/*
最近写了一个自动收邮件的机器人,原来一开始偷懒"娶"了 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>
 /// Summary description for Attachment.
 /// </summary>
 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

  /// <summary>
  /// raw attachment content bytes
  /// </summary>
  public byte[] RawBytes
  {
   get
   {
    return _rawBytes;
   }
   set
   {
    _rawBytes = value;
   }
  }

  /// <summary>
  /// whether attachment is in bytes
  /// </summary>
  public bool InBytes
  {
   get
   {
    return _inBytes;
   }
   set
   {
    _inBytes = value;
   }
  }

  /// <summary>
  /// Content length
  /// </summary>
  public long ContentLength
  {
   get
   {
    return _contentLength;
   }
  }

  /// <summary>
  /// verify the attachment whether it is a real attachment or not
  /// </summary>
  /// <remarks>this is so far not comprehensive and needs more work to finish</remarks>
  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;

   }
  }

  /// <summary>
  /// Content format
  /// </summary>
  public string ContentFormat
  {
   get
   {
    return _contentFormat;
   }
  }

  /// <summary>
  /// Content charset
  /// </summary>
  public string ContentCharset
  {
   get
   {
    return _contentCharset;
   }
  }

  /// <summary>
  /// default file name
  /// </summary>
  public string DefaultFileName
  {
   get
   {
    return _defaultFileName;
   }
   set
   {
    _defaultFileName = value;
   }
  }

  /// <summary>
  /// default file name 2
  /// </summary>
  public string DefaultFileName2
  {
   get
   {
    return _defaultFileName2;
   }
   set
   {
    _defaultFileName2 = value;
   }
  }

  /// <summary>
  /// default report file name
  /// </summary>
  public string DefaultReportFileName
  {
   get
   {
    return _defaultReportFileName;
   }
   set
   {
    _defaultReportFileName = value;
   }
  }

  /// <summary>
  /// default MIME File Name
  /// </summary>
  public string DefaultMIMEFileName
  {
   get
   {
    return _defaultMIMEFileName;
   }
   set
   {
    _defaultMIMEFileName = value;
   }
  }

  /// <summary>
  /// Content Type
  /// </summary>
  public string ContentType
  {
   get
   {
    return _contentType;
   }
  }

  /// <summary>
  /// Content Transfer Encoding
  /// </summary>
  public string ContentTransferEncoding
  {
   get
   {
    return _contentTransferEncoding;
   }
  }

  /// <summary>
  /// Content Description
  /// </summary>
  public string ContentDescription
  {
   get
   {
    return _contentDescription;
   }
  }

  /// <summary>
  /// Content File Name
  /// </summary>
  public string ContentFileName
  {
   get
   {
    return _contentFileName;
   }
   set
   {
    _contentFileName = value;
   }
  }

  /// <summary>
  /// Content Disposition
  /// </summary>
  public string ContentDisposition
  {
   get
   {
    return _contentDisposition;
   }
  }

  /// <summary>
  /// Content ID
  /// </summary>
  public string ContentID
  {
   get
   {
    return _contentID;
   }
  }

  /// <summary>
  /// Raw Attachment
  /// </summary>
  public string RawAttachment
  {
   get
   {
    return _rawAttachment;
   }
  }

  /// <summary>
  /// decoded attachment in bytes
  /// </summary>
  public byte[] DecodedAttachment
  {
   get
   {
    return DecodedAsBytes();
   }
  }

  #endregion

  /// <summary>
  /// release all objects
  /// </summary>
  ~Attachment()
  {
   _rawBytes = null;
   _rawAttachment = null;
  }

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

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

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

  /// <summary>
  /// New Attachment
  /// </summary>
  /// <param name="strAttachment">attachment content</param>
  public Attachment(string strAttachment)
  {
   this.NewAttachment(strAttachment, true);
  }

  /// <summary>
  /// create attachment
  /// </summary>
  /// <param name="strAttachment">raw attachment text</param>
  /// <param name="blnParseHeader">parse header</param>
  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;
  }

  /// <summary>
  /// Parse header fields and set member variables
  /// </summary>
  /// <param name="srReader">string reader</param>
  /// <param name="strLine">header line</param>
  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();

     ///<bug>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;
   }
  }

  /// <summary>
  /// verify the encoding
  /// </summary>
  /// <param name="encoding">encoding to verify</param>
  /// <returns>true if encoding</returns>
  private bool IsEncoding(string encoding)
  {
   return _contentTransferEncoding.ToLower().IndexOf(encoding.ToLower()) != -1;
  }

  /// <summary>
  /// Decode the attachment to text
  /// </summary>
  /// <returns>Decoded attachment text</returns>
  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;
  }

  /// <summary>
  /// decode attachment to be a message object
  /// </summary>
  /// <returns>message</returns>
  public Message DecodeAsMessage()
  {
   bool blnRet = false;
   return new Message(ref blnRet, "", false, _rawAttachment, false);
  }

  /// <summary>
  /// Decode the attachment to bytes
  /// </summary>
  /// <returns>Decoded attachment bytes</returns>
  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
 }

 /// <summary>
 /// Decoding Quoted-Printable text
 ///
 /// </summary>
 public class DecodeQP
 {
  public DecodeQP()
  {
  }

  /// <summary>
  /// Decoding Quoted-Printable string
  /// </summary>
  /// <param name="Hexstring">Quoted-Printable encoded string</param>
  /// <param name="encode">encoding method</param>
  /// <returns>decoded string</returns>
  public static string ConvertHexToString(string Hexstring, string Encoding)
  {
   try
   {
    return ConvertHexToString(Hexstring, System.Text.Encoding.GetEncoding(Encoding));
   }
   catch
   {
    return ConvertHexContent(Hexstring);
   }
  }

  /// <summary>
  /// Decoding Quoted-Printable string
  /// </summary>
  /// <param name="Hexstring">Quoted-Printable encoded string</param>
  /// <param name="encode">encoding method</param>
  /// <returns>decoded string</returns>
  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;
   }
  }

  /// <summary>
  /// Decoding Quoted-Printable string at a position
  /// </summary>
  /// <param name="Hexstring">Quoted-Printable encoded string</param>
  /// <param name="encode">encoding method, "Default" is suggested</param>
  /// <param name="nStart">position to start, normally 0</param>
  /// <returns>decoded string</returns>
  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();
  }


  /// <summary>
  /// Decoding Quoted-Printable string using default encoding and begin at 0
  /// </summary>
  /// <param name="Hexstring">Quoted-Printable encoded string</param>
  /// <returns>decoded string</returns>
  public static string ConvertHexContent(string Hexstring)
  {
   if (Hexstring == null || Hexstring.Equals("")) return Hexstring;

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

  }
 }

 /// <summary>
 /// Message Parser.
 /// </summary>
 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

  /// <summary>
  /// custom headers
  /// </summary>
  public Hashtable CustomHeaders
  {
   get
   {
    return _customHeaders;
   }
   set
   {
    _customHeaders = value;
   }
  }

  /// <summary>
  /// whether auto decoding MS-TNEF attachment files
  /// </summary>
  public bool AutoDecodeMSTNEF
  {
   get
   {
    return _autoDecodeMSTNEF;
   }
   set
   {
    _autoDecodeMSTNEF = value;
   }
  }

  /// <summary>
  /// path to extract MS-TNEF attachment files
  /// </summary>
  public string BasePath
  {
   get
   {
    return _basePath;
   }
   set
   {
    try
    {
     if (value.EndsWith("\\"))
      _basePath = value;
     else
      _basePath = value + "\\";
    }
    catch
    {
    }
   }
  }

  /// <summary>
  /// message keywords
  /// </summary>
  public ArrayList Keywords
  {
   get
   {
    return _keywords;
   }
  }

  /// <summary>
  /// disposition notification
  /// </summary>
  public string DispositionNotificationTo
  {
   get
   {
    return _dispositionNotificationTo;
   }
  }

  /// <summary>
  /// received server
  /// </summary>
  public string Received
  {
   get
   {
    return _received;
   }
  }

  /// <summary>
  /// importance level
  /// </summary>
  public string Importance
  {
   get
   {
    return _importance;
   }
  }

  /// <summary>
  /// importance level type
  /// </summary>
  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;
    }
   }
  }

  /// <summary>
  /// Content Charset
  /// </summary>
  public string ContentCharset
  {
   get
   {
    return _contentCharset;
   }
  }

  /// <summary>
  /// Content Transfer Encoding
  /// </summary>
  public string ContentTransferEncoding
  {
   get
   {
    return _contentTransferEncoding;
   }
  }

  /// <summary>
  /// Message Bodies
  /// </summary>
  public ArrayList MessageBody
  {
   get
   {
    return _messageBody;
   }
  }

  /// <summary>
  /// Attachment Boundry
  /// </summary>
  public string AttachmentBoundry
  {
   get
   {
    return _attachmentboundry;
   }
  }

  /// <summary>
  /// Alternate Attachment Boundry
  /// </summary>
  public string AttachmentBoundry2
  {
   get
   {
    return _attachmentboundry2;
   }
  }

  /// <summary>
  /// Attachment Count
  /// </summary>
  public int AttachmentCount
  {
   get
   {
    return _attachmentCount;
   }
  }

  /// <summary>
  /// Attachments
  /// </summary>
  public ArrayList Attachments
  {
   get
   {
    return _attachments;
   }
  }

  /// <summary>
  /// CC
  /// </summary>
  public string[] CC
  {
   get
   {
    return _cc;
   }
  }

  /// <summary>
  /// BCC
  /// </summary>
  public string[] BCC
  {
   get
   {
    return _bcc;
   }
  }

  /// <summary>
  /// TO
  /// </summary>
  public string[] TO
  {
   get
   {
    return _to;
   }
  }

  /// <summary>
  /// Content Encoding
  /// </summary>
  public string ContentEncoding
  {
   get
   {
    return _contentEncoding;
   }
  }

  /// <summary>
  /// Content Length
  /// </summary>
  public long ContentLength
  {
   get
   {
    return _contentLength;
   }
  }

  /// <summary>
  /// Content Type
  /// </summary>
  public string ContentType
  {
   get
   {
    return _contentType;
   }
  }

  /// <summary>
  /// Report Type
  /// </summary>
  public string ReportType
  {
   get
   {
    return _reportType;
   }
  }

  /// <summary>
  /// HTML
  /// </summary>
  public bool HTML
  {
   get
   {
    return _html;
   }
  }

  /// <summary>
  /// Date
  /// </summary>
  public string Date
  {
   get
   {
    return _date;
   }
  }

  /// <summary>
  /// DateTime Info
  /// </summary>
  public string DateTimeInfo
  {
   get
   {
    return _dateTimeInfo;
   }
  }

  /// <summary>
  /// From name
  /// </summary>
  public string From
  {
   get
   {
    return _from;
   }
  }

  /// <summary>
  /// From Email
  /// </summary>
  public string FromEmail
  {
   get
   {
    return _fromEmail;
   }
  }

  /// <summary>
  /// Reply to name
  /// </summary>
  public string ReplyTo
  {
   get
   {
    return _replyTo;
   }
  }

  /// <summary>
  /// Reply to email
  /// </summary>
  public string ReplyToEmail
  {
   get
   {
    return _replyToEmail;
   }
  }

  /// <summary>
  /// whether has attachment
  /// </summary>
  public bool HasAttachment
  {
   get
   {
    return _hasAttachment;
   }
  }

  /// <summary>
  /// raw message body
  /// </summary>
  public string RawMessageBody
  {
   get
   {
    return _rawMessageBody;
   }
  }

  /// <summary>
  /// Message ID
  /// </summary>
  public string MessageID
  {
   get
   {
    return _messageID;
   }
  }

  /// <summary>
  /// MIME version
  /// </summary>
  public string MimeVersion
  {
   get
   {
    return _mimeVersion;
   }
  }

  /// <summary>
  /// raw header
  /// </summary>
  public string RawHeader
  {
   get
   {
    return _rawHeader;
   }
  }

  /// <summary>
  /// raw message
  /// </summary>
  public string RawMessage
  {
   get
   {
    return _rawMessage;
   }
  }

  /// <summary>
  /// return path
  /// </summary>
  public string ReturnPath
  {
   get
   {
    return _returnPath;
   }
  }

  /// <summary>
  /// subject
  /// </summary>
  public string Subject
  {
   get
   {
    return _subject;
   }
  }

  #endregion

  /// <summary>
  /// release all objects
  /// </summary>
  ~Message()
  {
   _attachments.Clear();
   _attachments = null;
   _keywords.Clear();
   _keywords = null;
   _messageBody.Clear();
   _messageBody = null;
   _customHeaders.Clear();
   _customHeaders = null;
  }

  /// <summary>
  /// New Message
  /// </summary>
  /// <param name="blnFinish">reference for the finishing state</param>
  /// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
  /// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
  /// <param name="blnOnlyHeader">whether only decode the header without body</param>
  /// <param name="strEMLFile">file of email content to load from</param>
  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;
  }

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

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

  /// <summary>
  /// New Message
  /// </summary>
  /// <param name="blnFinish">reference for the finishing state</param>
  /// <param name="strMessage">raw message content</param>
  public Message(ref bool blnFinish, string strMessage)
  {
   NewMessage(ref blnFinish, "", false, strMessage, false);
  }

  /// <summary>
  /// get valid attachment
  /// </summary>
  /// <param name="intAttachmentNumber">attachment index in the attachments collection</param>
  /// <returns>attachment</returns>
  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];
  }

  /// <summary>
  /// New Message
  /// </summary>
  /// <param name="blnFinish">reference for the finishing state</param>
  /// <param name="strBasePath">path to extract MS-TNEF attachment files</param>
  /// <param name="blnAutoDecodeMSTNEF">whether auto decoding MS-TNEF attachments</param>
  /// <param name="strMessage">raw message content</param>
  /// <param name="blnOnlyHeader">whether only decode the header without body</param>
  /// <returns>construction result whether successfully new a message</returns>
  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;
  }

  /// <summary>
  /// parse message body
  /// </summary>
  /// <param name="strBuffer">raw message body</param>
  /// <returns>message body</returns>
  public string GetTextBody(string strBuffer)
  {
   if (strBuffer.EndsWith("\r\n."))
    return strBuffer.Substring(0, strBuffer.Length - "\r\n.".Length);
   else
    return strBuffer;
  }

  /// <summary>
  /// parse message body
  /// </summary>
  /// <param name="strBuffer">raw message body</param>
  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;
  }

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

  /// <summary>
  /// verify if the attachment is MIME Email file
  /// </summary>
  /// <param name="attItem">attachment</param>
  /// <returns>if MIME Email file, return true, else, false</returns>
  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;
   }
  }

  /// <summary>
  /// translate pictures url within the body
  /// </summary>
  /// <param name="strBody">message body</param>
  /// <param name="hsbFiles">pictures collection</param>
  /// <returns>translated message body</returns>
  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;
  }

  /// <summary>
  /// translate pictures url within the body
  /// </summary>
  /// <param name="strBody">message body</param>
  /// <param name="strPath">path of the pictures</param>
  /// <returns>translated message body</returns>
  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;
  }

  /// <summary>
  /// Get the proper attachment file name
  /// </summary>
  /// <param name="attItem">attachment</param>
  /// <returns>propery attachment file name</returns>
  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);
  }

  /// <summary>
  /// save attachments to a defined path
  /// </summary>
  /// <param name="strPath">path to have attachments to be saved to</param>
  /// <returns>true if save successfully, false if failed</returns>
  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;
  }

  /// <summary>
  /// save attachment to file
  /// </summary>
  /// <param name="attItem">Attachment</param>
  /// <param name="strFileName">File to be saved to</param>
  /// <returns>true if save successfully, false if failed</returns>
  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);
   }
  }

  /// <summary>
  /// set attachments
  /// </summary>
  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++;
   }
  }

  /// <summary>
  /// Set alternative attachment boundry
  /// </summary>
  /// <param name="strBuffer">raw message</param>
  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;
   }
  }

  /// <summary>
  /// Save message content to eml file
  /// </summary>
  /// <param name="strFile"></param>
  /// <returns></returns>
  public bool SaveToMIMEEmailFile(string strFile, bool blnReplaceExists)
  {
   return Utility.SavePlainTextToFile(strFile, _rawMessage, blnReplaceExists);
  }

  /// <summary>
  /// parse multi-line header
  /// </summary>
  /// <param name="sbdBuilder">string builder to hold header content</param>
  /// <param name="srdReader">string reader to get each line of the header</param>
  /// <param name="strValue">first line content</param>
  /// <param name="strLine">reference header line</param>
  /// <param name="alCollection">collection to hold every content line</param>
  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);
  }

  /// <summary>
  /// parse multi-line header
  /// </summary>
  /// <param name="sbdBuilder">string builder to hold header content</param>
  /// <param name="srdReader">string reader to get each line of the header</param>
  /// <param name="strName">collection key</param>
  /// <param name="strValue">first line content</param>
  /// <param name="strLine">reference header line</param>
  /// <param name="hstCollection">collection to hold every content line</param>
  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);
  }

  /// <summary>
  /// parse multi-line header
  /// </summary>
  /// <param name="sbdBuilder">string builder to hold header content</param>
  /// <param name="srdReader">string reader to get each line of the header</param>
  /// <param name="strValue">first line content</param>
  /// <param name="strLine">reference header line</param>
  /// <param name="strReturn">return value</param>
  /// <param name="blnLineDecode">decode each line</param>
  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);
  }

  /// <summary>
  /// Parse the headers populating respective member fields
  /// </summary>
  /// <param name="sbdBuilder">string builder to hold the header content</param>
  /// <param name="srdReader">string reader to get each line of the header</param>
  /// <param name="strLine">reference header line</param>
  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;
   }
  }
 }

 /// <summary>
 /// MIMETypes
 /// </summary>
 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");
  }

  /// <summary>Returns the MIME content-type for the supplied file extension</summary>
  /// <returns>string MIME type (Example: \"text/plain\")</returns>
  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>
 /// Summary description for Coding.
 /// </summary>
 public class QuotedCoding
 {
  /// <summary>
  /// zwraca tablice bajtow
  /// zamienia 3 znaki np '=A9' na odp wartosc.
  /// zamienia '_' na znak 32
  /// </summary>
  /// <param name="s">Kupis_Pawe=B3</param>
  /// <returns>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
  &nbs