Example #1
0
        public void TestArgumentExceptions()
        {
            var      uids = new UniqueIdSet(SortOrder.Ascending);
            UniqueId uid;

            Assert.IsFalse(uids.IsReadOnly);

            uids.Add(UniqueId.MinValue);

            Assert.Throws <ArgumentOutOfRangeException> (() => new UniqueIdSet((SortOrder)500));
            Assert.Throws <ArgumentException> (() => uids.Add(UniqueId.Invalid));
            Assert.Throws <ArgumentNullException> (() => uids.AddRange(null));
            Assert.Throws <ArgumentNullException> (() => uids.CopyTo(null, 0));
            Assert.Throws <ArgumentOutOfRangeException> (() => uids.CopyTo(new UniqueId[1], -1));
            Assert.Throws <ArgumentOutOfRangeException> (() => uids.RemoveAt(-1));
            Assert.Throws <ArgumentOutOfRangeException> (() => uid = uids[-1]);
            Assert.Throws <NotSupportedException> (() => uids[0]   = UniqueId.MinValue);
            Assert.Throws <NotSupportedException> (() => uids.Insert(0, UniqueId.MinValue));

            var list = new List <UniqueId> {
                UniqueId.Invalid
            };

            Assert.Throws <ArgumentNullException> (() => UniqueIdSet.ToString(null));
            Assert.Throws <ArgumentException> (() => UniqueIdSet.ToString(list));

            Assert.Throws <ArgumentNullException> (() => UniqueIdSet.TryParse(null, out uids));
        }
Example #2
0
        public void TestCopyTo()
        {
            var          ids     = new uint[] { 20, 19, 15, 12, 11, 10, 9, 6, 5, 3, 2, 1 };
            const string example = "20:19,15,12:9,6:5,3:1";
            var          copy    = new UniqueId[ids.Length];
            UniqueIdSet  uids;

            Assert.IsTrue(UniqueIdSet.TryParse(example, 20160117, out uids), "Failed to parse uids.");
            Assert.AreEqual(SortOrder.Descending, uids.SortOrder);
            Assert.AreEqual(20160117, uids.Validity);
            Assert.AreEqual(example, uids.ToString());
            Assert.AreEqual(ids.Length, uids.Count);

            for (int i = 0; i < uids.Count; i++)
            {
                Assert.AreEqual(20160117, uids[i].Validity);
                Assert.AreEqual(ids[i], uids[i].Id);
            }

            uids.CopyTo(copy, 0);

            for (int i = 0; i < copy.Length; i++)
            {
                Assert.AreEqual(20160117, copy[i].Validity);
                Assert.AreEqual(ids[i], copy[i].Id);
            }
        }
Example #3
0
        public void TestEnumerator()
        {
            var          ids     = new uint[] { 20, 19, 15, 12, 11, 10, 9, 6, 5, 3, 2, 1 };
            const string example = "20:19,15,12:9,6:5,3:1";
            UniqueIdSet  uids;

            Assert.IsTrue(UniqueIdSet.TryParse(example, 20160117, out uids), "Failed to parse uids.");
            Assert.AreEqual(SortOrder.Descending, uids.SortOrder);
            Assert.AreEqual(20160117, uids.Validity);
            Assert.AreEqual(example, uids.ToString());
            Assert.AreEqual(ids.Length, uids.Count);

            for (int i = 0; i < uids.Count; i++)
            {
                Assert.AreEqual(ids[i], uids[i].Id);
            }

            var list = new List <UniqueId> ();

            foreach (var uid in uids)
            {
                Assert.AreEqual(20160117, uid.Validity);
                list.Add(uid);
            }

            for (int i = 0; i < list.Count; i++)
            {
                Assert.AreEqual(ids[i], list[i].Id);
            }
        }
Example #4
0
        public void TestReversedUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(20), new UniqueId(19), new UniqueId(15),
                new UniqueId(12), new UniqueId(11), new UniqueId(10),
                new UniqueId(9),  new UniqueId(6),  new UniqueId(5),
                new UniqueId(3),  new UniqueId(2),  new UniqueId(1)
            };
            var list   = new UniqueIdSet(uids);
            var actual = list.ToString();

            Assert.AreEqual("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for unsorted set.");

            list   = new UniqueIdSet(uids, SortOrder.Ascending);
            actual = list.ToString();

            Assert.AreEqual("1:3,5:6,9:12,15,19:20", actual, "Unexpected result for ascending set.");
            Assert.AreEqual(0, list.IndexOf(new UniqueId(1)), "Unexpected index for descending set.");

            list   = new UniqueIdSet(uids, SortOrder.Descending);
            actual = list.ToString();

            Assert.AreEqual("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for descending set.");
            Assert.AreEqual(11, list.IndexOf(new UniqueId(1)), "Unexpected index for descending set.");
        }
Example #5
0
		/// <summary>
		/// Initializes a new instance of the <see cref="T:MailKit.Search.UidSearchQuery"/> class.
		/// </summary>
		/// <remarks>
		/// Creates a new unique identifier-based search query.
		/// </remarks>
		/// <param name="uid">The unique identifier to match against.</param>
		/// <exception cref="System.ArgumentException">
		/// <paramref name="uid"/> is an invalid unique identifier.
		/// </exception>
		public UidSearchQuery (UniqueId uid) : base (SearchTerm.Uid)
		{
			if (!uid.IsValid)
				throw new ArgumentException ("Cannot search for an invalid unique identifier.", nameof (uid));

			Uids = new UniqueIdSet (SortOrder.Ascending);
			Uids.Add (uid);
		}
        public void TestParsingSimple()
        {
            const string example = "1:3,5:6,9:12,15,19:20";
            UniqueIdSet  uids;

            Assert.IsTrue(UniqueIdSet.TryParse(example, out uids), "Failed to parse uids.");
            Assert.AreEqual(example, uids.ToString());
        }
        public void TestParsingInvalidInputs()
        {
            UniqueIdSet uids;

            Assert.IsFalse(UniqueIdSet.TryParse("xyz", out uids));
            Assert.IsFalse(UniqueIdSet.TryParse("1:x", out uids));
            Assert.IsFalse(UniqueIdSet.TryParse("1:1x", out uids));
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:MailKit.Search.UidSearchQuery"/> class.
        /// </summary>
        /// <remarks>
        /// Creates a new unique identifier-based search query.
        /// </remarks>
        /// <param name="uid">The unique identifier to match against.</param>
        /// <exception cref="System.ArgumentException">
        /// <paramref name="uid"/> is an invalid unique identifier.
        /// </exception>
        public UidSearchQuery(UniqueId uid) : base(SearchTerm.Uid)
        {
            if (!uid.IsValid)
            {
                throw new ArgumentException("Cannot search for an invalid unique identifier.", nameof(uid));
            }

            Uids = new UniqueIdSet(SortOrder.Ascending);
            Uids.Add(uid);
        }
Example #9
0
        public void TestNonSequentialUniqueIdSet()
        {
            UniqueId[] uids = {
                new UniqueId (1), new UniqueId (3), new UniqueId (5),
                new UniqueId (7), new UniqueId (9)
            };
            var list = new UniqueIdSet (uids);
            var actual = list.ToString ();

            Assert.AreEqual ("1,3,5,7,9", actual);
        }
Example #10
0
        public void TestNonSequentialUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(1), new UniqueId(3), new UniqueId(5),
                new UniqueId(7), new UniqueId(9)
            };
            var list   = new UniqueIdSet(uids);
            var actual = list.ToString();

            Assert.AreEqual("1,3,5,7,9", actual);
        }
Example #11
0
        public void TestReversedUniqueIdSet()
        {
            UniqueId[] uids = {
                new UniqueId (20), new UniqueId (19), new UniqueId (15),
                new UniqueId (12), new UniqueId (11), new UniqueId (10),
                new UniqueId (9), new UniqueId (6), new UniqueId (5),
                new UniqueId (3), new UniqueId (2), new UniqueId (1)
            };
            var list = new UniqueIdSet (uids);
            var actual = list.ToString ();

            Assert.AreEqual ("1:3,5:6,9:12,15,19:20", actual);
        }
        public void TestMergingRangesDescending()
        {
            UniqueId[] uids =
            {
                new UniqueId(1), new UniqueId(2),  new UniqueId(3),
                new UniqueId(5), new UniqueId(6),  new UniqueId(7),
                new UniqueId(9), new UniqueId(10), new UniqueId(11),
                new UniqueId(4)
            };
            var list   = new UniqueIdSet(uids, SortOrder.Descending);
            var actual = list.ToString();

            Assert.AreEqual("11:9,7:1", actual, "Unexpected result for sorted set.");
        }
Example #13
0
        public void TestComplexUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(1),  new UniqueId(2),  new UniqueId(3),
                new UniqueId(5),  new UniqueId(6),  new UniqueId(9),
                new UniqueId(10), new UniqueId(11), new UniqueId(12),
                new UniqueId(15), new UniqueId(19), new UniqueId(20)
            };
            var list   = new UniqueIdSet(uids);
            var actual = list.ToString();

            Assert.AreEqual("1:3,5:6,9:12,15,19:20", actual);
        }
        public void TestContainsDescending()
        {
            var uids = new UniqueIdSet(SortOrder.Descending);

            Assert.IsFalse(uids.Contains(new UniqueId(5)), "5");

            uids.Add(new UniqueId(2));
            uids.Add(new UniqueId(3));

            Assert.IsFalse(uids.Contains(new UniqueId(1)), "1");
            Assert.IsTrue(uids.Contains(new UniqueId(2)), "2");
            Assert.IsTrue(uids.Contains(new UniqueId(3)), "3");
            Assert.IsFalse(uids.Contains(new UniqueId(4)), "4");
        }
