/// <summary>
        /// Using mail with mime content to send a meeting request or cancel request
        /// </summary>
        /// <param name="calendarItem">Calendar information</param>
        /// <param name="subjectName">The subject name of meeting request mail</param>
        /// <param name="organizerEmailAddress">The organizer email address</param>
        /// <param name="attendeeEmailAddress">The attendee email address</param>
        /// <param name="method">Specify normal appointments from meeting requests, responses, and cancellations, it can be set to 'REQUEST', 'REPLY', or 'CANCEL'</param>
        /// <param name="replyMethod">Specify REPLY method, it can be set to 'ACCEPTED', 'TENTATIVE', or 'DECLINED'</param>
        protected void SendMimeMeeting(Calendar calendarItem, string subjectName, string organizerEmailAddress, string attendeeEmailAddress, string method, string replyMethod)
        {
            string icalendarContent = string.Empty;

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
            case "REQUEST":
            case "CANCEL":
                icalendarContent = TestSuiteHelper.CreateiCalendarFormatContent(calendarItem, method, replyMethod, organizerEmailAddress, attendeeEmailAddress);
                break;

            case "REPLY":
                icalendarContent = TestSuiteHelper.CreateiCalendarFormatContent(calendarItem, method, replyMethod, attendeeEmailAddress, organizerEmailAddress);
                break;
            }

            string body = string.Empty;

            string mime = TestSuiteHelper.CreateMeetingRequestMime(
                organizerEmailAddress,
                attendeeEmailAddress,
                subjectName,
                body,
                icalendarContent);

            // Send a meeting request
            SendMailRequest  sendMailRequest  = TestSuiteHelper.CreateSendMailRequest(TestSuiteHelper.Next(), false, mime);
            SendMailResponse sendMailResponse = this.CALAdapter.SendMail(sendMailRequest);

            Site.Assert.AreEqual <string>(
                string.Empty,
                sendMailResponse.ResponseDataXML,
                "The server should return an empty xml response data to indicate SendMail command success.");
        }
        /// <summary>
        /// Create iCalendar format string from one calendar instance
        /// </summary>
        /// <param name="calendar">Calendar information</param>
        /// <param name="method">Specify normal appointments from meeting requests, responses, and cancellations, it can be set to 'REQUEST', 'REPLY', or 'CANCEL'</param>
        /// <param name="replyMethod">Specify REPLY method, it can be set to 'ACCEPTED', 'TENTATIVE', or 'DECLINED'</param>
        /// <param name="organizerEmailAddress">The organizer email address</param>
        /// <param name="attendeeEmailAddress">The attendee email address</param>
        /// <returns>iCalendar formatted string</returns>
        internal static string CreateiCalendarFormatContent(Calendar calendar, string method, string replyMethod, string organizerEmailAddress, string attendeeEmailAddress)
        {
            StringBuilder icalendar = new StringBuilder();

            icalendar.AppendLine("BEGIN: VCALENDAR");
            icalendar.AppendLine("PRODID:-//Microsoft Protocols TestSuites");
            icalendar.AppendLine("VERSION:2.0");

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
            case "REQUEST":
                icalendar.AppendLine("METHOD:REQUEST");
                icalendar.AppendLine("X-MS-OLK-FORCEINSPECTOROPEN:TRUE");
                break;

            case "CANCEL":
                icalendar.AppendLine("METHOD:CANCEL");
                break;

            case "REPLY":
                icalendar.AppendLine("METHOD:REPLY");
                break;
            }

            icalendar.AppendLine("BEGIN:VTIMEZONE");
            icalendar.AppendLine("TZID:Universal Time");
            icalendar.AppendLine("BEGIN:STANDARD");
            icalendar.AppendLine("DTSTART:16011104T020000");
            icalendar.AppendLine("TZOFFSETFROM:-0000");
            icalendar.AppendLine("TZOFFSETTO:+0000");
            icalendar.AppendLine("END:STANDARD");
            icalendar.AppendLine("BEGIN:DAYLIGHT");
            icalendar.AppendLine("DTSTART:16010311T020000");
            icalendar.AppendLine("TZOFFSETFROM:-0000");
            icalendar.AppendLine("TZOFFSETTO:+0000");
            icalendar.AppendLine("END:DAYLIGHT");
            icalendar.AppendLine("END:VTIMEZONE");

            icalendar.AppendLine("BEGIN:VEVENT");
            icalendar.AppendLine("UID:" + calendar.UID);
            icalendar.AppendLine("DTSTAMP:" + ((DateTime)calendar.DtStamp).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
            icalendar.AppendLine("DESCRIPTION:" + calendar.Subject);

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
            case "REQUEST":
                icalendar.AppendLine("SUMMARY:" + calendar.Subject);
                icalendar.AppendLine("ATTENDEE;CN=\"\";RSVP=" + (calendar.ResponseRequested == true ? "TRUE" : "FALSE") + ":mailto:" + attendeeEmailAddress);

                icalendar.AppendLine("ORGANIZER:MAILTO:" + organizerEmailAddress);

                break;

            case "CANCEL":
                icalendar.AppendLine("STATUS:CANCELLED");
                icalendar.AppendLine("SUMMARY:" + "Cancelled:" + calendar.Subject);
                icalendar.AppendLine("ATTENDEE;CN=\"\";RSVP=" + (calendar.ResponseRequested == true ? "TRUE" : "FALSE") + ":mailto:" + attendeeEmailAddress);

                icalendar.AppendLine("ORGANIZER:MAILTO:" + organizerEmailAddress);

                break;

            case "REPLY":
                icalendar.AppendLine("SUMMARY:" + replyMethod + calendar.Subject);
                icalendar.AppendLine("ATTENDEE;PARTSTAT=" + replyMethod.ToUpper(CultureInfo.CurrentCulture) + ":mailto:" + attendeeEmailAddress);

                break;
            }

            icalendar.AppendLine("LOCATION:" + (calendar.Location ?? "My Office"));

            if (calendar.AllDayEvent == 1)
            {
                icalendar.AppendLine("DTSTART;VALUE=DATE:" + ((DateTime)calendar.StartTime).ToUniversalTime().Date.ToString("yyyyMMdd"));
                icalendar.AppendLine("DTEND;VALUE=DATE:" + ((DateTime)calendar.EndTime).ToUniversalTime().Date.ToString("yyyyMMdd"));
                icalendar.AppendLine("X-MICROSOFT-CDO-ALLDAYEVENT:TRUE");
            }
            else
            {
                icalendar.AppendLine("DTSTART;TZID=\"Universal Time\":" + ((DateTime)calendar.StartTime).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
                icalendar.AppendLine("DTEND;TZID=\"Universal Time\":" + ((DateTime)calendar.EndTime).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
            }

            if (calendar.Recurrence != null)
            {
                switch (calendar.Recurrence.Type)
                {
                case 0:
                    icalendar.AppendLine("RRULE:FREQ=DAILY;COUNT=" + calendar.Recurrence.Occurrences.ToString());
                    break;

                case 1:
                    icalendar.AppendLine("RRULE:FREQ=WEEKLY;BYDAY=MO;COUNT=" + calendar.Recurrence.Occurrences.ToString());
                    break;

                case 2:
                    icalendar.AppendLine("RRULE:FREQ=MONTHLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYMONTHDAY=1");
                    break;

                case 3:
                    icalendar.AppendLine("RRULE:FREQ=MONTHLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYDAY=1MO");
                    break;

                case 5:
                    icalendar.AppendLine("RRULE:FREQ=YEARLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYMONTHDAY=1;BYMONTH=1");
                    break;

                case 6:
                    icalendar.AppendLine("RRULE:FREQ=YEARLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYDAY=2MO;BYMONTH=1");
                    break;
                }
            }

            if (calendar.Exceptions != null)
            {
                icalendar.AppendLine("EXDATE;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].ExceptionStartTime);
            }

            switch (calendar.BusyStatus)
            {
            case 0:
                icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:FREE");
                break;

            case 1:
                icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE");
                break;

            case 2:
                icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY");
                break;

            case 3:
                icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:OOF");
                break;
            }

            if (calendar.DisallowNewTimeProposal == true)
            {
                icalendar.AppendLine("X-MICROSOFT-DISALLOW-COUNTER:TRUE");
            }

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
            case "REQUEST":
            case "CANCEL":
                if (calendar.Reminder.HasValue)
                {
                    icalendar.AppendLine("BEGIN:VALARM");
                    icalendar.AppendLine("TRIGGER:-PT" + calendar.Reminder + "M");
                    icalendar.AppendLine("ACTION:DISPLAY");
                    icalendar.AppendLine("END:VALARM");
                }

                break;
            }

            icalendar.AppendLine("END:VEVENT");

            if (calendar.Exceptions != null)
            {
                icalendar.AppendLine("BEGIN:VEVENT");
                icalendar.AppendLine("DTSTART;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].StartTime);
                icalendar.AppendLine("DTEND;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].EndTime);
                icalendar.AppendLine("UID:" + calendar.UID);
                icalendar.AppendLine("DTSTAMP:" + ((DateTime)calendar.DtStamp).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
                icalendar.AppendLine("SUMMARY:" + calendar.Exceptions.Exception[0].Subject);
                icalendar.AppendLine("RECURRENCE-ID;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].ExceptionStartTime);
                icalendar.AppendLine("LOCATION:" + calendar.Exceptions.Exception[0].Location);

                if (calendar.Exceptions.Exception[0].AllDayEvent == 1)
                {
                    icalendar.AppendLine("X-MICROSOFT-CDO-ALLDAYEVENT:TRUE");
                }

                if (calendar.Exceptions.Exception[0].ReminderSpecified == true)
                {
                    icalendar.AppendLine("BEGIN:VALARM");
                    icalendar.AppendLine("TRIGGER:-PT" + calendar.Exceptions.Exception[0].Reminder + "M");
                    icalendar.AppendLine("ACTION:DISPLAY");
                    icalendar.AppendLine("END:VALARM");
                }

                icalendar.AppendLine("END:VEVENT");
            }

            icalendar.AppendLine("END:VCALENDAR");
            return(icalendar.ToString());
        }
        /// <summary>
        /// Create iCalendar format string from one calendar instance
        /// </summary>
        /// <param name="calendar">Calendar information</param>
        /// <param name="method">Specify normal appointments from meeting requests, responses, and cancellations, it can be set to 'REQUEST', 'REPLY', or 'CANCEL'</param>
        /// <param name="replyMethod">Specify REPLY method, it can be set to 'ACCEPTED', 'TENTATIVE', or 'DECLINED'</param>
        /// <param name="organizerEmailAddress">The organizer email address</param>
        /// <param name="attendeeEmailAddress">The attendee email address</param>
        /// <returns>iCalendar formatted string</returns>
        internal static string CreateiCalendarFormatContent(Calendar calendar, string method, string replyMethod, string organizerEmailAddress, string attendeeEmailAddress)
        {
            StringBuilder icalendar = new StringBuilder();
            icalendar.AppendLine("BEGIN: VCALENDAR");
            icalendar.AppendLine("PRODID:-//Microsoft Protocols TestSuites");
            icalendar.AppendLine("VERSION:2.0");

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
                case "REQUEST":
                    icalendar.AppendLine("METHOD:REQUEST");
                    icalendar.AppendLine("X-MS-OLK-FORCEINSPECTOROPEN:TRUE");
                    break;

                case "CANCEL":
                    icalendar.AppendLine("METHOD:CANCEL");
                    break;

                case "REPLY":
                    icalendar.AppendLine("METHOD:REPLY");
                    break;
            }

            icalendar.AppendLine("BEGIN:VTIMEZONE");
            icalendar.AppendLine("TZID:Universal Time");
            icalendar.AppendLine("BEGIN:STANDARD");
            icalendar.AppendLine("DTSTART:16011104T020000");
            icalendar.AppendLine("TZOFFSETFROM:-0000");
            icalendar.AppendLine("TZOFFSETTO:+0000");
            icalendar.AppendLine("END:STANDARD");
            icalendar.AppendLine("BEGIN:DAYLIGHT");
            icalendar.AppendLine("DTSTART:16010311T020000");
            icalendar.AppendLine("TZOFFSETFROM:-0000");
            icalendar.AppendLine("TZOFFSETTO:+0000");
            icalendar.AppendLine("END:DAYLIGHT");
            icalendar.AppendLine("END:VTIMEZONE");

            icalendar.AppendLine("BEGIN:VEVENT");
            icalendar.AppendLine("UID:" + calendar.UID);
            icalendar.AppendLine("DTSTAMP:" + ((DateTime)calendar.DtStamp).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
            icalendar.AppendLine("DESCRIPTION:" + calendar.Subject);

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
                case "REQUEST":
                    icalendar.AppendLine("SUMMARY:" + calendar.Subject);
                    icalendar.AppendLine("ATTENDEE;CN=\"\";RSVP=" + (calendar.ResponseRequested == true ? "TRUE" : "FALSE") + ":mailto:" + attendeeEmailAddress);

                    icalendar.AppendLine("ORGANIZER:MAILTO:" + organizerEmailAddress);

                    break;

                case "CANCEL":
                    icalendar.AppendLine("STATUS:CANCELLED");
                    icalendar.AppendLine("SUMMARY:" + "Cancelled:" + calendar.Subject);
                    icalendar.AppendLine("ATTENDEE;CN=\"\";RSVP=" + (calendar.ResponseRequested == true ? "TRUE" : "FALSE") + ":mailto:" + attendeeEmailAddress);

                    icalendar.AppendLine("ORGANIZER:MAILTO:" + organizerEmailAddress);

                    break;

                case "REPLY":
                    icalendar.AppendLine("SUMMARY:" + replyMethod + calendar.Subject);
                    icalendar.AppendLine("ATTENDEE;PARTSTAT=" + replyMethod.ToUpper(CultureInfo.CurrentCulture) + ":mailto:" + attendeeEmailAddress);

                    break;
            }

            icalendar.AppendLine("LOCATION:" + (calendar.Location ?? "My Office"));

            if (calendar.AllDayEvent == 1)
            {
                icalendar.AppendLine("DTSTART;VALUE=DATE:" + ((DateTime)calendar.StartTime).ToUniversalTime().Date.ToString("yyyyMMdd"));
                icalendar.AppendLine("DTEND;VALUE=DATE:" + ((DateTime)calendar.EndTime).ToUniversalTime().Date.ToString("yyyyMMdd"));
                icalendar.AppendLine("X-MICROSOFT-CDO-ALLDAYEVENT:TRUE");
            }
            else
            {
                icalendar.AppendLine("DTSTART;TZID=\"Universal Time\":" + ((DateTime)calendar.StartTime).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
                icalendar.AppendLine("DTEND;TZID=\"Universal Time\":" + ((DateTime)calendar.EndTime).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
            }

            if (calendar.Recurrence != null)
            {
                switch (calendar.Recurrence.Type)
                {
                    case 0:
                        icalendar.AppendLine("RRULE:FREQ=DAILY;COUNT=" + calendar.Recurrence.Occurrences.ToString());
                        break;

                    case 1:
                        icalendar.AppendLine("RRULE:FREQ=WEEKLY;BYDAY=MO;COUNT=" + calendar.Recurrence.Occurrences.ToString());
                        break;

                    case 2:
                        icalendar.AppendLine("RRULE:FREQ=MONTHLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYMONTHDAY=1");
                        break;

                    case 3:
                        icalendar.AppendLine("RRULE:FREQ=MONTHLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYDAY=1MO");
                        break;

                    case 5:
                        icalendar.AppendLine("RRULE:FREQ=YEARLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYMONTHDAY=1;BYMONTH=1");
                        break;

                    case 6:
                        icalendar.AppendLine("RRULE:FREQ=YEARLY;COUNT=" + calendar.Recurrence.Occurrences.ToString() + ";BYDAY=2MO;BYMONTH=1");
                        break;
                }
            }

            if (calendar.Exceptions != null)
            {
                icalendar.AppendLine("EXDATE;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].ExceptionStartTime);
            }

            switch (calendar.BusyStatus)
            {
                case 0:
                    icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:FREE");
                    break;

                case 1:
                    icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:TENTATIVE");
                    break;

                case 2:
                    icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY");
                    break;

                case 3:
                    icalendar.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:OOF");
                    break;
            }

            if (calendar.DisallowNewTimeProposal == true)
            {
                icalendar.AppendLine("X-MICROSOFT-DISALLOW-COUNTER:TRUE");
            }

            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
                case "REQUEST":
                case "CANCEL":
                    if (!string.IsNullOrEmpty(calendar.Reminder))
                    {
                        icalendar.AppendLine("BEGIN:VALARM");
                        icalendar.AppendLine("TRIGGER:-PT" + calendar.Reminder + "M");
                        icalendar.AppendLine("ACTION:DISPLAY");
                        icalendar.AppendLine("END:VALARM");
                    }

                    break;
            }

            icalendar.AppendLine("END:VEVENT");

            if (calendar.Exceptions != null)
            {
                icalendar.AppendLine("BEGIN:VEVENT");
                icalendar.AppendLine("DTSTART;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].StartTime);
                icalendar.AppendLine("DTEND;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].EndTime);
                icalendar.AppendLine("UID:" + calendar.UID);
                icalendar.AppendLine("DTSTAMP:" + ((DateTime)calendar.DtStamp).ToUniversalTime().ToString("yyyyMMddTHHmmss"));
                icalendar.AppendLine("SUMMARY:" + calendar.Exceptions.Exception[0].Subject);
                icalendar.AppendLine("RECURRENCE-ID;TZID=\"Universal Time\":" + calendar.Exceptions.Exception[0].ExceptionStartTime);
                icalendar.AppendLine("LOCATION:" + calendar.Exceptions.Exception[0].Location);

                if (calendar.Exceptions.Exception[0].AllDayEvent == 1)
                {
                    icalendar.AppendLine("X-MICROSOFT-CDO-ALLDAYEVENT:TRUE");
                }

                if (!string.IsNullOrEmpty(calendar.Exceptions.Exception[0].Reminder))
                {
                    icalendar.AppendLine("BEGIN:VALARM");
                    icalendar.AppendLine("TRIGGER:-PT" + calendar.Exceptions.Exception[0].Reminder + "M");
                    icalendar.AppendLine("ACTION:DISPLAY");
                    icalendar.AppendLine("END:VALARM");
                }

                icalendar.AppendLine("END:VEVENT");
            }

            icalendar.AppendLine("END:VCALENDAR");
            return icalendar.ToString();
        }
        /// <summary>
        /// Using mail with mime content to send a meeting request or cancel request
        /// </summary>
        /// <param name="calendarItem">Calendar information</param>
        /// <param name="subjectName">The subject name of meeting request mail</param>
        /// <param name="organizerEmailAddress">The organizer email address</param>
        /// <param name="attendeeEmailAddress">The attendee email address</param>
        /// <param name="method">Specify normal appointments from meeting requests, responses, and cancellations, it can be set to 'REQUEST', 'REPLY', or 'CANCEL'</param>
        /// <param name="replyMethod">Specify REPLY method, it can be set to 'ACCEPTED', 'TENTATIVE', or 'DECLINED'</param>
        protected void SendMimeMeeting(Calendar calendarItem, string subjectName, string organizerEmailAddress, string attendeeEmailAddress, string method, string replyMethod)
        {
            string icalendarContent = string.Empty;
            switch (method.ToUpper(CultureInfo.CurrentCulture))
            {
                case "REQUEST":
                case "CANCEL":
                    icalendarContent = TestSuiteHelper.CreateiCalendarFormatContent(calendarItem, method, replyMethod, organizerEmailAddress, attendeeEmailAddress);
                    break;

                case "REPLY":
                    icalendarContent = TestSuiteHelper.CreateiCalendarFormatContent(calendarItem, method, replyMethod, attendeeEmailAddress, organizerEmailAddress);
                    break;
            }

            string body = string.Empty;

            string mime = TestSuiteHelper.CreateMeetingRequestMime(
                organizerEmailAddress,
                attendeeEmailAddress,
                subjectName,
                body,
                icalendarContent);

            // Send a meeting request
            SendMailRequest sendMailRequest = TestSuiteHelper.CreateSendMailRequest(TestSuiteHelper.Next(), false, mime);
            SendMailResponse sendMailResponse = this.CALAdapter.SendMail(sendMailRequest);

            Site.Assert.AreEqual<string>(
                string.Empty,
                sendMailResponse.ResponseDataXML,
                 "The server should return an empty xml response data to indicate SendMail command success.");
        }