public void TestCapabilityCaseInsensitivity()
		{
			const string welcomeMessage = "+OK";
			const string capabilityResponse =
				"+OK Capability list follows\r\n" +
				"TEST\r\n" +
				"TEST2 TEST\r\n" +
				"aBcDeFg\r\n" +
				".";
			const string quitOk = "+OK";

			const string serverResponses = welcomeMessage + "\r\n" + capabilityResponse + "\r\n" + quitOk + "\r\n";

			Stream inputStream = new MemoryStream(Encoding.ASCII.GetBytes(serverResponses));
			MemoryStream outputStream = new MemoryStream();

			using (Pop3Client client = new Pop3Client())
			{
				client.Connect(new CombinedStream(inputStream, outputStream));

				Dictionary<string, List<string>> capabilities = client.Capabilities();

				// Check the capabilities received was correct
				Assert.IsTrue(capabilities.ContainsKey("test"));
				Assert.IsTrue(capabilities.ContainsKey("TeSt2"));
				Assert.IsTrue(capabilities.ContainsKey("aBcDeFg"));
				Assert.IsTrue(capabilities.ContainsKey("AbCdEfG"));
				Assert.AreEqual(3, capabilities.Keys.Count);

				// Check arguments
				Assert.IsEmpty(capabilities["TEST"]);

				List<string> test2Arguments = capabilities["tEsT2"];
				Assert.NotNull(test2Arguments);
				Assert.Contains("TEST", test2Arguments);
				Assert.AreEqual(1, test2Arguments.Count);

				Assert.IsEmpty(capabilities["aBcDeFg"]);
			}
		}
		public void TestCapabilityOtherCapabilities()
		{
			const string welcomeMessage = "+OK";
			const string capabilityResponse =
				"+OK Capability list follows\r\n" +
				"FOO\r\n" +
				"BAR BAZ\r\n" +
				"SSS SSS1 SSS2\r\n" +
				"IMPLEMENTATION Foo-bar-baz-Server\r\n" +
				".";
			const string quitOk = "+OK";

			const string serverResponses = welcomeMessage + "\r\n" + capabilityResponse + "\r\n" + quitOk + "\r\n";

			Stream inputStream = new MemoryStream(Encoding.ASCII.GetBytes(serverResponses));
			MemoryStream outputStream = new MemoryStream();

			using (Pop3Client client = new Pop3Client())
			{
				client.Connect(new CombinedStream(inputStream, outputStream));

				Dictionary<string, List<string>> capabilities = client.Capabilities();

				// Check the capabilities received was correct
				Assert.Contains("FOO", capabilities.Keys);
				Assert.Contains("BAR", capabilities.Keys);
				Assert.Contains("SSS", capabilities.Keys);
				Assert.Contains("IMPLEMENTATION", capabilities.Keys);
				Assert.AreEqual(4, capabilities.Keys.Count);

				// Check arguments
				Assert.IsEmpty(capabilities["FOO"]);

				List<string> barArguments = capabilities["BAR"];
				Assert.NotNull(barArguments);
				Assert.Contains("BAZ", barArguments);
				Assert.AreEqual(1, barArguments.Count);

				List<string> sssArguments = capabilities["SSS"];
				Assert.NotNull(sssArguments);
				Assert.Contains("SSS1", sssArguments);
				Assert.Contains("SSS2", sssArguments);
				Assert.AreEqual(2, sssArguments.Count);

				List<string> implementationArguments = capabilities["IMPLEMENTATION"];
				Assert.NotNull(implementationArguments);
				Assert.Contains("Foo-bar-baz-Server", implementationArguments);
				Assert.AreEqual(1, implementationArguments.Count);

				// Check the correct command was sent
				const string expectedCommand = "CAPA";
				string actualCommand = GetLastCommand(new StreamReader(new MemoryStream(outputStream.ToArray())).ReadToEnd());

				Assert.AreEqual(expectedCommand, actualCommand);
			}
		}
		public void TestCapabilityInTransactionState()
		{
			const string welcomeMessage = "+OK";
			const string okUsername = "******";
			const string okPassword = "******";
			const string capabilityResponse =
				"+OK Capability list follows\r\n" +
				"TEST\r\n" +
				"TEST2 TEST\r\n" +
				".";
			const string quitOk = "+OK";

			const string serverResponses = welcomeMessage + "\r\n" + okUsername + "\r\n" + okPassword + "\r\n" + capabilityResponse + "\r\n" + quitOk + "\r\n";

			Stream inputStream = new MemoryStream(Encoding.ASCII.GetBytes(serverResponses));
			MemoryStream outputStream = new MemoryStream();

			using (Pop3Client client = new Pop3Client())
			{
				client.Connect(new CombinedStream(inputStream, outputStream));

				client.Authenticate("user", "password");

				Dictionary<string, List<string>> capabilities = client.Capabilities();

				// Check the capabilities received was correct
				Assert.Contains("TEST", capabilities.Keys);
				Assert.Contains("TEST2", capabilities.Keys);
				Assert.AreEqual(2, capabilities.Keys.Count);

				// Check arguments
				Assert.IsEmpty(capabilities["TEST"]);

				List<string> test2Arguments = capabilities["TEST2"];
				Assert.NotNull(test2Arguments);
				Assert.Contains("TEST", test2Arguments);
				Assert.AreEqual(1, test2Arguments.Count);

				// Check the correct command was sent
				const string expectedCommand = "CAPA";
				string actualCommand = GetLastCommand(new StreamReader(new MemoryStream(outputStream.ToArray())).ReadToEnd());

				Assert.AreEqual(expectedCommand, actualCommand);
			}
		}
		public void TestCapabilityRfcExample()
		{
			const string welcomeMessage = "+OK";
			const string capabilityResponse =
				"+OK Capability list follows\r\n" +
				"TOP\r\n" +
				"USER\r\n" +
				"SASL CRAM-MD5 KERBEROS_V4\r\n" +
				"RESP-CODES\r\n" +
				"LOGIN-DELAY 900\r\n" +
				"PIPELINING\r\n" +
				"EXPIRE 60\r\n" +
				"UIDL\r\n" +
				"IMPLEMENTATION Shlemazle-Plotz-v302\r\n" +
				".";
			const string quitOk = "+OK";

			const string serverResponses = welcomeMessage + "\r\n" + capabilityResponse + "\r\n" + quitOk + "\r\n";

			Stream inputStream = new MemoryStream(Encoding.ASCII.GetBytes(serverResponses));
			MemoryStream outputStream = new MemoryStream();

			using (Pop3Client client = new Pop3Client())
			{
				client.Connect(new CombinedStream(inputStream, outputStream));

				Dictionary<string, List<string>> capabilities = client.Capabilities();

				// Check the capabilities received was correct
				Assert.Contains("TOP", capabilities.Keys);
				Assert.Contains("USER", capabilities.Keys);
				Assert.Contains("SASL", capabilities.Keys);
				Assert.Contains("RESP-CODES", capabilities.Keys);
				Assert.Contains("LOGIN-DELAY", capabilities.Keys);
				Assert.Contains("PIPELINING", capabilities.Keys);
				Assert.Contains("EXPIRE", capabilities.Keys);
				Assert.Contains("UIDL", capabilities.Keys);
				Assert.Contains("IMPLEMENTATION", capabilities.Keys);
				Assert.AreEqual(9, capabilities.Keys.Count);

				// Check arguments
				Assert.IsEmpty(capabilities["TOP"]);
				Assert.IsEmpty(capabilities["USER"]);

				List<string> saslArguments = capabilities["SASL"];
				Assert.NotNull(saslArguments);
				Assert.Contains("CRAM-MD5", saslArguments);
				Assert.Contains("KERBEROS_V4", saslArguments);
				Assert.AreEqual(2, saslArguments.Count);

				Assert.IsEmpty(capabilities["RESP-CODES"]);

				List<string> loginDelayArguments = capabilities["LOGIN-DELAY"];
				Assert.NotNull(loginDelayArguments);
				Assert.Contains("900", loginDelayArguments);
				Assert.AreEqual(1, loginDelayArguments.Count);

				Assert.IsEmpty(capabilities["PIPELINING"]);

				List<string> expireArguments = capabilities["EXPIRE"];
				Assert.NotNull(expireArguments);
				Assert.Contains("60", expireArguments);
				Assert.AreEqual(1, expireArguments.Count);

				Assert.IsEmpty(capabilities["UIDL"]);

				List<string> implementationArguments = capabilities["IMPLEMENTATION"];
				Assert.NotNull(implementationArguments);
				Assert.Contains("Shlemazle-Plotz-v302", implementationArguments);
				Assert.AreEqual(1, implementationArguments.Count);

				// Check the correct command was sent
				const string expectedCommand = "CAPA";
				string actualCommand = GetLastCommand(new StreamReader(new MemoryStream(outputStream.ToArray())).ReadToEnd());

				Assert.AreEqual(expectedCommand, actualCommand);
			}
		}