// NAnt - A .NET build tool
// Copyright (C) 2001-2002 Gerry Shaw
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Jay Turpin (recipient2@sourceforge.net)
// Gerry Shaw (gerry_shaw@yahoo.com)
// Ryan Boggs (rmboggs@users.sourceforge.net)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using NUnit.Framework;
using NAnt.Core;
using NAnt.Core.Tasks;
using NAnt.Core.Types;

using netDumbster.smtp;

namespace Tests.NAnt.Core.Tasks
{

    [TestFixture]
    public class MailTaskTest : BuildTestBase
    {

        #region Private Static Fields

        /// <summary>
        /// The fake Smtp server to use for testing.  This ensures that
        /// the sample emails generated by these tests do not leave the
        /// testing machine.
        /// </summary>
        private static SimpleSmtpServer _smtpServer;

        /// <summary>
        /// A basic NAnt project template to use for new tests for the &lt;mail&gt;
        /// task that uses the tolist attribute.
        /// </summary>
        private const string _xmlToListProjectTemplate = @"
            <project>
                <mail
                    mailhost='localhost'
                    from='nant@sourceforge.net'
                    tolist='{0}'
                    subject='Message from the {1} test method'
                    mailport='{2}'
                    message='{3}'/>
            </project>";

        /// <summary>
        /// The From email address to use for all testing.
        /// </summary>
        private const string _fromEmail = "nant@sourceforge.net";

        /// <summary>
        /// The default mail host to use for testing.
        /// </summary>
        private const string _mailHost = "localhost";

        /// <summary>
        /// String format to use when creating email subject text.
        /// </summary>
        private const string _subjectText = "Message from {0} method";

        /// <summary>
        /// Valid email address to use for single email scenario testing.
        /// </summary>
        private const string _singleEmail = "jake@example.com";

        /// <summary>
        /// Valid (name) Email address pair to use for single email scenario testing.
        /// </summary>
        private const string _singleParenthesisNameEmail =
            "(Jake Example) jake@example.com";

        /// <summary>
        /// Valid name &lt;Email address&gt; pair to use for single email
        /// scenario testing.
        /// </summary>
        private const string _singleAngleBracketNameEmail =
            "Jake Example <jake@example.com>";

        /// <summary>
        /// Valid Email address (name) pair to use for single email scenario testing.
        /// </summary>
        private const string _singleParenthesisEmailName =
            "jake@example.com (Jake Example)";

        /// <summary>
        /// Valid &lt;Email address&gt; name pair to use for single email
        /// scenario testing.
        /// </summary>
        private const string _singleAngleBracketEmailName =
            "<jake@example.com> Jake Example";

        /// <summary>
        /// Invalid email address to use for single email scenario testing.
        /// </summary>
        /// <remarks>
        /// There is no @ symbol in the email address.
        /// </remarks>
        private const string _badEmail = "jake.example.com";

        /// <summary>
        /// Invalid (name) Email address pair to use for single email scenario testing.
        /// </summary>
        /// <remarks>
        /// The email address is surrounded by brackets.
        /// </remarks>
        private const string _badParenthesisNameEmail =
            "(Jake Example) [jake@example.com]";

        /// <summary>
        /// Invalid name &lt;Email address&gt; pair to use for single email
        /// scenario testing.
        /// </summary>
        /// <remarks>
        /// There is no @ symbol in the email address.
        /// </remarks>
        private const string _badAngleBracketNameEmail =
            "Jake Example <jake.example.com>";

        /// <summary>
        /// Invalid Email address (name) pair to use for single email scenario testing.
        /// </summary>
        /// <remarks>
        /// The email address is surrounded by parenthesis as well.
        /// </remarks>
        private const string _badParenthesisEmailName =
            "(jake@example.com) (Jake Example)";

        /// <summary>
        /// Invalid &lt;Email address&gt; name pair to use for single email
        /// scenario testing.
        /// </summary>
        /// <remarks>
        /// The email address contains angle brackets.
        /// </remarks>
        private const string _badAngleBracketEmailName =
            "<<jake@example.com>> Jake Example";

        #endregion Private Static Fields

        #region Private Instance Fields

        /// <summary>
        /// Holds the version of NAnt to print in the email messages.
        /// </summary>
        /// <remarks>
        /// A nice to have option just in case these tests are converted to
        /// another way (ie: actual working internal smtp server). It would be
        /// nice to see which version of NAnt created the test emails.
        /// </remarks>
        private Version _nantVersion;

