public ImapMultiPartBodyStructure(string section,
                                      IImapBodyStructure[] nestedStructures,
                                      string subtype)
        {
            if (section == null)
            throw new ArgumentNullException("section");
              if (nestedStructures == null)
            throw new ArgumentNullException("nestedStructures");

              this.Section          = section;
              this.MediaType        = MimeType.CreateMultipartType(subtype);
              this.NestedStructures = nestedStructures;

              ImapBodyStructureUtils.SetParentStructure(this);
        }
        public ImapMessageRfc822BodyStructure(string section,
                                          MimeType mediaType,
                                          IDictionary<string, string> parameters,
                                          string id,
                                          string description,
                                          string encoding,
                                          long size,
                                          ImapEnvelope envelope,
                                          IImapBodyStructure bodyStructure,
                                          long lineCount)
            : base(section, mediaType, parameters, id, description, encoding, size, lineCount)
        {
            if (envelope == null)
            throw new ArgumentNullException("envelope");
              if (bodyStructure == null)
            throw new ArgumentNullException("bodyStructure");

              this.Envelope       = envelope;
              this.BodyStructure  = bodyStructure;

              ImapBodyStructureUtils.SetParentStructure(this);
        }
        public void TestFetchResponseBodyStructureMessageRfc822()
        {
            var response =
            GetSingleDataResponse("* 14 FETCH (UID 30 BODYSTRUCTURE (" +
                              "(\"text\" \"plain\" (\"charset\" \"ISO-2022-JP\") NIL NIL \"7bit\" 6 1 NIL NIL NIL NIL)" +
                              "(\"message\" \"rfc822\" (\"name\" \"=?ISO-2022-JP?B?GyRCRTpJVSVhJUMlOyE8JTgbKEI=?=\") " +
                              "NIL NIL \"7bit\" 188 (NIL \"test mail\" NIL NIL NIL NIL NIL NIL NIL NIL) " +
                              "(\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\" 121 6 NIL NIL NIL NIL) 10 NIL " +
                              "(\"inline\" (\"filename\" \"ISO-2022-JP''%1B%24%42%45%3A%49%55%25%61%25%43%25%3B%21%3C%25%38%1B%28%42\")) NIL NIL) " +
                              "\"mixed\" (\"boundary\" \"------------040401080108050302040809\") NIL NIL NIL))\r\n");
              var message = ImapDataResponseConverter.FromFetch<ImapMessageStaticAttribute>(response);

              Assert.AreEqual(14L, message.Sequence);
              Assert.AreEqual(30L, message.Uid);

              var bodystructure = message.BodyStructure as ImapMultiPartBodyStructure;

              Assert.IsNotNull(bodystructure);
              Assert.IsNull(bodystructure.ParentStructure);
              Assert.AreEqual(2, bodystructure.NestedStructures.Length);
              Assert.AreEqual(string.Empty, bodystructure.Section);
              Assert.AreEqual("multipart/mixed", (string)bodystructure.MediaType);

              var extBodyStructure = bodystructure as ImapExtendedMultiPartBodyStructure;

              Assert.IsNotNull(extBodyStructure);
              Assert.AreEqual(1, extBodyStructure.Parameters.Count);
              Assert.AreEqual("------------040401080108050302040809", extBodyStructure.Parameters["boundary"]);
              Assert.IsNull(extBodyStructure.Disposition);
              Assert.IsNull(extBodyStructure.Languages);
              Assert.IsNull(extBodyStructure.Location);
              Assert.IsNull(extBodyStructure.Extensions);

              var nested = bodystructure.NestedStructures;
              var part1 = nested[0] as ImapSinglePartBodyStructure;

              Assert.IsNotNull(part1);
              Assert.AreSame(bodystructure, part1.ParentStructure);
              Assert.AreEqual("1", part1.Section);
              Assert.AreEqual("text/plain", (string)part1.MediaType);
              Assert.AreEqual(1, part1.Parameters.Count);
              Assert.AreEqual("ISO-2022-JP", part1.Parameters["charset"]);
              Assert.IsNull(part1.Id);
              Assert.IsNull(part1.Description);
              Assert.AreEqual("7bit", part1.Encoding);
              Assert.AreEqual(6L, part1.Size);
              Assert.AreEqual(1L, part1.LineCount);

              var part1ext = part1 as ImapExtendedSinglePartBodyStructure;

              Assert.IsNotNull(part1ext);
              Assert.IsNull(part1ext.MD5);
              Assert.IsNull(part1ext.Disposition);
              Assert.IsNull(part1ext.Languages);
              Assert.IsNull(part1ext.Location);
              Assert.IsNull(part1ext.Extensions);

              var part2 = nested[1] as ImapMessageRfc822BodyStructure;

              Assert.IsNotNull(part2);
              Assert.AreSame(bodystructure, part1.ParentStructure);
              Assert.AreEqual("2", part2.Section);
              Assert.AreEqual("message/rfc822", (string)part2.MediaType);
              Assert.AreEqual(1, part2.Parameters.Count);
              Assert.AreEqual("=?ISO-2022-JP?B?GyRCRTpJVSVhJUMlOyE8JTgbKEI=?=", part2.Parameters["name"]);
              Assert.IsNull(part2.Id);
              Assert.IsNull(part2.Description);
              Assert.AreEqual("7bit", part2.Encoding);
              Assert.AreEqual(188L, part2.Size);

              Assert.IsNotNull(part2.Envelope);
              Assert.IsNull(part2.Envelope.Date);
              Assert.AreEqual("test mail", part2.Envelope.Subject);
              Assert.IsEmpty(part2.Envelope.From);
              Assert.IsEmpty(part2.Envelope.Sender);
              Assert.IsEmpty(part2.Envelope.ReplyTo);
              Assert.IsEmpty(part2.Envelope.To);
              Assert.IsEmpty(part2.Envelope.Cc);
              Assert.IsEmpty(part2.Envelope.Bcc);
              Assert.IsNull(part2.Envelope.InReplyTo);
              Assert.IsNull(part2.Envelope.MessageId);

              var part2encapsulated = part2.BodyStructure as ImapSinglePartBodyStructure;

              Assert.IsNotNull(part2encapsulated);
              Assert.AreSame(part2, part2encapsulated.ParentStructure);
              Assert.AreEqual("2.1", part2encapsulated.Section);
              Assert.AreEqual("text/plain", (string)part2encapsulated.MediaType);
              Assert.AreEqual(1, part2encapsulated.Parameters.Count);
              Assert.AreEqual("us-ascii", part2encapsulated.Parameters["charset"]);
              Assert.IsNull(part2encapsulated.Id);
              Assert.IsNull(part2encapsulated.Description);
              Assert.AreEqual("7bit", part2encapsulated.Encoding);
              Assert.AreEqual(121L, part2encapsulated.Size);
              Assert.AreEqual(6L, part2encapsulated.LineCount);

              var part2encapsulatedExt = part2encapsulated as ImapExtendedSinglePartBodyStructure;

              Assert.IsNotNull(part2encapsulatedExt);
              Assert.IsNull(part2encapsulatedExt.MD5);
              Assert.IsNull(part2encapsulatedExt.Disposition);
              Assert.IsNull(part2encapsulatedExt.Languages);
              Assert.IsNull(part2encapsulatedExt.Location);
              Assert.IsNull(part2encapsulatedExt.Extensions);

              Assert.AreEqual(10L, part2.LineCount);

              var part2ext = part2 as ImapExtendedMessageRfc822BodyStructure;

              Assert.IsNotNull(part2ext);
              Assert.IsNull(part2ext.MD5);
              Assert.IsNotNull(part2ext.Disposition);
              Assert.AreEqual("inline", part2ext.Disposition.Type);
              Assert.IsTrue(part2ext.Disposition.IsInline);
              Assert.AreEqual(1, part2ext.Disposition.Parameters.Count);
              Assert.AreEqual("ISO-2022-JP''%1B%24%42%45%3A%49%55%25%61%25%43%25%3B%21%3C%25%38%1B%28%42",
                      part2ext.Disposition.Parameters["filename"]);
              Assert.AreEqual("ISO-2022-JP''%1B%24%42%45%3A%49%55%25%61%25%43%25%3B%21%3C%25%38%1B%28%42",
                      part2ext.Disposition.Filename);
              Assert.IsNull(part2ext.Languages);
              Assert.IsNull(part2ext.Location);
              Assert.IsNull(part2ext.Extensions);

              /*
               * IEnumerable
               */
              var expectingEnumeratedStructures = new IImapBodyStructure[] {
            part1,
            part2,
              };
              var index = 0;

              foreach (var part in bodystructure) {
            Assert.AreSame(expectingEnumeratedStructures[index++], part, "enumerated instances are same #{0}", index);
              }

              var expectingEnumeratedStructuresInPart2 = new IImapBodyStructure[] {
            part2encapsulated,
              };

              index = 0;

              foreach (var part in part2) {
            Assert.AreSame(expectingEnumeratedStructuresInPart2[index++], part, "enumerated instances are same #{0}", index);
              }

              /*
               * ImapBodyStructureUtils
               */
              var expectingTraversedStructures = new IImapBodyStructure[] {
            part1,
            part2,
            part2encapsulated,
              };

              index = 0;

              bodystructure.Traverse(delegate(IImapBodyStructure part) {
            Assert.AreSame(expectingTraversedStructures[index++], part, "traversed instances are same #{0}", index);
              });
        }
        public void TestFetchResponseBodyStructure()
        {
            var response =
            GetSingleDataResponse("* 7 FETCH (UID 23 BODYSTRUCTURE (" +
                              "(\"text\" \"plain\" (\"format\" \"flowed\" \"charset\" \"iso-2022-jp\" \"reply-type\" \"original\") "+
                              "NIL NIL \"7bit\" 75 3 NIL NIL NIL NIL)" +
                              "(\"application\" \"x-zip-compressed\" (\"name\" \"tmp.zip\") " +
                              "NIL NIL \"base64\" 8200 NIL (\"attachment\" (\"filename\" \"tmp.zip\")) NIL NIL) " +
                              "\"mixed\" (\"boundary\" \"----=_NextPart_000_0018_01CA37E0.F7885730\") NIL NIL NIL))\r\n");

              var message = ImapDataResponseConverter.FromFetch<ImapMessageAttribute>(response);

              Assert.AreEqual(7L, message.Sequence);
              Assert.AreEqual(23L, message.Uid);

              var bodystructure = message.BodyStructure as ImapMultiPartBodyStructure;

              Assert.IsNotNull(bodystructure);
              Assert.IsNull(bodystructure.ParentStructure);
              Assert.AreEqual(2, bodystructure.NestedStructures.Length);
              Assert.AreEqual(string.Empty, bodystructure.Section);
              Assert.AreEqual("multipart/mixed", (string)bodystructure.MediaType);

              var extBodyStructure = bodystructure as ImapExtendedMultiPartBodyStructure;

              Assert.IsNotNull(extBodyStructure);
              Assert.AreEqual(1, extBodyStructure.Parameters.Count);
              Assert.AreEqual("----=_NextPart_000_0018_01CA37E0.F7885730", extBodyStructure.Parameters["boundary"]);
              Assert.IsNull(extBodyStructure.Disposition);
              Assert.IsNull(extBodyStructure.Languages);
              Assert.IsNull(extBodyStructure.Location);
              Assert.IsNull(extBodyStructure.Extensions);

              var nested = bodystructure.NestedStructures;

              var part1 = nested[0] as ImapSinglePartBodyStructure;

              Assert.IsNotNull(part1);
              Assert.AreSame(bodystructure, part1.ParentStructure);
              Assert.AreEqual("1", part1.Section);
              Assert.AreEqual("text/plain", (string)part1.MediaType);
              Assert.AreEqual(3, part1.Parameters.Count);
              Assert.AreEqual("flowed", part1.Parameters["format"]);
              Assert.AreEqual("iso-2022-jp", part1.Parameters["charset"]);
              Assert.AreEqual("original", part1.Parameters["reply-type"]);
              Assert.IsNull(part1.Id);
              Assert.IsNull(part1.Description);
              Assert.AreEqual("7bit", part1.Encoding);
              Assert.AreEqual(75L, part1.Size);
              Assert.AreEqual(3L, part1.LineCount);

              var part1ext = part1 as ImapExtendedSinglePartBodyStructure;

              Assert.IsNotNull(part1ext);
              Assert.IsNull(part1ext.MD5);
              Assert.IsNull(part1ext.Disposition);
              Assert.IsNull(part1ext.Languages);
              Assert.IsNull(part1ext.Location);
              Assert.IsNull(part1ext.Extensions);

              var part2 = nested[1] as ImapSinglePartBodyStructure;

              Assert.IsNotNull(part2);
              Assert.AreSame(bodystructure, part2.ParentStructure);
              Assert.AreEqual("2", part2.Section);
              Assert.AreEqual("application/x-zip-compressed", (string)part2.MediaType);
              Assert.AreEqual(1, part2.Parameters.Count);
              Assert.AreEqual("tmp.zip", part2.Parameters["name"]);
              Assert.IsNull(part2.Id);
              Assert.IsNull(part2.Description);
              Assert.AreEqual("base64", part2.Encoding);
              Assert.AreEqual(8200, part2.Size);
              Assert.AreEqual(0L, part2.LineCount);

              var part2ext = part2 as ImapExtendedSinglePartBodyStructure;

              Assert.IsNotNull(part2ext);
              Assert.IsNull(part2ext.MD5);
              Assert.IsNotNull(part2ext.Disposition);
              Assert.AreEqual("attachment", part2ext.Disposition.Type);
              Assert.IsTrue(part2ext.Disposition.IsAttachment);
              Assert.IsFalse(part2ext.Disposition.IsInline);
              Assert.AreEqual(1, part2ext.Disposition.Parameters.Count);
              Assert.AreEqual("tmp.zip", part2ext.Disposition.Parameters["filename"]);
              Assert.AreEqual("tmp.zip", part2ext.Disposition.Filename);
              Assert.IsNull(part2ext.Languages);
              Assert.IsNull(part2ext.Location);
              Assert.IsNull(part2ext.Extensions);

              /*
               * IEnumerable
               */
              var expectingEnumeratedStructures = new IImapBodyStructure[] {
            part1,
            part2,
              };
              var index = 0;

              foreach (var part in bodystructure) {
            Assert.AreSame(expectingEnumeratedStructures[index++], part, "enumerated instances are same #{0}", index);
              }

              /*
               * ImapBodyStructureUtils
               */
              var expectingTraversedStructures = new IImapBodyStructure[] {
            part1,
            part2,
              };

              index = 0;

              bodystructure.Traverse(delegate(IImapBodyStructure part) {
            Assert.AreSame(expectingTraversedStructures[index++], part, "traversed instances are same #{0}", index);
              });
        }
        internal static Uri GetUrl(IImapBodyStructure bodyStructure, ImapUriBuilder baseUrl)
        {
            if (baseUrl == null)
            throw new NotSupportedException("The base URL is not specified.");
              else if (baseUrl.Uid == 0L)
            throw new NotSupportedException("The UID of the base URL is not specified.");

              if (baseUrl.Section != bodyStructure.Section)
            baseUrl.Section = bodyStructure.Section;

              return baseUrl.Uri;
        }