Example #15
0
        public void TestParsingReversedSet()
        {
            var          ids     = new uint[] { 20, 19, 15, 12, 11, 10, 9, 6, 5, 3, 2, 1 };
            const string example = "20:19,15,12:9,6:5,3:1";
            UniqueIdSet  uids;

            Assert.IsTrue(UniqueIdSet.TryParse(example, out uids), "Failed to parse uids.");
            Assert.AreEqual(example, uids.ToString());
            Assert.AreEqual(ids.Length, uids.Count);

            for (int i = 0; i < uids.Count; i++)
            {
                Assert.AreEqual(ids[i], uids[i].Id);
            }
        }
Example #16
0
 static void ProcessUnmodified(ImapCommand ic, ref UniqueIdSet uids, ulong?modseq)
 {
     if (modseq.HasValue)
     {
         foreach (var rc in ic.RespCodes.OfType <ModifiedResponseCode> ())
         {
             if (uids != null)
             {
                 uids.AddRange(rc.UidSet);
             }
             else
             {
                 uids = rc.UidSet;
             }
         }
     }
 }
Example #17
0
        public void TestReversedUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(20), new UniqueId(19), new UniqueId(15),
                new UniqueId(12), new UniqueId(11), new UniqueId(10),
                new UniqueId(9),  new UniqueId(6),  new UniqueId(5),
                new UniqueId(3),  new UniqueId(2),  new UniqueId(1)
            };
            var list   = new UniqueIdSet(uids, false);
            var actual = list.ToString();

            Assert.AreEqual("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for unsorted set.");

            list   = new UniqueIdSet(uids, true);
            actual = list.ToString();

            Assert.AreEqual("1:3,5:6,9:12,15,19:20", actual, "Unexpected result for sorted set.");
        }
        public void TestNonSequentialUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(1), new UniqueId(3), new UniqueId(5),
                new UniqueId(7), new UniqueId(9)
            };
            var list   = new UniqueIdSet(uids);
            var actual = list.ToString();

            Assert.AreEqual("1,3,5,7,9", actual);

            list   = new UniqueIdSet(uids, SortOrder.Ascending);
            actual = list.ToString();

            Assert.AreEqual("1,3,5,7,9", actual, "Unexpected result for ascending set.");

            list   = new UniqueIdSet(uids, SortOrder.Descending);
            actual = list.ToString();

            Assert.AreEqual("9,7,5,3,1", actual, "Unexpected result for descending set.");
        }
Example #19
0
		public void TestArgumentExceptions ()
		{
			var uids = new UniqueIdSet (SortOrder.Ascending);
			UniqueId uid;

			uids.Add (UniqueId.MinValue);

			Assert.Throws<ArgumentException> (() => uids.Add (UniqueId.Invalid));
			Assert.Throws<ArgumentNullException> (() => uids.AddRange (null));
			Assert.Throws<ArgumentNullException> (() => uids.CopyTo (null, 0));
			Assert.Throws<ArgumentOutOfRangeException> (() => uids.CopyTo (new UniqueId[1], -1));
			Assert.Throws<ArgumentOutOfRangeException> (() => uids.RemoveAt (-1));
			Assert.Throws<ArgumentOutOfRangeException> (() => uid = uids[-1]);
			Assert.Throws<NotSupportedException> (() => uids[0] = UniqueId.MinValue);
			Assert.Throws<NotSupportedException> (() => uids.Insert (0, UniqueId.MinValue));

			var list = new List<UniqueId> { UniqueId.Invalid };
			Assert.Throws<ArgumentNullException> (() => UniqueIdSet.ToString (null));
			Assert.Throws<ArgumentException> (() => UniqueIdSet.ToString (list));

			Assert.Throws<ArgumentNullException> (() => UniqueIdSet.TryParse (null, out uids));
		}
        public void TestUnsortedUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(1), new UniqueId(2), new UniqueId(3),
                new UniqueId(4), new UniqueId(5), new UniqueId(6),
                new UniqueId(7), new UniqueId(8), new UniqueId(9)
            };
            var list   = new UniqueIdSet(uids);
            var actual = list.ToString();

            Assert.AreEqual("1:9", actual, "Incorrect initial value.");
            Assert.AreEqual(9, list.Count, "Incorrect initial count.");

            // Test Remove()

            list.Remove(uids[0]);
            actual = list.ToString();

            Assert.AreEqual("2:9", actual, "Incorrect results after Remove() #1.");
            Assert.AreEqual(8, list.Count, "Incorrect count after Remove() #1.");

            list.Remove(uids[uids.Length - 1]);
            actual = list.ToString();

            Assert.AreEqual("2:8", actual, "Incorrect results after Remove() #2.");
            Assert.AreEqual(7, list.Count, "Incorrect count after Remove() #2.");

            list.Remove(uids[4]);
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8", actual, "Incorrect results after Remove() #3.");
            Assert.AreEqual(6, list.Count, "Incorrect count after Remove() #3.");

            // Test Add()

            list.Add(new UniqueId(5));
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8,5", actual, "Incorrect results after Add() #1.");
            Assert.AreEqual(7, list.Count, "Incorrect count after Add() #1.");

            list.Add(new UniqueId(1));
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8,5,1", actual, "Incorrect results after Add() #2.");
            Assert.AreEqual(8, list.Count, "Incorrect count after Add() #2.");

            list.Add(new UniqueId(9));
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8,5,1,9", actual, "Incorrect results after Add() #3.");
            Assert.AreEqual(9, list.Count, "Incorrect count after Add() #3.");

            // Test RemoveAt()

            list.RemoveAt(0);
            actual = list.ToString();

            Assert.AreEqual("3:4,6:8,5,1,9", actual, "Incorrect results after RemoveAt() #1.");
            Assert.AreEqual(8, list.Count, "Incorrect count after RemoveAt() #1.");

            list.RemoveAt(7);
            actual = list.ToString();

            Assert.AreEqual("3:4,6:8,5,1", actual, "Incorrect results after RemoveAt() #2.");
            Assert.AreEqual(7, list.Count, "Incorrect count after RemoveAt() #2.");

            list.RemoveAt(3);
            actual = list.ToString();

            Assert.AreEqual("3:4,6,8,5,1", actual, "Incorrect results after RemoveAt() #3.");
            Assert.AreEqual(6, list.Count, "Incorrect count after RemoveAt() #3.");

            // Test adding a range of items

            list.AddRange(uids);
            actual = list.ToString();

            Assert.AreEqual("3:4,6,8,5,1:2,7,9", actual, "Incorrect results after AddRange().");
            Assert.AreEqual(9, list.Count, "Incorrect count after AddRange().");

            // Test clearing the list
            list.Clear();
            Assert.AreEqual(0, list.Count, "Incorrect count after Clear().");
        }
