/// <summary>
        /// ヘッダ文字列から件名を取得する
        /// NOTE: 自分で出力した形式にしか対応していない
        /// </summary>
        /// <param name="headers">ヘッダ文字列</param>
        /// <returns>件名</returns>
        private static string GetSubjectText(string headers)
        {
            int startIndex = headers.IndexOf(MailMessage.SUBJECT, 0, StringComparison.CurrentCultureIgnoreCase);

            if (startIndex < 0)
            {
                return("");
            }

            startIndex += MailMessage.SUBJECT.Length;

            int index    = startIndex;
            int endIndex = startIndex;

            while (true)
            {
                index = headers.IndexOf("\r\n", index);
                if (index < 0)
                {
                    break;
                }
                if (headers.Length <= index + 2)
                {
                    break;
                }
                endIndex = index;
                if (headers[index + 2] != ' ' && headers[index + 2] != '\t')
                {
                    break;
                }
                index += 2;
            }
            if (endIndex == startIndex)
            {
                return("");
            }

            string subject = headers.Substring(startIndex, endIndex - startIndex);
            Regex  regex   = new Regex(@"=\?(?<charset>.*?)\?(?<encoding>.)\?(?<value>.*?)\?=");

            StringBuilder result = new StringBuilder();

            MatchCollection matchCollection = regex.Matches(subject);

            foreach (Match match in matchCollection)
            {
                if (match.Success)
                {
                    string charset  = match.Groups["charset"].Value.ToLower();
                    string encoding = match.Groups["encoding"].Value.ToLower();
                    string val      = match.Groups["value"].Value;

                    if (charset == "iso-2022-jp" && encoding == "b")
                    {
                        // OK
                    }
                    else
                    {
                        // 未対応
                        return("");
                    }

                    byte[] dataPart = Convert.FromBase64String(val);
                    bool   inJpn    = false;

                    int dataPartLength = dataPart.Length;

                    for (int i = 0; i < dataPartLength;)
                    {
                        if (CharCodeUtils.IsBeginEscapeSequence(dataPart, i))
                        {
                            inJpn = true;
                            i    += 3;
                            continue;
                        }
                        if (CharCodeUtils.IsEndEscapeSequence(dataPart, i))
                        {
                            inJpn = false;
                            i    += 3;
                            continue;
                        }
                        if (inJpn)
                        {
                            if (i <= dataPartLength - 2)
                            {
                                int   jiscode = CharCodeUtils.MergeHL(dataPart[i], dataPart[i + 1]);
                                Emoji emoji   = DataBags.Emojis.GetFromJiscode(jiscode);
                                if (emoji != null)
                                {
                                    result.Append(emoji.Unicode);
                                }
                                else
                                {
                                    string sch = CharCodeUtils.GetCharFromJisCode(jiscode);
                                    if (sch != null)
                                    {
                                        result.Append(sch);
                                    }
                                }

                                i += 2;
                            }
                            else
                            {
                                i += 1;
                            }
                        }
                        else
                        {
                            char ascii = (char)dataPart[i];
                            result.Append(ascii);
                            i += 1;
                        }
                    }
                }
            }

            return(result.ToString());
        }
        /// <summary>
        /// ボディ部データから本文を取得する
        /// NOTE: 自分で出力した形式にしか対応していない
        /// </summary>
        /// <param name="data">ボディ部データ</param>
        /// <param name="offset">オフセット</param>
        /// <returns>本文</returns>
        private static string GetBodyText(byte[] data, int offset)
        {
            bool inJpn = false;

            int dataLength = data.Length;

            StringBuilder result = new StringBuilder();

            for (int i = offset; i < dataLength;)
            {
                if (CharCodeUtils.IsCrLf(data, i))
                {
                    inJpn = false;
                    i    += 2;
                    result.Append("\r\n");
                    continue;
                }
                if (CharCodeUtils.IsBeginEscapeSequence(data, i))
                {
                    inJpn = true;
                    i    += 3;
                    continue;
                }
                if (CharCodeUtils.IsEndEscapeSequence(data, i))
                {
                    inJpn = false;
                    i    += 3;
                    continue;
                }
                if (inJpn)
                {
                    if (i <= dataLength - 2)
                    {
                        int   jiscode = CharCodeUtils.MergeHL(data[i], data[i + 1]);
                        Emoji emoji   = DataBags.Emojis.GetFromJiscode(jiscode);
                        if (emoji != null)
                        {
                            result.Append(emoji.Unicode);
                        }
                        else
                        {
                            string sch = CharCodeUtils.GetCharFromJisCode(jiscode);
                            if (sch != null)
                            {
                                result.Append(sch);
                            }
                        }

                        i += 2;
                    }
                    else
                    {
                        i += 1;
                    }
                }
                else
                {
                    char ascii = (char)data[i];
                    result.Append(ascii);
                    i += 1;
                }
            }

            return(result.ToString());
        }