        /// <summary>
        /// The system temp path to store test message files.
        /// </summary>
        private string _tempPath;

        /// <summary>
        /// Random number generator used to pick a random port for the
        /// fake smtp server to listen on.
        /// </summary>
        private Random _portRand = new Random();

        /// <summary>
        /// Contains the Port number for the fake smtp server to listen on.
        /// </summary>
        int _port;

        /// <summary>
        /// Contains the complete paths of the files used during testing.
        /// </summary>
        List<string> _files;

        // Email address array fields.
        // These should be used for multiple email tests (ie: multi To list, etc).

        /// <summary>
        /// Two format valid email addresses.
        /// </summary>
        string[] _twoEmails = new string[]
        {
            "jack@example.org", "jane@example.com"
        };

        /// <summary>
        /// Muliple format valid email addresses.
        /// </summary>
        string[] _multiEmails = new string[]
        {
            "jack@example.org", "jane@example.com",
            "carrie@example.net", "barbara@test.org",
            "brad@invalid.com", "jon@test.com"
        };

        /// <summary>
        /// Two format valid (name) email addresses.
        /// </summary>
        string[] _twoParenthesisNameEmails = new string[]
        {
            "(Michael Test) michael@test.org",
            "(Michele Test) michele@test.net"
        };

        /// <summary>
        /// Mulitple format valid (name) email addresses.
        /// </summary>
        string[] _multiParenthesisNameEmails = new string[]
        {
            "(Michael Test) michael@test.org",
            "(Michele Test) michele@test.net",
            "(Kathy Test) kathy@test.org",
            "(Janet Invalid) janet@invalid.net",
            "(Shannon Localhost) shannon@localhost.com",
            "(Margaret Localhost) margaret@localhost.net"
        };

        /// <summary>
        /// Two format valid name &lt;email addresses&gt;.
        /// </summary>
        string[] _twoAngleBracketsNameEmails = new string[]
        {
            "Frank Invalid <frank@invalid.org>",
            "Bill Localhost <bill@localhost.org>"
        };

        /// <summary>
        /// Multiple format valid name &lt;email addresses&gt;.
        /// </summary>
        string[] _multiAngleBracketsNameEmails = new string[]
        {
            "Frank Invalid <frank@invalid.org>",
            "Bill Localhost <bill@localhost.org>",
            "Morgan Example <morgan@example.net>",
            "Kathy Test <kathy@test.org>",
            "Janet Invalid <janet@invalid.net>",
            "Shannon Localhost <shannon@localhost.com>"
        };

        /// <summary>
        /// Two format valid email addresses (name).
        /// </summary>
        string[] _twoParenthesisEmailNames = new string[]
        {
            "michael@test.org (Michael Test)",
            "michele@test.net (Michele Test)"
        };

        /// <summary>
        /// Multiple format valid email addresses (name).
        /// </summary>
        string[] _multiParenthesisEmailNames = new string[]
        {
            "michael@test.org (Michael Test)",
            "michele@test.net (Michele Test)",
            "kathy@test.org (Kathy Test)",
            "janet@invalid.net (Janet Invalid)",
            "shannon@localhost.com (Shannon Localhost)",
            "margaret@localhost.net (Margaret Localhost)"
        };

        /// <summary>
        /// Two format valid &lt;email addresses&gt; name.
        /// </summary>
        string[] _twoAngleBracketsEmailNames = new string[]
        {
            "<frank@invalid.org> Frank Invalid",
            "<bill@localhost.org> Bill Localhost"
        };

        /// <summary>
        /// Multiple format valid &lt;email addresses&gt; name.
        /// </summary>
        string[] _multiAngleBracketsEmailNames = new string[]
        {
            "<frank@invalid.org> Frank Invalid",
            "<bill@localhost.org> Bill Localhost",
            "<morgan@example.net> Morgan Example",
            "<kathy@test.org> Kathy Test",
            "<janet@invalid.net> Janet Invalid",
            "<shannon@localhost.com> Shannon Localhost"
        };

        #endregion Private Instance Fields

        #region SetUp/TearDown Methods