Example #21
0
		public async void TestImapClientDovecot ()
		{
			var expectedFlags = MessageFlags.Answered | MessageFlags.Flagged | MessageFlags.Deleted | MessageFlags.Seen | MessageFlags.Draft;
			var expectedPermanentFlags = expectedFlags | MessageFlags.UserDefined;

			var commands = new List<ImapReplayCommand> ();
			commands.Add (new ImapReplayCommand ("", "dovecot.greeting.txt"));
			commands.Add (new ImapReplayCommand ("A00000000 LOGIN username password\r\n", "dovecot.authenticate.txt"));
			commands.Add (new ImapReplayCommand ("A00000001 NAMESPACE\r\n", "dovecot.namespace.txt"));
			commands.Add (new ImapReplayCommand ("A00000002 LIST \"\" \"INBOX\"\r\n", "dovecot.list-inbox.txt"));
			commands.Add (new ImapReplayCommand ("A00000003 LIST (SPECIAL-USE) \"\" \"*\"\r\n", "dovecot.list-special-use.txt"));
			commands.Add (new ImapReplayCommand ("A00000004 ENABLE QRESYNC CONDSTORE\r\n", "dovecot.enable-qresync.txt"));
			commands.Add (new ImapReplayCommand ("A00000005 LIST \"\" \"%\" RETURN (SUBSCRIBED CHILDREN STATUS (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN HIGHESTMODSEQ))\r\n", "dovecot.list-personal.txt"));
			commands.Add (new ImapReplayCommand ("A00000006 CREATE UnitTests.\r\n", ImapReplayCommandResponse.OK));
			commands.Add (new ImapReplayCommand ("A00000007 LIST \"\" UnitTests\r\n", "dovecot.list-unittests.txt"));
			commands.Add (new ImapReplayCommand ("A00000008 CREATE UnitTests.Messages\r\n", ImapReplayCommandResponse.OK));
			commands.Add (new ImapReplayCommand ("A00000009 LIST \"\" UnitTests.Messages\r\n", "dovecot.list-unittests-messages.txt"));

			var command = new StringBuilder ("A00000010 APPEND UnitTests.Messages");
			var internalDates = new List<DateTimeOffset> ();
			var messages = new List<MimeMessage> ();
			var flags = new List<MessageFlags> ();
			var now = DateTimeOffset.Now;

			messages.Add (CreateThreadableMessage ("A", "<*****@*****.**>", null, now.AddMinutes (-7)));
			messages.Add (CreateThreadableMessage ("B", "<*****@*****.**>", "<*****@*****.**>", now.AddMinutes (-6)));
			messages.Add (CreateThreadableMessage ("C", "<*****@*****.**>", "<*****@*****.**> <*****@*****.**>", now.AddMinutes (-5)));
			messages.Add (CreateThreadableMessage ("D", "<*****@*****.**>", "<*****@*****.**>", now.AddMinutes (-4)));
			messages.Add (CreateThreadableMessage ("E", "<*****@*****.**>", "<*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**>", now.AddMinutes (-3)));
			messages.Add (CreateThreadableMessage ("F", "<*****@*****.**>", "<*****@*****.**>", now.AddMinutes (-2)));
			messages.Add (CreateThreadableMessage ("G", "<*****@*****.**>", null, now.AddMinutes (-1)));
			messages.Add (CreateThreadableMessage ("H", "<*****@*****.**>", null, now));

			for (int i = 0; i < messages.Count; i++) {
				var message = messages[i];
				string latin1;
				long length;

				internalDates.Add (messages[i].Date);
				flags.Add (MessageFlags.Draft);

				using (var stream = new MemoryStream ()) {
					var options = FormatOptions.Default.Clone ();
					options.NewLineFormat = NewLineFormat.Dos;

					message.WriteTo (options, stream);
					length = stream.Length;
					stream.Position = 0;

					using (var reader = new StreamReader (stream, Latin1))
						latin1 = reader.ReadToEnd ();
				}

				command.AppendFormat (" (\\Draft) \"{0}\" ", ImapUtils.FormatInternalDate (message.Date));
				command.Append ('{');
				command.AppendFormat ("{0}+", length);
				command.Append ("}\r\n");
				command.Append (latin1);
			}
			command.Append ("\r\n");
			commands.Add (new ImapReplayCommand (command.ToString (), "dovecot.multiappend.txt"));
			commands.Add (new ImapReplayCommand ("A00000011 SELECT UnitTests.Messages (CONDSTORE)\r\n", "dovecot.select-unittests-messages.txt"));
			commands.Add (new ImapReplayCommand ("A00000012 UID STORE 1:8 +FLAGS.SILENT (\\Seen)\r\n", "dovecot.store-seen.txt"));
			commands.Add (new ImapReplayCommand ("A00000013 UID STORE 1:3 +FLAGS.SILENT (\\Answered)\r\n", "dovecot.store-answered.txt"));
			commands.Add (new ImapReplayCommand ("A00000014 UID STORE 8 +FLAGS.SILENT (\\Deleted)\r\n", "dovecot.store-deleted.txt"));
			commands.Add (new ImapReplayCommand ("A00000015 UID EXPUNGE 8\r\n", "dovecot.uid-expunge.txt"));
			commands.Add (new ImapReplayCommand ("A00000016 UID THREAD REFERENCES US-ASCII ALL\r\n", "dovecot.thread-references.txt"));
			commands.Add (new ImapReplayCommand ("A00000017 UID THREAD ORDEREDSUBJECT US-ASCII UID 1:* ALL\r\n", "dovecot.thread-orderedsubject.txt"));
			commands.Add (new ImapReplayCommand ("A00000018 UNSELECT\r\n", ImapReplayCommandResponse.OK));
			commands.Add (new ImapReplayCommand ("A00000019 SELECT UnitTests.Messages (QRESYNC (1436832084 2 1:8))\r\n", "dovecot.select-unittests-messages-qresync.txt"));
			commands.Add (new ImapReplayCommand ("A00000020 UID SEARCH RETURN (ALL COUNT MIN MAX) MODSEQ 2\r\n", "dovecot.search-changed-since.txt"));
			commands.Add (new ImapReplayCommand ("A00000021 UID FETCH 1:7 (UID FLAGS MODSEQ)\r\n", "dovecot.fetch1.txt"));
			commands.Add (new ImapReplayCommand ("A00000022 UID FETCH 1:* (UID FLAGS MODSEQ) (CHANGEDSINCE 2 VANISHED)\r\n", "dovecot.fetch2.txt"));
			commands.Add (new ImapReplayCommand ("A00000023 UID SORT RETURN (ALL COUNT MIN MAX) (REVERSE ARRIVAL) US-ASCII ALL\r\n", "dovecot.sort-reverse-arrival.txt"));
			commands.Add (new ImapReplayCommand ("A00000024 UID SEARCH RETURN () UNDELETED SEEN\r\n", "dovecot.optimized-search.txt"));
			commands.Add (new ImapReplayCommand ("A00000025 CREATE UnitTests.Destination\r\n", ImapReplayCommandResponse.OK));
			commands.Add (new ImapReplayCommand ("A00000026 LIST \"\" UnitTests.Destination\r\n", "dovecot.list-unittests-destination.txt"));
			commands.Add (new ImapReplayCommand ("A00000027 UID COPY 1:7 UnitTests.Destination\r\n", "dovecot.copy.txt"));
			commands.Add (new ImapReplayCommand ("A00000028 UID MOVE 1:7 UnitTests.Destination\r\n", "dovecot.move.txt"));
			commands.Add (new ImapReplayCommand ("A00000029 STATUS UnitTests.Destination (MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN HIGHESTMODSEQ)\r\n", "dovecot.status-unittests-destination.txt"));
			commands.Add (new ImapReplayCommand ("A00000030 SELECT UnitTests.Destination (CONDSTORE)\r\n", "dovecot.select-unittests-destination.txt"));
			commands.Add (new ImapReplayCommand ("A00000031 UID FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)]) (CHANGEDSINCE 1 VANISHED)\r\n", "dovecot.fetch3.txt"));
			commands.Add (new ImapReplayCommand ("A00000032 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)]) (CHANGEDSINCE 1)\r\n", "dovecot.fetch4.txt"));
			commands.Add (new ImapReplayCommand ("A00000033 FETCH 1:14 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)]) (CHANGEDSINCE 1)\r\n", "dovecot.fetch5.txt"));
			commands.Add (new ImapReplayCommand ("A00000034 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES)]) (CHANGEDSINCE 1)\r\n", "dovecot.fetch6.txt"));
			commands.Add (new ImapReplayCommand ("A00000035 FETCH 1:14 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES)]) (CHANGEDSINCE 1)\r\n", "dovecot.fetch7.txt"));
			commands.Add (new ImapReplayCommand ("A00000036 UID FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)])\r\n", "dovecot.fetch8.txt"));
			commands.Add (new ImapReplayCommand ("A00000037 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)])\r\n", "dovecot.fetch9.txt"));
			commands.Add (new ImapReplayCommand ("A00000038 FETCH 1:14 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES X-MAILER)])\r\n", "dovecot.fetch10.txt"));
			commands.Add (new ImapReplayCommand ("A00000039 FETCH 1:* (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES)])\r\n", "dovecot.fetch11.txt"));
			commands.Add (new ImapReplayCommand ("A00000040 FETCH 1:14 (UID FLAGS INTERNALDATE RFC822.SIZE ENVELOPE BODYSTRUCTURE MODSEQ BODY.PEEK[HEADER.FIELDS (REFERENCES)])\r\n", "dovecot.fetch12.txt"));
			commands.Add (new ImapReplayCommand ("A00000041 UID FETCH 1 (BODY.PEEK[HEADER] BODY.PEEK[TEXT])\r\n", "dovecot.getbodypart.txt"));
			commands.Add (new ImapReplayCommand ("A00000042 FETCH 1 (BODY.PEEK[HEADER] BODY.PEEK[TEXT])\r\n", "dovecot.getbodypart2.txt"));
			commands.Add (new ImapReplayCommand ("A00000043 UID FETCH 1 (BODY.PEEK[]<128.64>)\r\n", "dovecot.getstream.txt"));
			commands.Add (new ImapReplayCommand ("A00000044 UID FETCH 1 (BODY.PEEK[]<128.64>)\r\n", "dovecot.getstream2.txt"));
			commands.Add (new ImapReplayCommand ("A00000045 FETCH 1 (BODY.PEEK[]<128.64>)\r\n", "dovecot.getstream3.txt"));
			commands.Add (new ImapReplayCommand ("A00000046 FETCH 1 (BODY.PEEK[]<128.64>)\r\n", "dovecot.getstream4.txt"));
			commands.Add (new ImapReplayCommand ("A00000047 UID FETCH 1 (BODY.PEEK[HEADER.FIELDS (MIME-VERSION CONTENT-TYPE)])\r\n", "dovecot.getstream-section.txt"));
			commands.Add (new ImapReplayCommand ("A00000048 FETCH 1 (BODY.PEEK[HEADER.FIELDS (MIME-VERSION CONTENT-TYPE)])\r\n", "dovecot.getstream-section2.txt"));
			commands.Add (new ImapReplayCommand ("A00000049 UID STORE 1:14 (UNCHANGEDSINCE 3) +FLAGS.SILENT (\\Deleted $MailKit)\r\n", "dovecot.store-deleted-custom.txt"));
			commands.Add (new ImapReplayCommand ("A00000050 STORE 1:7 (UNCHANGEDSINCE 5) FLAGS.SILENT (\\Deleted \\Seen $MailKit)\r\n", "dovecot.setflags-unchangedsince.txt"));
			commands.Add (new ImapReplayCommand ("A00000051 UID SEARCH RETURN () UID 1:14 OR ANSWERED OR DELETED OR DRAFT OR FLAGGED OR RECENT OR UNANSWERED OR UNDELETED OR UNDRAFT OR UNFLAGGED OR UNSEEN OR KEYWORD $MailKit UNKEYWORD $MailKit\r\n", "dovecot.search-uids.txt"));
			commands.Add (new ImapReplayCommand ("A00000052 UID SEARCH RETURN (ALL COUNT MIN MAX) UID 1:14 LARGER 256 SMALLER 512\r\n", "dovecot.search-uids-options.txt"));
			commands.Add (new ImapReplayCommand ("A00000053 UID SORT RETURN () (REVERSE DATE SUBJECT DISPLAYFROM SIZE) US-ASCII OR OR (SENTBEFORE 12-Oct-2016 SENTSINCE 10-Oct-2016) NOT SENTON 11-Oct-2016 OR (BEFORE 12-Oct-2016 SINCE 10-Oct-2016) NOT ON 11-Oct-2016\r\n", "dovecot.sort-by-date.txt"));
			commands.Add (new ImapReplayCommand ("A00000054 UID SORT RETURN () (FROM TO CC) US-ASCII UID 1:14 OR BCC xyz OR CC xyz OR FROM xyz OR TO xyz OR SUBJECT xyz OR HEADER Message-Id mimekit.net OR BODY \"This is the message body.\" TEXT message\r\n", "dovecot.sort-by-strings.txt"));
			commands.Add (new ImapReplayCommand ("A00000055 UID SORT RETURN (ALL COUNT MIN MAX) (DISPLAYTO) US-ASCII UID 1:14 OLDER 1 YOUNGER 3600\r\n", "dovecot.sort-uids-options.txt"));
			commands.Add (new ImapReplayCommand ("A00000056 UID SEARCH ALL\r\n", "dovecot.search-raw.txt"));
			commands.Add (new ImapReplayCommand ("A00000057 UID SORT (REVERSE ARRIVAL) US-ASCII ALL\r\n", "dovecot.sort-raw.txt"));
			commands.Add (new ImapReplayCommand ("A00000058 EXPUNGE\r\n", "dovecot.expunge.txt"));
			commands.Add (new ImapReplayCommand ("A00000059 CLOSE\r\n", ImapReplayCommandResponse.OK));

			using (var client = new ImapClient ()) {
				try {
					client.ReplayConnect ("localhost", new ImapReplayStream (commands, false));
				} catch (Exception ex) {
					Assert.Fail ("Did not expect an exception in Connect: {0}", ex);
				}

				Assert.IsTrue (client.IsConnected, "Client failed to connect.");

				Assert.AreEqual (DovecotInitialCapabilities, client.Capabilities);
				Assert.AreEqual (4, client.AuthenticationMechanisms.Count);
				Assert.IsTrue (client.AuthenticationMechanisms.Contains ("PLAIN"), "Expected SASL PLAIN auth mechanism");
				Assert.IsTrue (client.AuthenticationMechanisms.Contains ("DIGEST-MD5"), "Expected SASL DIGEST-MD5 auth mechanism");
				Assert.IsTrue (client.AuthenticationMechanisms.Contains ("CRAM-MD5"), "Expected SASL CRAM-MD5 auth mechanism");
				Assert.IsTrue (client.AuthenticationMechanisms.Contains ("NTLM"), "Expected SASL NTLM auth mechanism");

				// Note: we do not want to use SASL at all...
				client.AuthenticationMechanisms.Clear ();

				try {
					await client.AuthenticateAsync ("username", "password");
				} catch (Exception ex) {
					Assert.Fail ("Did not expect an exception in Authenticate: {0}", ex);
				}

				Assert.AreEqual (DovecotAuthenticatedCapabilities, client.Capabilities);
				Assert.AreEqual (1, client.InternationalizationLevel, "Expected I18NLEVEL=1");
				Assert.IsTrue (client.ThreadingAlgorithms.Contains (ThreadingAlgorithm.OrderedSubject), "Expected THREAD=ORDEREDSUBJECT");
				Assert.IsTrue (client.ThreadingAlgorithms.Contains (ThreadingAlgorithm.References), "Expected THREAD=REFERENCES");
				// TODO: verify CONTEXT=SEARCH

				var personal = client.GetFolder (client.PersonalNamespaces[0]);

				// Make sure these all throw NotSupportedException
				Assert.Throws<NotSupportedException> (() => client.EnableUTF8 ());
				Assert.Throws<NotSupportedException> (() => client.Inbox.GetAccessRights ("smith"));
				Assert.Throws<NotSupportedException> (() => client.Inbox.GetMyAccessRights ());
				var rights = new AccessRights ("lrswida");
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddAccessRights ("smith", rights));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveAccessRights ("smith", rights));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetAccessRights ("smith", rights));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveAccess ("smith"));
				Assert.Throws<NotSupportedException> (() => client.Inbox.GetQuota ());
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetQuota (null, null));
				Assert.Throws<NotSupportedException> (() => client.GetMetadata (MetadataTag.PrivateComment));
				Assert.Throws<NotSupportedException> (() => client.GetMetadata (new MetadataTag[] { MetadataTag.PrivateComment }));
				Assert.Throws<NotSupportedException> (() => client.SetMetadata (new MetadataCollection ()));
				var labels = new string[] { "Label1", "Label2" };
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (UniqueId.MinValue, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (UniqueIdRange.All, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (UniqueIdRange.All, 1, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (0, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (new int[] { 0 }, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.AddLabels (new int[] { 0 }, 1, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (UniqueId.MinValue, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (UniqueIdRange.All, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (UniqueIdRange.All, 1, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (0, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (new int[] { 0 }, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.RemoveLabels (new int[] { 0 }, 1, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (UniqueId.MinValue, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (UniqueIdRange.All, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (UniqueIdRange.All, 1, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (0, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (new int[] { 0 }, labels, true));
				Assert.Throws<NotSupportedException> (() => client.Inbox.SetLabels (new int[] { 0 }, 1, labels, true));

				try {
					await client.EnableQuickResyncAsync ();
				} catch (Exception ex) {
					Assert.Fail ("Did not expect an exception when enabling QRESYNC: {0}", ex);
				}

				// take advantage of LIST-STATUS to get top-level personal folders...
				var statusItems = StatusItems.Count | StatusItems.HighestModSeq | StatusItems.Recent | StatusItems.UidNext | StatusItems.UidValidity | StatusItems.Unread;

				var folders = (await personal.GetSubfoldersAsync (statusItems, false)).ToArray ();
				Assert.AreEqual (6, folders.Length, "Expected 6 folders");

				var expectedFolderNames = new [] { "Archives", "Drafts", "Junk", "Sent Messages", "Trash", "INBOX" };
				var expectedUidValidities = new [] { 1436832059, 1436832060, 1436832061, 1436832062, 1436832063, 1436832057 };
				var expectedHighestModSeq = new [] { 1, 1, 1, 1, 1, 15 };
				var expectedMessages = new [] { 0, 0, 0, 0, 0, 4 };
				var expectedUidNext = new [] { 1, 1, 1, 1, 1, 5 };
				var expectedRecent = new [] { 0, 0, 0, 0, 0, 0 };
				var expectedUnseen = new [] { 0, 0, 0, 0, 0, 0 };

				for (int i = 0; i < folders.Length; i++) {
					Assert.AreEqual (expectedFolderNames[i], folders[i].FullName, "FullName did not match");
					Assert.AreEqual (expectedFolderNames[i], folders[i].Name, "Name did not match");
					Assert.AreEqual (expectedUidValidities[i], folders[i].UidValidity, "UidValidity did not match");
					Assert.AreEqual (expectedHighestModSeq[i], folders[i].HighestModSeq, "HighestModSeq did not match");
					Assert.AreEqual (expectedMessages[i], folders[i].Count, "Count did not match");
					Assert.AreEqual (expectedRecent[i], folders[i].Recent, "Recent did not match");
					Assert.AreEqual (expectedUnseen[i], folders[i].Unread, "Unread did not match");
				}

				var unitTests = await personal.CreateAsync ("UnitTests", false);
				Assert.AreEqual (FolderAttributes.HasNoChildren, unitTests.Attributes, "Unexpected UnitTests folder attributes");

				var folder = await unitTests.CreateAsync ("Messages", true);
				Assert.AreEqual (FolderAttributes.HasNoChildren, folder.Attributes, "Unexpected UnitTests.Messages folder attributes");
				//Assert.AreEqual (FolderAttributes.HasChildren, unitTests.Attributes, "Expected UnitTests Attributes to be updated");

				// Use MULTIAPPEND to append some test messages
				var appended = await folder.AppendAsync (messages, flags, internalDates);
				Assert.AreEqual (8, appended.Count, "Unexpected number of messages appended");

				// SELECT the folder so that we can test some stuff
				var access = await folder.OpenAsync (FolderAccess.ReadWrite);
				Assert.AreEqual (expectedPermanentFlags, folder.PermanentFlags, "UnitTests.Messages PERMANENTFLAGS");
				Assert.AreEqual (expectedFlags, folder.AcceptedFlags, "UnitTests.Messages FLAGS");
				Assert.AreEqual (8, folder.Count, "UnitTests.Messages EXISTS");
				Assert.AreEqual (8, folder.Recent, "UnitTests.Messages RECENT");
				Assert.AreEqual (0, folder.FirstUnread, "UnitTests.Messages UNSEEN");
				Assert.AreEqual (1436832084U, folder.UidValidity, "UnitTests.Messages UIDVALIDITY");
				Assert.AreEqual (9, folder.UidNext.Value.Id, "UnitTests.Messages UIDNEXT");
				Assert.AreEqual (2UL, folder.HighestModSeq, "UnitTests.Messages HIGHESTMODSEQ");
				Assert.AreEqual (FolderAccess.ReadWrite, access, "Expected UnitTests.Messages to be opened in READ-WRITE mode");

				// Keep track of various folder events
				var flagsChanged = new List<MessageFlagsChangedEventArgs> ();
				var modSeqChanged = new List<ModSeqChangedEventArgs> ();
				var vanished = new List<MessagesVanishedEventArgs> ();
				bool recentChanged = false;

				folder.MessageFlagsChanged += (sender, e) => {
					flagsChanged.Add (e);
				};

				folder.ModSeqChanged += (sender, e) => {
					modSeqChanged.Add (e);
				};

				folder.MessagesVanished += (sender, e) => {
					vanished.Add (e);
				};

				folder.RecentChanged += (sender, e) => {
					recentChanged = true;
				};

				// Keep track of UIDVALIDITY and HIGHESTMODSEQ values for our QRESYNC test later
				var highestModSeq = folder.HighestModSeq;
				var uidValidity = folder.UidValidity;

				// Make some FLAGS changes to our messages so we can test QRESYNC
				await folder.AddFlagsAsync (appended, MessageFlags.Seen, true);
				Assert.AreEqual (0, flagsChanged.Count, "Unexpected number of FlagsChanged events");
				Assert.AreEqual (8, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				for (int i = 0; i < modSeqChanged.Count; i++) {
					Assert.AreEqual (i, modSeqChanged[i].Index, "Unexpected modSeqChanged[{0}].Index", i);
					Assert.AreEqual (i + 1, modSeqChanged[i].UniqueId.Value.Id, "Unexpected modSeqChanged[{0}].UniqueId", i);
					Assert.AreEqual (3, modSeqChanged[i].ModSeq, "Unexpected modSeqChanged[{0}].ModSeq", i);
				}
				Assert.IsFalse (recentChanged, "Unexpected RecentChanged event");
				modSeqChanged.Clear ();
				flagsChanged.Clear ();

				var answered = new UniqueIdSet (SortOrder.Ascending);
				answered.Add (appended[0]); // A
				answered.Add (appended[1]); // B
				answered.Add (appended[2]); // C
				await folder.AddFlagsAsync (answered, MessageFlags.Answered, true);
				Assert.AreEqual (0, flagsChanged.Count, "Unexpected number of FlagsChanged events");
				Assert.AreEqual (3, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				for (int i = 0; i < modSeqChanged.Count; i++) {
					Assert.AreEqual (i, modSeqChanged[i].Index, "Unexpected modSeqChanged[{0}].Index", i);
					Assert.AreEqual (i + 1, modSeqChanged[i].UniqueId.Value.Id, "Unexpected modSeqChanged[{0}].UniqueId", i);
					Assert.AreEqual (4, modSeqChanged[i].ModSeq, "Unexpected modSeqChanged[{0}].ModSeq", i);
				}
				Assert.IsFalse (recentChanged, "Unexpected RecentChanged event");
				modSeqChanged.Clear ();
				flagsChanged.Clear ();

				// Delete some messages so we can test that QRESYNC emits some MessageVanished events
				// both now *and* when we use QRESYNC to re-open the folder
				var deleted = new UniqueIdSet (SortOrder.Ascending);
				deleted.Add (appended[7]); // H
				await folder.AddFlagsAsync (deleted, MessageFlags.Deleted, true);
				Assert.AreEqual (0, flagsChanged.Count, "Unexpected number of FlagsChanged events");
				Assert.AreEqual (1, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				Assert.AreEqual (7, modSeqChanged[0].Index, "Unexpected modSeqChanged[{0}].Index", 0);
				Assert.AreEqual (8, modSeqChanged[0].UniqueId.Value.Id, "Unexpected modSeqChanged[{0}].UniqueId", 0);
				Assert.AreEqual (5, modSeqChanged[0].ModSeq, "Unexpected modSeqChanged[{0}].ModSeq", 0);
				Assert.IsFalse (recentChanged, "Unexpected RecentChanged event");
				modSeqChanged.Clear ();
				flagsChanged.Clear ();

				await folder.ExpungeAsync (deleted);
				Assert.AreEqual (1, vanished.Count, "Expected MessagesVanished event");
				Assert.AreEqual (1, vanished[0].UniqueIds.Count, "Unexpected number of messages vanished");
				Assert.AreEqual (8, vanished[0].UniqueIds[0].Id, "Unexpected UID for vanished message");
				Assert.IsFalse (vanished[0].Earlier, "Expected EARLIER to be false");
				Assert.IsTrue (recentChanged, "Expected RecentChanged event");
				recentChanged = false;
				vanished.Clear ();

				// Verify that THREAD works correctly
				var threaded = await folder.ThreadAsync (ThreadingAlgorithm.References, SearchQuery.All);
				Assert.AreEqual (2, threaded.Count, "Unexpected number of root nodes in threaded results");

				threaded = await folder.ThreadAsync (UniqueIdRange.All, ThreadingAlgorithm.OrderedSubject, SearchQuery.All);
				Assert.AreEqual (7, threaded.Count, "Unexpected number of root nodes in threaded results");

				// UNSELECT the folder so we can re-open it using QRESYNC
				await folder.CloseAsync ();

				// Use QRESYNC to get the changes since last time we opened the folder
				access = await folder.OpenAsync (FolderAccess.ReadWrite, uidValidity, highestModSeq, appended);
				Assert.AreEqual (FolderAccess.ReadWrite, access, "Expected UnitTests.Messages to be opened in READ-WRITE mode");
				Assert.AreEqual (7, flagsChanged.Count, "Unexpected number of MessageFlagsChanged events");
				Assert.AreEqual (7, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				for (int i = 0; i < flagsChanged.Count; i++) {
					var messageFlags = MessageFlags.Seen | MessageFlags.Draft;

					if (i < 3)
						messageFlags |= MessageFlags.Answered;

					Assert.AreEqual (i, flagsChanged[i].Index, "Unexpected value for flagsChanged[{0}].Index", i);
					Assert.AreEqual ((uint) (i + 1), flagsChanged[i].UniqueId.Value.Id, "Unexpected value for flagsChanged[{0}].UniqueId", i);
					Assert.AreEqual (messageFlags, flagsChanged[i].Flags, "Unexpected value for flagsChanged[{0}].Flags", i);

					Assert.AreEqual (i, modSeqChanged[i].Index, "Unexpected value for modSeqChanged[{0}].Index", i);
					if (i < 3)
						Assert.AreEqual (4, modSeqChanged[i].ModSeq, "Unexpected value for modSeqChanged[{0}].ModSeq", i);
					else
						Assert.AreEqual (3, modSeqChanged[i].ModSeq, "Unexpected value for modSeqChanged[{0}].ModSeq", i);
				}
				modSeqChanged.Clear ();
				flagsChanged.Clear ();

				Assert.AreEqual (1, vanished.Count, "Unexpected number of MessagesVanished events");
				Assert.IsTrue (vanished[0].Earlier, "Expected VANISHED EARLIER");
				Assert.AreEqual (1, vanished[0].UniqueIds.Count, "Unexpected number of messages vanished");
				Assert.AreEqual (8, vanished[0].UniqueIds[0].Id, "Unexpected UID for vanished message");
				vanished.Clear ();

				// Use SEARCH and FETCH to get the same info
				var searchOptions = SearchOptions.All | SearchOptions.Count | SearchOptions.Min | SearchOptions.Max;
				var changed = await folder.SearchAsync (searchOptions, SearchQuery.ChangedSince (highestModSeq));
				Assert.AreEqual (7, changed.UniqueIds.Count, "Unexpected number of UIDs");
				Assert.IsTrue (changed.ModSeq.HasValue, "Expected the ModSeq property to be set");
				Assert.AreEqual (4, changed.ModSeq.Value, "Unexpected ModSeq value");
				Assert.AreEqual (1, changed.Min.Value.Id, "Unexpected Min");
				Assert.AreEqual (7, changed.Max.Value.Id, "Unexpected Max");
				Assert.AreEqual (7, changed.Count, "Unexpected Count");

				var fetched = await folder.FetchAsync (changed.UniqueIds, MessageSummaryItems.UniqueId | MessageSummaryItems.Flags | MessageSummaryItems.ModSeq);
				Assert.AreEqual (7, fetched.Count, "Unexpected number of messages fetched");
				for (int i = 0; i < fetched.Count; i++) {
					Assert.AreEqual (i, fetched[i].Index, "Unexpected Index");
					Assert.AreEqual (i + 1, fetched[i].UniqueId.Id, "Unexpected UniqueId");
				}

				// or... we could just use a single UID FETCH command like so:
				fetched = await folder.FetchAsync (UniqueIdRange.All, highestModSeq, MessageSummaryItems.UniqueId | MessageSummaryItems.Flags | MessageSummaryItems.ModSeq);
				for (int i = 0; i < fetched.Count; i++) {
					Assert.AreEqual (i, fetched[i].Index, "Unexpected Index");
					Assert.AreEqual (i + 1, fetched[i].UniqueId.Id, "Unexpected UniqueId");
				}
				Assert.AreEqual (7, fetched.Count, "Unexpected number of messages fetched");
				Assert.AreEqual (1, vanished.Count, "Unexpected number of MessagesVanished events");
				Assert.IsTrue (vanished[0].Earlier, "Expected VANISHED EARLIER");
				Assert.AreEqual (1, vanished[0].UniqueIds.Count, "Unexpected number of messages vanished");
				Assert.AreEqual (8, vanished[0].UniqueIds[0].Id, "Unexpected UID for vanished message");
				vanished.Clear ();

				// Use SORT to order by reverse arrival order
				var orderBy = new OrderBy[] { new OrderBy (OrderByType.Arrival, SortOrder.Descending) };
				var sorted = await folder.SearchAsync (searchOptions, SearchQuery.All, orderBy);
				Assert.AreEqual (7, sorted.UniqueIds.Count, "Unexpected number of UIDs");
				for (int i = 0; i < sorted.UniqueIds.Count; i++)
					Assert.AreEqual (7 - i, sorted.UniqueIds[i].Id, "Unexpected value for UniqueId[{0}]", i);
				Assert.IsFalse (sorted.ModSeq.HasValue, "Expected the ModSeq property to be null");
				Assert.AreEqual (7, sorted.Min.Value.Id, "Unexpected Min");
				Assert.AreEqual (1, sorted.Max.Value.Id, "Unexpected Max");
				Assert.AreEqual (7, sorted.Count, "Unexpected Count");

				// Verify that optimizing NOT queries works correctly
				var uids = await folder.SearchAsync (SearchQuery.Not (SearchQuery.Deleted).And (SearchQuery.Not (SearchQuery.NotSeen)));
				Assert.AreEqual (7, uids.Count, "Unexpected number of UIDs");
				for (int i = 0; i < uids.Count; i++)
					Assert.AreEqual (i + 1, uids[i].Id, "Unexpected value for uids[{0}]", i);

				// Create a Destination folder to use for copying/moving messages to
				var destination = await unitTests.CreateAsync ("Destination", true);
				Assert.AreEqual (FolderAttributes.HasNoChildren, destination.Attributes, "Unexpected UnitTests.Destination folder attributes");

				// COPY messages to the Destination folder
				var copied = await folder.CopyToAsync (uids, destination);
				Assert.AreEqual (uids.Count, copied.Source.Count, "Unexpetced Source.Count");
				Assert.AreEqual (uids.Count, copied.Destination.Count, "Unexpetced Destination.Count");

				// MOVE messages to the Destination folder
				var moved = await folder.MoveToAsync (uids, destination);
				Assert.AreEqual (uids.Count, copied.Source.Count, "Unexpetced Source.Count");
				Assert.AreEqual (uids.Count, copied.Destination.Count, "Unexpetced Destination.Count");
				Assert.AreEqual (1, vanished.Count, "Expected VANISHED event");
				vanished.Clear ();

				await destination.StatusAsync (statusItems);
				Assert.AreEqual (moved.Destination[0].Validity, destination.UidValidity, "Unexpected UIDVALIDITY");

				destination.MessageFlagsChanged += (sender, e) => {
					flagsChanged.Add (e);
				};

				destination.ModSeqChanged += (sender, e) => {
					modSeqChanged.Add (e);
				};

				destination.MessagesVanished += (sender, e) => {
					vanished.Add (e);
				};

				destination.RecentChanged += (sender, e) => {
					recentChanged = true;
				};

				await destination.OpenAsync (FolderAccess.ReadWrite);
				Assert.AreEqual (FolderAccess.ReadWrite, access, "Expected UnitTests.Destination to be opened in READ-WRITE mode");

				var fetchHeaders = new HashSet<HeaderId> ();
				fetchHeaders.Add (HeaderId.References);
				fetchHeaders.Add (HeaderId.XMailer);

				var indexes = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };

				// Fetch + modseq
				fetched = await destination.FetchAsync (UniqueIdRange.All, 1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (0, -1, 1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (indexes, 1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (0, -1, 1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (indexes, 1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				// Fetch
				fetched = await destination.FetchAsync (UniqueIdRange.All, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (indexes, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References, fetchHeaders);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (0, -1, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				fetched = await destination.FetchAsync (indexes, MessageSummaryItems.Full | MessageSummaryItems.UniqueId | 
				                                        MessageSummaryItems.BodyStructure | MessageSummaryItems.ModSeq | 
				                                        MessageSummaryItems.References);
				Assert.AreEqual (14, fetched.Count, "Unexpected number of messages fetched");

				uids = new UniqueIdSet (SortOrder.Ascending);

				for (int i = 0; i < fetched.Count; i++) {
					Assert.AreEqual (i, fetched[i].Index, "Unexpected Index");
					Assert.AreEqual (i + 1, fetched[i].UniqueId.Id, "Unexpected UniqueId");

					uids.Add (fetched[i].UniqueId);
				}

				var entity = await destination.GetBodyPartAsync (fetched[0].UniqueId, fetched[0].TextBody);
				Assert.IsInstanceOf<TextPart> (entity);

				entity = await destination.GetBodyPartAsync (fetched[0].Index, fetched[0].TextBody);
				Assert.IsInstanceOf<TextPart> (entity);

				using (var stream = await destination.GetStreamAsync (fetched[0].UniqueId, 128, 64)) {
					Assert.AreEqual (64, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("nit Tests <*****@*****.**>\r\nMIME-Version: 1.0\r\nContent-T", text);
				}

				using (var stream = await destination.GetStreamAsync (fetched[0].UniqueId, "", 128, 64)) {
					Assert.AreEqual (64, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("nit Tests <*****@*****.**>\r\nMIME-Version: 1.0\r\nContent-T", text);
				}

				using (var stream = await destination.GetStreamAsync (fetched[0].Index, 128, 64)) {
					Assert.AreEqual (64, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("nit Tests <*****@*****.**>\r\nMIME-Version: 1.0\r\nContent-T", text);
				}

				using (var stream = await destination.GetStreamAsync (fetched[0].Index, "", 128, 64)) {
					Assert.AreEqual (64, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("nit Tests <*****@*****.**>\r\nMIME-Version: 1.0\r\nContent-T", text);
				}

				using (var stream = await destination.GetStreamAsync (fetched[0].UniqueId, "HEADER.FIELDS (MIME-VERSION CONTENT-TYPE)")) {
					Assert.AreEqual (62, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("MIME-Version: 1.0\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n", text);
				}

				using (var stream = await destination.GetStreamAsync (fetched[0].Index, "HEADER.FIELDS (MIME-VERSION CONTENT-TYPE)")) {
					Assert.AreEqual (62, stream.Length, "Unexpected stream length");

					string text;
					using (var reader = new StreamReader (stream))
						text = reader.ReadToEnd ();

					Assert.AreEqual ("MIME-Version: 1.0\r\nContent-Type: text/plain; charset=utf-8\r\n\r\n", text);
				}

				var custom = new HashSet<string> ();
				custom.Add ("$MailKit");

				await destination.AddFlagsAsync (uids, destination.HighestModSeq, MessageFlags.Deleted, custom, true);
				Assert.AreEqual (14, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				Assert.AreEqual (5, destination.HighestModSeq);
				for (int i = 0; i < modSeqChanged.Count; i++) {
					Assert.AreEqual (i, modSeqChanged[i].Index, "Unexpected value for modSeqChanged[{0}].Index", i);
					Assert.AreEqual (5, modSeqChanged[i].ModSeq, "Unexpected value for modSeqChanged[{0}].ModSeq", i);
				}
				modSeqChanged.Clear ();

				await destination.SetFlagsAsync (new int[] { 0, 1, 2, 3, 4, 5, 6 }, destination.HighestModSeq, MessageFlags.Seen | MessageFlags.Deleted, custom, true);
				Assert.AreEqual (7, modSeqChanged.Count, "Unexpected number of ModSeqChanged events");
				Assert.AreEqual (6, destination.HighestModSeq);
				for (int i = 0; i < modSeqChanged.Count; i++) {
					Assert.AreEqual (i, modSeqChanged[i].Index, "Unexpected value for modSeqChanged[{0}].Index", i);
					Assert.AreEqual (6, modSeqChanged[i].ModSeq, "Unexpected value for modSeqChanged[{0}].ModSeq", i);
				}
				modSeqChanged.Clear ();

				var results = await destination.SearchAsync (uids, SearchQuery.Answered.Or (SearchQuery.Deleted.Or (SearchQuery.Draft.Or (SearchQuery.Flagged.Or (SearchQuery.Recent.Or (SearchQuery.NotAnswered.Or (SearchQuery.NotDeleted.Or (SearchQuery.NotDraft.Or (SearchQuery.NotFlagged.Or (SearchQuery.NotSeen.Or (SearchQuery.HasCustomFlag ("$MailKit").Or (SearchQuery.DoesNotHaveCustomFlag ("$MailKit")))))))))))));
				Assert.AreEqual (14, results.Count, "Unexpected number of UIDs");

				var matches = await destination.SearchAsync (searchOptions, uids, SearchQuery.LargerThan (256).And (SearchQuery.SmallerThan (512)));
				var expectedMatchedUids = new uint[] { 2, 3, 4, 5, 6, 9, 10, 11, 12, 13 };
				Assert.AreEqual (10, matches.Count, "Unexpected COUNT");
				Assert.AreEqual (13, matches.Max.Value.Id, "Unexpected MAX");
				Assert.AreEqual (2, matches.Min.Value.Id, "Unexpected MIN");
				Assert.AreEqual (10, matches.UniqueIds.Count, "Unexpected number of UIDs");
				for (int i = 0; i < matches.UniqueIds.Count; i++)
					Assert.AreEqual (expectedMatchedUids[i], matches.UniqueIds[i].Id);

				orderBy = new OrderBy[] { OrderBy.ReverseDate, OrderBy.Subject, OrderBy.DisplayFrom, OrderBy.Size };
				var sentDateQuery = SearchQuery.Or (SearchQuery.And (SearchQuery.SentBefore (new DateTime (2016, 10, 12)), SearchQuery.SentAfter (new DateTime (2016, 10, 10))), SearchQuery.Not (SearchQuery.SentOn (new DateTime (2016, 10, 11))));
				var deliveredDateQuery = SearchQuery.Or (SearchQuery.And (SearchQuery.DeliveredBefore (new DateTime (2016, 10, 12)), SearchQuery.DeliveredAfter (new DateTime (2016, 10, 10))), SearchQuery.Not (SearchQuery.DeliveredOn (new DateTime (2016, 10, 11))));
				results = await destination.SearchAsync (sentDateQuery.Or (deliveredDateQuery), orderBy);
				var expectedSortByDateResults = new uint[] { 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8 };
				Assert.AreEqual (14, results.Count, "Unexpected number of UIDs");
				for (int i = 0; i < results.Count; i++)
					Assert.AreEqual (expectedSortByDateResults[i], results[i].Id);

				var stringQuery = SearchQuery.BccContains ("xyz").Or (SearchQuery.CcContains ("xyz").Or (SearchQuery.FromContains ("xyz").Or (SearchQuery.ToContains ("xyz").Or (SearchQuery.SubjectContains ("xyz").Or (SearchQuery.HeaderContains ("Message-Id", "mimekit.net").Or (SearchQuery.BodyContains ("This is the message body.").Or (SearchQuery.MessageContains ("message"))))))));
				orderBy = new OrderBy[] { OrderBy.From, OrderBy.To, OrderBy.Cc };
				results = await destination.SearchAsync (uids, stringQuery, orderBy);
				Assert.AreEqual (14, results.Count, "Unexpected number of UIDs");
				for (int i = 0; i < results.Count; i++)
					Assert.AreEqual (i + 1, results[i].Id);

				orderBy = new OrderBy[] { OrderBy.DisplayTo };
				matches = await destination.SearchAsync (searchOptions, uids, SearchQuery.OlderThan (1).And (SearchQuery.YoungerThan (3600)), orderBy);
				Assert.AreEqual (14, matches.Count, "Unexpected COUNT");
				Assert.AreEqual (14, matches.Max.Value.Id, "Unexpected MAX");
				Assert.AreEqual (1, matches.Min.Value.Id, "Unexpected MIN");
				Assert.AreEqual (14, matches.UniqueIds.Count, "Unexpected number of UIDs");
				for (int i = 0; i < matches.UniqueIds.Count; i++)
					Assert.AreEqual (i + 1, matches.UniqueIds[i].Id);

				client.Capabilities &= ~ImapCapabilities.ESearch;
				matches = await ((ImapFolder) destination).SearchAsync ("ALL");
				Assert.IsFalse (matches.Max.HasValue, "MAX should not be set");
				Assert.IsFalse (matches.Min.HasValue, "MIN should not be set");
				Assert.AreEqual (0, matches.Count, "COUNT should not be set");
				Assert.AreEqual (14, matches.UniqueIds.Count);
				for (int i = 0; i < matches.UniqueIds.Count; i++)
					Assert.AreEqual (i + 1, matches.UniqueIds[i].Id);

				client.Capabilities &= ~ImapCapabilities.ESort;
				matches = await ((ImapFolder) destination).SortAsync ("(REVERSE ARRIVAL) US-ASCII ALL");
				Assert.IsFalse (matches.Max.HasValue, "MAX should not be set");
				Assert.IsFalse (matches.Min.HasValue, "MIN should not be set");
				Assert.AreEqual (0, matches.Count, "COUNT should not be set");
				Assert.AreEqual (14, matches.UniqueIds.Count);
				for (int i = 0; i < matches.UniqueIds.Count; i++)
					Assert.AreEqual (i + 1, matches.UniqueIds[i].Id);

				await destination.ExpungeAsync ();
				Assert.AreEqual (7, destination.HighestModSeq);
				Assert.AreEqual (1, vanished.Count, "Unexpected number of Vanished events");
				Assert.AreEqual (14, vanished[0].UniqueIds.Count, "Unexpected number of UIDs in Vanished event");
				for (int i = 0; i < vanished[0].UniqueIds.Count; i++)
					Assert.AreEqual (i + 1, vanished[0].UniqueIds[i].Id);
				Assert.IsFalse (vanished[0].Earlier, "Unexpected value for Earlier");
				vanished.Clear ();

				await destination.CloseAsync (true);

				await client.DisconnectAsync (false);
			}
		}
Example #22
0
        async Task <IList <UniqueId> > StoreAsync(IList <UniqueId> uids, IStoreLabelsRequest request, bool doAsync, CancellationToken cancellationToken)
        {
            if (uids == null)
            {
                throw new ArgumentNullException(nameof(uids));
            }

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if ((Engine.Capabilities & ImapCapabilities.GMailExt1) == 0)
            {
                throw new NotSupportedException("The IMAP server does not support the Google Mail extensions.");
            }

            CheckState(true, true);

            if (uids.Count == 0)
            {
                return(new UniqueId[0]);
            }

            var    @params = string.Empty;
            string action;

            switch (request.Action)
            {
            case StoreAction.Add:
                if (request.Labels == null || request.Labels.Count == 0)
                {
                    return(new UniqueId[0]);
                }

                action = request.Silent ? "+X-GM-LABELS.SILENT" : "+X-GM-LABELS";
                break;

            case StoreAction.Remove:
                if (request.Labels == null || request.Labels.Count == 0)
                {
                    return(new UniqueId[0]);
                }

                action = request.Silent ? "-X-GM-LABELS.SILENT" : "-X-GM-LABELS";
                break;

            default:
                action = request.Silent ? "X-GM-LABELS.SILENT" : "X-GM-LABELS";
                break;
            }

            if (request.UnchangedSince.HasValue)
            {
                @params = string.Format(CultureInfo.InvariantCulture, " (UNCHANGEDSINCE {0})", request.UnchangedSince.Value);
            }

            var         args       = new List <object> ();
            var         list       = LabelListToString(request.Labels, args);
            var         command    = string.Format("UID STORE %s{0} {1} {2}\r\n", @params, action, list);
            UniqueIdSet unmodified = null;

            foreach (var ic in Engine.QueueCommands(cancellationToken, this, command, uids, args.ToArray()))
            {
                await Engine.RunAsync(ic, doAsync).ConfigureAwait(false);

                ProcessResponseCodes(ic, null);

                if (ic.Response != ImapCommandResponse.Ok)
                {
                    throw ImapCommandException.Create("STORE", ic);
                }

                ProcessUnmodified(ic, ref unmodified, request.UnchangedSince);
            }

            if (unmodified == null)
            {
                return(new UniqueId[0]);
            }

            return(unmodified);
        }
Example #23
0
        async Task <IList <UniqueId> > StoreAsync(IList <UniqueId> uids, IStoreFlagsRequest request, bool doAsync, CancellationToken cancellationToken)
        {
            if (uids == null)
            {
                throw new ArgumentNullException(nameof(uids));
            }

            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (request.UnchangedSince.HasValue && !supportsModSeq)
            {
                throw new NotSupportedException("The ImapFolder does not support mod-sequences.");
            }

            CheckState(true, true);

            if (uids.Count == 0)
            {
                return(new UniqueId[0]);
            }

            int    numKeywords = request.Keywords != null ? request.Keywords.Count : 0;
            string action;

            switch (request.Action)
            {
            case StoreAction.Add:
                if ((request.Flags & SettableFlags) == 0 && numKeywords == 0)
                {
                    return(new UniqueId[0]);
                }

                action = request.Silent ? "+FLAGS.SILENT" : "+FLAGS";
                break;

            case StoreAction.Remove:
                if ((request.Flags & SettableFlags) == 0 && numKeywords == 0)
                {
                    return(new UniqueId[0]);
                }

                action = request.Silent ? "-FLAGS.SILENT" : "-FLAGS";
                break;

            default:
                action = request.Silent ? "FLAGS.SILENT" : "FLAGS";
                break;
            }

            var flaglist    = ImapUtils.FormatFlagsList(request.Flags & PermanentFlags, request.Keywords != null ? request.Keywords.Count : 0);
            var keywordList = request.Keywords != null?request.Keywords.ToArray() : new object[0];

            UniqueIdSet unmodified = null;
            var         @params    = string.Empty;

            if (request.UnchangedSince.HasValue)
            {
                @params = string.Format(CultureInfo.InvariantCulture, " (UNCHANGEDSINCE {0})", request.UnchangedSince.Value);
            }

            var command = string.Format("UID STORE %s{0} {1} {2}\r\n", @params, action, flaglist);

            foreach (var ic in Engine.QueueCommands(cancellationToken, this, command, uids, keywordList))
            {
                await Engine.RunAsync(ic, doAsync).ConfigureAwait(false);

                ProcessResponseCodes(ic, null);

                if (ic.Response != ImapCommandResponse.Ok)
                {
                    throw ImapCommandException.Create("STORE", ic);
                }

                ProcessUnmodified(ic, ref unmodified, request.UnchangedSince);
            }

            if (unmodified == null)
            {
                return(new UniqueId[0]);
            }

            return(unmodified);
        }
Example #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MailKit.Search.SearchResults"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a new <see cref="SearchResults"/>.
 /// </remarks>
 /// <param name="order">The sort-order to use for the unique identifiers.</param>
 public SearchResults(SortOrder order = SortOrder.None)
 {
     UniqueIds = new UniqueIdSet(order);
 }
Example #25
0
		public void TestNonSequentialUniqueIdSet ()
		{
			UniqueId[] uids = {
				new UniqueId (1), new UniqueId (3), new UniqueId (5),
				new UniqueId (7), new UniqueId (9)
			};
			var list = new UniqueIdSet (uids);
			var actual = list.ToString ();

			Assert.AreEqual ("1,3,5,7,9", actual);

			list = new UniqueIdSet (uids, SortOrder.Ascending);
			actual = list.ToString ();

			Assert.AreEqual ("1,3,5,7,9", actual, "Unexpected result for ascending set.");

			list = new UniqueIdSet (uids, SortOrder.Descending);
			actual = list.ToString ();

			Assert.AreEqual ("9,7,5,3,1", actual, "Unexpected result for descending set.");
		}
        public void TestAscendingUniqueIdSet()
        {
            UniqueId[] uids =
            {
                new UniqueId(1), new UniqueId(2), new UniqueId(3),
                new UniqueId(4), new UniqueId(5), new UniqueId(6),
                new UniqueId(7), new UniqueId(8), new UniqueId(9)
            };
            var list   = new UniqueIdSet(uids, SortOrder.Ascending);
            var actual = list.ToString();

            Assert.AreEqual("1:9", actual, "Incorrect initial value.");
            Assert.AreEqual(9, list.Count, "Incorrect initial count.");
            Assert.AreEqual(-1, list.IndexOf(new UniqueId(500)));
            Assert.IsFalse(list.Contains(new UniqueId(500)));
            Assert.IsFalse(list.Remove(new UniqueId(500)));

            // Test Remove()

            list.Remove(uids[0]);
            actual = list.ToString();

            Assert.AreEqual("2:9", actual, "Incorrect results after Remove() #1.");
            Assert.AreEqual(8, list.Count, "Incorrect count after Remove() #1.");

            list.Remove(uids[uids.Length - 1]);
            actual = list.ToString();

            Assert.AreEqual("2:8", actual, "Incorrect results after Remove() #2.");
            Assert.AreEqual(7, list.Count, "Incorrect count after Remove() #2.");

            list.Remove(uids[4]);
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8", actual, "Incorrect results after Remove() #3.");
            Assert.AreEqual(6, list.Count, "Incorrect count after Remove() #3.");

            // Test Add()

            list.Add(new UniqueId(5));
            actual = list.ToString();

            Assert.AreEqual("2:8", actual, "Incorrect results after Add() #1.");
            Assert.AreEqual(7, list.Count, "Incorrect count after Add() #1.");

            list.Add(new UniqueId(1));
            actual = list.ToString();

            Assert.AreEqual("1:8", actual, "Incorrect results after Add() #2.");
            Assert.AreEqual(8, list.Count, "Incorrect count after Add() #2.");

            list.Add(new UniqueId(9));
            actual = list.ToString();

            Assert.AreEqual("1:9", actual, "Incorrect results after Add() #3.");
            Assert.AreEqual(9, list.Count, "Incorrect count after Add() #3.");

            // Test RemoveAt()

            list.RemoveAt(0);
            actual = list.ToString();

            Assert.AreEqual("2:9", actual, "Incorrect results after RemoveAt() #1.");
            Assert.AreEqual(8, list.Count, "Incorrect count after RemoveAt() #1.");

            list.RemoveAt(7);
            actual = list.ToString();

            Assert.AreEqual("2:8", actual, "Incorrect results after RemoveAt() #2.");
            Assert.AreEqual(7, list.Count, "Incorrect count after RemoveAt() #2.");

            list.RemoveAt(3);
            actual = list.ToString();

            Assert.AreEqual("2:4,6:8", actual, "Incorrect results after RemoveAt() #3.");
            Assert.AreEqual(6, list.Count, "Incorrect count after RemoveAt() #3.");

            // Test adding a range of items

            list.AddRange(uids);
            actual = list.ToString();

            Assert.AreEqual("1:9", actual, "Incorrect results after AddRange().");
            Assert.AreEqual(9, list.Count, "Incorrect count after AddRange().");

            // Test clearing the list
            list.Clear();
            Assert.AreEqual(0, list.Count, "Incorrect count after Clear().");
        }
Example #27
0
		static void SearchMatches (ImapEngine engine, ImapCommand ic, int index)
		{
			var uids = new UniqueIdSet (SortOrder.Ascending);
			var results = (SearchResults) ic.UserData;
			ImapToken token;
			ulong modseq;
			uint uid;

			do {
				token = engine.PeekToken (ic.CancellationToken);

				// keep reading UIDs until we get to the end of the line or until we get a "(MODSEQ ####)"
				if (token.Type == ImapTokenType.Eoln || token.Type == ImapTokenType.OpenParen)
					break;

				token = engine.ReadToken (ic.CancellationToken);

				if (token.Type != ImapTokenType.Atom || !uint.TryParse ((string) token.Value, out uid) || uid == 0)
					throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "SEARCH", token);

				uids.Add (new UniqueId (ic.Folder.UidValidity, uid));
			} while (true);

			if (token.Type == ImapTokenType.OpenParen) {
				engine.ReadToken (ic.CancellationToken);

				do {
					token = engine.ReadToken (ic.CancellationToken);

					if (token.Type == ImapTokenType.CloseParen)
						break;

					if (token.Type != ImapTokenType.Atom)
						throw ImapEngine.UnexpectedToken (ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "SEARCH", token);

					var atom = (string) token.Value;

					switch (atom) {
					case "MODSEQ":
						token = engine.ReadToken (ic.CancellationToken);

						if (token.Type != ImapTokenType.Atom || !ulong.TryParse ((string) token.Value, out modseq)) {
							Debug.WriteLine ("Expected 64-bit nz-number as the MODSEQ value, but got: {0}", token);
							throw ImapEngine.UnexpectedToken (ImapEngine.GenericItemSyntaxErrorFormat, atom, token);
						}
						break;
					}

					token = engine.PeekToken (ic.CancellationToken);
				} while (token.Type != ImapTokenType.Eoln);
			}

			results.UniqueIds = uids;
		}
Example #28
0
		public void TestReversedUniqueIdSet ()
		{
			UniqueId[] uids = {
				new UniqueId (20), new UniqueId (19), new UniqueId (15),
				new UniqueId (12), new UniqueId (11), new UniqueId (10),
				new UniqueId (9), new UniqueId (6), new UniqueId (5),
				new UniqueId (3), new UniqueId (2), new UniqueId (1)
			};
			var list = new UniqueIdSet (uids);
			var actual = list.ToString ();

			Assert.AreEqual ("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for unsorted set.");

			list = new UniqueIdSet (uids, SortOrder.Ascending);
			actual = list.ToString ();

			Assert.AreEqual ("1:3,5:6,9:12,15,19:20", actual, "Unexpected result for ascending set.");
			Assert.AreEqual (0, list.IndexOf (new UniqueId (1)), "Unexpected index for descending set.");

			list = new UniqueIdSet (uids, SortOrder.Descending);
			actual = list.ToString ();

			Assert.AreEqual ("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for descending set.");
			Assert.AreEqual (11, list.IndexOf (new UniqueId (1)), "Unexpected index for descending set.");
		}
Example #29
0
		public void TestReversedUniqueIdSet ()
		{
			UniqueId[] uids = {
				new UniqueId (20), new UniqueId (19), new UniqueId (15),
				new UniqueId (12), new UniqueId (11), new UniqueId (10),
				new UniqueId (9), new UniqueId (6), new UniqueId (5),
				new UniqueId (3), new UniqueId (2), new UniqueId (1)
			};
			var list = new UniqueIdSet (uids, false);
			var actual = list.ToString ();

			Assert.AreEqual ("20:19,15,12:9,6:5,3:1", actual, "Unexpected result for unsorted set.");

			list = new UniqueIdSet (uids, true);
			actual = list.ToString ();

			Assert.AreEqual ("1:3,5:6,9:12,15,19:20", actual, "Unexpected result for sorted set.");
		}
Example #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MailKit.Search.SearchResults"/> class.
 /// </summary>
 /// <remarks>
 /// Creates a new <see cref="SearchResults"/>.
 /// </remarks>
 /// <param name="uidValidity">The UID validity value.</param>
 /// <param name="order">The sort-order to use for the unique identifiers.</param>
 public SearchResults(uint uidValidity, SortOrder order = SortOrder.None)
 {
     UniqueIds = new UniqueIdSet(uidValidity, order);
 }
Example #31
0
        async Task <IList <UniqueId> > StoreAsync(IList <UniqueId> uids, ulong?modseq, IList <Annotation> annotations, bool doAsync, CancellationToken cancellationToken)
        {
            if (uids == null)
            {
                throw new ArgumentNullException(nameof(uids));
            }

            if (modseq.HasValue && !SupportsModSeq)
            {
                throw new NotSupportedException("The ImapFolder does not support mod-sequences.");
            }

            if (annotations == null)
            {
                throw new ArgumentNullException(nameof(annotations));
            }

            CheckState(true, true);

            if (AnnotationAccess == AnnotationAccess.None)
            {
                throw new NotSupportedException("The ImapFolder does not support annotations.");
            }

            if (uids.Count == 0 || annotations.Count == 0)
            {
                return(new UniqueId[0]);
            }

            var         builder    = new StringBuilder("UID STORE %s ");
            var         values     = new List <object> ();
            UniqueIdSet unmodified = null;

            if (modseq.HasValue)
            {
                builder.AppendFormat(CultureInfo.InvariantCulture, "(UNCHANGEDSINCE {0}) ", modseq.Value);
            }

            ImapUtils.FormatAnnotations(builder, annotations, values, true);
            builder.Append("\r\n");

            var command = builder.ToString();
            var args    = values.ToArray();

            foreach (var ic in Engine.QueueCommands(cancellationToken, this, command, uids, args))
            {
                await Engine.RunAsync(ic, doAsync).ConfigureAwait(false);

                ProcessResponseCodes(ic, null);

                if (ic.Response != ImapCommandResponse.Ok)
                {
                    throw ImapCommandException.Create("STORE", ic);
                }

                ProcessUnmodified(ic, ref unmodified, modseq);
            }

            if (unmodified == null)
            {
                return(new UniqueId[0]);
            }

            return(unmodified);
        }
Example #32
0
		public void TestSortedUniqueIdSet ()
		{
			UniqueId[] uids = {
				new UniqueId (1), new UniqueId (2), new UniqueId (3),
				new UniqueId (4), new UniqueId (5), new UniqueId (6),
				new UniqueId (7), new UniqueId (8), new UniqueId (9)
			};
			var list = new UniqueIdSet (uids, true);
			var actual = list.ToString ();

			Assert.AreEqual ("1:9", actual, "Incorrect initial value.");
			Assert.AreEqual (9, list.Count, "Incorrect initial count.");

			// Test Remove()

			list.Remove (uids[0]);
			actual = list.ToString ();

			Assert.AreEqual ("2:9", actual, "Incorrect results after Remove() #1.");
			Assert.AreEqual (8, list.Count, "Incorrect count after Remove() #1.");

			list.Remove (uids[uids.Length - 1]);
			actual = list.ToString ();

			Assert.AreEqual ("2:8", actual, "Incorrect results after Remove() #2.");
			Assert.AreEqual (7, list.Count, "Incorrect count after Remove() #2.");

			list.Remove (uids[4]);
			actual = list.ToString ();

			Assert.AreEqual ("2:4,6:8", actual, "Incorrect results after Remove() #3.");
			Assert.AreEqual (6, list.Count, "Incorrect count after Remove() #3.");

			// Test Add()

			list.Add (new UniqueId (5));
			actual = list.ToString ();

			Assert.AreEqual ("2:8", actual, "Incorrect results after Add() #1.");
			Assert.AreEqual (7, list.Count, "Incorrect count after Add() #1.");

			list.Add (new UniqueId (1));
			actual = list.ToString ();

			Assert.AreEqual ("1:8", actual, "Incorrect results after Add() #2.");
			Assert.AreEqual (8, list.Count, "Incorrect count after Add() #2.");

			list.Add (new UniqueId (9));
			actual = list.ToString ();

			Assert.AreEqual ("1:9", actual, "Incorrect results after Add() #3.");
			Assert.AreEqual (9, list.Count, "Incorrect count after Add() #3.");

			// Test RemoveAt()

			list.RemoveAt (0);
			actual = list.ToString ();

			Assert.AreEqual ("2:9", actual, "Incorrect results after RemoveAt() #1.");
			Assert.AreEqual (8, list.Count, "Incorrect count after RemoveAt() #1.");

			list.RemoveAt (7);
			actual = list.ToString ();

			Assert.AreEqual ("2:8", actual, "Incorrect results after RemoveAt() #2.");
			Assert.AreEqual (7, list.Count, "Incorrect count after RemoveAt() #2.");

			list.RemoveAt (3);
			actual = list.ToString ();

			Assert.AreEqual ("2:4,6:8", actual, "Incorrect results after RemoveAt() #3.");
			Assert.AreEqual (6, list.Count, "Incorrect count after RemoveAt() #3.");

			// Test adding a range of items

			list.AddRange (uids);
			actual = list.ToString ();

			Assert.AreEqual ("1:9", actual, "Incorrect results after AddRange().");
			Assert.AreEqual (9, list.Count, "Incorrect count after AddRange().");

			// Test clearing the list
			list.Clear ();
			Assert.AreEqual (0, list.Count, "Incorrect count after Clear().");
		}