        [TestFixtureSetUp]
        public void Init()
        {
            // Assign the fake smtp port
            _port = _portRand.Next(50000, 60000);
            
            // Starts up the fake smtp server.
            _smtpServer = SimpleSmtpServer.Start(_port);

            // Gets the current executing version of NAnt to use for some
            // of the test emails.
            _nantVersion = Assembly.GetExecutingAssembly().GetName().Version;

            // Setup the temp directory
            _tempPath = Path.Combine(Path.GetTempPath(), "NAntEmailTesting");

            if (!Directory.Exists(_tempPath))
            {
                Directory.CreateDirectory(_tempPath);
            }

            // Create temp files containing messages to load for testing. The
            // resulting paths are stored in a List<string> var for location
            // purposes.
            _files = new List<string>(3);
            _files.Add(CreateEmailMessageTempFile("NAntMailFile1.txt"));
            _files.Add(CreateEmailMessageTempFile("NAntMailFile2.txt"));
            _files.Add(CreateEmailMessageTempFile("NAntMailFile3.txt"));

        }

        [TestFixtureTearDown]
        public void Shutdown()
        {
            // Shuts down the fake smtp server.
            _smtpServer.Stop();

            // Try to remove the temp directory and files from the system.
            // If the directory delete fails, print the exception message to
            // the console without interrupting the remaining tests.
            try
            {
                Directory.Delete(_tempPath, true);
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("Could not cleanup temp dir: {0}", _tempPath);
                System.Console.WriteLine("Encountered error:");
                System.Console.WriteLine(ex.Message);
            }
        }

        protected override void SetUp()
        {
            base.SetUp();
            // Clears out any existing emails in the fake smtp server
            // before running the next test.
            _smtpServer.ClearReceivedEmail();
        }

        #endregion SetUp/TearDown Methods

        #region Simple Email Test Methods

        [Test]
        public void IncludeTrailingSemiColon()
        {
            RunBuild(String.Format(_xmlToListProjectTemplate,
                                   String.Concat(_singleEmail, ";"),
                                   "IncludeTrailingSemiColon",
                                   _port,
                                   CreateSampleEmailMessage("IncludeTrailingSemiColon")
                                   )
                     );

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(1, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 1 email address.
        /// </summary>
        [Test]
        public void SimpleEmailTest()
        {
            string methodName = "SimpleEmailTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _singleEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Test a simple email scenario with 1 email address formatted as
        /// (Full Name) address@abcxyz.com in the To address field.
        /// </summary>
        [Test]
        public void SimpleNameEmailWithParenthesisTest()
        {
            string methodName = "SimpleNameEmailWithParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _singleParenthesisNameEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Test a simple email scenario with 1 email address formatted as
        /// address@abcxyz.com (Full Name) in the To address field.
        /// </summary>
        [Test]
        public void SimpleEmailNameWithParenthesisTest()
        {
            string methodName = "SimpleEmailNameWithParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _singleParenthesisEmailName;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Test a simple email scenario with 1 email address formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the To address field.
        /// </summary>
        [Test]
        public void SimpleNameEmailWithAngleBracketsTest()
        {
            string methodName = "SimpleNameEmailWithAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _singleAngleBracketNameEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Test a simple email scenario with 1 email address formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the To address field.
        /// </summary>
        [Test]
        public void SimpleEmailNameWithAngleBracketsTest()
        {
            string methodName = "SimpleEmailNameWithAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _singleAngleBracketEmailName;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        #endregion Simple Email Test Methods

        #region Mulitple To Email Test Methods

        /// <summary>
        /// Test a simple email scenario with 2 email addresses in the
        /// To Address field.
        /// </summary>
        [Test]
        public void TwoToEmailAddressesTest()
        {
            string methodName = "TwoToEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses in the
        /// To Address field.
        /// </summary>
        [Test]
        public void ManyToEmailAddressesTest()
        {
            string methodName = "ManyToEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_multiEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the To address field.
        /// </summary>
        [Test]
        public void TwoToNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "TwoToNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the To address field.
        /// </summary>
        [Test]
        public void ManyToNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "ManyToNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_multiParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the To address field.
        /// </summary>
        [Test]
        public void TwoToNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "TwoToNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the To address field.
        /// </summary>
        [Test]
        public void ManyToNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "ManyToNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_multiAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the To address field.
        [Test]
        public void TwoToEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "TwoToEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the To address field.
        [Test]
        public void ManyToEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "ManyToEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_multiParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the To address field.
        /// </summary>
        [Test]
        public void TwoToEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "TwoToEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the To address field.
        /// </summary>
        [Test]
        public void ManyToEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "ManyToEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_multiAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        #endregion Mulitple To Email Test Methods

        #region Mulitple CC Email Test Methods

        /// <summary>
        /// Test a simple email scenario with 2 email addresses in the
        /// CC Address field.
        /// </summary>
        [Test]
        public void TwoCcEmailAddressesTest()
        {
            string methodName = "TwoCcEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(2, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses in the
        /// CC Address field.
        /// </summary>
        [Test]
        public void ManyCcEmailAddressesTest()
        {
            string methodName = "ManyCcEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_multiEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(6, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the CC address field.
        /// </summary>
        [Test]
        public void TwoCcNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "TwoCcNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_twoParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(2, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the CC address field.
        /// </summary>
        [Test]
        public void ManyCcNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "ManyCcNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_multiParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(6, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the CC address field.
        /// </summary>
        [Test]
        public void TwoCcNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "TwoCcNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_twoAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(2, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the CC address field.
        /// </summary>
        [Test]
        public void ManyCcNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "ManyCcNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_multiAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(6, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the CC address field.
        /// </summary>
        [Test]
        public void TwoCcEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "TwoCcEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_twoParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(2, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the CC address field.
        /// </summary>
        [Test]
        public void ManyCcEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "ManyCcEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_multiParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(6, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the CC address field.
        /// </summary>
        [Test]
        public void TwoCcEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "TwoCcEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_twoAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(2, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the CC address field.
        /// </summary>
        [Test]
        public void ManyCcEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "ManyCcEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.CcList = CreateEmailListString(_multiAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            
            if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
            {
                string[] ccEmails = GetCcAddressesFromSentMail();
                
                Assert.AreEqual(6, ccEmails.Length);
            }
            else
            {
                Assert.Fail("Test email did not contain addresses in the CC line");
            }
        }

        #endregion Mulitple CC Email Test Methods

        #region Mulitple BCC Email Test Methods

        /// <summary>
        /// Test a simple email scenario with 2 email addresses in the
        /// BCC Address field.
        /// </summary>
        [Test]
        public void TwoBccEmailAddressesTest()
        {
            string methodName = "TwoBccEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
            
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses in the
        /// BCC Address field.
        /// </summary>
        [Test]
        public void ManyBccEmailAddressesTest()
        {
            string methodName = "ManyBccEmailAddressesTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_multiEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the BCC address field.
        /// </summary>
        [Test]
        public void TwoBccNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "TwoBccNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_twoParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// (Full Name) address@abcxyz.com in the BCC address field.
        /// </summary>
        [Test]
        public void ManyBccNamesAndEmailAddressesInParenthesisTest()
        {
            string methodName = "ManyBccNamesAndEmailAddressesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_multiParenthesisNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the BCC address field.
        /// </summary>
        [Test]
        public void TwoBccNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "TwoBccNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_twoAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// Full Name &lt;address@abcxyz.com&gt; in the BCC address field.
        /// </summary>
        [Test]
        public void ManyBccNamesAndEmailAddressesInAngleBracketsTest()
        {
            string methodName = "ManyBccNamesAndEmailAddressesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_multiAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the BCC address field.
        /// </summary>
        [Test]
        public void TwoBccEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "TwoBccEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_twoParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// address@abcxyz.com (Full Name) in the BCC address field.
        /// </summary>
        [Test]
        public void ManyBccEmailAddressesAndNamesInParenthesisTest()
        {
            string methodName = "ManyBccEmailAddressesAndNamesInParenthesisTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_multiParenthesisEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 2 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the BCC address field.
        /// </summary>
        [Test]
        public void TwoBccEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "TwoBccEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_twoAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(2, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        /// <summary>
        /// Test a simple email scenario with 6 email addresses formatted as
        /// &lt;address@abcxyz.com&gt; Full Name in the BCC address field.
        /// </summary>
        [Test]
        public void ManyBccEmailAddressesAndNamesInAngleBracketsTest()
        {
            string methodName = "ManyBccEmailAddressesAndNamesInAngleBracketsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.BccList = CreateEmailListString(_multiAngleBracketsEmailNames);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        #endregion Mulitple BCC Email Test Methods

        #region Misc Email Test Methods

        /// <summary>
        /// Tests sending an email with the To, CC, and BCC address fields
        /// filled in at once.
        /// </summary>
        [Test]
        public void AllRecipientListsTest()
        {
            string methodName = "AllRecipientListsTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoEmails);
            mailTask.CcList = CreateEmailListString(_twoParenthesisEmailNames);
            mailTask.BccList = CreateEmailListString(_twoAngleBracketsNameEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(6, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
            Assert.AreEqual(2, GetCcAddressesFromSentMail().Length);
        }

        /// <summary>
        /// Tests sending an email with multiple email address in the
        /// To address field in different formats.
        /// </summary>
        [Test]
        public void MixedEmailFormatTest()
        {
            string methodName = "MixedEmailFormatTest()";
            string[] toEmails = new string[]
            {
                CreateEmailListString(_twoEmails),
                CreateEmailListString(_twoAngleBracketsNameEmails),
                CreateEmailListString(_twoParenthesisEmailNames),
                CreateEmailListString(_twoAngleBracketsEmailNames),
                CreateEmailListString(_twoParenthesisNameEmails)
            };

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(toEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
            Assert.AreEqual(10, _smtpServer.ReceivedEmail[0].ToAddresses.Length);
        }

        #endregion Misc Email Test Methods

        #region Email With External Files Test Methods

        /// <summary>
        /// Tests sending an email where the body of the email was filled in
        /// using external files.
        /// </summary>
        [Test]
        public void EmailMessageFromFileTest()
        {
            string methodName = "EmailMessageFromFileTest()";
            FileSet fileSet = new FileSet();
            fileSet.FileNames.AddRange(_files.ToArray());

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Files = fileSet;

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Tests sending an email where the body of the email was filled in
        /// using external files and specified in the Message property.
        /// </summary>
        [Test]
        public void AppendedEmailMessageFromFileTest()
        {
            string methodName = "AppendedEmailMessageFromFileTest()";
            FileSet fileSet = new FileSet();
            fileSet.FileNames.AddRange(_files.ToArray());

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);
            mailTask.Files = fileSet;

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        /// <summary>
        /// Tests sending an email with attachments.
        /// </summary>
        [Test]
        public void EmailAttachmentTest()
        {
            string methodName = "EmailAttachmentTest()";
            FileSet fileSet = new FileSet();
            fileSet.FileNames.AddRange(_files.ToArray());

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = CreateEmailListString(_twoEmails);
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);
            mailTask.Attachments = fileSet;

            mailTask.Execute();

            Assert.AreEqual(1, _smtpServer.ReceivedEmailCount);
        }

        #endregion Email With External Files Test Methods

        #region Exception Test Methods

        /// <summary>
        /// Tests sending an email with a badly formatted email address.
        /// </summary>
        [Test]
        [ExpectedException(typeof(BuildException))]
        public void BadEmailTest()
        {
            string methodName = "BadEmailTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _badEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();
        }

        /// <summary>
        /// Tests sending an email with a badly formatted email address
        /// as Full Name &lt;address@abcxyz.com&gt;.
        /// </summary>
        [Test]
        [ExpectedException(typeof(BuildException))]
        public void BadAngleBracketNameEmailTest()
        {
            string methodName = "BadAngleBracketNameEmailTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _badAngleBracketNameEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();
        }

        /// <summary>
        /// Tests sending an email with a badly formatted email address
        /// as &lt;address@abcxyz.com&gt; Full Name.
        /// </summary>
        [Test]
        [ExpectedException(typeof(BuildException))]
        public void BadAngleBracketEmailNameTest()
        {
            string methodName = "BadAngleBracketEmailNameTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _badAngleBracketEmailName;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();
        }

        /// <summary>
        /// Tests sending an email with a badly formatted email address
        /// as (Full Name) address@abcxyz.com.
        /// </summary>
        [Test]
        [ExpectedException(typeof(BuildException))]
        public void BadParenthesisNameEmailTest()
        {
            string methodName = "BadParenthesisNameEmailTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _badParenthesisNameEmail;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();
        }

        /// <summary>
        /// Tests sending an email with a badly formatted email address
        /// as address@abcxyz.com (Full Name).
        /// </summary>
        [Test]
        [ExpectedException(typeof(BuildException))]
        public void BadParenthesisEmailNameTest()
        {
            string methodName = "BadParenthesisEmailNameTest()";

            MailTask mailTask = new MailTask();
            mailTask.Project = CreateEmptyProject();

            mailTask.Mailhost = _mailHost;
            mailTask.Port = _port;
            mailTask.From = _fromEmail;
            mailTask.ToList = _badParenthesisEmailName;
            mailTask.Subject = String.Format(_subjectText, methodName);
            mailTask.Message = CreateSampleEmailMessage(methodName);

            mailTask.Execute();
        }

        #endregion Exception Test Methods

        #region Private Instance Methods

        /// <summary>
        /// Creates a simple message <see cref="System.String"/> to use for all
        /// email tests that do not retrieve message text from external files.
        /// </summary>
        /// <remarks>
        /// The idea here is rather than simply printing 'Sample message text'
        /// in the test email, useful information can easily be put in all test
        /// emails just in case tests fail.  Any additional information that could
        /// prove useful when investigating failed test cases should be added to
        /// this method.
        /// </remarks>
        /// <param name='methodName'>
        /// The name of the test method that created the sample email message.
        /// </param>
        /// <returns>
        /// The sample email message.
        /// </returns>
        private string CreateSampleEmailMessage(string methodName)
        {
            StringBuilder msg = new StringBuilder();
            msg.AppendFormat(CultureInfo.InvariantCulture,
                "This test email was generated by the test method: {0}", methodName)
                .AppendLine();
            msg.AppendLine();
            msg.AppendFormat(CultureInfo.InvariantCulture,
                "This test was conducted on {0} using NAnt version: {1}.",
                DateTime.Now, _nantVersion)
                .AppendLine();

            return msg.ToString();
        }

        /// <summary>
        /// Creates the email message temp file.
        /// </summary>
        /// <param name='fileName'>
        /// Name of the file to save the message to with the complete path omitted.
        /// </param>
        /// <returns>
        /// The complete path and file name of the temp file that the method
        /// created.
        /// </returns>
        private string CreateEmailMessageTempFile(string fileName)
        {
            // Setup the complete path/filename to write to.
            string targetFile = Path.Combine(_tempPath, fileName);

            // Create the message
            StringBuilder msg = new StringBuilder();
            msg.AppendFormat(CultureInfo.InvariantCulture,
                "This text came from a temporary file named: {0}", fileName)
                .AppendLine();
            msg.AppendLine();
            msg.AppendLine(
                "It is ok to delete this file after NAnt's test suite finishes its run.");
            msg.AppendLine();
            msg.AppendFormat(CultureInfo.InvariantCulture,
                "This file was conducted on {0} using NAnt version: {1}.",
                DateTime.Now, _nantVersion)
                .AppendLine();

            // Write the above message to the file
            using (StreamWriter writer = File.CreateText(targetFile))
            {
                writer.Write(msg.ToString());
                writer.Flush();
                writer.Close();
            }
            return targetFile;
        }

        /// <summary>
        /// Creates a new <see cref="System.String"/> email list from an array
        /// of email addresses.
        /// </summary>
        /// <param name='emails'>
        /// A <see cref="System.String"/> array of email addresses to join together.
        /// </param>
        /// <returns>
        /// A new list of email addresses separated by a semicolon.
        /// </returns>
        private string CreateEmailListString(string[] emails)
        {
            return String.Join(";", emails);
        }
        
        /// <summary>
        /// Retrieves the CC addresses from the first email that was
        /// received by the fake smtp server.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String" /> array of email addresses that
        /// were in the CC line of the first email received by the fake
        /// smtp server.  If the email did not contain email addresses in
        /// the CC line, an empty <see cref="System.String" /> array is 
        /// returned.
        /// </returns>
        private string[] GetCcAddressesFromSentMail()
        {
            if (_smtpServer.ReceivedEmailCount > 0)
            {
                if (_smtpServer.ReceivedEmail[0].Headers.ContainsKey("Cc"))
                {
                    string ccEmails = 
                        _smtpServer.ReceivedEmail[0].Headers["Cc"].ToString();
                    
                    return ccEmails.Split(',',';');
                }
                return new string[0];
            }
            // This should not be reached...
            throw new ArgumentNullException("Test smtp server has not yet received emails");
        }

        #endregion Private Instance Methods
    }
}
